Skip to main content
Most merchants finish onboarding, get their brand attestation hash, get matched with a lender, and then never see any of it again. The trust-fabric posture they spent the onboarding flow earning sits in the SUPER_ADMIN console or in an attestation API they don’t know they can query. This page closes that loop: a drop-in widget that surfaces your trust-fabric posture — brand attestation status, credit line, recent lender associations, repayment history — on your own merchant dashboard, custom storefront, or external admin portal. Every endpoint the widget polls is @Public() — no JWT, no SDK, no IP allowlist. Copy the snippet, swap the two placeholder constants for your shop slug and merchant ID, and the widget renders.

What the widget shows

  • Your Schema A brand attestation status — ACTIVE, PENDING, or not-yet-issued.
  • Your associated lender(s) sourced from the LenderRegistry via the routing recommender.
  • Your most-recent credit-risk attestation (Schema B), if any — credit line amount + issuing lender.
  • Your repayment-history (Schema C) rollup — successful settlements count.
  • Your trust-tier (if /v2/upgrade-preview returns one — starter, verified, trusted, etc.).
  • Aggregate trust-fabric scale from /v2/trust-fabric/stats so you can display a “Powered by Droplinked Trust Fabric” badge with live platform numbers.

Live data sources

EndpointWhat it surfaces
GET /v2/attestations/brand/:slugSchema A brand attestation status
GET /v2/attestations/credit-risk/:merchantIdSchema B credit-risk attestation (current credit line + issuing lender)
GET /v2/attestations/repayment-history/:merchantIdSchema C repayment rollup
GET /v2/upgrade-previewTrust-tier projection
GET /v2/lender-routing/recommend?jurisdiction=...Associated / recommended lenders
GET /v2/trust-fabric/statsAggregate platform badge numbers
All six endpoints are public + unauthenticated. The widget calls them in parallel and renders whatever returns; missing endpoints (e.g. no credit-risk attestation yet) degrade gracefully to “none active”.

Widget code

Self-contained — drop into any existing HTML page or merchant admin template.
<div id="droplinked-trust-fabric-widget"></div>
<script>
  const SHOP_SLUG = 'your-shop-slug';       // change me
  const MERCHANT_ID = 'your-merchant-id';   // change me
  const API = 'https://apiv3.droplinked.com';

  async function loadTrustFabric() {
    const widget = document.getElementById('droplinked-trust-fabric-widget');
    widget.innerHTML = '<p style="color:#5b6b64;">Loading trust-fabric posture…</p>';
    try {
      const [brand, credit, repayment, upgrade, stats] = await Promise.all([
        fetch(`${API}/v2/attestations/brand/${SHOP_SLUG}`).then((r) => r.json()).catch(() => null),
        fetch(`${API}/v2/attestations/credit-risk/${MERCHANT_ID}`).then((r) => r.json()).catch(() => null),
        fetch(`${API}/v2/attestations/repayment-history/${MERCHANT_ID}`).then((r) => r.json()).catch(() => null),
        fetch(`${API}/v2/upgrade-preview?merchantId=${MERCHANT_ID}`).then((r) => r.json()).catch(() => null),
        fetch(`${API}/v2/trust-fabric/stats`).then((r) => r.json()).catch(() => null),
      ]);

      const creditLine = credit?.attestation?.creditLineCents
        ? `$${(credit.attestation.creditLineCents / 100).toFixed(2)}`
        : 'none active';
      const settlements = repayment?.summary?.successfulSettlements ?? 0;
      const tier = upgrade?.currentTier || 'starter';
      const brandStatus = brand?.status || 'not yet issued';
      const activeLenders = stats?.lenders?.active ?? 0;
      const schemaB = stats?.attestations?.schemaB ?? 0;

      widget.innerHTML = `
        <div style="background:#fff;border-radius:12px;padding:24px;box-shadow:0 1px 3px rgba(0,0,0,.06);font-family:system-ui,-apple-system,sans-serif;max-width:480px;">
          <h2 style="margin:0 0 16px;color:#11221c;font-size:18px;">Trust-Fabric Posture</h2>
          <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:16px;">
            <div>
              <div style="color:#5b6b64;font-size:11px;text-transform:uppercase;letter-spacing:.08em;">Brand attestation</div>
              <div style="font-size:14px;color:#11221c;margin-top:4px;">${brandStatus}</div>
            </div>
            <div>
              <div style="color:#5b6b64;font-size:11px;text-transform:uppercase;letter-spacing:.08em;">Trust tier</div>
              <div style="font-size:14px;color:#11221c;margin-top:4px;">${tier}</div>
            </div>
            <div>
              <div style="color:#5b6b64;font-size:11px;text-transform:uppercase;letter-spacing:.08em;">Credit line</div>
              <div style="font-size:14px;color:#11221c;margin-top:4px;">${creditLine}</div>
            </div>
            <div>
              <div style="color:#5b6b64;font-size:11px;text-transform:uppercase;letter-spacing:.08em;">Settlements</div>
              <div style="font-size:14px;color:#11221c;margin-top:4px;">${settlements}</div>
            </div>
          </div>
          <p style="color:#5b6b64;font-size:11px;margin:0;padding-top:12px;border-top:1px solid #eef2f0;">
            Powered by Droplinked Trust Fabric — ${activeLenders} active lenders, ${schemaB} on-chain credit attestations
          </p>
        </div>
      `;
    } catch (err) {
      widget.innerHTML = '<p style="color:#a13;">Could not load trust-fabric data.</p>';
      console.error(err);
    }
  }
  loadTrustFabric();
  setInterval(loadTrustFabric, 5 * 60_000); // 5 min refresh
