For the complete documentation index, see llms.txt. This page is also available as Markdown.

SDK Reference

Package: @epoch-protocol/epoch-intents-sdk

Main class: EpochIntentSDK

Peer dependency: viem ^2.x


Constructor

new EpochIntentSDK({
  apiBaseUrl: string;      // Epoch allocator URL (no trailing slash)
  walletClient: WalletClient;  // viem wallet client from wagmi or viem
  gaslessDefault?: boolean;  // when true, solveIntent prefers gasless relay on supported chains
  allowGaslessSmartAccount?: boolean;  // opt in local-wallet gasless relay (also overridable per solveIntent)
})

The wallet client must be connected to the source chain where the user's input tokens live.


Core methods

getTaskData(params)

Builds the task type string and intent data object used by quote and solve methods.

Validation: Either tokenInAmount or minTokenOut must be non-zero.

extraDataTypestring and extraData must declare the same keys with no spaces around commas (e.g. uint256 foo,uint256 bar, not uint256 foo, uint256 bar). Witness fields may use EIP-712 types including string (earn marketUid / action, Miden account ids, etc.). The allocator hashes witness data with EIP-712 hashStruct, matching client signing.

See Witness typestrings & Miden bridge for Miden field rules and exported constants.


getIntentQuote(params)

Fetches a quote without executing. Use this to display amounts to the user before signing.

RoutingAndLiquidityOptions (optional) — controls which solver liquidity paths SIO may quote. Mapped server-side to constraint.preferredSolvers. Use the same value in getIntentQuote and solveIntent.

Preset
UX
Behavior

{ preset: "any" }

Best quote (default)

All registered solvers

{ preset: "filler-single-transaction" }

One user transaction; seamless end-to-end execution

Epoch filler treasury only — protocol interactions bundled behind a single signature

{ preset: "external-multi-transactions" }

Multi-transaction flow

External aggregators only

