@curless/agentbank-merchant-sdk 0.6.0 → 0.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.
- package/README.md +68 -29
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -5,19 +5,22 @@ Drop into a merchant's backend (Shopify storefront, ClubMed booking flow,
|
|
|
5
5
|
TikTok Shop seller service, anything that wants to **accept agent payments**)
|
|
6
6
|
and you get:
|
|
7
7
|
|
|
8
|
-
- **`checkout.
|
|
8
|
+
- **`checkout.openACP`** — merchant-quoted **card** checkout. **You** price an order from your own catalog and open a checkout; an agent pays it with a card credential; the money lands in your account.
|
|
9
|
+
- **`checkout.openX402`** — merchant-quoted **USDC (x402)** checkout. You set the authoritative USDC amount; the gateway freezes it and returns the x402 challenge; a buyer agent signs an EIP-3009 authorization and pays `{ sessionId }` on-chain. Settlement is on Base (mainnet or Sepolia, decided by your account/key) — your USDC lands at your address. The stablecoin twin of `openACP`.
|
|
10
|
+
- **`orders`** — read your settled orders: `orders.list({ status, protocol, currency, from, to, limit, offset })` (filtered + paginated, with a total), `orders.get(id)` (one order in full + the card it was paid with), `orders.summary({…})` (count + gross by currency + breakdowns by protocol/status — a dashboard in one call).
|
|
9
11
|
- **`AgentbankMerchant`** — typed client; also exposes `PaymentIntents` (create/get/capture/list/ledger-entries across ACP / x402 / AP2 / UCP / A2A), `PaymentLinks`, `Customers`, `BalanceTransactions`, and `WebhookEndpoints`. No refund method — refunds are Curless-originated (see below).
|
|
10
12
|
- **`verifyWebhook` / `parseVerifiedWebhook`** — HMAC-SHA256 signature verification (Stripe-style `t=…,v1=…`), constant-time, **edge-safe** (Web Crypto, runs on Vercel Edge / Cloudflare Workers). Async — `await` them.
|
|
11
|
-
- **`x402`** — `buildChallenge()`
|
|
13
|
+
- **`x402`** — emit/parse payments yourself (`buildChallenge()`, `decodeXPaymentHeader()`) **plus zero-crypto-knowledge helpers**: `usdc(network)` (contract + EIP-712 domain + decimals — no hardcoded hex), `isMainnet/isTestnet(network)`, `explorerTxUrl(network, txHash)` (a basescan / sepolia.basescan receipt link), `formatUsdc(baseUnits)` (exact 6-dp string, no float drift).
|
|
12
14
|
|
|
13
|
-
One runtime dependency (`@curless/agentbank-core
|
|
15
|
+
agentbank never stores your catalog — the price you pass is authoritative, and you accept every agent-payment protocol with zero protocol code. One runtime dependency (`@curless/agentbank-core`). **Edge-safe** — Web Crypto only, no `node:` builtins. Node 18+.
|
|
14
16
|
|
|
15
17
|
> **Refunds**: agentbank exposes no refund-initiation endpoint. The merchant
|
|
16
|
-
> refunds in Curless (it holds the money); Curless executes the
|
|
17
|
-
> forwards the event, which advances the PI to `refunded` /
|
|
18
|
-
> Read the resulting state via `
|
|
18
|
+
> refunds in Curless (it holds the money); Curless executes the refund and
|
|
19
|
+
> forwards the event, which advances the order/PI to `refunded` /
|
|
20
|
+
> `partially_refunded`. Read the resulting state via `orders.list({ status:
|
|
21
|
+
> 'refunded' })` or `paymentIntents.get()`.
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
## Fast path — open a merchant-quoted checkout
|
|
21
24
|
|
|
22
25
|
```ts
|
|
23
26
|
import { AgentbankMerchant } from '@curless/agentbank-merchant-sdk';
|
|
@@ -28,30 +31,58 @@ const agentbank = new AgentbankMerchant({
|
|
|
28
31
|
merchantId: process.env.AGENTBANK_MERCHANT_ID!,
|
|
29
32
|
});
|
|
30
33
|
|
|
31
|
-
//
|
|
32
|
-
const checkout = await agentbank.checkout.
|
|
34
|
+
// CARD (ACP) — YOU set the price; an agent pays it; money lands in your account.
|
|
35
|
+
const checkout = await agentbank.checkout.openACP({
|
|
33
36
|
currency: 'EUR',
|
|
34
|
-
items: [
|
|
35
|
-
{ sku: 'resort-bali', name: 'Club Med Bali — 7 nights', quantity: 1, unitPrice: 192000 },
|
|
36
|
-
],
|
|
37
|
+
items: [{ sku: 'resort-bali', name: 'Club Med Bali — 7 nights', quantity: 1, unitPrice: 192000 }],
|
|
37
38
|
});
|
|
38
|
-
|
|
39
|
-
// Hand checkout.id back to the buyer agent; it pays, money lands in your account.
|
|
40
39
|
return { checkoutId: checkout.id, amount: checkout.amount, currency: checkout.currency };
|
|
40
|
+
|
|
41
|
+
// USDC (x402) — YOU set the USDC amount (base units, 6 dp). Hand the challenge
|
|
42
|
+
// to the buyer agent; it signs + pays `{ sessionId }` on-chain. The network
|
|
43
|
+
// (base / base-sepolia) is decided by your account — same code on testnet/mainnet.
|
|
44
|
+
const x402co = await agentbank.checkout.openX402({
|
|
45
|
+
amount: 1_050_000, // 1.05 USDC
|
|
46
|
+
items: [{ sku: 'resort-bali', name: 'Club Med Bali — 7 nights', quantity: 1, unitPrice: 1_050_000 }],
|
|
47
|
+
});
|
|
48
|
+
return { sessionId: x402co.sessionId, accepts: x402co.accepts, network: x402co.network };
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
That's the whole integration: install, set three env vars, call one method. You
|
|
52
|
+
stay the source of truth for your catalog and prices — nothing to sync.
|
|
53
|
+
|
|
54
|
+
## Read your orders
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
// Filtered + paginated (status / protocol / currency / date range):
|
|
58
|
+
const { data, pagination } = await agentbank.orders.list({ status: 'paid', protocol: 'x402', limit: 50 });
|
|
59
|
+
|
|
60
|
+
// One order in full (line items + the card it was paid with):
|
|
61
|
+
const { order, payment } = await agentbank.orders.get(data[0]!.id);
|
|
62
|
+
|
|
63
|
+
// A dashboard in one call: count + gross by currency + by protocol/status.
|
|
64
|
+
const summary = await agentbank.orders.summary({ from: '2026-06-01' });
|
|
65
|
+
// summary.count · summary.byCurrency[{ currency, count, totalAmount }] · summary.byProtocol · summary.byStatus
|
|
41
66
|
```
|
|
42
67
|
|
|
43
|
-
|
|
44
|
-
|
|
68
|
+
## x402 helpers — display a settled payment, zero crypto knowledge
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import { x402 } from '@curless/agentbank-merchant-sdk';
|
|
72
|
+
|
|
73
|
+
x402.explorerTxUrl('base', '0xa596…'); // → https://basescan.org/tx/0xa596… (sepolia.basescan on testnet)
|
|
74
|
+
x402.formatUsdc(1_050_000); // → "1.050000" (exact string math, no float drift)
|
|
75
|
+
x402.formatUsdc(1_050_000, { symbol: true }); // → "1.050000 USDC"
|
|
76
|
+
x402.isMainnet('base'); // → true (isTestnet('base-sepolia') → true)
|
|
77
|
+
x402.usdc('base')!.contract; // → "0x833589…02913" (no hardcoded hex)
|
|
78
|
+
```
|
|
45
79
|
|
|
46
|
-
|
|
80
|
+
## Lower-level — PaymentIntents, webhooks, self-emitted 402
|
|
47
81
|
|
|
48
82
|
```ts
|
|
49
83
|
import { AgentbankMerchant, parseVerifiedWebhook, x402 } from '@curless/agentbank-merchant-sdk';
|
|
50
84
|
|
|
51
|
-
const client = new AgentbankMerchant({
|
|
52
|
-
baseUrl: 'https://api.agentbank.dev',
|
|
53
|
-
apiKey: process.env.AGENTBANK_KEY!, // merchant:write
|
|
54
|
-
});
|
|
85
|
+
const client = new AgentbankMerchant({ baseUrl: 'https://mcp.curless.ai', apiKey: process.env.AGENTBANK_KEY! });
|
|
55
86
|
|
|
56
87
|
// Create a PaymentIntent the agent will pay against
|
|
57
88
|
const pi = await client.paymentIntents.create({
|
|
@@ -71,14 +102,22 @@ const event = await parseVerifiedWebhook(
|
|
|
71
102
|
req.headers['x-agentbank-signature'],
|
|
72
103
|
);
|
|
73
104
|
|
|
74
|
-
// Or emit your own 402 challenge from your route
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
105
|
+
// Or emit your own 402 challenge from your route. buildChallenge auto-fills the
|
|
106
|
+
// right EIP-712 domain per network ("USD Coin" on base, "USDC" on base-sepolia)
|
|
107
|
+
// — a wrong name reverts on-chain, so let the helper get it right.
|
|
108
|
+
const usdc = x402.usdc('base')!;
|
|
109
|
+
return new Response(
|
|
110
|
+
JSON.stringify(
|
|
111
|
+
x402.buildChallenge({
|
|
112
|
+
asset: usdc.contract, // no hardcoded hex
|
|
113
|
+
network: 'base',
|
|
114
|
+
payTo: '0xYourUsdcAddress',
|
|
115
|
+
amount: '1050000', // 1.05 USDC (6 dp)
|
|
116
|
+
resource: 'https://shop.example/api/checkout',
|
|
117
|
+
}),
|
|
118
|
+
),
|
|
119
|
+
{ status: 402, headers: { 'content-type': 'application/json' } },
|
|
120
|
+
);
|
|
82
121
|
```
|
|
83
122
|
|
|
84
123
|
## Timeouts & errors
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@curless/agentbank-merchant-sdk",
|
|
3
|
-
"version": "0.6.
|
|
4
|
-
"description": "Merchant-side SDK for agentbank — accept agent payments: open a merchant-quoted
|
|
3
|
+
"version": "0.6.1",
|
|
4
|
+
"description": "Merchant-side SDK for agentbank — accept agent payments: open a merchant-quoted card (ACP) or USDC (x402) checkout you price, list/summarize orders, PaymentIntents, edge-safe webhook verification, and x402 helpers.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|