import { Wallet, ZeroAddress, ZeroHash, randomBytes, hexlify } from "ethers";
async function fillOrder() {
// get the following from https://api.sx.bet/metadata
const EIP712FillHasherAddress = process.env.EIP712_FILL_HASHER_ADDRESS;
const chainId = Number(process.env.CHAIN_ID); // Mainnet — use 79479957 for testnet
const domainVersion = process.env.DOMAIN_VERSION;
const wallet = new Wallet(process.env.SX_PRIVATE_KEY);
const takerAddress = wallet.address;
const stakeWei = "50000000"; // 50 USDC
const marketHash = "0x0246b760b06009ece42d08e706563de1967e7f1b4799d0f559244e3f80bbc496"; // Liverpool vs Arsenal
const baseToken = "0x6629Ce1Cf35Cc1329ebB4F63202F3f197b3F050B"; // Mainnet — see References for testnet address
const desiredOdds = "83000000000000000000"; // ~1.20 decimal odds
const oddsSlippage = 5; // 5% slippage, so worst decimal odds ~1.14
const isTakerBettingOutcomeOne = true; // taker is betting that team 1 wins
const fillSalt = BigInt(hexlify(randomBytes(32))).toString();
const domain = {
name: "SX Bet",
version: domainVersion,
chainId,
verifyingContract: EIP712FillHasherAddress,
};
const types = {
Details: [
{ name: "action", type: "string" },
{ name: "market", type: "string" },
{ name: "betting", type: "string" },
{ name: "stake", type: "string" },
{ name: "worstOdds", type: "string" },
{ name: "worstReturning", type: "string" },
{ name: "fills", type: "FillObject" },
],
FillObject: [
{ name: "stakeWei", type: "string" },
{ name: "marketHash", type: "string" },
{ name: "baseToken", type: "string" },
{ name: "desiredOdds", type: "string" },
{ name: "oddsSlippage", type: "uint256" },
{ name: "isTakerBettingOutcomeOne", type: "bool" },
{ name: "fillSalt", type: "uint256" },
{ name: "beneficiary", type: "address" },
{ name: "beneficiaryType", type: "uint8" },
{ name: "cashOutTarget", type: "bytes32" },
],
};
const message = {
action: "N/A",
betting: "N/A",
stake: "N/A",
worstOdds: "N/A",
worstReturning: "N/A",
market: marketHash,
fills: {
stakeWei,
marketHash,
baseToken,
desiredOdds,
oddsSlippage,
isTakerBettingOutcomeOne,
fillSalt,
beneficiary: ZeroAddress,
beneficiaryType: 0,
cashOutTarget: ZeroHash,
},
};
const signature = await wallet.signTypedData(domain, types, message);
const apiPayload = {
market: marketHash,
baseToken,
isTakerBettingOutcomeOne,
stakeWei,
desiredOdds,
oddsSlippage,
taker: takerAddress,
takerSig: signature,
fillSalt,
};
const response = await fetch(`https://api.sx.bet/orders/fill/v2`, { // Mainnet — use https://api.toronto.sx.bet for testnet
method: "POST",
body: JSON.stringify(apiPayload),
headers: { "Content-Type": "application/json" },
});
}