Guides

Build a dApp

Read the catalog and build the transactions your users sign in their own wallet. Two paths: embed the ready-made widget, or build your own UI with the SDK below.

#Read the catalog

const res = await fetch(`${SUP}/api/adaptors?network=mainnet`);
const { adaptors } = await res.json();   // CatalogEntry[]

Each CatalogEntry has:

  • serviceType, packageId, publisher
  • manifest (verified) — name, category, summary, ops, feeBps, …
  • manifestVerified — did the off-chain body match the on-chain hash?
  • usage{ actions, uniqueWallets, lastActionMs } (objective, from events)
  • reviews{ count, avg, verifiedCount, verifiedAvg }
  • source"registry" (community) or "featured" (official seed)

Render it however you like. Sort by usage.actions and surface manifestVerified + verifiedCount as trust signals.

#Authorize an adaptor for a coin (owner signs)

This is the gate every adaptor op checks — the owner grants the input coin to the adaptor's witness service-type:

import { buildAuthorizeTx } from "@workspace/sup-marketplace/tx";

const tx = buildAuthorizeTx({
  supWalletPackage,        // the SupWallet package id for this network
  walletId,                // the user's vault object id
  serviceType: entry.serviceType,
  coinType: "0x2::sui::SUI",
});
await wallet.signAndExecuteTransaction({ transaction: tx });

On-chain this is SupWallet::wallet::grant_service_coin<Witness, Coin>(wallet). The user can revoke it any time. (For an AI-agent/delegate flow you'd also set per-service and per-coin allowance caps; for an owner-direct flow the grant alone is enough.)

#Run an adaptor op (owner signs)

From the manifest op's call spec, resolve a concrete PTB, then sign:

import { resolveOpCall, buildAdaptorOpTx } from "@workspace/sup-marketplace/tx";

const op = entry.manifest.ops.find((o) => o.entry === "swap_a_to_b" && o.call)!;
const call = resolveOpCall({
  packageId: entry.packageId,
  module: op.module, entry: op.entry, call: op.call!,
  walletId,
  amountAtomic: "1000000000",   // 1.0 of coinIn (atomic)
  minOutAtomic: "0",            // your slippage floor
  coinInType: SUI, coinOutType: USDC,
});
const tx = buildAdaptorOpTx(call);
await wallet.signAndExecuteTransaction({ transaction: tx });

Ops without a call spec are discover/authorize-only — show them but don't offer "Run". See Manifest & call spec.

#SDK

@workspace/sup-marketplace wraps the catalog read + the keyless PTB builders for browser, backend, and agent — one package, three surfaces:

import { createSupMarketplace } from "@workspace/sup-marketplace";
const sup = createSupMarketplace({ baseUrl: SUP, network: "mainnet" });
const { adaptors } = await sup.catalog();

Full method + builder list: SDK / CLI / MCP. Prefer the drop-in widget? Embed the widget.

#Networks, loading & errors

  • The catalog is per-network — pass ?network=testnet|mainnet (default testnet).
  • Endpoints return { "error": "…" } with a proper HTTP status; surface it.
  • The catalog read may hit RPC + Walrus — show a loading state; the widget already does.