Awarizon
DOCS/@awarizon/swap

@awarizon/swap

Multichain and cross-chain swaps behind one API. Every capable provider is queried in parallel and quotes come back sorted by output amount. Try it live on the swap demo.

Same-chain EVM0x Swap API v2 + LI.FISWAP
Same-chain SolanaJupiter + LI.FISWAP
Cross-chainEVM ↔ EVM, EVM ↔ Solana via LI.FIBRIDGE
Install
$npm install @awarizon/swap
💡

Executing swaps that start on Solana also needs @solana/web3.js (an optional peer dependency, loaded only when used).

new SwapClient(config)

swap.ts
import { SwapClient } from "@awarizon/swap"

export const swap = new SwapClient({
  integrator: "my-app",                  // LI.FI integrator id
  zeroEx:  { baseUrl: "/api/swap/0x" },  // your proxy — keeps the 0x key server-side
  lifi:    { baseUrl: "/api/swap/lifi" },
  jupiter: { baseUrl: "/api/swap/jupiter" },
})
SwapClientConfig
assetListUrlstring | string[]Hosted token list URL(s), tried in order. Defaults to the Awarizon list on jsDelivr.
assetListSwapListInline list — skips fetching (tests, SSR).
integratorstringLabel sent to LI.FI; needed for fee collection.
fee{ bps, evmRecipient?, solanaFeeAccount? }Integrator fee in basis points for 0x and Jupiter routes.
zeroEx{ apiKey?, baseUrl? }0x is skipped unless one of these is set.
lifi{ apiKey?, baseUrl? }Optional key for higher rate limits.
jupiter{ apiKey?, baseUrl? }Uses lite-api without a key.
rpcUrlsRecord<number, string>Override RPCs per chain id (recommended for Solana: 501000101).
defaultSlippageBpsnumberDefault 50 (0.5%).

getQuotes(request)

Tokens can be symbols from the list or any address. Amounts are in base units. fromAddress is optional — without it you get indicative previews.

TS
const { best, quotes, errors } = await swap.getQuotes({
  fromChainId: 8453,        // Base
  toChainId: 501000101,     // Solana
  fromToken: "USDC",
  toToken: "SOL",
  amount: "25000000",       // 25 USDC (6 decimals)
  fromAddress: "0x…",
  toAddress: "7xKX…",       // required when chain types differ
  slippageBps: 50,
})

best.toAmount            // base units of SOL
best.toAmountMin         // after slippage
best.steps               // [{ type: "bridge", tool: "Mayan (Swift)", … }]
best.estimatedDurationSec

execute(quote, signers)

Switches the wallet to the right chain (adding it if needed), approves the token when required, signs, submits, waits for confirmation and — for cross-chain routes — tracks the bridge until funds arrive.

TS
import { evmSignerFromEip1193 } from "@awarizon/swap"

const result = await swap.execute(best, {
  evm: evmSignerFromEip1193(window.ethereum),
  solana: window.phantom?.solana,   // any wallet-adapter-shaped wallet
}, {
  approval: "exact",                // or "infinite"
  onUpdate: (u) => console.log(u.stage, u.message, u.txLink),
})

// preparing → switching-chain → approving → signing → submitted → confirming → bridging → done
💡

Using wagmi? Wrap its wallet client with evmSignerFromViem(walletClient).

Server proxy

Keep aggregator keys off the client. The proxy forwards only the quote, swap, status and token endpoints, so it can’t be used as an open relay.

app/api/swap/[...path]/route.ts
import { createSwapProxy } from "@awarizon/swap/server"

const proxy = createSwapProxy({
  basePath: "/api/swap",
  zeroExApiKey: process.env.ZEROX_API_KEY,
  lifiApiKey: process.env.LIFI_API_KEY,
  jupiterApiKey: process.env.JUPITER_API_KEY,
})

export const GET = proxy
export const POST = proxy

Tokens & chains

TS
await swap.assets.load()
swap.assets.chains()                        // enabled mainnet chains
swap.assets.tokens(8453)                    // listed + user-imported tokens
await swap.assets.search("usdc", 8453)      // symbol / name, or a pasted address
await swap.assets.resolveToken(8453, "0x…") // list → imports → on-chain lookup
ℹ️

Chain ids are EVM chain ids; Solana is 501000101. Provider-specific ids (e.g. LI.FI’s Solana id) are mapped for you by the token list.