Crypto lending protocols
List Torq vaults natively inside an existing lending protocol while reusing its connected wallet and preserving Torq-specific execution semantics.
Add institutional tokenized-credit opportunities to an existing crypto lending protocol without rebuilding its application shell, wallet connection, portfolio, or transaction review experience. A Torq vault can appear as a native vault card and detail page; the underlying data and execution remain explicitly Torq-bound.
Developer Preview. This is an integration architecture, not a claim that Torq is currently listed by or affiliated with any named third-party protocol. Applications, credentials, wrapper routes, SDK packages, Sepolia access, and production admission remain controlled.
Protocol-native Torq Earn
Native vault listing, existing wallet, Torq execution truth
Render Torq vaults inside the host protocol catalog and design system.
Read the wallet already connected to the host protocol.
Prepare Torq-specific deposit or redemption transactions.
Wait for final_success and refresh the native portfolio.
Native opportunity cards, vault detail, and portfolio views.
Canonical vault, market, allocation, liquidity, and eligibility data.
EIP-1193 account and chain revalidation without a second connection flow.
Exact Torq intents, receipt registration, and canonical completion.
What you will build
- A native vault listing inside the host protocol's existing opportunity catalog.
- Torq-backed vault detail with asset, market, allocation, liquidity, fee, activity, risk, eligibility, and share-mobility data.
- A wallet bridge that adopts the already-connected wallet through the host EIP-1193 provider.
- Torq-specific deposit and redemption review, preparation, simulation, signing, and completion.
- One portfolio experience that reconciles Torq positions beside the host protocol's positions.
- A durable recovery path for reloads, rejected signatures, transaction replacement, reorgs, and delayed redemption completion.
The already-connected wallet remains the customer-controlled signer. Torq never receives its private key, and this integration never opens a competing wallet connection flow.
The native-integration boundary
The user should experience one application and one wallet, but the implementation must keep each source of truth explicit:
| Concern | Owner |
|---|---|
| Navigation, design system, account connection, transaction modal | Host lending protocol |
| Vault, market, allocation, liquidity, fee, eligibility, and position truth | Torq API canonical resources |
| Exact target, calldata, value, ordering, expiry, and postcondition | Torq typed workflow |
| Consent, simulation, transaction signature, and submission | Already-connected wallet |
| Product-visible completion | Torq transaction and workflow final_success, followed by resource reread |
This is not an ERC-4626 equivalence claim. Do not call a Torq wrapper as if it were an arbitrary
host-protocol vault or assume synchronous deposit, withdraw, redeem, preview, liquidity, or
share-price behavior. Adapt the native UI to Torq's documented resources and typed workflows.
An interface such as Morpho's public vault catalog is a useful illustration of the desired native product experience. Morpho's official developer documentation also separates vault data, SDK transaction construction, connected-account execution, and vault mechanics. Torq uses the same quality bar for native integration while retaining Torq-specific resource and completion contracts.
Prerequisites
- A Torq Developer Preview organization, approved application, allowed origin, Sepolia access, publishable key, partner wrapper, and investor workflow scopes.
- The host protocol's current wallet connector, EIP-1193 provider, active account, and chain state.
- A stable mapping between host opportunity IDs and Torq asset, market, vault, fund, wrapper, and deployment-namespace identifiers.
- Product review for institutional eligibility, disclosures, fees, liquidity, redemption timing, share mobility, and jurisdiction restrictions.
- A server-side signed-event inbox if the host must resume workflows after a browser closes.
Do not ship a Torq secret key or webhook secret to the browser. The browser uses an exact origin-bound publishable key plus a short-lived wallet session created from the current host wallet.
Project files
Start with the checked-in, dependency-free implementation:
examples/developer-platform/earn-program-reference/
├── src/catalog.mjs # canonical deep product loader
├── src/connected-wallet.mjs # existing EIP-1193 wallet and drift checks
├── src/torq-api.mjs # API and scoped wallet-session client
├── src/workflows.mjs # prepare, intent binding, submit, final_success
├── src/webhooks.mjs # exact raw-body event verification
├── src/use-cases.mjs # crypto-lending-protocol boundary profile
└── test/reference.test.mjs # wallet, request, workflow, and event regressionsMap it into the host codebase without replacing the host wallet stack:
src/features/earn/torq/catalog.ts # Torq resource queries and native view models
src/features/earn/torq/vault-detail.ts # deep vault, market, allocation, liquidity data
src/features/earn/torq/wallet-adapter.ts # adapter around the active host connector
src/features/earn/torq/session.ts # scoped Torq challenge signed by that wallet
src/features/earn/torq/workflow.ts # typed deposit/redeem orchestration
src/features/earn/torq/portfolio.ts # Torq position reconciliation
src/features/earn/torq/components/ # host-native cards, detail, review, and status
server/torq/event-inbox.ts # signed delivery verification and deduplication
server/torq/reconcile.ts # canonical affected-resource rereadsComplete data contract
Never substitute one generic object for these resources. Each native field must map to the exact schema in the linked API operation, including freshness and availability evidence.
| Native surface | Operations |
|---|---|
| Opportunity catalog | GET /v1/assets, GET /v1/markets, GET /v1/vaults, GET /v1/tranches, GET /v1/funds |
| Product identity | 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/vaults/{resourceId}/activity |
| Transfer and redemption | GET /v1/vaults/{resourceId}/share-mobility, GET /v1/eligibility |
| Wallet portfolio | GET /v1/positions, GET /v1/activity |
| Economics and routing | GET /v1/fees, GET /v1/partner-programs, GET /v1/wrappers |
| Workflow execution | POST /v1/workflows/prepare, POST /v1/workflows/{requestId}/transactions, GET /v1/workflows/{requestId} |
The Torq API is canonical for Torq product-visible state. RPC is limited to connected-wallet identity, signing-time simulation, transaction submission, and receipt observation. Do not rebuild allocations, liquidity, eligibility, APY, positions, or completion from raw RPC reads.
Complete credit lifecycle
Make the native Torq listing follow the complete credit lifecycle inside the host protocol:
| Customer moment | Crypto-lending-protocol implementation |
|---|---|
| Deposit and tranche selection | Render the Torq share class and wrapper behavior explicitly, then use the already-connected wallet for the exact prepared deposit. |
| Position, yield, and liquidity | Merge server GraphQL vaultHolderPerformanceCurrent, vault detail, allocations, GET /v1/vaults/{resourceId}/liquidity, and activity into the host portfolio without translating them into incompatible host semantics; keep GET /v1/positions as separate market-position context. |
| Redemption and claimable cash | Keep Torq immediate, queued, blocked, and claimable states distinct from a host protocol's standard withdraw or redeem state. |
| Impairment monitoring | Attach GET /v1/liquidation-recovery, GET /v1/vaults/{resourceId}/activity, and durable GET /v1/events to the same native vault listing and wallet position. |
| Recovery center | Present GET /v1/funds, GET /v1/funds/{resourceId}, GET /v1/funds/{resourceId}/holdings, and secret-key POST /graphql in the host position detail. |
| Distressed-fund decision | Use the same connected wallet but create a separate capital allocation. The affected Torq position does not automatically make the wallet eligible, compensate it, or grant a fund claim. |
| Customer action | Require explicit customer approval after revalidating account and chain. If no approved Preview executor exists, show capability_not_ready and never fall back to raw calldata. |
| Final reconciliation | Keep Torq vault and optional fund exposure as separate native portfolio records, each driven by canonical Torq state. |
This is where a native integration becomes more than another vault listing: the user stays inside the host protocol from deposit through stress, optional recovery participation, proceeds, and claims, while the already-connected wallet remains the only signer.
Build the integration
1. Register Torq as a native product source
Add torq to the host catalog's source discriminator. Persist Torq IDs separately from contract
addresses so links remain stable across deployments. Route a Torq card to the same host vault shell,
but load its model through loadEarnProduct() and Torq resource routes.
Recommended native card fields are product name, underlying asset, vault strategy, current availability, displayed yield fields with their documented basis, liquidity, principal or risk disclosures, fee summary, and freshness. Omit unsupported fields instead of estimating them.
2. Adopt the wallet already connected to the host
Pass the provider from the active host connector into the reference adapter. Read only the current account and chain; do not initiate a new connection modal.
import {
createExistingConnectedWalletSigner,
readExistingConnectedWallet,
} from './src/connected-wallet.mjs';
const walletAtOpen = await readExistingConnectedWallet(hostEip1193Provider);
const torqSigner = createExistingConnectedWalletSigner({
provider: hostEip1193Provider,
expected: walletAtOpen,
});readExistingConnectedWallet() calls eth_accounts and eth_chainId. If the host has no active
account, return to its existing connect control. Never render another wallet selector inside Torq.
3. Cancel work when account or network changes
Subscribe to the host connector's accountsChanged and chainChanged signals. On either event:
- abort in-flight Torq resource requests;
- clear the wallet session from memory;
- discard the prepared workflow and unsubmitted transaction plan;
- reset eligibility and position queries to the new account and chain;
- require a fresh proposal and explicit review.
Also reread eth_accounts and eth_chainId immediately before simulation and again before
submission. The reference signer performs this check and refuses account or chain drift.
4. Create a scoped Torq session with that same wallet
Request POST /v1/wallet-sessions/challenges for walletAtOpen.address and
walletAtOpen.chainId. Validate application, API origin, chain, wallet, purpose, challenge ID,
nonce, and expiry before asking the host connector's existing sign-message action to sign. Confirm
through POST /v1/wallet-sessions/confirm and keep the short-lived token only in memory.
This adds Torq API authority to the current wallet session; it does not create a second wallet connection or authorize an onchain transaction.
5. Render a native Torq vault detail
Use the host protocol's card, tabs, number formatting, token icons, chart containers, and transaction review components. Map every displayed value to the Torq schema:
| Host tab | Torq content |
|---|---|
| Overview | vault identity, asset, terms, availability, fees, freshness, limitations |
| Markets | attached markets, borrower exposure, allocation amount and limit |
| Liquidity | liquid capacity, redemption-relevant state, and freshness |
| Performance | documented vault/accounting history only; no locally inferred return |
| Risk | asset, market, lifecycle, permission, dependency, and redemption disclosures |
| Your position | connected-wallet position, activity, eligibility, and pending workflows |
Refetch deep data when the selected vault, connected address, chain, or deployment namespace changes. Never reuse a prior wallet's position or eligibility response.
6. Model deposit and redemption explicitly
For a deposit, propose role.investor.partnerWrapperDeposit with:
{
workflowType: 'role.investor.partnerWrapperDeposit',
chainId: walletAtOpen.chainId,
walletAddress: walletAtOpen.address,
deploymentNamespace,
input: {
wrapperAddress,
assetAddress,
assets: amountInBaseUnits,
receiver: walletAtOpen.address,
includeApproval: true,
},
}For a redemption, propose role.investor.partnerWrapperRedeem with wrapper address, share amount,
receiver, wallet, chain, and namespace. Torq may return a redemption-request transaction rather than
an immediate asset withdrawal. Render the returned lifecycle and canonical resources instead of
forcing the host protocol's standard synchronous redeem state.
7. Prepare and show the exact Torq transaction plan
Call POST /v1/workflows/prepare with a stable idempotency key. Require preflight passed. Bind and
display the returned request ID, snapshot hash, expiry, transaction order, target, calldata summary,
value, simulation requirement, approval step, and blocked reasons.
The human review may look native, but it must disclose that the transaction uses a Torq wrapper and must not relabel a queued redemption as an immediate withdrawal.
8. Revalidate the host wallet before every signature
Immediately before simulation and submission, call assertConnectedWalletUnchanged() or use the
reference signer. If address or chain differs from the preparation snapshot, discard the prepared
workflow. Do not silently change the receiver or reuse the old request.
9. Simulate, submit, and register
Simulate every required intent, then pass only its exact to, data, and value to the host wallet
transaction flow. Submit in declared order. Register each returned hash through
POST /v1/workflows/{requestId}/transactions with the transaction order and chain ID. Never accept
caller-authored target or calldata at this boundary.
10. Wait for canonical completion
Keep the native position pending while a wallet receipt is merely submitted, mined, or confirmed.
Poll GET /v1/workflows/{requestId} and its transaction resource until Torq returns
final_success. Then reread position, activity, vault, allocation, and liquidity resources before
updating the host portfolio.
If the browser closes, resume by request ID from the host's local order record or server event inbox. Signed events are notification pointers: verify, deduplicate, persist, and reread canonical state.
Native state mapping
| Torq state | Host protocol treatment |
|---|---|
| Product resource stale or capability unavailable | Keep card readable; disable action with exact reason |
| Ineligible connected wallet | Show the governed reason; no prepare request |
prepared | Show exact Torq plan, expiry, wallet, and network |
| Awaiting signature | Use the host's existing transaction modal |
| Submitted or mined | Show pending; do not increase available balance |
| Redemption requested | Show request lifecycle, not completed withdrawal |
final_success | Reread Torq resources and merge the resulting position into portfolio |
| Failed or reorged | Keep balances unchanged and show safe retry or support path |
Test the complete journey
Run:
node --test examples/developer-platform/earn-program-reference/test/*.test.mjsThen verify on Sepolia:
- opening Torq from an already-connected account never shows a second connection dialog;
- no connected account fails closed through the host's existing wallet control;
- account or chain changes during catalog load, eligibility, preparation, review, and signing cancel stale work and cannot submit it;
- native cards display exact Torq vault, allocation, liquidity, fee, and freshness schemas;
- approval plus deposit succeeds in declared order and appears only after
final_success; - redemption displays its Torq-specific request lifecycle and never promises immediate liquidity;
- rejected signatures, failed simulations, replaced transactions, duplicate registrations, reloads, webhook replays, delayed events, and reorgs preserve correct balances;
- switching between a native host vault and Torq vault does not leak state, signer, cache keys, or pending requests across product sources.
Production checklist
- Torq vaults look native but are visibly identified as Torq-backed products.
- Every displayed field maps to an exact Torq API schema and freshness contract.
- The integration uses only the already-connected wallet and the host transaction UI.
- Account, chain, vault, and deployment namespace are revalidated at every async boundary.
- Wallet or network drift discards prepared workflows and unsubmitted intents.
- Torq deposit and redemption semantics are documented instead of coerced into host assumptions.
- Exact target, calldata, value, order, expiry, and simulation results are reviewed before signing.
- Positions change only after transaction and workflow
final_successplus canonical reread. - Events are verified and deduplicated; events and receipts alone never credit a position.
- Origin restrictions, CSP, no-secret browser rules, telemetry redaction, and support evidence pass review.
- End-to-end tests cover reload, reject, retry, replacement, stale data, reorg, and delayed redemption.
- Developer Preview labels and the absence of third-party partnership claims remain explicit.
Continue with the wallet provider playbook, typed workflows, canonical state, API reference, and SDK reference.