Accepting Offers

An offer can be accepted by sending a Neo invocation transaction that invokes the acceptOffer operation. Accepting an offers support the use case of market orders or the matching for offers that meet a limit price.

As discussing in the previous section Offers to accept may be discovered by calling the API that returns matching offers, see the previous section. The response from the match API includes an array of offers to take. Each of the offers to be accepted requires an invocation transaction to be sent to the NEO blockchain. Here, we will give an example of accepting one of the offers in the offersToTake array in the response from the match call.

Example of Accepting an offer that buys APH on the NEO-APH market

import { wallet, u, api } from '@cityofzion/neon-js';

const account = new wallet.Account(wif);

async function buildAcceptOffer(offerId, assetIdToGive, quantityToGive, assetIdToReceive, quantityToReceive, shouldCreateIfTaken, nonce) {
  var configWithTx = await buildContractTransaction('acceptOffer',
  [
    offerId,
    u.reverseHex(wallet.getScriptHashFromAddress(account.address)),
    u.reverseHex(assetIdToGive),
    u.num2fixed8(quantityToGive),
    u.reverseHex(assetIdToReceive),
    u.num2fixed8(quantityToReceive),
    shouldCreateIfTaken ? 1 : 0, // whether or not to create a taker offer if this is no longer available
    u.num2fixed8(new Date().getTime() * 0.00000001),
  ]);
  configWithTx.offer = offer;
  offer.tx = await tx.serializeTransaction(configWithTx.tx, true);
  return configWithTx;
}

// For this example, we will accept the first offer returned by making the call to match offers:
// https://mainnet.aphelion-neo.com/api/book/match/NEO-APH?side=buy&quantity=50000
// In this case, the offer to accept is the result of obtaining an offer that was selling APH
offerToAccept = {
  "offerId": "0xaac43a348d236e32a1b35171fb3d6101e9af71049219e21e31b0ddb19c945273",
  "quantity": 44827.5,
  "price": 0.001399,
  "fee": 0,
  "isBackupOffer": false
}

// The result contains configuration and the built transaction
const configWithTx = buildAcceptOffer(
    offer.offerId.replace('0x', ''),
    '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7', // assetIdToGive = NEO asset id
    offerToAccept.quantity * offerToAccept.Price, // quantityToGive = order quantity * order price
    'a0777c3ce2b169d4a23bcba4565e3225a0122d95', // assetIdToReceive = APH
    offerToAccept.quantity, // quantityToReceive = offerToAccept.Quantity 
    false,  // specify behavior to not create an offer on the book if the offer had already been taken
    u.num2fixed8(new Date().getTime() * 0.00000001)  // nonce value
);
await api.sendTx(configWithTx);
// Note: If accepeting multiple offers, it's best to wait to monitor all for confirmation after sending them all.
await monitorTxForConfirmation(configWithTx.tx);