A vanilla Typescript dApp for claiming Ubiquity Rewards. It also includes tools for generating and invalidating permits and can be used to claim both ERC20 and ERC721 tokens.
- Install Foundry.
- Create a
.envfile in the project root with the following settings:
-
These are the suggested default test environment variables that allow for local setup using the supplied yarn commands. If you want to produce or invalidate real on-chain permits you must change the below values to reflect the real permit information such as address, chain ID, private key and so on.
# Common variables CHAIN_ID="31337" FRONTEND_URL="http://localhost:8080" UBIQUIBOT_PRIVATE_KEY="0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d" RPC_PROVIDER_URL="http://127.0.0.1:8545" PAYMENT_TOKEN_ADDRESS="0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d" # Variables depending on spender (bounty hunter) AMOUNT_IN_ETH="1" BENEFICIARY_ADDRESS="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
- Set
.envvariables. - Run
yarn test:anvilin terminal A andyarn test:fundin terminal B. - In terminal B, run
yarn start. - A permit URL for both ERC20 and ERC721 will be generated.
- Open the generated permit URL from the console.
- Connect your wallet (import anvil accounts [0] & [1] into your wallet).
- Depending on your connected account, either the claim or invalidate button will be visible.
- To test ERC721 permits, deploy the
nft-rewardscontract from the repository.
- Open your wallet provider and select
import walletorimport account. - Obtain the private keys by running
anvilor using the yarn command. - Copy and paste the private keys into your wallet provider.
- A local blockchain instance will be created for testing.
- The permit URL will be generated in the console. Ensure your console has enough space for the full URL.
- Imported anvil accounts [0] & [1] can claim and invalidate permits.
- Uses chain id
31337and RPC providerhttp://localhost:8545. - Claiming involves transferring tokens from the signer's account to the beneficiary's account.
- Signer must have signed a permit and have enough balance approved for the permit2 contract.
- Only the permit signer can invalidate it.
- Invalidating calls
invalidateUnorderedNonceson thePermit2smart contract.
- MetaMask is considered the default wallet provider.
- Ensure correct network selection in your wallet (
http://localhost:8545with chain id31337). - Use MetaMask Mobile Wallet Browser for mobile testing.
- Clear transaction history in MetaMask if transactions hang after restarting the Anvil instance.
- The test suite may show error toasts due to MetaMask spoofing.
- Ensure
.envis correctly configured and wallet provider network is correct ifAllowanceorBalanceis0.00. - Always start the Anvil instance before using
yarn startas permit generation requires an on-chain call totoken.decimals().
- Admin sets
env.AMOUNT_IN_ETHandenv.BENEFICIARY_ADDRESSdepending on a bounty hunter's reward and address - Admin generates an offline permit URL via
npx tsx generate-permit2-url.ts. Permit URL example:
http://localhost:8080?claim=eyJwZXJtaXQiOnsicGVybWl0dGVkIjp7InRva2VuIjoiMHgxMWZFNEI2QUUxM2QyYTYwNTVDOEQ5Y0Y2NWM1NWJhYzMyQjVkODQ0IiwiYW1vdW50IjoiMTAwMDAwMDAwMDAwMDAwMDAwMCJ9LCJub25jZSI6IjQ0NTUxMjc4NTQwNTU0MzM1MDQ2NzU2NDQ3MzM2MjI1ODg5OTE4OTY5MTczODQwNTU0Nzk2NzQ3MzQzMzAwOTg0NzU4MDIyMzY1ODczIiwiZGVhZGxpbmUiOiIxMTU3OTIwODkyMzczMTYxOTU0MjM1NzA5ODUwMDg2ODc5MDc4NTMyNjk5ODQ2NjU2NDA1NjQwMzk0NTc1ODQwMDc5MTMxMjk2Mzk5MzUifSwidHJhbnNmZXJEZXRhaWxzIjp7InRvIjoiMHhjODZhMDU5NzgwMThlMDRkNmVGMmFhNzNFNjlhNzMzQzA2ZDFmODllIiwicmVxdWVzdGVkQW1vdW50IjoiMTAwMDAwMDAwMDAwMDAwMDAwMCJ9LCJvd25lciI6IjB4NTRmNGEzNjQyMkRjOTZkMDg0OTY3NWMxZjBkZDJCOTZEMjc1NThFMiIsInNpZ25hdHVyZSI6IjB4NWI0OTE5MjhmYzI4MzBlMjZiNTViMWUxOWQ3YzVhMmVjNGE2ZmRhYWI1OGFiYjgyOWMwNmYzYzlkNGE4YTc5YjAzYmE2NjlkMDM4YjFmYzg5NjgzYzMyYjBiYTA5MzU2MDRjMGU1MDNjYWE3ZmY2ZWM2MDg2ZWZlYjY2MTY5MjQxYyJ9
- Admin posts offline permit URL in issue comments (with the payment portal domain name)
- Bounty hunter opens permit URL, connects wallet and clicks a "withdraw" button to get a payment
This section describes how to invalidate the following permit (i.e. invalidate a permit2 nonce)
- Setup
.envfile with the required env variables:NONCE(nonce number),NONCE_SIGNER_ADDRESS(i.e. the bot's wallet) andRPC_PROVIDER_URL. For this permit URL the.envfile will look like this:
NONCE="9867970486646789738815952475601005014850694197864057371518032581271992954680"
NONCE_SIGNER_ADDRESS="0xf87ca4583C792212e52720d127E7E0A38B818aD1"
RPC_PROVIDER_URL="https://rpc.ankr.com/gnosis"
- Run
yarn nonce:get-invalidate-params. You will get this output:
== Logs ==
Is nonce used: false
--------------------
Params for nonce invalidation via invalidateUnorderedNonces()
wordPos: 38546759713464022417249814357816425839260524210406474107492314770593722479
mask: 72057594037927936
- Open https://gnosisscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3#writeContract and connect your wallet
- Call
invalidateUnorderedNonces()with thewordPosandmaskparams you got on step 2
Notice that this examples uses gnosis chain for nonce invalidation. If you need to invalidate nonce on some other chain then:
- Set
RPC_PROVIDER_URLon step 1 to the desired RPC chain provider - On step 3 open UI for the desired chain