@genesis-tech/genesispay-seller 0.13.1 → 0.13.2

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 (70) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/checkout-return.d.ts +41 -0
  3. package/dist/checkout-return.d.ts.map +1 -0
  4. package/dist/checkout-return.js +67 -0
  5. package/dist/checkout-return.js.map +1 -0
  6. package/dist/client.d.ts +283 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +629 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/customers.d.ts +41 -0
  11. package/dist/customers.d.ts.map +1 -0
  12. package/dist/customers.js +76 -0
  13. package/dist/customers.js.map +1 -0
  14. package/dist/entitlements.d.ts +19 -0
  15. package/dist/entitlements.d.ts.map +1 -0
  16. package/dist/entitlements.js +30 -0
  17. package/dist/entitlements.js.map +1 -0
  18. package/dist/errors.d.ts +63 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +162 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/genesispay-settlement.d.ts +30 -0
  23. package/dist/genesispay-settlement.d.ts.map +1 -0
  24. package/dist/genesispay-settlement.js +103 -0
  25. package/dist/genesispay-settlement.js.map +1 -0
  26. package/dist/index.d.ts +16 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +18 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/invoices.d.ts +80 -0
  31. package/dist/invoices.d.ts.map +1 -0
  32. package/dist/invoices.js +133 -0
  33. package/dist/invoices.js.map +1 -0
  34. package/dist/mandate-gate.d.ts +49 -0
  35. package/dist/mandate-gate.d.ts.map +1 -0
  36. package/dist/mandate-gate.js +109 -0
  37. package/dist/mandate-gate.js.map +1 -0
  38. package/dist/mandates.d.ts +172 -0
  39. package/dist/mandates.d.ts.map +1 -0
  40. package/dist/mandates.js +213 -0
  41. package/dist/mandates.js.map +1 -0
  42. package/dist/networks.d.ts +10 -0
  43. package/dist/networks.d.ts.map +1 -0
  44. package/dist/networks.js +22 -0
  45. package/dist/networks.js.map +1 -0
  46. package/dist/payment-gate.d.ts +67 -0
  47. package/dist/payment-gate.d.ts.map +1 -0
  48. package/dist/payment-gate.js +106 -0
  49. package/dist/payment-gate.js.map +1 -0
  50. package/dist/plans.d.ts +68 -0
  51. package/dist/plans.d.ts.map +1 -0
  52. package/dist/plans.js +127 -0
  53. package/dist/plans.js.map +1 -0
  54. package/dist/products.d.ts +146 -0
  55. package/dist/products.d.ts.map +1 -0
  56. package/dist/products.js +295 -0
  57. package/dist/products.js.map +1 -0
  58. package/dist/resource.d.ts +47 -0
  59. package/dist/resource.d.ts.map +1 -0
  60. package/dist/resource.js +71 -0
  61. package/dist/resource.js.map +1 -0
  62. package/dist/usdc-amount.d.ts +7 -0
  63. package/dist/usdc-amount.d.ts.map +1 -0
  64. package/dist/usdc-amount.js +21 -0
  65. package/dist/usdc-amount.js.map +1 -0
  66. package/dist/webhooks.d.ts +277 -0
  67. package/dist/webhooks.d.ts.map +1 -0
  68. package/dist/webhooks.js +224 -0
  69. package/dist/webhooks.js.map +1 -0
  70. package/package.json +2 -1
