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 section | Source field |
|---|---|
| Earning | positions[].value (shares × sharePrice) |
| Pending | positions[].pending.deposits[] |
| Redeeming | positions[].pending.redeems[] |
| Ready to withdraw | positions[].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 flow — claim 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 wallets | individual |
| Consumer savings on top of your existing ledger, or fastest XAUa launch | omnibus |
| Your own balance-sheet yield | treasury |
| Treasury yield for your merchants or corporate clients | business |
Models mix freely — most platforms end up with two or three.