@devlab.group/agent-commerce 1.5.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +73 -71
  2. package/dist/ap2.d.ts +20 -23
  3. package/dist/ap2.js +53 -75
  4. package/dist/ap2.js.map +1 -1
  5. package/dist/authorization-BpbWGGrf.d.ts +115 -0
  6. package/dist/chunk-AFI2CEZS.js +10 -0
  7. package/dist/chunk-AFI2CEZS.js.map +1 -0
  8. package/dist/{chunk-PBYN7EK2.js → chunk-CBJIT7QP.js} +10 -9
  9. package/dist/chunk-CBJIT7QP.js.map +1 -0
  10. package/dist/{chunk-NKNXVDHN.js → chunk-JKEKKXRJ.js} +45 -66
  11. package/dist/chunk-JKEKKXRJ.js.map +1 -0
  12. package/dist/{chunk-5GEWKNIH.js → chunk-N5KRK7YA.js} +63 -27
  13. package/dist/chunk-N5KRK7YA.js.map +1 -0
  14. package/dist/{chunk-6D2EZ5ME.js → chunk-V2V2E7HX.js} +2 -2
  15. package/dist/{chunk-6D2EZ5ME.js.map → chunk-V2V2E7HX.js.map} +1 -1
  16. package/dist/{chunk-US622BKF.js → chunk-VKDXMXHL.js} +5 -8
  17. package/dist/chunk-VKDXMXHL.js.map +1 -0
  18. package/dist/cli/index.js +501 -494
  19. package/dist/cli/index.js.map +1 -1
  20. package/dist/{constants-6mypC60h.d.ts → constants-Bkq04FRZ.d.ts} +1 -3
  21. package/dist/guardrails-71XwtXlT.d.ts +31 -0
  22. package/dist/index.d.ts +230 -265
  23. package/dist/index.js +1050 -607
  24. package/dist/index.js.map +1 -1
  25. package/dist/mcp.d.ts +6 -59
  26. package/dist/mcp.js +61 -53
  27. package/dist/mcp.js.map +1 -1
  28. package/dist/mpp.d.ts +4 -4
  29. package/dist/mpp.js +21 -19
  30. package/dist/mpp.js.map +1 -1
  31. package/dist/protocol-adapter-DTkrXTev.d.ts +238 -0
  32. package/dist/runtime-CiYbgGpi.d.ts +303 -0
  33. package/dist/{types-CJtwLu1c.d.ts → types-O6lg3Q5V.d.ts} +17 -23
  34. package/dist/x402.d.ts +43 -75
  35. package/dist/x402.js +10 -9
  36. package/dist/x402.js.map +1 -1
  37. package/package.json +7 -5
  38. package/dist/authorization-DA7mjy_O.d.ts +0 -123
  39. package/dist/chunk-5GEWKNIH.js.map +0 -1
  40. package/dist/chunk-NKNXVDHN.js.map +0 -1
  41. package/dist/chunk-PBYN7EK2.js.map +0 -1
  42. package/dist/chunk-US622BKF.js.map +0 -1
  43. package/dist/guardrails-Dmwi63KB.d.ts +0 -38
  44. package/dist/protocol-adapter-APRjs1E2.d.ts +0 -273
  45. package/dist/runtime-DC5XQ9Cc.d.ts +0 -351
