Sponsored Nonce Issue - I think

Sponsored Nonce Issue - I think ¯_(ツ)_/¯

Hi All! We are trying to write an integration with sponsored transactions. This mostly works until the second transaction. I will give an example below:

As you can see in THIS WALLET, it has a nonce of 0. However, it has called 2 transactions. Typically this would set the nonce of the next transaction to 2 but since these were both sponsored transactions, the nonce stays at zero.

In our React app, we are calling openContractCall from Stacks/conncet (import { openContractCall } from '@stacks/connect';). Our code looks a little something like this:

const makeContractCall = async ({
  address,
  function_name,
  body,
  onFinish,
  postConditions,
}) => {
  const options = {
    contractAddress: process.env.REACT_APP_MEDAL_CONTRACT_ADDRESS,
    contractName: process.env.REACT_APP_MEDAL_CONTRACT_NAME || 'trajan-claim-7',
    functionName: function_name,
    functionArgs: body,
    sponsored: true,
    network: new StacksTestnet(),
    postConditions,
    appDetails: {
      name: 'Trajan',
      icon: window.location.origin + Logo,
    },
    onFinish,
  };
  await openContractCall(options);
};

Then, using the onFinish callback, we make an API call to our backend. This takes the serialized hash from the Hiro wallet and makes the contract call.

async claimNFT: async function (body) {
    // pass serialized transaction
    const bufferReader = new BufferReader(Buffer.from(body.txn, "hex"));
    const deserializedTx = deserializeTransaction(bufferReader);
    let userNonceResponse = await axios.get(
      `https://stacks-node-api.testnet.stacks.co/v2/accounts/${body.sender_address}`
    );
    const fee = 100000n;
    let sponserNonceResponse = await axios.get(
      `https://stacks-node-api.testnet.stacks.co/v2/accounts/${process.env.SPONSOR_STX_ADDRESS}`
    );
    if (!sponserNonce) {
      sponserNonce = sponserNonceResponse.data.nonce;
    }
    const sponsorOptions = {
      transaction: deserializedTx,
      sponsorPrivateKey:
        process.env.OWNER_PRIVATE_KEY,
      fee,
      sponsorNonce: sponserNonce,
    };

    const sponsoredTx = await sponsorTransaction(sponsorOptions);

    const broadcastResponse = await broadcastTransaction(sponsoredTx, network);
}

When the user called the function from the front-end, the hiro wallet is passing the wallets nonce (0 in this example) but Stacks is expecting 2 (showcased above). If you manually change the nonce in the Hiro wallet to the expected nonce, it transaction succeeds. We have tried forcing the nonce when creating the transactions (via the code) but have not successed yet :/.

A bit of a side note;

https://stacks-node-api.testnet.stacks.co/v2/accounts/{principal}

https://stacks-node-api.testnet.stacks.co/extended/v1/address/{principal}/nonces

These two endpoints return different values. The first one (v2) returned the correct value for us but the second one (this is being used by the Hiro wallet) is returnning the “incorrect” one.

I hope that I explained this in a way that makese sense. If anyone is willing, I would be happy to hop on a screenshare to further explain this issue.

Thanks in advance for your help!

This was caused by an issue with the Hiro API: Wrong nonce is getting sent on sponsored transactions. · Issue #2605 · hirosystems/stacks-wallet-web · GitHub

All is resolved now.

1 Like