@devlab.group/agent-commerce 0.2.0-beta.0 → 1.0.0

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.
package/dist/mcp.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { H as HttpProtocolAdapter } from './protocol-adapter-CtB0sOnV.js';
1
+ import { H as HttpProtocolAdapter } from './protocol-adapter-CZPOb9uG.js';
2
2
  import 'node:http';
3
- import './runtime-Bie-9FAM.js';
3
+ import './runtime-B-9IjMbO.js';
4
4
 
5
5
  /**
6
6
  * MCP protocol adapter.
package/dist/mcp.js CHANGED
@@ -1,4 +1,4 @@
1
- import { PACKAGE_VERSION, toCommerceError, CommerceError, PAYMENT_INPUT_FIELD, toErrorEnvelope, DELIVERY_SUMMARY_META_KEY, toDeliverySummary, toPaymentRequiredEnvelope } from './chunk-ASK67X56.js';
1
+ import { PACKAGE_VERSION, toCommerceError, CommerceError, PAYMENT_INPUT_FIELD, toErrorEnvelope, DELIVERY_SUMMARY_META_KEY, toDeliverySummary, toPaymentRequiredEnvelope } from './chunk-BQNE3A5H.js';
2
2
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
4
4
  import { ListToolsRequestSchema, CallToolRequestSchema, LATEST_PROTOCOL_VERSION } from '@modelcontextprotocol/sdk/types.js';
@@ -1,5 +1,5 @@
1
1
  import { IncomingMessage, ServerResponse } from 'node:http';
2
- import { I as IsoTimestamp, j as PaymentResult, o as ProtocolName, l as PaymentSubmission, i as PaymentRequirement, A as AdapterDescriptor, R as ResourceRegistry, L as Logger, c as Clock, d as IdGenerator, a as AdapterHealth } from './runtime-Bie-9FAM.js';
2
+ import { I as IsoTimestamp, j as PaymentResult, o as ProtocolName, l as PaymentSubmission, i as PaymentRequirement, A as AdapterDescriptor, R as ResourceRegistry, L as Logger, c as Clock, d as IdGenerator, a as AdapterHealth } from './runtime-B-9IjMbO.js';
3
3
 
4
4
  /**
5
5
  * Canonical commerce events.
@@ -12,9 +12,9 @@
12
12
  * boundaries. Never treat this as trusted input without validation.
13
13
  */
14
14
  type JsonSchema = Record<string, unknown>;
15
- /** Protocol surfaces a resource can be exposed through in v0.1. */
15
+ /** Protocol surfaces a resource can be exposed through in this release. */
16
16
  type ProtocolName = 'http' | 'mcp';
17
- /** Payment methods a resource can accept in v0.1. */
17
+ /** Payment methods a resource can accept in this release. */
18
18
  type PaymentMethodName = 'x402';
19
19
  /** ISO-8601 timestamp string, always UTC with millisecond precision. */
20
20
  type IsoTimestamp = string;
package/dist/x402.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { X as X402FacilitatorConfig } from './guardrails-Di_yI_DW.js';
2
- export { F as FacilitatorAuth } from './guardrails-Di_yI_DW.js';
3
- import { L as Logger, c as Clock, d as IdGenerator, b as PaymentProvider } from './runtime-Bie-9FAM.js';
1
+ import { X as X402FacilitatorConfig } from './guardrails-Dmwi63KB.js';
2
+ export { F as FacilitatorAuth } from './guardrails-Dmwi63KB.js';
3
+ import { L as Logger, c as Clock, d as IdGenerator, b as PaymentProvider } from './runtime-B-9IjMbO.js';
4
4
 
