Skip to main content

Use Cases

Four common product patterns, each mapped to the account model that fits it best. All examples use the sandbox base URL and a test key.

const BASE = "https://rwa-api-sandbox.tbook.com";
const HEADERS = {
Authorization: `Bearer ${process.env.TBK_TEST_KEY}`,
"Content-Type": "application/json",
};

1. Earn tab (consumer app) — individual accounts

Scenario: your app has an "Earn" section where end-users browse assets, deposit USDC, and watch yield accrue. Each user has their own WaaS wallet.

Recommended UI: an asset selector (name, APY, settlement timing), then per-asset balance breakdown:

Balance sectionSource field
Earningpositions[].value (shares × sharePrice)
Pendingpositions[].pending.deposits[]
Redeemingpositions[].pending.redeems[]
Ready to withdrawpositions[].claimable

Step 1 — show the catalog (one call; it is already filtered to assets enabled for you):

const { data: assets } = await fetch(`${BASE}/v1/assets`, { headers: HEADERS })
.then(r => r.json());
// → rcusdp (USD yield, live price/apy, T+1) · xaua (gold, T+3)

Step 2 — register the user once (at signup, after your KYC):

const account = await fetch(`${BASE}/v1/accounts`, {
method: "POST",
headers: { ...HEADERS, "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify({
externalId: user.id, // YOUR id — never share PII
type: "individual",
custody: "waas",
wallets: [{ chain: "sui", address: user.suiWallet }],
compliance: { kyc: { attested: true, provider: "your-kyc", ref: user.kycRef } },
}),
}).then(r => r.json());

Step 3 — deposit (build → sign with WaaS → confirm):

const intent = await fetch(`${BASE}/v1/vaults/rcusdp-sui/tx/deposit`, {
method: "POST",
headers: { ...HEADERS, "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify({ accountId: account.accountId, amount: "100.00" }),
}).then(r => r.json());

// intent.transaction = { format: "sui:tx-bytes-base64", data: "<unsigned tx bytes>" }
const digest = await waas.signAndSubmit(intent.transaction.data); // Crossmint, Privy, …
await fetch(`${BASE}/v1/transactions/${intent.intentId}/confirm`, {
method: "POST", headers: HEADERS, body: JSON.stringify({ digest }),
});

Step 4 — render balances and earnings (no math on your side):

const { data: positions } = await fetch(
`${BASE}/v1/accounts/${account.accountId}/positions`, { headers: HEADERS }
).then(r => r.json());

const earnings = await fetch(
`${BASE}/v1/accounts/${account.accountId}/earnings?assetId=rcusdp`,
{ headers: HEADERS }
).then(r => r.json());
// earnings.profit, earnings.profitRateBps — display as "Interest earned"

Step 5 — update the UI from webhooks, not polling: transaction.deposit.settled carries externalId, recordId, and the exact shares credited.


2. Treasury management — treasury account

Scenario: your organization holds idle USDC (float, reserves) and deploys it across assets. Backend-only; the wallet is your multisig.

// Allocation: 70% USD yield, 30% gold hedge
// (xaua-sui deposits require the wallet to be issuer-whitelisted — a one-time
// onboarding step; non-whitelisted wallets get 403 not_whitelisted at build time)
for (const [vaultId, amount] of [["rcusdp-sui", "700000.00"], ["xaua-sui", "300000.00"]]) {
const intent = await fetch(`${BASE}/v1/vaults/${vaultId}/tx/deposit`, {
method: "POST",
headers: { ...HEADERS, "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify({ accountId: TREASURY_ACCOUNT_ID, amount }),
}).then(r => r.json());

await submitToMultisigProposal(intent.transaction); // your Sui multisig flow
// Note intent.expiresAt — coordinate signers before building (see Account Models)
}

Withdrawals to external addresses go through the allowlist + dual-approval flowclaim back to your own wallet needs none of that.

Monitor everything from the analytics endpoints (/v1/analytics/aum?groupBy=asset) and the vault.cycle.settled webhook.


3. High-yield savings (white-label) — omnibus account

Scenario: a "Savings" balance in your consumer app. Users see USD amounts growing; shares, cycles, and chains are invisible. One pooled wallet; your core ledger keeps per-user balances.

The integration is three webhook-driven bookkeeping rules (see Account Models — omnibus for the full contract):

// 1. User "adds to savings" → your ledger debits the user, and you batch-deposit from the pool
// 2. On transaction.deposit.settled → book the settled shares to users pro-rata
app.post("/webhooks/tbook", verifyTBookSignature, (req, res) => {
const event = req.body;
if (event.type === "transaction.deposit.settled") {
const { recordId, shares } = event.data; // exact shares credited on-chain
ledger.allocateShares({ recordId, shares }); // YOUR sub-ledger, in shares
}
res.sendStatus(200);
});

// 3. Daily reconciliation: ledger total must equal the pool position
const pool = await fetch(`${BASE}/v1/accounts/${POOL_ACCOUNT_ID}/positions`, { headers: HEADERS })
.then(r => r.json());
assert(ledger.totalShares() === Number(pool.data[0].shares)); // alert on drift

Display each user's balance as userShares × sharePrice (current price from GET /v1/vaults/rcusdp-sui/price or the positions response) — yield shows up automatically as the share price rises.


4. Merchant treasury (two-tier platform) — business accounts

Scenario: merchants on your platform each want their own treasury yield. One business account per merchant — TBook indexes per-merchant positions and earnings, so you run no sub-ledger.

// Onboard a merchant (you KYB them and attest)
const merchant = await fetch(`${BASE}/v1/accounts`, {
method: "POST",
headers: { ...HEADERS, "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify({
externalId: `merchant-${m.id}`,
type: "business",
custody: "self", // merchant's own multisig
channel: "merchant-treasury",
wallets: [{ chain: "sui", address: m.multisigAddress }],
compliance: { kyb: { attested: true, provider: "your-kyb", ref: m.kybRef } },
}),
}).then(r => r.json());

// Per-merchant reporting comes free:
// GET /v1/accounts/:id/earnings — merchant statement
// GET /v1/analytics/aum?groupBy=channel — your dashboard

Merchant withdrawals get treasury-grade controls (allowlist + dual approval) per account.


Choosing

You are building…Use
Consumer earn/savings with per-user walletsindividual
Consumer savings on top of your existing ledger, or fastest XAUa launchomnibus
Your own balance-sheet yieldtreasury
Treasury yield for your merchants or corporate clientsbusiness

Models mix freely — most platforms end up with two or three.