@pollar/core 0.7.0 → 0.7.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/dist/index.d.ts CHANGED
@@ -390,6 +390,21 @@ type RampsTransactionResponse = paths['/ramps/transaction/{txId}']['get']['respo
390
390
  type RampTxStatus = RampsTransactionResponse['status'];
391
391
  type RampDirection = RampsTransactionResponse['direction'];
392
392
  type PaymentInstructions = RampsOnrampResponse['paymentInstructions'];
393
+ type DistributionRule = paths['/distribution/rules']['get']['responses'][200]['content']['application/json']['content']['rules'][number];
394
+ type RulePeriod = DistributionRule['period'];
395
+ type DistributionClaimBody = NonNullable<paths['/distribution/claim']['post']['requestBody']>['content']['application/json'];
396
+ type DistributionClaimContent = paths['/distribution/claim']['post']['responses'][200]['content']['application/json']['content'];
397
+ type DistributionRulesState = {
398
+ step: 'idle';
399
+ } | {
400
+ step: 'loading';
401
+ } | {
402
+ step: 'loaded';
403
+ rules: DistributionRule[];
404
+ } | {
405
+ step: 'error';
406
+ message: string;
407
+ };
393
408
  type AdapterFn<TParams = unknown> = (params: TParams) => Promise<{
394
409
  unsignedTransaction: string;
395
410
  }>;
@@ -423,6 +438,13 @@ declare class PollarClient {
423
438
  private _profile;
424
439
  /** Last `DPoP-Nonce` we saw from a server response. Carried into the next proof. */
425
440
  private _dpopNonce;
441
+ /**
442
+ * Snapshot of each in-flight request's body, taken in `onRequest` before
443
+ * `fetch()` consumes the stream. Needed because `Request.clone()` throws
444
+ * once the body is disturbed, so the auto-retry path (DPoP nonce challenge
445
+ * / 401 refresh) must rebuild the request from scratch instead of cloning.
446
+ */
447
+ private _requestBodyCache;
426
448
  /** Singleton in-flight refresh — concurrent 401s coalesce into one /auth/refresh call. */
427
449
  private _refreshPromise;
428
450
  private _storageEventHandler;
@@ -544,6 +566,8 @@ declare class PollarClient {
544
566
  intervalMs?: number;
545
567
  timeoutMs?: number;
546
568
  }): Promise<RampTxStatus>;
569
+ listDistributionRules(): Promise<DistributionRule[]>;
570
+ claimDistributionRule(body: DistributionClaimBody): Promise<DistributionClaimContent>;
547
571
  private _setTxHistoryState;
548
572
  private _setWalletBalanceState;
549
573
  private _newController;
@@ -953,9 +977,18 @@ interface paths {
953
977
  trace?: never;
954
978
  };
955
979
  "/auth/logout": {
956
- parameters: { query?: never; header?: never; path?: never; cookie?: never };
980
+ parameters: {
981
+ query?: never;
982
+ header?: never;
983
+ path?: never;
984
+ cookie?: never;
985
+ };
957
986
  get?: never;
958
987
  put?: never;
988
+ /**
989
+ * Revoke the current session (or all sessions)
990
+ * @description Server-side logout. Default behavior revokes the refresh-token family bound to the current access token. Pass `{"everywhere":true}` to revoke every active family for the authenticated user (logout from all devices).
991
+ */
959
992
  post: operations["postAuthLogout"];
960
993
  delete?: never;
961
994
  options?: never;
@@ -964,7 +997,16 @@ interface paths {
964
997
  trace?: never;
965
998
  };
966
999
  "/auth/sessions": {
967
- parameters: { query?: never; header?: never; path?: never; cookie?: never };
1000
+ parameters: {
1001
+ query?: never;
1002
+ header?: never;
1003
+ path?: never;
1004
+ cookie?: never;
1005
+ };
1006
+ /**
1007
+ * List active sessions for the authenticated user
1008
+ * @description Returns one row per active refresh-token family with the metadata captured at issuance (user agent, hashed IP, optional device label). The session whose `current: true` flag matches the access token in use can be highlighted in the UI.
1009
+ */
968
1010
  get: operations["getAuthSessions"];
969
1011
  put?: never;
970
1012
  post?: never;
@@ -975,11 +1017,17 @@ interface paths {
975
1017
  trace?: never;
976
1018
  };
977
1019
  "/auth/sessions/{familyId}": {
978
- parameters: { query?: never; header?: never; path?: never; cookie?: never };
1020
+ parameters: {
1021
+ query?: never;
1022
+ header?: never;
1023
+ path?: never;
1024
+ cookie?: never;
1025
+ };
979
1026
  get?: never;
980
1027
  put?: never;
981
1028
  post?: never;
982
- delete: operations["deleteAuthSessionByFamilyId"];
1029
+ /** Revoke a specific session (refresh-token family) */
1030
+ delete: operations["deleteAuthSessionsByFamilyId"];
983
1031
  options?: never;
984
1032
  head?: never;
985
1033
  patch?: never;
@@ -1265,6 +1313,46 @@ interface paths {
1265
1313
  patch?: never;
1266
1314
  trace?: never;
1267
1315
  };
1316
+ "/distribution/rules": {
1317
+ parameters: {
1318
+ query?: never;
1319
+ header?: never;
1320
+ path?: never;
1321
+ cookie?: never;
1322
+ };
1323
+ /**
1324
+ * List distribution rules
1325
+ * @description Returns every distribution rule defined for the calling application, each decorated with a `claimable` flag and (when not claimable) a `reason` ErrorCode the SDK can map to a UI message (expired, already claimed in window, exhausted, etc.).
1326
+ */
1327
+ get: operations["getDistributionRules"];
1328
+ put?: never;
1329
+ post?: never;
1330
+ delete?: never;
1331
+ options?: never;
1332
+ head?: never;
1333
+ patch?: never;
1334
+ trace?: never;
1335
+ };
1336
+ "/distribution/claim": {
1337
+ parameters: {
1338
+ query?: never;
1339
+ header?: never;
1340
+ path?: never;
1341
+ cookie?: never;
1342
+ };
1343
+ get?: never;
1344
+ put?: never;
1345
+ /**
1346
+ * Claim a distribution rule
1347
+ * @description Executes a claim against the given rule for the authenticated sdk-user. The server runs the same claimability checks as GET /distribution/rules against fresh counts; only the txHash and amount are returned on success.
1348
+ */
1349
+ post: operations["postDistributionClaim"];
1350
+ delete?: never;
1351
+ options?: never;
1352
+ head?: never;
1353
+ patch?: never;
1354
+ trace?: never;
1355
+ };
1268
1356
  }
1269
1357
  interface operations {
1270
1358
  getHealth: {
@@ -2084,6 +2172,159 @@ interface operations {
2084
2172
  };
2085
2173
  };
2086
2174
  };
2175
+ postAuthLogout: {
2176
+ parameters: {
2177
+ query?: never;
2178
+ header?: never;
2179
+ path?: never;
2180
+ cookie?: never;
2181
+ };
2182
+ requestBody: {
2183
+ content: {
2184
+ "application/json": {
2185
+ everywhere?: boolean;
2186
+ };
2187
+ };
2188
+ };
2189
+ responses: {
2190
+ /** @description Sessions revoked */
2191
+ 200: {
2192
+ headers: {
2193
+ [name: string]: unknown;
2194
+ };
2195
+ content: {
2196
+ "application/json": {
2197
+ /** @constant */
2198
+ code: "SDK_LOGOUT_SUCCESS";
2199
+ /** @constant */
2200
+ success: true;
2201
+ content: {
2202
+ revoked: number;
2203
+ };
2204
+ };
2205
+ };
2206
+ };
2207
+ /** @description Unauthorized */
2208
+ 401: {
2209
+ headers: {
2210
+ [name: string]: unknown;
2211
+ };
2212
+ content: {
2213
+ "application/json": {
2214
+ /** @constant */
2215
+ success: false;
2216
+ error: string;
2217
+ };
2218
+ };
2219
+ };
2220
+ };
2221
+ };
2222
+ getAuthSessions: {
2223
+ parameters: {
2224
+ query?: never;
2225
+ header?: never;
2226
+ path?: never;
2227
+ cookie?: never;
2228
+ };
2229
+ requestBody?: never;
2230
+ responses: {
2231
+ /** @description Sessions list */
2232
+ 200: {
2233
+ headers: {
2234
+ [name: string]: unknown;
2235
+ };
2236
+ content: {
2237
+ "application/json": {
2238
+ /** @constant */
2239
+ code: "SDK_SESSIONS_LIST";
2240
+ /** @constant */
2241
+ success: true;
2242
+ content: {
2243
+ sessions: {
2244
+ familyId: string;
2245
+ createdAt: string;
2246
+ lastUsedAt: string | null;
2247
+ userAgent: string | null;
2248
+ ipHash: string | null;
2249
+ deviceLabel: string | null;
2250
+ current: boolean;
2251
+ expiresAt: string;
2252
+ }[];
2253
+ };
2254
+ };
2255
+ };
2256
+ };
2257
+ /** @description Unauthorized */
2258
+ 401: {
2259
+ headers: {
2260
+ [name: string]: unknown;
2261
+ };
2262
+ content: {
2263
+ "application/json": {
2264
+ /** @constant */
2265
+ success: false;
2266
+ error: string;
2267
+ };
2268
+ };
2269
+ };
2270
+ };
2271
+ };
2272
+ deleteAuthSessionsByFamilyId: {
2273
+ parameters: {
2274
+ query?: never;
2275
+ header?: never;
2276
+ path: {
2277
+ familyId: string;
2278
+ };
2279
+ cookie?: never;
2280
+ };
2281
+ requestBody?: never;
2282
+ responses: {
2283
+ /** @description Session revoked */
2284
+ 200: {
2285
+ headers: {
2286
+ [name: string]: unknown;
2287
+ };
2288
+ content: {
2289
+ "application/json": {
2290
+ /** @constant */
2291
+ code: "SDK_SESSION_REVOKED";
2292
+ /** @constant */
2293
+ success: true;
2294
+ content: {
2295
+ revoked: number;
2296
+ };
2297
+ };
2298
+ };
2299
+ };
2300
+ /** @description Unauthorized */
2301
+ 401: {
2302
+ headers: {
2303
+ [name: string]: unknown;
2304
+ };
2305
+ content: {
2306
+ "application/json": {
2307
+ /** @constant */
2308
+ success: false;
2309
+ error: string;
2310
+ };
2311
+ };
2312
+ };
2313
+ /** @description Not found */
2314
+ 404: {
2315
+ headers: {
2316
+ [name: string]: unknown;
2317
+ };
2318
+ content: {
2319
+ "application/json": {
2320
+ /** @constant */
2321
+ success: false;
2322
+ error: string;
2323
+ };
2324
+ };
2325
+ };
2326
+ };
2327
+ };
2087
2328
  getApplicationsConfig: {
2088
2329
  parameters: {
2089
2330
  query?: never;
@@ -3294,86 +3535,137 @@ interface operations {
3294
3535
  };
3295
3536
  };
3296
3537
  };
3297
- postAuthLogout: {
3298
- parameters: { query?: never; header?: never; path?: never; cookie?: never };
3299
- requestBody?: {
3300
- content: {
3301
- "application/json": {
3302
- everywhere?: boolean;
3303
- };
3304
- };
3538
+ getDistributionRules: {
3539
+ parameters: {
3540
+ query?: never;
3541
+ header?: never;
3542
+ path?: never;
3543
+ cookie?: never;
3305
3544
  };
3545
+ requestBody?: never;
3306
3546
  responses: {
3547
+ /** @description List of distribution rules with claimability verdict per rule */
3307
3548
  200: {
3308
- headers: { [name: string]: unknown };
3549
+ headers: {
3550
+ [name: string]: unknown;
3551
+ };
3309
3552
  content: {
3310
3553
  "application/json": {
3311
3554
  /** @constant */
3312
- code: "SDK_LOGOUT_SUCCESS";
3555
+ code: "SDK_DISTRIBUTION_RULES_LIST";
3313
3556
  /** @constant */
3314
3557
  success: true;
3315
3558
  content: {
3316
- revoked: number;
3559
+ rules: {
3560
+ id: string;
3561
+ name: string;
3562
+ assetCode: string;
3563
+ amount: string;
3564
+ /** @enum {string} */
3565
+ period: "DAY" | "DAY_CALENDAR" | "WEEK" | "MONTH" | "MONTH_CALENDAR" | "LIFETIME";
3566
+ validFrom: string | null;
3567
+ validUntil: string | null;
3568
+ claimable: boolean;
3569
+ reason: string | null;
3570
+ }[];
3317
3571
  };
3318
3572
  };
3319
3573
  };
3320
3574
  };
3321
- };
3322
- };
3323
- getAuthSessions: {
3324
- parameters: { query?: never; header?: never; path?: never; cookie?: never };
3325
- requestBody?: never;
3326
- responses: {
3327
- 200: {
3328
- headers: { [name: string]: unknown };
3575
+ /** @description Unauthorized */
3576
+ 401: {
3577
+ headers: {
3578
+ [name: string]: unknown;
3579
+ };
3329
3580
  content: {
3330
3581
  "application/json": {
3331
3582
  /** @constant */
3332
- code: "SDK_SESSIONS_LIST";
3333
- /** @constant */
3334
- success: true;
3335
- content: {
3336
- sessions: {
3337
- familyId: string;
3338
- createdAt: string;
3339
- lastUsedAt: string | null;
3340
- userAgent: string | null;
3341
- ipHash: string | null;
3342
- deviceLabel: string | null;
3343
- current: boolean;
3344
- expiresAt: string;
3345
- }[];
3346
- };
3583
+ success: false;
3584
+ error: string;
3347
3585
  };
3348
3586
  };
3349
3587
  };
3350
3588
  };
3351
3589
  };
3352
- deleteAuthSessionByFamilyId: {
3590
+ postDistributionClaim: {
3353
3591
  parameters: {
3354
3592
  query?: never;
3355
3593
  header?: never;
3356
- path: { familyId: string };
3594
+ path?: never;
3357
3595
  cookie?: never;
3358
3596
  };
3359
- requestBody?: never;
3597
+ requestBody: {
3598
+ content: {
3599
+ "application/json": {
3600
+ ruleId: string;
3601
+ };
3602
+ };
3603
+ };
3360
3604
  responses: {
3605
+ /** @description Claim succeeded — payment submitted to Stellar */
3361
3606
  200: {
3362
- headers: { [name: string]: unknown };
3607
+ headers: {
3608
+ [name: string]: unknown;
3609
+ };
3363
3610
  content: {
3364
3611
  "application/json": {
3365
3612
  /** @constant */
3366
- code: "SDK_SESSION_REVOKED";
3613
+ code: "SDK_DISTRIBUTION_CLAIM_OK";
3367
3614
  /** @constant */
3368
3615
  success: true;
3369
3616
  content: {
3370
- revoked: number;
3617
+ ruleId: string;
3618
+ assetCode: string;
3619
+ amount: string;
3620
+ txHash: string | null;
3371
3621
  };
3372
3622
  };
3373
3623
  };
3374
3624
  };
3625
+ /** @description Validation error */
3626
+ 400: {
3627
+ headers: {
3628
+ [name: string]: unknown;
3629
+ };
3630
+ content: {
3631
+ "application/json": {
3632
+ /** @constant */
3633
+ success: false;
3634
+ error: string;
3635
+ };
3636
+ };
3637
+ };
3638
+ /** @description Unauthorized */
3639
+ 401: {
3640
+ headers: {
3641
+ [name: string]: unknown;
3642
+ };
3643
+ content: {
3644
+ "application/json": {
3645
+ /** @constant */
3646
+ success: false;
3647
+ error: string;
3648
+ };
3649
+ };
3650
+ };
3651
+ /** @description Rule not found, user has no wallet, or application has no distribution wallet */
3375
3652
  404: {
3376
- headers: { [name: string]: unknown };
3653
+ headers: {
3654
+ [name: string]: unknown;
3655
+ };
3656
+ content: {
3657
+ "application/json": {
3658
+ /** @constant */
3659
+ success: false;
3660
+ error: string;
3661
+ };
3662
+ };
3663
+ };
3664
+ /** @description Rule not claimable (disabled, expired, exhausted, rate-limited) */
3665
+ 409: {
3666
+ headers: {
3667
+ [name: string]: unknown;
3668
+ };
3377
3669
  content: {
3378
3670
  "application/json": {
3379
3671
  /** @constant */
@@ -3468,4 +3760,18 @@ declare function pollRampTransaction(api: PollarApiClient, txId: string, { inter
3468
3760
  timeoutMs?: number;
3469
3761
  }): Promise<RampTxStatus>;
3470
3762
 
3471
- export { AUTH_ERROR_CODES, type AdapterFn, AlbedoAdapter, type AuthErrorCode, type AuthState, type BuildProofArgs, type ConnectWalletResponse, FreighterAdapter, type KeyManager, type KycFlow, type KycLevel, type KycProvider, type KycStartBody, type KycStartResponse, type KycStatus, type LocalStorageAdapterOptions, type NetworkState, OnStorageDegrade, type PaymentInstructions, type PollarAdapter, type PollarAdapters, type PollarApiClient, type PollarApplicationConfigContent, type PollarApplicationConfigResponse, PollarClient, type PollarClientConfig, PollarFlowError, type PollarLoginOptions, type PollarPersistedSession, type PollarUserProfile, type PublicEcJwk, type RampDirection, type RampQuote, type RampTxStatus, type RampsOfframpBody, type RampsOfframpResponse, type RampsOnrampBody, type RampsOnrampResponse, type RampsQuoteQuery, type RampsQuoteResponse, type RampsTransactionResponse, type SessionInfo, type SignAuthEntryOptions, type SignAuthEntryResponse, type SignTransactionOptions, type SignTransactionResponse, type StellarBalance, StellarClient, type StellarClientConfig, type StellarNetwork, Storage, type TransactionState, type TxBuildBody, type TxBuildContent, type TxBuildResponse, type TxHistoryContent, type TxHistoryParams, type TxHistoryRecord, type TxHistoryState, type TxSignAndSendBody, type TxSignSendResponse, type WalletAdapter, type WalletAdapterResolver, type WalletBalanceContent, type WalletBalanceRecord, type WalletBalanceState, type WalletId, WalletType, WebCryptoKeyManager, buildProof, canonicalEcJwk, computeJwkThumbprint, createLocalStorageAdapter, createMemoryAdapter, createOffRamp, createOnRamp, defaultKeyManager, defaultStorage, getKycProviders, getKycStatus, getRampTransaction, getRampsQuote, isValidSession, normalizeHtu, pollKycStatus, pollRampTransaction, type paths as pollarPaths, resolveKyc, startKyc };
3763
+ /**
3764
+ * GET /distribution/rules
3765
+ * Returns the distribution rules visible to the calling sdk-user, each
3766
+ * decorated with `claimable` and (when not claimable) a `reason` ErrorCode
3767
+ * the UI maps to a friendly message.
3768
+ */
3769
+ declare function listDistributionRules(api: PollarApiClient): Promise<DistributionRule[]>;
3770
+ /**
3771
+ * POST /distribution/claim
3772
+ * Claims the given rule for the authenticated sdk-user. Returns the tx hash
3773
+ * once the payment is submitted to Stellar.
3774
+ */
3775
+ declare function claimDistributionRule(api: PollarApiClient, body: DistributionClaimBody): Promise<DistributionClaimContent>;
3776
+
3777
+ export { AUTH_ERROR_CODES, type AdapterFn, AlbedoAdapter, type AuthErrorCode, type AuthState, type BuildProofArgs, type ConnectWalletResponse, type DistributionClaimBody, type DistributionClaimContent, type DistributionRule, type DistributionRulesState, FreighterAdapter, type KeyManager, type KycFlow, type KycLevel, type KycProvider, type KycStartBody, type KycStartResponse, type KycStatus, type LocalStorageAdapterOptions, type NetworkState, OnStorageDegrade, type PaymentInstructions, type PollarAdapter, type PollarAdapters, type PollarApiClient, type PollarApplicationConfigContent, type PollarApplicationConfigResponse, PollarClient, type PollarClientConfig, PollarFlowError, type PollarLoginOptions, type PollarPersistedSession, type PollarUserProfile, type PublicEcJwk, type RampDirection, type RampQuote, type RampTxStatus, type RampsOfframpBody, type RampsOfframpResponse, type RampsOnrampBody, type RampsOnrampResponse, type RampsQuoteQuery, type RampsQuoteResponse, type RampsTransactionResponse, type RulePeriod, type SessionInfo, type SignAuthEntryOptions, type SignAuthEntryResponse, type SignTransactionOptions, type SignTransactionResponse, type StellarBalance, StellarClient, type StellarClientConfig, type StellarNetwork, Storage, type TransactionState, type TxBuildBody, type TxBuildContent, type TxBuildResponse, type TxHistoryContent, type TxHistoryParams, type TxHistoryRecord, type TxHistoryState, type TxSignAndSendBody, type TxSignSendResponse, type WalletAdapter, type WalletAdapterResolver, type WalletBalanceContent, type WalletBalanceRecord, type WalletBalanceState, type WalletId, WalletType, WebCryptoKeyManager, buildProof, canonicalEcJwk, claimDistributionRule, computeJwkThumbprint, createLocalStorageAdapter, createMemoryAdapter, createOffRamp, createOnRamp, defaultKeyManager, defaultStorage, getKycProviders, getKycStatus, getRampTransaction, getRampsQuote, isValidSession, listDistributionRules, normalizeHtu, pollKycStatus, pollRampTransaction, type paths as pollarPaths, resolveKyc, startKyc };
package/dist/index.js CHANGED
@@ -442,7 +442,7 @@ function createClient(clientOptions) {
442
442
  const {
443
443
  baseUrl: localBaseUrl,
444
444
  fetch: fetch2 = baseFetch,
445
- Request = CustomRequest,
445
+ Request: Request2 = CustomRequest,
446
446
  headers,
447
447
  params = {},
448
448
  parseAs = "json",
@@ -494,7 +494,7 @@ function createClient(clientOptions) {
494
494
  };
495
495
  let id;
496
496
  let options;
497
- let request = new Request(
497
+ let request = new Request2(
498
498
  createFinalURL(schemaPath, { baseUrl: finalBaseUrl, params, querySerializer, pathSerializer }),
499
499
  requestInit
500
500
  );
@@ -524,7 +524,7 @@ function createClient(clientOptions) {
524
524
  id
525
525
  });
526
526
  if (result) {
527
- if (result instanceof Request) {
527
+ if (result instanceof Request2) {
528
528
  request = result;
529
529
  } else if (result instanceof Response) {
530
530
  response = result;
@@ -896,6 +896,22 @@ function createApiClient(baseUrl) {
896
896
  return createClient({ baseUrl });
897
897
  }
898
898
 
899
+ // src/api/endpoints/distribution.ts
900
+ async function listDistributionRules(api) {
901
+ const { data, error } = await api.GET("/distribution/rules");
902
+ if (!data?.content || error) {
903
+ throw new Error(error?.error ?? "Failed to list distribution rules");
904
+ }
905
+ return data.content.rules;
906
+ }
907
+ async function claimDistributionRule(api, body) {
908
+ const { data, error } = await api.POST("/distribution/claim", { body });
909
+ if (!data?.content || error) {
910
+ throw new Error(error?.error ?? "Failed to claim distribution rule");
911
+ }
912
+ return data.content;
913
+ }
914
+
899
915
  // src/api/endpoints/kyc.ts
900
916
  async function getKycStatus(api, providerId) {
901
917
  const { data, error } = await api.GET("/kyc/status", {
@@ -1742,7 +1758,6 @@ async function loginWallet(type, deps) {
1742
1758
 
1743
1759
  // src/client/client.ts
1744
1760
  var isBrowser = typeof window !== "undefined" && typeof localStorage !== "undefined";
1745
- var RETRIED_HEADER = "X-Pollar-Retried";
1746
1761
  function warnServerSide(method) {
1747
1762
  console.warn(
1748
1763
  `[PollarClient] ${method}() called server-side \u2014 browser APIs unavailable. Use PollarClient only in Client Components.`
@@ -1760,6 +1775,13 @@ var PollarClient = class {
1760
1775
  this._profile = null;
1761
1776
  /** Last `DPoP-Nonce` we saw from a server response. Carried into the next proof. */
1762
1777
  this._dpopNonce = null;
1778
+ /**
1779
+ * Snapshot of each in-flight request's body, taken in `onRequest` before
1780
+ * `fetch()` consumes the stream. Needed because `Request.clone()` throws
1781
+ * once the body is disturbed, so the auto-retry path (DPoP nonce challenge
1782
+ * / 401 refresh) must rebuild the request from scratch instead of cloning.
1783
+ */
1784
+ this._requestBodyCache = /* @__PURE__ */ new WeakMap();
1763
1785
  /** Singleton in-flight refresh — concurrent 401s coalesce into one /auth/refresh call. */
1764
1786
  this._refreshPromise = null;
1765
1787
  this._storageEventHandler = null;
@@ -1844,6 +1866,13 @@ var PollarClient = class {
1844
1866
  onRequest: async ({ request }) => {
1845
1867
  request.headers.set("x-pollar-api-key", self.apiKey);
1846
1868
  await self._initialized;
1869
+ if (request.body !== null) {
1870
+ try {
1871
+ self._requestBodyCache.set(request, await request.clone().arrayBuffer());
1872
+ } catch (err) {
1873
+ console.warn("[PollarClient] Could not snapshot request body for retry", err);
1874
+ }
1875
+ }
1847
1876
  const isRefresh = request.url.includes("/auth/refresh");
1848
1877
  if (!isRefresh && self._refreshPromise) await self._refreshPromise;
1849
1878
  if (isRefresh) {
@@ -1866,7 +1895,6 @@ var PollarClient = class {
1866
1895
  const newNonce = response.headers.get("DPoP-Nonce");
1867
1896
  if (newNonce) self._dpopNonce = newNonce;
1868
1897
  if (response.status !== 401) return response;
1869
- if (request.headers.get(RETRIED_HEADER)) return response;
1870
1898
  if (request.url.includes("/auth/refresh")) return response;
1871
1899
  const wwwAuth = response.headers.get("WWW-Authenticate") ?? "";
1872
1900
  const isNonceChallenge = wwwAuth.includes("use_dpop_nonce");
@@ -1899,19 +1927,29 @@ var PollarClient = class {
1899
1927
  }
1900
1928
  }
1901
1929
  async _retryRequest(originalRequest) {
1902
- const clone = originalRequest.clone();
1903
- clone.headers.set(RETRIED_HEADER, "1");
1930
+ const headers = new Headers(originalRequest.headers);
1904
1931
  const accessToken = this._session?.token?.accessToken;
1905
1932
  if (accessToken) {
1906
- const proof = await this._buildProofForRequest(clone, accessToken);
1933
+ const proof = await this._buildProofForRequest(originalRequest, accessToken);
1907
1934
  if (proof) {
1908
- clone.headers.set("Authorization", `DPoP ${accessToken}`);
1909
- clone.headers.set("DPoP", proof);
1935
+ headers.set("Authorization", `DPoP ${accessToken}`);
1936
+ headers.set("DPoP", proof);
1910
1937
  } else {
1911
- clone.headers.set("Authorization", `Bearer ${accessToken}`);
1938
+ headers.set("Authorization", `Bearer ${accessToken}`);
1912
1939
  }
1913
1940
  }
1914
- return fetch(clone);
1941
+ const cachedBody = this._requestBodyCache.get(originalRequest);
1942
+ const retried = new Request(originalRequest.url, {
1943
+ method: originalRequest.method,
1944
+ headers,
1945
+ body: cachedBody ?? null,
1946
+ credentials: originalRequest.credentials,
1947
+ mode: originalRequest.mode,
1948
+ redirect: originalRequest.redirect,
1949
+ referrer: originalRequest.referrer,
1950
+ integrity: originalRequest.integrity
1951
+ });
1952
+ return fetch(retried);
1915
1953
  }
1916
1954
  // ─── Refresh (race-safe singleton) ───────────────────────────────────────
1917
1955
  /**
@@ -2236,7 +2274,8 @@ var PollarClient = class {
2236
2274
  const details = error?.details;
2237
2275
  this._setTransactionState({ step: "error", ...details && { details } });
2238
2276
  }
2239
- } catch {
2277
+ } catch (err) {
2278
+ console.error("[PollarClient] buildTx failed", err);
2240
2279
  this._setTransactionState({ step: "error" });
2241
2280
  }
2242
2281
  }
@@ -2324,6 +2363,13 @@ var PollarClient = class {
2324
2363
  pollRampTransaction(txId, opts) {
2325
2364
  return pollRampTransaction(this._api, txId, opts);
2326
2365
  }
2366
+ // ─── Distribution ─────────────────────────────────────────────────────────
2367
+ listDistributionRules() {
2368
+ return listDistributionRules(this._api);
2369
+ }
2370
+ claimDistributionRule(body) {
2371
+ return claimDistributionRule(this._api, body);
2372
+ }
2327
2373
  _setTxHistoryState(next) {
2328
2374
  this._txHistoryState = next;
2329
2375
  for (const cb of this._txHistoryStateListeners) cb(next);
@@ -2472,6 +2518,7 @@ exports.WalletType = WalletType;
2472
2518
  exports.WebCryptoKeyManager = WebCryptoKeyManager;
2473
2519
  exports.buildProof = buildProof;
2474
2520
  exports.canonicalEcJwk = canonicalEcJwk;
2521
+ exports.claimDistributionRule = claimDistributionRule;
2475
2522
  exports.computeJwkThumbprint = computeJwkThumbprint;
2476
2523
  exports.createLocalStorageAdapter = createLocalStorageAdapter;
2477
2524
  exports.createMemoryAdapter = createMemoryAdapter;
@@ -2484,6 +2531,7 @@ exports.getKycStatus = getKycStatus;
2484
2531
  exports.getRampTransaction = getRampTransaction;
2485
2532
  exports.getRampsQuote = getRampsQuote;
2486
2533
  exports.isValidSession = isValidSession;
2534
+ exports.listDistributionRules = listDistributionRules;
2487
2535
  exports.normalizeHtu = normalizeHtu;
2488
2536
  exports.pollKycStatus = pollKycStatus;
2489
2537
  exports.pollRampTransaction = pollRampTransaction;