A headless TypeScript SDK for cross-chain operations, token bridging, swapping, and unified balance management β built for backends, CLIs, and custom UI integrations.
β‘ Powering next-generation cross-chain apps with a single interface.
npm install @avail-project/nexus-coreimport { NexusSDK, NEXUS_EVENTS } from '@avail-project/nexus-core';
// Initialize SDK
const sdk = new NexusSDK({ network: 'mainnet' });
await sdk.initialize(provider); // Your EVM-compatible wallet provider
// (Optional) Add TRON support
const tronLinkAdapter = new TronLinkAdapter();
sdk.addTron(tronLinkAdapter);
// ---------------------------
// 1οΈβ£ Get unified balances
// ---------------------------
const balances = await sdk.getUnifiedBalances(false); // false = CA balances only
console.log('Balances:', balances);
// ---------------------------
// 2οΈβ£ Bridge tokens
// ---------------------------
const bridgeResult = await sdk.bridge(
{
token: 'USDC',
amount: 1_500_000n,
recipient: '0x...' // Optional
toChainId: 137, // Polygon
},
{
onEvent: (event) => {
if (event.name === NEXUS_EVENTS.STEPS_LIST) console.log('Bridge steps:', event.args);
if (event.name === NEXUS_EVENTS.STEP_COMPLETE) console.log('Step completed:', event.args);
},
},
);
// ---------------------------
// 3οΈβ£ Transfer tokens
// ---------------------------
const transferResult = await sdk.bridgeAndTransfer(
{
token: 'ETH',
amount: 1_500_000n,
toChainId: 1, // Ethereum
recipient: '0x742d35Cc6634C0532925a3b8D4C9db96c4b4Db45',
},
{
onEvent: (event) => {
if (event.name === NEXUS_EVENTS.STEPS_LIST) console.log('Transfer steps:', event.args);
if (event.name === NEXUS_EVENTS.STEP_COMPLETE) console.log('Step completed:', event.args);
},
},
);
// ---------------------------
// 4οΈβ£ Execute a contract
// ---------------------------
const executeResult = await sdk.execute(
{
to: '0x...',
value: 0n,
data: '0x...',
toChainId: 1,
tokenApproval: { token: 'USDC', amount: 10000n, spender: "0x..." },
},
{
onEvent: (event) => {
if (event.name === NEXUS_EVENTS.STEPS_LIST) console.log('Execute steps:', event.args);
if (event.name === NEXUS_EVENTS.STEP_COMPLETE) console.log('Step completed:', event.args);
},
},
);
// ---------------------------
// 5οΈβ£ Bridge and Execute
// ---------------------------
const bridgeAndExecuteResult = await sdk.bridgeAndExecute(
{
token: 'USDC',
amount: 100_000_000n,
toChainId: 1,
sourceChains: [8453],
execute: {
to: '0x...',
data: '0x...',
tokenApproval: { token: 'USDC', amount: 100_000_000n, spender: "0x..." },
},
},
{
onEvent: (event) => {
if (event.name === NEXUS_EVENTS.STEPS_LIST) console.log('Bridge+Execute steps:', event.args);
if (event.name === NEXUS_EVENTS.STEP_COMPLETE) console.log('Step completed:', event.args);
},
},
);
// ---------------------------
// 6οΈβ£ Swap tokens
// ---------------------------
const swapResult = await sdk.swapWithExactIn(
{
from: [
{ chainId: 10, amount: 1_000_000n, tokenAddress: '0x...' },
],
toChainId: 8453,
toTokenAddress: '0x...',
},
{
onEvent: (event) => console.log('Swap event:', event),
},
);- Cross-chain bridging β Move tokens seamlessly across 16+ chains.
- Cross-chain swaps β Execute EXACT_IN and EXACT_OUT swaps between any supported networks.
- Unified balances β Aggregate user assets and balances across all connected chains.
- Optimized transfers β Automatically choose the most efficient transfer route.
- Contract execution β Call smart contracts with automatic bridging and funding logic.
- Transaction simulation β Estimate gas, fees, and required approvals before sending.
- Complete testnet coverage β Full multi-chain test environment.
- Comprehensive utilities β Address, token, and chain helpers built in.
During bridge-and-execute operations, the SDK checks whether sufficient funds already exist on the destination chain:
- Balance detection β Verifies token and gas availability.
- Integrated gas supply β Provides gas alongside bridged tokens.
- Adaptive bridging β Skips unnecessary bridging or transfers only the shortfall.
- Seamless fallback β Uses chain abstraction if local funds are insufficient.
For transfers, the SDK automatically chooses the most efficient execution path:
- Local balance checking β Confirms token and gas availability on the target chain.
- Direct EVM transfers β Uses native transfers where possible (faster, cheaper).
- Chain abstraction fallback β Uses CA routing only when required.
- Universal compatibility β Works with both native tokens (ETH, MATIC) and ERC-20s (USDC, USDT).
import { NexusSDK, type NexusNetwork } from '@avail-project/nexus-core';
// Mainnet
const sdk = new NexusSDK({ network: 'mainnet' });
// Testnet
const sdkTest = new NexusSDK({ network: 'testnet' });
// Initialize with wallet provider
await sdk.initialize(window.ethereum);All main SDK functions support the onEvent hook:
bridgebridgeAndTransferexecutebridgeAndExecuteswapWithExactIn/swapWithExactOut
Example usage for progress steps:
sdk.bridge({...}, {
onEvent: (event) => {
if(event.name === NEXUS_EVENTS.STEPS_LIST) {
// Store list of steps
} else if(event.name === NEXUS_EVENTS.STEP_COMPLETE) {
// Mark step as done
}
}
});Additional hooks for user interactions:
sdk.setOnIntentHook(({ intent, allow, deny, refresh }) => {
if (userApproves) allow();
else deny();
});
sdk.setOnSwapIntentHook(({ intent, allow, deny, refresh }) => {
if (userApproves) allow();
else deny();
});
sdk.setOnAllowanceHook(({ sources, allow, deny }) => {
allow(['min']); // 'max' or custom bigint[] supported
});| Operation Type | Event Name | Description |
|---|---|---|
| Bridge / Execute | STEPS_LIST |
Full ordered list of steps emitted once |
STEP_COMPLETE |
Fired per completed step with data | |
| Swap | SWAP_STEP_COMPLETE |
Fired per completed step with data |
All events include typeID, transactionHash, explorerURL, and error (if any).
const unifiedBridgeBalances = await sdk.getBalancesForBridge(); // Returns balances that can be used in bridge operations
---
const swapBalances = await sdk.getBalancesForSwap(); // Returns balances that can be used in swap operationsconst result = await sdk.bridge({
token: 'USDC',
amount: 83_500_000n,
toChainId: 137,
recipient: '0x....',
});
const simulation = await sdk.simulateBridge({
token: 'USDC',
amount: 83_500_000n,
toChainId: 137,
recipient: '0x....',
});const result = await sdk.bridgeAndTransfer({
token: 'USDC',
amount: 1_530_000n,
toChainId: 42161,
recipient: '0x...',
});
const simulation = await sdk.simulateBridgeAndTransfer({
token: 'USDC',
amount: 1_530_000n, // = 1.53 USDC
toChainId: 42161,
recipient: '0x...',
});// Direct contract execution
const result = await sdk.execute({
toChainId: 1,
to: '0xc3d688B66703497DAA19211EEdff47f25384cdc3',
data: '0x...',
tokenApproval: { token: 'USDC', amount: 1000000n, spender: '0x...' },
});
// Bridge and execute
const result2 = await sdk.bridgeAndExecute({
token: 'USDC',
amount: 100_000_000n,
toChainId: 1,
sourceChains: [8453],
execute: {
to: '0xa354F35829Ae975e850e23e9615b11Da1B3dC4DE',
data: '0x...',
tokenApproval: { token: 'USDC', amount: 100_000_000n, spender: '0x...' },
},
});const swapResult = await sdk.swapWithExactIn(
{
from: [{ chainId: 10, amount: 1_000_000n, tokenAddress: '0x...' }],
toChainId: 8453,
toTokenAddress: '0x...',
},
{ onEvent: (event) => console.log(event) },
);| Type | Description | Example |
|---|---|---|
| EXACT_IN | Specify the amount youβre spending; output varies | βSwap 100 USDC for max ETHβ |
| EXACT_OUT | Specify the amount youβll receive; input varies | βGet exactly 1 ETHβ |
const intents = await sdk.getMyIntents(1);
console.log('Active intents:', intents);import { CHAIN_METADATA, formatTokenBalance, truncateAddress } from '@avail-project/nexus-core';
const isValid = sdk.utils.isValidAddress('0x...');
const chainMeta = CHAIN_METADATA[137];
const formatted = sdk.utils.formatTokenBalance('0.000294700412452583', {
symbol: 'ETH',
decimals: 18,
}); // "~0.0β2552 ETH"
// Direct imports (no sdk instance required) for stateless helpers:
const directFormatted = formatTokenBalance(12.345678, { symbol: 'USDC' });
const short = truncateAddress('0x1234567890123456789012345678901234567890');try {
await sdk.bridge({ token: 'USDC', amount: 1_530_000n, toChainId: 137 });
} catch (err) {
if (err instanceof NexusError) {
console.error(`[${err.code}] ${err.message}`);
} else {
console.error('Unexpected error:', err);
}
}import type {
BridgeParams,
ExecuteParams,
TransferParams,
SwapResult,
NexusNetwork,
TokenMetadata,
} from '@avail-project/nexus-core';The Nexus SDK includes built-in analytics powered by PostHog to help improve the SDK and understand usage patterns. Analytics are enabled by default but can be easily customized or disabled.
By default, the SDK sends anonymous telemetry data to Avail's PostHog instance:
- SDK initialization events
- Operation performance metrics
- Session duration and success rates
- Error tracking (without sensitive data)
No wallet addresses or transaction amounts are collected unless you explicitly configure custom analytics.
const sdk = new NexusSDK({
network: 'mainnet',
analytics: { enabled: false },
});const sdk = new NexusSDK({
network: 'mainnet',
analytics: {
enabled: true,
privacy: {
anonymizeWallets: true, // Hash wallet addresses
anonymizeAmounts: true, // Exclude transaction amounts
},
},
});You can use your own PostHog instance for custom analytics:
const sdk = new NexusSDK({
network: 'mainnet',
analytics: {
enabled: true,
posthogApiKey: 'your-posthog-key',
posthogApiHost: 'https://your-posthog-instance.com',
appMetadata: {
appName: 'My DApp',
appVersion: '1.0.0',
appUrl: 'https://mydapp.com',
},
},
});// Track custom events
sdk.analytics.track('custom_event', { foo: 'bar' });
// Identify users
sdk.analytics.identify('user-id', { plan: 'premium' });
// Check if analytics is enabled
if (sdk.analytics.isEnabled()) {
console.log('Analytics active');
}
// Disable analytics at runtime
sdk.analytics.disable();
// Re-enable analytics
sdk.analytics.enable();Adding PostHog analytics increases the bundle size by approximately ~50KB gzipped. The analytics code is tree-shakeable, so if you don't use it, it won't significantly impact your bundle.
| Network | Chain ID | Native | Status |
|---|---|---|---|
| Ethereum | 1 | ETH | β |
| Optimism | 10 | ETH | β |
| Polygon | 137 | MATIC | β |
| Arbitrum | 42161 | ETH | β |
| Avalanche | 43114 | AVAX | β |
| Base | 8453 | ETH | β |
| Scroll | 534352 | ETH | β |
| Sophon | 50104 | SOPH | β |
| Kaia | 8217 | KAIA | β |
| BNB | 56 | BNB | β |
| HyperEVM | 999 | HYPE | β |
| TRON | 728126428 | TRX | β |
| Network | Chain ID | Native | Status |
|---|---|---|---|
| Optimism Sepolia | 11155420 | ETH | β |
| Polygon Amoy | 80002 | MATIC | β |
| Arbitrum Sepolia | 421614 | ETH | β |
| Base Sepolia | 84532 | ETH | β |
| Sepolia | 11155111 | ETH | β |
| Monad Testnet | 10143 | MON | β |
| Token | Name | Decimals | Availability |
|---|---|---|---|
| ETH | Ethereum | 18 | All EVM chains |
| USDC | USD Coin | 6 | All supported |
| USDT | Tether USD | 6 | All supported |
- GitHub: availproject/nexus-sdk
- Docs: docs.availproject.org