Sign-Quote

After we validate the firm quote, we will ask you to sign the quote to give permission for the swapper for the approved amount. The sign quote endpoint provided must adhere to the following format:

Sign Quote Endpoint

POST <base-url>/sign-quote

Params

NameDescription

nonce

ID to prevent transaction to be executed more than once. Incremental for each transaction by txOrigin and pool.

signer

Public address of the signer that will sign this order.

seller

The address that will send seller token to market maker.

buyer

Native pool contract address that will execute this order.

sellerTokenAmount

The token input amount of the order. In wei.

buyerTokenAmount

The token output amount of the order. In wei. Can be modified by the signer to determine the final output amount.

sellerToken

The ERC20 token address will be sent to market maker.

buyerToken

The ERC20 token address will receive from market maker.

chainId

Chain ID of the network. In integer. eg: 1 for Ethereum, 56 for BSC.

deadlineTimestamp

The expiration time of the order, in block timestamp. Can be modified by the signer to determine the expiration time.

txOrigin

Address of the trader who initiated the order.

quoteId

Unique ID for this order request in UUID v5.

auth

The auth string received from get-quote. Can be used by the signer to verify the authenticity of the quote data. Signer and pricer can decide what auth protocol to use. Native just relay the auth string from pricer to signer.

Example body

{
    "nonce": 0,
    "signer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
    "buyer": "0xaaE854bdd940cf402d79e8051DC7E3390e32A3ac",
    "seller": "0x7d1F5C43998570629f5d00134321fB6a95451ec3",
    "buyerToken": "0x55d398326f99059ff775485246999027b3197955",
    "sellerToken": "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
    "buyerTokenAmount": "10100000000000000000000", // From firm-quote
    "sellerTokenAmount": "10000000000000000000000",
    "deadlineTimestamp": "1671086729", // From firm-quote
    "chainId": 56,
    "txOrigin": "0x7d1F5C43998570629f5d00134321fB6a95451ec3",
    "auth": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9", // From firm-quote
    "quoteId": "62716-206e-41cb-8559-013f1ed1a65a"
}

In this example, a user requests to sign an order of 10,000 USDC to 10,100 USDT on Binance Smart Chain (BSC) to be transacted on market maker's Native pool (0xaaE854bdd940cf402d79e8051DC7E3390e32A3ac). The order has to be signed by the signer (0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266) to be successfully executed on-chain.

Order signing

Native utilises EIP-712 signature to ensure the order is endorsed only by the assigned signer. The inputs required to sign the order corresponds to the data sent in POST sign-quote above. The code snippet below generates bytes encoded in hexdecimal to be returned in response for the POST /sign-quote request.

async function signOrderNative(data) {
    const wallet = new ethers.Wallet(privateKey, provider);
    const order = {
        id: data.nonce,
        signer: data.signer,
        buyer: data.buyer,
        seller: data.seller,
        buyerToken: data.buyerToken,
        sellerToken: data.sellerToken,
        buyerTokenAmount: data.buyerTokenAmount,
        sellerTokenAmount: data.sellerTokenAmount,
        deadlineTimestamp: data.deadlineTimestamp,
        caller: data.txOrigin,
        quoteId: data.quoteId
    };
    const signature = await generateSignature(order, wallet, data.buyer, data.chainId);

    return {
        success: true,
        signature: signature,
        order: order
    };
}

async function generateSignature(data, wallet, nativePool, chainId){
    const signatureData = {
        types: {
            Order: [
                { name: "id", type: "uint256" },
                { name: "signer", type: "address" },
                { name: "buyer", type: "address" },
                { name: "seller", type: "address" },
                { name: "buyerToken", type: "address" },
                { name: "sellerToken", type: "address" },
                { name: "buyerTokenAmount", type: "uint256" },
                { name: "sellerTokenAmount", type: "uint256" },
                { name: "deadlineTimestamp", type: "uint256" },
                { name: "caller", type: "address" },
                { name: "quoteId", type: "bytes16" }
            ],
        },
        primaryType: 'Order',
        domain: {
            name: "native pool",
            version: "1",
            verifyingContract: nativePool,
            chainId
        },
        message: {
            id: order.id,
            signer: order.signer,
            buyer: order.buyer,
            seller: order.seller,
            buyerToken: order.buyerToken,
            sellerToken: order.sellerToken,
            buyerTokenAmount: order.buyerTokenAmount,
            sellerTokenAmount: order.sellerTokenAmount,
            deadlineTimestamp: order.deadlineTimestamp,
            caller: order.caller,
            quoteId: Buffer.from(order.quoteId.replace(/-/g, ""), "hex")
        },
    }

    const signature = await userSigner._signTypedData(signatureData.domain, signatureData.types, signatureData.message);
    return signature;
}

Response

You need to provide a response in the following format:

NameDescription

success

Indicates true or false, whether you can sign the firm-quote.

signature

The signature from signing the EIP712 order object.

order

The order object that contains the order

Example response:

{
  "success": true,
  "signature": "0x0000000000000000000000000000000000000000000000000000000000000001f39fd6e51aad88f6f4ce6ab8827279cfffb92266bbf1de53900b78962f06efbb3a946c2dc5f9bf7eb5c489b32ff2111574c54339e147dde37a8fdc89f641e24cda0685aabe2bb88ef14d085cc3d7613452705086ae19feaef97ab0f3905a360857b8219900000000000000000000000000000000000000000000000001168fa91b8c800000000000000000000000000000000000000000000000000001195ffafa36000000000000000000000000000000000000000000000000000000000000639ac289d2d3051ca7b408bfc32478164a9d838a0a80f9d98120ae0902956fe0ea4af11fb550d9294d809864f3fe0f210ad4e45626dfcd9745b705708f06535f2248460fec2f927f1686994f4a2c4b81da367bcd0991f2001c",
  "order": {
    "id": 1, // Same as the nonce 
    "signer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
    "buyer": "0xaaE854bdd940cf402d79e8051DC7E3390e32A3ac",
    "seller": "0x7d1F5C43998570629f5d00134321fB6a95451ec3",
    "buyerToken": "0x55d398326f99059ff775485246999027b3197955",
    "sellerToken": "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
    "buyerTokenAmount": "10100000000000000000000",
    "sellerTokenAmount": "10000000000000000000000",
    "deadlineTimestamp": "1671086729",
    "caller": "0x7d1F5C43998570629f5d00134321fB6a95451ec3", // same as seller
    "quoteId": "62716-206e-41cb-8559-013f1ed1a65a"
  }
}

In the response above, market maker returns the signature generated and the corresponding order object to Native. With the signature customer can submit the transaction to execute the swap.

Note that the signature must start with 0x with 132 total characters.

Full code sample for signing can be found here.

Success!

Congratulations! You've successfully integrated with Native and you're now a Market Maker 🥳

Last updated