Ready. This template is published in uzolabs/templates and has been deployed and verified on testnet. It’s a learning template and hasn’t been audited. Use test funds only.
What you’ll build
A relayer that pays gas for the functions you choose on your own contract, with limits that fit your budget. Start with the settings, then change the contract and the relayer’s allowlist together.Prerequisites
- A copy of the template that relays, from Use a template.
- The walkthrough, so you know the relayer’s checks.
Rate limits and gas cap
These need no code changes. Set them in.env and restart the relayer:
.env
RateLimiter in relayer/src/rate-limit.ts with one backed by a shared store, or each instance counts separately.
Relay your own contract
1
Make the contract trust the forwarder
Extend A single
ERC2771Context, pass the forwarder’s address to the constructor, and use _msgSender() wherever you’d use msg.sender:contracts/Counter.sol
msg.sender left in your contract would record the relayer instead of the user.2
Deploy it with the forwarder
Update
script/Deploy.s.sol, ignition/modules/GuestBook.ts and scripts/deploy.ts to deploy your contract after UzoForwarder, passing the forwarder’s address. Keep writing both addresses to deployments/968.json.3
Change the relayer's allowlist
In Change the selector to your function, such as
relayer/src/forward.ts, the relayer refuses everything except one target and one function:relayer/src/forward.ts
toFunctionSelector("increment()"), and point the target check at your contract. Replace the message length checks below it with checks that suit your function’s arguments.Allow only the functions you’re willing to pay for. Every allowed function is one anyone can call at your expense, up to the rate limits.4
Test, refresh the ABI and redeploy
Terminal
Message length
To change the 280 byte limit, change all three together:
The contract is the final check. The other two only give a clearer error sooner.
Who may use it
To limit who can use your relayer, add a check inrelayer/src/app.ts before it sends, such as an allowlist of signer addresses or a login.
Host the relayer
- Run
npm run relayeron a server with its own.envand a relayer wallet funded with only what you’re willing to spend. - Put it behind HTTPS.
- Set
RELAYER_ALLOWED_ORIGINSto your site’s address. - Set
VITE_RELAYER_URLinfrontend/.envto the relayer’s public URL, then rebuild the web app.
RELAYER_TRUST_PROXY=true only if the relayer runs behind your own reverse proxy.
Change the look
Edit the variables at the top offrontend/src/theme.css for colours and fonts, and frontend/src/styles.css for this app’s own styles.
Verify
With the relayer running, sign from a wallet holding 0 tBOT. On BOTScan, the transaction’s sender is the relayer, and your contract records the signer. For the counter above,counts(<signer>) on the Read contract tab should go up by one.
Troubleshooting
This relayer only pays for calls to the guest book
This relayer only pays for calls to the guest book
The target check still points at the guest book, or
frontend/.env and deployments/968.json point at different deploys. Update the check, redeploy, and restart the relayer and the web app.My contract records the relayer as the sender
My contract records the relayer as the sender
Somewhere it uses
msg.sender instead of _msgSender(), or it was deployed with a different forwarder address.The forwarder rejected the signature or the request has expired
The forwarder rejected the signature or the request has expired
The request was already used, signed for an old nonce, or is more than 10 minutes old. Sign again. After a new deploy, restart the relayer so it uses the new forwarder.
Could not reach the relayer
Could not reach the relayer
Check that it’s running and that
VITE_RELAYER_URL matches its port. A CORS error in the browser console means the page’s address is missing from RELAYER_ALLOWED_ORIGINS.Too many requests
Too many requests
The signer or IP hit the rate limit. Wait, or raise
RELAYER_RATE_LIMIT and restart the relayer.The relayer is low on tBOT
The relayer is low on tBOT
Its balance is below
RELAYER_LOW_BALANCE. Send it tBOT from the faucet.Next steps
Run a relayer
Operating a relayer safely.
EOA paymaster
BOT Chain’s paymaster flow.