</script>

Privacy + auth

Every endpoint this widget calls is decorated with @Public() in the API — no JWT, no API key, no IP allowlist. That means you can embed the snippet directly in client-side code on a shop builder template or a custom storefront without proxying through a backend. The fields surfaced are public-safe by design:
  • Statuses, tier labels, credit line amount, settlement counts.
  • No operator-side actor IDs.
  • No signing wallet addresses.
  • No regulator references or audit reasons.
  • No counterparty PII.
Treat this widget as the merchant-facing analog of the public lender registry — everything is meant to be visible, and nothing leaks the operator-only fields that live behind SUPER_ADMIN.

Customization

  • Brand chrome — swap the #2bcfa1 / #06c295 / #11221c palette for your own; replace the <h2> heading with your own copy or logo.
  • Hide cards — remove the credit-line card on a storefront where you only want to show brand attestation, or remove the “Powered by” footer on an internal admin portal.
  • Per-tier badges — render a different SVG / color for each upgrade.currentTier value (starter / verified / trusted).
  • Lender association list — call /v2/lender-routing/recommend?jurisdiction=YOUR_GEO and render the top-N recommended lenders alongside the credit line for a “who’d underwrite you today” view.
  • Link to forensic chain — if you also want to expose attestation hashes, link brand.attestationUid through to the public block explorer rather than rendering the hex on the card itself.

Polling cadence

Recommend a client-side refresh of 5 minutes or greater for this widget. The endpoints used here are aggregate / lookup endpoints — they don’t change at high velocity. The reference Trust-Fabric Dashboard Template uses 60-second polling because it’s a platform-aggregate dashboard; a per-merchant posture widget changes more slowly (status flips, periodic credit-line refreshes), so 5 minutes is plenty. If you embed multiple instances of this widget on the same page, cache the fetch responses at module scope or behind SWR / React Query with staleTime: 300_000 to avoid duplicate requests.

CORS

All endpoints used here are CORS-permissive — they respond with Access-Control-Allow-Origin: * to browser fetches from any origin. You can verify locally:
curl -sI -H "Origin: https://yourdomain.example" \
  https://apiv3.droplinked.com/v2/trust-fabric/stats | grep -i access-control
If a specific origin fails, email support@droplinked.com with the origin
  • the failing request — it usually indicates a WAF rule rather than a CORS policy.

What this widget does NOT show

Operator-only fields stay in the SUPER_ADMIN console and never appear in the public attestation endpoints — so they don’t appear in this widget either:
  • Signing wallet addresses + key custody references.
  • Per-attestation audit-log entries (who issued, when, on what host).
  • Operator notes / underwriting reasons.
  • Regulator correspondence references.
  • Lender-side risk scoring detail.
If you need any of those surfaces for an internal admin tool, build it behind the SUPER_ADMIN JWT — don’t try to extend this widget.