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
Install the SDK
Install the package using your preferred package manager:npm install @1inch/cross-chain-sdk web3
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.
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.
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.
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.
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
Insufficient allowance error
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 })
Order expired before completion
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
Network connection errors
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: