Skip to Content
Avail Nexus is now live! Check out our docs to get started.
NexusNexus SDK ReferenceHooks and Errors

Hooks and Events

The Nexus SDK comes baked in with some helpful hooks and error codes to make your development experience easier.

Hooks

onEvent

Supported by all main SDK functions, this hook allows you to subscribe to progress events for submitted transactions.

Signature

Typescript
/** * EventUnion is a union type of all possible event types. */ type EventUnion = | { name: 'STEPS_LIST'; args: BridgeStepType[] } | { name: 'STEP_COMPLETE'; args: BridgeStepType } | { name: 'SWAP_STEP_COMPLETE'; args: SwapStepType }; type OnEventParam = { onEvent?: (event: EventUnion) => void; };

Example

Use onEvent to log the progress of a transaction to the console:

Typescript
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); }, }, );

STEPS_LIST is emitted with bridge(), bridgeAndTransfer() and bridgeAndExecute(). swapWithExactIn() and swapWithExactOut() however do emit SWAP_STEP_COMPLETE instead.

Typescript
const swapResult = await sdk.swapWithExactIn( { from: [{ chainId: 10, amount: 1_000_000n, tokenAddress: '0x...' }], toChainId: 8453, toTokenAddress: '0x...', }, { onEvent: (event) => { if (event.name === NEXUS_EVENTS.SWAP_STEP_COMPLETE) { console.log('Swap step:', event.args); } }, }, );

onIntentHook

This hook allows you to give your user a way to approve or deny the intent.

Signature

