Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3. With a custom paymaster #2

Open
wants to merge 1 commit into
base: 2-workshop-with-gsn
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# GSN v3 integration workshop

### (This branch already contains frontend and contract integration with GSN)
### (This branch adds a custom paymaster to our GSN-enabled sample)

This sample dapp emits an event with the last account that clicked on the "capture the flag" button. We will integrate
this dapp to work gaslessly with GSN v3. This will allow an externally owned account without ETH to capture the flag by
signing a meta transaction.

### To run the sample:


1. first clone and `yarn install`
2. run `yarn gsn-with-ganache` to start a node, and also deploy GSN contracts and start a relayer service.
3. Make sure you have Metamask installed, and pointing to "localhost"
Expand All @@ -17,8 +18,8 @@ signing a meta transaction.

You can see the integrations as GitHub pull requests:

1. (this branch) [Basic: Minimum viable GSN integration](https://github.com/opengsn/workshop/pull/1/files)
2. [Advanced: Write your own custom Paymaster](https://github.com/opengsn/workshop/pull/2/files_)
1. [Basic: Minimum viable GSN integration](https://github.com/opengsn/workshop/pull/1/files)
2. (this branch) [Advanced: Write your own custom Paymaster](https://github.com/opengsn/workshop/pull/2/files_)

Note: on testnet we maintain a public service "pay for everything" paymaster so writing your own is not strictly
required. On mainnet, you need a custom paymaster, such as a token paymaster that allow users to pay for gas in tokens,
Expand Down
6 changes: 6 additions & 0 deletions contracts/ImportArtifacts.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

//"import" it into our project for Truffle to generate artifacts
import "@opengsn/paymasters/contracts/WhitelistPaymaster.sol";

21 changes: 20 additions & 1 deletion migrations/2_deploy_contracts.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
const CaptureTheFlag = artifacts.require('CaptureTheFlag')
const WhitelistPaymaster = artifacts.require('WhitelistPaymaster')

module.exports = async function (deployer) {
module.exports = async function (deployer, network, accounts) {
const forwarder = require('../build/gsn/Forwarder').address
await deployer.deploy(CaptureTheFlag, forwarder)

console.log(`Deployed CTF at ${CaptureTheFlag.address} with forwarder ${forwarder}`)

await deployer.deploy(WhitelistPaymaster)
const relayHubAddress = require('../build/gsn/RelayHub.json').address
const paymaster = await WhitelistPaymaster.deployed()
await paymaster.setRelayHub(relayHubAddress)
await paymaster.setTrustedForwarder(forwarder)

// This is the first ganache address, when started with "ganache-cli -d"
// you can add your metamask address here.
await paymaster.whitelistSender('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')


// you can also add addresses by running `truffle console` and then running:
// const pm = await WhitelistPaymaster.deployed()
// pm.whitelistSender('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1')

await web3.eth.sendTransaction({from: accounts[0], to: paymaster.address, value: 1e18})
console.log(`1 ETH deposited to Paymaster(${WhitelistPaymaster.address})`)
}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"dependencies": {
"@opengsn/contracts": "^3.0.0-beta.1",
"@opengsn/dev": "^3.0.0-beta.1",
"@opengsn/paymasters": "^3.0.0-beta.1",
"@opengsn/provider": "^3.0.0-beta.1",
"browserify": "^17.0.0",
"ethers": "^5.6.8",
Expand All @@ -14,8 +15,8 @@
"serve": "^13.0.0"
},
"scripts": {
"ganache": "yarn run ganache-cli -d --networkId 1337 --chainId 1337",
"gsn-with-ganache": "run-with-testrpc -d --networkId 1337 --chainId 1337 'gsn start'",
"ganache": "yarn run ganache-cli -d --chainId 1337",
"gsn-with-ganache": "run-with-testrpc -d --chainId 1337 'gsn start'",
"test": "truffle test",
"compile": "truffle compile",
"build": "./ui/build.sh",
Expand Down
22 changes: 20 additions & 2 deletions test/testcontracts.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,31 @@ const {RelayProvider} = require('@opengsn/provider')
const {GsnTestEnvironment} = require('@opengsn/dev')

const CaptureTheFlag = artifacts.require('CaptureTheFlag')
const WhitelistPaymaster = artifacts.require('WhitelistPaymaster')

const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'

contract("CaptureTheFlag", async accounts => {

let account
let captureFlagContract
let whitelistPaymaster

before(async () => {
const {forwarderAddress, paymasterAddress} = GsnTestEnvironment.loadDeployment()
const {forwarderAddress, relayHubAddress} = GsnTestEnvironment.loadDeployment()

const whitelistPaymaster = await WhitelistPaymaster.new()
await whitelistPaymaster.setTrustedForwarder(forwarderAddress)
await whitelistPaymaster.setRelayHub(relayHubAddress)
await web3.eth.sendTransaction({from: accounts[0], to: whitelistPaymaster.address, value: 1e18})

captureFlagContract = await CaptureTheFlag.new(forwarderAddress);

const gsnProvider = await RelayProvider.newProvider({
provider: web3.currentProvider,
config: {
loggerConfiguration: {logLevel: 'error'},
paymasterAddress,
paymasterAddress: whitelistPaymaster.address,
//these 2 params are needed only for ganache:
methodSuffix: '',
jsonStringifyRequest: false,
Expand All @@ -33,6 +40,8 @@ contract("CaptureTheFlag", async accounts => {
// default ganache accounts all have eth.
// test from a different account, without any eth
account = gsnProvider.newAccount().address

await whitelistPaymaster.whitelistSender(account)
})

it('Runs with GSN', async () => {
Expand All @@ -41,4 +50,13 @@ contract("CaptureTheFlag", async accounts => {
assert.equal(res.logs[0].args.previousHolder, ZERO_ADDRESS, "Wrong previous flag holder");
assert.equal(res.logs[0].args.currentHolder, account, "Wrong current flag holder");
});

it('Paymaster should reject different account', async () => {
await captureFlagContract.captureTheFlag({from: accounts[2]})
.then(() => {
throw new Error('should revert')
})
.catch(() => {
})
});
});
10 changes: 7 additions & 3 deletions ui/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const ethers = require('ethers')
const {RelayProvider} = require('@opengsn/provider')
let whitelistPaymasterAddress

const paymasterAddress = require('../build/gsn/Paymaster').address
const WhitelistPaymasterArtifact = require('../build/contracts/WhitelistPaymaster.json')
const contractArtifact = require('../build/contracts/CaptureTheFlag.json')
const contractAbi = contractArtifact.abi

Expand All @@ -24,11 +25,14 @@ async function initContract() {
})
const networkId = await window.ethereum.request({method: 'net_version'})

whitelistPaymasterAddress = WhitelistPaymasterArtifact.networks[networkId].address
console.log('Using whitelistPaymaster at', whitelistPaymasterAddress)

gsnProvider = await RelayProvider.newProvider({
provider: window.ethereum,
config: {
loggerConfiguration: {logLevel: 'debug'},
paymasterAddress
//loggerConfiguration: { logLevel: 'error' },
paymasterAddress: whitelistPaymasterAddress
}
}).init()

Expand Down
Loading