Skip to main content

buildComposable

Build a composable instruction with support for runtime injection, conditions, and automatic encoding.
const instruction = await account.buildComposable(options);

Instruction Types

TypeDescription
defaultGeneric contract call
transferERC-20 token transfer
approveERC-20 approval
nativeTokenTransferNative token (ETH) transfer

Default Type

Call any contract function.
const instruction = await account.buildComposable({
  type: "default",
  data: {
    chainId: number;
    to: Address;
    abi: Abi;
    functionName: string;
    args: any[];
    value?: bigint;
    gasLimit?: bigint;
    conditions?: Condition[];
  }
});

Parameters

ParameterTypeRequiredDescription
chainIdnumberYesTarget chain
toAddressYesContract address
abiAbiYesContract ABI
functionNamestringYesFunction to call
argsany[]YesFunction arguments
valuebigintNoNative value to send
gasLimitbigintNoCustom gas limit
conditionsCondition[]NoExecution conditions

Example

const swap = await account.buildComposable({
  type: "default",
  data: {
    chainId: 8453,
    to: UNISWAP_ROUTER,
    abi: UniswapAbi,
    functionName: "exactInputSingle",
    args: [{
      tokenIn: USDC,
      tokenOut: WETH,
      amountIn: parseUnits("100", 6),
      amountOutMinimum: 0n,
      recipient: account.addressOn(8453, true),
      fee: 500,
      sqrtPriceLimitX96: 0n
    }]
  }
});

Transfer Type

Simplified ERC-20 token transfer.
const instruction = await account.buildComposable({
  type: "transfer",
  data: {
    chainId: number;
    tokenAddress: Address;
    recipient: Address;
    amount: bigint | RuntimeValue;
    conditions?: Condition[];
  }
});

Example

const transfer = await account.buildComposable({
  type: "transfer",
  data: {
    chainId: 8453,
    tokenAddress: USDC,
    recipient: "0x...",
    amount: parseUnits("50", 6)
  }
});

Approve Type

Simplified ERC-20 approval.
const instruction = await account.buildComposable({
  type: "approve",
  data: {
    chainId: number;
    tokenAddress: Address;
    spender: Address;
    amount: bigint | RuntimeValue;
  }
});

Example

const approve = await account.buildComposable({
  type: "approve",
  data: {
    chainId: 8453,
    tokenAddress: USDC,
    spender: UNISWAP_ROUTER,
    amount: parseUnits("100", 6)
  }
});

Native Token Transfer

Send ETH or native tokens.
const instruction = await account.buildComposable({
  type: "nativeTokenTransfer",
  data: {
    chainId: number;
    to: Address;
    value: bigint | RuntimeValue;
  }
});

Example

const sendEth = await account.buildComposable({
  type: "nativeTokenTransfer",
  data: {
    chainId: 8453,
    to: "0x...",
    value: parseEther("0.1")
  }
});

Bridge Operations

To bridge tokens (e.g. via Across Protocol), use type: "default" and encode the bridge protocol’s contract call directly. See the Across integration guide for a complete example.
const bridge = await account.buildComposable({
  type: "default",
  data: {
    chainId: 42161,                               // Source chain
    to: ACROSS_SPOKE_POOL,                         // Bridge contract
    abi: acrossSpokePoolAbi,                       // Bridge ABI
    functionName: "depositV3",
    args: [
      account.addressOn(42161, true),              // depositor
      account.addressOn(8453, true),               // recipient
      USDC_ARBITRUM,                               // inputToken
      USDC_BASE,                                   // outputToken
      parseUnits("100", 6),                        // inputAmount
      outputAmount,                                // outputAmount (from bridge quote API)
      8453,                                        // destinationChainId
      zeroAddress,                                 // exclusiveRelayer
      quoteTimestamp,                              // quoteTimestamp
      fillDeadline,                                // fillDeadline
      0,                                           // exclusivityDeadline
      "0x"                                         // message
    ]
  }
});
Bridge operations use the same type: "default" as any other contract call. Get bridge parameters (output amount, timestamps, deadlines) from the bridge protocol’s quote API before building the instruction.

build (Simple)

Build a simple instruction without composability.
const instruction = await account.build({
  type: "nativeTokenTransfer",
  data: {
    chainId: 8453,
    to: "0x...",
    value: 1n,
    lowerBoundTimestamp: Math.floor(Date.now() / 1000),
    upperBoundTimestamp: Math.floor(Date.now() / 1000) + 300
  }
});

Time Bounds

Add time constraints to instructions:
const instruction = await account.buildComposable({
  type: "default",
  data: {
    chainId: 8453,
    to: "0x...",
    abi: [...],
    functionName: "doSomething",
    args: [],
    lowerBoundTimestamp: Math.floor(Date.now() / 1000) + 60,  // Start in 1 min
    upperBoundTimestamp: Math.floor(Date.now() / 1000) + 300  // Expire in 5 min
  }
});
ParameterDescription
lowerBoundTimestampEarliest execution time (unix seconds)
upperBoundTimestampLatest execution time (unix seconds)