@agent-score/commerce 1.6.0 → 1.8.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.
Files changed (58) hide show
  1. package/README.md +8 -10
  2. package/dist/{_response-DpB-cm2c.d.mts → _response-BMt2y4Or.d.mts} +11 -8
  3. package/dist/{_response-C2yFQoIA.d.ts → _response-DyJ3mWI3.d.ts} +11 -8
  4. package/dist/challenge/index.d.mts +2 -1
  5. package/dist/challenge/index.d.ts +2 -1
  6. package/dist/challenge/index.js.map +1 -1
  7. package/dist/challenge/index.mjs.map +1 -1
  8. package/dist/core.d.mts +36 -27
  9. package/dist/core.d.ts +36 -27
  10. package/dist/core.js +21 -101
  11. package/dist/core.js.map +1 -1
  12. package/dist/core.mjs +21 -101
  13. package/dist/core.mjs.map +1 -1
  14. package/dist/identity/express.d.mts +12 -13
  15. package/dist/identity/express.d.ts +12 -13
  16. package/dist/identity/express.js +38 -121
  17. package/dist/identity/express.js.map +1 -1
  18. package/dist/identity/express.mjs +36 -118
  19. package/dist/identity/express.mjs.map +1 -1
  20. package/dist/identity/fastify.d.mts +12 -11
  21. package/dist/identity/fastify.d.ts +12 -11
  22. package/dist/identity/fastify.js +38 -121
  23. package/dist/identity/fastify.js.map +1 -1
  24. package/dist/identity/fastify.mjs +36 -118
  25. package/dist/identity/fastify.mjs.map +1 -1
  26. package/dist/identity/hono.d.mts +13 -28
  27. package/dist/identity/hono.d.ts +13 -28
  28. package/dist/identity/hono.js +31 -123
  29. package/dist/identity/hono.js.map +1 -1
  30. package/dist/identity/hono.mjs +29 -120
  31. package/dist/identity/hono.mjs.map +1 -1
  32. package/dist/identity/nextjs.d.mts +8 -7
  33. package/dist/identity/nextjs.d.ts +8 -7
  34. package/dist/identity/nextjs.js +27 -119
  35. package/dist/identity/nextjs.js.map +1 -1
  36. package/dist/identity/nextjs.mjs +27 -118
  37. package/dist/identity/nextjs.mjs.map +1 -1
  38. package/dist/identity/policy.d.mts +1 -0
  39. package/dist/identity/policy.d.ts +1 -0
  40. package/dist/identity/web.d.mts +12 -14
  41. package/dist/identity/web.d.ts +12 -14
  42. package/dist/identity/web.js +27 -119
  43. package/dist/identity/web.js.map +1 -1
  44. package/dist/identity/web.mjs +27 -118
  45. package/dist/identity/web.mjs.map +1 -1
  46. package/dist/index.d.mts +73 -11
  47. package/dist/index.d.ts +73 -11
  48. package/dist/index.js +45 -9
  49. package/dist/index.js.map +1 -1
  50. package/dist/index.mjs +41 -7
  51. package/dist/index.mjs.map +1 -1
  52. package/dist/payment/index.d.mts +1 -1
  53. package/dist/payment/index.d.ts +1 -1
  54. package/dist/payment/index.js.map +1 -1
  55. package/dist/payment/index.mjs.map +1 -1
  56. package/dist/{signer-kCAJUZwp.d.mts → signer-CFVQsWjL.d.mts} +1 -6
  57. package/dist/{signer-kCAJUZwp.d.ts → signer-CFVQsWjL.d.ts} +1 -6
  58. package/package.json +6 -6
