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.
This guide demonstrates how to swap native blockchain assets like ETH, AVAX, BNB, and MATIC using the NativeOrdersFactory for transaction broadcasting.
Overview
Native token swaps require special handling:
Use 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee as the token address
Submit orders using submitNativeOrder() instead of submitOrder()
Broadcast transactions using NativeOrdersFactory
Include native token value in the transaction
Prerequisites
Wallet with sufficient native token balance
No allowance required (native tokens don’t need approval)
RPC provider supporting the source chain
Complete Example
This example swaps 0.4 AVAX from Avalanche to USDC on BSC.
Setup Dependencies
Import required modules including NativeOrdersFactory. import {
EvmCrossChainOrder ,
HashLock ,
NetworkEnum ,
OrderStatus ,
PrivateKeyProviderConnector ,
SDK ,
EvmAddress ,
NativeOrdersFactory ,
Address
} from '@1inch/cross-chain-sdk'
import { JsonRpcProvider , Wallet } from 'ethers'
import { randomBytes } from 'node:crypto'
import assert from 'node:assert'
const PRIVATE_KEY = '0x...'
const WEB3_NODE_URL = 'https://...'
const AUTH_KEY = 'auth-key'
Initialize Providers
Set up ethers provider and SDK connector. const ethersRpcProvider = new JsonRpcProvider ( WEB3_NODE_URL )
const ethersProviderConnector = {
eth: {
call ( transactionConfig ) : Promise < string > {
return ethersRpcProvider . call ( transactionConfig )
}
},
extend () : void {}
}
const connector = new PrivateKeyProviderConnector (
PRIVATE_KEY ,
ethersProviderConnector
)
const wallet = new Wallet ( PRIVATE_KEY , ethersRpcProvider )
const sdk = new SDK ({
url: 'https://api.1inch.com/fusion-plus' ,
authKey: AUTH_KEY ,
blockchainProvider: connector
})
Get Quote for Native Token
Request a quote using the native token address. const quote = await sdk . getQuote ({
amount: '400000000000000000' , // 0.4 AVAX
srcChainId: NetworkEnum . AVALANCHE ,
dstChainId: NetworkEnum . BINANCE ,
enableEstimate: true ,
srcTokenAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' , // AVAX
dstTokenAddress: '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d' , // USDC
walletAddress: wallet . address
})
const preset = quote . recommendedPreset
The address 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee is used for all native tokens (ETH, AVAX, BNB, MATIC, etc.).
Generate Secrets and Create Order
Generate secrets and create the order. async function sleep ( ms : number ) : Promise < void > {
return new Promise (( resolve ) => setTimeout ( resolve , ms ))
}
// Generate secrets
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 order
const { hash , quoteId , order } = sdk . createOrder ( quote , {
walletAddress: wallet . address ,
hashLock ,
preset ,
source: 'sdk-tutorial' ,
secretHashes
})
assert ( order instanceof EvmCrossChainOrder )
console . log ({ hash }, 'order created' )
Submit Native Order
Submit the order using submitNativeOrder() instead of submitOrder(). const orderInfo = await sdk . submitNativeOrder (
quote . srcChainId ,
order ,
EvmAddress . fromString ( wallet . address ),
quoteId ,
secretHashes
)
console . log ({ hash }, 'order submitted' )
Use submitNativeOrder() for native tokens, not submitOrder(). This ensures proper handling of native token value.
Broadcast Transaction with NativeOrdersFactory
Create the transaction call data and broadcast it. // Get factory for the source chain
const factory = NativeOrdersFactory . default ( NetworkEnum . AVALANCHE )
// Create transaction call data
const call = factory . create (
new Address ( wallet . address ),
orderInfo . order
)
// Send transaction with native token value
const txRes = await wallet . sendTransaction ({
to: call . to . toString (),
data: call . data ,
value: call . value
})
console . log ({ txHash: txRes . hash }, 'transaction broadcasted' )
// Wait for confirmation
await wallet . provider . waitForTransaction ( txRes . hash , 3 )
The call.value field contains the amount of native token to send.
Monitor and Share Secrets
Monitor escrow deployments and share secrets. while ( true ) {
const secretsToShare = await sdk . getReadyToAcceptSecretFills ( hash )
if ( secretsToShare . fills . length ) {
for ( const { idx } of secretsToShare . fills ) {
// Verify escrow addresses before sharing secrets
await sdk . submitSecret ( hash , secrets [ idx ])
console . log ({ idx }, 'shared secret' )
}
}
// Check if order finished
const { status } = await sdk . getOrderStatus ( hash )
if (
status === OrderStatus . Executed ||
status === OrderStatus . Expired ||
status === OrderStatus . Refunded
) {
break
}
await sleep ( 1000 )
}
const statusResponse = await sdk . getOrderStatus ( hash )
console . log ( statusResponse )
Key Differences from Token Swaps
Native tokens use a special address: // Native token (ETH, AVAX, BNB, etc.)
srcTokenAddress : '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'
// vs ERC20 token
srcTokenAddress : '0xc2132d05d31c914a87c6611c10748aeb04b58e8f'
Use submitNativeOrder() for native tokens: // Native tokens
const orderInfo = await sdk . submitNativeOrder (
srcChainId ,
order ,
EvmAddress . fromString ( walletAddress ),
quoteId ,
secretHashes
)
// vs ERC20 tokens
const orderInfo = await sdk . submitOrder (
srcChainId ,
order ,
quoteId ,
secretHashes
)
Use NativeOrdersFactory to create transaction data: const factory = NativeOrdersFactory . default ( NetworkEnum . AVALANCHE )
const call = factory . create ( new Address ( wallet . address ), orderInfo . order )
await wallet . sendTransaction ({
to: call . to . toString (),
data: call . data ,
value: call . value // Native token amount
})
For ERC20 tokens, the order submission handles this automatically.
Native tokens don’t require approval: // No need for:
// await token.approve(limitOrderProtocol, amount)
You can create orders immediately if you have sufficient balance.
Supported Native Tokens
Chain Native Token Address Ethereum ETH 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeePolygon MATIC 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeBSC BNB 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeAvalanche AVAX 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeArbitrum ETH 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeOptimism ETH 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
Error Handling
try {
const txRes = await wallet . sendTransaction ({
to: call . to . toString (),
data: call . data ,
value: call . value
})
await wallet . provider . waitForTransaction ( txRes . hash , 3 )
} catch ( error ) {
if ( error . message . includes ( 'insufficient funds' )) {
console . error ( 'Insufficient native token balance' )
} else if ( error . message . includes ( 'gas required exceeds allowance' )) {
console . error ( 'Insufficient gas or gas price too low' )
} else {
console . error ( 'Transaction failed:' , error )
}
throw error
}
Best Practices
Wait for Confirmation Always wait for sufficient confirmations (3+ blocks) before proceeding.
Check Balance Verify sufficient native token balance before creating orders.
Gas Estimation Ensure wallet has extra native tokens for gas fees.
Use Recommended Preset Use quote.recommendedPreset for optimal execution.
Transaction Value Calculation
The call.value includes the swap amount plus any required deposits:
const call = factory . create ( new Address ( wallet . address ), orderInfo . order )
console . log ( 'Transaction breakdown:' )
console . log ( '- Total value:' , call . value . toString ())
console . log ( '- To address:' , call . to . toString ())
console . log ( '- Call data length:' , call . data . length )
Next Steps
EVM to EVM Learn about ERC20 token swaps
Integrator Fees Add fees to your integration