Exchanges and custodians
Build custodial Torq Earn with subaccount attribution, controlled execution, and canonical books and records.
Offer Torq Earn inside an exchange or custody product while preserving your custody controls, subaccount ledger, approval policy, and operational reconciliation. The exchange signs; Torq never receives private keys or decides which customer owns an omnibus position.
Private Preview. Custody topology, wallets, products, workflow roles, limits, and production access must be reviewed and explicitly approved.
Custodial Earn
Subaccounts, custody execution, and proof-bound balances
Publish approved vaults with deep risk and liquidity data.
Create idempotent deposit or redemption instructions.
Custody signs the exact Torq workflow transactions.
Post subaccount balances from canonical completion.
Catalog, terms, allocations, liquidity, and activity.
Idempotency, subaccount attribution, and queue state.
Controlled signing, simulation, and transaction submission.
Event inbox, positions, and invariant reconciliation.
What you will build
- Approved opportunity catalog with complete vault, market, asset, allocation, liquidity, and fee data.
- Customer Earn orders and subaccount balances backed by declared custody addresses.
- Policy-controlled custody execution for partner wrapper deposits and redemptions.
- Canonical transaction tracking, durable events, customer-ledger posting, and daily reconciliation.
- Operational queues for partial execution, stale state, reorg, delayed redemption, and mismatches.
Your custody service is the customer-controlled signer for the declared account model. A Torq secret key authenticates API requests but cannot substitute for custody approvals.
Prerequisites
- Approved Torq applications and secret keys per environment, custody wallets, wrapper and partner program, workflow scopes, webhook endpoint, and chain allowlist.
- Account and subaccount ownership model, deposit/redemption terms, allocation rules, and disclosures.
- Custody approval engine that verifies exact chain, target, calldata, value, limits, and order.
- Idempotent order service, double-entry ledger, durable inbox, reconciliation, alerting, and support.
Project files
Copy or adapt examples/developer-platform/earn-program-reference:
src/catalog.mjs # exact Torq opportunity and product resources
src/torq-api.mjs # server-authenticated client
src/workflows.mjs # exact prepared intent and canonical completion
src/webhooks.mjs # signed event verification and inbox boundary
src/use-cases.mjs # exchange credential, custody, and workflow profileProduction service layout:
earn-catalog/ # approved products and customer presentation
earn-orders/ # idempotent customer order state machine
custody-policy/ # approval, simulation, signing, submission
torq-orchestrator/ # prepare, register, wait, and reread
subaccount-ledger/ # pending/finalized customer journals
event-inbox/ # raw signed delivery storage and deduplication
reconciliation/ # Torq positions vs custody vs customer liabilitiesComplete data contract
| View | Operations |
|---|---|
| Opportunity index | GET /v1/assets, GET /v1/markets, GET /v1/vaults, GET /v1/tranches, GET /v1/funds |
| Product and risk | GET /v1/assets/{resourceId}, GET /v1/markets/{resourceId}, GET /v1/vaults/{resourceId} |
| Exposure | GET /v1/vaults/{resourceId}/allocations, GET /v1/vaults/{resourceId}/liquidity, GET /v1/vaults/{resourceId}/activity |
| Transfer and exit | GET /v1/vaults/{resourceId}/share-mobility, GET /v1/eligibility |
| Books and records | GET /v1/positions, GET /v1/activity, GET /v1/fees, GET /v1/wrappers |
| Execution | POST /v1/workflows/prepare, POST /v1/workflows/{requestId}/transactions, GET /v1/workflows/{requestId} |
Complete credit lifecycle
Extend the exchange product with the complete credit lifecycle for every attributed subaccount:
| Customer moment | Exchange or custodian implementation |
|---|---|
| Deposit and tranche selection | Bind the Torq product and share class to an immutable subaccount order before custody approval. |
| Position, yield, and liquidity | Reconcile server GraphQL vaultHolderPerformanceCurrent, vault economics, allocations, liquidity, fees, and activity against custody and customer books; keep GET /v1/positions as separate market-position context. |
| Redemption and claimable cash | Keep redemption request, queued obligation, claimable cash, custody settlement, and customer credit distinct. |
| Impairment monitoring | Correlate attributed vault exposure with GET /v1/liquidation-recovery, GET /v1/vaults/{resourceId}/activity, and durable GET /v1/events. |
| Recovery center | Offer fund terms and exposure using GET /v1/funds, GET /v1/funds/{resourceId}, GET /v1/funds/{resourceId}/holdings, and secret-key POST /graphql. |
| Distressed-fund decision | Book a separate capital allocation per participating subaccount. An affected Earn balance does not automatically make the customer eligible or grant compensation or fund proceeds. |
| Customer action | Capture explicit customer approval, then enforce custody policy. If no approved Preview executor exists, show capability_not_ready and do not construct calldata. |
| Final reconciliation | Reconcile protocol, custody, and customer ledgers independently for the vault path and the optional fund path. |
The omnibus wallet must never erase customer-level provenance. Store the subaccount authorization and allocation used for both the original position and any separate recovery-fund subscription.
Build the integration
1. Partition applications and custody accounts
Create distinct Torq applications, keys, webhook endpoints, custody accounts, and databases for test and production. Persist organization, application, chain, Torq resource, customer subaccount, custody wallet, workflow request, and transaction hash mappings. Never multiplex tenants through an unattributed wallet or shared idempotency namespace.
2. Build the approved opportunity index
Load the complete catalog plus deep resources through src/catalog.mjs. Show asset identity,
vault terms, market exposure, allocations, liquidity, fee structure, wrapper, activity, transfer
policy, freshness, and availability. Apply your listing and customer policy to canonical data; do
not estimate missing fields or scrape contract storage.
3. Model subaccount orders
Each deposit/redemption receives an immutable exchange order ID, customer/subaccount ID, amount, asset, vault, wrapper, custody wallet, policy version, and stable idempotency key. States must distinguish requested, policy-approved, prepared, custody-pending, submitted, canonical-success, ledger-posted, failed, and manual-review.
4. Check eligibility and available balance
Read GET /v1/eligibility, positions, liquidity, and share-mobility policy at proposal time. Lock or
reserve the customer balance in your ledger before signing, but do not finalize the Earn balance.
Repeat freshness, eligibility, and custody-balance checks before executing.
5. Prepare the partner workflow
Use role.partner.partnerWrapperDeposit or role.partner.partnerWrapperRedeem. Call
POST /v1/workflows/prepare, require preflight passed, store the exact response, and bind it to the
exchange order. Reject changed snapshots, expired workflows, unexpected approvals, or transactions
outside the product, wrapper, chain, and custody allowlists.
6. Execute at the custody boundary
Send only the exact prepared transactions to custody. Custody policy revalidates order, chain, target, calldata/value, amount, transaction order, simulation result, and approval quorum. Record the custody request ID and hash. Never let an API client provide raw target or calldata.
7. Register, deduplicate, and finalize
Register each hash with POST /v1/workflows/{requestId}/transactions using stable keys. If an order
is retried, return the existing order and workflow instead of signing again. Poll the transaction and
GET /v1/workflows/{requestId} until final_success, reread GET /v1/positions, then post the
customer Earn or redemption journal.
8. Process signed events
Verify exact raw bytes with src/webhooks.mjs, durably insert, deduplicate deliveryId and eventId,
and acknowledge. The worker rereads canonical Torq state and advances the exchange order. Event data
is a notification pointer, not an accounting journal.
9. Reconcile three books
At minimum reconcile: (1) Torq canonical positions/activity, (2) custody address balances and transactions, and (3) customer subaccount assets and liabilities. Flag any amount, owner, workflow, fee, or status mismatch. Preserve evidence and route unresolved breaks to operations.
10. Handle redemptions as a lifecycle
Display requested, submitted, pending canonical completion, claimable/available where applicable,
finalized, and failed states separately. Do not promise instant exits from vault liquidity alone.
Reread liquidity, position, activity, and share mobility after final_success.
Required negative tests
- Duplicate customer request and duplicate Torq registration do not create a second transaction.
- A stale catalog or eligibility resource blocks preparation.
- Custody rejects wrong chain, unexpected target, changed calldata, wrong amount, and expired plan.
- Receipt success without Torq
final_successdoes not credit a subaccount. - Webhook replay is deduplicated; webhook delay is recovered by polling.
- Reorg or failed canonical postcondition keeps the ledger uncredited and opens operations review.
- One customer cannot read, mutate, or receive another subaccount's order or balance.
Production checklist
- Secret keys and custody credentials never enter browsers, logs, events, or support exports.
- Torq applications, custody accounts, order IDs, and idempotency keys are environment-scoped.
- Catalog exposes exact allocations, liquidity, activity, fees, eligibility, and freshness.
- Custody signs only exact prepared and simulated Torq transactions.
- Retried orders deduplicate at customer, workflow, transaction, event, and ledger layers.
- Customer balances post only after transaction/workflow
final_successand position reread. - Daily three-book reconciliation has alert thresholds and named operational owners.
- Deposit, redemption, resume, reorg, timeout, and partial failure tests pass on Sepolia.
- Private Preview, custody, risk, fee, and redemption disclosures are approved.
Run node --test examples/developer-platform/earn-program-reference/test/*.test.mjs, then read
typed workflows, canonical state, and
errors and rate limits.