{ preset: "custom"; solvers: [\0x…`] }`

Pin specific solver(s)

Explicit solver address(es)

IntentQuoteResult fields:

Field
Type
Description

success

boolean

Whether quoting succeeded

tokenIn

string

Resolved input amount

tokenOut

string

Resolved output amount

tokenInDecimals

number

Input token decimals

tokenInSymbol

string

Input token symbol

path

array

Execution path

resourceLockRequired

boolean

Whether Compact lock is needed

transactions

array

Transaction preview


solveIntent(params)

Signs and submits the intent for execution. The user will be prompted to sign in their wallet.

When gasless: true on a supported testnet chain, the SDK submits on-chain steps without the user paying gas (relay for local signers with allowGaslessSmartAccount; wallet batching for injected smart wallets). Call convertToSmartAccount({ chainId }) once before the first gasless solve for local private-key wallets. The user still signs authorization and sponsor data. See Gasless Deposits.

Execution status phases (via onExecutionStatus):

Phase
Meaning

starting

Execution began

switching-chain

Prompting wallet chain switch

preparing-transaction

Simulating transaction

waiting-for-transaction

Retrying simulation

sending

Submitting transaction

sent

Transaction submitted; hash available


getIntentStatus(userAddress, nonce)

Polls execution progress.

Each entry includes status, transactionHash, and chainId per step.

Recommended polling interval: 3 seconds until all steps report completion.


retryIntentSolve(...)

Retries a failed intent solve. Contact Epoch for guidance on when retries are safe.


getHealthCheck()

Checks Epoch service availability.


Available for partner integrations using The Compact:

Method
Purpose

getDepositedBalances(account, tokens)

Query locked balances

withdrawToken(...)

Withdraw deposited tokens

initateDepositWithdrawal(id)

Initiate forced withdrawal

disableForcedWithdrawal(id)

Disable forced withdrawal

getForcedWithdrawalStatus(id)

Check withdrawal status

buildResourceLockCalls(params)

Build (not send) the Compact leg — returns { calls: [approve, depositERC20AndRegister], createAllocationRequest } for you to batch

submitAllocation(createAllocationRequest)

Start solving after the deposit+register lands on-chain (no off-chain sponsor signature — isRegisteredOnchain: true)

Contact Epoch before exposing Compact flows to end users. buildResourceLockCalls / submitAllocation are the build-don't-send split used by Smart Withdraw; confirm your SDK build exposes them (typeof sdk.buildResourceLockCalls === 'function') before relying on them.


Gasless methods (testnet)

Available when using a gasless-enabled allocator (GET /gasless-statusenabled: true).

Method
Purpose

getWalletGaslessStatus(chainId)

Probe delegation state, relay eligibility, accountType, setup needed

convertToSmartAccount({ chainId })

One-time smart-account enable for local signers (testnet)

setupSmartAccount({ chainId })

Legacy alias for smart-account enable

ensureGaslessReady({ chainId, allowSetup? })

Verify readiness; when allowSetup: false, does not auto-convert

setupGaslessWallet({ chainId })

Alias for smart-account setup

gaslessDepositToCompact(...)

Standalone relayed deposit (without full solve)

revokeGaslessWallet({ chainId })

Revoke smart-account delegation

Config / solve params

Field
Purpose

allowGaslessSmartAccount?: boolean

Opt in local-wallet gasless relay (config + solveIntent)

gasless?: boolean

Use relay when eligible; with allowGaslessSmartAccount, throws instead of wallet fallback

Exported helpers (also available from package root):

Local-wallet end-to-end test: smallocator/sdk/test/local-wallet-gasless.ts — run with pnpm example:local-wallet. See Gasless Deposits and Transaction Batching & EIP-7702.


Transaction batching (EIP-5792)

When multiple on-chain calls run on the same chain (Compact approve + deposit, or multi-tx intent execution), the SDK may batch them via wallet_sendCalls instead of separate eth_sendTransaction calls.

Strategy probe:

mode

Meaning

atomic

Smart wallet active (7702 delegation or EIP-5792 atomic enabled) — one prompt, atomic batch

sequential-tx

Plain EOA or local wallet — separate transactions

Local private-key wallets always use sequential-tx for deposits unless the gasless relay path is enabled. Injected wallets with an active smart account batch approve + deposit automatically inside depositToCompact and solveIntent.

Execution status: multi-leg batched flows report phase: "batching" via onExecutionStatus.

Full architecture, SIO relay flow, and test commands: Transaction Batching & EIP-7702.


Witness typestrings & Miden bridge

getTaskData assembles a full taskTypeString (core intent fields + your extraDataTypestring). The allocator, SIO, and compact validation all receive that same witnessTypeString alongside intentData.

Canonical extra suffixes

Import from @epoch-protocol/epoch-intents-sdk (re-exported from @epoch-protocol/epoch-commons-sdk):

Constant
Value
Use

MIDEN_TO_EVM_EXTRA_TYPESTRING

string midenSourceAccount,string midenFaucetId,string midenNoteType,string midenNoteId

Miden → EVM bridge collateral

EVM_TO_MIDEN_EXTRA_TYPESTRING

string midenRecipientAccount,string midenFaucetId

EVM → Miden delivery

DEPOSIT_EXTRADATA_TYPESTRING

string marketUid,string action,string payAsset,bool isAll

Earn / lending deposit

WITHDRAW_EXTRADATA_TYPESTRING

string marketUid,string action,string payAsset,bool isAll

Earn / lending withdraw

Compose lending + Miden by concatenating suffixes — protocol fields and Miden fields may appear in any order:

Miden field inclusion (not exact suffix matching)

For Miden bridge intents, the witness must declare and include the required Miden fields for the detected direction. Additional protocol fields (earn marketUid, etc.) are allowed before or after the Miden block.

Direction

Required in extraDataTypestring + extraData

Direction signal

Miden → EVM

midenSourceAccount, midenFaucetId, midenNoteType, midenNoteId

midenSourceAccount set

EVM → Miden

midenRecipientAccount, midenFaucetId

midenRecipientAccount set and midenSourceAccount absent

Do not set both midenSourceAccount and midenRecipientAccount on the same intent.

Shared Miden helpers

Also exported from the SDK for client-side checks:

The allocator uses the same helpers from epoch-commons-sdk when routing Miden intents through quote, compact validation, and SIO.


Task types

Import from @epoch-protocol/epoch-commons-sdk:


Smart Withdraw (headless)

Smart Withdraw = redeem a lending position and deliver the proceeds to a different chain/token, or to a Miden account, instead of the underlying on its native chain. It is not one intent — you compose two, then fuse them into a single EIP-5792 batch executed over a Compact resource lock. The widget does all of this for you in mode="earn"; this recipe is for headless integrations that build their own UI.

Functions used, in order:

Step
SDK function(s)
Purpose

1

getTaskData + getIntentQuoteTaskType.ProtocolInteraction

Quote the withdraw leg → returns raw withdraw(token, amount) calldata in transactions[] (resourceLockRequired: false, a direct user tx)

2

getTaskData + getIntentQuoteTaskType.GetTokenOut

Quote the swap/bridge leg with a minTokenOut slippage floor (resourceLockRequired: true, solver-executed over the lock)

3

buildResourceLockCalls(...)

Build the Compact leg → { calls: [approve, depositERC20AndRegister], createAllocationRequest }

4

resolveWalletBatchStrategy + executeWalletBatch

Fuse [...withdrawTxs, ...lockCalls] into one wallet_sendCalls (1 prompt), or fall back to sequential txs (N prompts)

5

submitAllocation(createAllocationRequest)

After the batch lands on-chain, start solving

6

getIntentStatus(user, nonce)

Poll to settlement

Order matters: the withdraw must fund the wallet before depositERC20AndRegister runs. In one atomic wallet_sendCalls this holds by construction; in the sequential-tx fallback you must await each receipt (as above). Only call submitAllocation after the batch lands — never submit an allocation for a batch that didn't execute.

Miden destination. For EVM→Miden, build the leg-2 GetTokenOut like the Miden → EVM Lending bridge shape — the EVM output slot is the zero sentinel and the real target rides in extraData:

Omitting midenSourceAccount is what flags the EVM→Miden direction to the allocator. You may append additional declared fields after the canonical Miden suffix when needed.

Availability. Everything except buildResourceLockCalls / submitAllocation is in the standard SDK. Those two are the resource-lock build-don't-send helpers (see Compact-related methods); confirm your @epoch-protocol/epoch-intents-sdk build exposes them before shipping, and contact Epoch to enable Compact resource-lock flows.


What the SDK handles internally

You do not need to implement these steps manually when using the SDK:

Internal step
Handled by

Nonce retrieval

SDK during solve flow

Intent signing

SDK via walletClient

Compact data assembly

SDK during quote/solve

Transaction simulation retries

SDK during solveIntent


Next steps

Last updated