⚙️
Native Developers
  • Native V1
    • Overview
    • Operations
      • Single-Hop Transaction: Off-chain Pricing
      • Single-Hop Transaction: On-chain Pricing
      • Multi-Hop Transaction
      • L1 Token Swap
      • Creating a Pool
      • Updating a Pool
    • System Components
      • GUI
      • Native Backend
      • Pricer
      • Registry
      • Signer
      • Pool
      • Pool Factory
      • Treasury
      • Router
    • Smart Contracts
      • Core
        • Registry
        • NativePool
        • NativePoolFactory
        • NativeRouter
      • Liquidity Pools
    • Contract Address
    • API References
      • GET /v1/indicative-quote
      • GET /v1/orderbook
      • GET v1/firm-quote
      • GET v1/firm-quote/calldata
    • Guide
      • Get quote for ETH to USDT
      • Execute ETH to USDT swap on Native
    • Routing
  • Market Maker Integration
    • WebSocket Connection
Powered by GitBook
On this page
  • Typescript
  • Python
  1. Native V1
  2. Guide

Execute ETH to USDT swap on Native

The following examples get transaction data to swap 1 ETH -> USDT on Ethereum and then submit the transaction data to Native Router to execute.

PreviousGet quote for ETH to USDTNextRouting

Last updated 1 year ago

Native infrastructure allows both on-chain and off-chain pricing to be used for a swap. Signer generates transaction data signature for the swap to be executed on-chain securely on Native smart contracts. Only two steps are required to start using Native.

  1. Call firm-quote to obtain transaction data.

  2. Submit the transaction data to Native Router to execute the swap. The security of the swap is ensured by transaction data signature.

Native Router addresses can be found at Native Router (proxy) records in section.

Typescript

import axios from 'axios';
import {ethers} from "ethers";
import routerAbi from './nativeRouter.json'

const apiKey = '' // Contact Native to get your API key;
const baseUrl = 'https://newapi.native.org/v1/';

const provider = 'https://eth.llamarpc.com';
const routerAddress = '0xEAd050515E10fDB3540ccD6f8236C46790508A76'; // Refer to Contract Address section -> NativeRouter (Proxy) for the address

const walletAddress = ''; // Your address
const privateKey = ''; // Your private key for the address above

// Swap input
const chain = 'ethereum'; // 1, 56
const tokenIn = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; // ETH
const tokenOut = '0xdAC17F958D2ee523a2206206994597C13D831ec7'; // USDT
const amount = 1; // in ether, not in wei

type FirmQuoteResult = {
  orders: any[],
  widgetFee: {
    signer: string,
    feeRecipient: string,
    feeRate: number
  },
  widgetFeeSignature: string,
  calldata: string,
  amountIn: string,
  amountOut: string,
  fallbackData: string
}

async function callFirmQuote(): Promise<FirmQuoteResult> {
  const endpoint = 'firm-quote?';
  const headers: any = {
    api_key: apiKey,
  };

  const response = await axios
    .get(
      `${baseUrl}${endpoint}chain=${chain}&token_in=${tokenIn}&token_out=${tokenOut}&amount=${amount}&address=${walletAddress}`,
      {
        headers,
      }
    )
  console.log('Firm quote result', response.data)
  return response.data;
}

function getRouterContract(): ethers.Contract {
  const jsonRpcProvider = new ethers.JsonRpcProvider(provider);
  const signer = new ethers.Wallet(privateKey, jsonRpcProvider);
  const routerContract = new ethers.Contract(routerAddress, routerAbi, signer);
  return routerContract
}

async function callRouterToSwap(firmQuoteResult: FirmQuoteResult) {
  const routerContract = getRouterContract();
  const args = {
    orders: firmQuoteResult.calldata,
    recipient: walletAddress,
    amountIn: firmQuoteResult.amountIn,
    amountOutMinimum: 0, // use this to specify your slippage tolerance
    widgetFee: {
      signer: firmQuoteResult.widgetFee.signer,
      feeRecipient: firmQuoteResult.widgetFee.feeRecipient,
      feeRate: firmQuoteResult.widgetFee.feeRate,
    },
    widgetFeeSignature: firmQuoteResult.widgetFeeSignature,
    fallbackSwapDataArray: firmQuoteResult.fallbackData,
  }
  const functionName = firmQuoteResult.orders.length > 1 ? 'exactInput' : 'exactInputSingle'
  const tx = await routerContract[functionName](args);
  await tx.wait()
}