@@ -0,0 +1,115 @@
1
+ import { f as AuthorizationMethodName, A as AdapterDescriptor, m as PaymentRequirement, c as AdapterHealth } from './runtime-CiYbgGpi.js';
2
+
3
+ /**
4
+ * Canonical authorization model. FROZEN CONTRACT.
5
+ *
6
+ * Payment proves that funds moved; authorization proves that the human behind
7
+ * the agent approved this exact purchase. A valid authorization gates
8
+ * settlement but never unlocks a paid resource on its own and never moves
9
+ * money, so a resource that requires one still needs a payment proof.
10
+ *
11
+ * Core decides that a resource requires authorization and when the pipeline
12
+ * checks it. Authorization providers decide how a submission is parsed,
13
+ * verified and bound to the purchase. No AP2, SD-JWT or JWT type may appear in
14
+ * this file.
15
+ */
16
+
17
+ /**
18
+ * Opaque authorization proof supplied by the buyer's client. Over HTTP it
19
+ * arrives as base64url JSON in the `Agent-Authorization` header; over MCP and
20
+ * A2A it is the same `{ method, payload }` object in the reserved
21
+ * `_authorization` input field.
22
+ *
23
+ * `payload` is kept byte for byte from the wire. It may hold signed or
24
+ * encoding-sensitive provider data, so transport adapters must not normalize
25
+ * it.
26
+ */
27
+ interface AuthorizationSubmission {
28
+ readonly method: AuthorizationMethodName;
29
+ readonly payload: string;
30
+ }
31
+ /**
32
+ * What a buyer must present, advertised with the payment challenge so a client
33
+ * learns before it pays that a payment proof alone will not do. The gateway
34
+ * never issues the authorization; it names the method, the spec version it
35
+ * verifies against and the payload profile it expects.
36
+ */
37
+ interface AuthorizationRequirement {
38
+ readonly method: AuthorizationMethodName;
39
+ readonly version: string;
40
+ readonly profile?: string;
41
+ }
42
+ /**
43
+ * Safe audit identity of an authorization, fit for a receipt. `reference` is a
44
+ * digest, because a receipt outlives its request and a stored proof would be a
45
+ * spendable secret at rest.
46
+ */
47
+ interface AuthorizationRecord {
48
+ readonly method: AuthorizationMethodName;
49
+ readonly reference: string;
50
+ /** Safe audit summary only. Never the proof, its disclosures, or PII */
51
+ readonly metadata?: Readonly<Record<string, unknown>>;
52
+ }
53
+ /**
54
+ * A verified, reserved authorization. `reservationId` is the handle the
55
+ * pipeline consumes, releases or marks uncertain once the payment resolves. It
56
+ * stays out of `AuthorizationRecord` because a handle is not an audit fact.
57
+ */
58
+ interface AuthorizationVerification extends AuthorizationRecord {
59
+ readonly status: 'verified';
60
+ readonly reservationId: string;
61
+ }
62
+ /** Input to {@link AuthorizationProvider.verifyAndReserve} */
63
+ interface AuthorizationVerificationContext {
64
+ readonly requestId: string;
65
+ readonly resourceId: string;
66
+ /**
67
+ * The validated resource input with reserved fields stripped: the same value
68
+ * the merchant backend is called with. A provider that binds a proof to the
69
+ * request hashes it, so it excludes `_payment`, `_authorization`, the request
70
+ * id and transport metadata.
71
+ */
72
+ readonly input: unknown;
73
+ readonly submission: AuthorizationSubmission;
74
+ /** The resolved price and destination the proof must match */
75
+ readonly requirement: PaymentRequirement;
76
+ }
77
+ /** Input to {@link AuthorizationProvider.consume}, `release` and `markUncertain` */
78
+ interface AuthorizationFinalizeContext {
79
+ readonly requestId: string;
80
+ readonly resourceId: string;
81
+ }
82
+ /**
83
+ * Contract every authorization method implements.
84
+ *
85
+ * The lifecycle straddles settlement: a proof is reserved before funds move, so
86
+ * a replay cannot race it, and its fate is known only afterwards. A reservation
87
+ * is released only after a failure that provably moved no money. Anything
88
+ * ambiguous is marked uncertain, because a proof handed back after a settlement
89
+ * that may have landed can be spent twice.
90
+ */
91
+ interface AuthorizationProvider {
92
+ readonly name: AuthorizationMethodName;
93
+ readonly descriptor: AdapterDescriptor;
94
+ /** What a buyer must present, advertised with the payment challenge */
95
+ readonly requirement: AuthorizationRequirement;
96
+ /**
97
+ * Verify a submission against the resolved purchase and atomically reserve it
98
+ * against reuse. Throws a `CommerceError` with an `AUTHORIZATION_*` code,
99
+ * never a payment code; a verifier or store outage is
100
+ * `AUTHORIZATION_PROVIDER_UNAVAILABLE`, not the buyer's fault.
101
+ */
102
+ verifyAndReserve(context: AuthorizationVerificationContext): Promise<AuthorizationVerification>;
103
+ /** Mark a reservation permanently spent. Called after settlement succeeds */
104
+ consume(reservationId: string, context: AuthorizationFinalizeContext): Promise<void>;
105
+ /** Return a reservation to unused. Only for failures that moved no funds */
106
+ release(reservationId: string, context: AuthorizationFinalizeContext): Promise<void>;
107
+ /**
108
+ * Settlement threw, so whether funds moved is unknown: neither spend the
109
+ * reservation nor hand it back, and flag it for an operator
110
+ */
111
+ markUncertain(reservationId: string, context: AuthorizationFinalizeContext): Promise<void>;
112
+ health(): Promise<AdapterHealth>;
113
+ }
114
+
115
+ export type { AuthorizationProvider as A, AuthorizationRequirement as a, AuthorizationSubmission as b, AuthorizationFinalizeContext as c, AuthorizationRecord as d, AuthorizationVerification as e, AuthorizationVerificationContext as f };
@@ -0,0 +1,10 @@
1
+ // src/protocols/mcp/constants.ts
2
+ var MCP_TOOL_NAME_CHARS = "A-Za-z0-9._-";
3
+ var MCP_TOOL_NAME_MAX_LENGTH = 128;
4
+ var MCP_TOOL_NAME_PATTERN = new RegExp(
5
+ `^[${MCP_TOOL_NAME_CHARS}]{1,${MCP_TOOL_NAME_MAX_LENGTH}}$`
6
+ );
7
+
8
+ export { MCP_TOOL_NAME_PATTERN };
9
+ //# sourceMappingURL=chunk-AFI2CEZS.js.map
10
+ //# sourceMappingURL=chunk-AFI2CEZS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/protocols/mcp/constants.ts"],"names":[],"mappings":";AAUO,IAAM,mBAAA,GAAsB,cAAA;AAG5B,IAAM,wBAAA,GAA2B,GAAA;AAQjC,IAAM,wBAAwB,IAAI,MAAA;AAAA,EACvC,CAAA,EAAA,EAAK,mBAAmB,CAAA,IAAA,EAAO,wBAAwB,CAAA,EAAA;AACzD","file":"chunk-AFI2CEZS.js","sourcesContent":["/**\n * MCP protocol constants shared by the config layer, the adapter and the\n * OpenAPI importer.\n *\n * Kept dependency-free: `src/config` validates tool names at load time, so\n * anything imported here would become a config-load dependency too, and the\n * MCP SDK is an optional peer the main entry and CLI must never load.\n */\n\n/** Characters SEP-986 allows in an MCP tool name, as a regex character class body */\nexport const MCP_TOOL_NAME_CHARS = 'A-Za-z0-9._-';\n\n/** Longest MCP tool name SEP-986 allows */\nexport const MCP_TOOL_NAME_MAX_LENGTH = 128;\n\n/**\n * MCP tool names per SEP-986: 1-128 chars of [A-Za-z0-9._-], the SDK's own\n * `TOOL_NAME_REGEX`, which it does not export. Config refuses an mcp-exposed\n * resource whose id fails it; the low-level `Server` checks no names, so the\n * adapter also skips such an id with a warning.\n */\nexport const MCP_TOOL_NAME_PATTERN = new RegExp(\n `^[${MCP_TOOL_NAME_CHARS}]{1,${MCP_TOOL_NAME_MAX_LENGTH}}$`,\n);\n"]}
@@ -1,6 +1,7 @@
1
- import { CommerceError } from './chunk-5GEWKNIH.js';
1
+ import { CommerceError } from './chunk-N5KRK7YA.js';
2
2
 
3
3
  // src/payments/x402/networks.ts
