@pafi-dev/issuer 0.7.8 → 0.8.0
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.cjs +767 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +469 -22
- package/dist/index.d.ts +469 -22
- package/dist/index.js +752 -34
- package/dist/index.js.map +1 -1
- package/package.json +11 -11
package/dist/index.d.cts
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
import { PafiSdkError, SdkErrorHttpStatus, PointTokenDomainConfig, PartialUserOperation, BurnRequest, PoolKey, UserOpTypedData, decodeBatchExecuteCalls, BROKER_HASHES, BuiltSponsorAuth, ENTRY_POINT_V08 } from '@pafi-dev/core';
|
|
1
|
+
import { PafiSdkError, SdkErrorHttpStatus, PointTokenDomainConfig, PartialUserOperation, BurnRequest, PoolKey, RedemptionPolicy, RedemptionPolicySource, RedemptionPreview, RedemptionDecision, RedemptionDenialCode, UserOpTypedData, decodeBatchExecuteCalls, BROKER_HASHES, BuiltSponsorAuth, ENTRY_POINT_V08 } from '@pafi-dev/core';
|
|
2
2
|
export { PAFI_SUBGRAPH_URL, PafiSdkError, SdkErrorHttpStatus, ValidationError } from '@pafi-dev/core';
|
|
3
3
|
import { Address, Hex, PublicClient, WalletClient } from 'viem';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* `PafiSdkError` + `SdkErrorHttpStatus` are exported from
|
|
7
7
|
* `@pafi-dev/core/errors` so core-level errors (e.g. `OracleStaleError`)
|
|
8
|
-
* can extend the same base. Issuer re-exports the canonical types
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* Effect: `instanceof PafiSdkError` from EITHER package now catches
|
|
12
|
-
* errors thrown from EITHER package — no more silent fall-through to
|
|
13
|
-
* 500 for core-thrown errors.
|
|
8
|
+
* can extend the same base. Issuer re-exports the canonical types here
|
|
9
|
+
* for back-compat — `instanceof PafiSdkError` from EITHER package
|
|
10
|
+
* catches errors thrown from EITHER package.
|
|
14
11
|
*/
|
|
15
12
|
|
|
16
13
|
/**
|
|
@@ -19,8 +16,6 @@ import { Address, Hex, PublicClient, WalletClient } from 'viem';
|
|
|
19
16
|
* `/pools` called but `poolsProvider` not configured). 503 because
|
|
20
17
|
* the endpoint genuinely can't serve the request — caller's payload
|
|
21
18
|
* is fine, the issuer's deployment is incomplete.
|
|
22
|
-
*
|
|
23
|
-
* v0.7.1 — added per SDK_ISSUER_AUDIT.md H1.
|
|
24
19
|
*/
|
|
25
20
|
declare class ConfigurationError extends PafiSdkError {
|
|
26
21
|
readonly httpStatus: "service_unavailable";
|
|
@@ -293,6 +288,15 @@ interface MemorySessionStoreOptions {
|
|
|
293
288
|
nonceTtlMs?: number;
|
|
294
289
|
/** Clock override for tests. */
|
|
295
290
|
now?: () => number;
|
|
291
|
+
/**
|
|
292
|
+
* Bypass the production-safety guard. By default, instantiating
|
|
293
|
+
* `MemorySessionStore` when `process.env.NODE_ENV === "production"`
|
|
294
|
+
* THROWS — multi-pod K8s deploys do not share Map state, so sessions
|
|
295
|
+
* are not revocable across replicas, and tokens remain valid on pod
|
|
296
|
+
* B after `logout` on pod A. Only set this `true` for single-pod
|
|
297
|
+
* deployments where you've consciously accepted the trade-off.
|
|
298
|
+
*/
|
|
299
|
+
dangerouslyAllowMemoryStoreInProduction?: boolean;
|
|
296
300
|
}
|
|
297
301
|
/**
|
|
298
302
|
* In-memory `ISessionStore` — Map-backed nonces and sessions with lazy
|
|
@@ -351,6 +355,21 @@ interface AuthServiceConfig {
|
|
|
351
355
|
domain: string;
|
|
352
356
|
/** Expected chain id. */
|
|
353
357
|
chainId: number;
|
|
358
|
+
/**
|
|
359
|
+
* Optional `iss` (issuer) claim baked into JWTs and validated on
|
|
360
|
+
* verify. Recommended for multi-issuer deployments to prevent
|
|
361
|
+
* cross-validation if a JWT secret is accidentally shared. Examples:
|
|
362
|
+
* `"gg56-issuer"`, `"issuer.gg56.com"`. When unset, no `iss` is
|
|
363
|
+
* written or required (back-compat).
|
|
364
|
+
*/
|
|
365
|
+
issuer?: string;
|
|
366
|
+
/**
|
|
367
|
+
* Optional `aud` (audience) claim baked into JWTs and validated on
|
|
368
|
+
* verify. Recommended to bind tokens to a specific consumer, e.g.
|
|
369
|
+
* `"gg56-mobile"` or `"gg56-web"`. When unset, no `aud` is written
|
|
370
|
+
* or required (back-compat).
|
|
371
|
+
*/
|
|
372
|
+
audience?: string;
|
|
354
373
|
/** Clock override for tests. */
|
|
355
374
|
now?: () => Date;
|
|
356
375
|
}
|
|
@@ -384,6 +403,8 @@ declare class AuthService {
|
|
|
384
403
|
private readonly jwtExpiresIn;
|
|
385
404
|
private readonly domain;
|
|
386
405
|
private readonly chainId;
|
|
406
|
+
private readonly issuer?;
|
|
407
|
+
private readonly audience?;
|
|
387
408
|
private readonly nonceManager;
|
|
388
409
|
private readonly now;
|
|
389
410
|
constructor(config: AuthServiceConfig);
|
|
@@ -396,6 +417,7 @@ declare class AuthService {
|
|
|
396
417
|
login(message: string, signature: Hex): Promise<LoginResult>;
|
|
397
418
|
/** Revoke the session backing the given JWT (logout). */
|
|
398
419
|
logout(token: string): Promise<void>;
|
|
420
|
+
private logSessionStoreError;
|
|
399
421
|
/**
|
|
400
422
|
* Verify a JWT and return the authenticated user context. Throws an
|
|
401
423
|
* `AuthError` if the token is missing, malformed, expired, revoked, or
|
|
@@ -421,10 +443,9 @@ declare function authenticateRequest(authHeader: string | undefined, authService
|
|
|
421
443
|
*/
|
|
422
444
|
type AuthErrorCode = "INVALID_MESSAGE" | "DOMAIN_MISMATCH" | "CHAIN_MISMATCH" | "NONCE_INVALID" | "MESSAGE_EXPIRED" | "MESSAGE_NOT_YET_VALID" | "SIGNATURE_INVALID" | "MISSING_TOKEN" | "MALFORMED_TOKEN" | "TOKEN_INVALID" | "TOKEN_EXPIRED" | "SESSION_REVOKED";
|
|
423
445
|
/**
|
|
424
|
-
*
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
* SDK_ISSUER_AUDIT.md H2.
|
|
446
|
+
* Extends `PafiSdkError` so issuer controllers can route auth failures
|
|
447
|
+
* through the same `createSdkErrorMapper` as everything else (no
|
|
448
|
+
* separate `instanceof AuthError` check needed).
|
|
428
449
|
*/
|
|
429
450
|
declare class AuthError extends PafiSdkError {
|
|
430
451
|
readonly code: AuthErrorCode;
|
|
@@ -432,6 +453,88 @@ declare class AuthError extends PafiSdkError {
|
|
|
432
453
|
constructor(code: AuthErrorCode, message: string);
|
|
433
454
|
}
|
|
434
455
|
|
|
456
|
+
/**
|
|
457
|
+
* Per-key rate limiting for unauthenticated public endpoints.
|
|
458
|
+
*
|
|
459
|
+
* `/auth/nonce` and `/auth/login` are unauthenticated and CPU-bound
|
|
460
|
+
* (SIWE message parsing + ECDSA `recover`), so without rate limiting
|
|
461
|
+
* an attacker can saturate the issuer at low cost. Worse, on
|
|
462
|
+
* `/auth/nonce` they can flood the session store with single-use
|
|
463
|
+
* nonces; with `MemorySessionStore` this is a pure DoS.
|
|
464
|
+
*
|
|
465
|
+
* Issuers wire a `IRateLimiter` impl in `IssuerApiHandlersConfig` —
|
|
466
|
+
* `MemoryRateLimiter` is the default reference impl (single-pod, dev).
|
|
467
|
+
* Production deployments use a Redis-backed impl that shares state
|
|
468
|
+
* across replicas (similar pattern to `ISessionStore`).
|
|
469
|
+
*
|
|
470
|
+
* The "key" is up to the caller — typically the client IP, but the
|
|
471
|
+
* issuer's HTTP layer chooses (could be userAddress on POST /login).
|
|
472
|
+
*/
|
|
473
|
+
interface IRateLimiter {
|
|
474
|
+
/**
|
|
475
|
+
* Check + increment a counter under `key`. Returns `{ allowed: false,
|
|
476
|
+
* retryAfterMs }` when the caller has exceeded its quota for this
|
|
477
|
+
* window. Default config is action-specific (see
|
|
478
|
+
* `RateLimiterConfig`).
|
|
479
|
+
*
|
|
480
|
+
* Idempotent in the sense that successive calls with the same `key`
|
|
481
|
+
* within the same window count toward the limit; a separate window
|
|
482
|
+
* starts after `windowMs` elapses.
|
|
483
|
+
*/
|
|
484
|
+
consume(key: string, action: RateLimitAction): Promise<{
|
|
485
|
+
allowed: boolean;
|
|
486
|
+
retryAfterMs?: number;
|
|
487
|
+
}>;
|
|
488
|
+
}
|
|
489
|
+
type RateLimitAction = "auth_nonce" | "auth_login";
|
|
490
|
+
interface RateLimiterConfig {
|
|
491
|
+
/**
|
|
492
|
+
* Per-key max requests per `windowMs`. Defaults:
|
|
493
|
+
* - auth_nonce: 1 per 2s (30/min)
|
|
494
|
+
* - auth_login: 5 per minute
|
|
495
|
+
*
|
|
496
|
+
* Issuers can tune per their threat model.
|
|
497
|
+
*/
|
|
498
|
+
limits?: Partial<Record<RateLimitAction, {
|
|
499
|
+
max: number;
|
|
500
|
+
windowMs: number;
|
|
501
|
+
}>>;
|
|
502
|
+
/** Clock override for tests. */
|
|
503
|
+
now?: () => number;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* In-memory `IRateLimiter` — Map of `{key, action}` → count + window
|
|
507
|
+
* start. Lazy expiry on read. Single-process: NOT safe for multi-pod
|
|
508
|
+
* deployments. Use a Redis impl in production.
|
|
509
|
+
*/
|
|
510
|
+
declare class MemoryRateLimiter implements IRateLimiter {
|
|
511
|
+
private buckets;
|
|
512
|
+
private readonly limits;
|
|
513
|
+
private readonly now;
|
|
514
|
+
constructor(config?: RateLimiterConfig);
|
|
515
|
+
consume(key: string, action: RateLimitAction): Promise<{
|
|
516
|
+
allowed: boolean;
|
|
517
|
+
retryAfterMs?: number;
|
|
518
|
+
}>;
|
|
519
|
+
/**
|
|
520
|
+
* Test helper — clear all buckets. Not part of `IRateLimiter`; only
|
|
521
|
+
* exposed on the in-memory impl for unit tests.
|
|
522
|
+
*/
|
|
523
|
+
reset(): void;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Convenience: a no-op `IRateLimiter` that lets every request through.
|
|
527
|
+
* Useful as a default in `IssuerApiHandlersConfig` when the issuer
|
|
528
|
+
* hasn't wired a rate limiter yet (back-compat) — emits a one-time
|
|
529
|
+
* warning at construction so consumers notice.
|
|
530
|
+
*/
|
|
531
|
+
declare class NoopRateLimiter implements IRateLimiter {
|
|
532
|
+
private warned;
|
|
533
|
+
consume(): Promise<{
|
|
534
|
+
allowed: boolean;
|
|
535
|
+
}>;
|
|
536
|
+
}
|
|
537
|
+
|
|
435
538
|
type RelayErrorCode = "ENCODE_FAILED";
|
|
436
539
|
declare class RelayError extends PafiSdkError {
|
|
437
540
|
readonly httpStatus: "unprocessable";
|
|
@@ -724,6 +827,16 @@ interface PointIndexerConfig {
|
|
|
724
827
|
pollIntervalMs?: number;
|
|
725
828
|
/** Clock override for tests. */
|
|
726
829
|
now?: () => number;
|
|
830
|
+
/**
|
|
831
|
+
* Observability hook fired on EVERY tick error (RPC failure, ledger
|
|
832
|
+
* write failure, etc). Issuers MUST wire this to their alert
|
|
833
|
+
* pipeline (Sentry / Datadog / PagerDuty) — without it, the indexer
|
|
834
|
+
* silently swallows errors via `console.error`, and indexer outage
|
|
835
|
+
* means PENDING mint locks never resolve (user balances stuck).
|
|
836
|
+
*
|
|
837
|
+
* When omitted, falls back to `console.error` for back-compat.
|
|
838
|
+
*/
|
|
839
|
+
onTickError?: (err: unknown) => void;
|
|
727
840
|
}
|
|
728
841
|
/**
|
|
729
842
|
* Watches `PointToken.Transfer(from=0x0 → to)` events and finalizes the
|
|
@@ -755,6 +868,7 @@ declare class PointIndexer {
|
|
|
755
868
|
private readonly confirmations;
|
|
756
869
|
private readonly batchSize;
|
|
757
870
|
private readonly pollIntervalMs;
|
|
871
|
+
private readonly onTickError?;
|
|
758
872
|
private running;
|
|
759
873
|
private timer;
|
|
760
874
|
constructor(config: PointIndexerConfig);
|
|
@@ -768,6 +882,7 @@ declare class PointIndexer {
|
|
|
768
882
|
* schedules the next tick. Visible for test harnesses via a public name.
|
|
769
883
|
*/
|
|
770
884
|
tick(): Promise<void>;
|
|
885
|
+
private handleTickError;
|
|
771
886
|
private scheduleNext;
|
|
772
887
|
/**
|
|
773
888
|
* Scan `[from, to]` inclusive for mint events in `batchSize` chunks.
|
|
@@ -816,6 +931,13 @@ interface BurnIndexerConfig {
|
|
|
816
931
|
* ledger uses a lookup by lockId supplied out-of-band from the claim flow.
|
|
817
932
|
*/
|
|
818
933
|
matchLockId: (event: BurnEvent) => Promise<string | undefined>;
|
|
934
|
+
/**
|
|
935
|
+
* Observability hook — see PointIndexerConfig.onTickError for full
|
|
936
|
+
* rationale. Critical for burn indexer too: silent failure means
|
|
937
|
+
* pending credits never resolve, user reports "I burned my PT but
|
|
938
|
+
* never got my off-chain credit".
|
|
939
|
+
*/
|
|
940
|
+
onTickError?: (err: unknown) => void;
|
|
819
941
|
}
|
|
820
942
|
/**
|
|
821
943
|
* Mirror of `PointIndexer` for the reverse direction — watches
|
|
@@ -846,6 +968,7 @@ declare class BurnIndexer {
|
|
|
846
968
|
private readonly confirmations;
|
|
847
969
|
private readonly batchSize;
|
|
848
970
|
private readonly pollIntervalMs;
|
|
971
|
+
private readonly onTickError?;
|
|
849
972
|
matchLockId: (event: BurnEvent) => Promise<string | undefined>;
|
|
850
973
|
private running;
|
|
851
974
|
private timer;
|
|
@@ -853,6 +976,7 @@ declare class BurnIndexer {
|
|
|
853
976
|
start(): void;
|
|
854
977
|
stop(): void;
|
|
855
978
|
tick(): Promise<void>;
|
|
979
|
+
private handleTickError;
|
|
856
980
|
private scheduleNext;
|
|
857
981
|
/**
|
|
858
982
|
* Scan `[from, to]` inclusive for burn events. Callers can drive this
|
|
@@ -975,8 +1099,161 @@ interface ApiUserResponse {
|
|
|
975
1099
|
balance: bigint;
|
|
976
1100
|
isMinter: boolean;
|
|
977
1101
|
}
|
|
1102
|
+
interface ApiRedemptionPreviewRequest {
|
|
1103
|
+
pointTokenAddress?: Address;
|
|
1104
|
+
}
|
|
1105
|
+
interface ApiRedemptionPreviewResponse {
|
|
1106
|
+
availableAmountPt: bigint;
|
|
1107
|
+
dailyRemainingPt: bigint;
|
|
1108
|
+
cooldownUntilUnixSec: number | null;
|
|
1109
|
+
nextBlackoutEndsAtUnixSec: number | null;
|
|
1110
|
+
perTxMinPt: bigint;
|
|
1111
|
+
perTxMaxPt: bigint;
|
|
1112
|
+
policyVersion: string;
|
|
1113
|
+
policySource: "settlement" | "cache" | "default";
|
|
1114
|
+
}
|
|
1115
|
+
interface ApiRedemptionEvaluateRequest {
|
|
1116
|
+
amountPt: bigint;
|
|
1117
|
+
pointTokenAddress?: Address;
|
|
1118
|
+
}
|
|
1119
|
+
interface ApiRedemptionEvaluateResponse {
|
|
1120
|
+
allowed: boolean;
|
|
1121
|
+
denial?: {
|
|
1122
|
+
code: "AMOUNT_BELOW_MIN" | "AMOUNT_ABOVE_MAX" | "DAILY_LIMIT_EXCEEDED" | "COOLDOWN_ACTIVE" | "BLACKOUT_WINDOW";
|
|
1123
|
+
message: string;
|
|
1124
|
+
};
|
|
1125
|
+
preview: ApiRedemptionPreviewResponse;
|
|
1126
|
+
}
|
|
978
1127
|
type PoolsProvider = (request: ApiPoolsRequest) => Promise<ApiPoolsResponse>;
|
|
979
1128
|
|
|
1129
|
+
/**
|
|
1130
|
+
* Per-user redemption history needed by the evaluator. The issuer can
|
|
1131
|
+
* implement this with their existing burn audit table (preferred) or
|
|
1132
|
+
* use the bundled MemoryRedemptionHistoryStore for tests.
|
|
1133
|
+
*/
|
|
1134
|
+
interface IRedemptionHistoryStore {
|
|
1135
|
+
/**
|
|
1136
|
+
* Sum of PT redeemed by `user` from `sinceUnixSec` onwards. Used for
|
|
1137
|
+
* the rolling 24h daily-limit check. MUST count both confirmed burns
|
|
1138
|
+
* and currently-reserved-pending entries — the policy treats reserved
|
|
1139
|
+
* burns as "spent" so a flood of pending requests can't bypass the cap.
|
|
1140
|
+
*/
|
|
1141
|
+
sumRedeemedSince(user: Address, sinceUnixSec: number, pointTokenAddress?: Address): Promise<bigint>;
|
|
1142
|
+
/**
|
|
1143
|
+
* Unix-second timestamp of the user's last redemption attempt
|
|
1144
|
+
* (confirmed or reserved). null if never. Used for cooldown.
|
|
1145
|
+
*/
|
|
1146
|
+
getLastRedeemedAtUnixSec(user: Address, pointTokenAddress?: Address): Promise<number | null>;
|
|
1147
|
+
/**
|
|
1148
|
+
* Record a new redemption attempt. Called by handleRedemptionInitiate
|
|
1149
|
+
* AFTER policy.evaluate() returns ALLOW and the BurnRequest is signed.
|
|
1150
|
+
* Implementations may persist this row in a redemption_history table or
|
|
1151
|
+
* derive from existing pending-credit reservations.
|
|
1152
|
+
*/
|
|
1153
|
+
recordRedemption(entry: {
|
|
1154
|
+
user: Address;
|
|
1155
|
+
amountPt: bigint;
|
|
1156
|
+
pointTokenAddress?: Address;
|
|
1157
|
+
unixSec: number;
|
|
1158
|
+
/** Optional pointer back to the reservation lock id. */
|
|
1159
|
+
reservationId?: string;
|
|
1160
|
+
}): Promise<void>;
|
|
1161
|
+
}
|
|
1162
|
+
interface SettlementClientConfig {
|
|
1163
|
+
/**
|
|
1164
|
+
* chainId — used to derive the issuer-api base URL via
|
|
1165
|
+
* `getPafiServiceUrls(chainId).issuerApi`. SDK ships with the URL
|
|
1166
|
+
* per chainId; bump SDK version to retarget.
|
|
1167
|
+
*/
|
|
1168
|
+
chainId: number;
|
|
1169
|
+
/** PAFI-assigned issuer id used in `X-Issuer-Id` header. */
|
|
1170
|
+
issuerId: string;
|
|
1171
|
+
/** Raw API key sent as `Authorization: Bearer <apiKey>`. */
|
|
1172
|
+
apiKey: string;
|
|
1173
|
+
/** Per-request timeout in milliseconds. Default 1000. */
|
|
1174
|
+
fetchTimeoutMs?: number;
|
|
1175
|
+
/** Override fetch (testing). */
|
|
1176
|
+
fetchImpl?: typeof fetch;
|
|
1177
|
+
}
|
|
1178
|
+
interface PolicyProviderConfig extends SettlementClientConfig {
|
|
1179
|
+
/** Cache TTL in milliseconds. Default 5 * 60 * 1000 (5min). */
|
|
1180
|
+
cacheTtlMs?: number;
|
|
1181
|
+
/**
|
|
1182
|
+
* Optional clock for testability. Returns unix milliseconds.
|
|
1183
|
+
* Defaults to () => Date.now().
|
|
1184
|
+
*/
|
|
1185
|
+
now?: () => number;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
interface ResolvedPolicy {
|
|
1189
|
+
policy: RedemptionPolicy;
|
|
1190
|
+
source: RedemptionPolicySource;
|
|
1191
|
+
}
|
|
1192
|
+
/**
|
|
1193
|
+
* Wraps SettlementClient with a 5-minute TTL cache and a hardcoded
|
|
1194
|
+
* default fallback. Single-flight: concurrent getPolicy() calls during
|
|
1195
|
+
* a cache miss share the same in-flight request.
|
|
1196
|
+
*
|
|
1197
|
+
* Resolution order:
|
|
1198
|
+
* 1. fresh cache hit → return cached
|
|
1199
|
+
* 2. cache miss → fetch ok → cache + return (source=settlement)
|
|
1200
|
+
* 3. cache miss → fetch failed → DEFAULT_REDEMPTION_POLICY (source=default)
|
|
1201
|
+
*
|
|
1202
|
+
* Stale cache is NEVER returned — once the TTL expires we either fetch
|
|
1203
|
+
* fresh data or fall through to default. This keeps behavior predictable:
|
|
1204
|
+
* "default" means "we couldn't talk to settlement RIGHT NOW", not "we got
|
|
1205
|
+
* lucky with a stale entry".
|
|
1206
|
+
*/
|
|
1207
|
+
declare class PolicyProvider {
|
|
1208
|
+
private readonly client;
|
|
1209
|
+
private readonly issuerId;
|
|
1210
|
+
private readonly cacheTtlMs;
|
|
1211
|
+
private readonly now;
|
|
1212
|
+
private cache;
|
|
1213
|
+
private inflight;
|
|
1214
|
+
constructor(config: PolicyProviderConfig);
|
|
1215
|
+
getPolicy(): Promise<ResolvedPolicy>;
|
|
1216
|
+
/** Drop cached policy. Next getPolicy() will refetch. */
|
|
1217
|
+
invalidate(): void;
|
|
1218
|
+
private readCache;
|
|
1219
|
+
private fetchAndStore;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
interface RedemptionServiceConfig {
|
|
1223
|
+
policyProvider: PolicyProvider | PolicyProviderConfig;
|
|
1224
|
+
historyStore: IRedemptionHistoryStore;
|
|
1225
|
+
/** Defaults to () => Math.floor(Date.now() / 1000). */
|
|
1226
|
+
nowUnixSec?: () => number;
|
|
1227
|
+
}
|
|
1228
|
+
/**
|
|
1229
|
+
* High-level facade used by HTTP handlers. Combines PolicyProvider +
|
|
1230
|
+
* IRedemptionHistoryStore into preview/evaluate operations.
|
|
1231
|
+
*
|
|
1232
|
+
* preview(user) → RedemptionPreview (no amount required)
|
|
1233
|
+
* evaluate(user, amount) → RedemptionDecision
|
|
1234
|
+
* recordSuccessfulInitiate(..) → call AFTER signing the BurnRequest
|
|
1235
|
+
*
|
|
1236
|
+
* Note: this service does NOT mutate anything during evaluate(). The
|
|
1237
|
+
* caller must call recordSuccessfulInitiate() after the BurnRequest is
|
|
1238
|
+
* signed and the pending credit is reserved on the ledger. Splitting
|
|
1239
|
+
* "decide" from "record" lets the handler atomically reserve + record
|
|
1240
|
+
* under one DB transaction if it wants.
|
|
1241
|
+
*/
|
|
1242
|
+
declare class RedemptionService {
|
|
1243
|
+
private readonly policyProvider;
|
|
1244
|
+
private readonly historyStore;
|
|
1245
|
+
private readonly nowUnixSec;
|
|
1246
|
+
constructor(config: RedemptionServiceConfig);
|
|
1247
|
+
preview(user: Address, pointTokenAddress?: Address): Promise<RedemptionPreview>;
|
|
1248
|
+
evaluate(user: Address, amountPt: bigint, pointTokenAddress?: Address): Promise<RedemptionDecision>;
|
|
1249
|
+
recordSuccessfulInitiate(entry: {
|
|
1250
|
+
user: Address;
|
|
1251
|
+
amountPt: bigint;
|
|
1252
|
+
pointTokenAddress?: Address;
|
|
1253
|
+
reservationId?: string;
|
|
1254
|
+
}): Promise<void>;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
980
1257
|
interface IssuerApiHandlersConfig {
|
|
981
1258
|
authService: AuthService;
|
|
982
1259
|
ledger: IPointLedger;
|
|
@@ -1004,6 +1281,19 @@ interface IssuerApiHandlersConfig {
|
|
|
1004
1281
|
feeManager?: FeeManager;
|
|
1005
1282
|
/** Required by `handlePools`; omit to disable the endpoint. */
|
|
1006
1283
|
poolsProvider?: PoolsProvider;
|
|
1284
|
+
/**
|
|
1285
|
+
* Required by `handleRedemptionPreview` / `handleRedemptionEvaluate`;
|
|
1286
|
+
* omit to disable both. Wired by createIssuerService when the top-level
|
|
1287
|
+
* `redemption` config is provided.
|
|
1288
|
+
*/
|
|
1289
|
+
redemption?: RedemptionService;
|
|
1290
|
+
/**
|
|
1291
|
+
* Rate limiter for `/auth/nonce` and `/auth/login` (both unauthenticated +
|
|
1292
|
+
* CPU-bound). When omitted, defaults to a `NoopRateLimiter` that lets
|
|
1293
|
+
* every request through (with a one-time prod warning) — issuers MUST
|
|
1294
|
+
* wire a real impl in production.
|
|
1295
|
+
*/
|
|
1296
|
+
rateLimiter?: IRateLimiter;
|
|
1007
1297
|
}
|
|
1008
1298
|
/**
|
|
1009
1299
|
* Framework-agnostic HTTP handlers that match the endpoints a `PafiSDK`
|
|
@@ -1030,11 +1320,27 @@ declare class IssuerApiHandlers {
|
|
|
1030
1320
|
private readonly pafiWebUrl?;
|
|
1031
1321
|
private readonly feeManager?;
|
|
1032
1322
|
private readonly poolsProvider?;
|
|
1323
|
+
private readonly redemption?;
|
|
1324
|
+
private readonly rateLimiter;
|
|
1033
1325
|
constructor(config: IssuerApiHandlersConfig);
|
|
1034
|
-
/**
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1326
|
+
/**
|
|
1327
|
+
* `GET /auth/nonce`
|
|
1328
|
+
*
|
|
1329
|
+
* @param rateLimitKey Caller-side rate-limit key (typically client IP).
|
|
1330
|
+
* The HTTP layer (controller/middleware) extracts
|
|
1331
|
+
* this from the request and passes it through.
|
|
1332
|
+
* When omitted, no rate limit applies — production
|
|
1333
|
+
* callers SHOULD always pass a key.
|
|
1334
|
+
*/
|
|
1335
|
+
handleGetNonce(rateLimitKey?: string): Promise<ApiNonceResponse>;
|
|
1336
|
+
/**
|
|
1337
|
+
* `POST /auth/login`
|
|
1338
|
+
*
|
|
1339
|
+
* @param body Login message + signature.
|
|
1340
|
+
* @param rateLimitKey Caller-side rate-limit key (typically client IP
|
|
1341
|
+
* or `body.userAddress` if known). See `handleGetNonce`.
|
|
1342
|
+
*/
|
|
1343
|
+
handleLogin(body: ApiLoginRequest, rateLimitKey?: string): Promise<ApiLoginResponse>;
|
|
1038
1344
|
/**
|
|
1039
1345
|
* `GET /config?chainId=<id>`
|
|
1040
1346
|
*
|
|
@@ -1061,6 +1367,26 @@ declare class IssuerApiHandlers {
|
|
|
1061
1367
|
* balance.
|
|
1062
1368
|
*/
|
|
1063
1369
|
handleUser(userAddress: Address, request: ApiUserRequest): Promise<ApiUserResponse>;
|
|
1370
|
+
/**
|
|
1371
|
+
* `GET /redemption/preview?pointToken=<addr>`
|
|
1372
|
+
*
|
|
1373
|
+
* Returns the headroom currently available to `userAddress` under the
|
|
1374
|
+
* configured RedemptionPolicy. Pure read — does not record anything.
|
|
1375
|
+
* Use this for UI to render "X PT redeemable now / next available at …".
|
|
1376
|
+
*/
|
|
1377
|
+
handleRedemptionPreview(userAddress: Address, request: ApiRedemptionPreviewRequest): Promise<ApiRedemptionPreviewResponse>;
|
|
1378
|
+
/**
|
|
1379
|
+
* `POST /redemption/evaluate`
|
|
1380
|
+
*
|
|
1381
|
+
* Pre-flight check before the issuer signs a BurnRequest. Returns
|
|
1382
|
+
* { allowed, denial?, preview }. Caller (the burn-orchestrator) MUST
|
|
1383
|
+
* re-check on the actual initiate path — evaluate is read-only and a
|
|
1384
|
+
* caller could race two requests under the same headroom. The intended
|
|
1385
|
+
* write path is: evaluate → sign BurnRequest → reserve pending credit
|
|
1386
|
+
* → call `service.redemption.recordSuccessfulInitiate()`.
|
|
1387
|
+
*/
|
|
1388
|
+
handleRedemptionEvaluate(userAddress: Address, request: ApiRedemptionEvaluateRequest): Promise<ApiRedemptionEvaluateResponse>;
|
|
1389
|
+
private requireSupportedToken;
|
|
1064
1390
|
}
|
|
1065
1391
|
|
|
1066
1392
|
/**
|
|
@@ -1134,6 +1460,16 @@ interface PTRedeemHandlerConfig {
|
|
|
1134
1460
|
signatureDeadlineSeconds?: number;
|
|
1135
1461
|
/** Clock injection for tests; defaults to `Date.now`. */
|
|
1136
1462
|
now?: () => number;
|
|
1463
|
+
/**
|
|
1464
|
+
* Optional — when wired, the handler enforces the per-issuer
|
|
1465
|
+
* RedemptionPolicy (daily limit / cooldown / blackout / per-tx range)
|
|
1466
|
+
* BEFORE signing the BurnRequest. On denial it throws
|
|
1467
|
+
* PTRedeemError("REDEMPTION_POLICY_DENIED", ...) with the policy
|
|
1468
|
+
* denial code in `policyDenialCode`. After a successful sign+reserve,
|
|
1469
|
+
* the handler records the redemption against the user's history so
|
|
1470
|
+
* the next preview reflects the spend.
|
|
1471
|
+
*/
|
|
1472
|
+
redemptionService?: RedemptionService;
|
|
1137
1473
|
}
|
|
1138
1474
|
interface PTRedeemRequest {
|
|
1139
1475
|
/** Address extracted from the verified JWT — must match `userAddress`. */
|
|
@@ -1193,11 +1529,14 @@ interface PTRedeemResponse {
|
|
|
1193
1529
|
/** The BurnRequest deadline (unix seconds) — FE uses this to surface a countdown. */
|
|
1194
1530
|
signatureDeadline: bigint;
|
|
1195
1531
|
}
|
|
1196
|
-
type PTRedeemErrorCode = "UNAUTHORIZED" | "INVALID_AMOUNT" | "NONCE_READ_FAILED" | "NONCE_IN_FLIGHT" | "LEDGER_NOT_SUPPORTED" | "SIGNING_FAILED";
|
|
1532
|
+
type PTRedeemErrorCode = "UNAUTHORIZED" | "INVALID_AMOUNT" | "NONCE_READ_FAILED" | "NONCE_IN_FLIGHT" | "LEDGER_NOT_SUPPORTED" | "SIGNING_FAILED" | "REDEMPTION_POLICY_DENIED";
|
|
1197
1533
|
declare class PTRedeemError extends PafiSdkError {
|
|
1198
1534
|
readonly httpStatus: "unprocessable";
|
|
1199
1535
|
readonly code: PTRedeemErrorCode;
|
|
1200
|
-
|
|
1536
|
+
readonly policyDenialCode?: RedemptionDenialCode;
|
|
1537
|
+
constructor(code: PTRedeemErrorCode, message: string, options?: {
|
|
1538
|
+
policyDenialCode?: RedemptionDenialCode;
|
|
1539
|
+
});
|
|
1201
1540
|
}
|
|
1202
1541
|
declare class PTRedeemHandler {
|
|
1203
1542
|
private readonly ledger;
|
|
@@ -1212,6 +1551,7 @@ declare class PTRedeemHandler {
|
|
|
1212
1551
|
private readonly redeemLockDurationMs;
|
|
1213
1552
|
private readonly signatureDeadlineSeconds;
|
|
1214
1553
|
private readonly now;
|
|
1554
|
+
private readonly redemptionService?;
|
|
1215
1555
|
/**
|
|
1216
1556
|
* Per-user in-flight nonce guard (single-process only).
|
|
1217
1557
|
*
|
|
@@ -1238,7 +1578,12 @@ interface RetryConfig {
|
|
|
1238
1578
|
maxRetryAfterMs?: number;
|
|
1239
1579
|
}
|
|
1240
1580
|
interface PafiBackendConfig {
|
|
1241
|
-
|
|
1581
|
+
/**
|
|
1582
|
+
* chainId — used to derive the sponsor-relayer base URL via
|
|
1583
|
+
* `getPafiServiceUrls(chainId).sponsorRelayer`. SDK ships with the
|
|
1584
|
+
* URL per chainId; bump SDK version to retarget.
|
|
1585
|
+
*/
|
|
1586
|
+
chainId: number;
|
|
1242
1587
|
issuerId: string;
|
|
1243
1588
|
apiKey: string;
|
|
1244
1589
|
fetchImpl?: typeof fetch;
|
|
@@ -1343,6 +1688,7 @@ interface SponsorshipResponse {
|
|
|
1343
1688
|
}
|
|
1344
1689
|
declare class PafiBackendClient {
|
|
1345
1690
|
private readonly config;
|
|
1691
|
+
private readonly baseUrl;
|
|
1346
1692
|
constructor(config: PafiBackendConfig);
|
|
1347
1693
|
requestSponsorship(request: SponsorshipRequest): Promise<SponsorshipResponse>;
|
|
1348
1694
|
/**
|
|
@@ -2145,6 +2491,28 @@ interface IssuerServiceConfig {
|
|
|
2145
2491
|
*/
|
|
2146
2492
|
autoStart?: boolean;
|
|
2147
2493
|
};
|
|
2494
|
+
/**
|
|
2495
|
+
* Redemption restriction config. When provided, the SDK fetches the
|
|
2496
|
+
* per-issuer policy from PAFI issuer-api (with 5min cache + default
|
|
2497
|
+
* fallback) and exposes preview/evaluate via `service.redemption`.
|
|
2498
|
+
* The handler endpoints `handleRedemptionPreview` / `handleRedemptionEvaluate`
|
|
2499
|
+
* are wired only when this is configured.
|
|
2500
|
+
*
|
|
2501
|
+
* `chainId` is taken from the top-level config; the issuer-api URL
|
|
2502
|
+
* is looked up via `getPafiServiceUrls(chainId)`. Only credentials
|
|
2503
|
+
* + the history store are required here.
|
|
2504
|
+
*/
|
|
2505
|
+
redemption?: {
|
|
2506
|
+
issuerId: string;
|
|
2507
|
+
apiKey: string;
|
|
2508
|
+
historyStore: IRedemptionHistoryStore;
|
|
2509
|
+
/** Override fetch (testing). */
|
|
2510
|
+
fetchImpl?: typeof fetch;
|
|
2511
|
+
/** Per-fetch timeout in ms. Default 1000. */
|
|
2512
|
+
fetchTimeoutMs?: number;
|
|
2513
|
+
/** Cache TTL in ms. Default 5 * 60 * 1000. */
|
|
2514
|
+
cacheTtlMs?: number;
|
|
2515
|
+
};
|
|
2148
2516
|
}
|
|
2149
2517
|
interface IssuerService {
|
|
2150
2518
|
/** AuthService — login, logout, nonce management. */
|
|
@@ -2166,6 +2534,12 @@ interface IssuerService {
|
|
|
2166
2534
|
indexer: PointIndexer;
|
|
2167
2535
|
/** Framework-agnostic HTTP handlers — wire into Express / Fastify / Hono. */
|
|
2168
2536
|
api: IssuerApiHandlers;
|
|
2537
|
+
/**
|
|
2538
|
+
* Redemption restriction service. Undefined when `redemption` is not
|
|
2539
|
+
* configured — the corresponding handlers throw "not configured" at
|
|
2540
|
+
* request time.
|
|
2541
|
+
*/
|
|
2542
|
+
redemption: RedemptionService | undefined;
|
|
2169
2543
|
}
|
|
2170
2544
|
/**
|
|
2171
2545
|
* Wire a fully-functional issuer service from a single config object.
|
|
@@ -2866,6 +3240,79 @@ declare class IssuerStateValidator {
|
|
|
2866
3240
|
private fetchIssuerState;
|
|
2867
3241
|
}
|
|
2868
3242
|
|
|
3243
|
+
/**
|
|
3244
|
+
* SDK-side fallback used when settlement-api is unreachable, returns
|
|
3245
|
+
* 404, or returns 5xx. Keep it permissive enough that an outage doesn't
|
|
3246
|
+
* lock all users out, but tight enough that it's not an abuse vector.
|
|
3247
|
+
*/
|
|
3248
|
+
declare const DEFAULT_REDEMPTION_POLICY: RedemptionPolicy;
|
|
3249
|
+
declare function defaultPolicyFor(issuerId: string): RedemptionPolicy;
|
|
3250
|
+
|
|
3251
|
+
/**
|
|
3252
|
+
* Either a successful policy fetch or a structured failure. We never
|
|
3253
|
+
* throw from `fetchPolicy()` — callers fall back to cache/default on
|
|
3254
|
+
* any failure mode, so a thrown error would just force every caller
|
|
3255
|
+
* to wrap in try/catch.
|
|
3256
|
+
*/
|
|
3257
|
+
type FetchResult = {
|
|
3258
|
+
ok: true;
|
|
3259
|
+
policy: RedemptionPolicy;
|
|
3260
|
+
} | {
|
|
3261
|
+
ok: false;
|
|
3262
|
+
reason: FetchFailureReason;
|
|
3263
|
+
status?: number;
|
|
3264
|
+
};
|
|
3265
|
+
type FetchFailureReason = "TIMEOUT" | "NETWORK" | "NOT_FOUND" | "UNAUTHORIZED" | "SERVER_ERROR" | "INVALID_RESPONSE";
|
|
3266
|
+
declare class SettlementClient {
|
|
3267
|
+
private readonly config;
|
|
3268
|
+
constructor(config: SettlementClientConfig);
|
|
3269
|
+
fetchPolicy(): Promise<FetchResult>;
|
|
3270
|
+
}
|
|
3271
|
+
|
|
3272
|
+
interface UserHistory {
|
|
3273
|
+
/** Total PT redeemed by user in the rolling 24h window. */
|
|
3274
|
+
redeemedLast24hPt: bigint;
|
|
3275
|
+
/** Last redemption timestamp (unix seconds), or null if never. */
|
|
3276
|
+
lastRedeemedAtUnixSec: number | null;
|
|
3277
|
+
}
|
|
3278
|
+
interface EvaluateInput {
|
|
3279
|
+
policy: RedemptionPolicy;
|
|
3280
|
+
policySource: RedemptionPolicySource;
|
|
3281
|
+
history: UserHistory;
|
|
3282
|
+
/** Amount being requested. Pass 0n for a pure preview. */
|
|
3283
|
+
amountPt: bigint;
|
|
3284
|
+
/** Current unix time in seconds (caller-controlled for testability). */
|
|
3285
|
+
nowUnixSec: number;
|
|
3286
|
+
}
|
|
3287
|
+
/**
|
|
3288
|
+
* Pure evaluator. Given a policy + user history snapshot + requested
|
|
3289
|
+
* amount, returns either ALLOW + a preview of the user's remaining
|
|
3290
|
+
* headroom, or DENY + the first failing rule.
|
|
3291
|
+
*
|
|
3292
|
+
* Preview is always populated, even on denial — UI uses it to render
|
|
3293
|
+
* "X PT redeemable now" / "next available at HH:MM" regardless.
|
|
3294
|
+
*/
|
|
3295
|
+
declare function evaluateRedemption(input: EvaluateInput): RedemptionDecision;
|
|
3296
|
+
declare const REDEMPTION_HISTORY_WINDOW_SEC: number;
|
|
3297
|
+
|
|
3298
|
+
/**
|
|
3299
|
+
* In-memory IRedemptionHistoryStore for tests + the bundled NestJS
|
|
3300
|
+
* example. Production issuers should implement this against their
|
|
3301
|
+
* existing burn/audit table — sumRedeemedSince is hot path on every
|
|
3302
|
+
* redemption preview.
|
|
3303
|
+
*/
|
|
3304
|
+
declare class MemoryRedemptionHistoryStore implements IRedemptionHistoryStore {
|
|
3305
|
+
private readonly entries;
|
|
3306
|
+
sumRedeemedSince(user: Address, sinceUnixSec: number, pointTokenAddress?: Address): Promise<bigint>;
|
|
3307
|
+
getLastRedeemedAtUnixSec(user: Address, pointTokenAddress?: Address): Promise<number | null>;
|
|
3308
|
+
recordRedemption(entry: {
|
|
3309
|
+
user: Address;
|
|
3310
|
+
amountPt: bigint;
|
|
3311
|
+
pointTokenAddress?: Address;
|
|
3312
|
+
unixSec: number;
|
|
3313
|
+
}): Promise<void>;
|
|
3314
|
+
}
|
|
3315
|
+
|
|
2869
3316
|
declare const PAFI_ISSUER_SDK_VERSION: string;
|
|
2870
3317
|
|
|
2871
|
-
export { AdapterMisconfiguredError, type ApiConfigResponse, type ApiGasFeeResponse, type ApiLoginRequest, type ApiLoginResponse, type ApiNonceResponse, type ApiPoolsRequest, type ApiPoolsResponse, type ApiUserRequest, type ApiUserResponse, type AuthContext, AuthError, type AuthErrorCode, AuthService, type AuthServiceConfig, BalanceAggregator, type BalanceAggregatorConfig, BundlerNotConfiguredError, BundlerRejectedError, type BurnEvent, BurnIndexer, type BurnIndexerConfig, type BurnStatusParams, type BurnStatusResponse, type ClaimDto, type CombinedBalance, type ConfigDto, ConfigurationError, type DecodedCallDto, DefaultPolicyEngine, type DefaultPolicyEngineOptions, type DelegatePrepareDto, type DelegateStatusDto, FeeManager, type FeeManagerConfig, type GasFeeDto, type HandleDelegateSubmitParams, type HandleDelegateSubmitResult, type HandleMobilePrepareParams, type HandleMobilePrepareResult, type HandleMobileSubmitParams, type IIndexerCursorStore, type IPendingUserOpStore, type IPointLedger, type IPolicyEngine, type ISessionStore, InMemoryCursorStore, IssuerApiAdapter, type IssuerApiAdapterConfig, IssuerApiHandlers, type IssuerApiHandlersConfig, type IssuerRegistryRecord, type IssuerService, type IssuerServiceConfig, IssuerStateError, IssuerStateValidator, LockNotFoundError, type LockedMintRequest, type LoginResult, MemoryPendingUserOpStore, MemorySessionStore, type MemorySessionStoreOptions, type MintEvent, type MintStatusParams, type MintStatusResponse, type MintingStatus, type MobilePrepareDto, type MobileSubmitDto, type NativePtQuoterConfig, NonceManager, PAFI_ISSUER_SDK_VERSION, PTClaimError, PTClaimHandler, type PTClaimHandlerConfig, type PTClaimRequest, type PTClaimResponse, PTRedeemError, PTRedeemHandler, type PTRedeemHandlerConfig, type PTRedeemRequest, type PTRedeemResponse, PafiBackendClient, type PafiBackendConfig, PafiBackendError, type PafiBackendErrorCode, type PendingCredit, type PendingUserOpEntry, PendingUserOpForbiddenError, PendingUserOpNotFoundError, type PerpDepositDto, PerpDepositError, PerpDepositHandler, type PerpDepositHandlerConfig, type PerpDepositRequest, type PerpDepositResponse, PointIndexer, type PointIndexerConfig, type PolicyDecision, type PolicyEvalRequest, type PoolsDto, type PoolsProvider, type PreValidateMintResult, type PrepareBurnParams, type PrepareMintParams, type PrepareMobileUserOpParams, type PrepareMobileUserOpResult, type PreparedUserOp, type RedeemDto, type RedeemPrepareDto, RelayError, type RelayErrorCode, RelayService, type RelayUserOpParams, type RelayUserOpRequest, type RelayUserOpResponse, type RequestPaymasterParams, type RetryConfig, type SdkErrorBody, type SdkErrorMapperFactories, type SdkErrorStatus, type SerializedUserOpTypedData, type Session, type SponsorshipRequest, type SponsorshipResponse, type SponsorshipTarget, type SponsorshipUserOp, type SubgraphNativeUsdtQuoterConfig, type SubgraphPoolsProviderConfig, type UserDto, authenticateRequest, createIssuerService, createNativePtQuoter, createSdkErrorMapper, createSubgraphNativeUsdtQuoter, createSubgraphPoolsProvider, handleClaimStatus, handleDelegateSubmit, handleMobilePrepare, handleMobileSubmit, handleRedeemStatus, mergePaymasterFields, prepareMobileUserOp, relayUserOp, requestPaymaster, serializeEntryToJsonRpc, serializeUserOpTypedData };
|
|
3318
|
+
export { AdapterMisconfiguredError, type ApiConfigResponse, type ApiGasFeeResponse, type ApiLoginRequest, type ApiLoginResponse, type ApiNonceResponse, type ApiPoolsRequest, type ApiPoolsResponse, type ApiRedemptionEvaluateRequest, type ApiRedemptionEvaluateResponse, type ApiRedemptionPreviewRequest, type ApiRedemptionPreviewResponse, type ApiUserRequest, type ApiUserResponse, type AuthContext, AuthError, type AuthErrorCode, AuthService, type AuthServiceConfig, BalanceAggregator, type BalanceAggregatorConfig, BundlerNotConfiguredError, BundlerRejectedError, type BurnEvent, BurnIndexer, type BurnIndexerConfig, type BurnStatusParams, type BurnStatusResponse, type ClaimDto, type CombinedBalance, type ConfigDto, ConfigurationError, DEFAULT_REDEMPTION_POLICY, type DecodedCallDto, DefaultPolicyEngine, type DefaultPolicyEngineOptions, type DelegatePrepareDto, type DelegateStatusDto, type EvaluateInput, FeeManager, type FeeManagerConfig, type FetchFailureReason, type FetchResult, type GasFeeDto, type HandleDelegateSubmitParams, type HandleDelegateSubmitResult, type HandleMobilePrepareParams, type HandleMobilePrepareResult, type HandleMobileSubmitParams, type IIndexerCursorStore, type IPendingUserOpStore, type IPointLedger, type IPolicyEngine, type IRateLimiter, type IRedemptionHistoryStore, type ISessionStore, InMemoryCursorStore, IssuerApiAdapter, type IssuerApiAdapterConfig, IssuerApiHandlers, type IssuerApiHandlersConfig, type IssuerRegistryRecord, type IssuerService, type IssuerServiceConfig, IssuerStateError, IssuerStateValidator, LockNotFoundError, type LockedMintRequest, type LoginResult, MemoryPendingUserOpStore, MemoryRateLimiter, MemoryRedemptionHistoryStore, MemorySessionStore, type MemorySessionStoreOptions, type MintEvent, type MintStatusParams, type MintStatusResponse, type MintingStatus, type MobilePrepareDto, type MobileSubmitDto, type NativePtQuoterConfig, NonceManager, NoopRateLimiter, PAFI_ISSUER_SDK_VERSION, PTClaimError, PTClaimHandler, type PTClaimHandlerConfig, type PTClaimRequest, type PTClaimResponse, PTRedeemError, PTRedeemHandler, type PTRedeemHandlerConfig, type PTRedeemRequest, type PTRedeemResponse, PafiBackendClient, type PafiBackendConfig, PafiBackendError, type PafiBackendErrorCode, type PendingCredit, type PendingUserOpEntry, PendingUserOpForbiddenError, PendingUserOpNotFoundError, type PerpDepositDto, PerpDepositError, PerpDepositHandler, type PerpDepositHandlerConfig, type PerpDepositRequest, type PerpDepositResponse, PointIndexer, type PointIndexerConfig, type PolicyDecision, type PolicyEvalRequest, PolicyProvider, type PolicyProviderConfig, type PoolsDto, type PoolsProvider, type PreValidateMintResult, type PrepareBurnParams, type PrepareMintParams, type PrepareMobileUserOpParams, type PrepareMobileUserOpResult, type PreparedUserOp, REDEMPTION_HISTORY_WINDOW_SEC, type RateLimitAction, type RateLimiterConfig, type RedeemDto, type RedeemPrepareDto, RedemptionService, type RedemptionServiceConfig, RelayError, type RelayErrorCode, RelayService, type RelayUserOpParams, type RelayUserOpRequest, type RelayUserOpResponse, type RequestPaymasterParams, type ResolvedPolicy, type RetryConfig, type SdkErrorBody, type SdkErrorMapperFactories, type SdkErrorStatus, type SerializedUserOpTypedData, type Session, SettlementClient, type SettlementClientConfig, type SponsorshipRequest, type SponsorshipResponse, type SponsorshipTarget, type SponsorshipUserOp, type SubgraphNativeUsdtQuoterConfig, type SubgraphPoolsProviderConfig, type UserDto, type UserHistory, authenticateRequest, createIssuerService, createNativePtQuoter, createSdkErrorMapper, createSubgraphNativeUsdtQuoter, createSubgraphPoolsProvider, defaultPolicyFor, evaluateRedemption, handleClaimStatus, handleDelegateSubmit, handleMobilePrepare, handleMobileSubmit, handleRedeemStatus, mergePaymasterFields, prepareMobileUserOp, relayUserOp, requestPaymaster, serializeEntryToJsonRpc, serializeUserOpTypedData };
|