<BridgeAndExecuteButton>
SET UP THE SDK BEFORE YOU START:
You can find the SDK setup instructions in the Overview page.
Use the BridgeAndExecuteButton
component to provide a pre-built interface that handles bridging tokens to a destination chain and then executing a smart contract function on that chain in a single flow.
The widget automatically manages the bridge + execute flow, UI modals, transaction state, and token approvals.
Useful for flows like “bridge 500 USDC to Base and stake it in a lending pool in a single click.”
Note:
-
We made a small demo website that implements the
BridgeAndExecuteButton
widget. Check it out here: nexus-ui-components-demo.vercel.app -
If you just want to see an example that uses the
BridgeAndExecuteButton
widget, refer to the repo here: nexus-ui-components-demo
Props
interface BridgeAndExecuteButtonProps {
contractAddress: `0x${string}`;
contractAbi: Abi;
functionName: string;
buildFunctionParams: DynamicParamBuilder;
prefill?: {
toChainId?: SUPPORTED_CHAINS_IDS;
token?: SUPPORTED_TOKENS;
amount?: string;
};
children: (props: {
onClick: () => void;
isLoading: boolean;
disabled: boolean;
}) => ReactNode;
className?: string;
}
type DynamicParamBuilder = (
token: SUPPORTED_TOKENS,
amount: string,
chainId: SUPPORTED_CHAINS_IDS,
userAddress: `0x${string}`
) => {
functionParams: readonly unknown[];
value?: string;
};
Example
Note:
Refer to the API reference for a full list of supported tokens and chains,
as well as more examples of how to use the BridgeAndExecuteButton
widget.
Here are examples of how to use the BridgeAndExecuteButton
widget:
Basic Bridge & Execute Button
import { BridgeAndExecuteButton, TOKEN_METADATA, TOKEN_CONTRACT_ADDRESSES } from '@avail-project/nexus';
import { parseUnits } from 'viem';
function App() {
return (
<BridgeAndExecuteButton
contractAddress="0x794a61358D6845594F94dc1DB02A252b5b4814aD"
contractAbi={[
{
name: 'supply',
type: 'function',
stateMutability: 'nonpayable',
inputs: [
{ name: 'asset', type: 'address' },
{ name: 'amount', type: 'uint256' },
{ name: 'onBehalfOf', type: 'address' },
{ name: 'referralCode', type: 'uint16' },
],
outputs: [],
},
]}
functionName="supply"
buildFunctionParams={(token, amount, chainId, userAddress) => {
const decimals = TOKEN_METADATA[token].decimals;
const amountWei = parseUnits(amount, decimals);
const tokenAddr = TOKEN_CONTRACT_ADDRESSES[token][chainId];
return {
functionParams: [tokenAddr, amountWei, userAddress, 0],
value: '0' // No ETH value for ERC-20 token supply
};
}}
>
{({ onClick, isLoading, disabled }) => (
<button onClick={onClick} disabled={disabled || isLoading}>
{isLoading ? 'Processing…' : 'Bridge & Supply to AAVE'}
</button>
)}
</BridgeAndExecuteButton>
);
}
buildFunctionParams
receives the validated UX input (token, amount, destination chainId) plus the connected wallet address and must return the encoded functionParams
(and optional ETH value) used in the destination call.
The library then:
- Bridges the asset to toChainId.
- Sets ERC-20 allowance if required.
- Executes
contractAddress.functionName(functionParams, { value })
.
Pre-filled Bridge & Execute
import { BridgeAndExecuteButton, TOKEN_METADATA, TOKEN_CONTRACT_ADDRESSES } from '@avail-project/nexus';
import { parseUnits } from 'viem';
function App() {
return (
<BridgeAndExecuteButton
contractAddress="0x794a61358D6845594F94dc1DB02A252b5b4814aD"
contractAbi={[
{
name: 'supply',
type: 'function',
stateMutability: 'nonpayable',
inputs: [
{ name: 'asset', type: 'address' },
{ name: 'amount', type: 'uint256' },
{ name: 'onBehalfOf', type: 'address' },
{ name: 'referralCode', type: 'uint16' },
],
outputs: [],
},
]}
functionName="supply"
buildFunctionParams={(token, amount, chainId, userAddress) => {
const decimals = TOKEN_METADATA[token].decimals;
const amountWei = parseUnits(amount, decimals);
const tokenAddr = TOKEN_CONTRACT_ADDRESSES[token][chainId];
return {
functionParams: [tokenAddr, amountWei, userAddress, 0]
};
}}
prefill={{
toChainId: 42161, // Arbitrum
token: 'USDT',
amount: '100'
}}
>
{({ onClick, isLoading, disabled }) => (
<button onClick={onClick} disabled={disabled || isLoading}>
{isLoading ? 'Processing…' : 'Bridge 100 USDT to Arbitrum & Supply to AAVE'}
</button>
)}
</BridgeAndExecuteButton>
);
}