Sign
If the quote includes permit2Message, sign it and submit permit2Signature to the /sor/assemble endpoint.
- JavaScript
- Python
import { ethers } from 'ethers';
import 'dotenv/config';
import fetch from 'node-fetch';
const SWAP_URL = 'https://enterprise-api.odos.xyz/sor/swap/v3';
const ROUTER = '0x0D05a7D3448512B78fa8A9e46c4872C88C4a0D05'; // Base
// assume `quote` and `quoteBody` from Step 1
let permit2Signature;
if (quote.permit2Message) {
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY);
permit2Signature = await wallet._signTypedData(
quote.permit2Message.domain,
quote.permit2Message.types,
quote.permit2Message.message
);
}
const swapRequest = { ...quoteBody, permit2Signature };
const swapRes = await fetch(SWAP_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.ODOS_API_KEY
},
body: JSON.stringify(swapRequest)
});
const swapData = await swapRes.json();
console.log('Swap response:', swapData);
from eth_account import Account
from eth_account.messages import encode_structured_data
import os, requests
SWAP_URL = 'https://enterprise-api.odos.xyz/sor/swap/v3'
permit2_signature = None
if 'permit2Message' in quote and quote['permit2Message']:
msg = encode_structured_data(primitive=quote['permit2Message'])
signed = Account.sign_message(msg, os.getenv("PRIVATE_KEY"))
permit2_signature = signed.signature.hex()
swap_request = { **quote_body, "permit2Signature": permit2_signature }
swap_res = requests.post(SWAP_URL, json=swap_request, headers=headers)
swap_data = swap_res.json()
print("Swap response:", swap_data)
Notes
- Always verify token decimals for Base before deploying to production.
- Cache the Permit2 signature by token/spender until it expires for improved UX.
- The consolidated
/sor/swap/v3endpoint removes the need to call/sor/assembleseparately.