Paymaster whitelisting and funding of transaction not working in truffle tests

Hi Guys,

I am trying to replicate a full gsn flow in my truffle tests:
So I am using gsn start to get the forwarder and relayhub and have my own custom paymaster set up which has my complete whitelisting logic here is the contract


  • SPDX-License-Identifier: MIT

pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;

import “@opengsn/gsn/contracts/forwarder/IForwarder.sol”;
import “@opengsn/gsn/contracts/BasePaymaster.sol”;

contract FrontPayMaster is BasePaymaster {
// allow the owner to set ourTarget
event TargetSet(address target);
event PreRelayed(uint);
event PostRelayed(uint);

// whitelisting details of users and their wallets
mapping (address=>bool) public senderWhitelist;
mapping (address=>bool) public targetWhitelist;

   @dev whitelisting of sender and target as part of auth mechanism.

function whitelist(address _target, address _sender) external onlyOwner {
emit TargetSet(_target);

function preRelayedCall(
GsnTypes.RelayRequest calldata relayRequest,
bytes calldata signature,
bytes calldata approvalData,
uint256 maxPossibleGas
) external override virtual
returns (bytes memory context, bool) {
require(senderWhitelist[relayRequest.request.from], “sender not whitelisted”);
require(targetWhitelist[], “target not whitelisted”);
(signature, approvalData, maxPossibleGas);
emit PreRelayed(now);
return (abi.encode(now), false);

function postRelayedCall(
    bytes calldata context,
    bool success,
    uint256 gasUseWithoutPost,
    GsnTypes.RelayData calldata relayData
) external virtual override {
    (context, success, gasUseWithoutPost, relayData);
    emit PostRelayed(abi.decode(context, (uint256)));

function versionPaymaster()
    returns (string memory)
    return "1.0";


Now what happens is I am able to set the relay hub and transfer eth to paymaster but when I call my recipient contract which is


  • SPDX-License-Identifier: MIT

pragma solidity 0.6.11;

import { Create2 } from “@openzeppelin/contracts/utils/Create2.sol”;
import “@opengsn/gsn/contracts/BaseRelayRecipient.sol”;
import “@opengsn/gsn/contracts/interfaces/IKnowForwarderAddress.sol”;
import “./FrontSmartWallet.sol”;

contract FrontProxyFactory is BaseRelayRecipient, IKnowForwarderAddress {
mapping (address => address) public registry;
string public override versionRecipient = “2.0.0”;

event FrontProxyCreated(address minimalProxy);

constructor(address _forwarder) public {
trustedForwarder = _forwarder;

function computeAddress(uint256 salt, address implementation)
    returns (address)
   @dev smart wallet deployment using create2 + minimal proxy.
function deploy(
    uint256 salt,
    address implementation,
    bytes memory _data,
    address _forwarder
) public {
    address minimalProxy = Create2.deploy(
  if(_data.length > 0) {
  (bool success,) =;
    registry[msg.sender] = minimalProxy;
    address payable wallet = address(uint160(minimalProxy));
    emit FrontProxyCreated(minimalProxy);

function getContractCreationCode(address logic)
    returns (bytes memory)
    bytes10 creation = 0x3d602d80600a3d3981f3;
    bytes10 prefix = 0x363d3d373d3d3d363d73;
    bytes20 targetBytes = bytes20(logic);
    bytes15 suffix = 0x5af43d82803e903d91602b57fd5bf3;
    return abi.encodePacked(creation, prefix, targetBytes, suffix);

function getTrustedForwarder() external override view returns (address) {
    return trustedForwarder;


but when I check relay hub balance before and after calling my recipient contract I see the same balance which implies the tx is not funded by relay hub also since the paymaster has all my auth related logic as I said so it doesn’t get checked either looks like when I call my recipient contract it gets called straight away and not via relay hub as mentioned in the docs so am I missing something ?

The best way to know if a call went through GSN is to send the request an from account without eth…

sender = gsnProvider.newAccount().address
await myContract.someMethod( ... { from:sender} )

The other way is to enable logging (using the gsnconfig param logLevel:"debug")
If you’re using metamask, the you should get a signing dialog, and not transaction sending dialog.