Complete credit lifecycle
Build one Torq Earn experience from product discovery and vault deposit through impairment, optional distressed-fund participation, recovery proceeds, and final reconciliation.
An institutional Earn integration should not end at deposit, yield, and redemption. It should keep the customer informed if credit deteriorates, explain what happened to the original position, show the recovery path, and—when a separate opportunity is actually open and the wallet is eligible—let the customer review a Distressed Recovery Fund as a new investment decision.
This guide is the shared lifecycle contract for every Torq use case. The audience playbooks explain who owns each service, signer, ledger, and customer surface.
Developer Preview. Public recovery reads and documentation are available for integration design. Credentials, wallet sessions, server GraphQL, approved packages, and investor fund-action execution remain controlled Preview capabilities. Never replace an unavailable capability with a caller-supplied contract call.
Completion rule
A wallet confirmation is only one step in a completed Torq workflow
User sees what will change and what authority is required.
The required transaction or metadata write is executed.
The affected chain or persisted event is refreshed.
Postgres current-state rows are recomputed.
The workspace rereads persisted truth before showing complete.
The whole customer journey
Institutional Earn lifecycle
One customer experience from opportunity discovery through recovery
Compare current vault, market, allocation, liquidity, fee, and eligibility evidence.
Review the exact product, share class, amount, signer, network, and redemption terms.
Reconcile value, net flow, yield evidence, liquidity, activity, and risk state.
Track immediate or queued redemption through canonical completion and claimable cash.
Keep the original exposure visible through impairment, recovery cash, and claims.
Preserve its vault, market, share class, loss, redemption, recovery-cash, and claim state.
Show current fund terms and eligibility, then require a new amount and explicit approval.
| Stage | What your product must do | Canonical Torq surfaces |
|---|---|---|
| Discover and compare | Show the asset, market, vault, share class or tranche, allocation exposure, liquidity, fees, mobility, activity, and freshness. | GET /v1/assets, GET /v1/markets, GET /v1/vaults, detail and vault subresources |
| Establish wallet access | Bind the current wallet, application, origin, chain, session scopes, eligibility, and signer. | Wallet-session APIs, GET /v1/eligibility, plus GET /v1/positions for wallet market-position context |
| Deposit and tranche selection | Explain the selected share class, amount, wrapper, fees, expected workflow, and redemption behavior before preparation. | POST /v1/workflows/prepare, exact intent review, customer-controlled signer |
| Position, yield, and liquidity monitoring | Reconcile the selected vault holder's current value, net flow, and net gain and show product, liquidity, allocation, and activity evidence without inventing APY or availability. | Server GraphQL vaultHolderPerformanceCurrent, vault detail, allocations, liquidity, activity, signed events |
| Redemption and claimable cash | Present immediate versus queued behavior, request state, claimable cash, and blocked reasons. A wallet receipt is not completion. | Typed redemption workflow, GET /v1/workflows/{requestId}, position and vault reread |
| Impairment and recovery monitoring | Detect a material status change from canonical resources and events; explain liquidation, residual debt, loss, recovery cash, and affected-product state. | GET /v1/liquidation-recovery, vault activity, event stream, server-side recovery GraphQL |
| Distressed-fund decision | If a relevant fund is open, show its quote asset, terms, capacity, eligibility, holdings, fees, pauses, and risks as a separate proposal. | GET /v1/funds, fund detail, holdings, investor recovery GraphQL |
| Separate subscription | Require explicit customer approval of a new amount and exact fund terms. Use only an approved Preview executor for that application. | Approved capability/package; otherwise capability_not_ready |
| Side-pocket and claim tracking | Show idle capital, committed exposure, side-pocket holdings, sales, workout proceeds, quote claims, in-kind claims, pauses, and evidence. | Fund detail and holdings, recovery GraphQL, canonical events |
| Recovery proceeds and final reconciliation | Update the correct customer ledger only after the applicable transaction and canonical fund or vault state agree. | Canonical resource reread, signed event inbox, reconciliation evidence |
Two positions, two decisions
The original vault position and a Distressed Recovery Fund position are economically and operationally separate:
| Original vault exposure | Optional recovery-fund exposure |
|---|---|
| Created by the customer's vault or wrapper deposit. | Created only by a separate subscription to an open fund epoch. |
| Carries the chosen vault, market, share-class, liquidity, and redemption terms. | Carries the selected fund's quote asset, epoch, capacity, eligibility, side-pocket, fee, pause, and claim terms. |
| Can be affected by borrower stress, loss accounting, recovery cash, and redemption constraints. | Can acquire impaired assets and may later realize quote proceeds or make an in-kind distribution. |
| Its recovery state remains on the originating vault path. | Its proceeds belong only to the applicable fund claims. |
An affected position does not automatically make a wallet eligible for a recovery fund, subscribe the wallet, compensate a loss, or create a fund claim. Distressed-fund participation is a separate capital allocation with different risks and requires explicit customer approval.
Build the lifecycle data service
Use the dependency-free reference in
examples/developer-platform/earn-program-reference/src/credit-lifecycle.mjs. Keep browser-safe
wallet reads and secret-key server reads separate:
const lifecycle = await loadCreditLifecycle(walletApi, {
serverApi, // server secret only; never bundle it into the client
walletAddress,
vaultId,
fundId: selectedFundId,
});
renderOriginalVaultExposure(lifecycle.originalVaultExposure);
renderOptionalFundExposure(lifecycle.optionalFundExposure);The loader uses these exact operations:
| Evidence | Operation and placement |
|---|---|
| Wallet market-position context | GET /v1/positions with the wallet session; this is not a substitute for the selected vault holder record |
| Selected vault holder value, net flow, and net gain | POST /graphql with vaultHolderPerformanceCurrent(vaultId, accountAddress) from the server |
| Vault state | GET /v1/vaults/{resourceId} |
| Vault activity | GET /v1/vaults/{resourceId}/activity |
| Exit capacity and terms | GET /v1/vaults/{resourceId}/liquidity |
| Liquidation and residual-debt context | GET /v1/liquidation-recovery |
| Available funds | GET /v1/funds |
| Selected fund terms | GET /v1/funds/{resourceId} |
| Current acquired holdings | GET /v1/funds/{resourceId}/holdings |
| Durable event cursor | GET /v1/events from the server |
| Wallet-specific subscriptions and fund statuses | POST /graphql with distressedRecoverySubscriptions and distressedRecoveryFundInvestorStatuses from the server |
Do not infer that one resource belongs to another from matching names or timing. Preserve the canonical vault, market, position, fund, epoch, side-pocket, wallet, chain, block, and transaction identifiers returned by Torq. When a direct relationship is unavailable, label it unconfirmed.
Detect impairment without alarming customers incorrectly
- Maintain a durable cursor for
GET /v1/eventsor signed webhooks. - On any relevant vault, market, position, liquidation, loss, recovery, or fund event, reread the affected canonical resources.
- Compare identifiers and freshness evidence; do not classify a position from an event name alone.
- Show a plain-language state such as
monitoring,redemption constrained,loss recorded,recovery active, orclaimableonly when the current schema supports it. - Keep deposits and other risk-increasing actions disabled when required evidence is stale, missing, blocked, or contradictory.
APY movement, a failed RPC request, a pending transaction, or a third-party alert is not proof that a Torq position is impaired.
Present the distressed-fund decision
Only present a subscribe action after all of these checks pass:
- The selected fund exists and its
freshness.statusis current. subscriptionStatusisopen.- The wallet-specific canonical eligibility status is
eligible. - The amount is a positive base-unit integer within the current minimum and maximum.
- The customer has reviewed the quote asset, epoch, capacity, idle-redemption rules, acquisition exposure, side-pocket behavior, fees, pauses, claim paths, and lack of guaranteed recovery.
- The customer explicitly approves this new allocation independently of the original vault action.
- The current application has an approved Preview execution capability.
const proposal = buildDistressedFundDecisionReview({
fund: selectedFund,
amount: subscriptionAssets,
explicitlyApproved: customerApprovedSeparateAllocation,
});
if (proposal.executionAvailability !== 'requires_approved_preview_capability') {
throw new Error('Unexpected recovery-fund execution boundary');
}Current execution boundary
The current external typed workflow catalog does not export investor fund subscription, idle redemption, or claim execution. Those actions exist in Torq's investor product, but an external integration must use only the exact executor and package supplied for its approved Developer Preview application.
If that capability is absent:
- keep the recovery center and canonical monitoring experience available;
- show the specific action as unavailable with
capability_not_ready; - provide the Preview access and support route;
- never synthesize target or calldata;
- never copy internal action identifiers into a public client and call them public SDK methods;
- never turn an event, receipt, or raw contract result into customer-visible completion.
This fail-closed boundary is intentionally explicit. It tells an integration exactly what can be built today and prevents an incomplete recovery write path from being disguised as production support.
Reconcile recovery safely
Keep a durable record keyed by customer, wallet, original vault position, optional fund position, fund epoch, side pocket, request, and transaction. Reconciliation should answer these questions independently:
- What is the canonical state of the original vault position and any redemption claim?
- What recovery cash, loss, or claim state is visible for the originating vault path?
- Did the customer separately subscribe to a recovery fund?
- How much fund capital remains idle, committed, claimable in quote, or claimable in kind?
- Are claims paused, expired, already claimed, or still awaiting canonical projection?
- Do the event cursor, current resource rows, and customer ledger agree?
For typed Torq workflows, require transaction and workflow final_success, then reread the affected
resource. For an approved fund-action executor, follow its documented canonical completion rule and
reread the fund investor status before posting any customer balance.
Test the complete journey
Run the reference tests, then exercise these scenarios on the approved Sepolia environment:
- eligible and ineligible wallets;
- Single Share, Senior, and Junior product presentation where configured;
- deposit success, rejection, replacement, duplicate registration, and reorg;
- current yield and liquidity changes without impairment;
- immediate and queued redemption states;
- stale or contradictory recovery evidence;
- an affected position with no available recovery fund;
- a relevant fund that is closed, full, paused, stale, or wallet-ineligible;
- explicit decline of the separate fund allocation;
- fund action requested while the Preview capability is absent;
- approved subscription, idle redemption, quote proceeds, and in-kind claim where the supplied Preview executor supports them;
- reload and cross-device resume from the durable event cursor;
- final reconciliation of the original vault path and the separate fund path.
Ship checklist
- The product explains the complete lifecycle before the first deposit.
- The original vault exposure and optional fund exposure use separate records and approvals.
- No alert, ranking, AI output, event, or APY movement invents an impairment state.
- The customer sees exact terms, risks, signer, network, amount, and availability before action.
- Missing fund eligibility or execution capability fails closed with a stable reason.
- Recovery-fund participation is never described as automatic compensation or guaranteed recovery.
- Every customer balance comes from canonical state, not a wallet receipt alone.
- The integration can resume every pending and recovery state after reload.
Continue with Wallet providers, Crypto lending protocols, Distressed recovery, and the API reference.