OISY wallet error when calling approve function

I am trying to call the approve function on an icrc2 token through oisy wallet, and it’s failing with this error:
Failed to entitle the spender to transfer the amount
It’s difficult to know what the issue really is the error is not giving any more useful information!

The code here:

  let wallet: IcrcWallet | undefined;
      wallet = await IcrcWallet.connect({
        url: WALLET_URL,
      });

      const accounts = await wallet?.accounts();

      const account = accounts?.[0];

      if (!account) {
        toast.error("No account found");
        return;
      }
      if (!user) {
        return;
      }
      console.log("Approving");
      let res = await wallet?.approve({
        owner: account.owner,
        params: {
          expected_allowance: BigInt(total * ckUSDCe6s),
          expires_at: undefined,
          spender: {
            owner: Principal.fromText(id),
            subaccount: [],
          },
          amount: BigInt(total * ckUSDCe6s),
        },
        ledgerCanisterId: USDCCanisterId,
      });

Anything I am missing?
Thank you!

What are all the details of the error you are getting? In addition to the message, you should receive an errorType that contains the reason and more details coming from the response of the ledger.

if ('Err' in response) {
      throw new IcrcTransferError({
        errorType: response.Err,
        msg: 'Failed to entitle the spender to transfer the amount'
      });
    }

That’s what I was also expecting but it’s just giving that single line not sure why, no other errors.

It’s also kind of doing an ON and OFF thing, one time it’s working the next it’s not, maybe it’s my system I’m not sure.

Most probably an issue on your side as the errorType cannot be ommited within the library. Try to wrap a try / catch around the approve function and debug the error. Once this reason is found, the issue will be easier to debug.

1 Like

Did you got the details of the error?

Still not showing, I have a try catch block:

catch (error) {
      setSaving(false);
      console.error("Error minting units:", error);
    }

This is the full thing:

index-94fc0278.js:1607 Error minting units: aO: Failed to entitle the spender to transfer the amount at cde.approve (https://3r5ad-ciaaa-aaaag-aldza-cai.icp0.io/assets/index-94fc0278.js:1607:32126) at async b (https://3r5ad-ciaaa-aaaag-aldza-cai.icp0.io/assets/index-94fc0278.js:1607:33682)

And now it’s just failing continously

  • Do you get more traces with a console.log?
  • What version of the library are you using?
  • Does the spender have enough funds to approve the message on the selected ledger?
  • Is the expected_allowance equal to the current allowance for the spender?
  • Can you share your implementation and a reproduction?

Hey @peterparker ,

  1. The library is: "@dfinity/oisy-wallet-signer": "^0.1.2",

  2. The spender does have enough funds, also was expecting an insufficient error when it didn’t have.

  3. Yes I think the expected_allowance is equal with the current allowance for the user. Are the parameters below for the approve correct?

The code:

  const handleConfirm = async () => {
    setSaving(true);
    try {
      if (!id) {
        console.error("Id is undefined");
        return;
      }
      let wallet: IcrcWallet | undefined;
      wallet = await IcrcWallet.connect({
        url: WALLET_URL,
      });

      const accounts = await wallet?.accounts();

      const account = accounts?.[0];

      if (!account) {
        toast.error("No account found");
        return;
      }
      if (!user) {
        return;
      }
      console.log("Approving, waiting for approval");
      let res = await wallet?.approve({
        owner: account.owner,
        params: {
          expected_allowance: BigInt(total * ckUSDCe6s),
          expires_at: undefined,
          spender: {
            owner: Principal.fromText(id),
            subaccount: [],
          },
          amount: BigInt(total * ckUSDCe6s),
        },
        ledgerCanisterId: USDCCanisterId,
      });
      console.log("approval res", res);

      // Minting functionallity

    } catch (error) {
      setSaving(false);
      console.error("Error minting units:", error);
    }
  };

Thanks for the answer. As mentionned previously, have you try console.log(error) instead of console.error("Error minting units:", error); and can you please copy/paste/share the all stacktrace of the error?

If you do not get more details, can you share either your project or a sample repo to reproduce the error?

I did a console.log(error) instead of console.error()

It loged the same thing:

Error minting units: cR: Failed to entitle the spender to transfer the amount
    at Fle.approve (https://3r5ad-ciaai-aaaag-aldza-cai.icp0.io/assets/index-885eaa62.js:179:46366)
    at async m (https://3r5ad-ciaai-aaaag-aldza-cai.icp0.io/assets/index-885eaa62.js:1607:14404)

I’m confuse, where is this code deployed? 3r5ad-ciaai-aaaag-aldza-cai does not exist.

Anyway, I would need to debug, can you share a (sample) repo to reproduce the error?

Thanks for sharing the details per pm @iamenochchirima !

I cannot replicate the exact same issue but, finally clicked on how we can get the effective error. Can you update your catch as following, give it a try again and share the error message?

try {
   ...
} catch (error: unknown) {
    console.error("Error approving", error);

    if (error instanceof IcrcTransferError) {
        console.error(error.errorType);
    }
}
1 Like

Thanks a lot David, I was finally able to see the actual error, it was an AllowanceChanged error, I just removed the expected allowance value, now it’s approving and working well.

1 Like

Great to hear! Apologies for taking so much time to click on how to find the effective error, happy that we figured out.

1 Like