
\ERC-4337 (Account Abstraction) has revolutionized the Ethereum user experience. By introducing Smart Accounts and Paymasters, we have enabled gasless transactions, social recovery, and batched operations. Apps can now sponsor users' gas fees, making Web3 feel like Web2.
But this magic comes with a hidden operational risk: Liquidity Management.
A Paymaster is essentially a gas tank. It holds ETH (or the native chain token) and uses it to reimburse the Bundler for executing UserOperations. If that gas tank runs empty, the entire application grinds to a halt. Transactions fail, users get frustrated, and the "magical" UX breaks.
In Part 1 of this series, we will build the "Fuel Gauge" for your AA infrastructure. We will create a Paymaster Liquidity Monitor using the Covalent GoldRush API. This agent will:
Continuously track the native balance of your Paymaster wallet.
Understand the difference between "Wallet Balance" and "EntryPoint Deposit."
Trigger alerts when liquidity drops below a critical threshold.
Before we write code, we must understand where the money lives. In ERC-4337, a Paymaster handles funds in two distinct places:
The EntryPoint Deposit: This is the actual gas tank. The Paymaster contract must deposit native tokens (ETH/MATIC/AVAX) into the global EntryPoint contract. The Bundler deducts gas costs directly from this internal balance during UserOp execution.
The Paymaster EOA/Wallet: This is the "Refill Truck." It is the external wallet or contract balance that holds the reserve funds before they are deposited into the EntryPoint.
The Monitoring Strategy:
While tracking the EntryPoint deposit requires reading contract state (often via RPC calls), tracking the Paymaster's Wallet Balance is the first line of defense. If the wallet is empty, the Paymaster cannot refill the EntryPoint.
We will use the GoldRush Token Balances API to monitor this reserve balance.
We will build a lightweight Node.js service.
Node.js v18+
A Covalent API Key (Get it from GoldRush.dev)
A target Paymaster address (We can use a known public Paymaster on Base or Polygon for testing)
Add this to your CLI:
mkdir paymaster-monitor
cd paymaster-monitor
npm init -y
npm install @covalenthq/client-sdk dotenv typescript ts-node @types/node
npx tsc --initCreate your .env file:
GOLDRUSH_API_KEY=your_covalent_api_key
# Example: A generic Paymaster address on Base
PAYMASTER_ADDRESS=0x00000f79b7152151b3741c0f190294741938a9b9
CHAIN_NAME=base-mainnet
LOW_BALANCE_THRESHOLD=0.5We will use the BalanceService from the GoldRush SDK. This endpoint is highly optimized for retrieving the complete portfolio of an address, but for a Paymaster, we specifically care about the Native Token (Gas Token).
Create src/monitor.ts:
import { GoldRushClient } from "@covalenthq/client-sdk";
import * as dotenv from "dotenv";
dotenv.config();
const API_KEY = process.env.GOLDRUSH_API_KEY!;
const PAYMASTER = process.env.PAYMASTER_ADDRESS!;
const CHAIN = process.env.CHAIN_NAME || "base-mainnet";
const THRESHOLD = parseFloat(process.env.LOW_BALANCE_THRESHOLD || "0.1");
const client = new GoldRushClient(API_KEY);
interface BalanceReport {
address: string;
chain: string;
nativeBalance: number;
quoteBalance: number; // USD Value
isCritical: boolean;
}
async function checkPaymasterHealth(): Promise<BalanceReport | null> {
console.log(`š Checking Paymaster Fuel: ${PAYMASTER} on ${CHAIN}...`);
try {
const resp = await client.BalanceService.getTokenBalancesForWalletAddress(
CHAIN,
PAYMASTER
);
if (resp.error) {
console.error("ā API Error:", resp.error_message);
return null;
}
// Filter for the Native Token (e.g., ETH on Base, MATIC on Polygon)
// The SDK usually marks native tokens with `native_token: true`
const nativeToken = resp.data.items.find(item => item.native_token);
if (!nativeToken) {
console.error("ā ļø No native token found in wallet!");
return null;
}
// Convert raw balance (BigInt string) to decimal
// Formula: balance / 10^decimals
const rawBalance = BigInt(nativeToken.balance);
const decimals = nativeToken.contract_decimals;
const formattedBalance = Number(rawBalance) / Math.pow(10, decimals);
const report: BalanceReport = {
address: PAYMASTER,
chain: CHAIN,
nativeBalance: formattedBalance,
quoteBalance: nativeToken.quote || 0,
isCritical: formattedBalance < THRESHOLD
};
return report;
} catch (error) {
console.error("š Fatal Error:", error);
return null;
}
}
// --- Execution Block ---
(async () => {
const health = await checkPaymasterHealth();
if (health) {
console.log("\nš PAYMASTER HEALTH REPORT");
console.log("---------------------------");
console.log(`ā½ Native Balance: ${health.nativeBalance.toFixed(4)} ETH`);
console.log(`šµ USD Value: $${health.quoteBalance.toFixed(2)}`);
console.log(`šØ Status: ${health.isCritical ? "CRITICAL LOW FUEL" : "HEALTHY"}`);
if (health.isCritical) {
// Placeholder for alerting logic (PagerDuty / Slack)
console.log(">>> TRIGGERING REFILL ALERT <<<");
}
}
})();Run the script to verify your connection to the GoldRush API.
npx ts-node src/monitor.ts

This simple output is powerful. It gives you an instant snapshot of your Paymaster's ability to fund operations.
Account Abstraction is inherently multi-chain. A dApp deployed on Base, Optimism, and Arbitrum needs Paymasters on all three.
The GoldRush SDK simplifies this. We can wrap our logic in a loop.
const CHAINS = ["base-mainnet", "optimism-mainnet", "arbitrum-mainnet"];
async function checkFleet() {
for (const chain of CHAINS) {
// We assume the Paymaster address is the same (deterministic deployment)
// or mapped via configuration
const health = await checkPaymasterHealth(chain, PAYMASTER);
// ... Log logic ...
}
}We have successfully built the "Fuel Gauge." We are monitoring the reserve liquidity that keeps the Paymaster running. However, knowing how much gas you have is only half the battle. You also need to know how fast you are burning it.
Is your Paymaster draining 0.1 ETH per day, or did it suddenly drain 5 ETH in an hour due to a bot spamming UserOps? To answer that, we need Activity Tracking.
In Part 2, we will build the "UserOp Traffic Controller." We will use the GoldRush Wallet Activity API to monitor the actual interactions with the Paymaster contract, allowing us to detect spikes, analyze gas usage patterns, and spot potential exploits in real-time.