Typescript
type OnIntentHookData = { allow: () => void; deny: () => void; intent: ReadableIntent; // human-readable breakdown of sources, destination, fees refresh: (selectedSources?: number[]) => Promise<ReadableIntent>; // recompute plan };
  • Call allow() to continue or deny() to abort. Model this behaviour behind allow and deny buttons in your UI.
  • If you need to re-plan (e.g., change source chains), call refresh(...) and re-render.
  • On allow, the SDK marks INTENT_ACCEPTED and proceeds to the allowance phase (if required).

Example

Typescript
sdk.setOnIntentHook(({ intent, allow, deny, refresh }) => { // Render the plan and fees to the user using `intent` // Optionally let the user change source chains if (userApproves) allow(); else deny(); });
  • If you don’t set this hook, the SDK defaults to allowing the intent automatically.
  • After acceptance, allowance approvals (if any) are handled via onAllowance.

onSwapIntentHook

Use this hook to prompt the user to approve or deny the swap plan before execution begins.

Signature

Typescript
type OnSwapIntentHookData = { allow: () => void; deny: () => void; intent: SwapIntent; refresh: () => Promise<SwapIntent>; };

Lifecycle:

  • Called during swapWithExactIn() / swapWithExactOut() after a route is computed and before the actual swap is executed.
  • refresh() recomputes the route (e.g., after user changes inputs); call allow() to proceed or deny() to abort.
  • If you don’t set this hook, the SDK defaults to allowing the swap automatically.

Example

Typescript
sdk.setOnSwapIntentHook(({ intent, allow, deny, refresh }) => { // Render swap route and destination details from `intent` // Optionally call `refresh()` if the user tweaks inputs if (userApproves) allow(); else deny(); });

onAllowanceHook

Use this hook to allow your users to approve or deny any additional allowances that are required for an intent to go through.

Signature

Typescript
type OnAllowanceHookData = { allow: (values: Array<'max' | 'min' | bigint | string>) => void; deny: () => void; sources: { allowance: { current: string; minimum: string }; chain: { id: number; logo: string; name: string }; token: { contractAddress: `0x${string}`; decimals: number; logo: string; name: string; symbol: string }; }[]; };
  • Call allow(values) to approve the allowances. values is an array of strings, numbers, or bigints that represent the amount of the allowance.
  • Call deny() to abort if the user does not want to approve the allowances.
  • sources is an array of objects that represent the sources of the allowances.

Example

Typescript
sdk.setOnAllowanceHook(({ allow, deny, sources }) => { // `sources` is an array of objects with minAllowance, chainID, token symbol, etc. // allow(values): continues the transaction flow with the specified allowances; // `values` is an array with the chosen allowance for each of the requirements (values.length === sources.length), either 'min', 'max', a bigint or a string // deny(): stops the flow if (userApproves) allow(['min']); // or ['max'] or custom per source else deny(); });
  • Values:
    • ‘min’: set minimum required allowance for that source
    • ‘max’: set unlimited (maxUint256) for that source`

Behavior:

  • Fires after the intent is accepted via setOnIntentHook.
  • If not set, the SDK defaults to min for each source.
  • Progress events for approvals appear via onEvent as allowance steps complete.

Error Codes

The Nexus SDK uses the NexusError class to throw errors. It extends the built-in Error class and adds a code property to the error object.

Typescript
function handleNexusError(err: unknown) { if (err instanceof NexusError) { console.error(`[${err.code}] ${err.message}`); if (err.data?.context) { console.error(`Context: ${err.data.context}`); } if (err.data?.details) { console.error('Details:', err.data.details); } switch (err.code) { case ERROR_CODES.USER_DENIED_INTENT: case ERROR_CODES.USER_DENIED_ALLOWANCE: alert('You rejected the transaction. Please try again.'); break; case ERROR_CODES.INSUFFICIENT_BALANCE: alert('Your wallet does not have enough funds.'); break; case ERROR_CODES.TRON_DEPOSIT_FAIL: case ERROR_CODES.FUEL_DEPOSIT_FAIL: console.warn('Deposit failed'); // Possibly ask user to retry break; default: // Unknown but typed error console.error('Unexpected NexusError:', err.toJSON()); } // Optional: logErrorToService(err.toJSON()); } else { // Non-Nexus errors (network, library, etc.) console.error('Unexpected error:', err); } }

Complete List of ERROR_CODES

The Nexus SDK also provides a list of error codes that can be used to identify the type of error that occurred, and handle them accordingly.

You can view the list of error codes and their signatures respectively in the Nexus SDK Github repo:

Typescript
import { ERROR_CODES } from '@avail-project/nexus-core'; export const ERROR_CODES = { INVALID_VALUES_ALLOWANCE_HOOK: 'INVALID_VALUES_ALLOWANCE_HOOK', SDK_NOT_INITIALIZED: 'SDK_NOT_INITIALIZED', CHAIN_NOT_FOUND: 'CHAIN_NOT_FOUND', INTERNAL_ERROR: 'INTERNAL_ERROR', TOKEN_NOT_SUPPORTED: 'TOKEN_NOT_SUPPORTED', TRON_DEPOSIT_FAIL: 'TRON_DEPOSIT_FAIL', TRON_APPROVAL_FAIL: 'TRON_APPROVAL_FAIL', FUEL_DEPOSIT_FAIL: 'FUEL_DEPOSIT_FAIL', LIQUIDITY_TIMEOUT: 'LIQUIDITY_TIMEOUT', USER_DENIED_INTENT: 'USER_DENIED_INTENT', USER_DENIED_ALLOWANCE: 'USER_DENIED_ALLOWANCE', USER_DENIED_INTENT_SIGNATURE: 'USER_DENIED_INTENT_SIGNATURE', INSUFFICIENT_BALANCE: 'INSUFFICIENT_BALANCE', WALLET_NOT_CONNECTED: 'WALLET_NOT_CONNECTED', USER_DENIED_SIWE_SIGNATURE: 'USER_DENIED_SIWE_SIGNATURE', FETCH_GAS_PRICE_FAILED: 'FETCH_GAS_PRICE_FAILED', SIMULATION_FAILED: 'SIMULATION_FAILED', CONNECT_ACCOUNT_FAILED: 'CONNECT_ACCOUNT_FAILED', VAULT_CONTRACT_NOT_FOUND: 'VAULT_CONTRACT_NOT_FOUND', SLIPPAGE_EXCEEDED_ALLOWANCE: 'SLIPPAGE_EXCEEDED_ALLOWANCE', RFF_FEE_EXPIRED: 'RFF_FEE_EXPIRED', } as const;
Last updated on