@sweepconsole/node 0.1.1 → 0.2.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 CHANGED
@@ -91,7 +91,7 @@ app.post("/subscribe/usdc", async (req, res) => {
91
91
  email: req.user.email,
92
92
  maxAmount: usdc("15.00"), // the CEILING, not the price
93
93
  interval: "monthly",
94
- chains: ["base", "arbitrum", "optimism"],
94
+ chains: ["base", "arbitrum", "optimism"], // what to OFFER — they pick
95
95
  expiresAt: new Date("2027-01-01"),
96
96
  returnUrl: "https://shop.example.com/thanks",
97
97
  });
@@ -101,6 +101,11 @@ app.post("/subscribe/usdc", async (req, res) => {
101
101
  });
102
102
  ```
103
103
 
104
+ The payer chooses which of those chains to sign, so `chains` is a maximum rather
105
+ than a promise. What they actually granted comes back as `mandate.grantedChains`,
106
+ and on the `mandate.authorized` event as `chain_ids`. Charge against those — a
107
+ mandate offered on three chains is often live on one.
108
+
104
109
  **2 — react to what happens**
105
110
 
106
111
  ```ts
package/dist/client.js CHANGED
@@ -247,6 +247,7 @@ function toMandate(raw) {
247
247
  interval: raw.interval,
248
248
  periodDuration: raw.period_duration,
249
249
  chains: raw.chains ?? [],
250
+ grantedChains: raw.granted_chains ?? [],
250
251
  testMode: !!raw.test_mode,
251
252
  expiresAt: date(raw.expires_at),
252
253
  authorizationUrl: raw.authorization_url ?? null,
package/dist/types.d.ts CHANGED
@@ -33,7 +33,22 @@ export interface Mandate {
33
33
  currency: "USDC";
34
34
  interval: Interval;
35
35
  periodDuration: number;
36
+ /**
37
+ * The chains you OFFERED when you created the mandate.
38
+ *
39
+ * Not what the payer granted. The authorization page lets them choose which
40
+ * of these to sign, so a mandate offered on three chains can be live on one
41
+ * — and this still reads three. Charge against `grantedChains`.
42
+ */
36
43
  chains: string[];
44
+ /**
45
+ * The chains the payer actually signed, and what a charge can draw from.
46
+ *
47
+ * Empty while the mandate is pending. It shrinks if they later disable a
48
+ * chain in their own wallet, which is the same set `grant.revoked` reports
49
+ * as `remaining_chains`.
50
+ */
51
+ grantedChains: string[];
37
52
  testMode: boolean;
38
53
  /** When the authorization stops being redeemable. */
39
54
  expiresAt: Date;
@@ -78,6 +93,12 @@ export interface CreateMandateParams {
78
93
  /** The ceiling per interval — NOT the price. Give it headroom. */
79
94
  maxAmount: Usdc;
80
95
  interval: Interval;
96
+ /**
97
+ * The chains to OFFER the payer. They choose which to sign, so this is a
98
+ * maximum, not a promise — read `grantedChains` back to see what you got.
99
+ * More chains means more ways for a charge to succeed, so offer all you
100
+ * support unless you have a reason not to.
101
+ */
81
102
  chains: Chain[];
82
103
  expiresAt: Date;
83
104
  returnUrl?: string;
@@ -172,7 +193,7 @@ export interface RetrievedSession {
172
193
  expiresAt: Date;
173
194
  createdAt: Date;
174
195
  }
175
- export type WebhookEventType = "checkout.session.completed" | "subscription.created" | "subscription.renewed" | "subscription.past_due" | "subscription.cancelled" | "payment.succeeded" | "payment.failed" | "mandate.authorized" | "mandate.revoked" | "mandate.expiring" | "mandate.expired" | "charge.succeeded" | "charge.failed";
196
+ export type WebhookEventType = "checkout.session.completed" | "subscription.created" | "subscription.renewed" | "subscription.past_due" | "subscription.cancelled" | "payment.succeeded" | "payment.failed" | "mandate.authorized" | "mandate.revoked" | "grant.revoked" | "grant.added" | "mandate.expiring" | "mandate.expired" | "charge.succeeded" | "charge.failed";
176
197
  /**
177
198
  * What each event carries.
178
199
  *
@@ -299,6 +320,12 @@ export interface WebhookPayloads {
299
320
  */
300
321
  wallet_reused: boolean;
301
322
  };
323
+ /**
324
+ * The authorization is FINISHED — nothing left to charge on any chain.
325
+ *
326
+ * One chain leaving a live mandate is `grant.revoked`, not this. Acting on
327
+ * the wrong one cuts off a customer who is still paying you.
328
+ */
302
329
  "mandate.revoked": {
303
330
  mandate_id: string;
304
331
  external_ref: string;
@@ -312,6 +339,44 @@ export interface WebhookPayloads {
312
339
  * guaranteed is that Sweep Console will not redeem it again.
313
340
  */
314
341
  on_chain: boolean;
342
+ /** Always empty here — the authorization is over. */
343
+ remaining_chains: string[];
344
+ /** Always false here. Branch on this rather than on the event name. */
345
+ mandate_still_active: boolean;
346
+ };
347
+ /**
348
+ * A payer withdrew ONE chain's permission in their own wallet.
349
+ *
350
+ * The authorization survives on the rest, so this is not a reason to stop
351
+ * serving. A wallet-side withdrawal is invisible to Sweep until the daily
352
+ * reconciliation looks, so this arrives then rather than the moment they act.
353
+ */
354
+ "grant.revoked": {
355
+ mandate_id: string;
356
+ chain_id: number;
357
+ grant_id: string | null;
358
+ subscription_id: string | null;
359
+ reason: string;
360
+ /** What is still chargeable. Empty would make this a mandate.revoked. */
361
+ remaining_chains: string[];
362
+ /** True here, by definition. */
363
+ mandate_still_active: boolean;
364
+ };
365
+ /**
366
+ * A payer authorized an EXTRA chain on a live mandate.
367
+ *
368
+ * The mirror of `grant.revoked` — more ways for a charge to succeed, and
369
+ * nothing to stop. Not sent during the first authorization, where
370
+ * `mandate.authorized` already carries every chain in `chain_ids`.
371
+ */
372
+ "grant.added": {
373
+ mandate_id: string;
374
+ chain_id: number;
375
+ grant_id: string | null;
376
+ /** The whole chargeable set after the change, not just the new chain. */
377
+ granted_chains: string[];
378
+ /** True here, by definition. */
379
+ mandate_still_active: boolean;
315
380
  };
316
381
  "mandate.expiring": {
317
382
  mandate_id: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sweepconsole/node",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "Node/TypeScript client for the Sweep Console payment rail — charge a USDC wallet from your own app",
5
5
  "license": "MIT",
6
6
  "type": "module",