Skip to content

Paymaster API

The Paymaster API signs paymaster data for your ERC-4337 UserOperations over an ERC-7677-compliant JSON-RPC surface. Two surfaces exist:

  • Managed (https://api.harness.stablecoinx.com) — the platform proxy. Authenticates a publishable client key, enforces per-client origin/chain and contract allowlists, records attribution, then proxies to the paymaster service. This is the surface most integrators use.
  • Direct (https://paymaster.harness.stablecoinx.com) — the underlying paymaster service (global allowlist + per-sender policy). Its OpenAPI is at paymaster.harness.stablecoinx.com/openapi.yaml.

This page documents the managed surface.

The JSON-RPC endpoint authenticates with a publishable client ID, not a bearer key:

X-Client-Id: pmc_live_...

The client ID is safe to ship in a browser bundle — security comes from a strict per-client allowedOrigins[] + allowedChainIds[] whitelist (the publishable-key model), enforced on the request Origin. Server keys (sk_*) are not valid against the paymaster RPC.

Management endpoints (/v1/paymaster/clients|allowlist|usage) use the merchant JWT from SIWE login.

Endpoint: POST https://api.harness.stablecoinx.com/v1/paymaster/rpc with X-Client-Id + a browser Origin.

Both methods take the same positional params: the UserOperation, the EntryPoint address, the chain ID (hex), and an optional context object.

Returns dummy paymaster data for gas estimation.

{
"jsonrpc": "2.0",
"id": 1,
"method": "pm_getPaymasterStubData",
"params": [
{ "sender": "0x...", "nonce": "0x...", "callData": "0x..." },
"0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
"0x2105",
{}
]
}

The first element is the UserOperation (abbreviated above), the second is the EntryPoint address, 0x2105 is the chain ID (Base), and the last is the context object.

Identical request shape with "method": "pm_getPaymasterData"; returns the final signed paymaster values ready to submit.

The platform decodes the UserOp’s target from callData and only signs when the target is in the calling merchant’s contract allowlist for that chain. Every signed (or denied) operation is recorded for attribution.

MethodPathPurpose
GET/v1/paymaster/clientsList clients (returns the full pmc_* value).
POST/v1/paymaster/clientsCreate; returns { client } with the full clientId, allowedOrigins[], allowedChainIds[].
PATCH/v1/paymaster/clients/:idUpdate label / origins / chains.
DELETE/v1/paymaster/clients/:idRevoke.

The paymaster only sponsors UserOps whose decoded target is allowlisted. By default no contract is allowed.

MethodPathPurpose
GET/v1/paymaster/allowlistList (chainId, contractAddress) tuples.
POST/v1/paymaster/allowlistUpsert (chainId, contractAddress, label?).
DELETE/v1/paymaster/allowlist/:idRemove an entry.

GET /v1/paymaster/usage — paginated SponsorshipUsage records (cursor + filters), each with status (denied_target · denied_upstream · submitted · onchain_success · onchain_reverted · dropped), gas cost, USD snapshot, and userOpHash.

JSON-RPC errors on /rpc; standard HTTP envelopes on management routes.

ConditionResult
Unknown / revoked X-Client-Id401 paymaster_unauthorized
Origin not in allowedOrigins[]403 paymaster_origin_not_allowed
Chain not in allowedChainIds[]403 paymaster_chain_not_allowed
Target not allowlistedJSON-RPC error; usage row denied_target
Undecodable callDataJSON-RPC error; usage row denied_target (undecodable_calldata)
Paymaster service rejected the signJSON-RPC error; usage row denied_upstream
  • Paymaster — modes, architecture, and the attribution model.
  • Session Payment — pair gas sponsorship with stablecoin checkout.