Relay Hub Tx reverts

Hi Guys,

I am trying to integrate gsn in my use case and getting

Rejected relayTransaction call TypeError: Cannot read property ‘contract’ of undefined
at ContractInteractor.getPastEventsForHub (/Users/virazmalhotra/Development/front-monorepo/packages/front-contracts/node_modules/@opengsn/gsn/src/relayclient/ContractInteractor.ts:306:60)
at KnownRelaysManager._fetchRecentlyActiveRelayManagers (/Users/virazmalhotra/Development/front-monorepo/packages/front-contracts/node_modules/@opengsn/gsn/src/relayclient/KnownRelaysManager.ts:109:62)
at processTicksAndRejections (internal/process/task_queues.js:85:5)
at KnownRelaysManager.refresh (/Users/virazmalhotra/Development/front-monorepo/packages/front-contracts/node_modules/@opengsn/gsn/src/relayclient/KnownRelaysManager.ts:66:41)
at RelayClient.relayTransaction (/Users/virazmalhotra/Development/front-monorepo/packages/front-contracts/node_modules/@opengsn/gsn/src/relayclient/RelayClient.ts:176:5)

Also, I get a warning

WARNING: beta ignore version compatibility Error: Provided Hub version(1.0) is not supported by the current interactor(2.0.1)
at ContractInteractor._validateVersion (/Users/virazmalhotra/Development/front-monorepo/packages/front-contracts/node_modules/@opengsn/gsn/src/relayclient/ContractInteractor.ts:173:13)
at /Users/virazmalhotra/Development/front-monorepo/packages/front-contracts/node_modules/@opengsn/gsn/src/relayclient/GSNConfigurator.ts:76:154
at processTicksAndRejections (internal/process/task_queues.js:85:5)
at async Promise.all (index 3)
at Object.resolveConfigurationGSN (/Users/virazmalhotra/Development/front-monorepo/packages/front-contracts/node_modules/@opengsn/gsn/src/relayclient/GSNConfigurator.ts:71:7)

I have open gsn 2.0.1
I have a custom patymaster contract and setting the relayhub like this

  await paymaster.setRelayHub(
    RELAYHUB.address, { from: gsnAccount})
  config = resolveConfigurationGSN( web3provider.currentProvider, {paymasterAddress: paymaster.address, preferredRelays: [  'http://127.0.0.1:55712' ], forwarderAddress: FORWARDER.address});

And I am able see my relayhub address when doing getHubAddr() but it looks like at the time of my tx call i.e

await factory.deploy(salt, smartwallet.address, encodedData, FORWARDER.address, { from: user2 });

the relay hub instance here
https://github.com/opengsn/gsn/blob/master/src/relayclient/ContractInteractor.ts#L299 is still undefined not sure why is that user2 here is the no eth fresh account created from the gsn provider
Need help on this thanks

  1. the above WARNING can be safely ignored (we’re fixing it in the new release) - the 2.0.1 client is perfectly OK with 2.0.0 contracts
  2. I can’t tell where you get the error without knowing neither your code nor the logs.
  3. I suggest you start with the sample and see the tests runs ok, then add your code. and see when it breaks. Then it should be much clearer why your code breaks.

@drortirosh here is my test code Few things are commented for now here is my code I get the issue in line 75

import {
FrontSmartWalletInstance, Executed
} from ‘…/@types/generated/FrontSmartWallet’;
import * as Gsn from ‘@opengsn/gsn’;
import { resolveConfigurationGSN } from ‘@opengsn/gsn/dist/src/relayclient/GSNConfigurator’
import RELAYHUB from ‘…/build/gsn/RelayHub.json’
import FORWARDER from ‘…/build/gsn/Forwarder.json’
// mock token address for testing smart wallet

import Web3 from ‘web3’;
const FrontProxyFactory = artifacts.require(“FrontProxyFactory”);
const FrontSmartWallet = artifacts.require(“FrontSmartWallet”);
const FrontPayMaster = artifacts.require(“FrontPayMaster”);
const RelayHub = artifacts.require(“IRelayHub”);

