Docs

Typed workflows

Prepare explicit Torq actions without exposing an arbitrary contract-call API.

Use POST /v1/workflows/prepare with a documented workflowType. Torq does not accept arbitrary targets, ABIs, function names, or calldata as workflow input.

{
  "workflowType": "borrow",
  "chainId": 11155111,
  "input": {
    "marketAddress": "0x...",
    "amount": "1000000"
  },
  "constraints": {
    "maxFreshnessLagSeconds": 60,
    "requireExecutable": true
  }
}

Register each externally submitted transaction in order:

POST /v1/workflows/{requestId}/transactions
Idempotency-Key: a-stable-operation-key

{"order":0,"chainId":11155111,"txHash":"0x..."}

Borrower, lender, liquidator, NAV reporter, partner distribution, and the explicitly listed vault-owner actions have maintained adapters in private preview. Other approved-role actions remain unavailable until their canonical server-side planners and authority proofs are complete. They return capability_not_ready; they never fall back to caller-supplied calldata.

Submit an Asset Issuer request

role.asset_issuer.assetSubmissionRequestCreate is a metadata-only, canonical Postgres workflow. It requires an authenticated wallet session with the current active Asset Issuer MANAGE_ISSUER_ASSET_POLICY authority. Torq never asks a wallet to sign a transaction for this step and never accepts a caller-supplied submitterWallet value.

{
  "workflowType": "role.asset_issuer.assetSubmissionRequestCreate",
  "chainId": 11155111,
  "input": {
    "assetIssuerId": "issuer_alpha",
    "assetSymbol": "TQF",
    "assetName": "Torq Fund",
    "tokenAddress": "0x...",
    "assetMetadata": {
      "topCategory": "private_credit",
      "subcategory": "distressed_debt"
    },
    "pricingType": "live-feed",
    "preferredAssetManagerId": "manager_alpha",
    "approvedAssetManagerIds": ["manager_alpha"]
  }
}

For a signed-nav submission, provide at least one requestedReporterId instead of routing the request through an Asset Manager. A successful response has executionMode: "metadata_only", no transactions, and status: "final_success" only after the request is visible in the canonical submission queue. The corresponding event is workflow.assetSubmissionRequestCreate.updated.

Sign and submit a NAV report

role.nav_reporter.navReportSignAndSubmit prepares a signed active-V2 NAV or price-report action for a currently allowlisted signer that is canonically bound to the oracle's NAV reporter entity. The request is always derived from the canonical Postgres projection: oracle address, reporter binding, signer allowlist, nonce, pending-report state, base-asset supply, and freshness. It never accepts caller-supplied calldata, a nonce, a supply value, or a reusable signature.

{
  "workflowType": "role.nav_reporter.navReportSignAndSubmit",
  "chainId": 11155111,
  "input": {
    "oracleAddress": "0x...",
    "assetSymbol": "TQF",
    "reportType": "nav",
    "answer": "123450000",
    "startedAt": "1784937480",
    "updatedAt": "1784937540",
    "deadline": "1784937700"
  }
}

All numeric values are base-10 strings; timestamps are Unix seconds. A price report additionally requires reportDecimals and isFinal; it may include revisionOfRoundId and revisionNumber. Torq supplies the canonical quote asset and uses a zero NAV-supply field for price reports, as required by the active V2 contract.

The prepared transaction includes an eip712_signed_nav_submit instruction. The TypeScript SDK calls the customer-owned signTypedData callback locally, compacts the local signature into the transaction calldata, simulates that exact calldata, and submits it through the customer-owned signer. Torq never receives, stores, transmits, or logs that signature. A signer without EIP-712 support fails before simulation or submission.

Before the transaction hash can be registered, Torq rereads canonical signer authority, nonce, pending-report state, and freshness. final_success for this signer action requires the exact ReportApprovalRecorded receipt event and canonical readback after the receipt. A partial quorum therefore completes the submitted approval, but does not claim that the report is scheduled or activated; subsequent approved signers create separately tracked approvals.

Update vault deposit caps

role.vault_owner.vaultCuratorCapsSettingsSave prepares the existing active-V2 setMinDeposit(uint256) and setCaps(uint256,uint256) calls:

{
  "workflowType": "role.vault_owner.vaultCuratorCapsSettingsSave",
  "chainId": 11155111,
  "input": {
    "vaultAddress": "0x...",
    "minDeposit": "1000000",
    "vaultCap": "1000000000",
    "accountCap": "100000000"
  }
}

All amounts are base-10 strings in the vault asset's smallest unit. Torq rereads the current Postgres-backed vault state and current onchain owner at preparation and execution. It derives which calls are necessary; unchanged requests are blocked as no-ops.

When both calls are needed, the SDK waits for the minimum-deposit transaction to reach canonical final_success before it revalidates and sends the caps transaction. Completion requires the exact tracked receipt events and a healthy Postgres snapshot at or after the receipt block with all three requested values visible.