async function main() {
  const firmQuoteResult = await callFirmQuote();
  await callRouterToSwap(firmQuoteResult)
}

main();

Python

import os
import json
import requests
import asyncio
import urllib.parse
from decimal import Decimal
from web3 import AsyncHTTPProvider, Web3
from web3.eth import AsyncEth
from web3.net import AsyncNet
from web3.middleware import async_geth_poa_middleware
from async_web3_helper import constructAsyncSignAndSendRawMiddleware

apiKey = '' # Contact Native to get your API key;
baseUrl = 'https://newapi.native.org/v1/';

provider = 'https://eth.llamarpc.com';
routerAddress = '0xEAd050515E10fDB3540ccD6f8236C46790508A76'; # Refer to Contract Address section -> NativeRouter (Proxy) for the address

walletAddress = ''; # Your address
privateKey = ''; # Your private key for the address above
path_to_native_router_abi_json = ""

# Swap input
chainId = 'ethereum'; # 1, 56
tokenIn = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; # ETH
tokenOut = '0xdAC17F958D2ee523a2206206994597C13D831ec7'; # USDT
amount = 1; # in ether, not in wei

# firm quote
def call_firm_quote():
    endpoint = "firm-quote?"
    params = {
        "chain": chain,
        "token_in": tokenIn,
        "token_out": tokenOut,
        "amount": amount,
        "address": walletAddress,
    }
    response = requests.request(
        "GET",
        baseUrl + endpoint + urllib.parse.urlencode(params),
        data="",
        headers={
            "apiKey": apiKey,
        },
        params=params,
        timeout=3,
    )

    print("Get firm quote")
    print(response.status_code)
    print(response.json())

    return response.json()


# call router to swap
def loadAbi(name: str):
    with open(path_to_native_router_abi_json) as json_file:
        json_data = json.load(json_file)
        return json_data


async def loadContract(web3: Web3, contractAddress: str, abiName: str):
    address = web3.to_checksum_address(contractAddress)
    abi = loadAbi(abiName)
    return web3.eth.contract(address=address, abi=abi)


async def getRouterContract(web3: Web3):
    return await loadContract(web3, routerAddress, "Router")


async def callRouterToSwap(calldata, fallbackData, orders, widgetFee, widgetFeeSignature):
    web3 = Web3(
        AsyncHTTPProvider(provider),
        modules={"eth": AsyncEth, "net": AsyncNet},
        middlewares=[],
    )
    web3.middleware_onion.inject(async_geth_poa_middleware, layer=0)
    web3.middleware_onion.add(constructAsyncSignAndSendRawMiddleware(privateKey))

    routerContract = await getRouterContract(web3)
  
    tx = {
        "chainId": await web3.eth.chain_id,
        "from": web3.to_checksum_address(walletAddress),
        "nonce": await web3.eth.get_transaction_count(walletAddress),
        "gasPrice": await web3.eth.gas_price,
    }
    widgetFeeTuple = (
        widgetFee["signer"],
        widgetFee["feeRecipient"],
        int(widgetFee["feeRate"]),
    )
    
    sendTx = None
    useExactInputSingle = len(orders) == 1
    args = (
                calldata,
                web3.to_checksum_address(walletAddress),
                int(orders[0]["sellerTokenAmount"]),
                0, #use this to specify your slippage tolerance
                widgetFeeTuple,
                widgetFeeSignature,
                fallbackData
            )
    if useExactInputSingle:
        sendTx = await routerContract.functions.exactInput(args).transact(tx)
    else:
        sendTx = await routerContract.functions.exactInputSingle(args).transact(tx)
    txReceipt = await web3.eth.wait_for_transaction_receipt(sendTx)
    return txReceipt


def main():
    firmQuoteRes = call_firm_quote()

    loop = asyncio.get_event_loop()

    calldata = firmQuoteRes["calldata"]
    orders = firmQuoteRes["orders"]
    widgetFee = firmQuoteRes["widgetFee"]
    widgetFeeSignature = firmQuoteRes["widgetFeeSignature"]
    fallbackData = firmQuoteRes["fallbackData"]

    tasks = [callRouterToSwap(calldata, fallbackData, orders, widgetFee, widgetFeeSignature)]

    caroutines = asyncio.gather(*tasks)
    txReceipt = loop.run_until_complete(caroutines)

    loop.close()


main()
Smart Contracts