contract(“Front”, accounts => {
let user1: any
let user2: any
let gsnAccount: any
// have the contract instances type as any since with the exact instance mappings are not available to access and also unable to specify the sender of the tx
let paymaster: any;
let factory: any;
let smartwallet: FrontSmartWalletInstance;
let salt: number;
let encodedData: string;
let toBN: any;
let tokenApproveEncodedData: string
let web3provider: any
let config: any
let gsnProvider: any

beforeEach(async () => {
gsnAccount = accounts[0]

toBN = await web3.utils.toBN;
paymaster = await FrontPayMaster.new({from: gsnAccount})

// factory = await FrontProxyFactory.deployed();
web3provider = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"))
  factory = await FrontProxyFactory.new(FORWARDER.address, {from: gsnAccount})
  smartwallet = await FrontSmartWallet.new({from: gsnAccount});

  await paymaster.setRelayHub(
    RELAYHUB.address, { from: gsnAccount})
  config = resolveConfigurationGSN( web3provider.currentProvider, {paymasterAddress: paymaster.address, preferredRelays: [  'http://127.0.0.1:55712' ], forwarderAddress: FORWARDER.address});

gsnProvider = new Gsn.RelayProvider(web3provider.currentProvider, config)

// new gas less accounts
user1 = await web3.utils.toChecksumAddress(gsnProvider.newAccount().address)
user2 = await gsnProvider.newAccount().address
FrontProxyFactory.setProvider(gsnProvider, user2)

//hardcoded for now
// encoded byte data of setForwarder method in smart wallet for deploy function
encodedData = '0xb9998a2400000000000000000000000018eee2eb65942a5237fe2a9982f8ffc2da2647cf';
// testing smart wallet
tokenApproveEncodedData = "0x095ea7b30000000000000000000000003c94b82f7ba55b327900d5e9f2e2704ac07b0b6c0000000000000000000000000000000000000000000000000de0b6b3a7640000"

});

it(‘Able to deploy Factory Contract with gsn’, async () => {
// paymaster eth transfer check
const initialRelayHubBalance = await web3.eth.getBalance(RELAYHUB.address);
await web3.eth.sendTransaction({ from: gsnAccount, to: paymaster.address, value: 1e18 })
const relayHubBalanceAfterPaymasterDeposit = await web3.eth.getBalance(RELAYHUB.address);
expect(toBN(relayHubBalanceAfterPaymasterDeposit).sub(toBN(initialRelayHubBalance)).toString()).to.equal(toBN(1e18).toString());

// factory smart wallet deployment check
salt = 34;
await paymaster.whitelist(factory.address, user2, { from: gsnAccount });

// gsn transaction i want to make
await factory.deploy(salt, smartwallet.address, encodedData, FORWARDER.address, { from: user2 });
const smartWalletAddress = await factory.computeAddress(salt, smartwallet.address);
const createdWallet = await factory.registry(accounts[1]);
expect(smartWalletAddress).to.equal(createdWallet);

})

where it says cannot read property contract of undefined
Issue at execution of this tx

await factory.deploy(salt, smartwallet.address, encodedData, FORWARDER.address, { from: user2 });

@drortirosh line where I get the error https://github.com/opengsn/gsn/blob/master/src/relayclient/ContractInteractor.ts#L386 I have been following the web3 gsn example only the only diff is there neither relay hub address is sent in paymaster nor eth is transferred to paymaster contract

The only issue right now is relayHub instance in the open gsn package code is still undefined despite the fact that I am setting relay hub in paymaster contract

change configuration to:

  config = resolveConfigurationGSN( web3provider.currentProvider, {paymasterAddress: paymaster.address, logLevel: 1});

but I also see that you didn’t call paymaster.setTrustedForwarder just before calling configure.

didn’t saw trusted forwarder being set here https://docs.opengsn.org/tutorials/integration.html#example_capturetheflag will do it anyways

@drortirosh made the changes still same issue

import {
FrontSmartWalletInstance, Executed
} from ‘…/@types/generated/FrontSmartWallet’;
import * as Gsn from ‘@opengsn/gsn’;
import { resolveConfigurationGSN } from ‘@opengsn/gsn/dist/src/relayclient/GSNConfigurator’
import RELAYHUB from ‘…/build/gsn/RelayHub.json’
import FORWARDER from ‘…/build/gsn/Forwarder.json’
// mock token address for testing smart wallet

import Web3 from ‘web3’;
const FrontProxyFactory = artifacts.require(“FrontProxyFactory”);
const FrontSmartWallet = artifacts.require(“FrontSmartWallet”);
const FrontPayMaster = artifacts.require(“FrontPayMaster”);
const RelayHub = artifacts.require(“IRelayHub”);

contract(“Front”, accounts => {
let user1: any
let user2: any
let gsnAccount: any
// have the contract instances type as any since with the exact instance mappings are not available to access and also unable to specify the sender of the tx
let paymaster: any;
let factory: any;
let smartwallet: FrontSmartWalletInstance;
let salt: number;
let encodedData: string;
let toBN: any;
let tokenApproveEncodedData: string
let web3provider: any
let config: any
let gsnProvider: any

beforeEach(async () => {
gsnAccount = accounts[0]

toBN = await web3.utils.toBN;
paymaster = await FrontPayMaster.new({ from: gsnAccount })

// factory = await FrontProxyFactory.deployed();
web3provider = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"))
factory = await FrontProxyFactory.new(FORWARDER.address, { from: gsnAccount })
smartwallet = await FrontSmartWallet.new({ from: gsnAccount });
await paymaster.setRelayHub(
  RELAYHUB.address, { from: gsnAccount })


config = resolveConfigurationGSN(web3provider.currentProvider, { paymasterAddress: paymaster.address, preferredRelays: ['http://127.0.0.1:59690'], logLevel: 1 });


gsnProvider = new Gsn.RelayProvider(web3provider.currentProvider, config)

// new gas less accounts
user1 = await web3.utils.toChecksumAddress(gsnProvider.newAccount().address)
user2 = await gsnProvider.newAccount().address
FrontProxyFactory.setProvider(gsnProvider, user2)


//hardcoded for now
// encoded byte data of setForwarder method in smart wallet for deploy function
encodedData = '0xb9998a2400000000000000000000000018eee2eb65942a5237fe2a9982f8ffc2da2647cf';
// testing smart wallet
tokenApproveEncodedData = "0x095ea7b30000000000000000000000003c94b82f7ba55b327900d5e9f2e2704ac07b0b6c0000000000000000000000000000000000000000000000000de0b6b3a7640000"

});

it(‘Able to deploy Factory Contract with gsn’, async () => {
// paymaster eth transfer check

const initialRelayHubBalance = await web3.eth.getBalance(RELAYHUB.address);
await web3.eth.sendTransaction({ from: gsnAccount, to: paymaster.address, value: 1e18 })
const relayHubBalanceAfterPaymasterDeposit = await web3.eth.getBalance(RELAYHUB.address);
expect(toBN(relayHubBalanceAfterPaymasterDeposit).sub(toBN(initialRelayHubBalance)).toString()).to.equal(toBN(1e18).toString());

// factory smart wallet deployment check
salt = 34;
await paymaster.whitelist(factory.address, user2, { from: gsnAccount });

// gsn transaction i want to make
await factory.deploy(salt, smartwallet.address, encodedData, FORWARDER.address, { from: user2 });
const smartWalletAddress = await factory.computeAddress(salt, smartwallet.address);
const createdWallet = await factory.registry(accounts[1]);
expect(smartWalletAddress).to.equal(createdWallet);

})

The logs in the console

calling sendAsync{“jsonrpc”:“2.0”,“id”:99,“method”:“eth_sendTransaction”,“params”:[{“from”:“0xa289bcf9c2a2cacc6cf5b7741eb2670fc46c3c9b”,“gas”:“0x6691b7”,“gasPrice”:“0x4a817c800”,“to”:“0x00fb050deabedaef9c9f46dcd6eea7129f340b2e”,“data”:“0x04325f45000000000000000000000000000000000000000000000000000000000000002200000000000000000000000003f3b60ac7ccb40a493227c3d36ceeca8a7cbf2500000000000000000000000000000000000000000000000000000000000000800000000000000000000000002d18e5d7855be5b6780a103964bdee527ce4d2f90000000000000000000000000000000000000000000000000000000000000024b9998a2400000000000000000000000018eee2eb65942a5237fe2a9982f8ffc2da2647cf00000000000000000000000000000000000000000000000000000000”}]}
Rejected relayTransaction call TypeError: Cannot read property ‘contract’ of undefined
at ContractInteractor.getPastEventsForHub (/Users/virazmalhotra/Development/front-monorepo/packages/front-contracts/node_modules/@opengsn/gsn/src/relayclient/ContractInteractor.ts:306:60)
at KnownRelaysManager._fetchRecentlyActiveRelayManagers (/Users/virazmalhotra/Development/front-monorepo/packages/front-contracts/node_modules/@opengsn/gsn/src/relayclient/KnownRelaysManager.ts:109:62)
at processTicksAndRejections (internal/process/task_queues.js:85:5)
at KnownRelaysManager.refresh (/Users/virazmalhotra/Development/front-monorepo/packages/front-contracts/node_modules/@opengsn/gsn/src/relayclient/KnownRelaysManager.ts:66:41)
at RelayClient.relayTransaction (/Users/virazmalhotra/Development/front-monorepo/packages/front-contracts/node_modules/@opengsn/gsn/src/relayclient/RelayClient.ts:176:5)

FYI I saw these logs before using loglevel 1 in config

@drortirosh I have a constructor instead of a set trusted forwarder method in my recipient contract so setting it here

factory = await FrontProxyFactory.new(FORWARDER.address, { from: gsnAccount })

any other issue you see?

@drortirosh also even after adding this

await paymaster.setTrustedForwarder(FORWARDER.address, { from: gsnAccount })

before setting configuration I get the same issue as shared in above logs

@drortirosh resolved missed an await :sweat_smile:

That’s one of the good things of typescript: it warns you if you miss it.