@@ -0,0 +1,80 @@
1
+ import { type Customer } from "./customers.js";
2
+ import { type GenesisPayRequest } from "./resource.js";
3
+ export type InvoiceStatus = "draft" | "open" | "past_due" | "paid" | "void" | "uncollectible";
4
+ export type InvoiceLineInput = {
5
+ description: string;
6
+ quantity: number;
7
+ /** Decimal amount in the invoice asset, as a string with up to 6 decimals. */
8
+ unitAmount: string;
9
+ };
10
+ export type InvoiceDraftInput = {
11
+ customerId: string;
12
+ asset?: "USDC" | "EURC";
13
+ /** ISO-8601 timestamp with an offset. */
14
+ dueAt: string;
15
+ discountBps?: number;
16
+ taxBps?: number;
17
+ memo?: string;
18
+ footer?: string;
19
+ lineItems: InvoiceLineInput[];
20
+ };
21
+ export type Invoice = {
22
+ id: string;
23
+ publicId: string;
24
+ invoiceNumber: string | null;
25
+ status: InvoiceStatus;
26
+ asset: "USDC" | "EURC";
27
+ chainId: number;
28
+ customer: Customer;
29
+ lineItems: Array<{
30
+ id: string;
31
+ position: number;
32
+ description: string;
33
+ quantity: number;
34
+ unitAmountMinor: string;
35
+ amountMinor: string;
36
+ }>;
37
+ subtotalMinor: string;
38
+ discountBps: number;
39
+ discountMinor: string;
40
+ taxBps: number;
41
+ taxMinor: string;
42
+ totalMinor: string;
43
+ memo: string | null;
44
+ footer: string | null;
45
+ dueAt: string;
46
+ createdAt: string;
47
+ updatedAt: string;
48
+ finalizedAt: string | null;
49
+ paidAt: string | null;
50
+ voidedAt: string | null;
51
+ uncollectibleAt: string | null;
52
+ hostedInvoiceUrl: string | null;
53
+ pdfUrl: string | null;
54
+ payment: {
55
+ payUrl: string | null;
56
+ txHash: string | null;
57
+ payerWallet: string | null;
58
+ };
59
+ };
60
+ export type InvoiceEmailDelivery = {
61
+ id: string;
62
+ status: "sent";
63
+ providerMessageId: string | null;
64
+ sentAt: string | null;
65
+ };
66
+ export interface InvoicesResource {
67
+ create(input: InvoiceDraftInput): Promise<Invoice>;
68
+ list(): Promise<Invoice[]>;
69
+ retrieve(publicId: string): Promise<Invoice>;
70
+ update(publicId: string, input: InvoiceDraftInput): Promise<Invoice>;
71
+ finalize(publicId: string): Promise<Invoice>;
72
+ send(publicId: string, options: {
73
+ idempotencyKey: string;
74
+ }): Promise<InvoiceEmailDelivery>;
75
+ void(publicId: string): Promise<Invoice>;
76
+ markUncollectible(publicId: string): Promise<Invoice>;
77
+ }
78
+ export declare function createInvoicesResource(request: GenesisPayRequest): InvoicesResource;
79
+ export declare function toInvoice(raw: Record<string, unknown>): Invoice;
80
+ //# sourceMappingURL=invoices.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoices.d.ts","sourceRoot":"","sources":["../src/invoices.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ // `genesispay.invoices.*` — one-off invoice lifecycle over `/api/v1/invoices`.
2
+ import { GenesisPayConfigError } from "./errors.js";
3
+ import { toCustomer } from "./customers.js";
4
+ import { asRecord, oneOf, optionalString, requiredString, toAmountString, toCount, } from "./resource.js";
5
+ export function createInvoicesResource(request) {
6
+ return {
7
+ create: async (input) => invoiceRequest(request, "POST", "/api/v1/invoices", input, "create an invoice"),
8
+ list: async () => {
9
+ const body = await request({
10
+ path: "/api/v1/invoices",
11
+ operation: "GET /api/v1/invoices",
12
+ action: "list invoices",
13
+ });
14
+ const rows = asRecord(body)?.invoices;
15
+ if (!Array.isArray(rows)) {
16
+ throw new GenesisPayConfigError(`GenesisPay GET /api/v1/invoices returned no invoices array: ${JSON.stringify(body)}`);
17
+ }
18
+ return rows
19
+ .map(asRecord)
20
+ .filter((row) => Boolean(row?.publicId))
21
+ .map(toInvoice);
22
+ },
23
+ retrieve: async (publicId) => {
24
+ const id = requirePublicId(publicId, "invoices.retrieve");
25
+ return invoiceRequest(request, "GET", `/api/v1/invoices/${encodeURIComponent(id)}`, undefined, `retrieve invoice "${id}"`);
26
+ },
27
+ update: async (publicId, input) => {
28
+ const id = requirePublicId(publicId, "invoices.update");
29
+ return invoiceRequest(request, "PATCH", `/api/v1/invoices/${encodeURIComponent(id)}`, input, `update invoice "${id}"`);
30
+ },
31
+ finalize: async (publicId) => transition(request, publicId, "finalize", "finalize an invoice"),
32
+ void: async (publicId) => transition(request, publicId, "void", "void an invoice"),
33
+ markUncollectible: async (publicId) => transition(request, publicId, "mark-uncollectible", "mark an invoice uncollectible"),
34
+ send: async (publicId, options) => {
35
+ const id = requirePublicId(publicId, "invoices.send");
36
+ const idempotencyKey = options?.idempotencyKey?.trim();
37
+ if (!idempotencyKey) {
38
+ throw new GenesisPayConfigError("invoices.send requires a non-empty idempotencyKey.");
39
+ }
40
+ const path = `/api/v1/invoices/${encodeURIComponent(id)}/send`;
41
+ const response = await request({
42
+ method: "POST",
43
+ path,
44
+ operation: `POST ${path}`,
45
+ action: `send invoice "${id}"`,
46
+ headers: { "idempotency-key": idempotencyKey },
47
+ });
48
+ const delivery = asRecord(asRecord(response)?.delivery);
49
+ if (!delivery?.id) {
50
+ throw new GenesisPayConfigError(`GenesisPay POST ${path} returned no delivery: ${JSON.stringify(response)}`);
51
+ }
52
+ return {
53
+ id: requiredString(delivery.id),
54
+ status: "sent",
55
+ providerMessageId: optionalString(delivery.providerMessageId),
56
+ sentAt: optionalString(delivery.sentAt),
57
+ };
58
+ },
59
+ };
60
+ }
61
+ async function transition(request, publicId, transitionName, action) {
62
+ const id = requirePublicId(publicId, `invoices.${transitionName}`);
63
+ return invoiceRequest(request, "POST", `/api/v1/invoices/${encodeURIComponent(id)}/${transitionName}`, undefined, action);
64
+ }
65
+ async function invoiceRequest(request, method, path, body, action) {
66
+ const response = await request({
67
+ method,
68
+ path,
69
+ operation: `${method} ${path}`,
70
+ action,
71
+ ...(body === undefined ? {} : { body }),
72
+ });
73
+ const raw = asRecord(asRecord(response)?.invoice);
74
+ if (!raw?.publicId) {
75
+ throw new GenesisPayConfigError(`GenesisPay ${method} ${path} returned no invoice: ${JSON.stringify(response)}`);
76
+ }
77
+ return toInvoice(raw);
78
+ }
79
+ function requirePublicId(publicId, method) {
80
+ const id = publicId?.trim();
81
+ if (!id) {
82
+ throw new GenesisPayConfigError(`${method}(publicId) requires the publicId returned by invoices.create().`);
83
+ }
84
+ return id;
85
+ }
86
+ export function toInvoice(raw) {
87
+ const customer = asRecord(raw.customer) ?? {};
88
+ const payment = asRecord(raw.payment) ?? {};
89
+ const lines = Array.isArray(raw.lineItems) ? raw.lineItems : [];
90
+ return {
91
+ id: requiredString(raw.id),
92
+ publicId: requiredString(raw.publicId),
93
+ invoiceNumber: optionalString(raw.invoiceNumber),
94
+ status: oneOf(raw.status, ["draft", "open", "past_due", "paid", "void", "uncollectible"], "draft"),
95
+ asset: oneOf(raw.asset, ["USDC", "EURC"], "USDC"),
96
+ chainId: toCount(raw.chainId),
97
+ customer: toCustomer(customer),
98
+ lineItems: lines
99
+ .map(asRecord)
100
+ .filter((line) => Boolean(line?.id))
101
+ .map((line) => ({
102
+ id: requiredString(line.id),
103
+ position: toCount(line.position),
104
+ description: requiredString(line.description),
105
+ quantity: toCount(line.quantity),
106
+ unitAmountMinor: toAmountString(line.unitAmountMinor),
107
+ amountMinor: toAmountString(line.amountMinor),
108
+ })),
109
+ subtotalMinor: toAmountString(raw.subtotalMinor),
110
+ discountBps: toCount(raw.discountBps),
111
+ discountMinor: toAmountString(raw.discountMinor),
112
+ taxBps: toCount(raw.taxBps),
113
+ taxMinor: toAmountString(raw.taxMinor),
114
+ totalMinor: toAmountString(raw.totalMinor),
115
+ memo: optionalString(raw.memo),
116
+ footer: optionalString(raw.footer),
117
+ dueAt: requiredString(raw.dueAt),
118
+ createdAt: requiredString(raw.createdAt),
119
+ updatedAt: requiredString(raw.updatedAt),
120
+ finalizedAt: optionalString(raw.finalizedAt),
121
+ paidAt: optionalString(raw.paidAt),
122
+ voidedAt: optionalString(raw.voidedAt),
123
+ uncollectibleAt: optionalString(raw.uncollectibleAt),
124
+ hostedInvoiceUrl: optionalString(raw.hostedInvoiceUrl),
125
+ pdfUrl: optionalString(raw.pdfUrl),
126
+ payment: {
127
+ payUrl: optionalString(payment.payUrl),
128
+ txHash: optionalString(payment.txHash),
129
+ payerWallet: optionalString(payment.payerWallet),
130
+ },
131
+ };
132
+ }
133
+ //# sourceMappingURL=invoices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoices.js","sourceRoot":"","sources":["../src/invoices.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Mandate gate — the signature-free metered path for humans and subscriptions.
3
+ *
4
+ * Instead of demanding a fresh signed payment per request (the x402 gate), the
5
+ * caller presents a standing payment mandate id via the `GENESISPAY-MANDATE`
6
+ * header. The gate debits the mandate through GenesisPay
7
+ * (`POST /api/v1/mandates/:id/charge`) — a non-custodial on-chain pull from
8
+ * the payer's wallet directly to yours — and only runs your handler once the
9
+ * charge settled. Combine with `createPaymentGate` to accept both per-call
10
+ * x402 payments and mandate-metered calls on one endpoint.
11
+ */
12
+ export declare const MANDATE_HEADER = "GENESISPAY-MANDATE";
13
+ export type MandateGateOptions = {
14
+ /** Decimal charge per request, e.g. "0.08". */
15
+ amount: string;
16
+ /** Base URL of the GenesisPay app (your GENESISPAY_BASE_URL). */
17
+ baseUrl: string;
18
+ /** GenesisPay seller API key ("gp_sk_..."). */
19
+ apiKey: string;
20
+ /** Description attached to each charge (shows up in activity/usage). */
21
+ description?: string;
22
+ /** Override for testing; defaults to global fetch. */
23
+ fetchFn?: typeof fetch;
24
+ };
25
+ export type MandateChargeOutcome = {
26
+ ok: true;
27
+ charge: {
28
+ id: string;
29
+ amountMinor: string;
30
+ txHash: string;
31
+ };
32
+ } | {
33
+ ok: false;
34
+ status: number;
35
+ code?: string;
36
+ error: string;
37
+ };
38
+ export type MandateGate = {
39
+ /** Charges the mandate once. Exposed for custom flows. */
40
+ charge: (mandateId: string, resourceUrl?: string) => Promise<MandateChargeOutcome>;
41
+ /**
42
+ * Wraps a fetch-style handler: requests carrying a valid `GENESISPAY-MANDATE`
43
+ * header are charged and passed through; requests without one get a 402
44
+ * JSON body explaining how to attach a mandate.
45
+ */
46
+ wrap: (handler: (request: Request) => Response | Promise<Response>) => (request: Request) => Promise<Response>;
47
+ };
48
+ export declare function createMandateGate(options: MandateGateOptions): MandateGate;
49
+ //# sourceMappingURL=mandate-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mandate-gate.d.ts","sourceRoot":"","sources":["../src/mandate-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAEnD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAC5B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7D,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,MAAM,MAAM,WAAW,GAAG;IACxB,0DAA0D;IAC1D,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACnF;;;;OAIG;IACH,IAAI,EAAE,CACJ,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,KACxD,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC9C,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAsH1E"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Mandate gate — the signature-free metered path for humans and subscriptions.
3
+ *
4
+ * Instead of demanding a fresh signed payment per request (the x402 gate), the
5
+ * caller presents a standing payment mandate id via the `GENESISPAY-MANDATE`
6
+ * header. The gate debits the mandate through GenesisPay
7
+ * (`POST /api/v1/mandates/:id/charge`) — a non-custodial on-chain pull from
8
+ * the payer's wallet directly to yours — and only runs your handler once the
9
+ * charge settled. Combine with `createPaymentGate` to accept both per-call
10
+ * x402 payments and mandate-metered calls on one endpoint.
11
+ */
12
+ export const MANDATE_HEADER = "GENESISPAY-MANDATE";
13
+ export function createMandateGate(options) {
14
+ const apiKey = options.apiKey?.trim();
15
+ if (!apiKey) {
16
+ throw new Error("createMandateGate requires a GenesisPay seller API key (gp_sk_...).");
17
+ }
18
+ const baseUrl = options.baseUrl?.trim().replace(/\/+$/, "");
19
+ if (!baseUrl) {
20
+ throw new Error("createMandateGate requires the GenesisPay base URL.");
21
+ }
22
+ if (!/^\d+(\.\d{1,6})?$/.test(options.amount)) {
23
+ throw new Error("createMandateGate requires a decimal amount with up to 6 decimals, e.g. \"0.08\".");
24
+ }
25
+ const fetchFn = options.fetchFn ?? fetch;
26
+ async function charge(mandateId, resourceUrl) {
27
+ let response;
28
+ try {
29
+ response = await fetchFn(`${baseUrl}/api/v1/mandates/${encodeURIComponent(mandateId)}/charge`, {
30
+ method: "POST",
31
+ headers: {
32
+ "Content-Type": "application/json",
33
+ Authorization: `Bearer ${apiKey}`,
34
+ },
35
+ body: JSON.stringify({
36
+ amount: options.amount,
37
+ resourceUrl,
38
+ description: options.description,
39
+ }),
40
+ });
41
+ }
42
+ catch (error) {
43
+ return {
44
+ ok: false,
45
+ status: 503,
46
+ error: `GenesisPay is unreachable: ${error instanceof Error ? error.message : String(error)}`,
47
+ };
48
+ }
49
+ let body = null;
50
+ try {
51
+ body = await response.json();
52
+ }
53
+ catch {
54
+ // Non-JSON error body; fall through with a generic message.
55
+ }
56
+ const record = (body ?? {});
57
+ if (!response.ok) {
58
+ return {
59
+ ok: false,
60
+ status: response.status,
61
+ code: typeof record.code === "string" ? record.code : undefined,
62
+ error: typeof record.error === "string"
63
+ ? record.error
64
+ : `GenesisPay rejected the mandate charge (${response.status}).`,
65
+ };
66
+ }
67
+ const chargeRecord = (record.charge ?? {});
68
+ return {
69
+ ok: true,
70
+ charge: {
71
+ id: String(chargeRecord.id ?? ""),
72
+ amountMinor: String(chargeRecord.amountMinor ?? ""),
73
+ txHash: String(chargeRecord.txHash ?? ""),
74
+ },
75
+ };
76
+ }
77
+ function wrap(handler) {
78
+ return async (request) => {
79
+ const mandateId = request.headers.get(MANDATE_HEADER)?.trim();
80
+ if (!mandateId) {
81
+ return jsonResponse({
82
+ error: "Payment required.",
83
+ howToPay: `Attach an active GenesisPay mandate id via the ${MANDATE_HEADER} header, or pay per call via x402.`,
84
+ amount: options.amount,
85
+ }, 402);
86
+ }
87
+ const outcome = await charge(mandateId, request.url);
88
+ if (!outcome.ok) {
89
+ return jsonResponse({ error: outcome.error, code: outcome.code }, outcome.status === 403 || outcome.status === 404 ? outcome.status : 402);
90
+ }
91
+ const response = await handler(request);
92
+ const headers = new Headers(response.headers);
93
+ headers.set("GENESISPAY-MANDATE-CHARGE", outcome.charge.id);
94
+ return new Response(response.body, {
95
+ status: response.status,
96
+ statusText: response.statusText,
97
+ headers,
98
+ });
99
+ };
100
+ }
101
+ return { charge, wrap };
102
+ }
103
+ function jsonResponse(body, status) {
104
+ return new Response(JSON.stringify(body), {
105
+ status,
106
+ headers: { "Content-Type": "application/json" },
107
+ });
108
+ }
109
+ //# sourceMappingURL=mandate-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mandate-gate.js","sourceRoot":"","sources":["../src/mandate-gate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,172 @@
1
+ import { type GenesisPayRequest } from "./resource.js";
2
+ export type MandateKind = "per_use" | "subscription";
3
+ export type MandateStatus = "pending_permit" | "active" | "past_due" | "revoked" | "expired";
4
+ export type MandateChargeStatus = "pending" | "settled" | "failed";
5
+ export type Mandate = {
6
+ id: string;
7
+ kind: MandateKind;
8
+ status: MandateStatus;
9
+ asset: "USDC" | "EURC";
10
+ chainId: number;
11
+ payerWallet: string;
12
+ destinationWallet: string;
13
+ /**
14
+ * The subscription plan this mandate was signed from, or `null` when it was
15
+ * proposed directly via `mandates.create` — that path has no plan, and one
16
+ * supplied by the caller would let a mandate be attributed to a foreign plan.
17
+ * `null` is a valid state, not a missing value; older mandates have it too.
18
+ */
19
+ subscriptionPlanId: string | null;
20
+ /** Total approved spend, in 6-decimal minor units (string — no precision loss). */
21
+ allowanceMinor: string;
22
+ /** Ceiling for any single charge, in minor units. */
23
+ capPerChargeMinor: string;
24
+ spentMinor: string;
25
+ /** `allowanceMinor - spentMinor`, as the server computes it. */
26
+ remainingMinor: string;
27
+ /** Subscription mandates only; null for `per_use`. */
28
+ amountPerPeriodMinor: string | null;
29
+ /** Subscription mandates only; null for `per_use`. */
30
+ periodDays: number | null;
31
+ nextChargeAt: string | null;
32
+ /** After this the unsubmitted permit is dead and the mandate needs re-signing. */
33
+ permitDeadline: string;
34
+ permitTxHash: string | null;
35
+ createdAt: string;
36
+ /** Set when the payer's signature was submitted — until then the mandate is inert. */
37
+ activatedAt: string | null;
38
+ revokedAt: string | null;
39
+ };
40
+ /**
41
+ * The EIP-712 payload the payer's wallet signs (`eth_signTypedData_v4`).
42
+ *
43
+ * Passed through **verbatim** from the server rather than remapped: a signature
44
+ * covers the exact bytes of this structure, so normalizing a field would
45
+ * produce a signature over something other than what the contract verifies.
46
+ */
47
+ export type PermitTypedData = {
48
+ domain: {
49
+ name: string;
50
+ version: string;
51
+ chainId: number;
52
+ verifyingContract: string;
53
+ };
54
+ types: Record<string, ReadonlyArray<{
55
+ name: string;
56
+ type: string;
57
+ }>>;
58
+ primaryType: string;
59
+ message: {
60
+ owner: string;
61
+ spender: string;
62
+ value: string;
63
+ nonce: string;
64
+ deadline: string;
65
+ };
66
+ };
67
+ export type MandateCreateInput = {
68
+ payerWallet: string;
69
+ kind: MandateKind;
70
+ /** Total spending approval as a decimal amount, e.g. "20". */
71
+ allowance: string;
72
+ /** Ceiling for a single charge as a decimal amount, e.g. "0.10". */
73
+ capPerCharge: string;
74
+ /** Required for `kind: "subscription"`. Decimal amount, e.g. "9". */
75
+ amountPerPeriod?: string;
76
+ /** Required for `kind: "subscription"`. Whole days, e.g. 30. */
77
+ periodDays?: number;
78
+ /** Defaults to USDC. */
79
+ asset?: "USDC" | "EURC";
80
+ /** Defaults to the account's receiving wallet. */
81
+ destinationWallet?: string;
82
+ };
83
+ export type MandateCreateResult = {
84
+ mandate: Mandate;
85
+ /** Give this to the payer's wallet to sign; then activate from the frontend. */
86
+ permitTypedData: PermitTypedData;
87
+ /** The facilitator address the permit approves as spender. */
88
+ spender: string;
89
+ };
90
+ export type MandateChargeInput = {
91
+ /** Decimal amount, e.g. "0.08". Must not exceed the mandate's cap per charge. */
92
+ amount: string;
93
+ /** What was paid for — surfaced to the payer in their mandate history. */
94
+ resourceUrl?: string;
95
+ description?: string;
96
+ };
97
+ export type MandateCharge = {
98
+ id: string;
99
+ status: MandateChargeStatus;
100
+ amountMinor: string;
101
+ /** Null while the pull is still pending, and for a failed charge. */
102
+ txHash: string | null;
103
+ };
104
+ export type MandateListOptions = {
105
+ /**
106
+ * A plan's **public** id (`plan.publicId`) — the identifier the routes take —
107
+ * not the internal uuid. An unknown or foreign plan id matches nothing and
108
+ * yields an empty page rather than an error, so it cannot be used to probe
109
+ * which plans exist.
110
+ */
111
+ planId?: string;
112
+ status?: MandateStatus;
113
+ /** 1–100. The server defaults to 25 when omitted. */
114
+ limit?: number;
115
+ /** Id of the **last** mandate of the previous page — see `list`. */
116
+ startingAfter?: string;
117
+ };
118
+ export type MandateListPage = {
119
+ /** Newest first (`createdAt` descending), at most `limit` entries. */
120
+ mandates: Mandate[];
121
+ /** True when another page exists behind this one. */
122
+ hasMore: boolean;
123
+ };
124
+ export interface MandatesResource {
125
+ /**
126
+ * Proposes a mandate. The returned mandate is inert (`pending_permit`) until
127
+ * the payer signs `permitTypedData` and that signature is submitted from the
128
+ * payer's frontend — see the note at the top of this module on `activate`.
129
+ */
130
+ create(input: MandateCreateInput): Promise<MandateCreateResult>;
131
+ /**
132
+ * One page of this account's mandates, newest first.
133
+ *
134
+ * This is how you find a mandate id without having kept the `mandate.active`
135
+ * webhook: a customer who wants to cancel can be served by listing, matching
136
+ * on `payerWallet` (or `subscriptionPlanId`), and calling `revoke`.
137
+ *
138
+ * **Paging is keyset-based**, so pass the id of the *last* mandate you
139
+ * received as `startingAfter` and repeat while `hasMore` is true:
140
+ *
141
+ * ```ts
142
+ * const all: Mandate[] = [];
143
+ * let startingAfter: string | undefined;
144
+ * for (;;) {
145
+ * const page = await genesispay.mandates.list({
146
+ * planId: "plan_1",
147
+ * status: "active",
148
+ * limit: 100,
149
+ * startingAfter,
150
+ * });
151
+ * all.push(...page.mandates);
152
+ * if (!page.hasMore) break;
153
+ * startingAfter = page.mandates[page.mandates.length - 1]!.id;
154
+ * }
155
+ * ```
156
+ *
157
+ * Do **not** pass the id of an arbitrary mandate: the cursor is a position in
158
+ * `(createdAt desc, id desc)`, not a filter. A `startingAfter` that names no
159
+ * mandate of this account is refused by the server (as a `GenesisPayConfigError`
160
+ * — it carries no field-level detail to raise as a validation error).
161
+ */
162
+ list(opts?: MandateListOptions): Promise<MandateListPage>;
163
+ /** Entitlement check: is it active, and how much approval is left? */
164
+ retrieve(id: string): Promise<Mandate>;
165
+ /** Pulls a single charge. Signature-free — this is the metered path. */
166
+ charge(id: string, input: MandateChargeInput): Promise<MandateCharge>;
167
+ /** Stops all future charges. Already-settled charges are unaffected. */
168
+ revoke(id: string): Promise<Mandate>;
169
+ }
170
+ export declare function createMandatesResource(request: GenesisPayRequest): MandatesResource;
171
+ export declare function toMandate(raw: Record<string, unknown>): Mandate;
172
+ //# sourceMappingURL=mandates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mandates.d.ts","sourceRoot":"","sources":["../src/mandates.ts"],"names":[],"mappings":"AAgBA,OAAO,EASL,KAAK,iBAAiB,EACvB,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,cAAc,CAAC;AAErD,MAAM,MAAM,aAAa,GACrB,gBAAgB,GAChB,QAAQ,GACR,UAAU,GACV,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEnE,MAAM,MAAM,OAAO,GAAG;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,mFAAmF;IACnF,cAAc,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,cAAc,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,sDAAsD;IACtD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,kFAAkF;IAClF,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;IAClB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,kDAAkD;IAClD,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,gFAAgF;IAChF,eAAe,EAAE,eAAe,CAAC;IACjC,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,mBAAmB,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,sEAAsE;IACtE,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAChE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,IAAI,CAAC,IAAI,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC1D,sEAAsE;IACtE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,wEAAwE;IACxE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACtE,wEAAwE;IACxE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtC;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAmKnF;AAyCD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CA8B/D"}