Skip to main content
The NativeOrdersFactory is used to create cross-chain swap orders with native blockchain assets (ETH, MATIC, BNB, AVAX, etc.) instead of ERC20 tokens.
This factory is re-exported from @1inch/fusion-sdk. The Cross Chain SDK extends it for cross-chain native asset swaps.

Overview

When swapping native assets, you need to:
  1. Create an order using the SDK’s submitNativeOrder() method
  2. Use NativeOrdersFactory to build the transaction
  3. Broadcast the transaction with the required native asset value

NativeOrdersFactory class

Getting an instance

import { NativeOrdersFactory, NetworkEnum } from '@1inch/cross-chain-sdk'

const factory = NativeOrdersFactory.default(NetworkEnum.AVALANCHE)

Methods

default

Static factory method to get the default instance for a chain.
static default(chainId: NetworkEnum): NativeOrdersFactory
chainId
NetworkEnum
required
The chain ID where the native order will be created
Returns: A NativeOrdersFactory instance configured for the specified chain

create

Creates a transaction call data for submitting a native order on-chain.
create(
  maker: Address,
  order: EvmCrossChainOrder
): { to: Address, data: string, value: bigint }
maker
Address
required
The address of the order maker (your wallet address)
order
EvmCrossChainOrder
required
The order object created by the SDK
Returns: An object containing:
  • to - The contract address to send the transaction to
  • data - The encoded transaction data
  • value - The amount of native asset to send (in wei)

Complete example

Here’s a complete example of creating a native asset swap from AVAX to USDC:
import {
  SDK,
  NetworkEnum,
  HashLock,
  EvmAddress,
  NativeOrdersFactory,
  Address,
  PrivateKeyProviderConnector,
  EvmCrossChainOrder
} 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://api.avax.network/ext/bc/C/rpc'
const AUTH_KEY = 'your-auth-key'

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
})

async function main(): Promise<void> {
  // Get quote for 0.4 AVAX -> USDC swap
  const quote = await sdk.getQuote({
    amount: '400000000000000000', // 0.4 AVAX
    srcChainId: NetworkEnum.AVALANCHE,
    dstChainId: NetworkEnum.BINANCE,
    enableEstimate: true,
    srcTokenAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', // Native AVAX
    dstTokenAddress: '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d', // USDC on BSC
    walletAddress: wallet.address
  })

  const preset = quote.recommendedPreset

  // 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
  const orderInfo = await sdk.submitNativeOrder(
    quote.srcChainId,
    order,
    EvmAddress.fromString(wallet.address),
    quoteId,
    secretHashes
  )
  console.log({ hash }, 'order submitted')

  // Build transaction using NativeOrdersFactory
  const factory = NativeOrdersFactory.default(NetworkEnum.AVALANCHE)
  const call = factory.create(
    new Address(wallet.address),
    orderInfo.order
  )

  // Broadcast transaction
  const txRes = await wallet.sendTransaction({
    to: call.to.toString(),
    data: call.data,
    value: call.value // This sends the native AVAX
  })

  console.log({ txHash: txRes.hash }, 'transaction broadcasted')

  await wallet.provider.waitForTransaction(txRes.hash, 3)

  // ... continue with secret submission
}

main()

Key points

Native token address

Use 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee as the token address for native assets in quotes

Transaction value

The value field from factory.create() must be included in your transaction to send the native asset

Order submission

Use sdk.submitNativeOrder() instead of sdk.submitOrder() for native asset orders

Supported chains

Native orders work on all EVM chains (ETH, MATIC, BNB, AVAX, etc.)

Native asset addresses

The native asset address constant across all chains:
const NATIVE_TOKEN = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'
You can also use the EvmAddress.NATIVE constant:
import { EvmAddress } from '@1inch/cross-chain-sdk'

const nativeAddress = EvmAddress.NATIVE

Order types

NativeOrdersImpl

The NativeOrdersImpl class is the implementation contract that handles native orders. It’s re-exported from @1inch/fusion-sdk.
import { NativeOrdersImpl } from '@1inch/cross-chain-sdk'
You typically don’t need to interact with NativeOrdersImpl directly. The NativeOrdersFactory handles the contract interaction for you.

Error handling

Make sure your wallet has enough native asset balance to cover:
  • The order amount
  • The safety deposit (if required)
  • Gas fees for the transaction
try {
  const txRes = await wallet.sendTransaction({
    to: call.to.toString(),
    data: call.data,
    value: call.value
  })
} catch (error) {
  if (error.code === 'INSUFFICIENT_FUNDS') {
    console.error('Insufficient native asset balance')
  }
  throw error
}

Build docs developers (and LLMs) love