@pollar/core 0.6.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.mts CHANGED
@@ -1,3 +1,5 @@
1
+ import { S as Storage, O as OnStorageDegrade } from './types-DqgJIJBl.mjs';
2
+ export { a as StorageDegradeReason } from './types-DqgJIJBl.mjs';
1
3
  import * as openapi_fetch from 'openapi-fetch';
2
4
 
3
5
  type StellarNetwork = 'mainnet' | 'testnet';
@@ -21,10 +23,70 @@ declare class StellarClient {
21
23
  }>;
22
24
  }
23
25
 
26
+ /**
27
+ * Public JWK shape for an EC P-256 key. Only the four required members for
28
+ * RFC 7638 thumbprint computation; never includes private fields or extras
29
+ * like `alg` / `use` / `kid`.
30
+ */
31
+ interface PublicEcJwk {
32
+ kty: 'EC';
33
+ crv: 'P-256';
34
+ /** Base64url-encoded big-endian X coordinate (32 bytes). */
35
+ x: string;
36
+ /** Base64url-encoded big-endian Y coordinate (32 bytes). */
37
+ y: string;
38
+ }
39
+ /**
40
+ * Manages the per-session ECDSA P-256 keypair used to sign DPoP proofs.
41
+ *
42
+ * Implementations:
43
+ * - `WebCryptoKeyManager` (web): non-extractable `CryptoKey` persisted in
44
+ * IndexedDB. Private key bytes never leave the browser's crypto context.
45
+ * - `NobleKeyManager` (React Native): private scalar bytes stored through an
46
+ * injected `Storage` adapter (Keychain / SecureStore). Pure-JS ECDSA via
47
+ * `@noble/curves`.
48
+ */
49
+ interface KeyManager {
50
+ /**
51
+ * Load an existing key for this session or generate a new one. Idempotent.
52
+ * Must be called before `getPublicJwk`, `getThumbprint`, or `sign`.
53
+ */
54
+ init(): Promise<void>;
55
+ /**
56
+ * Destroy the key. Removes it from persistent storage and clears any
57
+ * cached state. Used on logout.
58
+ */
59
+ reset(): Promise<void>;
60
+ /**
61
+ * The public JWK that goes into the DPoP proof header. Returns a fresh
62
+ * object every call (callers may mutate without affecting the manager).
63
+ */
64
+ getPublicJwk(): Promise<PublicEcJwk>;
65
+ /**
66
+ * RFC 7638 JWK thumbprint, base64url(SHA-256(canonical JWK)). The server
67
+ * compares this to the access token's `cnf.jkt` claim.
68
+ */
69
+ getThumbprint(): Promise<string>;
70
+ /**
71
+ * Sign the given bytes with ECDSA-P256-SHA256. Returns 64-byte raw r||s
72
+ * (IEEE P1363 / JOSE format), NOT DER. Suitable for direct base64url
73
+ * encoding into the JWS signature segment.
74
+ */
75
+ sign(payload: Uint8Array): Promise<Uint8Array>;
76
+ }
77
+
24
78
  declare enum WalletType {
25
79
  FREIGHTER = "freighter",
26
80
  ALBEDO = "albedo"
27
81
  }
