Submit Order

Below we provide some example code for making a JAM trade on Bebop.

You confirm submitting an order offchain. The winning solver sends the order on chain having received user's signature.

Gasless example with Permit2 approval:

import axios from "axios";
import {ethers} from "ethers";

// Trade Info (Insert your values)
let privateKey = ""
let tokensAddressesSell = ["0xaf88d065e77c8cC2239327C5EDb3A432268e5831"] // USDC
let tokensSellAmounts = [ethers.parseUnits("1", 6)] // 1 USDC
let tokensAddressBuy = ["0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"] // USDT
let chain = {
    chainId: 42161,
    name: "arbitrum" // "polygon" / "ethereum" / "arbitrum" / etc
}

// Constants
const JAM_SETTLEMENT_ADDRESS = "0xbeb0b0623f66bE8cE162EbDfA2ec543A522F4ea6"
const JAM_ORDER_WITH_PERMIT2_TYPES = {
    'PermitBatchWitnessTransferFrom': [
        { 'name': 'permitted', 'type': 'TokenPermissions[]' },
        { 'name': 'spender', 'type': 'address' },
        { 'name': 'nonce', 'type': 'uint256' },
        { 'name': 'deadline', 'type': 'uint256' },
        { 'name': 'witness', 'type': 'JamOrder' }
    ],
    'TokenPermissions': [
        { 'name': 'token', 'type': 'address' },
        { 'name': 'amount', 'type': 'uint256' }
    ],
    'JamOrder': [
        { 'name': 'taker', 'type': 'address' },
        { 'name': 'receiver', 'type': 'address' },
        { 'name': 'expiry', 'type': 'uint256' },
        { 'name': 'exclusivityDeadline', 'type': 'uint256' },
        { 'name': 'nonce', 'type': 'uint256' },
        { 'name': 'executor', 'type': 'address' },
        { 'name': 'partnerInfo', 'type': 'uint256' },
        { 'name': 'sellTokens', 'type': 'address[]' },
        { 'name': 'buyTokens', 'type': 'address[]' },
        { 'name': 'sellAmounts', 'type': 'uint256[]' },
        { 'name': 'buyAmounts', 'type': 'uint256[]' },
        { 'name': 'hooksHash', 'type': 'bytes32' }
    ]
}

const PERMIT2_DOMAIN = {
    name: "Permit2",
    chainId: chain.chainId,
    verifyingContract: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
}


// Getting quote and submitting it onchain
async function sendTx() {

    // Init you wallet and provider
    let account = new ethers.Wallet(privateKey)

    // Get quote
    let quote = (await axios.get(`https://api.bebop.xyz/jam/${chain.name}/v2/quote`, {
        params: {
            buy_tokens: tokensAddressBuy.toString(),
            sell_tokens: tokensAddressesSell.toString(),
            sell_amounts: tokensSellAmounts.toString(),
            taker_address: account.address,
            approval_type: "Permit2"
        }
    })).data
    console.log(quote)

    // Sign quote
    let signature = await account.signTypedData(PERMIT2_DOMAIN, JAM_ORDER_WITH_PERMIT2_TYPES, quote.toSign)

    // Send Transaction
    let response = (await axios.post(`https://api.bebop.xyz/jam/${chain.name}/v2/order`, {
        signature: signature,
        quote_id: quote.quoteId,
    }, {
        headers: {
            'Content-Type': 'application/json; charset=utf-8'
        }
    })).data
    console.log(response)
}

sendTx()

For gasless mode with Standard ERC20 approvals, specify approval_type: "Standard" in quote request and use these structures to create signature:

const JAM_ORDER_TYPES = {
    'JamOrder': [
        { 'name': 'taker', 'type': 'address' },
        { 'name': 'receiver', 'type': 'address' },
        { 'name': 'expiry', 'type': 'uint256' },
        { 'name': 'exclusivityDeadline', 'type': 'uint256' },
        { 'name': 'nonce', 'type': 'uint256' },
        { 'name': 'executor', 'type': 'address' },
        { 'name': 'partnerInfo', 'type': 'uint256' },
        { 'name': 'sellTokens', 'type': 'address[]' },
        { 'name': 'buyTokens', 'type': 'address[]' },
        { 'name': 'sellAmounts', 'type': 'uint256[]' },
        { 'name': 'buyAmounts', 'type': 'uint256[]' },
        { 'name': 'hooksHash', 'type': 'bytes32' }
    ]
}
const JAM_DOMAIN = {
    name: "JamSettlement",
    version: "2",
    chainId: chain.chainId,
    verifyingContract: JAM_SETTLEMENT_ADDRESS,
}

// ...

let signature = await account.signTypedData(JAM_DOMAIN, JAM_ORDER_TYPES, quote.toSign)

Last updated