package/dist/core.d.mts CHANGED
@@ -1,3 +1,5 @@
1
+ import { P as PaymentSigner } from './signer-CFVQsWjL.mjs';
2
+
1
3
  interface AgentIdentity {
2
4
  address?: string;
3
5
  operatorToken?: string;
@@ -225,14 +227,28 @@ interface CaptureWalletOptions {
225
227
  * prevents agent retries from inflating transaction_count. */
226
228
  idempotencyKey?: string;
227
229
  }
228
- interface VerifyWalletSignerMatchOptions {
229
- /** The wallet claimed via `X-Wallet-Address`. */
230
- claimedWallet: string;
231
- /** The signer wallet recovered from the payment credential. `null` means the rail carries
232
- * no wallet signer (SPT, card) — the helper returns `wallet_auth_requires_wallet_signing`. */
233
- signer: string | null;
234
- /** Network of the signer. EVM covers every EVM chain; `solana` lives in its own namespace. */
235
- network?: 'evm' | 'solana';
230
+ /** Combined wallet-signer verdict surfaced by `getSignerVerdict(c)` — both verdicts come
231
+ * through the gate's primary `/v1/assess` call (single round trip). `signer_match` describes
232
+ * the wallet-binding (claimed wallet's operator ≡ signer wallet's operator); `signer_sanctions`
233
+ * describes the OFAC SDN wallet-address check.
234
+ *
235
+ * `signer_match` is projected to the gate's camelCase `VerifyWalletSignerResult` shape so
236
+ * existing `buildSignerMismatchBody(...)` helpers consume it unchanged. `signer_sanctions`
237
+ * passes through in the API's wire shape (already short and stable). Returned `undefined`
238
+ * from `getSignerVerdict` when the gate didn't run with a signer (operator-token-only
239
+ * paths, discovery legs with no payment header). */
240
+ interface SignerVerdict {
241
+ signer_match: VerifyWalletSignerResult | null;
242
+ signer_sanctions: {
243
+ status: 'clear';
244
+ } | {
245
+ sanctioned: true;
246
+ ofac_label: string;
247
+ sdn_uid: string;
248
+ listed_at: string | null;
249
+ } | {
250
+ status: 'unavailable';
251
+ } | null;
236
252
  }
237
253
  type VerifyWalletSignerResult = {
238
254
  kind: 'pass';
@@ -252,9 +268,6 @@ type VerifyWalletSignerResult = {
252
268
  kind: 'wallet_auth_requires_wallet_signing';
253
269
  claimedWallet: string;
254
270
  agentInstructions: string;
255
- } | {
256
- kind: 'api_error';
257
- claimedWallet: string;
258
271
  };
259
272
  interface AgentScoreCore {
260
273
  /**
@@ -263,26 +276,22 @@ interface AgentScoreCore {
263
276
  * @param ctx - optional framework-specific context (Hono c, Express req, etc.) passed
264
277
  * through to `createSessionOnMissing` hooks. Opaque to core.
265
278
  */
266
- evaluate(identity: AgentIdentity | undefined, ctx?: unknown): Promise<EvaluateOutcome>;
279
+ evaluate(identity: AgentIdentity | undefined, ctx?: unknown,
280
+ /** Pre-extracted payment signer from the inbound request (the adapter middleware
281
+ * extracts it via `extractPaymentSigner`). When provided, the assess call carries
282
+ * it and the response includes `signer_match` + `signer_sanctions` verdicts in one
283
+ * round trip. */
284
+ signer?: PaymentSigner | null): Promise<EvaluateOutcome>;
285
+ /** Synchronous read of the cached signer verdicts (signer_match + signer_sanctions)
286
+ * populated when the gate's evaluate call was made with a pre-extracted signer. Returns
287
+ * `undefined` when the gate didn't run, the request was operator-token-authenticated,
288
+ * or no signer was extractable (discovery legs). */
289
+ getSignerVerdict(claimedAddress: string): SignerVerdict | undefined;
267
290
  /** Report a wallet seen paying under an operator credential. Fire-and-forget; silently
268
291
  * swallows non-fatal errors because capture is informational, not on the critical path. */
269
292
  captureWallet(options: CaptureWalletOptions): Promise<void>;
270
- /**
271
- * Verify the payment signer resolves to the same operator as the claimed `X-Wallet-Address`.
272
- *
273
- * Returns `pass` when the signer is linked to the same operator as the claimed wallet
274
- * (byte-equal wallets pass trivially; other wallets linked to the same operator also pass —
275
- * multi-wallet agents work without ergonomic pain). Returns `wallet_signer_mismatch` when
276
- * the signer resolves to a different (or no) operator. Returns `wallet_auth_requires_wallet_signing`
277
- * when the signer is `null` (SPT, card — rails that carry no wallet signature).
278
- *
279
- * Call this AFTER the gate evaluates (so the claimed wallet's operator is cached) and
280
- * AFTER the payment credential is parsed (so the signer is known). Merchants should call
281
- * it before settling payment.
282
- */
283
- verifyWalletSignerMatch(options: VerifyWalletSignerMatchOptions): Promise<VerifyWalletSignerResult>;
284
293
  }
285
294
  declare function buildAgentMemoryHint(): AgentMemoryHint;
286
295
  declare function createAgentScoreCore(options: AgentScoreCoreOptions): AgentScoreCore;
287
296
 
288
- export { type AccountVerification, type AgentIdentity, type AgentMemoryHint, type AgentScoreCore, type AgentScoreCoreOptions, type AssessResult, type CaptureWalletOptions, type CreateSessionOnMissing, type DenialCode, type DenialReason, type EvaluateOutcome, type FailOpenInfraReason, type GateQuotaInfo, type OperatorVerification, type PolicyCheck, type PolicyResult, type SessionMetadata, type VerifyWalletSignerMatchOptions, type VerifyWalletSignerResult, buildAgentMemoryHint, createAgentScoreCore };
297
+ export { type AccountVerification, type AgentIdentity, type AgentMemoryHint, type AgentScoreCore, type AgentScoreCoreOptions, type AssessResult, type CaptureWalletOptions, type CreateSessionOnMissing, type DenialCode, type DenialReason, type EvaluateOutcome, type FailOpenInfraReason, type GateQuotaInfo, type OperatorVerification, type PolicyCheck, type PolicyResult, type SessionMetadata, type SignerVerdict, type VerifyWalletSignerResult, buildAgentMemoryHint, createAgentScoreCore };
package/dist/core.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { P as PaymentSigner } from './signer-CFVQsWjL.js';
2
+
1
3
  interface AgentIdentity {
2
4
  address?: string;
3
5
  operatorToken?: string;
@@ -225,14 +227,28 @@ interface CaptureWalletOptions {
225
227
  * prevents agent retries from inflating transaction_count. */
226
228
  idempotencyKey?: string;
227
229
  }
228
- interface VerifyWalletSignerMatchOptions {
229
- /** The wallet claimed via `X-Wallet-Address`. */
230
- claimedWallet: string;
231
- /** The signer wallet recovered from the payment credential. `null` means the rail carries
232
- * no wallet signer (SPT, card) — the helper returns `wallet_auth_requires_wallet_signing`. */
233
- signer: string | null;
234
- /** Network of the signer. EVM covers every EVM chain; `solana` lives in its own namespace. */
235
- network?: 'evm' | 'solana';
230
+ /** Combined wallet-signer verdict surfaced by `getSignerVerdict(c)` — both verdicts come
231
+ * through the gate's primary `/v1/assess` call (single round trip). `signer_match` describes
232
+ * the wallet-binding (claimed wallet's operator ≡ signer wallet's operator); `signer_sanctions`
233
+ * describes the OFAC SDN wallet-address check.
234
+ *
235
+ * `signer_match` is projected to the gate's camelCase `VerifyWalletSignerResult` shape so
236
+ * existing `buildSignerMismatchBody(...)` helpers consume it unchanged. `signer_sanctions`
237
+ * passes through in the API's wire shape (already short and stable). Returned `undefined`
238
+ * from `getSignerVerdict` when the gate didn't run with a signer (operator-token-only
239
+ * paths, discovery legs with no payment header). */
240
+ interface SignerVerdict {
241
+ signer_match: VerifyWalletSignerResult | null;
242
+ signer_sanctions: {
243
+ status: 'clear';
244
+ } | {
245
+ sanctioned: true;
246
+ ofac_label: string;
247
+ sdn_uid: string;
248
+ listed_at: string | null;
249
+ } | {
250
+ status: 'unavailable';
251
+ } | null;
236
252
  }
237
253
  type VerifyWalletSignerResult = {
238
254
  kind: 'pass';
@@ -252,9 +268,6 @@ type VerifyWalletSignerResult = {
252
268
  kind: 'wallet_auth_requires_wallet_signing';
253
269
  claimedWallet: string;
254
270
  agentInstructions: string;
255
- } | {
256
- kind: 'api_error';
257
- claimedWallet: string;
258
271
  };
259
272
  interface AgentScoreCore {
260
273
  /**
@@ -263,26 +276,22 @@ interface AgentScoreCore {
263
276
  * @param ctx - optional framework-specific context (Hono c, Express req, etc.) passed
264
277
  * through to `createSessionOnMissing` hooks. Opaque to core.
265
278
  */
266
- evaluate(identity: AgentIdentity | undefined, ctx?: unknown): Promise<EvaluateOutcome>;
279
+ evaluate(identity: AgentIdentity | undefined, ctx?: unknown,
280
+ /** Pre-extracted payment signer from the inbound request (the adapter middleware
281
+ * extracts it via `extractPaymentSigner`). When provided, the assess call carries
282
+ * it and the response includes `signer_match` + `signer_sanctions` verdicts in one
283
+ * round trip. */
284
+ signer?: PaymentSigner | null): Promise<EvaluateOutcome>;
285
+ /** Synchronous read of the cached signer verdicts (signer_match + signer_sanctions)
286
+ * populated when the gate's evaluate call was made with a pre-extracted signer. Returns
287
+ * `undefined` when the gate didn't run, the request was operator-token-authenticated,
288
+ * or no signer was extractable (discovery legs). */
289
+ getSignerVerdict(claimedAddress: string): SignerVerdict | undefined;
267
290
  /** Report a wallet seen paying under an operator credential. Fire-and-forget; silently
268
291
  * swallows non-fatal errors because capture is informational, not on the critical path. */
269
292
  captureWallet(options: CaptureWalletOptions): Promise<void>;
270
- /**
271
- * Verify the payment signer resolves to the same operator as the claimed `X-Wallet-Address`.
272
- *
273
- * Returns `pass` when the signer is linked to the same operator as the claimed wallet
274
- * (byte-equal wallets pass trivially; other wallets linked to the same operator also pass —
275
- * multi-wallet agents work without ergonomic pain). Returns `wallet_signer_mismatch` when
276
- * the signer resolves to a different (or no) operator. Returns `wallet_auth_requires_wallet_signing`
277
- * when the signer is `null` (SPT, card — rails that carry no wallet signature).
278
- *
279
- * Call this AFTER the gate evaluates (so the claimed wallet's operator is cached) and
280
- * AFTER the payment credential is parsed (so the signer is known). Merchants should call
281
- * it before settling payment.
282
- */
283
- verifyWalletSignerMatch(options: VerifyWalletSignerMatchOptions): Promise<VerifyWalletSignerResult>;
284
293
  }
285
294
  declare function buildAgentMemoryHint(): AgentMemoryHint;
286
295
  declare function createAgentScoreCore(options: AgentScoreCoreOptions): AgentScoreCore;
287
296
 
288
- export { type AccountVerification, type AgentIdentity, type AgentMemoryHint, type AgentScoreCore, type AgentScoreCoreOptions, type AssessResult, type CaptureWalletOptions, type CreateSessionOnMissing, type DenialCode, type DenialReason, type EvaluateOutcome, type FailOpenInfraReason, type GateQuotaInfo, type OperatorVerification, type PolicyCheck, type PolicyResult, type SessionMetadata, type VerifyWalletSignerMatchOptions, type VerifyWalletSignerResult, buildAgentMemoryHint, createAgentScoreCore };
297
+ export { type AccountVerification, type AgentIdentity, type AgentMemoryHint, type AgentScoreCore, type AgentScoreCoreOptions, type AssessResult, type CaptureWalletOptions, type CreateSessionOnMissing, type DenialCode, type DenialReason, type EvaluateOutcome, type FailOpenInfraReason, type GateQuotaInfo, type OperatorVerification, type PolicyCheck, type PolicyResult, type SessionMetadata, type SignerVerdict, type VerifyWalletSignerResult, buildAgentMemoryHint, createAgentScoreCore };
package/dist/core.js CHANGED
@@ -220,7 +220,7 @@ function createAgentScoreCore(options) {
220
220
  } = options;
221
221
  const baseUrl = stripTrailingSlashes(rawBaseUrl);
222
222
  const agentMemoryHint = buildAgentMemoryHint();
223
- const defaultUa = `@agent-score/commerce@${"1.6.0"}`;
223
+ const defaultUa = `@agent-score/commerce@${"1.8.0"}`;
224
224
  const userAgentHeader = userAgent ? `${userAgent} (${defaultUa})` : defaultUa;
225
225
  const sdk = new import_sdk.AgentScore({ apiKey, baseUrl, userAgent: userAgentHeader });
226
226
  const sessionSdkCache = /* @__PURE__ */ new Map();
@@ -294,7 +294,7 @@ function createAgentScoreCore(options) {
294
294
  return void 0;
295
295
  }
296
296
  }
297
- async function evaluate(identity, ctx) {
297
+ async function evaluate(identity, ctx, signer) {
298
298
  if (!identity || !identity.address && !identity.operatorToken) {
299
299
  if (failOpen) return { kind: "allow" };
300
300
  const sessionReason = await tryMintSessionDenial(ctx);
@@ -354,7 +354,12 @@ function createAgentScoreCore(options) {
354
354
  try {
355
355
  const opts = {
356
356
  chain: gateChain,
357
- ...Object.keys(policy).length > 0 ? { policy } : {}
357
+ ...Object.keys(policy).length > 0 ? { policy } : {},
358
+ // Pre-extracted payment signer (by the adapter middleware). When present, the API
359
+ // composes BOTH signer_match (wallet-binding) and signer_sanctions (OFAC SDN wallet
360
+ // check) verdicts on the response in one round trip. Under
361
+ // policy.require_sanctions_clear, a signer_sanctions hit flips decision -> deny inline.
362
+ ...signer && { signer: { address: signer.address, network: signer.network } }
358
363
  };
359
364
  const result = identity.address ? await sdk.assess(identity.address, { ...opts, operatorToken: identity.operatorToken }) : await sdk.assess(null, { ...opts, operatorToken: identity.operatorToken });
360
365
  data = result;
@@ -462,36 +467,6 @@ function createAgentScoreCore(options) {
462
467
  console.warn("[agentscore-commerce] captureWallet failed:", err instanceof Error ? err.message : err);
463
468
  }
464
469
  }
465
- async function resolveWalletToOperator(walletAddress) {
466
- const wallet = normalizeAddress(walletAddress);
467
- const extractFromCached = (raw) => {
468
- const op = raw.resolved_operator;
469
- const links = raw.linked_wallets;
470
- return {
471
- operator: typeof op === "string" ? op : null,
472
- linkedWallets: Array.isArray(links) ? links.filter((w) => typeof w === "string") : []
473
- };
474
- };
475
- const plainCached = cache.get(wallet);
476
- if (plainCached?.raw) {
477
- return { ok: true, ...extractFromCached(plainCached.raw) };
478
- }
479
- const resolveCached = cache.get(`resolve:${wallet}`);
480
- if (resolveCached?.raw) {
481
- return { ok: true, ...extractFromCached(resolveCached.raw) };
482
- }
483
- try {
484
- const data = await sdk.assess(walletAddress);
485
- cache.set(`resolve:${wallet}`, { allow: true, raw: data });
486
- return { ok: true, ...extractFromCached(data) };
487
- } catch (err) {
488
- console.warn("[gate] resolveWalletToOperator failed \u2014 returning { ok:false }:", err instanceof Error ? err.message : err);
489
- return { ok: false };
490
- }
491
- }
492
- function reportSignerEvent(kind) {
493
- void sdk.telemetrySignerMatch({ kind });
494
- }
495
470
  function projectSignerMatch(sm, claimedNorm, signerNorm) {
496
471
  const kind = sm.kind;
497
472
  if (kind === "pass") {
@@ -519,77 +494,22 @@ function createAgentScoreCore(options) {
519
494
  agentInstructions: sm.agent_instructions ?? WALLET_SIGNER_MISMATCH_INSTRUCTIONS
520
495
  };
521
496
  }
522
- async function verifyWalletSignerMatch(options2) {
523
- const { claimedWallet, signer, network } = options2;
524
- if (!signer) {
525
- reportSignerEvent("wallet_auth_requires_wallet_signing");
526
- return {
527
- kind: "wallet_auth_requires_wallet_signing",
528
- claimedWallet,
529
- agentInstructions: WALLET_AUTH_REQUIRES_WALLET_SIGNING_INSTRUCTIONS
530
- };
531
- }
532
- const claimedNorm = normalizeAddress(claimedWallet);
533
- const signerNorm = normalizeAddress(signer);
534
- if (claimedNorm === signerNorm) {
535
- reportSignerEvent("pass");
536
- return { kind: "pass", claimedOperator: null, signerOperator: null };
537
- }
538
- const cachedEntry = cache.get(claimedNorm);
539
- const cachedMatch = cachedEntry?.signerMatchBySigner?.get(signerNorm);
540
- if (cachedMatch) {
541
- return projectSignerMatch(cachedMatch, claimedNorm, signerNorm);
542
- }
543
- const inferredNetwork = network ?? (signerNorm.startsWith("0x") ? "evm" : "solana");
544
- let assessResponse;
545
- try {
546
- assessResponse = await sdk.assess(claimedNorm, {
547
- resolveSigner: { address: signerNorm, network: inferredNetwork }
548
- });
549
- } catch (err) {
550
- console.warn("[gate] verifyWalletSignerMatch assess failed:", err instanceof Error ? err.message : err);
551
- reportSignerEvent("api_error");
552
- return { kind: "api_error", claimedWallet: claimedNorm };
553
- }
554
- const signerMatch = assessResponse.signer_match;
555
- if (signerMatch && typeof signerMatch === "object") {
556
- if (cachedEntry) {
557
- const map = cachedEntry.signerMatchBySigner ?? /* @__PURE__ */ new Map();
558
- map.set(signerNorm, signerMatch);
559
- cachedEntry.signerMatchBySigner = map;
560
- } else {
561
- const entry = { allow: true, raw: assessResponse };
562
- entry.signerMatchBySigner = /* @__PURE__ */ new Map([[signerNorm, signerMatch]]);
563
- cache.set(claimedNorm, entry);
564
- }
565
- return projectSignerMatch(signerMatch, claimedNorm, signerNorm);
566
- }
567
- const [claimedResolve, signerResolve] = await Promise.all([
568
- resolveWalletToOperator(claimedNorm),
569
- resolveWalletToOperator(signerNorm)
570
- ]);
571
- if (!claimedResolve.ok || !signerResolve.ok) {
572
- reportSignerEvent("api_error");
573
- return { kind: "api_error", claimedWallet: claimedNorm };
574
- }
575
- const claimedOperator = claimedResolve.operator;
576
- const signerOperator = signerResolve.operator;
577
- if (claimedOperator && signerOperator && claimedOperator === signerOperator) {
578
- reportSignerEvent("pass");
579
- return { kind: "pass", claimedOperator, signerOperator };
580
- }
581
- reportSignerEvent("wallet_signer_mismatch");
497
+ function getSignerVerdict(claimedAddress) {
498
+ const claimedNorm = normalizeAddress(claimedAddress);
499
+ const cached = cache.get(claimedNorm);
500
+ if (!cached) return void 0;
501
+ const raw = cached.raw;
502
+ if (!raw) return void 0;
503
+ const rawMatch = raw.signer_match;
504
+ const rawSanctions = raw.signer_sanctions;
505
+ if (!rawMatch && !rawSanctions) return void 0;
506
+ const signerNorm = rawMatch?.actual_signer ?? claimedNorm;
582
507
  return {
583
- kind: "wallet_signer_mismatch",
584
- claimedOperator,
585
- actualSignerOperator: signerOperator,
586
- expectedSigner: claimedNorm,
587
- actualSigner: signerNorm,
588
- linkedWallets: claimedResolve.linkedWallets,
589
- agentInstructions: WALLET_SIGNER_MISMATCH_INSTRUCTIONS
508
+ signer_match: rawMatch ? projectSignerMatch(rawMatch, claimedNorm, signerNorm) : null,
509
+ signer_sanctions: rawSanctions ?? null
590
510
  };
591
511
  }
592
- return { evaluate, captureWallet, verifyWalletSignerMatch };
512
+ return { evaluate, captureWallet, getSignerVerdict };
593
513
  }
594
514
  // Annotate the CommonJS export names for ESM import in node:
595
515
  0 && (module.exports = {