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

Custom Contract Calls

Custom contract calls let you run additional on-chain actions after the deposit swap completes — all in the same user flow. Stake the received tokens, wrap them, add liquidity, deposit into a vault: any contract interaction, chained.

The widget executes the flow as: swap → deliver → your calls, in sequence. If any call reverts, the whole thing reverts.

The ContractCall object

Each call is:

interface ContractCall {
  callType: ContractCallType; // how to handle amounts
  target: string;             // contract to call
  value: string;              // native value in wei (usually "0")
  callData: string;           // ABI-encoded function call
  payload: string;            // extra data for balance encoding
}

Pass an array as customContractCalls:

import { SwapperIframe, ContractCallType } from "@swapper-finance/deposit-sdk";

const swapper = new SwapperIframe({
  integratorId: "your-id",
  dstChainId: "1",
  dstTokenAddr: "0x…",        // token the calls operate on
  depositWalletAddress: "0x…",
  customContractCalls: [ /* calls */ ],
});

Call types

ContractCallType controls how the executor fills in amounts — because the exact post-swap balance isn't known when you build the calls.

Type
Value
Behavior

DEFAULT

0

Use the exact amounts encoded in callData; nothing is rewritten. payload is "0x".

FULL_TOKEN_BALANCE

1

Overwrite one argument of callData with the full token balance at execution time. payload names the token and which argument to overwrite — see Balance payload encoding.

FULL_NATIVE_BALANCE

2

Send the entire native balance as the call's value. payload is "0x" — nothing in callData is rewritten.

COLLECT_TOKEN_BALANCE

3

Book-keeping step that snapshots a token's balance for a later call. payload is only the token address; target/callData are empty.

Balance payload encoding

FULL_TOKEN_BALANCE is the type you'll reach for most, and its payload is the part that trips people up. The rule:

amountArgIndex is the zero-indexed position of the amount argument in your target function's signature — i.e. which 32-byte word of the calldata the executor overwrites with the token balance. It is not a fixed constant, and it is unrelated to the placeholder value you put in callData. Compute it from your own function:

Function

amount is argument…

amountArgIndex

approve(address spender, uint256 amount)

2nd

1

transfer(address recipient, uint256 amount)

2nd

1

deposit(uint256 _amount, bool _shouldQueue, bytes[] _data)

1st

0

depositFor(address currency, address forAddress, uint256 amount, uint256 broker)

3rd

2

In callData, put a placeholder (0) at that same argument — the executor overwrites it with the real balance at runtime. A wrong amountArgIndex patches the wrong word of your calldata and the call will almost certainly revert (e.g. using 0 for depositFor would overwrite the currency address with a number). The index equals the argument position whenever every preceding argument is a value type — the usual case; functions with dynamic-type args before the amount are the exception.

The other two balance types are shaped differently — don't copy the (address, uint256) payload onto them:

ERC-20 helpers

The SDK ships helpers so you don't hand-encode common ERC-20 ops.

Exact amount:

Full balance (most common after a swap, when the amount isn't known ahead of time):

Both helpers target standard ERC-20 approve/transfer, where amount is argument index 1 — a handy reference for the rule above. For a non-standard target function, build the payload with the exported helper instead of hand-rolling the tuple (harder to misread as "always 0"):

Worked example: swap → stake → return receipt

Deposit any token, swap to POL, approve the staking pool, stake the full balance, and send the staked receipt token to the user:

Updating calls at runtime

Guidelines

  • Order matters. Calls run sequentially — approvals before the operations that need them.

  • Get amountArgIndex right for FULL_TOKEN_BALANCE — it's the position of the amount argument in your function, not always 0. See Balance payload encoding.

  • All-or-nothing. A revert anywhere rolls back the entire sequence.

  • Test with small amounts first. Chained calls are easy to get subtly wrong; verify the whole sequence before relying on it.

  • Gas is estimated automatically for the chain.

Last updated