WDK logoWDK documentation

LI.FI Swidge Usage

Install and use @lifi/wdk-protocol-swidge-lifi for LI.FI swap and bridge routes.

Community modules are developed and maintained independently by third-party contributors.

Tether and the WDK Team do not endorse or assume responsibility for their code, security, or maintenance. Use your own judgment and proceed at your own risk.

Install

npm install @lifi/wdk-protocol-swidge-lifi

Install the wallet module for the account type you plan to use:

npm install @tetherto/wdk-wallet-evm

For an ERC-4337 smart account, install its wallet module instead:

npm install @tetherto/wdk-wallet-evm-erc-4337

Create the Protocol

import { WalletAccountEvm } from '@tetherto/wdk-wallet-evm'
import { LifiSwidgeProtocol } from '@lifi/wdk-protocol-swidge-lifi'

const account = new WalletAccountEvm(seedPhrase, "0'/0/0", {
  provider: 'https://mainnet.infura.io/v3/YOUR_KEY'
})

const swidge = new LifiSwidgeProtocol(account, {
  integrator: 'my-app',
  order: 'RECOMMENDED'
})

Discover Chains and Tokens

Discovery calls are read-only. They can be used before a wallet account is available.

const discovery = new LifiSwidgeProtocol(undefined, {
  provider: 'https://mainnet.infura.io/v3/YOUR_KEY'
})

const chains = await discovery.getSupportedChains()
const ethereumTokens = await discovery.getSupportedTokens({
  fromChain: 1
})

Use returned chain and token identifiers when building route forms.

Quote a Route

Call quoteSwidge() before execution so users can review the expected output and fees.

const route = {
  fromToken: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  toToken: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  toChain: 'arbitrum',
  fromTokenAmount: 10_000_000n,
  slippage: 0.01
}

const quote = await swidge.quoteSwidge(route)

console.log('Expected output:', quote.toTokenAmount)
console.log('Minimum output:', quote.toTokenAmountMin)
console.log('Fees:', quote.fees)

When sending to another account, set recipient to its complete EVM address. If omitted, the module uses the bound account address.

For same-chain swaps, omit toChain and provide the destination token on the source chain.

const quote = await swidge.quoteSwidge({
  fromToken: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
  toToken: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
  fromTokenAmount: 10_000_000n
})

Execute a Route

After the user confirms the quote, call swidge() with the same route shape. The module handles required ERC-20 approvals, including reset-to-zero flows for tokens such as USDT on Ethereum.

const result = await swidge.swidge(route, {
  maxNetworkFeeBps: 100,
  maxProtocolFeeBps: 50
})

console.log('Swidge ID:', result.id)
console.log('Transaction hash:', result.hash)

Guard a quote-first flow with minAmountOut

swidge() fetches a fresh quote at execution time, which can differ from the quote the user reviewed. Pass minAmountOut — the toTokenAmountMin from the displayed quote — to reject execution if the fresh quote's minimum output has dropped below what the user accepted. The guard runs before any approval or transaction is sent, and the value is never forwarded to LI.FI.

const quote = await swidge.quoteSwidge(route)
// ...user reviews and confirms the quote...

const result = await swidge.swidge({
  ...route,
  minAmountOut: quote.toTokenAmountMin
})

Track Status

swidge() returns after the source transaction is broadcast. Use getSwidgeStatus() with the returned operation ID to follow the route to a terminal state. Chain hints can speed up indexing. LI.FI can return NOT_FOUND while a transaction is waiting to be indexed; keep polling only for that status error.

import { LifiStatusError } from '@lifi/wdk-protocol-swidge-lifi'

const terminalStatuses = new Set([
  'completed',
  'failed',
  'refunded',
  'partial',
  'cancelled',
  'expired'
])
const maxStatusAttempts = 60

let status

for (let attempt = 0; attempt < maxStatusAttempts; attempt += 1) {
  if (attempt > 0) {
    await new Promise(resolve => setTimeout(resolve, 10_000))
  }

  try {
    const statusResult = await swidge.getSwidgeStatus(result.id, {
      fromChain: 1,
      toChain: 42161
    })
    status = statusResult.status
  } catch (error) {
    if (error instanceof LifiStatusError && error.lifiStatus === 'NOT_FOUND') {
      continue
    }

    throw error
  }

  console.log('Route status:', status)

  if (terminalStatuses.has(status)) {
    break
  }
}

if (!terminalStatuses.has(status)) {
  throw new Error('Timed out waiting for a terminal LI.FI status')
}

Handle Common Failures

import {
  LifiProtocolError,
  LifiRateLimitError,
  LifiSlippageError,
  LifiTimeoutError
} from '@lifi/wdk-protocol-swidge-lifi'

try {
  await swidge.swidge(route)
} catch (error) {
  if (error instanceof LifiSlippageError) {
    // Request a fresh quote before retrying.
  } else if (error instanceof LifiRateLimitError || error instanceof LifiTimeoutError) {
    // Retry later or use a configured API key.
  } else if (error instanceof LifiProtocolError) {
    // Handle another LI.FI module error.
  }
}

On this page