A unified component for swap, send, and deposit flows powered by Avail Nexus intents.
Network support: Nexus One currently supports mainnet only. Testnet is not supported at the moment.
npx shadcn@latest add @nexus-elements/nexus-one- Install dependencies:
npm install @avail-project/nexus-core decimal.js lucide-react viem wagmi class-variance-authority clsx tailwind-merge- Copy the component source code into your project.
- Update import paths to match your project setup.
Wrap your app with NexusProvider before rendering NexusOne.
import { NexusProvider } from "@/components/nexus/NexusProvider";
export default function RootLayout({ children }) {
return <NexusProvider>{children}</NexusProvider>;
}Swap between any supported token pairs across chains. Nexus One switches between exact-in and exact-out quoting based on which amount field the user changes.
import { NexusOne } from "@/components/nexus-one/nexus-one";
export function SwapExample({ address }: { address?: `0x${string}` }) {
return (
<NexusOne
config={{
mode: "swap",
prefill: {
source: {
token: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
chain: 42161, // USDC on Arbitrum
},
destination: {
token: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
chain: 8453, // USDC on Base
},
},
}}
connectedAddress={address}
/>
);
}Cross-chain send flow. Users choose the token and amount to send, then Nexus resolves the pay-with sources.
import { NexusOne } from "@/components/nexus-one/nexus-one";
export function SendExample({ address }: { address?: `0x${string}` }) {
return (
<NexusOne
config={{
mode: "send",
prefill: {
token: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
chain: 8453, // USDC on Base
amount: "0.1",
recipient: "0xF3a15b38e63dBb1a1b2d7842CcD9B9dD8fB9b2E",
},
}}
connectedAddress={address}
/>
);
}Deposit into DeFi protocols with a single intent. A non-empty opportunities array is required when mode is "deposit".
import { NexusOne } from "@/components/nexus-one/nexus-one";
import { encodeFunctionData } from "viem";
const AAVE_POOL = "0x794a61358D6845594F94dc1DB02A252b5b4814aD";
const USDT_ARBITRUM = "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9";
const AAVE_ABI = [
{
inputs: [
{ name: "asset", type: "address" },
{ name: "amount", type: "uint256" },
{ name: "onBehalfOf", type: "address" },
{ name: "referralCode", type: "uint16" },
],
name: "supply",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
] as const;
export function DepositExample({ address }: { address?: `0x${string}` }) {
return (
<NexusOne
config={{
mode: "deposit",
opportunities: [
{
id: "aave-usdt-arbitrum",
title: "Aave",
protocol: "Aave",
subtitle: "Deposit USDT on Arbitrum",
logo: "https://files.availproject.org/uploads/2026-04-16/aave.svg",
chainId: 42161,
tokenSymbol: "USDT",
tokenAddress: USDT_ARBITRUM,
execute: (amount, connectedAddress) => ({
to: AAVE_POOL,
data: encodeFunctionData({
abi: AAVE_ABI,
functionName: "supply",
args: [USDT_ARBITRUM, amount, connectedAddress, 0],
}),
gas: BigInt(300000),
tokenApproval: {
token: USDT_ARBITRUM,
amount,
spender: AAVE_POOL,
},
}),
},
],
}}
connectedAddress={address}
/>
);
}Use lifecycle callbacks to integrate with your app's toast, analytics, or navigation.
import { NexusOne } from "@/components/nexus-one/nexus-one";
export function SwapWithCallbacks({ address }: { address?: `0x${string}` }) {
return (
<NexusOne
config={{ mode: "swap" }}
connectedAddress={address}
onStart={() => console.log("Transaction started")}
onComplete={(explorerUrl) => {
console.log("Transaction complete:", explorerUrl);
}}
onError={(message) => {
console.error("Transaction failed:", message);
}}
/>
);
}Limit which source or destination tokens users can select.
import { NexusOne } from "@/components/nexus-one/nexus-one";
export function RestrictedSwap({ address }: { address?: `0x${string}` }) {
return (
<NexusOne
config={{
mode: "swap",
allowedSourcePairs: [
{ token: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", chain: 42161 }, // USDC on Arbitrum
{ token: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", chain: 8453 }, // USDC on Base
],
allowedDestinationPairs: [
{ token: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", chain: 42161 }, // USDT on Arbitrum
],
}}
connectedAddress={address}
/>
);
}| Prop | Type | Required | Notes |
|---|---|---|---|
config |
NexusOneConfig |
✅ | Selects the workflow and any mode-specific behavior. |
connectedAddress |
`0x${string}` |
Wallet address. Falls back to connected wagmi account. | |
embed |
boolean |
Defaults to true. Set false for modal rendering. |
|
onComplete |
(explorerUrl?: string) => void |
Called on success. | |
onStart |
() => void |
Called when execution begins. | |
onError |
(message: string) => void |
Called on failure. | |
onClose |
() => void |
Close button handler (modal mode only). |
| Field | Type | Notes |
|---|---|---|
mode |
"swap" | "send" | "deposit" |
Required. Selects the active flow. |
prefill.amount |
string |
Prefills the amount input. |
prefill.recipient |
`0x${string}` |
Prefills recipient (send mode). |
prefill.token |
`0x${string}` |
Prefills token address. |
prefill.chain |
number |
Prefills chain id. |
prefill.source |
{ token; chain } |
Prefills source token and chain. |
prefill.destination |
{ token; chain } |
Prefills destination token and chain. |
allowedSourcePairs |
{ token; chain }[] |
Restricts selectable source pairs. |
allowedDestinationPairs |
{ token; chain }[] |
Restricts selectable destination pairs. |
opportunities |
DepositOpportunity[] |
Required for deposit mode. |