82
+ /**
83
+ * A wallet identifier. Accepts the internal `WalletType` enum values
84
+ * (`'freighter'`, `'albedo'`) plus any opaque string id used by external
85
+ * adapter packages (e.g. Stellar Wallets Kit ids like `'xbull'`, `'lobstr'`).
86
+ * The `(string & {})` keeps autocomplete on the enum values without rejecting
87
+ * arbitrary strings.
88
+ */
89
+ type WalletId = WalletType | (string & {});
28
90
  interface ConnectWalletResponse {
29
91
  address: string;
30
92
  publicKey: string;
@@ -44,7 +106,7 @@ interface SignAuthEntryResponse {
44
106
  signedAuthEntry: string;
45
107
  }
46
108
  interface WalletAdapter {
47
- type: WalletType;
109
+ type: WalletId;
48
110
  isAvailable(): Promise<boolean>;
49
111
  connect(): Promise<ConnectWalletResponse>;
50
112
  disconnect(): Promise<void>;
@@ -52,6 +114,12 @@ interface WalletAdapter {
52
114
  signTransaction(xdr: string, options?: SignTransactionOptions): Promise<SignTransactionResponse>;
53
115
  signAuthEntry(entryXdr: string, options?: SignAuthEntryOptions): Promise<SignAuthEntryResponse>;
54
116
  }
117
+ /**
118
+ * Resolves a {@link WalletAdapter} for a given wallet id. Injected through
119
+ * `PollarClientConfig.walletAdapter` so wallet implementations (Stellar
120
+ * Wallets Kit, custom modules, etc.) can live outside `@pollar/core`.
121
+ */
122
+ type WalletAdapterResolver = (id: WalletId) => WalletAdapter | Promise<WalletAdapter>;
55
123
 
56
124
  declare class FreighterAdapter implements WalletAdapter {
57
125
  readonly type = WalletType.FREIGHTER;
@@ -76,11 +144,102 @@ declare class AlbedoAdapter implements WalletAdapter {
76
144
  }
77
145
 
78
146
  type PollarApplicationConfigResponse = paths['/auth/login']['post']['responses'][200]['content']['application/json'];
147
+ /** Full `/auth/login` response shape — used in transit but NOT persisted. */
79
148
  type PollarApplicationConfigContent = PollarApplicationConfigResponse['content'];
149
+ /**
150
+ * What we actually write to `Storage`. Drops the PII subtree (`data.*`)
151
+ * which is held in memory only on `PollarClient._profile` after auth.
152
+ */
153
+ interface PollarPersistedSession {
154
+ clientSessionId: string;
155
+ userId: string | null;
156
+ status: string;
157
+ token: {
158
+ accessToken: string;
159
+ refreshToken: string;
160
+ expiresAt: number;
161
+ };
162
+ user: {
163
+ id?: string;
164
+ ready: boolean;
165
+ };
166
+ wallet: {
167
+ publicKey: string | null;
168
+ existsOnStellar?: boolean;
169
+ createdAt?: number;
170
+ };
171
+ }
172
+ /** In-memory user profile (kept on `PollarClient`, never persisted). */
173
+ interface PollarUserProfile {
174
+ mail: string;
175
+ first_name: string;
176
+ last_name: string;
177
+ avatar: string;
178
+ providers: {
179
+ email: {
180
+ address: string;
181
+ } | null;
182
+ google: {
183
+ id: string;
184
+ } | null;
185
+ github: {
186
+ id: string;
187
+ } | null;
188
+ wallet: {
189
+ address: string;
190
+ } | null;
191
+ };
192
+ }
80
193
  interface PollarClientConfig {
81
194
  stellarNetwork?: StellarNetwork;
82
195
  baseUrl?: string;
83
196
  apiKey: string;
197
+ /**
198
+ * Pluggable storage. Defaults to `defaultStorage()` on web (localStorage
199
+ * with memory fallback). On RN you must inject one of the adapters from
200
+ * `@pollar/core/adapters/expo` or `@pollar/core/adapters/react-native-keychain`.
201
+ */
202
+ storage?: Storage;
203
+ /**
204
+ * Pluggable DPoP key manager. Defaults to `defaultKeyManager(storage,
205
+ * apiKeyHash)`: WebCrypto in browsers, `@noble/curves` in RN.
206
+ */
207
+ keyManager?: KeyManager;
208
+ /**
209
+ * Notified when persistent storage silently degrades to in-memory mode
210
+ * (Safari private browsing quota errors, sandboxed iframes, etc.). Useful
211
+ * for telemetry — the SDK keeps working but sessions won't survive reload.
212
+ */
213
+ onStorageDegrade?: OnStorageDegrade;
214
+ /**
215
+ * Resolves a {@link WalletAdapter} for a given wallet id. If omitted, the
216
+ * SDK falls back to its built-in `FreighterAdapter` / `AlbedoAdapter`,
217
+ * which only know `WalletType.FREIGHTER` and `WalletType.ALBEDO`. Inject
218
+ * `@pollar/stellar-wallets-kit-adapter` (or your own resolver) to support
219
+ * additional wallets without bundling those dependencies into `@pollar/core`.
220
+ */
221
+ walletAdapter?: WalletAdapterResolver;
222
+ /**
223
+ * Optional human-friendly label sent at /auth/login time and recorded on
224
+ * the server-side refresh-token row so the user can identify it in the
225
+ * "active sessions" UI (e.g. "iPhone — Safari", "Mac — Chrome 126").
226
+ * If unset, the server-recorded `user_agent` header is the fallback.
227
+ */
228
+ deviceLabel?: string;
229
+ }
230
+ /**
231
+ * One row in the active-sessions list (returned by `PollarClient.listSessions()`).
232
+ * Mirrors the sdk-api `SessionsListContent` schema.
233
+ */
234
+ interface SessionInfo {
235
+ familyId: string;
236
+ createdAt: string;
237
+ lastUsedAt: string | null;
238
+ userAgent: string | null;
239
+ ipHash: string | null;
240
+ deviceLabel: string | null;
241
+ current: boolean;
242
+ expiresAt: string;
84
243
  }
85
244
  type TxBuildBody = NonNullable<paths['/tx/build']['post']['requestBody']>['content']['application/json'];
86
245
  type TxBuildResponse = paths['/tx/build']['post']['responses'][200]['content']['application/json'];
@@ -95,7 +254,7 @@ type PollarLoginOptions = {
95
254
  email: string;
96
255
  } | {
97
256
  provider: 'wallet';
98
- type: WalletType;
257
+ type: WalletId;
99
258
  };
100
259
  type TxBuildContent = TxBuildResponse['content'];
101
260
  type TransactionState = {
@@ -155,17 +314,17 @@ type AuthState = {
155
314
  provider: 'google' | 'github';
156
315
  } | {
157
316
  step: 'connecting_wallet';
158
- walletType: WalletType;
317
+ walletType: WalletId;
159
318
  } | {
160
319
  step: 'wallet_not_installed';
161
- walletType: WalletType;
320
+ walletType: WalletId;
162
321
  } | {
163
322
  step: 'authenticating_wallet';
164
323
  } | {
165
324
  step: 'authenticating';
166
325
  } | {
167
326
  step: 'authenticated';
168
- session: PollarApplicationConfigContent;
327
+ session: PollarPersistedSession;
169
328
  } | {
170
329
  step: 'error';
171
330
  previousStep: string;
@@ -231,12 +390,27 @@ type RampsTransactionResponse = paths['/ramps/transaction/{txId}']['get']['respo
231
390
  type RampTxStatus = RampsTransactionResponse['status'];
232
391
  type RampDirection = RampsTransactionResponse['direction'];
233
392
  type PaymentInstructions = RampsOnrampResponse['paymentInstructions'];
234
- type EscrowFn<TParams = unknown> = (params: TParams) => Promise<{
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
+ };
408
+ type AdapterFn<TParams = unknown> = (params: TParams) => Promise<{
235
409
  unsignedTransaction: string;
236
410
  }>;
237
- type EscrowAdapter = Record<string, EscrowFn<any>>;
411
+ type PollarAdapter = Record<string, AdapterFn<any>>;
238
412
  interface PollarAdapters {
239
- [key: string]: EscrowAdapter;
413
+ [key: string]: PollarAdapter;
240
414
  }
241
415
 
242
416
  declare class PollarClient {
@@ -244,7 +418,39 @@ declare class PollarClient {
244
418
  readonly id: string;
245
419
  readonly basePath: string;
246
420
  private readonly _api;
421
+ private readonly _storage;
422
+ private readonly _keyManager;
423
+ /** Resolves once `keyManager.init()` and the initial session restore complete. */
424
+ private readonly _initialized;
425
+ /**
426
+ * Per-API-key storage namespace. Computed asynchronously inside
427
+ * `_initialize()` because SHA-256 lives behind `crypto.subtle.digest`.
428
+ * Accessing `apiKeyHash` before `await client.ready()` throws.
429
+ */
430
+ private _apiKeyHash;
431
+ /**
432
+ * Short SHA-256-derived namespace for this client's persisted state.
433
+ * Available after `await client.ready()` (or any awaited method); throws
434
+ * if read before initialization completes.
435
+ */
436
+ get apiKeyHash(): string;
247
437
  private _session;
438
+ private _profile;
439
+ /** Last `DPoP-Nonce` we saw from a server response. Carried into the next proof. */
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;
448
+ /** Singleton in-flight refresh — concurrent 401s coalesce into one /auth/refresh call. */
449
+ private _refreshPromise;
450
+ private _storageEventHandler;
451
+ /** Optional UI label sent to the server at /auth/login so the sessions UI
452
+ * can show a recognizable device name. Set via PollarClientConfig.deviceLabel. */
453
+ private readonly _deviceLabel;
248
454
  private _transactionState;
249
455
  private _transactionStateListeners;
250
456
  private _txHistoryState;
@@ -256,17 +462,61 @@ declare class PollarClient {
256
462
  private _networkState;
257
463
  private _networkStateListeners;
258
464
  private _walletAdapter;
465
+ private readonly _walletAdapterResolver;
259
466
  private _loginController;
260
467
  constructor(config: PollarClientConfig);
468
+ /** Awaitable handle for the initial keypair + session restore. */
469
+ ready(): Promise<void>;
470
+ private _initialize;
471
+ /** Detach the cross-tab storage listener and abort any in-flight login. */
472
+ destroy(): void;
473
+ private _wireMiddlewares;
474
+ private _buildProofForRequest;
475
+ private _retryRequest;
476
+ /**
477
+ * Coalesce concurrent refresh attempts. The first caller does the work;
478
+ * everyone else awaits the same promise and sees the new tokens.
479
+ */
480
+ refresh(): Promise<void>;
481
+ private _doRefresh;
261
482
  getAuthState(): AuthState;
262
483
  onAuthStateChange(cb: (state: AuthState) => void): () => void;
484
+ /** PII (email, names, avatar, providers). Held in memory only — never persisted. */
485
+ getUserProfile(): PollarUserProfile | null;
263
486
  login(options: PollarLoginOptions): void;
264
487
  beginEmailLogin(): void;
265
488
  sendEmailCode(email: string): void;
266
489
  verifyEmailCode(code: string): void;
267
- loginWallet(type: WalletType): void;
490
+ loginWallet(type: WalletId): void;
268
491
  cancelLogin(): void;
269
- logout(): void;
492
+ /**
493
+ * Revoke the current session server-side, then clear local storage.
494
+ *
495
+ * Server revocation is best-effort: if the POST fails (offline, server
496
+ * down), local state is wiped regardless. The orphan refresh token then
497
+ * remains unused until its natural expiry. The in-flight access token
498
+ * stays valid until its own TTL elapses (≤10 min for DPoP-bound tokens).
499
+ *
500
+ * Pass `everywhere: true` to revoke every active session for this user
501
+ * across all devices.
502
+ */
503
+ logout(options?: {
504
+ everywhere?: boolean;
505
+ }): Promise<void>;
506
+ /** Convenience: revoke every active session for this user (all devices). */
507
+ logoutEverywhere(): Promise<void>;
508
+ /**
509
+ * List active sessions for the authenticated user. Returns one entry per
510
+ * refresh-token family with the metadata captured at issuance time. The
511
+ * `current` flag identifies which entry corresponds to this client.
512
+ */
513
+ listSessions(): Promise<SessionInfo[]>;
514
+ /**
515
+ * Revoke a specific refresh-token family (a single device session). Use
516
+ * `listSessions` to enumerate the familyIds. Revoking the current session
517
+ * does NOT clear local state — call `logout()` for that case.
518
+ */
519
+ revokeSession(familyId: string): Promise<void>;
270
520
  getNetwork(): StellarNetwork;
271
521
  getNetworkState(): NetworkState;
272
522
  setNetwork(network: StellarNetwork): void;
@@ -280,7 +530,7 @@ declare class PollarClient {
280
530
  onWalletBalanceStateChange(cb: (state: WalletBalanceState) => void): () => void;
281
531
  refreshBalance(publicKey?: string): Promise<void>;
282
532
  buildTx(operation: TxBuildBody['operation'], params: TxBuildBody['params'], options?: TxBuildBody['options']): Promise<void>;
283
- getWalletType(): WalletType | null;
533
+ getWalletType(): WalletId | null;
284
534
  signAndSubmitTx(unsignedXdr: string): Promise<void>;
285
535
  getAppConfig(): Promise<unknown>;
286
536
  getKycStatus(providerId?: string): Promise<{
@@ -316,12 +566,19 @@ declare class PollarClient {
316
566
  intervalMs?: number;
317
567
  timeoutMs?: number;
318
568
  }): Promise<RampTxStatus>;
569
+ listDistributionRules(): Promise<DistributionRule[]>;
570
+ claimDistributionRule(body: DistributionClaimBody): Promise<DistributionClaimContent>;
319
571
  private _setTxHistoryState;
320
572
  private _setWalletBalanceState;
321
- /** Creates a new AbortController, cancelling any existing flow first. */
322
573
  private _newController;
323
- /** Builds the deps object passed to flow functions via bind pattern. */
324
574
  private _flowDeps;
575
+ /**
576
+ * Resolves a wallet adapter for the requested id. Uses the consumer's
577
+ * injected `walletAdapter` resolver when present; otherwise falls back to
578
+ * the built-in `FreighterAdapter` / `AlbedoAdapter`. Throws if the id is
579
+ * unknown and no resolver is configured.
580
+ */
581
+ private _resolveWalletAdapter;
325
582
  private _handleFlowError;
326
583
  private _restoreSession;
327
584
  private _storeSession;
@@ -332,6 +589,179 @@ declare class PollarClient {
332
589
  private _setTransactionState;
333
590
  }
334
591
 
592
+ /**
593
+ * In-memory storage backed by a `Map`. Always available, never throws.
594
+ * Used as the default fallback for SSR, private browsing, sandboxed iframes
595
+ * without `allow-same-origin`, or any environment where `localStorage` is
596
+ * unusable.
597
+ */
598
+ declare function createMemoryAdapter(): Storage;
599
+ interface LocalStorageAdapterOptions {
600
+ /**
601
+ * Optional callback invoked the first time the adapter degrades to its
602
+ * in-memory fallback (e.g. quota exceeded, throwing `localStorage`).
603
+ */
604
+ onDegrade?: OnStorageDegrade;
605
+ }
606
+ /**
607
+ * `localStorage`-backed adapter that wraps every operation in try/catch and
608
+ * silently degrades to an in-memory fallback for the rest of the process
609
+ * lifetime on any throw. A single warning is logged when the degrade happens.
610
+ *
611
+ * Why every op (not just the probe): Safari private mode and sandboxed iframes
612
+ * may expose `localStorage` but throw `QuotaExceededError` / `SecurityError`
613
+ * on the first write — a successful probe at construction time isn't enough.
614
+ *
615
+ * Tokens persisted here are DPoP-bound to a non-extractable WebCrypto
616
+ * keypair, so XSS exposure is limited to a signing-oracle attack (the key
617
+ * itself never leaves the browser's crypto subsystem). Consumers who need
618
+ * stricter isolation can inject a custom `Storage` adapter — e.g. one that
619
+ * proxies to an httpOnly cookie on a host origin.
620
+ */
621
+ declare function createLocalStorageAdapter(options?: LocalStorageAdapterOptions): Storage;
622
+
623
+ /**
624
+ * Returns `localStorage`-backed storage when it works, otherwise an in-memory
625
+ * fallback. The probe writes-reads-removes a sentinel; any throw, value
626
+ * mismatch, or missing `localStorage` (SSR / disabled storage) falls back.
627
+ *
628
+ * Run-time degrade still happens inside `createLocalStorageAdapter` — see its
629
+ * docstring for the rationale.
630
+ */
631
+ declare function defaultStorage(options?: LocalStorageAdapterOptions): Storage;
632
+
633
+ /**
634
+ * Construct the default `KeyManager` for the current runtime. Throws if no
635
+ * factory has been registered — that only happens if `@pollar/core` was
636
+ * imported in a way that bypassed the entry-point module (a bundler or
637
+ * test setup bug).
638
+ */
639
+ declare function defaultKeyManager(storage: Storage, apiKey: string): KeyManager;
640
+
641
+ declare class WebCryptoKeyManager implements KeyManager {
642
+ private readonly apiKey;
643
+ private apiKeyHash;
644
+ private keyPair;
645
+ private publicJwk;
646
+ private thumbprint;
647
+ /**
648
+ * Cached in-flight init. Lets `init()` be called concurrently (or implicitly
649
+ * from `getPublicJwk` / `sign`) without doing the work twice. Cleared on
650
+ * failure so callers can retry, and cleared on `reset()`.
651
+ */
652
+ private _initPromise;
653
+ constructor(apiKey: string);
654
+ /**
655
+ * Idempotent and safe under concurrency. The first call kicks off the real
656
+ * init; subsequent (and concurrent) calls return the same in-flight promise.
657
+ * Other methods (`getPublicJwk`, `getThumbprint`, `sign`) auto-await this so
658
+ * the manager is self-healing if `init()` was never explicitly invoked.
659
+ */
660
+ init(): Promise<void>;
661
+ private _doInit;
662
+ reset(): Promise<void>;
663
+ getPublicJwk(): Promise<PublicEcJwk>;
664
+ getThumbprint(): Promise<string>;
665
+ sign(payload: Uint8Array): Promise<Uint8Array>;
666
+ }
667
+
668
+ /**
669
+ * Compute the RFC 7638 JWK thumbprint for an EC P-256 public JWK.
670
+ *
671
+ * Algorithm (RFC 7638 §3):
672
+ * 1. Build a JSON object containing ONLY the required members of the JWK,
673
+ * ordered lexicographically by member name (Unicode code point).
674
+ * For EC keys, that's exactly {crv, kty, x, y}.
675
+ * 2. Serialize to UTF-8 with no whitespace and no line breaks.
676
+ * 3. Hash with SHA-256.
677
+ * 4. Base64url-encode the hash (no padding).
678
+ *
679
+ * Common bugs guarded against:
680
+ * - Including extra fields (`alg`, `use`, `kid`, `ext`, `key_ops`).
681
+ * - Wrong member ordering (must be lex by Unicode code point).
682
+ * - Padded base64 instead of base64url unpadded.
683
+ * - Using `JSON.stringify(jwk)` of an arbitrary-key-order object — we build
684
+ * a fresh literal in canonical order to make the order explicit and not
685
+ * rely on V8's insertion-order semantics.
686
+ */
687
+ declare function computeJwkThumbprint(jwk: PublicEcJwk): Promise<string>;
688
+ /**
689
+ * Strip a JWK to only the four required EC public members. Useful when the
690
+ * input came from `crypto.subtle.exportKey('jwk', publicKey)` which adds
691
+ * `ext` / `key_ops`. Returns a fresh object — never mutates input.
692
+ */
693
+ declare function canonicalEcJwk(jwk: {
694
+ kty?: string;
695
+ crv?: string;
696
+ x?: string;
697
+ y?: string;
698
+ }): PublicEcJwk;
699
+
700
+ /**
701
+ * RFC 9449 DPoP proof builder.
702
+ *
703
+ * Produces a compact JWS that the consumer attaches as the `DPoP` HTTP
704
+ * header. The header `jwk` is the public part of the SDK's per-session
705
+ * keypair; the server verifies the signature, validates the `htm` / `htu` /
706
+ * `iat` / `jti` / optional `nonce` / optional `ath` claims, and matches the
707
+ * proof's JWK thumbprint against the access token's `cnf.jkt` claim.
708
+ *
709
+ * Server-issued nonce flow (RFC 9449 §8/§9): the server may respond with
710
+ * `WWW-Authenticate: DPoP ... error="use_dpop_nonce"` plus a `DPoP-Nonce`
711
+ * header. The client should re-build the proof with the new nonce and retry.
712
+ * `buildProof` accepts an optional nonce; the SDK client tracks it across
713
+ * requests and feeds it back here.
714
+ *
715
+ * The last seen `DPoP-Nonce` is stored verbatim and embedded in the next
716
+ * proof. The server validates it as an HMAC token, so an attacker who
717
+ * injects an arbitrary nonce cannot escalate — verification fails and the
718
+ * server replies with a fresh nonce on the next request.
719
+ */
720
+ interface BuildProofArgs {
721
+ /** HTTP method, e.g. `"GET"`. Will be uppercased before signing. */
722
+ htm: string;
723
+ /**
724
+ * HTTP target URI. Will be normalized per RFC 3986 §6.2 (lowercase scheme
725
+ * + host, default port elided, query+fragment+userinfo stripped, path
726
+ * dot-segments resolved, trailing slash preserved exactly as provided).
727
+ */
728
+ htu: string;
729
+ /**
730
+ * Access token to bind the proof to (its base64url(SHA-256) goes in the
731
+ * `ath` claim). Omit for proofs sent to the token endpoint per RFC 9449
732
+ * §5 / §6.1 (those proofs MUST NOT include `ath`).
733
+ */
734
+ accessToken?: string;
735
+ /**
736
+ * Server-issued DPoP nonce, if the server has previously challenged this
737
+ * client with `WWW-Authenticate: DPoP ... error="use_dpop_nonce"`. RFC
738
+ * 9449 §8.
739
+ */
740
+ nonce?: string;
741
+ }
742
+ /**
743
+ * Build a DPoP proof JWS for the given request. Returns the compact-form
744
+ * JWS string (`<header>.<payload>.<signature>`).
745
+ */
746
+ declare function buildProof(args: BuildProofArgs, keyManager: KeyManager): Promise<string>;
747
+ /**
748
+ * Normalize an HTTP URI for use as the `htu` claim.
749
+ *
750
+ * RFC 9449 §4.3 + RFC 3986 §6.2:
751
+ * - lowercase scheme + host
752
+ * - elide default port (`:443` for https, `:80` for http)
753
+ * - strip userinfo (never appears in `htu`)
754
+ * - strip query + fragment
755
+ * - apply path dot-segment removal (handled by the URL constructor)
756
+ * - **preserve trailing slash exactly** — `/foo` and `/foo/` are distinct
757
+ * paths per RFC 3986 §6 and must round-trip identically.
758
+ * - preserve IPv6 brackets in host
759
+ *
760
+ * Both client and server must apply the same normalization so the `htu`
761
+ * claim matches deterministically.
762
+ */
763
+ declare function normalizeHtu(rawUrl: string): string;
764
+
335
765
  /**
336
766
  * This file was auto-generated by openapi-typescript.
337
767
  * Do not make direct changes to the file.
@@ -435,6 +865,26 @@ interface paths {
435
865
  patch?: never;
436
866
  trace?: never;
437
867
  };
868
+ "/auth/oidc": {
869
+ parameters: {
870
+ query?: never;
871
+ header?: never;
872
+ path?: never;
873
+ cookie?: never;
874
+ };
875
+ /**
876
+ * Redirect to Authentik OIDC
877
+ * @description Redirects the user to the Authentik authorization endpoint (PKCE, per-app).
878
+ */
879
+ get: operations["getAuthOidc"];
880
+ put?: never;
881
+ post?: never;
882
+ delete?: never;
883
+ options?: never;
884
+ head?: never;
885
+ patch?: never;
886
+ trace?: never;
887
+ };
438
888
  "/auth/email": {
439
889
  parameters: {
440
890
  query?: never;
@@ -506,6 +956,83 @@ interface paths {
506
956
  patch?: never;
507
957
  trace?: never;
508
958
  };
959
+ "/auth/refresh": {
960
+ parameters: {
961
+ query?: never;
962
+ header?: never;
963
+ path?: never;
964
+ cookie?: never;
965
+ };
966
+ get?: never;
967
+ put?: never;
968
+ /**
969
+ * Rotate a DPoP-bound refresh token
970
+ * @description Single-use rotation per RFC 9449 §5. Requires a DPoP proof (no `ath`) bound to the same key as the refresh token (`cnf.jkt`). On reuse outside the 30s grace window, the entire token family is revoked.
971
+ */
972
+ post: operations["postAuthRefresh"];
973
+ delete?: never;
974
+ options?: never;
975
+ head?: never;
976
+ patch?: never;
977
+ trace?: never;
978
+ };
979
+ "/auth/logout": {
980
+ parameters: {
981
+ query?: never;
982
+ header?: never;
983
+ path?: never;
984
+ cookie?: never;
985
+ };
986
+ get?: never;
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
+ */
992
+ post: operations["postAuthLogout"];
993
+ delete?: never;
994
+ options?: never;
995
+ head?: never;
996
+ patch?: never;
997
+ trace?: never;
998
+ };
999
+ "/auth/sessions": {
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
+ */
1010
+ get: operations["getAuthSessions"];
1011
+ put?: never;
1012
+ post?: never;
1013
+ delete?: never;
1014
+ options?: never;
1015
+ head?: never;
1016
+ patch?: never;
1017
+ trace?: never;
1018
+ };
1019
+ "/auth/sessions/{familyId}": {
1020
+ parameters: {
1021
+ query?: never;
1022
+ header?: never;
1023
+ path?: never;
1024
+ cookie?: never;
1025
+ };
1026
+ get?: never;
1027
+ put?: never;
1028
+ post?: never;
1029
+ /** Revoke a specific session (refresh-token family) */
1030
+ delete: operations["deleteAuthSessionsByFamilyId"];
1031
+ options?: never;
1032
+ head?: never;
1033
+ patch?: never;
1034
+ trace?: never;
1035
+ };
509
1036
  "/applications/config": {
510
1037
  parameters: {
511
1038
  query?: never;
@@ -786,6 +1313,46 @@ interface paths {
786
1313
  patch?: never;
787
1314
  trace?: never;
788
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
+ };
789
1356
  }
790
1357
  interface operations {
791
1358
  getHealth: {
@@ -905,29 +1472,8 @@ interface operations {
905
1472
  "text/event-stream": {
906
1473
  status: string;
907
1474
  user: {
908
- id?: string;
909
1475
  ready: boolean;
910
1476
  };
911
- data: {
912
- mail: string;
913
- first_name: string;
914
- last_name: string;
915
- avatar: string;
916
- providers: {
917
- email: {
918
- address: string;
919
- } | null;
920
- google: {
921
- id: string;
922
- } | null;
923
- github: {
924
- id: string;
925
- } | null;
926
- wallet: {
927
- address: string;
928
- } | null;
929
- };
930
- };
931
1477
  };
932
1478
  };
933
1479
  };
@@ -1081,6 +1627,66 @@ interface operations {
1081
1627
  };
1082
1628
  };
1083
1629
  };
1630
+ getAuthOidc: {
1631
+ parameters: {
1632
+ query: {
1633
+ api_key: string;
1634
+ client_session_id: string;
1635
+ };
1636
+ header?: never;
1637
+ path?: never;
1638
+ cookie?: never;
1639
+ };
1640
+ requestBody?: never;
1641
+ responses: {
1642
+ /** @description Redirect to Authentik */
1643
+ 302: {
1644
+ headers: {
1645
+ [name: string]: unknown;
1646
+ };
1647
+ content?: never;
1648
+ };
1649
+ /** @description Validation error */
1650
+ 400: {
1651
+ headers: {
1652
+ [name: string]: unknown;
1653
+ };
1654
+ content: {
1655
+ "application/json": {
1656
+ /** @constant */
1657
+ success: false;
1658
+ error: string;
1659
+ };
1660
+ };
1661
+ };
1662
+ /** @description Unauthorized */
1663
+ 401: {
1664
+ headers: {
1665
+ [name: string]: unknown;
1666
+ };
1667
+ content: {
1668
+ "application/json": {
1669
+ /** @constant */
1670
+ success: false;
1671
+ error: string;
1672
+ };
1673
+ };
1674
+ };
1675
+ /** @description Not found */
1676
+ 404: {
1677
+ headers: {
1678
+ [name: string]: unknown;
1679
+ };
1680
+ content: {
1681
+ "application/json": {
1682
+ /** @constant */
1683
+ success: false;
1684
+ error: string;
1685
+ };
1686
+ };
1687
+ };
1688
+ };
1689
+ };
1084
1690
  postAuthEmail: {
1085
1691
  parameters: {
1086
1692
  query?: never;
@@ -1257,7 +1863,226 @@ interface operations {
1257
1863
  };
1258
1864
  };
1259
1865
  };
1260
- postAuthWallet: {
1866
+ postAuthWallet: {
1867
+ parameters: {
1868
+ query?: never;
1869
+ header?: never;
1870
+ path?: never;
1871
+ cookie?: never;
1872
+ };
1873
+ requestBody: {
1874
+ content: {
1875
+ "application/json": {
1876
+ clientSessionId: string;
1877
+ walletAddress: string;
1878
+ };
1879
+ };
1880
+ };
1881
+ responses: {
1882
+ /** @description Wallet authenticated */
1883
+ 200: {
1884
+ headers: {
1885
+ [name: string]: unknown;
1886
+ };
1887
+ content: {
1888
+ "application/json": {
1889
+ /** @constant */
1890
+ code: "SDK_WALLET_AUTHENTICATED";
1891
+ /** @constant */
1892
+ success: true;
1893
+ content: {
1894
+ clientSessionId: string;
1895
+ walletAddress: string;
1896
+ };
1897
+ };
1898
+ };
1899
+ };
1900
+ /** @description Validation error */
1901
+ 400: {
1902
+ headers: {
1903
+ [name: string]: unknown;
1904
+ };
1905
+ content: {
1906
+ "application/json": {
1907
+ /** @constant */
1908
+ success: false;
1909
+ error: string;
1910
+ };
1911
+ };
1912
+ };
1913
+ /** @description Unauthorized */
1914
+ 401: {
1915
+ headers: {
1916
+ [name: string]: unknown;
1917
+ };
1918
+ content: {
1919
+ "application/json": {
1920
+ /** @constant */
1921
+ success: false;
1922
+ error: string;
1923
+ };
1924
+ };
1925
+ };
1926
+ /** @description Forbidden */
1927
+ 403: {
1928
+ headers: {
1929
+ [name: string]: unknown;
1930
+ };
1931
+ content: {
1932
+ "application/json": {
1933
+ /** @constant */
1934
+ success: false;
1935
+ error: string;
1936
+ };
1937
+ };
1938
+ };
1939
+ /** @description Not found */
1940
+ 404: {
1941
+ headers: {
1942
+ [name: string]: unknown;
1943
+ };
1944
+ content: {
1945
+ "application/json": {
1946
+ /** @constant */
1947
+ success: false;
1948
+ error: string;
1949
+ };
1950
+ };
1951
+ };
1952
+ };
1953
+ };
1954
+ postAuthLogin: {
1955
+ parameters: {
1956
+ query?: never;
1957
+ header?: never;
1958
+ path?: never;
1959
+ cookie?: never;
1960
+ };
1961
+ requestBody: {
1962
+ content: {
1963
+ "application/json": {
1964
+ clientSessionId: string;
1965
+ dpopJwk?: {
1966
+ /** @constant */
1967
+ kty: "EC";
1968
+ /** @constant */
1969
+ crv: "P-256";
1970
+ x: string;
1971
+ y: string;
1972
+ };
1973
+ deviceLabel?: string;
1974
+ };
1975
+ };
1976
+ };
1977
+ responses: {
1978
+ /** @description Authenticated */
1979
+ 200: {
1980
+ headers: {
1981
+ [name: string]: unknown;
1982
+ };
1983
+ content: {
1984
+ "application/json": {
1985
+ /** @constant */
1986
+ code: "SDK_LOGIN_SUCCESS";
1987
+ /** @constant */
1988
+ success: true;
1989
+ content: {
1990
+ clientSessionId: string;
1991
+ userId: string | null;
1992
+ status: string;
1993
+ token: {
1994
+ accessToken: string;
1995
+ refreshToken: string;
1996
+ expiresAt: number;
1997
+ };
1998
+ user: {
1999
+ id?: string;
2000
+ ready: boolean;
2001
+ };
2002
+ wallet: {
2003
+ publicKey: string | null;
2004
+ existsOnStellar?: boolean;
2005
+ createdAt?: number;
2006
+ };
2007
+ data: {
2008
+ mail: string;
2009
+ first_name: string;
2010
+ last_name: string;
2011
+ avatar: string;
2012
+ providers: {
2013
+ email: {
2014
+ address: string;
2015
+ } | null;
2016
+ google: {
2017
+ id: string;
2018
+ } | null;
2019
+ github: {
2020
+ id: string;
2021
+ } | null;
2022
+ wallet: {
2023
+ address: string;
2024
+ } | null;
2025
+ };
2026
+ };
2027
+ };
2028
+ };
2029
+ };
2030
+ };
2031
+ /** @description Validation error */
2032
+ 400: {
2033
+ headers: {
2034
+ [name: string]: unknown;
2035
+ };
2036
+ content: {
2037
+ "application/json": {
2038
+ /** @constant */
2039
+ success: false;
2040
+ error: string;
2041
+ };
2042
+ };
2043
+ };
2044
+ /** @description Unauthorized */
2045
+ 401: {
2046
+ headers: {
2047
+ [name: string]: unknown;
2048
+ };
2049
+ content: {
2050
+ "application/json": {
2051
+ /** @constant */
2052
+ success: false;
2053
+ error: string;
2054
+ };
2055
+ };
2056
+ };
2057
+ /** @description Forbidden */
2058
+ 403: {
2059
+ headers: {
2060
+ [name: string]: unknown;
2061
+ };
2062
+ content: {
2063
+ "application/json": {
2064
+ /** @constant */
2065
+ success: false;
2066
+ error: string;
2067
+ };
2068
+ };
2069
+ };
2070
+ /** @description Not found */
2071
+ 404: {
2072
+ headers: {
2073
+ [name: string]: unknown;
2074
+ };
2075
+ content: {
2076
+ "application/json": {
2077
+ /** @constant */
2078
+ success: false;
2079
+ error: string;
2080
+ };
2081
+ };
2082
+ };
2083
+ };
2084
+ };
2085
+ postAuthRefresh: {
1261
2086
  parameters: {
1262
2087
  query?: never;
1263
2088
  header?: never;
@@ -1267,13 +2092,12 @@ interface operations {
1267
2092
  requestBody: {
1268
2093
  content: {
1269
2094
  "application/json": {
1270
- clientSessionId: string;
1271
- walletAddress: string;
2095
+ refreshToken: string;
1272
2096
  };
1273
2097
  };
1274
2098
  };
1275
2099
  responses: {
1276
- /** @description Wallet authenticated */
2100
+ /** @description New token pair issued */
1277
2101
  200: {
1278
2102
  headers: {
1279
2103
  [name: string]: unknown;
@@ -1281,12 +2105,15 @@ interface operations {
1281
2105
  content: {
1282
2106
  "application/json": {
1283
2107
  /** @constant */
1284
- code: "SDK_WALLET_AUTHENTICATED";
2108
+ code: "SDK_TOKEN_REFRESHED";
1285
2109
  /** @constant */
1286
2110
  success: true;
1287
2111
  content: {
1288
- clientSessionId: string;
1289
- walletAddress: string;
2112
+ token: {
2113
+ accessToken: string;
2114
+ refreshToken: string;
2115
+ expiresAt: number;
2116
+ };
1290
2117
  };
1291
2118
  };
1292
2119
  };
@@ -1345,7 +2172,7 @@ interface operations {
1345
2172
  };
1346
2173
  };
1347
2174
  };
1348
- postAuthLogin: {
2175
+ postAuthLogout: {
1349
2176
  parameters: {
1350
2177
  query?: never;
1351
2178
  header?: never;
@@ -1355,12 +2182,12 @@ interface operations {
1355
2182
  requestBody: {
1356
2183
  content: {
1357
2184
  "application/json": {
1358
- clientSessionId: string;
2185
+ everywhere?: boolean;
1359
2186
  };
1360
2187
  };
1361
2188
  };
1362
2189
  responses: {
1363
- /** @description Authenticated */
2190
+ /** @description Sessions revoked */
1364
2191
  200: {
1365
2192
  headers: {
1366
2193
  [name: string]: unknown;
@@ -1368,53 +2195,17 @@ interface operations {
1368
2195
  content: {
1369
2196
  "application/json": {
1370
2197
  /** @constant */
1371
- code: "SDK_LOGIN_SUCCESS";
2198
+ code: "SDK_LOGOUT_SUCCESS";
1372
2199
  /** @constant */
1373
2200
  success: true;
1374
2201
  content: {
1375
- clientSessionId: string;
1376
- userId: string | null;
1377
- status: string;
1378
- token: {
1379
- accessToken: string;
1380
- refreshToken: string;
1381
- expiresAt: number;
1382
- };
1383
- user: {
1384
- id?: string;
1385
- ready: boolean;
1386
- };
1387
- wallet: {
1388
- publicKey: string | null;
1389
- existsOnStellar?: boolean;
1390
- createdAt?: number;
1391
- };
1392
- data: {
1393
- mail: string;
1394
- first_name: string;
1395
- last_name: string;
1396
- avatar: string;
1397
- providers: {
1398
- email: {
1399
- address: string;
1400
- } | null;
1401
- google: {
1402
- id: string;
1403
- } | null;
1404
- github: {
1405
- id: string;
1406
- } | null;
1407
- wallet: {
1408
- address: string;
1409
- } | null;
1410
- };
1411
- };
2202
+ revoked: number;
1412
2203
  };
1413
2204
  };
1414
2205
  };
1415
2206
  };
1416
- /** @description Validation error */
1417
- 400: {
2207
+ /** @description Unauthorized */
2208
+ 401: {
1418
2209
  headers: {
1419
2210
  [name: string]: unknown;
1420
2211
  };
@@ -1426,6 +2217,43 @@ interface operations {
1426
2217
  };
1427
2218
  };
1428
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
+ };
1429
2257
  /** @description Unauthorized */
1430
2258
  401: {
1431
2259
  headers: {
@@ -1439,8 +2267,38 @@ interface operations {
1439
2267
  };
1440
2268
  };
1441
2269
  };
1442
- /** @description Forbidden */
1443
- 403: {
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: {
1444
2302
  headers: {
1445
2303
  [name: string]: unknown;
1446
2304
  };
@@ -2677,12 +3535,153 @@ interface operations {
2677
3535
  };
2678
3536
  };
2679
3537
  };
3538
+ getDistributionRules: {
3539
+ parameters: {
3540
+ query?: never;
3541
+ header?: never;
3542
+ path?: never;
3543
+ cookie?: never;
3544
+ };
3545
+ requestBody?: never;
3546
+ responses: {
3547
+ /** @description List of distribution rules with claimability verdict per rule */
3548
+ 200: {
3549
+ headers: {
3550
+ [name: string]: unknown;
3551
+ };
3552
+ content: {
3553
+ "application/json": {
3554
+ /** @constant */
3555
+ code: "SDK_DISTRIBUTION_RULES_LIST";
3556
+ /** @constant */
3557
+ success: true;
3558
+ content: {
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
+ }[];
3571
+ };
3572
+ };
3573
+ };
3574
+ };
3575
+ /** @description Unauthorized */
3576
+ 401: {
3577
+ headers: {
3578
+ [name: string]: unknown;
3579
+ };
3580
+ content: {
3581
+ "application/json": {
3582
+ /** @constant */
3583
+ success: false;
3584
+ error: string;
3585
+ };
3586
+ };
3587
+ };
3588
+ };
3589
+ };
3590
+ postDistributionClaim: {
3591
+ parameters: {
3592
+ query?: never;
3593
+ header?: never;
3594
+ path?: never;
3595
+ cookie?: never;
3596
+ };
3597
+ requestBody: {
3598
+ content: {
3599
+ "application/json": {
3600
+ ruleId: string;
3601
+ };
3602
+ };
3603
+ };
3604
+ responses: {
3605
+ /** @description Claim succeeded — payment submitted to Stellar */
3606
+ 200: {
3607
+ headers: {
3608
+ [name: string]: unknown;
3609
+ };
3610
+ content: {
3611
+ "application/json": {
3612
+ /** @constant */
3613
+ code: "SDK_DISTRIBUTION_CLAIM_OK";
3614
+ /** @constant */
3615
+ success: true;
3616
+ content: {
3617
+ ruleId: string;
3618
+ assetCode: string;
3619
+ amount: string;
3620
+ txHash: string | null;
3621
+ };
3622
+ };
3623
+ };
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 */
3652
+ 404: {
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
+ };
3669
+ content: {
3670
+ "application/json": {
3671
+ /** @constant */
3672
+ success: false;
3673
+ error: string;
3674
+ };
3675
+ };
3676
+ };
3677
+ };
3678
+ };
2680
3679
  }
2681
3680
 
2682
3681
  type PollarApiClient = ReturnType<typeof createApiClient>;
2683
3682
  declare function createApiClient(baseUrl: string): openapi_fetch.Client<paths, `${string}/${string}`>;
2684
3683
 
2685
- declare function isValidSession(value: unknown): value is PollarApplicationConfigContent;
3684
+ declare function isValidSession(value: unknown): value is PollarPersistedSession;
2686
3685
 
2687
3686
  /**
2688
3687
  * GET /kyc/status
@@ -2761,4 +3760,18 @@ declare function pollRampTransaction(api: PollarApiClient, txId: string, { inter
2761
3760
  timeoutMs?: number;
2762
3761
  }): Promise<RampTxStatus>;
2763
3762
 
2764
- export { AUTH_ERROR_CODES, AlbedoAdapter, type AuthErrorCode, type AuthState, type ConnectWalletResponse, type EscrowAdapter, type EscrowFn, FreighterAdapter, type KycFlow, type KycLevel, type KycProvider, type KycStartBody, type KycStartResponse, type KycStatus, type NetworkState, type PaymentInstructions, type PollarAdapters, type PollarApiClient, type PollarApplicationConfigContent, type PollarApplicationConfigResponse, PollarClient, type PollarClientConfig, PollarFlowError, type PollarLoginOptions, type RampDirection, type RampQuote, type RampTxStatus, type RampsOfframpBody, type RampsOfframpResponse, type RampsOnrampBody, type RampsOnrampResponse, type RampsQuoteQuery, type RampsQuoteResponse, type RampsTransactionResponse, type SignAuthEntryOptions, type SignAuthEntryResponse, type SignTransactionOptions, type SignTransactionResponse, type StellarBalance, StellarClient, type StellarClientConfig, type StellarNetwork, type TransactionState, type TxBuildBody, type TxBuildContent, type TxBuildResponse, type TxHistoryContent, type TxHistoryParams, type TxHistoryRecord, type TxHistoryState, type TxSignAndSendBody, type TxSignSendResponse, type WalletAdapter, type WalletBalanceContent, type WalletBalanceRecord, type WalletBalanceState, WalletType, createOffRamp, createOnRamp, getKycProviders, getKycStatus, getRampTransaction, getRampsQuote, isValidSession, 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 };