Skip to main content

Send Multichain Transactions

Overview

Multichain transactions let you compose multiple universal transactions into a single ordered flow across different routes.

This allows you to submit a single user-signed transaction to Push Chain that coordinates execution across Push Chain, external chains, or both.

Prerequisite: Familiarize yourself with Send Universal Transaction before reading this page.

Mental Model

  1. Prepare each transaction step with prepareTransaction
  2. Execute all steps together with executeTransactions

Prepare Transaction

pushChainClient.universal.prepareTransaction({tx}): Promise<PreparedUniversalTx>

Prepares a transaction without executing it. Returns a PreparedUniversalTx object that you pass to executeTransactions.

const preparedTx = await pushChainClient.universal.prepareTransaction({
to: '0xContractAddress',
value: BigInt(0),
data: PushChain.utils.helpers.encodeTxData({
abi: MyABI,
functionName: 'myFunction',
args: [arg1, arg2],
}),
});
info

PreparedUniversalTx is an intermediate object that you pass to executeTransactions. Most apps do not need to manually inspect or modify its fields.

TheseArgumentsare mandatory

ArgumentsTypeDescription
tx.tostring | { address: string; chain: CHAIN }Target address on Push Chain (plain string), or { address, chain } for an external chain via CEA.
PushChain.CONSTANTS.CHAIN
PushChain.CONSTANTS.CHAIN.PUSH_TESTNETPushChain.CONSTANTS.CHAIN.PUSH_TESTNET_DONUTPushChain.CONSTANTS.CHAIN.ETHEREUM_SEPOLIAPushChain.CONSTANTS.CHAIN.BNB_TESTNETPushChain.CONSTANTS.CHAIN.BASE_SEPOLIAPushChain.CONSTANTS.CHAIN.ARBITRUM_SEPOLIAPushChain.CONSTANTS.CHAIN.SOLANA_DEVNET
tx.from{ chain: CHAIN }Optional. When set, originates from the CEA on that chain.
tx.valueBigIntNative value to send in the smallest unit of the execution context.
tx.datastring | Array<{ to: string; value: bigint; data: string }>Encoded calldata for a single call string or batched multicall Array<{ to, value, data }>.

Use encodeTxData to produce the correct bytes for EVM (ABI) or Solana (Anchor IDL) targets.
tx.funds{ amount: bigint; token?: MoveableToken }Move tokens from origin chain atomically with the call. Use PushChain.CONSTANTS.MOVEABLE.TOKEN.<CHAIN>.<TOKEN>.

prepareTransaction accepts the same transaction arguments as Send Universal Transaction.

Returns `PreparedUniversalTx` <object>
PropertyTypeDescription
route'UOA_TO_PUSH' | 'UOA_TO_CEA' | 'CEA_TO_PUSH' | 'CEA_TO_CEA'Detected routing mode for this transaction.
estimatedGasbigintEstimated gas units for execution.
noncebigintNonce to use for submission.
deadlinebigintSignature expiry deadline.
payloadstringEncoded payload ready for submission.
gatewayRequestobjectGateway request object (inbound or outbound).
Live Playground: Inspect PreparedUniversalTx
VIRTUAL NODE IDE
Copy playground link
Copy code

Execute Transactions

pushChainClient.universal.executeTransactions(txs: PreparedUniversalTx[], options?: { progressHook? }): Promise<CascadedTxResponse>

Executes an ordered array of prepared transactions as a multichain flow. This is submitted and handled as a single transaction. You sign once, and the SDK coordinates execution across Push Chain and supported external chains automatically.

Each prepared transaction becomes one ordered step in the multichain flow.

const step1 = await pushChainClient.universal.prepareTransaction({...}); // Push Chain
const step2 = await pushChainClient.universal.prepareTransaction({...}); // BNB

// Live progress for pre-flight, broadcast, and cascade tracking.
const result = await pushChainClient.universal.executeTransactions([step1, step2], {
progressHook: (event) => {
console.log('[' + event.id + '] ' + event.level + ' - ' + event.title);
},
});

