Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Agent commerce SDK for Node.js. The full merchant-side toolkit: identity gating + payment helpers + 402 builders + discovery + Stripe multichain. One install, subpath imports per concern.

Every helper lifts directly from working production code (`agentscore/martin-estate`) — extract from real consumers, not speculation.
Every helper is extracted from a real consumer, not speculated.

## Subpaths

Expand Down Expand Up @@ -75,7 +75,7 @@ app.use('/purchase', async (c, next) => {
});
```

Anonymous POST flows through to the handler unauthenticated and gets a 402 with all rails + per-order pricing. Identity is verified at settle time on the retry leg (when the agent submits `X-Payment` / `Authorization: Payment`); `createSessionOnMissing` still auto-mints a verification session there. The same wrap pattern works identically across all 5 framework adapters (hono, express, fastify, nextjs, web). martin-estate runs this pattern in production. See `examples/multi-rail-merchant.ts` and `examples/compliance-merchant.ts`.
Anonymous POST flows through to the handler unauthenticated and gets a 402 with all rails + per-order pricing. Identity is verified at settle time on the retry leg (when the agent submits `X-Payment` / `Authorization: Payment`); `createSessionOnMissing` still auto-mints a verification session there. The same wrap pattern works identically across all 5 framework adapters (hono, express, fastify, nextjs, web). See `examples/multi-rail-merchant.ts` and `examples/compliance-merchant.ts`.

### `compatible_clients` field on emitted 402s

Expand Down
12 changes: 6 additions & 6 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions examples/multi-rail-merchant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
* Example: full multi-rail agent commerce merchant
*
* Scenario: you want to accept agent payments via every rail — Tempo MPP, x402 on
* Base + Solana, AND Stripe SPT. Identity-gated for compliance. This mirrors what
* Martin Estate runs in production, stripped of wine-specific business logic.
* Base + Solana, AND Stripe SPT. Identity-gated for compliance.
*
* The flow on each /purchase POST:
* 1. Identity gate (agentscoreGate): KYC + age + jurisdiction + sanctions
Expand Down
3 changes: 0 additions & 3 deletions examples/per-product-policy-merchant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@
* - shippingCountryAllowed / shippingStateAllowed
* (per-product shipping allowlists; null = ship anywhere)
*
* The pattern was extracted from agentscore/store. See its
* store/routes/purchase.py (Python sibling) for the full per-request flow.
*
* Peer deps:
* bun add @agent-score/commerce hono
*
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@agent-score/commerce",
"version": "1.0.1",
"version": "1.0.2",
"description": "Agent commerce SDK — identity middleware (Hono, Express, Fastify, Next.js, Web Fetch) + payment helpers + 402 builders + discovery + Stripe multichain. The full merchant-side toolkit for AgentScore-powered agent commerce.",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
Expand Down Expand Up @@ -120,7 +120,7 @@
"node": ">=20"
},
"dependencies": {
"@agent-score/sdk": "^2.1.0"
"@agent-score/sdk": "^2.1.1"
},
"overrides": {
"axios": "^1.15.0"
Expand Down Expand Up @@ -161,9 +161,9 @@
"eslint-plugin-unused-imports": "^4.4.1",
"express": "^5.2.1",
"fastify": "^5.8.5",
"hono": "^4.12.15",
"hono": "^4.12.16",
"lefthook": "^2.1.6",
"mppx": "^0.6.7",
"mppx": "^0.6.8",
"tsup": "^8.5.1",
"typescript": "^6.0.3",
"typescript-eslint": "^8.59.1",
Expand Down
3 changes: 1 addition & 2 deletions src/identity/policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
* {@link GateResult} so the vendor decides how to surface it.
*
* All three are additive — vendors using `agentscoreGate(...)` directly are
* unaffected. The pattern was extracted from `agentscore/store`; see its
* `store/routes/purchase.py` (Python sibling) for the full per-request flow.
* unaffected.
*/

import type { AgentScoreCoreOptions, DenialReason } from '../core.js';
Expand Down
6 changes: 3 additions & 3 deletions src/stripe-multichain/pi-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
*
* All three are TTL-bounded (default 300s — long enough for an agent to retry, short
* enough to bound memory). Backed by Redis when `redisUrl` is set, falls back to
* in-process Map otherwise. Single-instance servers can use the in-memory cache; ECS
* Fargate / multi-task deployments need Redis so a deposit lands on whichever task
* settles it.
* in-process Map otherwise. Single-instance servers can use the in-memory cache;
* multi-instance deployments need a shared cache (Redis) so a deposit lands on
* whichever instance settles it.
*/

// ioredis is an optional peer dep — typed structurally to avoid pulling its types into
Expand Down
4 changes: 2 additions & 2 deletions tests/integration.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { describe, expect, it } from 'vitest';

const API_KEY = process.env.AGENTSCORE_API_KEY;
const BASE_URL = process.env.AGENTSCORE_BASE_URL || 'http://api.dev.agentscore.internal';
const BASE_URL = process.env.AGENTSCORE_BASE_URL;
const TEST_ADDRESS = '0x339559a2d1cd15059365fc7bd36b3047bba480e0';

const describeIf = API_KEY ? describe : describe.skip;
const describeIf = (API_KEY && BASE_URL) ? describe : describe.skip;

describeIf('integration: real API assess response shape', () => {
it('assess returns correct top-level shape', async () => {
Expand Down
Loading