Test GSN locally

The above answers (How to test/use the GSN network locally) did help in some aspects, but I’m having some issues regarding writing tests

The following is what I have, and works. But I would like something more clean, like https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/test/GSN/GSNRecipient.test.js#L78 But when I do it like that, it actually makes the sender pays. Could you guys help me please? Thanks :pray:

import { should } from 'chai';
import { MyContractInstance } from '../types/truffle-contracts';
import { fromConnection } from "@openzeppelin/network";

const gsn = require('@openzeppelin/gsn-helpers');
const MyContractJSON = require('../build/contracts/MyContract.json');
const MyContract = artifacts.require('./MyContract.sol') as Truffle.Contract<MyContractInstance>;

contract('MyContract', ([payee, sender, newRelayHub, user]) => {
    it('get a stamp', async () => {
        const myContract = await MyContract.new();
        console.log((await web3.eth.getBalance(user)).toString());
        await gsn.fundRecipient(web3, { recipient: myContract.address });
        const context = await fromConnection('http://localhost:8545', {
            gsn: {
                dev: true,
        } as any);
        const { lib } = context;
        const instance = new lib.eth.Contract(
            MyContractJSON.abi as any,
        console.log((await web3.eth.getBalance(user)).toString());
        const tx = await instance.methods.addStore(5).send({ from: user });
        console.log((await web3.eth.getBalance(user)).toString());
        console.log(user, tx.events);
1 Like

Hi @obernardovieira,

I moved to a new topic (as I think it makes it easier for the community to answer)

I created the following simple example of a GSN enabled Counter contract with a test via the GSN, using OpenZeppelin Test Environment

Let me know if you have any questions.


Based on https://docs.openzeppelin.com/learn/sending-gasless-transactions#creating-our-contract
With addition of a Sender event

// contracts/Counter.sol
pragma solidity ^0.5.0;

import "@openzeppelin/contracts/GSN/GSNRecipient.sol";

contract Counter is GSNRecipient {
    uint256 public value;

    event Sender(address sender);

    function increase() public {
        value += 1;

        emit Sender(_msgSender());

    function acceptRelayedCall(
        address relay,
        address from,
        bytes calldata encodedFunction,
        uint256 transactionFee,
        uint256 gasPrice,
        uint256 gasLimit,
        uint256 nonce,
        bytes calldata approvalData,
        uint256 maxPossibleCharge
    ) external view returns (uint256, bytes memory) {
        return _approveRelayedCall();

    // We won't do any pre or post processing, so leave _preRelayedCall and _postRelayedCall empty
    function _preRelayedCall(bytes memory context) internal returns (bytes32) {

    function _postRelayedCall(bytes memory context, bool, uint256 actualCharge, bytes32) internal {


// test/Counter.test.js

// Load dependencies
const { accounts, contract, web3 } = require('@openzeppelin/test-environment');
const { expectEvent } = require('@openzeppelin/test-helpers');
const gsn = require('@openzeppelin/gsn-helpers');
const { expect } = require('chai');

// Load compiled artifacts
const Counter = contract.fromArtifact('Counter');

// Start test block
describe('Counter', function () {
  const [ sender ] = accounts;

  beforeEach(async function () {
    // Deploy a new Counter contract for each test
    this.contract = await Counter.new();
    await gsn.fundRecipient(web3, { recipient: this.contract.address });

  // Test case
  it('retrieve returns a value previously stored', async function () {
    // Increase value
    const { tx } = await this.contract.increase({ from: sender, useGSN: true });

    await expectEvent.inTransaction(tx, Counter, 'Sender', { sender, sender });

    // Test if the returned value is the same one
    // Note that we need to use strings to compare the 256 bit integers
    expect((await this.contract.value()).toString()).to.equal('1');


From: https://docs.openzeppelin.com/test-environment/0.1/getting-started#advanced-options

// test-environment.config.js
// from: https://docs.openzeppelin.com/test-environment/0.1/getting-started#advanced-options

module.exports = {
    setupProvider: (baseProvider) => {
      const { GSNDevProvider } = require('@openzeppelin/gsn-provider');
      const { accounts } = require('@openzeppelin/test-environment');
      return new GSNDevProvider(baseProvider, {
        txfee: 70,
        useGSN: false,
        ownerAddress: accounts[8],
        relayerAddress: accounts[9],

Hi, thanks.

It says that no test files were found. Does this suppor ts files?

1 Like

Hi @obernardovieira,

Just to clarify, did you try OpenZeppelin Test Environment and get the error no test files were found when using typescript tests? I am not sure if Typescript tests are supported.

That’s right @abcoathup

1 Like

Hey @obernardovieira! How do you use Mocha tests with TypeScript? How do you run them? Is there open-source link to take a look. I am pretty sure it is possible to run test with Test Environment because it is a library not a framework.

1 Like