TheseArgumentsare mandatory

ArgumentsTypeDescription
txsPreparedUniversalTx[]Ordered array of prepared transactions from prepareTransaction.
options.progressHook(event: ProgressEvent) => voidOptional per-call progress callback. Progress hook follows the same structure as Send Universal Transaction - Progress Hook.

In the API response, each executed step is reported as a hop.

Returns `CascadedTxResponse` <object>
PropertyTypeDescription
initialTxHashstringHash of the user-signed Push Chain transaction that kicked off the cascade.
initialTxResponseUniversalTxResponseFull response object for the initial Push Chain transaction.
hopsCascadeHopInfo[]Ordered list of all hops with routing and status information.
hopCountnumberTotal number of hops in the cascade.
wait(opts?)Promise<CascadeCompletionResult>Alias for waitForAll. Waits for all hops to complete.
waitForAll(opts?)Promise<CascadeCompletionResult>Waits for all hops to complete across all chains.

CascadeHopInfo fields:

PropertyTypeDescription
hopIndexnumberPosition in the cascade (0-indexed).
routestringRouting mode for this hop (UOA_TO_PUSH, UOA_TO_CEA, etc.).
executionChainCHAINChain where this hop executes.
status'pending' | 'submitted' | 'confirmed' | 'failed'Current hop status.
txHashstringResolved transaction hash once available.
outboundDetailsobjectExternal chain tx details for outbound hops, including hash, explorer URL, recipient, and amount.

CascadeCompletionResult fields:

PropertyTypeDescription
successbooleanWhether all hops completed successfully.
hopsCascadeHopInfo[]Final state of all hops.
failedAtnumberIndex of first failed hop, if any.

waitForAll options:

OptionTypeDefaultDescription
pollingIntervalMsnumber5000Polling interval in milliseconds.
timeoutnumber600000Total timeout in milliseconds (10 min).
progressHook(event: CascadeProgressEvent) => void-Progress callback per hop. Reports hopIndex, route, chain, status, txHash, elapsed.
Live Playground: Execute Multiple Transactions in One Flow
VIRTUAL NODE IDE
Copy playground link
Copy code

More Examples

Batch Contract Calls: Push Chain + BNB + Solana in One Signature

Increment counters on Push Chain and BNB Testnet, then trigger a call on Solana Devnet. Three independent contract interactions across three chains, all composed into a single user signature.

Live Playground: Cross-Chain Contract Calls
VIRTUAL NODE IDE
Copy playground link
Copy code

Cross-Chain AMM Swap: ETH → pSOL via Push Chain AMM

Swap ETH on Sepolia for pSOL on Solana Devnet in a single user signature.

  • Hop 0 bridges 0.065 ETH from the Sepolia EOA into 0.005 gas and 0.001 pETH on the UEA on Push Chain, with value: 25 PC seeding the UEA's gas via SDK fee-locking.
  • Hops 1 and 2 approve the SwapRouter for pETH and WPC.
  • Hops 3 and 4 swap pETH → WPC → pSOL via two exactInputSingle calls on the Push Chain AMM (the AMM has no direct pETH/pSOL pool, so WPC is the intermediate).
  • Hop 5 bridges the pSOL out to the user's Solana Devnet CEA.
Live Playground: ETH → pETH → WPC → pSOL → Solana
VIRTUAL NODE IDE
Copy playground link
Copy code

Key Considerations

  • Single signature: executeTransactions submits one transaction to Push Chain. You sign once, and the SDK coordinates the full multichain execution automatically.
  • No atomicity guarantee: If a downstream hop fails, earlier hops are already on-chain. Design contracts to handle partial execution.
  • Gas per hop: Each hop has its own estimated gas. Ensure gas is properly funded.
  • Tracking: Progress channel work side-by-side and can be wired too keep track of the execution flow:
    • executeTransactions(txs, { progressHook }) streams every ProgressEvent (rich marker ids like SEND-TX-101, severity, structured payload) across pre-flight, broadcast, and cascade phases. Best for UI step indicators and granular telemetry.

Next Steps