Yield aggregators
List, compare, and route Torq Earn opportunities with transparent data, wrappers, fees, and canonical positions.
Add Torq vaults to an Earn marketplace without reducing them to a single APY. Expose the complete asset, market, allocation, liquidity, fee, activity, and transfer-policy picture, then let users deposit and redeem through an approved partner wrapper inside your product.
Private Preview. Listing, wrapper routing, partner programs, fee shares, credentials, and production access depend on Torq and commercial approval. Revenue or relative price is not guaranteed.
Earn aggregation
Comparable opportunities, partner routing, transparent economics
Normalize canonical vault, market, fee, and liquidity data.
Select the disclosed wrapper and partner-program path.
The user signs an exact prepared deposit or redemption.
Reconcile positions, fees, and activity after final_success.
Deep product data without scraping protocol RPC.
Partner programs, wrapper terms, and disclosed fees.
Eligibility, prepared intent review, and customer signing.
Canonical position, activity, and fee reconciliation.
What you will build
- Comparable Torq opportunity index with deep product and freshness data.
- Vault page with markets, allocations, liquidity, fees, activity, eligibility, and mobility policy.
- Approved wrapper and partner program routing with explicit customer economics.
- User-wallet deposit, position, redemption, and fee-aware activity flows.
- Canonical position reconciliation, signed events, analytics, and partner fee-share servicing.
The user wallet is the customer-controlled signer. Your frontend may use an origin-bound publishable key and wallet session; server-only partner and webhook credentials remain private.
Prerequisites
- Approved Torq partner application, origin, keys, wallet scopes, wrapper, partner program, and test products.
- Listing methodology that explains freshness, liquidity, allocations, fees, risks, and missing data.
- Customer disclosures for product risks, your fee, Torq/vault fees, partner economics, and exits.
- Browser wallet integration plus a server event inbox and canonical reconciliation worker.
Project files
Use examples/developer-platform/earn-program-reference as the runnable request boundary:
src/catalog.mjs # full opportunity list and deep selected product
src/torq-api.mjs # publishable/secret client and wallet session
src/workflows.mjs # prepared wrapper flow and final_success
src/webhooks.mjs # signed delivery verification
src/use-cases.mjs # yield-aggregator modules and workflowsSuggested product implementation:
opportunity-index/ # normalized display fields plus source provenance
product-detail/ # exact Torq vault/market/exposure data
economics/ # wrapper, partner program, and fee disclosures
wallet-flow/ # eligibility, proposal, prepare, simulate, submit
portfolio/ # canonical position, activity, and redemption state
partner-backend/ # secret-key fee servicing and signed webhooksComplete data contract
| Aggregator experience | Operations |
|---|---|
| Discovery | GET /v1/assets, GET /v1/markets, GET /v1/vaults, GET /v1/tranches, GET /v1/funds |
| Comparable detail | GET /v1/assets/{resourceId}, GET /v1/markets/{resourceId}, GET /v1/vaults/{resourceId} |
| Exposure and capacity | GET /v1/vaults/{resourceId}/allocations, GET /v1/vaults/{resourceId}/liquidity, GET /v1/markets/{resourceId}/activity |
| Terms and access | GET /v1/vaults/{resourceId}/share-mobility, GET /v1/eligibility, GET /v1/fees |
| Routing and portfolio | GET /v1/wrappers, GET /v1/partner-programs, GET /v1/positions, GET /v1/activity |
| Transactions | POST /v1/workflows/prepare, POST /v1/workflows/{requestId}/transactions, GET /v1/workflows/{requestId} |
Complete credit lifecycle
Carry every routed position through the complete credit lifecycle, not only the initial APY ranking:
| Customer moment | Yield-aggregator implementation |
|---|---|
| Deposit and tranche selection | Compare actual asset, share-class, allocation, liquidity, fee, and redemption fields before routing to the selected wrapper. |
| Position, yield, and liquidity | Pin the canonical product identity and reconcile server GraphQL vaultHolderPerformanceCurrent, allocations, GET /v1/vaults/{resourceId}/liquidity, and activity after routing; do not substitute GET /v1/positions for the vault holder record. |
| Redemption and claimable cash | Keep queued or claimable Torq exit states visible in the aggregate portfolio instead of collapsing them into withdrawn. |
| Impairment monitoring | Use GET /v1/liquidation-recovery, GET /v1/vaults/{resourceId}/activity, and durable GET /v1/events to update affected opportunities and holdings. |
| Recovery opportunity | Compare open funds from GET /v1/funds, then load GET /v1/funds/{resourceId} and GET /v1/funds/{resourceId}/holdings for the selected option. |
| Distressed-fund decision | Never auto-roll an affected position. This is a separate capital allocation; the affected holding does not automatically create eligibility, compensation, or fund rights. |
| Customer action | Require explicit customer approval and the user wallet. Without an approved Preview executor, show capability_not_ready and preserve read-only monitoring. |
| Final reconciliation | Display original vault and optional fund exposure separately, using server POST /graphql, canonical resource rereads, and signed-event reconciliation. |
Ranking must not imply that a recovery fund repairs the original position or guarantees superior returns. Present its cost basis, illiquidity, side-pocket, fee, and claim terms as a different risk.
Build the integration
1. Create the source-grounded opportunity model
Keep Torq resource IDs and original canonical fields alongside any normalized aggregator fields. Model asset, vault, market, tranche, fund, allocations, liquidity, fees, activity, eligibility, mobility, freshness, and limitations. Do not convert incomplete fields into a synthetic APY or score.
2. Load all candidates and deep selected products
Use loadEarnCatalog() for discovery and loadEarnProduct() for the selected opportunity. Fetch
detail and activity rather than displaying the generic list item as a complete product. Cache only
within documented freshness behavior and mark stale/unavailable opportunities non-actionable.
3. Compare transparently
Define every normalized field, source, unit, timestamp, and limitation. Show gross/declared product data separately from vault fees, Torq or wrapper economics, your fee, and estimated net customer outcome. Never promise yield, liquidity, partner margin, approval, or that your route is always cheaper.
4. Resolve wrapper and partner program
Read GET /v1/wrappers, GET /v1/partner-programs, and fees for the exact application and product.
Show routing attribution and customer economics before consent. Reject caller-provided wrapper or fee
terms that are absent from canonical Torq resources.
5. Establish the wallet session and eligibility
Use the origin-bound challenge/confirm flow from src/torq-api.mjs. Validate audience, API origin,
chain, application, wallet, purpose, and expiry before invoking the wallet. Read GET /v1/eligibility,
current positions, liquidity, and share-mobility state for the selected wallet and vault.
6. Prepare the wrapper action
Build role.partner.partnerWrapperDeposit or role.partner.partnerWrapperRedeem with typed product,
wrapper, amount, beneficiary, and partner attribution. Call POST /v1/workflows/prepare using a stable
idempotency key, require preflight passed, and show exact chain, targets, values, ordering, fees,
simulation requirement, and expiry.
7. Simulate and sign
Immediately reread GET /v1/workflows/{requestId} and compare the prepared snapshot/intents. The user
wallet simulates and submits exact prepared transactions. No aggregator API caller may supply a raw
target or calldata value.
8. Register and reconcile the canonical position
Call POST /v1/workflows/{requestId}/transactions for each hash. Wait for transaction and workflow
final_success, then reread GET /v1/positions, vault activity, liquidity, and wrapper/fee resources.
Only then update the canonical position shown in your portfolio.
9. Process partner events and fees
Verify webhook raw bytes with src/webhooks.mjs, deduplicate, and reread referenced resources.
Display partner fee shares from canonical program/fee state. If approved, use
role.partner.partnerFeeSharesClaim through the same review, prepare, signer, register, and canonical
completion path. Keep company revenue separate from customer balances.
10. Monitor data quality and price claims
Continuously test field provenance, units, stale state, missing values, ranking behavior, route fees, position reconciliation, and disclosure rendering. If any essential comparison input is unavailable, the opportunity must become non-actionable instead of receiving a zero or optimistic default.
Ranking and UX rules
- Display yield inputs and limitations, not only a headline percentage.
- Show allocation concentration, market exposures, available liquidity, fees, and activity.
- Distinguish current, stale, blocked, paused, redemption-pending, and unavailable states.
- Preserve Torq resource links and timestamps for support and investigation.
- Clearly identify wrapper/partner route and every fee charged to the customer.
- Never rank on hidden partner compensation without a visible and governed methodology.
Production checklist
- Every normalized field has an exact canonical source, unit, timestamp, and missing-data rule.
- Detail pages use deep endpoints, not generic list-sample data.
- Origin-bound publishable and server secret keys stay in their correct boundaries.
- Wrapper, partner program, and fee terms are canonical and disclosed before signing.
- User wallet signs only exact, current, simulated prepared intents.
- Portfolio changes require transaction/workflow
final_successand canonical position reread. - Partner revenue never alters or obscures customer position accounting.
- Stale, unavailable, replay, reorg, fee-change, and redemption tests pass on Sepolia.
- Private Preview labels and no-guarantee disclosures remain visible.
Run node --test examples/developer-platform/earn-program-reference/test/*.test.mjs, then use the
API reference, SDK reference, and yield accounting guide.