Nexus Elements - Deposit
Install
- Install widget:
- npx shadcn@latest add @nexus-elements/deposit
- Ensure
NexusProvideris installed and initialized before rendering.
Required setup before rendering
- Ensure
useNexus().nexusSDKis initialized. - Ensure
exchangeRatecontains destination token rate (widget requires it for amount simulation). - Provide a correct
destinationconfig andexecuteDepositbuilder. - If using the built-in
MAXinteraction, ensure the widget can compute current source selections so it can callsdk.calculateMaxForSwap(...).
Initialize SDK (required once per app)
- On wallet connect, resolve an EIP-1193 provider and call
useNexus().handleInit(provider). - Wait for
useNexus().nexusSDKbefore allowing amount confirmation. - Re-run init after reconnect if wallet session resets.
Render widget
"use client";
import NexusDeposit from "@/components/deposit/nexus-deposit";
import {
SUPPORTED_CHAINS,
TOKEN_CONTRACT_ADDRESSES,
TOKEN_METADATA,
CHAIN_METADATA,
} from "@avail-project/nexus-core";
import { encodeFunctionData, type Abi } from "viem";
export function DepositPanel() {
return (
<NexusDeposit
heading="Deposit USDC"
destination={{
chainId: SUPPORTED_CHAINS.BASE,
tokenAddress: TOKEN_CONTRACT_ADDRESSES["USDC"][SUPPORTED_CHAINS.BASE],
tokenSymbol: "USDC",
tokenDecimals: TOKEN_METADATA["USDC"].decimals,
tokenLogo: TOKEN_METADATA["USDC"].icon,
label: "Deposit to protocol",
gasTokenSymbol: CHAIN_METADATA[SUPPORTED_CHAINS.BASE].nativeCurrency.symbol,
explorerUrl: CHAIN_METADATA[SUPPORTED_CHAINS.BASE].blockExplorerUrls[0],
estimatedTime: "~30s",
}}
executeDeposit={(tokenSymbol, tokenAddress, amount, _chainId, user) => {
const contract = "0x0000000000000000000000000000000000000000" as const;
const abi: Abi = [
{
type: "function",
name: "deposit",
stateMutability: "nonpayable",
inputs: [
{ name: "asset", type: "address" },
{ name: "amount", type: "uint256" },
{ name: "beneficiary", type: "address" },
],
outputs: [],
},
];
const data = encodeFunctionData({
abi,
functionName: "deposit",
args: [tokenAddress, amount, user],
});
return {
to: contract,
data,
tokenApproval: {
token: tokenAddress,
amount,
spender: contract,
},
};
}}
onSuccess={() => {
// success
}}
onError={(message) => {
console.error(message);
}}
/>
);
}Live prop contract
- Required:
- destination: DestinationConfig - executeDeposit(tokenSymbol, tokenAddress, amount, chainId, user)
- Optional:
- heading, embed, className - open, onOpenChange, defaultOpen (dialog mode) - onSuccess, onError, onClose
SDK flow details (under the hood)
- Main execute call:
- sdk.swapAndExecute({toChainId, toTokenAddress, toAmount, fromSources?, execute}, {onEvent})
- Max amount call:
- sdk.calculateMaxForSwap({toChainId, toTokenAddress, fromSources?})
- Step and status behavior:
- amount step starts simulation-loading - waits for swapIntent hook to enter previewing state - confirm order calls activeIntent.allow() and moves to executing
- Event mapping:
- listens to NEXUS_EVENTS.SWAP_STEP_COMPLETE - handles DETERMINING_SWAP and SWAP_SKIPPED
- Fee handling:
- destination execute receipt computes actual gas USD in success path
Important amount semantics
- Amount input is interpreted as USD in this widget flow.
- Widget converts USD amount to destination token amount via provider exchange rates.
MAXis destination-token aware:
- widget computes MaxSwapInput from the current destination and selected source pool - widget calls sdk.calculateMaxForSwap(...) - returned destination-token max is converted back to USD for the input field
- If destination token exchange rate is missing/invalid, widget shows error and blocks confirmation.
Source selection semantics
- Amount changes reset source selection back to auto mode.
- In auto mode, the widget derives source balances from the current filter and current widget logic before simulation.
- Preset filters in the source picker (
Any token,Stablecoins,Native) act as explicit source selections for that pool. - Manual source edits are treated as exact selected sources until the amount changes again.
Pay usingand thefromSourcessent tosdk.swapAndExecute(...)should reflect the same current source set.
Preview cancellation behavior
- Backing out from the confirmation screen before
activeIntent.allow()denies the preview intent. - This intentional preview cancellation should not surface as the widget's own local error banner, though external
onErrorhandlers may still observe the rejection if the app wants it.
E2E verification
- Enter amount and continue to confirmation.
- Confirm simulation appears and updates every polling cycle.
- Confirm order and verify status screen transitions.
- Verify both source and destination explorer links when available.
- Verify
onSuccessand balance refresh after completion. - Verify error screen appears on failed simulation/execution.
Common failure cases
Nexus SDK is not initialized:
- ensure handleInit(provider) ran after wallet connect.
Unable to fetch pricing for <token>:
- ensure rates loaded in provider and token symbol is valid.
- Execute revert:
- validate executeDeposit target, calldata, and token approval spender.