gasLimit too low using Opensea Plugin

How to use the postOrder() ? I dont have docs for that. I dont see that function on this page:

will this works? :slight_smile:
await Moralis.Plugins.opensea.postOrder(params)

hi @dani,

I came up with this code:

const MORALIS_SPEEDY_NODE =
  "https://speedy-nodes-nyc.moralis.io/535b0f87fd7f16e6e5e013bb/eth/rinkeby";

// Connect to Moralis server
let web3 = new Web3(MORALIS_SPEEDY_NODE);
let web3Account;

const init = async () => {
  web3Account = await web3.eth.accounts.wallet.add(_testBot("rinkeby"));
  await createBuyOrder();
};

const ERROR_WEB3_MISSING =
  "Missing web3 instance, make sure to call Moralis.enableWeb3() or Moralis.authenticate()";

const handleTriggers = async (triggersArray, payload) => {
  function ensureWeb3IsInstalled() {
    return web3 ? true : false;
  }
  if (!triggersArray) return;
  let response;
  for (let i = 0; i < triggersArray.length; i++) {
    switch (triggersArray[i]?.name) {
    
      // Handles `web3Sign` trigger
      case "web3Sign":
        if (!ensureWeb3IsInstalled()) throw new Error(ERROR_WEB3_MISSING);
        if (!triggersArray[i].message)
          throw new Error("web3Sign trigger does not have a message to sign");
        if (
          !triggersArray[i].signer ||
          !web3.utils.isAddress(triggersArray[i].signer)
        )
          throw new Error("web3Sign trigger signer address missing or invalid");

        // Sign a message using web3 (await)
        if (triggersArray[i]?.shouldAwait === true)
          response = await web3.eth.personal.sign(
            triggersArray[i].message,
            triggersArray[i].signer
          );

        // Sign a message using web3 (does NOT await)
        if (triggersArray[i]?.shouldAwait === false)
          response = web3.eth.personal.sign(
            triggersArray[i].message,
            triggersArray[i].signer
          );

        // Save response
        // if (triggersArray[i]?.saveResponse === true)
        //   memoryCard.save(response);

        // Return payload and response
        if (triggersArray[i]?.shouldReturnPayload === true)
          return { payload: payload, response: response };

        // Only return response
        if (triggersArray[i]?.shouldReturnResponse === true) return response;
        break;

      // Calls a given plugin endpoint
      case "callPluginEndpoint":
        if (!triggersArray[i].pluginName)
          throw new Error(
            "callPluginEndpoint trigger does not have an plugin name to call"
          );
        if (!triggersArray[i].endpoint)
          throw new Error(
            "callPluginEndpoint trigger does not have an endpoint to call"
          );

        // Call a plugin endpoint (await)
        if (triggersArray[i]?.shouldAwait === true) {

          let response = await Moralis.Plugins.opensea.postOrder(
            triggersArray[i].params
          );
          return console.log(
            " Moralis.Plugins.opensea.postOrder => response = ",
            JSON.stringify(response)
          );
        
        } else {
          ___.stopOnError("unhandled option..");
        }
    }
  }
};

const createBuyOrder = async () => {
  console.log("Placing offers from:", user.get("ethAddress"));
  const { tokenAddress, amount, fromId, toId, duration } = tx;
  const expirationTime = Math.round(Date.now() / 1000 + duration * 60 * 60);

  let triggerParams;
  try {
    const options = {
      disableTriggers: true,
    };
    triggerParams = await Moralis.Plugins.opensea.createBuyOrder(
      {
        network: "testnet",
        tokenAddress: tokenAddress, //0xCae0b79679dC38E045525077Aa949aacBCB17791
        tokenId: "11",
        tokenType: "ERC721",
        amount: amount,
        userAddress: web3Account.address, //user.get("ethAddress"), //"0x255b7DaBbBEa98dD315f8f6E09B3F2c5871dDf75",
        paymentTokenAddress: "0xc778417e063141139fce010982780140aa0cd5ab",
        expirationTime: expirationTime,
        gas: 50000,
      },
      options
    );
    console.log(
      "Got parameters to create a new buy order::\n",
      JSON.stringify(triggerParams)
    );
  } catch (er) {
    console.log("Error:", er);
  }
  await handleTriggers(triggerParams.triggers, triggerParams);
};

however it shows the error:

the method personal_sign does not exist/is not available

triggerParams logged out is like this:

triggerParams = {
  data: {
    sign: {
      data: {
        exchange: "0x5206e78b21ce315ce284fb24cf05e0585a93b1d9",
        maker: "0x255b7dabbbea98dd315f8f6e09b3f2c5871ddf75",
        taker: "0x0000000000000000000000000000000000000000",
        quantity: "1",
        makerRelayerFee: "0",
        takerRelayerFee: "250",
        makerProtocolFee: "0",
        takerProtocolFee: "0",
        makerReferrerFee: "0",
        waitingForBestCounterOrder: "false",
        feeMethod: "1",
        feeRecipient: "0x5b3256965e7c3cf26e11fcaf296dfc8807c01073",
        side: "0",
        saleKind: "0",
        target: "0xcae0b79679dc38e045525077aa949aacbcb17791",
        howToCall: "0",
        calldata:
          "0x23b872dd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000255b7dabbbea98dd315f8f6e09b3f2c5871ddf75000000000000000000000000000000000000000000000000000000000000000b",
        replacementPattern:
          "0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        staticTarget: "0x0000000000000000000000000000000000000000",
        staticExtradata: "0x",
        paymentToken: "0xc778417e063141139fce010982780140aa0cd5ab",
        basePrice: "111000000000000000",
        extra: "0",
        listingTime: "1635910730",
        expirationTime: "0",
        salt: "62835573254372216507758797343392650739275880710809955748296098887027741353954",
        hash: "0xb5d36fbad51ea35a6b504fc94df0165a954d5d0ef7738c38369a1e4410c85d16",
        assetId: "11",
        assetAddress: "0xcae0b79679dc38e045525077aa949aacbcb17791",
        tokenType: "ERC721",
      },
    },
  },
  triggers: [
    {
      name: "web3Sign",
      message:
        "0xb5d36fbad51ea35a6b504fc94df0165a954d5d0ef7738c38369a1e4410c85d16",
      signer: "0x255b7dabbbea98dd315f8f6e09b3f2c5871ddf75",
      shouldAwait: true,
      saveResponse: true,
    },
    {
      name: "callPluginEndpoint",
      pluginName: "opensea",
      endpoint: "postOrder",
      params: {
        message:
          "0xb5d36fbad51ea35a6b504fc94df0165a954d5d0ef7738c38369a1e4410c85d16",
        orderSide: 0,
      },
      useSavedResponse: true,
      savedResponseAs: "signature",
      savedResponseAt: [],
      shouldAwait: true,
      runResponseTrigger: true,
    },
  ],
};
{
      name: "web3Sign",
      message:
        "0xb5d36fbad51ea35a6b504fc94df0165a954d5d0ef7738c38369a1e4410c85d16",
      signer: "0x255b7dabbbea98dd315f8f6e09b3f2c5871ddf75",
      shouldAwait: true,
      saveResponse: true,
}

The trigger above requires to sign a message with your user.
Then you should post this object (including the signature param) to the postOrder endpoint.

I found that error thrown from here:

// Sign a message using web3 (await)

          if (triggersArray[i]?.shouldAwait === true) {

            response = await web3.eth.personal.sign(

              triggersArray[i].message,

              web3Account.address,  //Returned error: the method personal_sign does not exist/is not available

            );

          }

I also tried providing private as instructed in web3 docs, but it dont works either…

// Sign a message using web3 (await)

          if (triggersArray[i]?.shouldAwait === true) {

            response = await web3.eth.personal.sign(

              triggersArray[i].message,

              web3Account.address,  
              
             web3Account.privateKey, 
//Returned error: the method personal_sign does not exist/is not available
            );

          }

tried searching around the net but no use :sob:

You can sign using web3 or ether, check their docs for examples :slight_smile:

I see this in the docs, but don’t know what I did I missed? or maybe there is problem with my web3 instance provided by Speedynode?

Signing a message with personal.sign is not the same thing as signing a transaction, the seedy node will be used only to send the final signed transaction.

1 Like

Hey @tungtien

I made a full implementation of the OpenSea plugin in NodeJs.

1 Like

@dani This is awesome that you implemented this.
However, I tried to run the code and I get the following error when executing a buy order on the Rinkeby test network, I believe I have done everything correct and the error is given on line 67:

{ result: { status: 502, data: { error: true } } }

I would be very grateful if you could help me.

createBuyOrder(
β€˜testnet’,
β€˜0x16baF0dE678E52367adC69fD067E5eDd1D33e3bF’,
β€˜3353’,
β€˜ERC721’,
β€˜0x83d74eead25e3f4dd89400592c96c33c2f8d791d’,
0.1,
β€˜0xc778417e063141139fce010982780140aa0cd5ab’
)

Oddly enough it suddenly works for the testnet however at the same time when it is called to the mainnet I get the same error.