4
+ var LOCAL_CHAIN_ID = 84532;
4
5
  var PROFILES = [
5
6
  {
6
7
  id: "eip155:84532",
@@ -44,7 +45,7 @@ function resolveDeploymentMode(profile, facilitatorMode) {
44
45
  if (facilitatorMode === "local") return "local";
45
46
  return profile.kind;
46
47
  }
47
- var LIVE_MAINNET_BANNER = "LIVE MAINNET MODE \u2014 REAL FUNDS";
48
+ var LIVE_MAINNET_BANNER = "LIVE MAINNET MODE - REAL FUNDS";
48
49
  function describeDeploymentMode(mode) {
49
50
  return mode === "mainnet" ? LIVE_MAINNET_BANNER : mode.toUpperCase();
50
51
  }
@@ -81,7 +82,7 @@ function isWellKnownDevAddress(address) {
81
82
  }
82
83
  function isLikelyLocalOrPrivateHost(hostname) {
83
84
  const h = hostname.toLowerCase().replace(/^\[|\]$/g, "");
84
- if (h === "localhost" || h === "127.0.0.1" || h === "::1") return true;
85
+ if (h === "localhost" || h === "::1") return true;
85
86
  if (/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(h)) return true;
86
87
  if (/^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(h)) return true;
87
88
  if (/^192\.168\.\d{1,3}\.\d{1,3}$/.test(h)) return true;
@@ -117,7 +118,7 @@ function assertDevKeyIsLocalOnly(rpcUrl, signerPrivateKey) {
117
118
  if (!isLikelyLocalOrPrivateHost(hostname)) {
118
119
  throw new CommerceError(
119
120
  "CONFIG_INVALID",
120
- `x402 provider: facilitator.signerPrivateKey is a well-known Anvil development key, but rpcUrl ${describeRpc(rpcUrl)} does not look like a local/private chain. A public dev key must never sign against a public network \u2014 it is instantly drainable and can grief real settlements via nonce exhaustion. Use a real facilitator key for any non-local RPC, or point rpcUrl at your local/dev chain.`
121
+ `x402 provider: facilitator.signerPrivateKey is a well-known Anvil development key, but rpcUrl ${describeRpc(rpcUrl)} does not look like a local/private chain. A public dev key must never sign against a public network: it is instantly drainable and can grief real settlements via nonce exhaustion. Use a real facilitator key for any non-local RPC, or point rpcUrl at your local/dev chain.`
121
122
  );
122
123
  }
123
124
  }
@@ -157,7 +158,7 @@ function resolveX402Deployment(input) {
157
158
  assertFacilitatorUrlIsSafe(input.facilitator.url, mode, at);
158
159
  if (mode === "mainnet" && input.facilitator.auth.type === "none" && input.allowUnauthenticatedFacilitator !== true) {
159
160
  throw invalid(
160
- `${at}: facilitator ${describeOrigin(input.facilitator.url)} takes no credential, and this is a mainnet deployment. It will see every payment authorisation you handle, with no account, terms or support behind it. Set ${at}.allowUnauthenticatedFacilitator: true to accept that, or configure facilitator.auth.`,
161
+ `${at}: no credential is configured for facilitator ${describeOrigin(input.facilitator.url)} on mainnet. Set ${at}.allowUnauthenticatedFacilitator: true to accept anonymous access and the facilitator's limits, or configure facilitator.auth.`,
161
162
  `${at}.allowUnauthenticatedFacilitator`
162
163
  );
163
164
  }
@@ -224,7 +225,7 @@ function assertFacilitatorUrlIsSafe(url, mode, at) {
224
225
  }
225
226
  if (mode !== "mainnet" && isLikelyLocalOrPrivateHost(parsed.hostname)) return;
226
227
  throw invalid(
227
- `${at}: facilitator ${describeOrigin(url)} is reached over plain HTTP. Payment authorisations and settlement results would travel unencrypted. Use https, or point at a local/private host on a non-mainnet deployment.`,
228
+ `${at}: facilitator ${describeOrigin(url)} is reached over plain HTTP. Payment authorizations and settlement results would travel unencrypted. Use https, or point at a local/private host on a non-mainnet deployment.`,
228
229
  `${at}.facilitator.url`
229
230
  );
230
231
  }
@@ -252,6 +253,6 @@ function sameAddress(a, b) {
252
253
  return a.toLowerCase() === b.toLowerCase();
253
254
  }
254
255
 
255
- export { SUPPORTED_NETWORK_IDS, assertDevKeyIsLocalOnly, assertPayToIsNotDevAddress, describeDeploymentMode, describeRpc, requireNetworkProfile, resolveDeploymentMode, resolveX402Deployment };
256
- //# sourceMappingURL=chunk-PBYN7EK2.js.map
257
- //# sourceMappingURL=chunk-PBYN7EK2.js.map
256
+ export { LOCAL_CHAIN_ID, SUPPORTED_NETWORK_IDS, assertDevKeyIsLocalOnly, assertPayToIsNotDevAddress, describeDeploymentMode, describeRpc, requireNetworkProfile, resolveDeploymentMode, resolveX402Deployment };
257
+ //# sourceMappingURL=chunk-CBJIT7QP.js.map
258
+ //# sourceMappingURL=chunk-CBJIT7QP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/payments/x402/networks.ts","../src/payments/x402/local-chain/accounts.ts","../src/payments/x402/dev-key-guard.ts","../src/payments/x402/guardrails.ts"],"names":[],"mappings":"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","file":"chunk-CBJIT7QP.js","sourcesContent":["/**\n * The networks this gateway settles on, as data: the chain id to sign against,\n * a display name, and whether real money is involved.\n *\n * A registry rather than \"parse any `eip155:*`\": the chain id parses from any\n * such string, but whether it is a mainnet does not, and the guardrails key off\n * that. An unknown id is refused at startup instead of passing as a testnet.\n *\n * The local dev chain runs under Base Sepolia's `eip155:84532`, so nothing may\n * infer \"public network\" from the id alone. `resolveDeploymentMode` derives\n * the mode from the facilitator too, and the provider's health check confirms\n * that a local facilitator's node is Anvil.\n */\nimport { CommerceError } from '../../core';\n\n/** Chain id of the local dev chain, which Base Sepolia uses too */\nexport const LOCAL_CHAIN_ID = 84532;\n\nexport interface NetworkProfile {\n /** CAIP-2 identifier, e.g. `eip155:84532` */\n readonly id: string;\n /** Signed into the buyer's EIP-712 domain */\n readonly chainId: number;\n readonly displayName: string;\n readonly kind: 'testnet' | 'mainnet';\n /**\n * The USDC deployment this network settles in, with the EIP-712 domain the\n * token reports. Enforced on mainnet only, since a testnet may use a mock\n * token.\n *\n * `name` is the signed EIP-712 domain name, not the symbol, and the two\n * deployments differ: `\"USDC\"` on Base Sepolia, `\"USD Coin\"` on Base. The\n * values were read back from the contracts.\n */\n readonly canonicalAsset?: {\n readonly symbol: string;\n readonly address: string;\n readonly name: string;\n readonly version: string;\n };\n}\n\nconst PROFILES: readonly NetworkProfile[] = [\n {\n id: 'eip155:84532',\n chainId: 84532,\n displayName: 'Base Sepolia',\n kind: 'testnet',\n canonicalAsset: {\n symbol: 'USDC',\n address: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n name: 'USDC',\n version: '2',\n },\n },\n {\n id: 'eip155:8453',\n chainId: 8453,\n displayName: 'Base',\n kind: 'mainnet',\n canonicalAsset: {\n symbol: 'USDC',\n address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n name: 'USD Coin',\n version: '2',\n },\n },\n];\n\nconst BY_ID = new Map(PROFILES.map((profile) => [profile.id, profile]));\n\nexport const SUPPORTED_NETWORK_IDS: readonly string[] = PROFILES.map((p) => p.id);\n\nexport function findNetworkProfile(id: string): NetworkProfile | undefined {\n return BY_ID.get(id);\n}\n\nexport function requireNetworkProfile(id: string, path: string): NetworkProfile {\n const profile = BY_ID.get(id);\n if (!profile) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `${path}: \"${id}\" is not a supported network. Supported CAIP-2 identifiers: ${SUPPORTED_NETWORK_IDS.join(', ')}`,\n { details: { path, network: id } },\n );\n }\n return profile;\n}\n\n/**\n * What a deployment is, as opposed to the network it names. `local` comes from\n * the facilitator: the in-process facilitator makes a deployment local whatever\n * CAIP-2 id it is configured with, which lets diagnostics show `eip155:84532`\n * without claiming public Base Sepolia.\n */\nexport type DeploymentMode = 'local' | 'testnet' | 'mainnet';\n\nexport function resolveDeploymentMode(\n profile: NetworkProfile,\n facilitatorMode: 'local' | 'remote',\n): DeploymentMode {\n if (facilitatorMode === 'local') return 'local';\n return profile.kind;\n}\n\n// The banner an operator must not miss. Printed for mainnet only\nconst LIVE_MAINNET_BANNER = 'LIVE MAINNET MODE - REAL FUNDS';\n\nexport function describeDeploymentMode(mode: DeploymentMode): string {\n return mode === 'mainnet' ? LIVE_MAINNET_BANNER : mode.toUpperCase();\n}\n","/**\n * Anvil's well-known development accounts.\n *\n * LOCAL DEVELOPMENT ONLY - DO NOT FUND. The keys come from Foundry's public\n * default mnemonic (\"test test ... junk\"), so value sent to these addresses on\n * a real network can be taken by anyone.\n *\n * Index layout on the local demo chain:\n * 0 - deployer and local facilitator signer (pays gas, broadcasts settlement)\n * 1 - merchant settlement destination (`payTo`)\n * 2 - buyer (signs EIP-3009 authorizations; never held by the gateway)\n */\nexport interface AnvilWellKnownAccount {\n readonly address: `0x${string}`;\n readonly privateKey: `0x${string}`;\n}\n\n/** A fixed-length tuple, so indexing by the layout above is typed */\nexport const ANVIL_WELL_KNOWN_ACCOUNTS: readonly [\n AnvilWellKnownAccount,\n AnvilWellKnownAccount,\n AnvilWellKnownAccount,\n] = [\n {\n address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\n privateKey: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',\n },\n {\n address: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',\n privateKey: '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d',\n },\n {\n address: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',\n privateKey: '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a',\n },\n];\n\nexport const LOCAL_FACILITATOR_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[0];\nexport const LOCAL_MERCHANT_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[1];\nexport const LOCAL_BUYER_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[2];\n\n/** Label printed wherever a dev key appears in output, logs or manifests */\nexport const DEV_KEY_LABEL = 'LOCAL DEVELOPMENT ONLY - DO NOT FUND';\n","/**\n * Rejects well-known Anvil keys and payment destinations when the RPC host\n * does not look local or private. Their private keys are published, so anyone\n * can spend what such an address receives on a public chain.\n *\n * The check uses the RPC hostname because the local chain shares Base\n * Sepolia's chain id. Both guards run at provider construction.\n */\nimport { CommerceError } from '../../core';\nimport { ANVIL_WELL_KNOWN_ACCOUNTS } from './local-chain/accounts';\n\nconst WELL_KNOWN_DEV_KEYS: ReadonlySet<string> = new Set(\n ANVIL_WELL_KNOWN_ACCOUNTS.map((a) => a.privateKey.toLowerCase()),\n);\n\nconst WELL_KNOWN_DEV_ADDRESSES: ReadonlySet<string> = new Set(\n ANVIL_WELL_KNOWN_ACCOUNTS.map((a) => a.address.toLowerCase()),\n);\n\n// `0x` plus 64 hex characters, the only shape `privateKeyToAccount` accepts\nconst PRIVATE_KEY_SHAPE = /^0x[0-9a-fA-F]{64}$/;\n\nexport function isWellKnownDevKey(privateKey: string): boolean {\n return WELL_KNOWN_DEV_KEYS.has(privateKey.toLowerCase());\n}\n\nexport function isWellKnownDevAddress(address: string): boolean {\n return WELL_KNOWN_DEV_ADDRESSES.has(address.toLowerCase());\n}\n\n/**\n * True for loopback addresses, RFC 1918 private ranges, and bare (dot-free)\n * hostnames, such as the compose service name \"anvil\".\n *\n * Bare hostnames are treated as local without resolving them. Operators must\n * point them at a private chain.\n */\nexport function isLikelyLocalOrPrivateHost(hostname: string): boolean {\n const h = hostname.toLowerCase().replace(/^\\[|\\]$/g, '');\n if (h === 'localhost' || h === '::1') return true;\n if (/^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^192\\.168\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^172\\.(1[6-9]|2\\d|3[01])\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (!h.includes('.') && !h.includes(':')) return true; // bare hostname\n return false;\n}\n\nfunction parseHostnameOrThrow(rpcUrl: string): string {\n try {\n return new URL(rpcUrl).hostname;\n } catch (cause) {\n // Never the URL itself: RPC providers commonly put an API key in the path,\n // and this message reaches startup output and CI logs\n throw new CommerceError('CONFIG_INVALID', 'x402 provider: rpcUrl is not a valid URL', {\n cause,\n });\n }\n}\n\n/** Origin only, for diagnostics: RPC URLs often carry an API key in the path or query */\nexport function describeRpc(rpcUrl: string): string {\n try {\n return new URL(rpcUrl).origin;\n } catch {\n return '[unparseable rpcUrl]';\n }\n}\n\n/**\n * Throws CONFIG_INVALID if `signerPrivateKey` is not shaped like a private key,\n * or if it is a well-known dev key and the RPC is not local.\n *\n * The shape check runs first, so a truncated key is reported as malformed\n * instead of passing as \"not a dev key\".\n */\nexport function assertDevKeyIsLocalOnly(rpcUrl: string, signerPrivateKey: string): void {\n if (!PRIVATE_KEY_SHAPE.test(signerPrivateKey)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: facilitator.signerPrivateKey is not a well-formed private key ' +\n '(expected \"0x\" followed by exactly 64 hex characters).',\n );\n }\n\n if (!isWellKnownDevKey(signerPrivateKey)) return; // the operator's own key\n\n const hostname = parseHostnameOrThrow(rpcUrl);\n\n if (!isLikelyLocalOrPrivateHost(hostname)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: facilitator.signerPrivateKey is a well-known Anvil development key, but rpcUrl ' +\n `${describeRpc(rpcUrl)} does not look like a local/private chain. A public dev key must never sign against ` +\n 'a public network: it is instantly drainable and can grief real settlements via nonce exhaustion. ' +\n 'Use a real facilitator key for any non-local RPC, or point rpcUrl at your local/dev chain.',\n );\n }\n}\n\n/**\n * Throws CONFIG_INVALID if `payTo` is a well-known Anvil address and `rpcUrl`\n * does not look local or private.\n *\n * Guards the receiving side, in every facilitator mode. `agent-commerce init`\n * defaults `payTo` to a well-known address for the local demo, and on a real\n * network that default sends every payment where anyone can sweep it.\n */\nexport function assertPayToIsNotDevAddress(rpcUrl: string, payTo: string): void {\n if (!isWellKnownDevAddress(payTo)) return;\n\n const hostname = parseHostnameOrThrow(rpcUrl);\n\n if (!isLikelyLocalOrPrivateHost(hostname)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"payTo\" (${payTo}) is a well-known Anvil development address, but rpcUrl ` +\n `${describeRpc(rpcUrl)} does not look like a local/private chain. The private key behind that address ` +\n 'is public knowledge, so any revenue settled to it is immediately spendable by anyone. Set ' +\n '\"payTo\" to your own merchant wallet for any non-local RPC, or point rpcUrl at your ' +\n 'local/dev chain.',\n );\n }\n}\n","/**\n * What must hold before this gateway may settle a payment on the configured\n * network. Two callers share these checks: the provider runs them at\n * construction, so a library consumer who skips our config loader still gets\n * them, and the config loader runs them, so `validate` and `doctor` report\n * them too.\n *\n * Both run before any request, because a failure found in `settle()` would\n * come after the pipeline reserved the buyer's replay key.\n *\n * Imports no peer (no viem, no `@x402/*`), so the CLI can load it.\n */\nimport { CommerceError } from '../../core';\nimport { isLikelyLocalOrPrivateHost, isWellKnownDevAddress } from './dev-key-guard';\nimport {\n type DeploymentMode,\n type NetworkProfile,\n requireNetworkProfile,\n resolveDeploymentMode,\n} from './networks';\n\n/**\n * How the gateway authenticates to a remote facilitator.\n *\n * - `none`: send no credential; use it when the facilitator accepts\n * anonymous requests.\n * - `bearer`: send a static token; no extra peer package is needed.\n * - `cdp`: Coinbase Developer Platform. The optional peer `@coinbase/x402`,\n * imported only for this type, signs a fresh JWT per request.\n *\n * Any other auth type is refused at config load.\n */\nexport type FacilitatorAuth =\n | { readonly type: 'none' }\n | { readonly type: 'bearer'; readonly token: string }\n | { readonly type: 'cdp'; readonly apiKeyId: string; readonly apiKeySecret: string };\n\nexport type X402FacilitatorConfig =\n | { readonly mode: 'local'; readonly signerPrivateKey: string }\n | { readonly mode: 'remote'; readonly url: string; readonly auth: FacilitatorAuth };\n\nexport interface X402DeploymentInput {\n readonly network: string;\n readonly payTo: string;\n readonly asset: string;\n /** EIP-712 domain of the asset, as the token itself reports it */\n readonly assetName?: string;\n readonly assetVersion?: string;\n readonly facilitator: X402FacilitatorConfig;\n /** Must be `true` before anything settles on a mainnet */\n readonly allowMainnet?: boolean;\n /**\n * Must be `true` on mainnet when facilitator auth is `none`. A separate\n * decision from `allowMainnet`: it accepts settling without an account at\n * the facilitator, under its anonymous-access limits.\n */\n readonly allowUnauthenticatedFacilitator?: boolean;\n /** Error-path prefix, `payments.x402` by default */\n readonly configPath?: string;\n /** Settlement-recipient field named in errors, `payTo` by default */\n readonly payToField?: string;\n}\n\nexport interface X402Deployment {\n readonly profile: NetworkProfile;\n readonly mode: DeploymentMode;\n}\n\nfunction invalid(message: string, path: string): CommerceError {\n return new CommerceError('CONFIG_INVALID', message, { details: { path } });\n}\n\n/**\n * Resolves the deployment and refuses the combinations that could move real\n * money by accident. The network must resolve first; the other checks are\n * independent.\n */\nexport function resolveX402Deployment(input: X402DeploymentInput): X402Deployment {\n const at = input.configPath ?? 'payments.x402';\n const payTo = input.payToField ?? 'payTo';\n const profile = requireNetworkProfile(input.network, `${at}.network`);\n const mode = resolveDeploymentMode(profile, input.facilitator.mode);\n\n // Local mode keeps a gas-paying key in the gateway process. A compromise\n // could expose that key, so mainnet requires a remote facilitator.\n if (profile.kind === 'mainnet' && input.facilitator.mode === 'local') {\n throw invalid(\n `${at}: network \"${profile.id}\" (${profile.displayName}) is a mainnet and cannot be served by facilitator.mode \"local\". A mainnet deployment must settle through a remote facilitator.`,\n `${at}.facilitator.mode`,\n );\n }\n\n if (mode === 'mainnet' && input.allowMainnet !== true) {\n throw invalid(\n `${at}: network \"${profile.id}\" (${profile.displayName}) settles real funds. Set ${at}.allowMainnet: true to acknowledge this explicitly - it is never the default.`,\n `${at}.allowMainnet`,\n );\n }\n\n if (input.facilitator.mode === 'remote') {\n assertFacilitatorUrlIsSafe(input.facilitator.url, mode, at);\n // The authorization fixes recipient, amount and chain, so a facilitator\n // cannot redirect funds. A credential adds an account: rate limits, terms\n // and support. On mainnet, going without one is an explicit choice.\n if (\n mode === 'mainnet' &&\n input.facilitator.auth.type === 'none' &&\n input.allowUnauthenticatedFacilitator !== true\n ) {\n throw invalid(\n `${at}: no credential is configured for facilitator ${describeOrigin(input.facilitator.url)} on mainnet. Set ${at}.allowUnauthenticatedFacilitator: true to accept anonymous access and the facilitator's limits, or configure facilitator.auth.`,\n `${at}.allowUnauthenticatedFacilitator`,\n );\n }\n // A blank credential reaches the facilitator as \"unauthenticated\" and fails\n // every payment after the buyer signed. `${VAR:- }` resolving to whitespace\n // is the usual cause.\n for (const [field, value] of credentialFields(input.facilitator.auth)) {\n if (value.trim() === '') {\n throw invalid(\n `${at}: facilitator.auth.type is \"${input.facilitator.auth.type}\" but ${field} is empty. An empty credential is refused rather than sent.`,\n `${at}.facilitator.auth.${field}`,\n );\n }\n }\n }\n\n // The config loader's address check refuses this too; repeated here for a\n // library consumer who calls `createX402PaymentProvider` without it\n if (/^0x0{40}$/i.test(input.payTo)) {\n throw invalid(\n `${at}: \"${payTo}\" is the zero address. Every payment settled there is destroyed.`,\n `${at}.${payTo}`,\n );\n }\n\n // Anyone can spend from a well-known Anvil address. `dev-key-guard` refuses\n // one behind a public RPC; this refuses one on any non-local deployment,\n // whose RPC host says nothing about where a remote facilitator settles.\n if (mode !== 'local' && isWellKnownDevAddress(input.payTo)) {\n throw invalid(\n `${at}: \"${payTo}\" (${input.payTo}) is a well-known Anvil development address and this is a ${mode} deployment. Anyone can spend what settles there. Set ${payTo} to your own merchant wallet.`,\n `${at}.${payTo}`,\n );\n }\n\n // Mainnet only: a testnet is where pointing at a mock token is normal\n const canonical = profile.canonicalAsset;\n if (mode === 'mainnet' && canonical) {\n if (!sameAddress(input.asset, canonical.address)) {\n throw invalid(\n `${at}: asset ${input.asset} is not ${canonical.symbol} on ${profile.displayName} (expected ${canonical.address}). Settling a mainnet payment in an unintended token is refused.`,\n `${at}.asset`,\n );\n }\n // The buyer signs the EIP-712 domain and the scheme checks it. A wrong one\n // refuses every payment with `invalid_exact_evm_token_name_mismatch` after\n // the buyer signed, so it is caught here, before the gateway starts.\n if (input.assetName !== undefined && input.assetName !== canonical.name) {\n throw invalid(\n `${at}: assetName \"${input.assetName}\" is not the EIP-712 domain name ${canonical.symbol} reports on ${profile.displayName} (expected \"${canonical.name}\"). Every payment would be refused after the buyer signed.`,\n `${at}.assetName`,\n );\n }\n if (input.assetVersion !== undefined && input.assetVersion !== canonical.version) {\n throw invalid(\n `${at}: assetVersion \"${input.assetVersion}\" is not the EIP-712 domain version ${canonical.symbol} reports on ${profile.displayName} (expected \"${canonical.version}\").`,\n `${at}.assetVersion`,\n );\n }\n }\n\n return { profile, mode };\n}\n\n/**\n * A facilitator sees every payment authorization this gateway handles. Plain\n * HTTP puts those on the wire in the clear and lets anyone in the path rewrite\n * a settlement result, so it is allowed only to a local or private host, and\n * never on a mainnet.\n */\nfunction assertFacilitatorUrlIsSafe(url: string, mode: DeploymentMode, at: string): void {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch (cause) {\n throw new CommerceError('CONFIG_INVALID', `${at}: facilitator.url is not a valid URL`, {\n cause,\n details: { path: `${at}.facilitator.url` },\n });\n }\n\n if (parsed.protocol === 'https:') return;\n if (parsed.protocol !== 'http:') {\n throw invalid(\n `${at}: facilitator ${describeOrigin(url)} must be reached over https (or http on a local/private host); got \"${parsed.protocol}//\"`,\n `${at}.facilitator.url`,\n );\n }\n if (mode !== 'mainnet' && isLikelyLocalOrPrivateHost(parsed.hostname)) return;\n\n // The origin, never the whole URL: the path can carry a tenant or an API\n // key, and this message reaches `validate`, `doctor`, startup output and CI logs\n throw invalid(\n `${at}: facilitator ${describeOrigin(url)} is reached over plain HTTP. Payment authorizations and settlement results would travel unencrypted. Use https, or point at a local/private host on a non-mainnet deployment.`,\n `${at}.facilitator.url`,\n );\n}\n\n// Origin only: a facilitator URL can carry a tenant path or an API key\nfunction describeOrigin(url: string): string {\n try {\n return new URL(url).origin;\n } catch {\n return '[unparseable facilitator.url]';\n }\n}\n\n// The secret-bearing fields of an auth block, for emptiness checks only. Never logged\nfunction credentialFields(auth: FacilitatorAuth): readonly (readonly [string, string])[] {\n switch (auth.type) {\n case 'bearer':\n return [['token', auth.token]];\n case 'cdp':\n return [\n ['apiKeyId', auth.apiKeyId],\n ['apiKeySecret', auth.apiKeySecret],\n ];\n default:\n return [];\n }\n}\n\nfunction sameAddress(a: string, b: string): boolean {\n return a.toLowerCase() === b.toLowerCase();\n}\n"]}
@@ -1,9 +1,10 @@
1
- import { assertPayToIsNotDevAddress, resolveX402Deployment, assertDevKeyIsLocalOnly, describeRpc, describeDeploymentMode } from './chunk-PBYN7EK2.js';
2
- import { CommerceError, systemClock, NOOP_LOGGER, PACKAGE_VERSION } from './chunk-5GEWKNIH.js';
3
- import { encodeAbiParameters, keccak256, isAddress, getAddress, createWalletClient, http, publicActions, createPublicClient, HttpRequestError, TimeoutError, WaitForTransactionReceiptTimeoutError, ContractFunctionRevertedError, ContractFunctionExecutionError } from 'viem';
1
+ import { assertPayToIsNotDevAddress, resolveX402Deployment, assertDevKeyIsLocalOnly, describeRpc, LOCAL_CHAIN_ID, describeDeploymentMode } from './chunk-CBJIT7QP.js';
2
+ import { CommerceError, systemClock, NOOP_LOGGER, PACKAGE_VERSION, redactedErrorText } from './chunk-N5KRK7YA.js';
3
+ import { encodeAbiParameters, keccak256, isAddress, getAddress, formatUnits, createWalletClient, http, publicActions, createPublicClient, HttpRequestError, TimeoutError, WaitForTransactionReceiptTimeoutError, BaseError, ContractFunctionRevertedError } from 'viem';
4
4
  import { privateKeyToAccount } from 'viem/accounts';
5
5
  import { x402Facilitator } from '@x402/core/facilitator';
6
6
  import { HTTPFacilitatorClient } from '@x402/core/http';
7
+ import { VerifyError } from '@x402/core/types';
7
8
  import { isEIP3009Payload, toFacilitatorEvmSigner } from '@x402/evm';
8
9
  import { registerExactEvmScheme } from '@x402/evm/exact/facilitator';
9
10
  import { PaymentPayloadV2Schema } from '@x402/core/schemas';
@@ -35,19 +36,6 @@ function parseCanonicalAmount(amount, decimals) {
35
36
  const combined = `${integerPart}${paddedFraction}`;
36
37
  return BigInt(combined);
37
38
  }
38
- function formatCanonicalAmount(baseUnits, decimals) {
39
- if (!Number.isInteger(decimals) || decimals < 0) {
40
- throw new CommerceError("INTERNAL_ERROR", `Invalid asset decimals: ${decimals}`);
41
- }
42
- const negative = baseUnits < 0n;
43
- const abs = negative ? -baseUnits : baseUnits;
44
- const digits = abs.toString().padStart(decimals + 1, "0");
45
- const integerPart = digits.slice(0, digits.length - decimals) || "0";
46
- const fractionPart = digits.slice(digits.length - decimals).replace(/0+$/, "");
47
- const sign = negative ? "-" : "";
48
- return fractionPart.length > 0 ? `${sign}${integerPart}.${fractionPart}` : `${sign}${integerPart}`;
49
- }
50
- var LOCAL_CHAIN_ID = 84532;
51
39
  function chainIdFromCaip2(network) {
52
40
  const match = /^eip155:(\d+)$/.exec(network);
53
41
  if (!match?.[1]) return void 0;
@@ -114,9 +102,6 @@ function createLocalFacilitatorBinding(client, network, isTransportError) {
114
102
  settle: (payload, requirements) => facilitator.settle(payload, requirements),
115
103
  transportFailed: failed
116
104
  };
117
- },
118
- async supported() {
119
- return build().facilitator.getSupported().kinds;
120
105
  }
121
106
  };
122
107
  }
@@ -144,6 +129,16 @@ function cdpAuthHeaders(apiKeyId, apiKeySecret) {
144
129
  return await create();
145
130
  };
146
131
  }
