Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/1inch/cross-chain-sdk/llms.txt

Use this file to discover all available pages before exploring further.

Overview

This guide walks you through executing a complete cross-chain swap from Polygon to BNB Chain using the 1inch Cross-Chain SDK.
Prerequisites:
  • Node.js 18.16.0 or higher
  • An API key from 1inch Developer Portal
  • A wallet with USDT on Polygon (for this example)

Steps

1

Install the SDK

Install the package using your preferred package manager:
npm install @1inch/cross-chain-sdk web3
2

Set up the SDK

Initialize the SDK with your private key and API authentication:
import { SDK, PrivateKeyProviderConnector, NetworkEnum } from '@1inch/cross-chain-sdk'
import Web3 from 'web3'

const privateKey = process.env.PRIVATE_KEY // Your wallet private key
const rpc = 'https://polygon-rpc.com'
const authKey = process.env.AUTH_KEY // From 1inch Developer Portal

const web3 = new Web3(rpc)
const walletAddress = web3.eth.accounts.privateKeyToAccount(privateKey).address

const sdk = new SDK({
  url: 'https://api.1inch.com/fusion-plus',
  authKey,
  blockchainProvider: new PrivateKeyProviderConnector(privateKey, web3)
})

console.log(`Wallet: ${walletAddress}`)
Never commit your private key to version control. Use environment variables or a secure key management solution.
3

Get a quote

Request a quote for swapping 10 USDT on Polygon to BNB on BNB Chain:
import { PresetEnum } from '@1inch/cross-chain-sdk'

const quote = await sdk.getQuote({
  amount: '10000000', // 10 USDT (6 decimals)
  srcChainId: NetworkEnum.POLYGON,
  dstChainId: NetworkEnum.BINANCE,
  enableEstimate: true, // Required for order creation
  srcTokenAddress: '0xc2132d05d31c914a87c6611c10748aeb04b58e8f', // USDT on Polygon
  dstTokenAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', // Native BNB
  walletAddress
})

console.log(`Expected output: ${quote.dstTokenAmount} BNB`)
console.log(`Recommended preset: ${quote.recommendedPreset}`)
The enableEstimate: true flag generates a quoteId required for order creation.
4

Generate secrets

Create cryptographic secrets for the atomic swap:
import { HashLock } from '@1inch/cross-chain-sdk'
import { randomBytes } from 'crypto'

const preset = PresetEnum.fast

// Generate secrets based on preset requirements
const secrets = Array.from({
  length: quote.presets[preset].secretsCount
}).map(() => '0x' + randomBytes(32).toString('hex'))

// Create hash lock
const hashLock = secrets.length === 1
  ? HashLock.forSingleFill(secrets[0])
  : HashLock.forMultipleFills(HashLock.getMerkleLeaves(secrets))

// Hash secrets for submission
const secretHashes = secrets.map(s => HashLock.hashSecret(s))

console.log(`Generated ${secrets.length} secret(s)`)
Secrets are cryptographic commitments that ensure the swap is atomic. You’ll reveal them later to complete the swap.
5

Create and submit order

Create the order and submit it to the 1inch relayer:
// Create order
const { hash, quoteId, order } = await sdk.createOrder(quote, {
  walletAddress,
  hashLock,
  preset,
  source: 'sdk-quickstart',
  secretHashes
})

console.log(`Order created: ${hash}`)

// Submit order
const orderInfo = await sdk.submitOrder(
  quote.srcChainId,
  order,
  quoteId,
  secretHashes
)

console.log('Order submitted successfully')
Ensure your wallet has approved USDT spending for the Limit Order Protocol contract before submitting.
6

Monitor and complete the swap

Watch for escrow deployments and submit secrets to complete the swap:
import { OrderStatus } from '@1inch/cross-chain-sdk'

console.log('Monitoring order...')

while (true) {
  // Check for ready fills
  const secretsToShare = await sdk.getReadyToAcceptSecretFills(hash)

  if (secretsToShare.fills.length) {
    for (const { idx } of secretsToShare.fills) {
      await sdk.submitSecret(hash, secrets[idx])
      console.log(`Submitted secret ${idx}`)
    }
  }

  // Check order status
  const { status } = await sdk.getOrderStatus(hash)

  if (
    status === OrderStatus.Executed ||
    status === OrderStatus.Expired ||
    status === OrderStatus.Refunded
  ) {
    console.log(`Order completed with status: ${status}`)
    break
  }

  // Wait before checking again
  await new Promise(resolve => setTimeout(resolve, 2000))
}

