Avail Nexus SDK API Reference
The Avail Nexus SDK provides a comprehensive set of APIs for cross-chain bridging, token transfers, and balance management across multiple EVM chains.
Quick Start
- While this page already contains instructions for getting started with the SDK, we also provide two optimized entry points for devs looking to work with specific use cases
Headless
npm
npm install @avail-project/nexus/core
Headless SDK
import { NexusSDK } from '@avail-project/nexus/core';
// Initialize SDK
const sdk = new NexusSDK({ network: 'mainnet' });
await sdk.initialize(provider); // Your wallet provider
// Get unified balances
const balances = await sdk.getUnifiedBalances();
console.log('All balances:', balances);
// Bridge tokens
const bridgeResult = await sdk.bridge({
token: 'USDC',
amount: 100,
chainId: 137, // to Polygon
});
// Transfer tokens (automatically optimized)
const transferResult = await sdk.transfer({
token: 'ETH',
amount: 0.1,
chainId: 1, // Uses direct transfer if ETH + gas available on Ethereum
recipient: '0x742d35Cc6634C0532925a3b8D4C9db96c4b4Db45',
});
const executeResult = await sdk.execute({
contractAddress,
contractAbi: contractAbi,
functionName: functionName,
buildFunctionParams: (
token: SUPPORTED_TOKENS,
amount: string,
chainId: SUPPORTED_CHAINS_IDS,
user: `0x${string}`,
) => {
const decimals = TOKEN_METADATA[token].decimals;
const amountWei = parseUnits(amount, decimals);
const tokenAddr = TOKEN_CONTRACT_ADDRESSES[token][chainId];
return { functionParams: [tokenAddr, amountWei, user, 0] };
},
value: ethValue,
tokenApproval: {
token: 'USDC',
amount: '100000000',
},
});
Configuration Options
Supported Chains
Mainnet
Network | Chain ID | Native Currency | Status |
---|---|---|---|
Ethereum | 1 | ETH | ✅ |
Optimism | 10 | ETH | ✅ |
Polygon | 137 | MATIC | ✅ |
Arbitrum | 42161 | ETH | ✅ |
Avalanche | 43114 | AVAX | ✅ |
Base | 8453 | ETH | ✅ |
Scroll | 534351 | ETH | ✅ |
Sophon | 50104 | SOPH | ✅ |
Kaia | 8217 | KAIA | ✅ |
Supported Tokens
Token | Name | Decimals | Networks |
---|---|---|---|
ETH | Ethereum | 18 | All EVM chains |
USDC | USD Coin | 6 | All supported |
USDT | Tether USD | 6 | All supported |
How to fetch supported chains from the SDK?
import { SUPPORTED_CHAINS } from @avail-project/nexus/core;
// Mainnet Chain IDs
SUPPORTED_CHAINS.ETHEREUM; // 1
SUPPORTED_CHAINS.OPTIMISM; // 10
SUPPORTED_CHAINS.POLYGON; // 137
SUPPORTED_CHAINS.ARBITRUM; // 42161
SUPPORTED_CHAINS.AVALANCHE; // 43114
SUPPORTED_CHAINS.BASE; // 8453
SUPPORTED_CHAINS.LINEA; // 59144
SUPPORTED_CHAINS.SCROLL; // 534351
Headless API Reference
Initialization
import type { NexusNetwork } from '@avail-project/nexus/core';
// Mainnet (default)
const sdk = new NexusSDK();
// Testnet
const sdk = new NexusSDK({ network: 'testnet' as NexusNetwork });
// Initialize with provider (required)
await sdk.initialize(window.ethereum); // Returns: Promise<void>
Unified Balance(s)
import type { UserAsset, TokenBalance } from '@avail-project/nexus/core';
// Get all balances across chains
const balances: UserAsset[] = await sdk.getUnifiedBalances();
// Get balance for specific token
const usdcBalance: UserAsset | undefined = await sdk.getUnifiedBalance('USDC');
Bridge Operations
import type { BridgeParams, BridgeResult, SimulationResult } from '@avail-project/nexus/core';
// Bridge tokens between chains
const result: BridgeResult = await sdk.bridge({
token: 'USDC',
amount: 100,
chainId: 137,
} as BridgeParams);
// Simulate bridge to preview costs
const simulation: SimulationResult = await sdk.simulateBridge({
token: 'USDC',
amount: 100,
chainId: 137,
});
Transfer Operations
import type { TransferParams, TransferResult } from '@avail-project/nexus/core';
// Smart transfer with automatic optimization
const result: TransferResult = await sdk.transfer({
token: 'USDC',
amount: 100,
chainId: 42161, // Arbitrum
recipient: '0x...',
} as TransferParams);
// The SDK automatically:
// 1. Checks if you have USDC + ETH for gas on Arbitrum
// 2. Uses direct EVM transfer if available (faster, cheaper)
// 3. Falls back to chain abstraction if local funds insufficient
// Simulate transfer to preview costs and optimization path
const simulation: SimulationResult = await sdk.simulateTransfer({
token: 'USDC',
amount: 100,
chainId: 42161,
recipient: '0x...',
});
// Check if direct transfer will be used
console.log('Fees:', simulation.intent.fees);
// For direct transfers: gasSupplied shows actual native token cost
// For CA transfers: includes additional CA routing fees
Execute Operations
import type {
ExecuteParams,
ExecuteResult,
ExecuteSimulation,
BridgeAndExecuteParams,
BridgeAndExecuteResult,
BridgeAndExecuteSimulationResult,
} from '@avail-project/nexus/core';
// Execute contract functions with dynamic parameter builder - Compound V3 Supply
const result: ExecuteResult = await sdk.execute({
toChainId: 1,
contractAddress: '0xc3d688B66703497DAA19211EEdff47f25384cdc3', // Compound V3 USDC Market
contractAbi: [
{
inputs: [
{ internalType: 'address', name: 'asset', type: 'address' },
{ internalType: 'uint256', name: 'amount', type: 'uint256' },
],
name: 'supply',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
],
functionName: 'supply',
buildFunctionParams: (
token: SUPPORTED_TOKENS,
amount: string,
chainId: SUPPORTED_CHAIN_IDS,
userAddress: `0x${string}`,
) => {
const decimals = TOKEN_METADATA[token].decimals;
const amountWei = parseUnits(amount, decimals);
const tokenAddress = TOKEN_CONTRACT_ADDRESSES[token][chainId];
return {
functionParams: [tokenAddress, amountWei],
};
},
waitForReceipt: true,
requiredConfirmations: 3,
tokenApproval: {
token: 'USDC',
amount: '1000000', // Amount in token units
},
} as ExecuteParams);
// Simulate execute to preview costs and check for approval requirements
const simulation: ExecuteSimulation = await sdk.simulateExecute(executeParams);
if (!simulation.success) {
console.log('Simulation failed:', simulation.error);
// Error might indicate missing token approval
}
// Bridge tokens and execute contract function - Yearn Vault Deposit
const bridgeAndExecuteResult: BridgeAndExecuteResult = await sdk.bridgeAndExecute({
token: 'USDC',
amount: '100000000', // 100 USDC (6 decimals)
toChainId: 1, // Ethereum
execute: {
contractAddress: '0xa354F35829Ae975e850e23e9615b11Da1B3dC4DE', // Yearn USDC Vault
contractAbi: [
{
inputs: [
{ internalType: 'uint256', name: 'assets', type: 'uint256' },
{ internalType: 'address', name: 'receiver', type: 'address' },
],
name: 'deposit',
outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }],
stateMutability: 'nonpayable',
type: 'function',
},
],
functionName: 'deposit',
buildFunctionParams: (
token: SUPPORTED_TOKENS,
amount: string,
chainId: SUPPORTED_CHAIN_IDS,
userAddress: `0x${string}`,
) => {
const decimals = TOKEN_METADATA[token].decimals;
const amountWei = parseUnits(amount, decimals);
return {
functionParams: [amountWei, userAddress],
};
},
tokenApproval: {
token: 'USDC',
amount: '100000000',
},
},
waitForReceipt: true,
} as BridgeAndExecuteParams);
// Comprehensive simulation with detailed step analysis and approval handling
const simulation: BridgeAndExecuteSimulationResult = await sdk.simulateBridgeAndExecute(params);
// The simulation provides detailed step analysis:
console.log('Steps:', simulation.steps);
console.log('Total estimated cost:', simulation.totalEstimatedCost);
console.log('Approval required:', simulation.metadata?.approvalRequired);
console.log('Bridge receive amount:', simulation.metadata?.bridgeReceiveAmount);
Allowance Management
import type { AllowanceResponse } from '@avail-project/nexus/core';
// Check allowances
const allowances: AllowanceResponse[] = await sdk.getAllowance(137, ['USDC', 'USDT']);
// Set allowances
await sdk.setAllowance(137, ['USDC'], 1000000n);
// Revoke allowances
await sdk.revokeAllowance(137, ['USDC']);
Intent Management
import type { RequestForFunds } from '@avail-project/nexus/core';
// Get user's transaction intents
const intents: RequestForFunds[] = await sdk.getMyIntents(1);
Utilities
All utility functions are available under sdk.utils
:
import type { ChainMetadata, TokenMetadata, SUPPORTED_TOKENS } from '@avail-project/nexus/core';
// Address utilities
const isValid: boolean = sdk.utils.isValidAddress('0x...');
const shortened: string = sdk.utils.truncateAddress('0x...');
// Balance formatting
const formatted: string = sdk.utils.formatBalance('1000000', 6);
const units: bigint = sdk.utils.parseUnits('100.5', 6);
const readable: string = sdk.utils.formatUnits(100500000n, 6);
// Token amount formatting
const formattedAmount: string = sdk.utils.formatTokenAmount('1000000', 'USDC'); // "1.0 USDC"
const testnetFormatted: string = sdk.utils.formatTestnetTokenAmount('1000000', 'USDC'); // "1.0 USDC"
// Chain & token info
const chainMeta: ChainMetadata | undefined = sdk.utils.getChainMetadata(137);
const tokenMeta: TokenMetadata | undefined = sdk.utils.getTokenMetadata('USDC');
const mainnetTokenMeta: TokenMetadata | undefined = sdk.utils.getMainnetTokenMetadata('USDC');
const testnetTokenMeta: TokenMetadata | undefined = sdk.utils.getTestnetTokenMetadata('USDC');
// Chain/token validation
const isSupported: boolean = sdk.utils.isSupportedChain(137);
const isSupportedToken: boolean = sdk.utils.isSupportedToken('USDC');
// Get supported chains
const chains: Array<{ id: number; name: string; logo: string }> = sdk.utils.getSupportedChains();
// Chain ID conversion
const hexChainId: string = sdk.utils.chainIdToHex(137);
const decimalChainId: number = sdk.utils.hexToChainId('0x89');
Event Handling
import type { OnIntentHook, OnAllowanceHook, EventListener } from '@avail-project/nexus/core';
// Intent approval flows
sdk.setOnIntentHook(({ intent, allow, deny, refresh }: Parameters<OnIntentHook>[0]) => {
// This is a hook for the dev to show user the intent, the sources and associated fees
// intent: Intent data containing sources and fees for display purpose
// allow(): accept the current intent and continue the flow
// deny(): deny the intent and stop the flow
// refresh(): should be on a timer of 5s to refresh the intent
// (old intents might fail due to fee changes if not refreshed)
if (userConfirms) allow();
else deny();
});
// Allowance approvals
sdk.setOnAllowanceHook(({ allow, deny, sources }: Parameters<OnAllowanceHook>[0]) => {
// This is a hook for the dev to show user the allowances that need to be setup
// for the current tx to happen.
// sources: an array of objects with minAllowance, chainID, token symbol, etc.
// allow(allowances): continues the transaction flow with `allowances` array
// allowances.length === sources.length;
// valid values are "max" | "min" | string | bigint
// deny(): stops the flow
allow(['min']); // or ['max'] or custom amounts
});
// Account/chain changes
sdk.onAccountChanged((account) => console.log('Account:', account));
sdk.onChainChanged((chainId) => console.log('Chain:', chainId));
Progress Events for All Operations
import { NEXUS_EVENTS, ProgressStep } from '@avail-project/nexus/core';
// Bridge & Execute Progress
const unsubscribeBridgeExecuteExpected = sdk.nexusEvents.on(
NEXUS_EVENTS.BRIDGE_EXECUTE_EXPECTED_STEPS,
(steps: ProgressStep[]) => {
console.log(
'Bridge & Execute steps →',
steps.map((s) => s.typeID),
);
},
);
const unsubscribeBridgeExecuteCompleted = sdk.nexusEvents.on(
NEXUS_EVENTS.BRIDGE_EXECUTE_COMPLETED_STEPS,
(step: ProgressStep) => {
console.log('Bridge & Execute completed →', step.typeID, step.data);
if (step.typeID === 'IS' && step.data.explorerURL) {
console.log('View transaction:', step.data.explorerURL);
}
},
);
// Transfer & Bridge Progress (optimized operations)
const unsubscribeTransferExpected = sdk.nexusEvents.on(
NEXUS_EVENTS.EXPECTED_STEPS,
(steps: ProgressStep[]) => {
console.log(
'Transfer/Bridge steps →',
steps.map((s) => s.typeID),
);
// For direct transfers: ['CS', 'TS', 'IS'] (3 steps, ~5-15s)
},
);
const unsubscribeTransferCompleted = sdk.nexusEvents.on(
NEXUS_EVENTS.STEP_COMPLETE,
(step: ProgressStep) => {
console.log('Transfer/Bridge completed →', step.typeID, step.data);
if (step.typeID === 'IS' && step.data.explorerURL) {
// Transaction submitted with hash - works for both direct and CA
console.log('Transaction hash:', step.data.transactionHash);
console.log('Explorer URL:', step.data.explorerURL);
}
},
);
// Cleanup
return () => {
unsubscribeBridgeExecuteExpected();
unsubscribeBridgeExecuteCompleted();
unsubscribeTransferExpected();
unsubscribeTransferCompleted();
};
The SDK emits consistent event patterns for all operations:
- Bridge & Execute Operations:
bridge_execute_expected_steps
: once with full ordered array of ProgressSteps
bridge_execute_completed_steps
: many; one per finished step with runtime data
- Transfer & Bridge Operations:
expected_steps
: once; with full ordered array of ProgressSteps
step_complete
:many; one per finished step with runtime data
All events include the same typeID
structure and runtime data
such as transactionHash
, explorerURL
, confirmations
, error
, etc.
This provides consistent progress tracking whether using optimized direct operations or chain abstraction.
Provider Methods
import type { EthereumProvider, RequestArguments } from '@avail-project/nexus/core';
// Get enhanced provider
const provider: EthereumProvider = sdk.getEVMProviderWithCA();
// Make EIP-1193 requests
const result = await sdk.request({
method: 'eth_accounts',
params: [],
} as RequestArguments);
// Cleanup
await sdk.deinit();
Usage Examples
Basic Bridge with Result Handling
import { NexusSDK, type BridgeResult } from '@avail-project/nexus/core';
const sdk = new NexusSDK();
await sdk.initialize(window.ethereum);
try {
const result: BridgeResult = await sdk.bridge({
token: 'USDC',
amount: 100,
chainId: 137,
});
if (result.success) {
console.log('✅ Bridge successful!');
if (result.explorerUrl) {
console.log('View transaction:', result.explorerUrl);
}
} else {
console.error('❌ Bridge failed:', result.error);
}
} catch (error) {
console.error('Bridge error:', error);
}
Execute with Receipt Confirmation
import type { ExecuteResult } from '@avail-project/nexus/core';
// MakerDAO DSR (Dai Savings Rate) Deposit
const result: ExecuteResult = await sdk.execute({
toChainId: 1,
contractAddress: '0x373238337Bfe1146fb49989fc222523f83081dDb', // DSR Manager
contractAbi: [
{
inputs: [
{ internalType: 'address', name: 'usr', type: 'address' },
{ internalType: 'uint256', name: 'wad', type: 'uint256' },
],
name: 'join',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
],
functionName: 'join',
buildFunctionParams: (
token: SUPPORTED_TOKENS,
amount: string,
chainId: SUPPORTED_CHAIN_IDS,
userAddress: `0x${string}`,
) => {
const decimals = TOKEN_METADATA[token].decimals;
const amountWei = parseUnits(amount, decimals);
return {
functionParams: [userAddress, amountWei],
};
},
waitForReceipt: true,
requiredConfirmations: 3,
tokenApproval: {
token: 'USDC', // Will be converted to DAI in the bridge
amount: '1000000',
},
});
console.log('Transaction hash:', result.transactionHash);
console.log('Explorer URL:', result.explorerUrl);
console.log('Gas used:', result.gasUsed);
console.log('Confirmations:', result.confirmations);
Bridge and Execute with Error Handling
import type { BridgeAndExecuteResult } from '@avail-project/nexus/core';
try {
const result: BridgeAndExecuteResult = await sdk.bridgeAndExecute({
token: 'USDC',
amount: '1000',
toChainId: 1,
execute: {
contractAddress: '0xA238Dd80C259a72e81d7e4664a9801593F98d1c5',
contractAbi: [
{
inputs: [
{ internalType: 'address', name: 'asset', type: 'address' },
{ internalType: 'uint256', name: 'amount', type: 'uint256' },
{ internalType: 'address', name: 'onBehalfOf', type: 'address' },
{ internalType: 'uint16', name: 'referralCode', type: 'uint16' },
],
name: 'supply',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
],
functionName: 'supply',
buildFunctionParams: (token, amount, chainId, userAddress) => {
const decimals = TOKEN_METADATA[token].decimals;
const amountWei = parseUnits(amount, decimals);
const tokenAddress = TOKEN_CONTRACT_ADDRESSES[token][chainId];
return {
functionParams: [tokenAddress, amountWei, userAddress, 0],
};
},
tokenApproval: {
token: 'USDC',
amount: '1000000000',
},
},
waitForReceipt: true,
});
console.log('✅ Bridge and execute completed!');
if (result.executeTransactionHash) {
console.log('Execute transaction:', result.executeTransactionHash);
console.log('View on explorer:', result.executeExplorerUrl);
}
} catch (error) {
if (error.message.includes('User denied')) {
console.log('User cancelled transaction');
} else if (error.message.includes('Bridge phase failed')) {
console.error('Bridge failed:', error);
} else if (error.message.includes('Execute phase failed')) {
console.error('Execute failed:', error);
} else {
console.error('Operation failed:', error);
}
}
Complete Portfolio Management
import type { UserAsset, ChainMetadata } from '@avail-project/nexus/core';
// Get complete balance overview
const balances: UserAsset[] = await sdk.getUnifiedBalances();
for (const asset of balances) {
console.log(`\n${asset.symbol}: ${asset.balance}`);
console.log(`Fiat value: $${asset.balanceInFiat || 0}`);
if (asset.breakdown) {
console.log('Chain breakdown:');
for (const chainBalance of asset.breakdown) {
const chain: ChainMetadata | undefined = sdk.utils.getChainMetadata(chainBalance.chain.id);
console.log(` ${chain?.name}: ${chainBalance.balance}`);
}
}
}
Error Handling
import type { BridgeResult } from '@avail-project/nexus/core';
try {
const result: BridgeResult = await sdk.bridge({ token: 'USDC', amount: 100, chainId: 137 });
if (!result.success) {
// Handle bridge failure
console.error('Bridge failed:', result.error);
}
} catch (error) {
if (error.message.includes('User denied')) {
// User cancelled transaction
} else if (error.message.includes('Insufficient')) {
// Insufficient balance
} else if (error.message.includes('Unsupported')) {
// Unsupported chain or token
} else {
// Other errors
console.error('Unexpected error:', error);
}
}
Troubleshooting
Common Issues
- SDK not initialized: Always call
await sdk.initialize(provider)
before using other methods. - Unsupported chain/token: Check supported chains and tokens using
sdk.isSupportedChain()
andsdk.isSupportedToken()
. - Insufficient allowance: Use allowance management methods to check and set appropriate allowances.
- Provider issues: Ensure your Web3 provider is properly connected and on a supported network.