132
+ function verdictFromVerifyError(err) {
133
+ if (err instanceof VerifyError && err.statusCode === 400 && typeof err.invalidReason === "string") {
134
+ return {
135
+ isValid: false,
136
+ invalidReason: err.invalidReason,
137
+ ...err.payer !== void 0 ? { payer: err.payer } : {}
138
+ };
139
+ }
140
+ throw err;
141
+ }
147
142
  function createRemoteFacilitatorBinding(options) {
148
143
  const auth = options.auth;
149
144
  let createAuthHeaders;
@@ -157,7 +152,7 @@ function createRemoteFacilitatorBinding(options) {
157
152
  }
158
153
  const client = new HTTPFacilitatorClient({
159
154
  url: options.url,
160
- timeoutMs: options.timeoutMs ?? SETTLEMENT_CONFIRMATION_TIMEOUT_MS,
155
+ timeoutMs: SETTLEMENT_CONFIRMATION_TIMEOUT_MS,
161
156
  ...createAuthHeaders ? { createAuthHeaders } : {}
162
157
  });
163
158
  return {
@@ -174,7 +169,7 @@ function createRemoteFacilitatorBinding(options) {
174
169
  }
175
170
  };
176
171
  return {
177
- verify: (payload, requirements) => watch(() => client.verify(payload, requirements)),
172
+ verify: (payload, requirements) => watch(() => client.verify(payload, requirements).catch(verdictFromVerifyError)),
178
173
  settle: (payload, requirements) => watch(() => client.settle(payload, requirements)),
179
174
  transportFailed: () => failed
180
175
  };
@@ -217,7 +212,7 @@ var SETTLEMENT_PENDING_REASON = "settlement_pending";
217
212
  var TRANSACTION_FAILED_REASON = "invalid_exact_evm_transaction_failed";
218
213
  var MAX_REASON_LENGTH = 64;
219
214
  var REASON_SHAPE = /^[a-z0-9_.-]+$/i;
220
- function sanitiseReason(reason, fallback) {
215
+ function sanitizeReason(reason, fallback) {
221
216
  if (reason === void 0) return fallback;
222
217
  const trimmed = reason.trim();
223
218
  if (trimmed.length === 0 || trimmed.length > MAX_REASON_LENGTH) return fallback;
@@ -269,7 +264,7 @@ function createX402PaymentProvider(options) {
269
264
  } catch (cause) {
270
265
  throw new CommerceError(
271
266
  "CONFIG_INVALID",
272
- "x402 provider: could not construct a local facilitator signer from facilitator.signerPrivateKey \u2014 it must be a valid 32-byte hex private key",
267
+ "x402 provider: could not construct a local facilitator signer from facilitator.signerPrivateKey. It must be a valid 32-byte hex private key.",
273
268
  { cause }
274
269
  );
275
270
  }
@@ -303,7 +298,7 @@ function createX402PaymentProvider(options) {
303
298
  `mode=${mode}`
304
299
  ],
305
300
  status: "stable",
306
- unsupported: ["svm", "permit2", "upto scheme"]
301
+ unsupported: ["svm", "permit2", "upto scheme", "deferred scheme"]
307
302
  };
308
303
  async function createRequirement(context) {
309
304
  const amount = parseCanonicalAmount(context.amount, options.assetDecimals).toString();
@@ -314,15 +309,10 @@ function createX402PaymentProvider(options) {
314
309
  amount,
315
310
  payTo: options.payTo,
316
311
  maxTimeoutSeconds,
317
- // `name`/`version` are what let a buyer and the facilitator build the
318
- // same EIP-712 domain without an on-chain `version()` call, so
319
- // verification stays deterministic against a token that has none.
320
- //
321
- // `assetTransferMethod` is stated rather than left to default: x402 v2's
322
- // `exact`/EVM scheme also has a Permit2 path, and a client that picked it
323
- // would produce a payload this provider cannot settle. Declaring the one
324
- // supported method turns that into a client-side non-choice instead of a
325
- // server-side rejection.
312
+ // `name`/`version` let the buyer and the facilitator build the same
313
+ // EIP-712 domain without calling `version()` on the token.
314
+ // `assetTransferMethod` names the one method this provider settles, so a
315
+ // conforming client never picks the `exact` scheme's Permit2 path.
326
316
  extra: {
327
317
  name: options.assetName,
328
318
  version: options.assetVersion,
@@ -418,17 +408,14 @@ function createX402PaymentProvider(options) {
418
408
  try {
419
409
  sdkResult = await scope.verify(payload, requirements);
420
410
  } catch (err) {
421
- if (isProviderUnavailableError(err) || scope.transportFailed()) {
422
- throw new CommerceError(
423
- "PAYMENT_PROVIDER_UNAVAILABLE",
424
- `x402 provider: ${binding.kind} facilitator unreachable during verify()`,
425
- {
426
- cause: err
427
- }
428
- );
411
+ if (!isProviderUnavailableError(err) && !scope.transportFailed()) {
412
+ logger.warn({ err: redactedErrorText(err) }, "x402 verify(): unexpected SDK error");
429
413
  }
430
- logger.warn({ err: describeError(err) }, "x402 verify(): unexpected SDK error");
431
- return rejected("unexpected_verify_error");
414
+ throw new CommerceError(
415
+ "PAYMENT_PROVIDER_UNAVAILABLE",
416
+ `x402 provider: ${binding.kind} facilitator returned no verdict during verify()`,
417
+ { cause: err }
418
+ );
432
419
  }
433
420
  if (!sdkResult.isValid) {
434
421
  if (scope.transportFailed()) {
@@ -449,14 +436,10 @@ function createX402PaymentProvider(options) {
449
436
  "x402 verify(): facilitator rejection reason"
450
437
  );
451
438
  }
452
- return rejected(sanitiseReason(sdkResult.invalidReason, "invalid_payment"));
453
- }
454
- const payloadChainId = chainIdFromCaip2(payload.accepted.network);
455
- if (payloadChainId === void 0) {
456
- return rejected("wrong_network");
439
+ return rejected(sanitizeReason(sdkResult.invalidReason, "invalid_payment"));
457
440
  }
458
441
  const replayKey = computeReplayKey({
459
- chainId: payloadChainId,
442
+ chainId: profile.chainId,
460
443
  asset: getAddress(requirements.asset),
461
444
  from: getAddress(authorization.from),
462
445
  nonce: authorization.nonce
@@ -466,7 +449,7 @@ function createX402PaymentProvider(options) {
466
449
  provider: "x402",
467
450
  payer: getAddress(authorization.from),
468
451
  payee: getAddress(authorization.to),
469
- amount: formatCanonicalAmount(authorizedValue, options.assetDecimals),
452
+ amount: formatUnits(authorizedValue, options.assetDecimals),
470
453
  currency: requirement.currency,
471
454
  network: payload.accepted.network,
472
455
  asset: getAddress(requirements.asset),
@@ -519,7 +502,7 @@ function createX402PaymentProvider(options) {
519
502
  }
520
503
  if (!isOnChainRevertError(err)) {
521
504
  logger.warn(
522
- { err: describeError(err) },
505
+ { err: redactedErrorText(err) },
523
506
  "x402 settle(): settlement failed with an unclassified error; outcome unknown"
524
507
  );
525
508
  throw new CommerceError(
@@ -529,7 +512,7 @@ function createX402PaymentProvider(options) {
529
512
  );
530
513
  }
531
514
  logger.warn(
532
- { err: describeError(err), rejectionReason: "transaction_reverted" },
515
+ { err: redactedErrorText(err), rejectionReason: "transaction_reverted" },
533
516
  "x402 settle(): settlement transaction reverted on chain"
534
517
  );
535
518
  return rejectedSettlement("transaction_reverted");
@@ -561,7 +544,7 @@ function createX402PaymentProvider(options) {
561
544
  );
562
545
  }
563
546
  return {
564
- ...rejectedSettlement(sanitiseReason(sdkResult.errorReason, "settlement_failed")),
547
+ ...rejectedSettlement(sanitizeReason(sdkResult.errorReason, "settlement_failed")),
565
548
  network: sdkResult.network,
566
549
  ...sdkResult.payer !== void 0 ? { payer: sdkResult.payer } : {}
567
550
  };
@@ -617,7 +600,7 @@ function createX402PaymentProvider(options) {
617
600
  }
618
601
  return {
619
602
  status: "pass",
620
- detail: `${describeDeploymentMode(mode)} \u2014 RPC ${rpcOrigin} reachable, chain id ${profile.chainId} (${profile.displayName}), asset ${options.asset} has code, facilitator ${binding.describe} supports exact/${options.network}`,
603
+ detail: `${describeDeploymentMode(mode)}: RPC ${rpcOrigin} reachable, chain id ${profile.chainId} (${profile.displayName}), asset ${options.asset} has code, facilitator ${binding.describe} supports exact/${options.network}`,
621
604
  checkedAt,
622
605
  durationMs: clock.monotonicMs() - startedAt
623
606
  };
@@ -626,21 +609,21 @@ function createX402PaymentProvider(options) {
626
609
  if (!isAnvil) {
627
610
  return {
628
611
  status: "fail",
629
- detail: `RPC at ${rpcOrigin} reports chain id ${profile.chainId} but does not answer "anvil_nodeInfo" \u2014 it does not look like a local Anvil dev node. Refusing to treat it as safe for a local-facilitator dev key.`,
612
+ detail: `RPC at ${rpcOrigin} reports chain id ${profile.chainId} but does not answer "anvil_nodeInfo", so it does not look like a local Anvil dev node. Refusing to treat it as safe for a local-facilitator dev key.`,
630
613
  checkedAt,
631
614
  durationMs: clock.monotonicMs() - startedAt
632
615
  };
633
616
  }
634
617
  return {
635
618
  status: "pass",
636
- detail: `${describeDeploymentMode(mode)} \u2014 RPC ${rpcOrigin} reachable, chain id ${profile.chainId}, asset ${options.asset} has code, confirmed Anvil dev node`,
619
+ detail: `${describeDeploymentMode(mode)}: RPC ${rpcOrigin} reachable, chain id ${profile.chainId}, asset ${options.asset} has code, confirmed Anvil dev node`,
637
620
  checkedAt,
638
621
  durationMs: clock.monotonicMs() - startedAt
639
622
  };
640
623
  } catch (err) {
641
624
  return {
642
625
  status: "fail",
643
- detail: `x402 health check failed: ${describeError(err)}`,
626
+ detail: `x402 health check failed: ${redactedErrorText(err)}`,
644
627
  checkedAt,
645
628
  durationMs: clock.monotonicMs() - startedAt
646
629
  };
@@ -673,19 +656,15 @@ function createX402PaymentProvider(options) {
673
656
  };
674
657
  }
675
658
  function isOnChainRevertError(err) {
676
- return err instanceof ContractFunctionRevertedError || err instanceof ContractFunctionExecutionError;
659
+ return err instanceof BaseError && err.walk((e) => e instanceof ContractFunctionRevertedError) !== null;
677
660
  }
678
661
  function isProviderUnavailableError(err) {
679
662
  if (err instanceof HttpRequestError || err instanceof TimeoutError || err instanceof WaitForTransactionReceiptTimeoutError) {
680
663
  return true;
681
664
  }
682
- const message = describeError(err).toLowerCase();
665
+ const message = redactedErrorText(err).toLowerCase();
683
666
  return message.includes("econnrefused") || message.includes("fetch failed") || message.includes("enotfound") || message.includes("etimedout") || message.includes("timed out") || message.includes("network error");
684
667
  }
685
- function describeError(err) {
686
- const text = err instanceof Error ? `${err.name}: ${err.message}` : String(err);
687
- return text.replace(/\bhttps?:\/\/[^\s"'<>]+/gi, (url) => describeRpc(url));
688
- }
689
668
  async function probeIsAnvilNode(client) {
690
669
  const request = client.request;
691
670
  try {
@@ -696,6 +675,6 @@ async function probeIsAnvilNode(client) {
696
675
  }
697
676
  }
698
677
 
699
- export { chainIdFromCaip2, computeReplayKey, createX402PaymentProvider, parseCanonicalAmount };
700
- //# sourceMappingURL=chunk-NKNXVDHN.js.map
701
- //# sourceMappingURL=chunk-NKNXVDHN.js.map
678
+ export { DEFAULT_IDS, chainIdFromCaip2, computeReplayKey, createX402PaymentProvider, parseCanonicalAmount };
679
+ //# sourceMappingURL=chunk-JKEKKXRJ.js.map
680
+ //# sourceMappingURL=chunk-JKEKKXRJ.js.map