// Get final status
const finalStatus = await sdk.getOrderStatus(hash)
console.log('Final status:', finalStatus)
The resolver deploys escrows on both chains. Once deployed, you submit secrets to unlock the funds and complete the swap.

Complete Example

Here’s the full code for a working cross-chain swap:
import {
  SDK,
  PrivateKeyProviderConnector,
  NetworkEnum,
  HashLock,
  PresetEnum,
  OrderStatus
} from '@1inch/cross-chain-sdk'
import Web3 from 'web3'
import { randomBytes } from 'crypto'

async function main() {
  // Setup
  const privateKey = process.env.PRIVATE_KEY
  const web3 = new Web3('https://polygon-rpc.com')
  const walletAddress = web3.eth.accounts.privateKeyToAccount(privateKey).address

  const sdk = new SDK({
    url: 'https://api.1inch.com/fusion-plus',
    authKey: process.env.AUTH_KEY,
    blockchainProvider: new PrivateKeyProviderConnector(privateKey, web3)
  })

  // Get quote
  const quote = await sdk.getQuote({
    amount: '10000000',
    srcChainId: NetworkEnum.POLYGON,
    dstChainId: NetworkEnum.BINANCE,
    enableEstimate: true,
    srcTokenAddress: '0xc2132d05d31c914a87c6611c10748aeb04b58e8f',
    dstTokenAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
    walletAddress
  })

  // Generate secrets
  const preset = PresetEnum.fast
  const secrets = Array.from({ length: quote.presets[preset].secretsCount })
    .map(() => '0x' + randomBytes(32).toString('hex'))
  
  const hashLock = secrets.length === 1
    ? HashLock.forSingleFill(secrets[0])
    : HashLock.forMultipleFills(HashLock.getMerkleLeaves(secrets))
  
  const secretHashes = secrets.map(s => HashLock.hashSecret(s))

  // Create and submit order
  const { hash, quoteId, order } = await sdk.createOrder(quote, {
    walletAddress,
    hashLock,
    preset,
    source: 'sdk-quickstart',
    secretHashes
  })

  await sdk.submitOrder(quote.srcChainId, order, quoteId, secretHashes)
  console.log(`Order submitted: ${hash}`)

  // Monitor and complete
  while (true) {
    const secretsToShare = await sdk.getReadyToAcceptSecretFills(hash)

    if (secretsToShare.fills.length) {
      for (const { idx } of secretsToShare.fills) {
        await sdk.submitSecret(hash, secrets[idx])
      }
    }

    const { status } = await sdk.getOrderStatus(hash)
    if (status === OrderStatus.Executed) {
      console.log('Swap completed!')
      break
    }

    await new Promise(resolve => setTimeout(resolve, 2000))
  }
}

main().catch(console.error)

Next Steps

Core Concepts

Learn how atomic swaps work under the hood

EVM to EVM Guide

Detailed guide for EVM chain swaps

Solana Integration

Bridge assets between Solana and EVM chains

API Reference

Explore the complete SDK API

Troubleshooting

Your wallet needs to approve USDT spending for the Limit Order Protocol contract. Use:
// Approve USDT for Limit Order Protocol
const tokenContract = new web3.eth.Contract(ERC20_ABI, srcTokenAddress)
await tokenContract.methods.approve(
  LIMIT_ORDER_PROTOCOL_ADDRESS,
  '115792089237316195423570985008687907853269984665640564039457584007913129639935' // Max uint256
).send({ from: walletAddress })
Orders have time limits. If an order expires:
  • Funds are automatically refunded to your source chain wallet
  • Try again with a fast preset for quicker execution
  • Ensure you submit secrets promptly when fills become ready
If you experience RPC connection issues:
  • Use a reliable RPC provider (avoid public RPCs for production)
  • Implement retry logic with exponential backoff
  • Consider using services like Infura, Alchemy, or QuickNode

Support

Need help? Check out these resources: