A Practical Guide for Building Gasless dApps
PART ONE
Understanding AVNU Paymaster
Imagine this:
You're a normal Web2 user.
You've been hearing about Web3 for a while, and you finally decide to try it out.
You find a cool game.
The UI looks clean. It feels legit for a gamer.
So you go through the process:
You install MetaMask.
You follow a YouTube tutorial.
You create your wallet.
You come back, connect your wallet, and click the main button:
"Start"
And then you see this:
"Insufficient ETH for gas fees."
You pause.
What is gas?
Why do I need ETH?
I just want to start my game…
At this point, most users don't go buy ETH.
They leave.
This is the gas fee problem — and it quietly kills Web3 adoption.
No matter how good your product is, requiring users to hold a native token before doing anything is friction most won't tolerate, especially new web3 users.
On Starknet, AVNU Paymaster has successfully fixed this problem.
Built on Starknet's account abstraction model, it allows:
- Your dApp to sponsor gas fees entirely for users
- Or users to pay fees in supported tokens (like USDC, USDT)
No STRK required for normal transactions.
No onboarding friction.
What Is a Paymaster?
A Paymaster is a smart contract that handles transaction fees on behalf of a user. Users do not pay gas fees — the fees are paid by a sponsor on behalf of the user.
This unlocks a UX potential for dApps running on Starknet. Coupled with native account abstraction on Starknet, builders can now achieve web2 level of UX in their applications.
PART TWO
Paymaster Setup
- Setup paymaster account and create API key on AVNU portal.
Go to https://portal.avnu.fi/
Click on connect wallet and sign in
Create your account
The next page will require you to enter your name and your contact details, fill in the required details accordingly. Once you are done, click on create account and it takes you straight to your dashboard:
- Click on
Create Your First Keyto create your API key. Enter your project name (can be anything) and click oncreate key.
If you got everything right, you'll see this page:
Click on
add creditsto fund your paymaster account. The credit is what is actually used to make payments on behalf of your users.Monitor your dashboard
Once live, you can track everything from the dashboard — gas sponsored, success rate, number of unique accounts sponsored, burn rate, etc.
Now that we have completed the paymaster setup, next is to show how you can integrate it in your dApp.
PART THREE
Integration Guide
Prerequisites
- Node.js (v18+)
- JavaScript / TypeScript project
Step 1 — Install Dependencies
The PaymasterRpc class is imported directly from the starknet package. If you don't have it installed yet, add it to your project:
npm install starknet
Step 2 — Initialise the Paymaster
The PaymasterRpc class is your connection to the AVNU Paymaster service. Initialise it with your chosen network endpoint and API key:
import { PaymasterRpc } from 'starknet';
const paymaster = new PaymasterRpc({
nodeUrl: 'https://starknet.paymaster.avnu.fi', // mainnet
// nodeUrl: 'https://sepolia.paymaster.avnu.fi', // testnet (free)
headers: {
'x-paymaster-api-key': process.env.AVNU_API_KEY,
},
});
Step 3 — Execute a Sponsored Transaction
Pass the paymaster into the Account constructor, then call executePaymasterTransaction():
import { Account, RpcProvider, PaymasterRpc } from 'starknet';
const account = new Account({
provider,
address: process.env.ACCOUNT_ADDRESS,
signer: process.env.PRIVATE_KEY,
paymaster,
});
const result = await account.executePaymasterTransaction(calls, {
feeMode: { mode: 'sponsored' }, // You sponsor, user pays nothing
});
✅ No gas required from the user
✅ Paid from your AVNU credits
Step 4 — Secure Your API Key (Server Proxy)
Never expose your API key in frontend code.
Create a server-side proxy that forwards requests to AVNU with your key attached. Here's a Next.js example:
// app/api/paymaster/route.ts
export async function POST(request: Request) {
const body = await request.json();
const response = await fetch('https://starknet.paymaster.avnu.fi', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-paymaster-api-key': process.env.AVNU_API_KEY!,
},
body: JSON.stringify(body),
});
return Response.json(await response.json());
}
Here's the same pattern in an Express backend — this is taken directly from Zapcode's production wallet.js:
router.post('/paymaster', async (req, res) => {
try {
const response = await fetch(AVNU_PAYMASTER_URL, {
method: 'POST',
headers: avnuHeaders, // includes x-paymaster-api-key, stored server-side
body: JSON.stringify(req.body),
});
const data = await response.json();
res.status(response.status).json(data);
} catch (err) {
console.error('[paymaster]', err.message);
res.status(500).json({ error: err.message });
}
});
Step 5 — Use the Proxy on the Client
Point your PaymasterRpc to your own proxy route instead of directly to AVNU — your API key never touches the browser:
const paymaster = new PaymasterRpc({
nodeUrl: '/api/paymaster', // your proxy route
});
Full Working Code Example
Here's a complete, annotated JavaScript file combining all the steps above. Replace the placeholder values with your own before running.
// avnu-paymaster-example.js
import { Account, RpcProvider, PaymasterRpc } from "starknet";
import * as dotenv from "dotenv";
dotenv.config();
async function main() {
// 1. Set up the Starknet RPC provider
const provider = new RpcProvider({
// For Sepolia testnet: "https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_10/YOUR_ALCHEMY_KEY"
nodeUrl: "https://starknet-mainnet.g.alchemy.com/starknet/version/rpc/v0_10/YOUR_ALCHEMY_KEY",
});
// 2. Initialise the AVNU Paymaster
const paymaster = new PaymasterRpc({
// For Sepolia testnet: "https://sepolia.paymaster.avnu.fi"
nodeUrl: "https://starknet.paymaster.avnu.fi",
headers: {
"x-paymaster-api-key": process.env.AVNU_API_KEY,
},
});
// 3. Set up account — paymaster is passed in the constructor
const account = new Account({
provider,
address: process.env.ACCOUNT_ADDRESS,
signer: process.env.PRIVATE_KEY,
paymaster,
});
// 4. Define the contract calls to execute (we use STRK for demo)
const STRK_ADDRESS = "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d";
const calls = [
{
contractAddress: STRK_ADDRESS,
entrypoint: "transfer",
calldata: [
"0xRECIPIENT_ADDRESS", // recipient wallet address
"1000000", // amount (STRK has 18 decimals — adjust accordingly)
"0",
],
},
];
// 5. Execute — user pays nothing, your AVNU credits cover the gas
console.log("Submitting sponsored transaction...");
const result = await account.executePaymasterTransaction(calls, {
feeMode: { mode: "sponsored" },
});
console.log("Transaction hash:", result.transaction_hash);
// 6. Wait for on-chain confirmation
await provider.waitForTransaction(result.transaction_hash, {
retryInterval: 2000,
});
console.log("Confirmed!");
}
main().catch(console.error);
Create a .env file in your project root:
AVNU_API_KEY=your_api_key_from_portal
ACCOUNT_ADDRESS=0xYOUR_STARKNET_ACCOUNT_ADDRESS
PRIVATE_KEY=0xYOUR_PRIVATE_KEY
Run it:
node avnu-paymaster-example.js
Testing & Verifying Your Integration
Test on Sepolia first — switch your PaymasterRpc nodeUrl to sepolia.paymaster.avnu.fi. Credits are unlimited and free.
Check your dashboard — after running a transaction, go to your AVNU Portal explorer on your dashboard. You should see:
- The transaction hash appear in your logs
- The gas cost deducted (on Sepolia this is simulated — no real cost)
- Transaction status: confirmed or failed
Common errors:
| Error | Fix |
|---|---|
| 401 Unauthorised | API key is missing or incorrect — check your .env file |
| Account not compatible | Your wallet must be Ready (ArgentX) or Braavos and deployed on-chain |
| Insufficient credits | Top up your credit balance in the AVNU Portal (mainnet only) |
| Transaction rejected | Check your calldata and contract address are correct |
Conclusion & Next Steps
You now have everything you need to integrate AVNU Paymaster into your Starknet dApp. To recap what you've built:
- Set up your account and API key in the AVNU Portal
- Initialised the
PaymasterRpcprovider with starknet.js - Executed a fully sponsored transaction — gas paid by your dApp
- Set up a secure server-side proxy to protect your API key
Gas sponsorship is one part of the AVNU paymaster guide. In the next guide, we'll cover the second mode — letting users pay gas in any token (USDC, USDT, LORDS, wstETH, and more) — which opens up entirely new possibilities for builders on Starknet.
Useful Links
- AVNU Portal — portal.avnu.fi
- AVNU Paymaster Docs — docs.avnu.fi/docs/paymaster
- starknet.js — starknetjs.com
- GitHub — github.com/avnu-labs/paymaster
For questions or feedback, kindly leave a comment or send a message at https://x.com/okolievans




Top comments (0)