BETA — mainnet live (chain 482120); features are still being finished. Transparency →
Bitcoin Swap BETA Chain 482120
Developers · Guides

Gasless transactions (ERC-4337)

Smart-account wallets with gas paid by the paymaster: bundler, ERC-7677 paymaster service, what is sponsored.

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.70x0000000071727De22E5E9d8BAf0edAc6f37da032
SimpleAccountFactory v0.70x91E60e0613810449d098b0b5Ec8b51A0FE8c8985
VerifyingPaymaster0x876Be0170F5fb4Cd86b1990Bb2A34fe52F089aEd

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

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).