Trouble Migrating defender relayer from Mumbai to Amoy Tesnet

Background of our application - Ours is a NFT marketplace (ngagen.com) and whitelabel solution. We pay the gas fees via the defender relayer. User not exposed to crypto and we bear the gas fees for the transactions.

Issue faced - While migrating from mumbai testnet to Amoy testnet, we created a new relayer, deployed contracts for the new relayer on Amoy updated the relevant api key and secrets.
But now we are getting 2 errors -

  1. UnhandledPromiseRejectionWarning -
(node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
[2024-04-22 11:49:52.097 +0000] ERROR (1 on staging-ngagen-store-livecopy-api-service-7cd46c74f8-b8m6h): Failed to get a token for the API key 4HR1eXudpt2iEPoRYE1v4wmsuNdqH37w: Password attempts exceeded
    err: {
      "type": "Error",
      "message": "Failed to get a token for the API key 4HR1eXudpt2iEPoRYE1v4wmsuNdqH37w: Password attempts exceeded",
      "stack":
          Error: Failed to get a token for the API key 4HR1eXudpt2iEPoRYE1v4wmsuNdqH37w: Password attempts exceeded
              at Object.authenticate (/app/node_modules/defender-base-client/lib/api/auth.js:28:15)
              at processTicksAndRejections (internal/process/task_queues.js:95:5)
              at async Object.createAuthenticatedApi (/app/node_modules/defender-base-client/lib/api/api.js:28:19)
    }
  1. Incorrect username or password -
Failed to get a token for the API key 4HR1eXudpt2iEPoRYE1v4wmsuNdqH37w: Incorrect username or password.
    err: {
      "type": "Error",
      "message": "Failed to get a token for the API key 4HR1eXudpt2iEPoRYE1v4wmsuNdqH37w: Incorrect username or password.",
      "stack":
          Error: Failed to get a token for the API key 4HR1eXudpt2iEPoRYE1v4wmsuNdqH37w: Incorrect username or password.
              at Object.authenticate (/app/node_modules/defender-base-client/lib/api/auth.js:28:15)
              at processTicksAndRejections (internal/process/task_queues.js:95:5)
              at async Object.createAuthenticatedApi (/app/node_modules/defender-base-client/lib/api/api.js:28:19)

:computer: Environment
Defender Relayer, we pay gas fees via the relayer on behalf of our users and avoid exposing the users to cryptos

Hi! Usually we experience that issue when there the API keys set is wrong, just to be sure, have you generated new API keys for your Amoy relayer and then changed that in your code?

Here an example on how to instantiate Defender for most operations + amoy relayer operations

const creds = {
  apiKey: <your team api key>,
  apiSecret: <your team api secret>
  relayerApiKey: <amoy relayer api key>,
  relayerApiSecret: <amoy relayer api secret>,
};
const client = new Defender(creds);

If you could attach some code snippet to see where the error is throwing that would be super helpful

Hi Marcos, thanks for the reply

  1. We created/generated new keys for Amoy Testnet,
  2. added testnet matic tokens to the relayer wallet
  3. deployed our contracts using the relayer wallet
  4. updated api keys and secret in the code
  5. we store api key in env variable and store the secret in a different file that that gets accessed at run time

I wonder if the script is somehow failing to get the secret, and then the Defender fails to authenticate because the secret is wrong/missing?

The suspicious part to me is
Failed to get a token for the API key 4HR1eXudpt2iEPoRYE1v4wmsuNdqH37w

Hi Marcos,

We are confused around that only. We tried with 2 relayers for one we are getting Unhandled promise reject and for other incorrect username and password. can we test with the one where we are getting unhandled promise? I have disabled the other relayer and made the necessary changes in api key and secret.

Sure, if you could share some code snippet I could try to reproduce the issue in my own environment

Hi @marcos.carlomagno

here is the code snippet.. We are using the relayerAddress to sign the txn and pay the gas fees on blockchain. these actions / txn can be creating a collection, minting nft, transferring nft etc etc. We are not exposing the end users to crypto payments/gas fees, we bear the cost via this relayer

var Web3 = require('web3');
const { config } = require('../config/config.development.js');
const logger = require('./logger');

const { DefenderRelayProvider } = require('defender-relay-client/lib/web3');

let web3Instance = null;
const relayerAddress = config.RelayerAddress;

try {
  const credentials = {
    apiKey: config.RelayerAPIKey,
    apiSecret: config.RelayerAPIPass,
  };
  const provider = new DefenderRelayProvider(credentials, { speed: 'fast' });
  web3Instance = new Web3(provider);
} catch (err) {
  logger.error(err);
}

module.exports = {
  web3Instance,
  relayerAddress,
};

also we are importing and extending the following packages/classes from OpenZeppelin

import '@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol';
import '@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol';
import '@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol';
import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';

Hi Marcos, did you get a chance to look at the below code snippet?

@marcos.carlomagno can you please help us here, this is impacting our deliverables.

Hi! Sorry about the late response, I just tried to reproduce your case using the following code snippet and it worked perfectly

require('dotenv').config();
const { DefenderRelayProvider } = require('defender-relay-client/lib/web3');
const Web3 = require('web3');

async function main() {
  const creds = { apiKey: process.env.RELAYER_API_KEY, apiSecret: process.env.RELAYER_API_SECRET };
  const provider = new DefenderRelayProvider(creds, { speed: 'fast' });
  const web3 = new Web3(provider);
  const [from] = await web3.eth.getAccounts();
  const balance = await web3.eth.getBalance(from);
  console.log(`Relayer address is ${from} with balance ${balance}`);
}

main().catch(console.error);

So believe there might be 2 possible problems:

  1. const { config } = require('../config/config.development.js'); is returning some wrong or missing key
  2. The RelayerAPIKey and/or RelayerAPIPass are wrong, have you generated those keys under relayer details, like in the screenshot below? using Create new API key action

I would debug this by generating a new set of keys for your relayer, and then logging what the code is loading (config object) and then comparing the output with the previously generated keys. Could you try that please?

If that didn't work, could you send an email attaching this thread, with your tenantId and relayerId to defender-support@openzeppelin.com? So we can better investigate your case

Thanks!

Hi @marcos.carlomagno ,

Thanks for the reply. Please find my comments inline

  1. const { config } = require('../config/config.development.js'); is returning some wrong or missing key
    It could be but we just updated the relayer from one testnet to a newer testnet. If its working previously then the return statement is correct and returning the correct key

  2. We created the new API key from the same place shown in the screenshot that you shared. Then deployed our contracts on the eth wallet that was provided when new relayer was created. We tried creating a new relayer with new keys too.

Let me try with a new set of keys again if that doesnt work will send an as suggested.

Thanks!