NERONERO 402
SDK

@nerochain/x402-aa

Paymaster-sponsored signer for the aa-native scheme.

@nerochain/x402-aa is the signer that satisfies the aa-native scheme. Plug it into @nerochain/x402-client's x402Fetch and the agent can pay merchants from an ERC-4337 SCW with sponsored gas.

Install

pnpm add @nerochain/x402-aa @nerochain/x402-client ethers

Usage

import { ethers } from "ethers";
import { x402Fetch } from "@nerochain/x402-client";
import { aaNativeSigner } from "@nerochain/x402-aa";

const wallet = new ethers.Wallet(process.env.NERO_PRIVATE_KEY!);

const f = x402Fetch({
  signer: aaNativeSigner({
    signer: wallet,
    rpcUrl:           "https://rpc.nerochain.io",
    bundlerUrl:       "https://bundler-mainnet.nerochain.io",
    paymasterUrl:     "https://paymaster-mainnet.nerochain.io",
    paymasterApiKey:  process.env.NERO_PAYMASTER_API_KEY!,
    settlementContract: "0x5eCfc64f2339992668f555918674B604F97B412D",
  }),
});

Options

type AaNativeSignerOptions = {
  signer: ethers.Wallet | ethers.HDNodeWallet;
  rpcUrl: string;
  bundlerUrl: string;
  paymasterUrl: string;
  paymasterApiKey: string;
  settlementContract: string;
  entryPoint?: string;             // default: NERO v0.6 EntryPoint
  accountFactory?: string;          // default: NERO SimpleAccountFactory
  endpointFor?: (req, resource) => string;
  scwSalt?: number | bigint;        // default: 0
};
  • signer — the EOA that owns the SCW. Any ethers.Wallet or ethers.HDNodeWallet. For browser flows, a JsonRpcSigner from a Web3Auth provider works in place after a cast (see the Web3Auth integration guide).
  • rpcUrl — chain RPC.
  • bundlerUrl — ERC-4337 bundler endpoint.
  • paymasterUrl + paymasterApiKey — NERO paymaster endpoint and API key. From the NERO AA Platform dashboard.
  • settlementContract — the deployed SettlementContract proxy address.
  • entryPoint / accountFactory — defaults are correct for NERO mainnet and testnet. Override only if you're targeting a different deployment.
  • endpointFor — overrides the canonical endpoint string used in requestHash. Default: resource.url.
  • scwSalt — distinguish multiple SCWs owned by the same EOA. Default: 0.

What the signer does

When x402Fetch calls signer.buildPayload(requirement):

  1. Compute requestHash = keccak256(abi.encode(merchant, chainId, "POST", endpoint, timestampBucket, clientNonce)).
  2. Initialize a SimpleAccount builder via the userop SDK using the configured factory and salt.
  3. Set paymaster options (type 0) so the bundler routes through the paymaster.
  4. Encode executeBatch([approve(token, settlement, amount), settle(merchant, token, amount, requestHash)]).
  5. Run the paymaster + signature middleware via Client.buildUserOperation.
  6. Pack the resulting UserOp and the settlementCallSpec into the V2 envelope.

The agent's process produces a fully-formed, paymaster-sponsored, signed UserOp ready for the merchant to forward to the facilitator.

Reading the SCW address

import { Presets } from "userop";
const builder = await Presets.Builder.SimpleAccount.init(wallet, rpcUrl, {
  overrideBundlerRpc: bundlerUrl,
});
const scwAddress = builder.proxy?.address;

The address is deterministic from the EOA and the factory. It's the same on every call; you can compute it ahead of time to fund the SCW (counterfactual) before its first UserOp.

Errors

If anything in the build / sponsor / sign flow fails (bundler unreachable, paymaster API rejected the key, simulation reverts), the signer throws a PaymentSignerError with the underlying cause attached. x402Fetch propagates the error to the caller.

try {
  const res = await f(url, init);
} catch (e) {
  if (e instanceof PaymentSignerError) {
    // failed to construct the payload — bundler / paymaster issue
  } else {
    // network or other error
  }
}

On this page