5
5
  interface NetworkProfile {
6
6
  /** CAIP-2 identifier, e.g. `eip155:84532`. */
@@ -10,13 +10,22 @@ interface NetworkProfile {
10
10
  readonly displayName: string;
11
11
  readonly kind: 'testnet' | 'mainnet';
12
12
  /**
13
- * The USDC deployment this network is expected to settle in. Enforced only
14
- * on mainnet (see `guardrails.ts`) — a testnet is where a mock token is a
15
- * legitimate thing to point at.
13
+ * The USDC deployment this network is expected to settle in, with the EIP-712
14
+ * domain the token actually reports. Enforced only on mainnet (see
15
+ * `guardrails.ts`) — a testnet is where a mock token is a legitimate thing to
16
+ * point at.
17
+ *
18
+ * `name` is not decorative and is not the symbol: it is signed into every
19
+ * buyer's EIP-712 domain, and the two USDC deployments disagree. Base Sepolia
20
+ * reports `"USDC"`; Base mainnet reports `"USD Coin"`. Configure the wrong
21
+ * one and every payment is refused `invalid_exact_evm_token_name_mismatch`
22
+ * after the buyer has signed. Read back from the contracts, not assumed.
16
23
  */
17
24
  readonly canonicalAsset?: {
18
25
  readonly symbol: string;
19
26
  readonly address: string;
27
+ readonly name: string;
28
+ readonly version: string;
20
29
  };
21
30
  }
22
31
  declare const SUPPORTED_NETWORK_IDS: readonly string[];
@@ -120,6 +129,11 @@ interface X402ProviderOptions {
120
129
  * default — see `guardrails.ts`.
121
130
  */
122
131
  readonly allowMainnet?: boolean;
132
+ /**
133
+ * Required to be `true` to settle on a mainnet through a facilitator that
134
+ * takes no credential. Never a default.
135
+ */
136
+ readonly allowUnauthenticatedFacilitator?: boolean;
123
137
  readonly logger?: Logger;
124
138
  readonly clock?: Clock;
125
139
  readonly ids?: IdGenerator;
package/dist/x402.js CHANGED
@@ -1,11 +1,11 @@
1
- import { assertPayToIsNotDevAddress, resolveX402Deployment, assertDevKeyIsLocalOnly, describeDeploymentMode } from './chunk-MQMKQGAB.js';
2
- export { SUPPORTED_NETWORK_IDS } from './chunk-MQMKQGAB.js';
3
- import { CommerceError, systemClock, NOOP_LOGGER, PACKAGE_VERSION } from './chunk-ASK67X56.js';
1
+ import { assertPayToIsNotDevAddress, resolveX402Deployment, assertDevKeyIsLocalOnly, describeDeploymentMode } from './chunk-MEPETSP6.js';
2
+ export { SUPPORTED_NETWORK_IDS } from './chunk-MEPETSP6.js';
3
+ import { CommerceError, systemClock, NOOP_LOGGER, PACKAGE_VERSION } from './chunk-BQNE3A5H.js';
4
4
  import { PaymentRequirementsV2Schema, PaymentPayloadV2Schema } from '@x402/core/schemas';
5
5
  import { getAddress, toHex, isAddress, createWalletClient, http, publicActions, createPublicClient, HttpRequestError, TimeoutError, WaitForTransactionReceiptTimeoutError, encodeAbiParameters, keccak256, ContractFunctionRevertedError, ContractFunctionExecutionError } from 'viem';
6
6
  import { privateKeyToAccount } from 'viem/accounts';
7
7
  import { x402Facilitator } from '@x402/core/facilitator';
8
- import { HTTPFacilitatorClient, FacilitatorResponseError } from '@x402/core/http';
8
+ import { HTTPFacilitatorClient } from '@x402/core/http';
9
9
  import { isEIP3009Payload, toFacilitatorEvmSigner } from '@x402/evm';
10
10
  import { registerExactEvmScheme } from '@x402/evm/exact/facilitator';
11
11
 
@@ -16,9 +16,9 @@ function chainIdFromCaip2(network) {
16
16
  const chainId = Number(match[1]);
17
17
  return Number.isSafeInteger(chainId) && chainId > 0 ? chainId : void 0;
18
18
  }
19
- function buildLocalChain(rpcUrl) {
19
+ function buildLocalChain(rpcUrl, chainId = LOCAL_CHAIN_ID) {
20
20
  return {
21
- id: LOCAL_CHAIN_ID,
21
+ id: chainId,
22
22
  name: "agent-commerce-local",
23
23
  nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
24
24
  rpcUrls: {
@@ -26,9 +26,9 @@ function buildLocalChain(rpcUrl) {
26
26
  }
27
27
  };
28
28
  }
29
- function createLocalPublicClient(rpcUrl, timeoutMs) {
29
+ function createLocalPublicClient(rpcUrl, timeoutMs, chainId) {
30
30
  return createPublicClient({
31
- chain: buildLocalChain(rpcUrl),
31
+ chain: buildLocalChain(rpcUrl, chainId),
32
32
  transport: http(rpcUrl, { timeout: timeoutMs } )
33
33
  });
34
34
  }
@@ -196,12 +196,41 @@ function createLocalFacilitatorBinding(client, network, isTransportError) {
196
196
  }
197
197
  };
198
198
  }
199
- function createRemoteFacilitatorBinding(options, isTransportError) {
199
+ function cdpAuthHeaders(apiKeyId, apiKeySecret) {
200
+ const loading = import('@coinbase/x402').then(
201
+ (mod) => mod.createCdpAuthHeaders(apiKeyId, apiKeySecret),
202
+ (cause) => {
203
+ throw new CommerceError(
204
+ "CONFIG_INVALID",
205
+ 'x402 provider: facilitator.auth.type is "cdp", which needs the optional peer "@coinbase/x402". Install it (npm install @coinbase/x402), or use a facilitator that accepts a static token with auth.type "bearer".',
206
+ { cause }
207
+ );
208
+ }
209
+ );
210
+ loading.catch(() => {
211
+ });
212
+ return async () => {
213
+ const create = await loading;
214
+ if (!create) {
215
+ throw new CommerceError(
216
+ "PAYMENT_PROVIDER_UNAVAILABLE",
217
+ "x402 provider: @coinbase/x402 returned no auth-header factory"
218
+ );
219
+ }
220
+ return await create();
221
+ };
222
+ }
223
+ function createRemoteFacilitatorBinding(options) {
200
224
  const auth = options.auth;
201
- const createAuthHeaders = auth.type === "bearer" ? async () => {
202
- const headers = { Authorization: `Bearer ${auth.token}` };
203
- return { verify: headers, settle: headers, supported: headers };
204
- } : void 0;
225
+ let createAuthHeaders;
226
+ if (auth.type === "bearer") {
227
+ createAuthHeaders = async () => {
228
+ const headers = { Authorization: `Bearer ${auth.token}` };
229
+ return { verify: headers, settle: headers, supported: headers };
230
+ };
231
+ } else if (auth.type === "cdp") {
232
+ createAuthHeaders = cdpAuthHeaders(auth.apiKeyId, auth.apiKeySecret);
233
+ }
205
234
  const client = new HTTPFacilitatorClient({
206
235
  url: options.url,
207
236
  timeoutMs: options.timeoutMs ?? SETTLEMENT_CONFIRMATION_TIMEOUT_MS,
@@ -216,7 +245,7 @@ function createRemoteFacilitatorBinding(options, isTransportError) {
216
245
  try {
217
246
  return await call();
218
247
  } catch (err) {
219
- if (err instanceof FacilitatorResponseError || isTransportError(err)) failed = true;
248
+ failed = true;
220
249
  throw err;
221
250
  }
222
251
  };
@@ -261,6 +290,14 @@ var DEFAULT_MAX_TIMEOUT_SECONDS = 60;
261
290
  var DEFAULT_MIME_TYPE = "application/json";
262
291
  var HEALTH_TIMEOUT_MS = 4e3;
263
292
  var SETTLEMENT_PENDING_REASON = "settlement_pending";
293
+ var MAX_REASON_LENGTH = 64;
294
+ var REASON_SHAPE = /^[a-z0-9_.-]+$/i;
295
+ function sanitiseReason(reason, fallback) {
296
+ if (reason === void 0) return fallback;
297
+ const trimmed = reason.trim();
298
+ if (trimmed.length === 0 || trimmed.length > MAX_REASON_LENGTH) return fallback;
299
+ return REASON_SHAPE.test(trimmed) ? trimmed : fallback;
300
+ }
264
301
  var DEFAULT_IDS = {
265
302
  next: (prefix) => `${prefix ? `${prefix}_` : ""}${crypto.randomUUID()}`
266
303
  };
@@ -288,8 +325,11 @@ function createX402PaymentProvider(options) {
288
325
  network: options.network,
289
326
  payTo: options.payTo,
290
327
  asset: options.asset,
328
+ assetName: options.assetName,
329
+ assetVersion: options.assetVersion,
291
330
  facilitator: options.facilitator,
292
- ...options.allowMainnet !== void 0 ? { allowMainnet: options.allowMainnet } : {}
331
+ ...options.allowMainnet !== void 0 ? { allowMainnet: options.allowMainnet } : {},
332
+ ...options.allowUnauthenticatedFacilitator !== void 0 ? { allowUnauthenticatedFacilitator: options.allowUnauthenticatedFacilitator } : {}
293
333
  });
294
334
  const network = options.network;
295
335
  let binding;
@@ -310,12 +350,16 @@ function createX402PaymentProvider(options) {
310
350
  }
311
351
  binding = createLocalFacilitatorBinding(client, network, isProviderUnavailableError);
312
352
  } else {
313
- binding = createRemoteFacilitatorBinding(
314
- { url: options.facilitator.url, auth: options.facilitator.auth },
315
- isProviderUnavailableError
316
- );
353
+ binding = createRemoteFacilitatorBinding({
354
+ url: options.facilitator.url,
355
+ auth: options.facilitator.auth
356
+ });
317
357
  }
318
- const healthPublicClient = createLocalPublicClient(options.rpcUrl, HEALTH_TIMEOUT_MS);
358
+ const healthPublicClient = createLocalPublicClient(
359
+ options.rpcUrl,
360
+ HEALTH_TIMEOUT_MS,
361
+ profile.chainId
362
+ );
319
363
  const clock = options.clock ?? systemClock;
320
364
  const ids = options.ids ?? DEFAULT_IDS;
321
365
  const logger = options.logger ?? NOOP_LOGGER;
@@ -445,7 +489,7 @@ function createX402PaymentProvider(options) {
445
489
  } catch {
446
490
  return rejected("malformed_payment_payload");
447
491
  }
448
- if (authorizedValue < required) {
492
+ if (authorizedValue !== required) {
449
493
  return rejected("wrong_amount");
450
494
  }
451
495
  const scope = binding.open();
@@ -473,7 +517,13 @@ function createX402PaymentProvider(options) {
473
517
  { details: { reportedReason: sdkResult.invalidReason ?? "invalid_payment" } }
474
518
  );
475
519
  }
476
- return rejected(sdkResult.invalidReason ?? "invalid_payment");
520
+ if (sdkResult.invalidReason !== void 0) {
521
+ logger.debug(
522
+ { reportedReason: sdkResult.invalidReason },
523
+ "x402 verify(): facilitator rejection reason"
524
+ );
525
+ }
526
+ return rejected(sanitiseReason(sdkResult.invalidReason, "invalid_payment"));
477
527
  }
478
528
  const payloadChainId = chainIdFromCaip2(payload.accepted.network);
479
529
  if (payloadChainId === void 0) {
@@ -558,8 +608,14 @@ function createX402PaymentProvider(options) {
558
608
  }
559
609
  );
560
610
  }
611
+ if (sdkResult.errorReason !== void 0) {
612
+ logger.debug(
613
+ { reportedReason: sdkResult.errorReason },
614
+ "x402 settle(): facilitator failure reason"
615
+ );
616
+ }
561
617
  return {
562
- ...rejectedSettlement(sdkResult.errorReason ?? "settlement_failed"),
618
+ ...rejectedSettlement(sanitiseReason(sdkResult.errorReason, "settlement_failed")),
563
619
  network: sdkResult.network,
564
620
  ...sdkResult.payer !== void 0 ? { payer: sdkResult.payer } : {}
565
621
  };