Guides › Gasless transactions (ERC-4337)
Chain 482120 runs the standard ERC-4337 stack: EntryPoint v0.7 and SimpleAccountFactory at their usual addresses, a public bundler, and a paymaster that pays the gas of new smart-account wallets. A user with no BTCw at all can create a wallet and trade in the first transaction.
Endpoints and contracts
| Bundler (ERC-4337 JSON-RPC) | https://btcw.tech/api/v2/4337/bundler |
|---|---|
| Paymaster service (ERC-7677) | https://btcw.tech/api/v2/4337/paymaster · status /api/v2/4337/paymaster/healthz |
| EntryPoint v0.7 | 0x0000000071727De22E5E9d8BAf0edAc6f37da032 |
| SimpleAccountFactory v0.7 | 0x91E60e0613810449d098b0b5Ec8b51A0FE8c8985 |
| VerifyingPaymaster | 0x876Be0170F5fb4Cd86b1990Bb2A34fe52F089aEd |
The factory and the EntryPoint have the same address and code as on Ethereum, so SDKs that use the standard 4337 addresses (viem, permissionless) work without
extra configuration. The paymaster is the VerifyingPaymaster that ships with EntryPoint v0.7 (@account-abstraction/contracts 0.7.0), source verified on the explorer.
Bundler methods: eth_chainId, eth_supportedEntryPoints, eth_estimateUserOperationGas, eth_sendUserOperation,
eth_getUserOperationByHash, eth_getUserOperationReceipt, pimlico_getUserOperationGasPrice. Gas price: 1000000 wei for both
maxFeePerGas and maxPriorityFeePerGas (base fee is always 0).
What is sponsored
- Wallets: SimpleAccount wallets created by the factory above, during their first 30 days (counted from their first sponsored operation).
- Calls: every call in the operation must go to one of the swap and Earn contracts — SwapRouter, OracleAMM, the ETHw oracle AMM, ClpPools, UsdClpPools,
Uniswap V2 Router02, Uniswap V3 SwapRouter02, SimpleEarn, FixedEarn, StakedBTCw (addresses in Addresses) — or be an
approvewhose spender is one of them. Transfers to other addresses are not sponsored. - Limits: 10 operations per wallet per day, 50 in its first 30 days, 600,000 gas per operation; 30 per network address per day; 1,000 per day in total.
- Vouchers are signed for one exact operation and expire after 120 seconds; the service simulates the calls before signing.
Operations outside these rules are refused with a JSON-RPC error that says why (for example call to 0x… is not covered by the sponsorship).
A wallet can always pay its own gas instead: send the operation without a paymaster once the account holds a little BTCw.
Example: a first transaction with 0 BTCw (viem + permissionless)
import { createPublicClient, http, encodeFunctionData, parseAbi, defineChain } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { createBundlerClient, createPaymasterClient, entryPoint07Address } from "viem/account-abstraction";
import { toSimpleSmartAccount } from "permissionless/accounts";
const chain = defineChain({ id: 482120, name: "Bitcoin Swap", nativeCurrency: { name: "Bitcoin Swap", symbol: "BTCw", decimals: 18 },
rpcUrls: { default: { http: ["https://rpc.btcw.tech"] } } });
const client = createPublicClient({ chain, transport: http() });
const owner = privateKeyToAccount(process.env.OWNER_KEY); // the user's signing key; it needs no BTCw
const account = await toSimpleSmartAccount({ client, owner, entryPoint: { address: entryPoint07Address, version: "0.7" },
factoryAddress: "0x91E60e0613810449d098b0b5Ec8b51A0FE8c8985" });
const fees = { maxFeePerGas: 1_000_000n, maxPriorityFeePerGas: 1_000_000n };
const bundler = createBundlerClient({ account, client,
transport: http("https://btcw.tech/api/v2/4337/bundler"),
paymaster: createPaymasterClient({ transport: http("https://btcw.tech/api/v2/4337/paymaster") }),
userOperation: { estimateFeesPerGas: async () => fees } });
// approve USDC (Bitcoin Swap) for ClpPools (an allowed spender); add the swap call to the same array to trade in one operation
const approve = encodeFunctionData({ abi: parseAbi(["function approve(address,uint256)"]), functionName: "approve",
args: ["0x557aDc3d900c471F3907cdDA3a9F5377d6F9E7e0", 10n ** 18n] });
const hash = await bundler.sendUserOperation({ calls: [{ to: "0x3b5BD179CA6Aab4DAF0f842829776843ABe6e727", value: 0n, data: approve }], ...fees });
const receipt = await bundler.waitForUserOperationReceipt({ hash });
console.log(account.address, receipt.success, receipt.receipt.transactionHash);
The first operation also deploys the wallet (about 270,000 gas); later ones cost about 120,000 gas plus the calls. Swap transactions to put in calls
come ready-built from the quote API (use the smart-account address as sender and recipient).