Update a vault allocator

role.vault_owner.vaultAllocatorUpdate prepares the active-V2 setAllocator(address,bool) call:

{
  "workflowType": "role.vault_owner.vaultAllocatorUpdate",
  "chainId": 11155111,
  "input": {
    "vaultAddress": "0x...",
    "allocators": ["0x..."]
  }
}

Use an empty allocators array to disable the current allocator. Active V2 permits at most one enabled allocator, so requests with multiple addresses fail closed. The current vault owner is the only authorized signer; an enabled allocator cannot assign or remove itself.

Preparation fails closed with deployment_bytecode_not_attested unless the target vault has an exact governed chain, namespace, address, runtime-code hash, block proof, and evidence-manifest attestation for AllocatorUpdated(address,bool). Torq then reads the Postgres-backed vault owner, allocator, and freshness evidence, and the SDK refreshes the prepared workflow immediately before asking the external wallet to sign. Once a transaction has been submitted, Torq accepts its hash for tracking even if that transaction's own allocator postcondition is already visible; it never strands an external write by mistaking its result for pre-signing drift.

Torq never relays the production transaction or receives signer secrets. final_success requires a post-preparation receipt from the prepared owner to the prepared vault, the exact three-topic AllocatorUpdated(address,bool) event arguments, and a healthy canonical readback at or after the receipt block.

Manage the active-V2 vault lifecycle

The following owner and allocator workflows are available in private preview:

  • role.vault_owner.vaultCuratorFeeSettingsSave
  • role.vault_owner.vaultManagementSettingsSave
  • role.vault_owner.vaultOwnerSettingsSave
  • role.vault_owner.vaultOwnerTransferUpdate
  • role.vault_owner.vaultReallocationBatch
  • role.vault_owner.vaultRoleSettingsSave
  • role.vault_owner.vaultRoutingUpdate
  • role.vault_owner.vaultSettingsUpdate
  • role.allocator.vaultReallocationBatch

Each request is rebuilt from the current canonical vault snapshot. The API returns only the exact active-V2 calls needed to reach the requested state, in execution order, and requires client-side simulation before an external signer submits them. Required predecessor calls must reach canonical final_success before a later call can be registered.

vaultOwnerTransferUpdate is a direct active-V2 ownership transfer despite the legacy pendingOwner request-field name. Active V2 has no pending-owner acceptance selector, so role.vault_pending_owner.vaultPendingOwnerAccept is absent from the REST contract and every SDK; it must not be integrated.

vaultSettingsUpdate includes the owner-only setMinDeposit and setCaps calls. Use role.vault_owner.vaultSettingsUpdate; the mixed curator workflow is intentionally absent until a separate, authority-bounded curator-only settings action has its own active-V2 and canonical proof.

List a market for a vault

role.curator.vaultMarketListingSave is available in private preview for the exact active-V2 market-listing sequence. The authenticated wallet must be the current vault owner or curator. The API reads the vault, market, registry, supply-access, authority, and indexer-freshness state from canonical Postgres before preparing any call.

Provide a complete config matching the active-V2 VaultMarketConfig tuple. When necessary, the ordered transaction intents are: registry attachVaultToMarket, selected-vault market setSupplyAccess(vault,true), and vault attachMarket. A selected-supply market additionally requires the same wallet to be its current creator or access manager. The workflow refuses stale state, an unregistered supply vault, an asset mismatch, a pre-existing attachment, or missing authority.

Each predecessor must reach canonical final_success before the next transaction is registered. Torq verifies the exact VaultMarketAttached or MarketSupplyAccessSet receipt evidence and the corresponding canonical readback; it never treats mined status as completion and never relays or receives the external signer secret.

vaultMarketApprovalUpdate, vaultMarketConfigSave, vaultMarketAllocationToggle, and vaultResellerManagerUpdate are also absent for the curator role. Their current active-V2 selectors require the vault owner or guardian. A future SDK workflow must name and prove that exact actor; it cannot relabel the authority as curator.

partnerManagerBootstrap deploys or attaches a manager through the vault's owner-only reseller manager write. It is intentionally absent for both curator and vault_manager; it must not be integrated until an owner-scoped workflow has complete API and canonical-finality proof.

createSharedMarket and pairOracleCreate are not public Developer Platform capabilities. They are intentionally absent from the external workflow union and must never be reconstructed through a contract factory, unpublished route, or caller-selected authority.

For reserve operations, each allocation or deallocation has its own transaction intent. A completed intent needs the matching CapacityAllocated or CapacityDeallocated receipt event and a healthy Postgres snapshot at or after its receipt block. Other lifecycle controls finish only after their requested owner, curator, allocator, fee, routing, tranche-policy, or cap value is visible in the canonical read model.

On this page