@curless/agentbank-merchant-sdk 0.0.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 ADDED
@@ -0,0 +1,48 @@
1
+ # @curless/agentbank-merchant-sdk
2
+
3
+ Merchant-side SDK for [agentbank](https://gitlab.com/robin-ruan/agentbank).
4
+ Drop into a merchant's backend (Shopify storefront, ClubMed booking flow,
5
+ TikTok Shop seller service, anything that wants to **accept agent payments**)
6
+ and you get:
7
+
8
+ - **`AgentbankMerchant`** — typed client for `PaymentIntents` (create/get/capture/list across ACP / x402 / AP2 / UCP / A2A) and `WebhookEndpoints`.
9
+ - **`verifyWebhook` / `parseVerifiedWebhook`** — HMAC-SHA256 signature verification (Stripe-style `t=…,v1=…`), constant-time.
10
+ - **`x402`** — `buildChallenge()` to emit your own canonical 402 from your route, `decodeXPaymentHeader()` to parse what the agent paid with.
11
+
12
+ Zero runtime dependencies (pure `fetch` + `node:crypto`). Node 18+.
13
+
14
+ ```ts
15
+ import { AgentbankMerchant, parseVerifiedWebhook, x402 } from '@curless/agentbank-merchant-sdk';
16
+
17
+ const client = new AgentbankMerchant({
18
+ baseUrl: 'https://api.agentbank.dev',
19
+ apiKey: process.env.AGENTBANK_KEY!, // merchant:write
20
+ });
21
+
22
+ // Create a PaymentIntent the agent will pay against
23
+ const pi = await client.paymentIntents.create({
24
+ organizationId: 'org_123',
25
+ curlessMerchantId: 'curless_mch_clubmed_bali',
26
+ amount: 1160,
27
+ currency: 'USD',
28
+ protocol: 'x402',
29
+ items: [{ catalogItemId: 'room-suite', quantity: 1, unitPrice: 1160 }],
30
+ idempotencyKey: req.headers['idempotency-key'],
31
+ });
32
+
33
+ // Verify an inbound agentbank webhook
34
+ const event = parseVerifiedWebhook(
35
+ process.env.WEBHOOK_SECRET!, // whsec_… from /v1/webhook-endpoints
36
+ await req.text(), // RAW body, NOT JSON-parsed
37
+ req.headers['x-agentbank-signature'],
38
+ );
39
+
40
+ // Or emit your own 402 challenge from your route
41
+ return new Response(JSON.stringify(x402.buildChallenge({
42
+ asset: '0x036CbD…F7e', // base-sepolia USDC
43
+ network: 'base-sepolia',
44
+ payTo: '0xMerchantAddr',
45
+ amount: '6200000', // 6.20 USDC
46
+ resource: 'https://shop.example/api/checkout',
47
+ })), { status: 402, headers: { 'content-type': 'application/json' } });
48
+ ```
@@ -0,0 +1,24 @@
1
+ import { PaymentIntentsResource } from './resources/payment-intents.js';
2
+ import { WebhookEndpointsResource } from './resources/webhook-endpoints.js';
3
+ export type FetchLike = typeof fetch;
4
+ export type RequestOptions = {
5
+ query?: Record<string, string | number | undefined>;
6
+ body?: unknown;
7
+ idempotencyKey?: string;
8
+ };
9
+ export type AgentbankMerchantOptions = {
10
+ baseUrl: string;
11
+ apiKey: string;
12
+ fetch?: FetchLike;
13
+ };
14
+ export declare class AgentbankMerchant {
15
+ readonly baseUrl: string;
16
+ private readonly fetchImpl;
17
+ private readonly apiKey;
18
+ readonly paymentIntents: PaymentIntentsResource;
19
+ readonly webhookEndpoints: WebhookEndpointsResource;
20
+ constructor(opts: AgentbankMerchantOptions);
21
+ /** @internal */
22
+ request<T>(method: string, path: string, opts?: RequestOptions): Promise<T>;
23
+ }
24
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAE5E,MAAM,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC;AAErC,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;IACpD,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,EAAE,MAAM,CAAC;IAEhB,MAAM,EAAE,MAAM,CAAC;IAEf,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAOF,qBAAa,iBAAiB;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,QAAQ,CAAC,cAAc,EAAE,sBAAsB,CAAC;IAChD,QAAQ,CAAC,gBAAgB,EAAE,wBAAwB,CAAC;gBAExC,IAAI,EAAE,wBAAwB;IAQ1C,gBAAgB;IACV,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;CAyBtF"}
package/dist/client.js ADDED
@@ -0,0 +1,59 @@
1
+ import { AgentbankError } from './errors.js';
2
+ import { PaymentIntentsResource } from './resources/payment-intents.js';
3
+ import { WebhookEndpointsResource } from './resources/webhook-endpoints.js';
4
+ // Merchant-side client for agentbank. Wraps the HTTP surface a merchant
5
+ // integrates against: create + capture PaymentIntents (any protocol),
6
+ // manage webhook subscriptions, query PI status. Webhook verification
7
+ // + x402 challenge helpers live in ./webhooks and ./x402 as pure
8
+ // functions (no client needed).
9
+ export class AgentbankMerchant {
10
+ baseUrl;
11
+ fetchImpl;
12
+ apiKey;
13
+ paymentIntents;
14
+ webhookEndpoints;
15
+ constructor(opts) {
16
+ this.baseUrl = opts.baseUrl.replace(/\/+$/, '');
17
+ this.apiKey = opts.apiKey;
18
+ this.fetchImpl = opts.fetch ?? fetch;
19
+ this.paymentIntents = new PaymentIntentsResource(this);
20
+ this.webhookEndpoints = new WebhookEndpointsResource(this);
21
+ }
22
+ /** @internal */
23
+ async request(method, path, opts = {}) {
24
+ const url = new URL(`${this.baseUrl}${path}`);
25
+ if (opts.query) {
26
+ for (const [k, v] of Object.entries(opts.query)) {
27
+ if (v !== undefined)
28
+ url.searchParams.set(k, String(v));
29
+ }
30
+ }
31
+ const headers = {
32
+ 'content-type': 'application/json',
33
+ authorization: `Bearer ${this.apiKey}`,
34
+ };
35
+ if (opts.idempotencyKey)
36
+ headers['idempotency-key'] = opts.idempotencyKey;
37
+ const res = await this.fetchImpl(url.toString(), {
38
+ method,
39
+ headers,
40
+ body: opts.body === undefined ? undefined : JSON.stringify(opts.body),
41
+ });
42
+ const text = await res.text();
43
+ const json = text ? JSON.parse(text) : undefined;
44
+ if (!res.ok)
45
+ throw toError(res.status, json);
46
+ return json;
47
+ }
48
+ }
49
+ const toError = (status, json) => {
50
+ if (json && typeof json === 'object') {
51
+ const o = json;
52
+ if (o.error && typeof o.error === 'object') {
53
+ const e = o.error;
54
+ return new AgentbankError(status, String(e.code ?? 'error'), String(e.message ?? 'request failed'), e.details);
55
+ }
56
+ }
57
+ return new AgentbankError(status, 'error', `request failed with status ${status}`);
58
+ };
59
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare class AgentbankError extends Error {
2
+ readonly status: number;
3
+ readonly code: string;
4
+ readonly details?: unknown;
5
+ constructor(status: number, code: string, message: string, details?: unknown);
6
+ }
7
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;gBAEf,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;CAO7E"}
package/dist/errors.js ADDED
@@ -0,0 +1,15 @@
1
+ // Thrown for any non-2xx agentbank response. `code` is the agentbank
2
+ // error code (e.g. CONFLICT, FORBIDDEN, NOT_FOUND) and `status` is HTTP.
3
+ export class AgentbankError extends Error {
4
+ status;
5
+ code;
6
+ details;
7
+ constructor(status, code, message, details) {
8
+ super(message);
9
+ this.name = 'AgentbankError';
10
+ this.status = status;
11
+ this.code = code;
12
+ this.details = details;
13
+ }
14
+ }
15
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,yEAAyE;AACzE,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,MAAM,CAAS;IACf,IAAI,CAAS;IACb,OAAO,CAAW;IAE3B,YAAY,MAAc,EAAE,IAAY,EAAE,OAAe,EAAE,OAAiB;QAC1E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ export { AgentbankMerchant } from './client.js';
2
+ export type { AgentbankMerchantOptions, FetchLike, RequestOptions, } from './client.js';
3
+ export { AgentbankError } from './errors.js';
4
+ export type { Paginated, PaymentIntent, PaymentIntentStatus, PaymentProtocol, WebhookEndpoint, WebhookEndpointWithSecret, X402PaymentRequirements, } from './types.js';
5
+ export type { CreatePaymentIntentInput } from './resources/payment-intents.js';
6
+ export type { CreateWebhookEndpointInput } from './resources/webhook-endpoints.js';
7
+ export { WEBHOOK_SIGNATURE_HEADER, parseVerifiedWebhook, verifyWebhook, } from './webhooks.js';
8
+ export type { VerifyWebhookOptions, WebhookEvent } from './webhooks.js';
9
+ import * as x402 from './x402.js';
10
+ export { x402 };
11
+ export type { BuildChallengeInput, DecodedXPayment, X402ChallengeBody, } from './x402.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EACV,wBAAwB,EACxB,SAAS,EACT,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EACV,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC/E,YAAY,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAExE,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,CAAC;AAChB,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,iBAAiB,GAClB,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { AgentbankMerchant } from './client.js';
2
+ export { AgentbankError } from './errors.js';
3
+ export { WEBHOOK_SIGNATURE_HEADER, parseVerifiedWebhook, verifyWebhook, } from './webhooks.js';
4
+ // x402 helpers — namespaced so consumers `import { x402 } from ...`.
5
+ import * as x402 from './x402.js';
6
+ export { x402 };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAMhD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAY7C,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,aAAa,GACd,MAAM,eAAe,CAAC;AAEvB,qEAAqE;AACrE,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { AgentbankMerchant } from '../client.js';
2
+ import type { Paginated, PaymentIntent, PaymentIntentStatus, PaymentProtocol } from '../types.js';
3
+ export type CreatePaymentIntentInput = {
4
+ organizationId: string;
5
+ agentId?: string;
6
+ curlessMerchantId: string;
7
+ amount: number;
8
+ currency: string;
9
+ protocol: PaymentProtocol;
10
+ items: Array<{
11
+ catalogItemId: string;
12
+ quantity: number;
13
+ unitPrice: number;
14
+ }>;
15
+ metadata?: Record<string, unknown>;
16
+ idempotencyKey?: string;
17
+ };
18
+ export declare class PaymentIntentsResource {
19
+ private readonly client;
20
+ constructor(client: AgentbankMerchant);
21
+ create(input: CreatePaymentIntentInput): Promise<PaymentIntent>;
22
+ get(id: string): Promise<PaymentIntent>;
23
+ capture(id: string): Promise<PaymentIntent>;
24
+ list(params?: {
25
+ limit?: number;
26
+ offset?: number;
27
+ status?: PaymentIntentStatus;
28
+ }): Promise<Paginated<PaymentIntent>>;
29
+ }
30
+ //# sourceMappingURL=payment-intents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment-intents.d.ts","sourceRoot":"","sources":["../../src/resources/payment-intents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAElG,MAAM,MAAM,wBAAwB,GAAG;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAIF,qBAAa,sBAAsB;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,iBAAiB;IAEtD,MAAM,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,aAAa,CAAC;IAQ/D,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAOvC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAO3C,IAAI,CACF,MAAM,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,mBAAmB,CAAA;KAAO,GAC7E,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;CAKrC"}
@@ -0,0 +1,27 @@
1
+ // PaymentIntents — the rail-agnostic create/capture/get/list a merchant
2
+ // uses regardless of protocol (ACP / x402 / AP2 / UCP / A2A / direct).
3
+ export class PaymentIntentsResource {
4
+ client;
5
+ constructor(client) {
6
+ this.client = client;
7
+ }
8
+ create(input) {
9
+ const { idempotencyKey, ...body } = input;
10
+ return this.client.request('POST', '/v1/payment-intents', {
11
+ body,
12
+ idempotencyKey,
13
+ });
14
+ }
15
+ get(id) {
16
+ return this.client.request('GET', `/v1/payment-intents/${encodeURIComponent(id)}`);
17
+ }
18
+ capture(id) {
19
+ return this.client.request('POST', `/v1/payment-intents/${encodeURIComponent(id)}/capture`);
20
+ }
21
+ list(params = {}) {
22
+ return this.client.request('GET', '/v1/payment-intents', {
23
+ query: params,
24
+ });
25
+ }
26
+ }
27
+ //# sourceMappingURL=payment-intents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment-intents.js","sourceRoot":"","sources":["../../src/resources/payment-intents.ts"],"names":[],"mappings":"AAeA,wEAAwE;AACxE,uEAAuE;AACvE,MAAM,OAAO,sBAAsB;IACJ;IAA7B,YAA6B,MAAyB;QAAzB,WAAM,GAAN,MAAM,CAAmB;IAAG,CAAC;IAE1D,MAAM,CAAC,KAA+B;QACpC,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;QAC1C,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAgB,MAAM,EAAE,qBAAqB,EAAE;YACvE,IAAI;YACJ,cAAc;SACf,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CACxB,KAAK,EACL,uBAAuB,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAChD,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CACxB,MAAM,EACN,uBAAuB,kBAAkB,CAAC,EAAE,CAAC,UAAU,CACxD,CAAC;IACJ,CAAC;IAED,IAAI,CACF,SAA4E,EAAE;QAE9E,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAA2B,KAAK,EAAE,qBAAqB,EAAE;YACjF,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ import type { AgentbankMerchant } from '../client.js';
2
+ import type { Paginated, WebhookEndpoint, WebhookEndpointWithSecret } from '../types.js';
3
+ export type CreateWebhookEndpointInput = {
4
+ url: string;
5
+ description?: string;
6
+ eventTypes?: string[];
7
+ };
8
+ export declare class WebhookEndpointsResource {
9
+ private readonly client;
10
+ constructor(client: AgentbankMerchant);
11
+ create(input: CreateWebhookEndpointInput): Promise<WebhookEndpointWithSecret>;
12
+ list(params?: {
13
+ limit?: number;
14
+ offset?: number;
15
+ }): Promise<Paginated<WebhookEndpoint>>;
16
+ delete(endpointId: string): Promise<{
17
+ deleted: string;
18
+ }>;
19
+ }
20
+ //# sourceMappingURL=webhook-endpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-endpoints.d.ts","sourceRoot":"","sources":["../../src/resources/webhook-endpoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAEzF,MAAM,MAAM,0BAA0B,GAAG;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAMF,qBAAa,wBAAwB;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,iBAAiB;IAEtD,MAAM,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAM7E,IAAI,CAAC,MAAM,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAM3F,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAMzD"}
@@ -0,0 +1,24 @@
1
+ // Webhook endpoint subscriptions. agentbank fans payment events out to
2
+ // enabled endpoints (signed via HMAC, retried via outbox). The signing
3
+ // secret is returned ONLY on create — store it; you'll need it for
4
+ // verifyWebhook(). See ../webhooks.ts.
5
+ export class WebhookEndpointsResource {
6
+ client;
7
+ constructor(client) {
8
+ this.client = client;
9
+ }
10
+ create(input) {
11
+ return this.client.request('POST', '/v1/webhook-endpoints', {
12
+ body: input,
13
+ });
14
+ }
15
+ list(params = {}) {
16
+ return this.client.request('GET', '/v1/webhook-endpoints', {
17
+ query: params,
18
+ });
19
+ }
20
+ delete(endpointId) {
21
+ return this.client.request('DELETE', `/v1/webhook-endpoints/${encodeURIComponent(endpointId)}`);
22
+ }
23
+ }
24
+ //# sourceMappingURL=webhook-endpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-endpoints.js","sourceRoot":"","sources":["../../src/resources/webhook-endpoints.ts"],"names":[],"mappings":"AAUA,uEAAuE;AACvE,uEAAuE;AACvE,mEAAmE;AACnE,uCAAuC;AACvC,MAAM,OAAO,wBAAwB;IACN;IAA7B,YAA6B,MAAyB;QAAzB,WAAM,GAAN,MAAM,CAAmB;IAAG,CAAC;IAE1D,MAAM,CAAC,KAAiC;QACtC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAA4B,MAAM,EAAE,uBAAuB,EAAE;YACrF,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,SAA8C,EAAE;QACnD,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAA6B,KAAK,EAAE,uBAAuB,EAAE;YACrF,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,UAAkB;QACvB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CACxB,QAAQ,EACR,yBAAyB,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAC1D,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,53 @@
1
+ export type PaymentIntentStatus = 'initiated' | 'authorized' | 'authorizing' | 'captured' | 'settled' | 'reconciled' | 'failed' | 'refunded' | 'disputed';
2
+ export type PaymentProtocol = 'a2a' | 'acp' | 'ap2' | 'ucp' | 'mcp' | 'x402' | 'tap' | 'mc' | 'direct';
3
+ export type PaymentIntent = {
4
+ id: string;
5
+ organizationId: string | null;
6
+ agentId?: string | null;
7
+ curlessMerchantId: string;
8
+ protocol: PaymentProtocol;
9
+ rail?: string | null;
10
+ status: PaymentIntentStatus;
11
+ amount: number;
12
+ currency: string;
13
+ railReference?: string | null;
14
+ idempotencyKey?: string | null;
15
+ createdAt: string;
16
+ updatedAt: string;
17
+ settledAt?: string | null;
18
+ };
19
+ export type WebhookEndpoint = {
20
+ id: string;
21
+ url: string;
22
+ description?: string | null;
23
+ enabled: boolean;
24
+ eventTypes: string[];
25
+ createdAt: string;
26
+ };
27
+ export type WebhookEndpointWithSecret = WebhookEndpoint & {
28
+ secret: string;
29
+ };
30
+ export type Paginated<T> = {
31
+ data: T[];
32
+ pagination: {
33
+ limit: number;
34
+ offset: number;
35
+ count: number;
36
+ };
37
+ };
38
+ export type X402PaymentRequirements = {
39
+ scheme: 'exact';
40
+ network: string;
41
+ maxAmountRequired: string;
42
+ resource: string;
43
+ description: string;
44
+ mimeType: string;
45
+ payTo: string;
46
+ maxTimeoutSeconds: number;
47
+ asset: string;
48
+ extra?: {
49
+ name?: string;
50
+ version?: string;
51
+ };
52
+ };
53
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,mBAAmB,GAC3B,WAAW,GACX,YAAY,GACZ,aAAa,GACb,UAAU,GACV,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,UAAU,GACV,UAAU,CAAC;AAEf,MAAM,MAAM,eAAe,GACvB,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,MAAM,GACN,KAAK,GACL,IAAI,GACJ,QAAQ,CAAC;AAEb,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAGF,MAAM,MAAM,yBAAyB,GAAG,eAAe,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7E,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI;IACzB,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9D,CAAC;AAIF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,4 @@
1
+ // Resource types mirror the agentbank API. Kept loose (some fields
2
+ // optional) so a minor server-side addition doesn't break consumers.
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,qEAAqE"}
@@ -0,0 +1,14 @@
1
+ export declare const WEBHOOK_SIGNATURE_HEADER = "x-agentbank-signature";
2
+ export type VerifyWebhookOptions = {
3
+ toleranceSec?: number;
4
+ nowSec?: number;
5
+ };
6
+ export declare const verifyWebhook: (secret: string, rawBody: string, signatureHeader: string | undefined | null, opts?: VerifyWebhookOptions) => boolean;
7
+ export type WebhookEvent = {
8
+ id: string;
9
+ type: string;
10
+ data: Record<string, unknown>;
11
+ createdAt?: string;
12
+ };
13
+ export declare const parseVerifiedWebhook: (secret: string, rawBody: string, signatureHeader: string | undefined | null, opts?: VerifyWebhookOptions) => WebhookEvent;
14
+ //# sourceMappingURL=webhooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,wBAAwB,0BAA0B,CAAC;AAEhE,MAAM,MAAM,oBAAoB,GAAG;IAEjC,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,QAAQ,MAAM,EACd,SAAS,MAAM,EACf,iBAAiB,MAAM,GAAG,SAAS,GAAG,IAAI,EAC1C,OAAM,oBAAyB,KAC9B,OAeF,CAAC;AAIF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,MAAM,EACd,SAAS,MAAM,EACf,iBAAiB,MAAM,GAAG,SAAS,GAAG,IAAI,EAC1C,OAAM,oBAAyB,KAC9B,YAYF,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { createHmac, timingSafeEqual } from 'node:crypto';
2
+ // HMAC-SHA256 webhook signature verification (Stripe-style). The signed
3
+ // content is `${timestamp}.${rawBody}` and the header value is
4
+ // `t=<unix seconds>,v1=<hex hmac>`. Header name: `x-agentbank-signature`.
5
+ //
6
+ // Always verify against the RAW request body — DO NOT parse JSON first
7
+ // or you'll re-serialize differently and the HMAC won't match.
8
+ export const WEBHOOK_SIGNATURE_HEADER = 'x-agentbank-signature';
9
+ export const verifyWebhook = (secret, rawBody, signatureHeader, opts = {}) => {
10
+ if (!signatureHeader)
11
+ return false;
12
+ const toleranceSec = opts.toleranceSec ?? 300;
13
+ const nowSec = opts.nowSec ?? Math.floor(Date.now() / 1000);
14
+ const fields = new Map(signatureHeader.split(',').map((p) => p.split('=')));
15
+ const t = Number(fields.get('t'));
16
+ const v1 = fields.get('v1');
17
+ if (!Number.isFinite(t) || !v1)
18
+ return false;
19
+ if (Math.abs(nowSec - t) > toleranceSec)
20
+ return false;
21
+ const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
22
+ const got = Buffer.from(v1);
23
+ const want = Buffer.from(expected);
24
+ return got.length === want.length && timingSafeEqual(got, want);
25
+ };
26
+ export const parseVerifiedWebhook = (secret, rawBody, signatureHeader, opts = {}) => {
27
+ if (!verifyWebhook(secret, rawBody, signatureHeader, opts)) {
28
+ throw new Error('invalid webhook signature');
29
+ }
30
+ let event;
31
+ try {
32
+ event = JSON.parse(rawBody);
33
+ }
34
+ catch {
35
+ throw new Error('malformed webhook body');
36
+ }
37
+ if (!event.id || !event.type)
38
+ throw new Error('webhook missing id/type');
39
+ return event;
40
+ };
41
+ //# sourceMappingURL=webhooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE1D,wEAAwE;AACxE,+DAA+D;AAC/D,0EAA0E;AAC1E,EAAE;AACF,uEAAuE;AACvE,+DAA+D;AAE/D,MAAM,CAAC,MAAM,wBAAwB,GAAG,uBAAuB,CAAC;AAShE,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,MAAc,EACd,OAAe,EACf,eAA0C,EAC1C,OAA6B,EAAE,EACtB,EAAE;IACX,IAAI,CAAC,eAAe;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,GAAG,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAE5D,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC,CAAC,CAAC;IAChG,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,YAAY;QAAE,OAAO,KAAK,CAAC;IAEtD,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtF,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnC,OAAO,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAClE,CAAC,CAAC;AAWF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,MAAc,EACd,OAAe,EACf,eAA0C,EAC1C,OAA6B,EAAE,EACjB,EAAE;IAChB,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,KAAmB,CAAC;IACxB,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAiB,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACzE,OAAO,KAAK,CAAC;AACf,CAAC,CAAC"}
package/dist/x402.d.ts ADDED
@@ -0,0 +1,39 @@
1
+ import type { X402PaymentRequirements } from './types.js';
2
+ export type BuildChallengeInput = {
3
+ asset: string;
4
+ network: string;
5
+ payTo: string;
6
+ amount: string | number | bigint;
7
+ resource: string;
8
+ description?: string;
9
+ mimeType?: string;
10
+ maxTimeoutSeconds?: number;
11
+ extra?: {
12
+ name?: string;
13
+ version?: string;
14
+ };
15
+ };
16
+ export type X402ChallengeBody = {
17
+ x402Version: 1;
18
+ accepts: X402PaymentRequirements[];
19
+ error?: string;
20
+ };
21
+ export declare const buildChallenge: (input: BuildChallengeInput) => X402ChallengeBody;
22
+ export type DecodedXPayment = {
23
+ x402Version: number;
24
+ scheme: string;
25
+ network: string;
26
+ payload: {
27
+ signature: string;
28
+ authorization: {
29
+ from: string;
30
+ to: string;
31
+ value: string;
32
+ validAfter: string;
33
+ validBefore: string;
34
+ nonce: string;
35
+ };
36
+ };
37
+ };
38
+ export declare const decodeXPaymentHeader: (header: string | undefined | null) => DecodedXPayment;
39
+ //# sourceMappingURL=x402.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.d.ts","sourceRoot":"","sources":["../src/x402.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAO1D,MAAM,MAAM,mBAAmB,GAAG;IAEhC,KAAK,EAAE,MAAM,CAAC;IAEd,OAAO,EAAE,MAAM,CAAC;IAEhB,KAAK,EAAE,MAAM,CAAC;IAEd,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAEjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,EAAE,CAAC,CAAC;IACf,OAAO,EAAE,uBAAuB,EAAE,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAGF,eAAO,MAAM,cAAc,GAAI,OAAO,mBAAmB,KAAG,iBAc3D,CAAC;AAIF,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE;YACb,IAAI,EAAE,MAAM,CAAC;YACb,EAAE,EAAE,MAAM,CAAC;YACX,KAAK,EAAE,MAAM,CAAC;YACd,UAAU,EAAE,MAAM,CAAC;YACnB,WAAW,EAAE,MAAM,CAAC;YACpB,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;KACH,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,GAAG,SAAS,GAAG,IAAI,KAAG,eAmBxE,CAAC"}
package/dist/x402.js ADDED
@@ -0,0 +1,40 @@
1
+ // Build the canonical body for a 402 response.
2
+ export const buildChallenge = (input) => {
3
+ const requirements = {
4
+ scheme: 'exact',
5
+ network: input.network,
6
+ maxAmountRequired: String(input.amount),
7
+ resource: input.resource,
8
+ description: input.description ?? '',
9
+ mimeType: input.mimeType ?? 'application/json',
10
+ payTo: input.payTo,
11
+ maxTimeoutSeconds: input.maxTimeoutSeconds ?? 300,
12
+ asset: input.asset,
13
+ extra: { name: input.extra?.name ?? 'USDC', version: input.extra?.version ?? '2' },
14
+ };
15
+ return { x402Version: 1, accepts: [requirements] };
16
+ };
17
+ export const decodeXPaymentHeader = (header) => {
18
+ if (!header)
19
+ throw new Error('missing X-PAYMENT header');
20
+ let decoded;
21
+ try {
22
+ decoded = Buffer.from(header, 'base64').toString('utf8');
23
+ }
24
+ catch {
25
+ throw new Error('X-PAYMENT is not valid base64');
26
+ }
27
+ let parsed;
28
+ try {
29
+ parsed = JSON.parse(decoded);
30
+ }
31
+ catch {
32
+ throw new Error('X-PAYMENT does not decode to JSON');
33
+ }
34
+ const p = parsed;
35
+ if (!p?.payload?.signature || !p?.payload?.authorization?.from) {
36
+ throw new Error('X-PAYMENT missing payload.signature / payload.authorization');
37
+ }
38
+ return p;
39
+ };
40
+ //# sourceMappingURL=x402.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.js","sourceRoot":"","sources":["../src/x402.ts"],"names":[],"mappings":"AA+BA,+CAA+C;AAC/C,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAA0B,EAAqB,EAAE;IAC9E,MAAM,YAAY,GAA4B;QAC5C,MAAM,EAAE,OAAO;QACf,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,iBAAiB,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;QACvC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE;QACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,kBAAkB;QAC9C,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,IAAI,GAAG;QACjD,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,IAAI,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,IAAI,GAAG,EAAE;KACnF,CAAC;IACF,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC;AACrD,CAAC,CAAC;AAqBF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAiC,EAAmB,EAAE;IACzF,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACzD,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IACD,MAAM,CAAC,GAAG,MAAyB,CAAC;IACpC,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@curless/agentbank-merchant-sdk",
3
+ "version": "0.0.1",
4
+ "description": "Merchant-side SDK for agentbank — accept agent payments: PaymentIntents, webhook verification, x402 challenge helpers.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": ["dist", "README.md"],
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "typecheck": "tsc --noEmit",
19
+ "test": "vitest run",
20
+ "clean": "rm -rf dist",
21
+ "prepublishOnly": "npm run build"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^22.10.1",
25
+ "typescript": "^5.6.3",
26
+ "vitest": "^2.1.9"
27
+ },
28
+ "engines": {
29
+ "node": ">=18"
30
+ },
31
+ "keywords": ["agentbank", "curless", "agent", "payments", "merchant", "x402", "webhook"]
32
+ }