@pafi-dev/issuer 0.39.2 → 0.39.3

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.js CHANGED
@@ -11,11 +11,16 @@ import {
11
11
  payloadFromGenericError,
12
12
  payloadFromHttpException,
13
13
  payloadFromPafiSdkError
14
- } from "./chunk-QLNGNH4A.js";
15
- import "./chunk-BRKEJJFQ.js";
14
+ } from "./chunk-RNQQYJIB.js";
15
+ import {
16
+ __name
17
+ } from "./chunk-7QVYU63E.js";
16
18
 
17
19
  // src/policy/defaultPolicy.ts
18
20
  var DefaultPolicyEngine = class {
21
+ static {
22
+ __name(this, "DefaultPolicyEngine");
23
+ }
19
24
  ledger;
20
25
  provider;
21
26
  mintingOracleAddress;
@@ -31,20 +36,18 @@ var DefaultPolicyEngine = class {
31
36
  if (opts.resolveIssuer) this.resolveIssuer = opts.resolveIssuer;
32
37
  if (!opts.mintingOracleAddress || !opts.provider || !opts.verifyMintCap || !opts.resolveIssuer) {
33
38
  if (process.env.NODE_ENV === "production") {
34
- throw new Error(
35
- "[PAFI] DefaultPolicyEngine: on-chain MintingOracle cap check is required in production. Configure mintingOracleAddress, provider, verifyMintCap, and resolveIssuer."
36
- );
39
+ throw new Error("[PAFI] DefaultPolicyEngine: on-chain MintingOracle cap check is required in production. Configure mintingOracleAddress, provider, verifyMintCap, and resolveIssuer.");
37
40
  }
38
41
  }
39
42
  }
40
43
  async evaluate(request) {
41
44
  if (request.amount <= 0n) {
42
- return { approved: false, reason: "Amount must be positive" };
45
+ return {
46
+ approved: false,
47
+ reason: "Amount must be positive"
48
+ };
43
49
  }
44
- const available = await this.ledger.getBalance(
45
- request.userAddress,
46
- request.pointTokenAddress
47
- );
50
+ const available = await this.ledger.getBalance(request.userAddress, request.pointTokenAddress);
48
51
  if (available < request.amount) {
49
52
  return {
50
53
  approved: false,
@@ -54,12 +57,7 @@ var DefaultPolicyEngine = class {
54
57
  if (this.mintingOracleAddress && this.provider && this.verifyMintCap && this.resolveIssuer) {
55
58
  try {
56
59
  const issuer = await this.resolveIssuer(request.pointTokenAddress);
57
- await this.verifyMintCap(
58
- this.provider,
59
- this.mintingOracleAddress,
60
- issuer,
61
- request.amount
62
- );
60
+ await this.verifyMintCap(this.provider, this.mintingOracleAddress, issuer, request.amount);
63
61
  } catch (err) {
64
62
  const msg = err instanceof Error ? err.message : String(err);
65
63
  return {
@@ -68,7 +66,9 @@ var DefaultPolicyEngine = class {
68
66
  };
69
67
  }
70
68
  }
71
- return { approved: true };
69
+ return {
70
+ approved: true
71
+ };
72
72
  }
73
73
  };
74
74
 
@@ -77,17 +77,16 @@ import { randomBytes } from "crypto";
77
77
  import { getAddress } from "viem";
78
78
  var DEFAULT_NONCE_TTL_MS = 5 * 60 * 1e3;
79
79
  var MemorySessionStore = class {
80
+ static {
81
+ __name(this, "MemorySessionStore");
82
+ }
80
83
  nonces = /* @__PURE__ */ new Map();
81
- // nonce → expiresAt
82
84
  sessions = /* @__PURE__ */ new Map();
83
- // tokenId → session
84
85
  nonceTtlMs;
85
86
  now;
86
87
  constructor(opts = {}) {
87
88
  if (process.env.NODE_ENV === "production" && !opts.dangerouslyAllowMemoryStoreInProduction) {
88
- throw new Error(
89
- "[PAFI] MemorySessionStore refuses to start in production (NODE_ENV=production). Multi-pod K8s deploys do not share Map state, so sessions are not revocable across replicas \u2014 `logout` on pod A leaves the token valid on pod B until expiry. Use a Redis-backed session store (see RedisSessionStoreService in gg56-backend or implement your own ISessionStore). To bypass for a single-pod deploy, pass `dangerouslyAllowMemoryStoreInProduction: true`."
90
- );
89
+ throw new Error("[PAFI] MemorySessionStore refuses to start in production (NODE_ENV=production). Multi-pod K8s deploys do not share Map state, so sessions are not revocable across replicas \u2014 `logout` on pod A leaves the token valid on pod B until expiry. Use a Redis-backed session store (see RedisSessionStoreService in gg56-backend or implement your own ISessionStore). To bypass for a single-pod deploy, pass `dangerouslyAllowMemoryStoreInProduction: true`.");
91
90
  }
92
91
  this.nonceTtlMs = opts.nonceTtlMs ?? DEFAULT_NONCE_TTL_MS;
93
92
  this.now = opts.now ?? (() => Date.now());
@@ -127,7 +126,9 @@ var MemorySessionStore = class {
127
126
  this.sessions.delete(tokenId);
128
127
  return null;
129
128
  }
130
- return { ...session };
129
+ return {
130
+ ...session
131
+ };
131
132
  }
132
133
  async revokeSession(tokenId) {
133
134
  this.sessions.delete(tokenId);
@@ -159,18 +160,21 @@ var MemorySessionStore = class {
159
160
 
160
161
  // src/auth/nonceManager.ts
161
162
  var NonceManager = class {
163
+ static {
164
+ __name(this, "NonceManager");
165
+ }
166
+ store;
162
167
  constructor(store) {
163
168
  this.store = store;
164
169
  }
165
- store;
166
170
  /** Generate a fresh login nonce. The store is responsible for TTL. */
167
171
  async generate() {
168
172
  return this.store.createNonce();
169
173
  }
170
174
  /**
171
- * Atomically validate + consume a nonce. Returns `true` iff the nonce
172
- * was known and unexpired (and is now removed from the store).
173
- */
175
+ * Atomically validate + consume a nonce. Returns `true` iff the nonce
176
+ * was known and unexpired (and is now removed from the store).
177
+ */
174
178
  async consume(nonce) {
175
179
  return this.store.consumeNonce(nonce);
176
180
  }
@@ -202,7 +206,11 @@ function statusForCode(code) {
202
206
  return "not_found";
203
207
  }
204
208
  }
209
+ __name(statusForCode, "statusForCode");
205
210
  var AuthError = class extends PafiSdkError {
211
+ static {
212
+ __name(this, "AuthError");
213
+ }
206
214
  code;
207
215
  httpStatus;
208
216
  constructor(code, message) {
@@ -215,37 +223,28 @@ var AuthError = class extends PafiSdkError {
215
223
  // src/auth/loginVerifier.ts
216
224
  function assertJwtSecretStrength(secret) {
217
225
  if (!secret) {
218
- throw new Error(
219
- "AuthService: jwtSecret is required. Generate via `node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\"`"
220
- );
226
+ throw new Error("AuthService: jwtSecret is required. Generate via `node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\"`");
221
227
  }
222
228
  if (secret.length < 32) {
223
- throw new Error(
224
- `AuthService: jwtSecret too short (${secret.length} chars; need \u2265 32). HS256 brute-force becomes feasible below this threshold.`
225
- );
229
+ throw new Error(`AuthService: jwtSecret too short (${secret.length} chars; need \u2265 32). HS256 brute-force becomes feasible below this threshold.`);
226
230
  }
227
231
  const uniqueChars = new Set(secret).size;
228
232
  if (uniqueChars < 16) {
229
- throw new Error(
230
- `AuthService: jwtSecret has only ${uniqueChars} unique characters; need \u2265 16. A trivially weak secret (e.g. "aaaaa...") will pass length but offer almost no entropy. Use \`crypto.randomBytes(32).toString('hex')\`.`
231
- );
233
+ throw new Error(`AuthService: jwtSecret has only ${uniqueChars} unique characters; need \u2265 16. A trivially weak secret (e.g. "aaaaa...") will pass length but offer almost no entropy. Use \`crypto.randomBytes(32).toString('hex')\`.`);
232
234
  }
233
235
  const entropy = shannonEntropyBitsPerChar(secret);
234
236
  if (entropy < 3.5) {
235
- throw new Error(
236
- `AuthService: jwtSecret entropy too low (${entropy.toFixed(2)} bits/char; need \u2265 3.5). Use \`crypto.randomBytes(32).toString('hex')\` (\u2248 4.0 bits/char).`
237
- );
237
+ throw new Error(`AuthService: jwtSecret entropy too low (${entropy.toFixed(2)} bits/char; need \u2265 3.5). Use \`crypto.randomBytes(32).toString('hex')\` (\u2248 4.0 bits/char).`);
238
238
  }
239
239
  for (let period = 1; period <= secret.length / 4; period++) {
240
240
  if (secret.length % period !== 0) continue;
241
241
  const head = secret.slice(0, period);
242
242
  if (secret === head.repeat(secret.length / period)) {
243
- throw new Error(
244
- `AuthService: jwtSecret is a repeating pattern of period ${period}. Use \`crypto.randomBytes(32).toString('hex')\`.`
245
- );
243
+ throw new Error(`AuthService: jwtSecret is a repeating pattern of period ${period}. Use \`crypto.randomBytes(32).toString('hex')\`.`);
246
244
  }
247
245
  }
248
246
  }
247
+ __name(assertJwtSecretStrength, "assertJwtSecretStrength");
249
248
  function shannonEntropyBitsPerChar(s) {
250
249
  const counts = /* @__PURE__ */ new Map();
251
250
  for (const c of s) counts.set(c, (counts.get(c) ?? 0) + 1);
@@ -257,6 +256,7 @@ function shannonEntropyBitsPerChar(s) {
257
256
  }
258
257
  return h;
259
258
  }
259
+ __name(shannonEntropyBitsPerChar, "shannonEntropyBitsPerChar");
260
260
  function decodeExpiredJwtJti(token) {
261
261
  try {
262
262
  const parts = token.split(".");
@@ -266,13 +266,19 @@ function decodeExpiredJwtJti(token) {
266
266
  const padded = payloadB64.replace(/-/g, "+").replace(/_/g, "/") + "===".slice((payloadB64.length + 3) % 4);
267
267
  const json = Buffer.from(padded, "base64").toString("utf-8");
268
268
  const claims = JSON.parse(json);
269
- return typeof claims.jti === "string" ? { jti: claims.jti } : {};
269
+ return typeof claims.jti === "string" ? {
270
+ jti: claims.jti
271
+ } : {};
270
272
  } catch {
271
273
  return {};
272
274
  }
273
275
  }
276
+ __name(decodeExpiredJwtJti, "decodeExpiredJwtJti");
274
277
  var DEFAULT_EXPIRES_IN = "24h";
275
278
  var AuthService = class {
279
+ static {
280
+ __name(this, "AuthService");
281
+ }
276
282
  sessionStore;
277
283
  jwtSecret;
278
284
  jwtExpiresIn;
@@ -302,9 +308,9 @@ var AuthService = class {
302
308
  return this.nonceManager.generate();
303
309
  }
304
310
  /**
305
- * Verify a signed login message and issue a JWT on success.
306
- * Throws an `AuthError` on any validation failure.
307
- */
311
+ * Verify a signed login message and issue a JWT on success.
312
+ * Throws an `AuthError` on any validation failure.
313
+ */
308
314
  async login(message, signature) {
309
315
  let parsed;
310
316
  try {
@@ -314,46 +320,28 @@ var AuthService = class {
314
320
  throw new AuthError("INVALID_MESSAGE", `Could not parse login message: ${msg}`);
315
321
  }
316
322
  if (parsed.expirationTime == null) {
317
- throw new AuthError(
318
- "INVALID_MESSAGE",
319
- "login message must include expirationTime"
320
- );
323
+ throw new AuthError("INVALID_MESSAGE", "login message must include expirationTime");
321
324
  }
322
325
  if (parsed.domain !== this.domain) {
323
- throw new AuthError(
324
- "DOMAIN_MISMATCH",
325
- `Expected domain "${this.domain}", got "${parsed.domain}"`
326
- );
326
+ throw new AuthError("DOMAIN_MISMATCH", `Expected domain "${this.domain}", got "${parsed.domain}"`);
327
327
  }
328
328
  if (parsed.chainId !== this.chainId) {
329
- throw new AuthError(
330
- "CHAIN_MISMATCH",
331
- `Expected chainId ${this.chainId}, got ${parsed.chainId}`
332
- );
329
+ throw new AuthError("CHAIN_MISMATCH", `Expected chainId ${this.chainId}, got ${parsed.chainId}`);
333
330
  }
334
331
  const now = this.now();
335
332
  if (parsed.notBefore && parsed.notBefore.getTime() > now.getTime()) {
336
- throw new AuthError(
337
- "MESSAGE_NOT_YET_VALID",
338
- "Login message is not yet valid"
339
- );
333
+ throw new AuthError("MESSAGE_NOT_YET_VALID", "Login message is not yet valid");
340
334
  }
341
335
  if (parsed.expirationTime && parsed.expirationTime.getTime() <= now.getTime()) {
342
336
  throw new AuthError("MESSAGE_EXPIRED", "Login message has expired");
343
337
  }
344
338
  const verifyResult = await verifyLoginMessage(message, signature);
345
339
  if (!verifyResult.valid) {
346
- throw new AuthError(
347
- "SIGNATURE_INVALID",
348
- "Signature does not match the address in the login message"
349
- );
340
+ throw new AuthError("SIGNATURE_INVALID", "Signature does not match the address in the login message");
350
341
  }
351
342
  const nonceOk = await this.nonceManager.consume(parsed.nonce);
352
343
  if (!nonceOk) {
353
- throw new AuthError(
354
- "NONCE_INVALID",
355
- "Nonce is unknown, expired, or already used"
356
- );
344
+ throw new AuthError("NONCE_INVALID", "Nonce is unknown, expired, or already used");
357
345
  }
358
346
  const userAddress = getAddress2(verifyResult.address);
359
347
  const tokenId = randomBytes2(16).toString("hex");
@@ -370,11 +358,18 @@ var AuthService = class {
370
358
  let signer = new SignJWT({
371
359
  userAddress,
372
360
  chainId: this.chainId
373
- }).setProtectedHeader({ alg: "HS256" }).setJti(tokenId).setIssuedAt(Math.floor(issuedAt.getTime() / 1e3)).setExpirationTime(Math.floor(expiresAt.getTime() / 1e3));
361
+ }).setProtectedHeader({
362
+ alg: "HS256"
363
+ }).setJti(tokenId).setIssuedAt(Math.floor(issuedAt.getTime() / 1e3)).setExpirationTime(Math.floor(expiresAt.getTime() / 1e3));
374
364
  if (this.issuer) signer = signer.setIssuer(this.issuer);
375
365
  if (this.audience) signer = signer.setAudience(this.audience);
376
366
  const token = await signer.sign(this.jwtSecret);
377
- return { token, userAddress, tokenId, expiresAt };
367
+ return {
368
+ token,
369
+ userAddress,
370
+ tokenId,
371
+ expiresAt
372
+ };
378
373
  }
379
374
  /** Revoke the session backing the given JWT (logout). */
380
375
  async logout(token) {
@@ -382,9 +377,12 @@ var AuthService = class {
382
377
  try {
383
378
  const result = await jwtVerify(token, this.jwtSecret, {
384
379
  clockTolerance: 60,
385
- // allow logout right after expiry
386
- ...this.issuer ? { issuer: this.issuer } : {},
387
- ...this.audience ? { audience: this.audience } : {}
380
+ ...this.issuer ? {
381
+ issuer: this.issuer
382
+ } : {},
383
+ ...this.audience ? {
384
+ audience: this.audience
385
+ } : {}
388
386
  });
389
387
  payload = result.payload;
390
388
  } catch (err) {
@@ -402,10 +400,7 @@ var AuthService = class {
402
400
  if (err instanceof joseErrors.JWSSignatureVerificationFailed || err instanceof joseErrors.JWSInvalid || err instanceof joseErrors.JWTInvalid) {
403
401
  throw new AuthError("TOKEN_INVALID", "JWT verification failed");
404
402
  }
405
- throw new AuthError(
406
- "TOKEN_INVALID",
407
- `JWT verification failed: ${err instanceof Error ? err.message : String(err)}`
408
- );
403
+ throw new AuthError("TOKEN_INVALID", `JWT verification failed: ${err instanceof Error ? err.message : String(err)}`);
409
404
  }
410
405
  if (payload.jti) {
411
406
  try {
@@ -421,16 +416,20 @@ var AuthService = class {
421
416
  console.error("[PAFI] AuthService logout: session store error", err);
422
417
  }
423
418
  /**
424
- * Verify a JWT and return the authenticated user context. Throws an
425
- * `AuthError` if the token is missing, malformed, expired, revoked, or
426
- * signed by a different key.
427
- */
419
+ * Verify a JWT and return the authenticated user context. Throws an
420
+ * `AuthError` if the token is missing, malformed, expired, revoked, or
421
+ * signed by a different key.
422
+ */
428
423
  async verifyToken(token) {
429
424
  let payload;
430
425
  try {
431
426
  const result = await jwtVerify(token, this.jwtSecret, {
432
- ...this.issuer ? { issuer: this.issuer } : {},
433
- ...this.audience ? { audience: this.audience } : {}
427
+ ...this.issuer ? {
428
+ issuer: this.issuer
429
+ } : {},
430
+ ...this.audience ? {
431
+ audience: this.audience
432
+ } : {}
434
433
  });
435
434
  payload = result.payload;
436
435
  } catch (err) {
@@ -448,10 +447,7 @@ var AuthService = class {
448
447
  }
449
448
  const session = await this.sessionStore.getSession(tokenId);
450
449
  if (!session) {
451
- throw new AuthError(
452
- "SESSION_REVOKED",
453
- "Session is no longer active (revoked or expired)"
454
- );
450
+ throw new AuthError("SESSION_REVOKED", "Session is no longer active (revoked or expired)");
455
451
  }
456
452
  const userAddress = payload.userAddress;
457
453
  const chainId = payload.chainId;
@@ -468,51 +464,50 @@ var AuthService = class {
468
464
  function parseExpiry(from, expiresIn) {
469
465
  const match = expiresIn.match(/^(\d+)\s*(s|m|h|d)$/i);
470
466
  if (!match) {
471
- throw new Error(
472
- `AuthService: unsupported jwtExpiresIn "${expiresIn}" \u2014 use e.g. "24h"`
473
- );
467
+ throw new Error(`AuthService: unsupported jwtExpiresIn "${expiresIn}" \u2014 use e.g. "24h"`);
474
468
  }
475
469
  const n = Number(match[1]);
476
470
  const unit = match[2].toLowerCase();
477
471
  const multiplier = unit === "s" ? 1e3 : unit === "m" ? 6e4 : unit === "h" ? 36e5 : 864e5;
478
472
  return new Date(from.getTime() + n * multiplier);
479
473
  }
474
+ __name(parseExpiry, "parseExpiry");
480
475
 
481
476
  // src/auth/jwtMiddleware.ts
482
477
  async function authenticateRequest(authHeader, authService) {
483
478
  if (!authHeader) {
484
- throw new AuthError(
485
- "MISSING_TOKEN",
486
- "Authorization header is required"
487
- );
479
+ throw new AuthError("MISSING_TOKEN", "Authorization header is required");
488
480
  }
489
481
  const match = authHeader.match(/^Bearer\s+(\S+)\s*$/i);
490
482
  if (!match) {
491
- throw new AuthError(
492
- "MALFORMED_TOKEN",
493
- "Authorization header must be in the form 'Bearer <token>'"
494
- );
483
+ throw new AuthError("MALFORMED_TOKEN", "Authorization header must be in the form 'Bearer <token>'");
495
484
  }
496
485
  const token = match[1];
497
486
  return authService.verifyToken(token);
498
487
  }
488
+ __name(authenticateRequest, "authenticateRequest");
499
489
 
500
490
  // src/auth/rateLimiter.ts
501
491
  var DEFAULT_LIMITS = {
502
- auth_nonce: { max: 30, windowMs: 6e4 },
503
- // 30 nonces/min ≈ 1 per 2s
504
- auth_login: { max: 5, windowMs: 6e4 }
505
- // 5 logins/min
492
+ auth_nonce: {
493
+ max: 30,
494
+ windowMs: 6e4
495
+ },
496
+ auth_login: {
497
+ max: 5,
498
+ windowMs: 6e4
499
+ }
506
500
  };
507
501
  var MemoryRateLimiter = class {
502
+ static {
503
+ __name(this, "MemoryRateLimiter");
504
+ }
508
505
  buckets = /* @__PURE__ */ new Map();
509
506
  limits;
510
507
  now;
511
508
  constructor(config = {}) {
512
509
  if (process.env.NODE_ENV === "production" && !process.env.PAFI_ALLOW_MEMORY_RATE_LIMITER_IN_PROD) {
513
- console.warn(
514
- "[PAFI] MemoryRateLimiter not safe for multi-pod K8s deploys \u2014 rate counters are NOT shared across replicas, allowing round-robin bypass. Use a Redis-backed IRateLimiter in production."
515
- );
510
+ console.warn("[PAFI] MemoryRateLimiter not safe for multi-pod K8s deploys \u2014 rate counters are NOT shared across replicas, allowing round-robin bypass. Use a Redis-backed IRateLimiter in production.");
516
511
  }
517
512
  this.limits = {
518
513
  ...DEFAULT_LIMITS,
@@ -522,47 +517,62 @@ var MemoryRateLimiter = class {
522
517
  }
523
518
  async consume(key, action) {
524
519
  const limit = this.limits[action];
525
- if (!limit) return { allowed: true };
520
+ if (!limit) return {
521
+ allowed: true
522
+ };
526
523
  const bucketKey = `${action}:${key}`;
527
524
  const now = this.now();
528
525
  const bucket = this.buckets.get(bucketKey);
529
526
  if (!bucket || now - bucket.windowStartedAt >= limit.windowMs) {
530
- this.buckets.set(bucketKey, { count: 1, windowStartedAt: now });
531
- return { allowed: true };
527
+ this.buckets.set(bucketKey, {
528
+ count: 1,
529
+ windowStartedAt: now
530
+ });
531
+ return {
532
+ allowed: true
533
+ };
532
534
  }
533
535
  if (bucket.count < limit.max) {
534
536
  bucket.count += 1;
535
- return { allowed: true };
537
+ return {
538
+ allowed: true
539
+ };
536
540
  }
537
- const retryAfterMs = Math.max(
538
- 0,
539
- bucket.windowStartedAt + limit.windowMs - now
540
- );
541
- return { allowed: false, retryAfterMs };
541
+ const retryAfterMs = Math.max(0, bucket.windowStartedAt + limit.windowMs - now);
542
+ return {
543
+ allowed: false,
544
+ retryAfterMs
545
+ };
542
546
  }
543
547
  /**
544
- * Test helper — clear all buckets. Not part of `IRateLimiter`; only
545
- * exposed on the in-memory impl for unit tests.
546
- */
548
+ * Test helper — clear all buckets. Not part of `IRateLimiter`; only
549
+ * exposed on the in-memory impl for unit tests.
550
+ */
547
551
  reset() {
548
552
  this.buckets.clear();
549
553
  }
550
554
  };
551
555
  var NoopRateLimiter = class {
556
+ static {
557
+ __name(this, "NoopRateLimiter");
558
+ }
552
559
  warned = false;
553
560
  async consume() {
554
561
  if (!this.warned && process.env.NODE_ENV === "production") {
555
- console.warn(
556
- "[PAFI] NoopRateLimiter active \u2014 `/auth/nonce` and `/auth/login` are NOT throttled. Wire a `MemoryRateLimiter` (dev) or Redis-backed impl (prod) via `IssuerApiHandlersConfig.rateLimiter`."
557
- );
562
+ console.warn("[PAFI] NoopRateLimiter active \u2014 `/auth/nonce` and `/auth/login` are NOT throttled. Wire a `MemoryRateLimiter` (dev) or Redis-backed impl (prod) via `IssuerApiHandlersConfig.rateLimiter`.");
558
563
  this.warned = true;
559
564
  }
560
- return { allowed: true };
565
+ return {
566
+ allowed: true
567
+ };
561
568
  }
562
569
  };
563
570
 
564
571
  // src/relay/types.ts
565
572
  var RelayError = class extends PafiSdkError {
573
+ static {
574
+ __name(this, "RelayError");
575
+ }
566
576
  httpStatus = "unprocessable";
567
577
  code;
568
578
  constructor(code, message, cause) {
@@ -575,21 +585,12 @@ var RelayError = class extends PafiSdkError {
575
585
  };
576
586
 
577
587
  // src/relay/relayService.ts
578
- import {
579
- encodeFunctionData,
580
- erc20Abi
581
- } from "viem";
582
- import {
583
- POINT_TOKEN_MINT_SIG_ABI,
584
- POINT_TOKEN_BURN_SIG_ABI,
585
- mintFeeWrapperAbi,
586
- buildPartialUserOperation,
587
- signMintRequest,
588
- getContractAddresses,
589
- quoteOperatorFeePt,
590
- Source
591
- } from "@pafi-dev/core";
588
+ import { encodeFunctionData, erc20Abi } from "viem";
589
+ import { POINT_TOKEN_MINT_SIG_ABI, POINT_TOKEN_BURN_SIG_ABI, mintFeeWrapperAbi, buildPartialUserOperation, signMintRequest, getContractAddresses, quoteOperatorFeePt, Source } from "@pafi-dev/core";
592
590
  var RelayService = class {
591
+ static {
592
+ __name(this, "RelayService");
593
+ }
593
594
  provider;
594
595
  chainId;
595
596
  constructor(config = {}) {
@@ -597,25 +598,28 @@ var RelayService = class {
597
598
  this.chainId = config.chainId;
598
599
  }
599
600
  /**
600
- * Resolve the fee recipient + amount applied to the next UserOp:
601
- *
602
- * - If caller passed an explicit `feeRecipient`, use it (testing
603
- * only — sponsor-relayer's L1 will reject any non-canonical
604
- * recipient with `INSUFFICIENT_FEE`). Otherwise, default to
605
- * `getContractAddresses(chainId).pafiFeeRecipient` when the
606
- * service has a `chainId` configured.
607
- * - If caller passed `feeAmount`, use it. Otherwise, when the
608
- * service has both `provider` + `chainId`, auto-quote via
609
- * `quoteOperatorFeePt`.
610
- * - When the service is unconfigured AND caller passed nothing,
611
- * return `{ feeAmount: 0n, feeRecipient: undefined }` — legacy
612
- * "no fee" behavior, caller must opt in for the gas-reimbursement
613
- * transfer to be added to the batch.
614
- */
601
+ * Resolve the fee recipient + amount applied to the next UserOp:
602
+ *
603
+ * - If caller passed an explicit `feeRecipient`, use it (testing
604
+ * only — sponsor-relayer's L1 will reject any non-canonical
605
+ * recipient with `INSUFFICIENT_FEE`). Otherwise, default to
606
+ * `getContractAddresses(chainId).pafiFeeRecipient` when the
607
+ * service has a `chainId` configured.
608
+ * - If caller passed `feeAmount`, use it. Otherwise, when the
609
+ * service has both `provider` + `chainId`, auto-quote via
610
+ * `quoteOperatorFeePt`.
611
+ * - When the service is unconfigured AND caller passed nothing,
612
+ * return `{ feeAmount: 0n, feeRecipient: undefined }` — legacy
613
+ * "no fee" behavior, caller must opt in for the gas-reimbursement
614
+ * transfer to be added to the batch.
615
+ */
615
616
  async resolveFee(params) {
616
617
  const feeRecipient = params.feeRecipient ?? (this.chainId !== void 0 ? getContractAddresses(this.chainId).pafiFeeRecipient : void 0);
617
618
  if (params.feeAmount !== void 0) {
618
- return { feeAmount: params.feeAmount, feeRecipient };
619
+ return {
620
+ feeAmount: params.feeAmount,
621
+ feeRecipient
622
+ };
619
623
  }
620
624
  if (this.provider && this.chainId !== void 0) {
621
625
  const feeAmount = await quoteOperatorFeePt({
@@ -623,44 +627,39 @@ var RelayService = class {
623
627
  chainId: this.chainId,
624
628
  pointTokenAddress: params.pointTokenAddress,
625
629
  allowStaleFallback: true,
626
- onFallback: (info) => {
627
- console.warn(
628
- `[RelayService] operatorFeeQuoter fallback (${info.source}): ${info.reason} \u2192 using ${info.fallbackValue}`
629
- );
630
- }
630
+ onFallback: /* @__PURE__ */ __name((info) => {
631
+ console.warn(`[RelayService] operatorFeeQuoter fallback (${info.source}): ${info.reason} \u2192 using ${info.fallbackValue}`);
632
+ }, "onFallback")
631
633
  });
632
- return { feeAmount, feeRecipient };
634
+ return {
635
+ feeAmount,
636
+ feeRecipient
637
+ };
633
638
  }
634
- return { feeAmount: 0n, feeRecipient };
639
+ return {
640
+ feeAmount: 0n,
641
+ feeRecipient
642
+ };
635
643
  }
636
644
  /**
637
- * Build an unsigned UserOp for Scenario 1 (Mint) — sig-gated
638
- * `PointToken.mint(to, amount, deadline, minterSig)`.
639
- */
645
+ * Build an unsigned UserOp for Scenario 1 (Mint) — sig-gated
646
+ * `PointToken.mint(to, amount, deadline, minterSig)`.
647
+ */
640
648
  async prepareMint(params) {
641
649
  if (!params.batchExecutorAddress) {
642
- throw new RelayError(
643
- "ENCODE_FAILED",
644
- "prepareMint: batchExecutorAddress required"
645
- );
650
+ throw new RelayError("ENCODE_FAILED", "prepareMint: batchExecutorAddress required");
646
651
  }
647
652
  if (!params.userAddress) {
648
653
  throw new RelayError("ENCODE_FAILED", "prepareMint: userAddress required");
649
654
  }
650
655
  if (!params.pointTokenAddress) {
651
- throw new RelayError(
652
- "ENCODE_FAILED",
653
- "prepareMint: pointTokenAddress required"
654
- );
656
+ throw new RelayError("ENCODE_FAILED", "prepareMint: pointTokenAddress required");
655
657
  }
656
658
  if (params.amount <= 0n) {
657
659
  throw new RelayError("ENCODE_FAILED", "prepareMint: amount must be positive");
658
660
  }
659
661
  if (!params.issuerSignerWallet) {
660
- throw new RelayError(
661
- "ENCODE_FAILED",
662
- "prepareMint: issuerSignerWallet required (for MintRequest EIP-712 signature)"
663
- );
662
+ throw new RelayError("ENCODE_FAILED", "prepareMint: issuerSignerWallet required (for MintRequest EIP-712 signature)");
664
663
  }
665
664
  if (params.deadline <= 0n) {
666
665
  throw new RelayError("ENCODE_FAILED", "prepareMint: deadline must be positive");
@@ -671,35 +670,24 @@ var RelayService = class {
671
670
  }
672
671
  const MAX_DEADLINE_WINDOW = 3600n;
673
672
  if (params.deadline > nowSecs + MAX_DEADLINE_WINDOW) {
674
- throw new RelayError(
675
- "ENCODE_FAILED",
676
- "prepareMint: deadline exceeds maximum allowed window (1 hour)"
677
- );
673
+ throw new RelayError("ENCODE_FAILED", "prepareMint: deadline exceeds maximum allowed window (1 hour)");
678
674
  }
679
675
  const MINT_SOURCE = Source.EQUITY;
680
676
  const useWrapper = params.mintFeeWrapperAddress !== void 0;
681
677
  const receiverForSig = useWrapper ? params.mintFeeWrapperAddress : params.userAddress;
682
678
  let minterSig;
683
679
  try {
684
- const sig = await signMintRequest(
685
- params.issuerSignerWallet,
686
- params.domain,
687
- {
688
- user: params.userAddress,
689
- receiver: receiverForSig,
690
- amount: params.amount,
691
- source: MINT_SOURCE,
692
- nonce: params.mintRequestNonce,
693
- deadline: params.deadline
694
- }
695
- );
680
+ const sig = await signMintRequest(params.issuerSignerWallet, params.domain, {
681
+ user: params.userAddress,
682
+ receiver: receiverForSig,
683
+ amount: params.amount,
684
+ source: MINT_SOURCE,
685
+ nonce: params.mintRequestNonce,
686
+ deadline: params.deadline
687
+ });
696
688
  minterSig = sig.serialized;
697
689
  } catch (err) {
698
- throw new RelayError(
699
- "ENCODE_FAILED",
700
- `prepareMint: failed to sign MintForRequest: ${errorMessage(err)}`,
701
- err
702
- );
690
+ throw new RelayError("ENCODE_FAILED", `prepareMint: failed to sign MintForRequest: ${errorMessage(err)}`, err);
703
691
  }
704
692
  let mintCallData;
705
693
  let mintTarget;
@@ -732,11 +720,7 @@ var RelayService = class {
732
720
  mintTarget = params.pointTokenAddress;
733
721
  }
734
722
  } catch (err) {
735
- throw new RelayError(
736
- "ENCODE_FAILED",
737
- `prepareMint: failed to encode mint call: ${errorMessage(err)}`,
738
- err
739
- );
723
+ throw new RelayError("ENCODE_FAILED", `prepareMint: failed to encode mint call: ${errorMessage(err)}`, err);
740
724
  }
741
725
  const operations = [
742
726
  {
@@ -752,16 +736,10 @@ var RelayService = class {
752
736
  });
753
737
  if (feeAmount > 0n) {
754
738
  if (!feeRecipient) {
755
- throw new RelayError(
756
- "ENCODE_FAILED",
757
- "prepareMint: feeRecipient could not be resolved \u2014 pass `feeRecipient` explicitly or construct RelayService with a `chainId`."
758
- );
739
+ throw new RelayError("ENCODE_FAILED", "prepareMint: feeRecipient could not be resolved \u2014 pass `feeRecipient` explicitly or construct RelayService with a `chainId`.");
759
740
  }
760
741
  if (feeRecipient === "0x0000000000000000000000000000000000000000") {
761
- throw new RelayError(
762
- "ENCODE_FAILED",
763
- "prepareMint: feeRecipient must not be zero address"
764
- );
742
+ throw new RelayError("ENCODE_FAILED", "prepareMint: feeRecipient must not be zero address");
765
743
  }
766
744
  operations.push({
767
745
  target: params.pointTokenAddress,
@@ -769,7 +747,10 @@ var RelayService = class {
769
747
  data: encodeFunctionData({
770
748
  abi: erc20Abi,
771
749
  functionName: "transfer",
772
- args: [feeRecipient, feeAmount]
750
+ args: [
751
+ feeRecipient,
752
+ feeAmount
753
+ ]
773
754
  })
774
755
  });
775
756
  }
@@ -785,29 +766,23 @@ var RelayService = class {
785
766
  });
786
767
  }
787
768
  /**
788
- * Build an unsigned UserOp for Scenario 2 (Burn/Redeem) — sig-gated
789
- * `PointToken.burn(from, amount, deadline, burnerSig)`. Caller
790
- * provides a pre-signed `BurnRequest` + sig bytes (typically from
791
- * `PTRedeemHandler`).
792
- *
793
- * Direct burn (no sig) is not used — every burn goes through the
794
- * issuer-signed `BurnRequest` path.
795
- */
769
+ * Build an unsigned UserOp for Scenario 2 (Burn/Redeem) — sig-gated
770
+ * `PointToken.burn(from, amount, deadline, burnerSig)`. Caller
771
+ * provides a pre-signed `BurnRequest` + sig bytes (typically from
772
+ * `PTRedeemHandler`).
773
+ *
774
+ * Direct burn (no sig) is not used — every burn goes through the
775
+ * issuer-signed `BurnRequest` path.
776
+ */
796
777
  async prepareBurn(params) {
797
778
  if (!params.pointTokenAddress) {
798
779
  throw new RelayError("ENCODE_FAILED", "prepareBurn: pointTokenAddress required");
799
780
  }
800
781
  if (!params.batchExecutorAddress) {
801
- throw new RelayError(
802
- "ENCODE_FAILED",
803
- "prepareBurn: batchExecutorAddress required"
804
- );
782
+ throw new RelayError("ENCODE_FAILED", "prepareBurn: batchExecutorAddress required");
805
783
  }
806
784
  if (!params.burnRequest || !params.burnerSignature) {
807
- throw new RelayError(
808
- "ENCODE_FAILED",
809
- "prepareBurn: burnRequest + burnerSignature required"
810
- );
785
+ throw new RelayError("ENCODE_FAILED", "prepareBurn: burnRequest + burnerSignature required");
811
786
  }
812
787
  let burnCallData;
813
788
  try {
@@ -823,11 +798,7 @@ var RelayService = class {
823
798
  ]
824
799
  });
825
800
  } catch (err) {
826
- throw new RelayError(
827
- "ENCODE_FAILED",
828
- `prepareBurn: failed to encode burn call: ${errorMessage(err)}`,
829
- err
830
- );
801
+ throw new RelayError("ENCODE_FAILED", `prepareBurn: failed to encode burn call: ${errorMessage(err)}`, err);
831
802
  }
832
803
  const operations = [];
833
804
  const { feeAmount, feeRecipient } = await this.resolveFee({
@@ -837,16 +808,10 @@ var RelayService = class {
837
808
  });
838
809
  if (feeAmount > 0n) {
839
810
  if (!feeRecipient) {
840
- throw new RelayError(
841
- "ENCODE_FAILED",
842
- "prepareBurn: feeRecipient could not be resolved \u2014 pass `feeRecipient` explicitly or construct RelayService with a `chainId`."
843
- );
811
+ throw new RelayError("ENCODE_FAILED", "prepareBurn: feeRecipient could not be resolved \u2014 pass `feeRecipient` explicitly or construct RelayService with a `chainId`.");
844
812
  }
845
813
  if (feeRecipient === "0x0000000000000000000000000000000000000000") {
846
- throw new RelayError(
847
- "ENCODE_FAILED",
848
- "prepareBurn: feeRecipient must not be zero address"
849
- );
814
+ throw new RelayError("ENCODE_FAILED", "prepareBurn: feeRecipient must not be zero address");
850
815
  }
851
816
  operations.push({
852
817
  target: params.pointTokenAddress,
@@ -854,7 +819,10 @@ var RelayService = class {
854
819
  data: encodeFunctionData({
855
820
  abi: erc20Abi,
856
821
  functionName: "transfer",
857
- args: [feeRecipient, feeAmount]
822
+ args: [
823
+ feeRecipient,
824
+ feeAmount
825
+ ]
858
826
  })
859
827
  });
860
828
  }
@@ -889,10 +857,10 @@ var RelayService = class {
889
857
  // call seeds the cache; subsequent ones hit it.
890
858
  // =========================================================================
891
859
  /**
892
- * Build a dummy `PartialUserOperation` for the mint scenario, suitable
893
- * for `feeManager.estimateGasFee({ partialUserOp, ... })`. NO signing —
894
- * uses a 65-byte zero signature placeholder.
895
- */
860
+ * Build a dummy `PartialUserOperation` for the mint scenario, suitable
861
+ * for `feeManager.estimateGasFee({ partialUserOp, ... })`. NO signing —
862
+ * uses a 65-byte zero signature placeholder.
863
+ */
896
864
  previewMintUserOp(params) {
897
865
  const useWrapper = params.mintFeeWrapperAddress !== void 0;
898
866
  let mintCallData;
@@ -927,7 +895,13 @@ var RelayService = class {
927
895
  return buildPartialUserOperation({
928
896
  sender: params.userAddress,
929
897
  nonce: params.aaNonce,
930
- operations: [{ target: mintTarget, value: 0n, data: mintCallData }],
898
+ operations: [
899
+ {
900
+ target: mintTarget,
901
+ value: 0n,
902
+ data: mintCallData
903
+ }
904
+ ],
931
905
  // Gas limits ignored by bundler estimate — it computes them.
932
906
  gasLimits: {
933
907
  callGasLimit: 1n,
@@ -953,7 +927,11 @@ var RelayService = class {
953
927
  sender: params.userAddress,
954
928
  nonce: params.aaNonce,
955
929
  operations: [
956
- { target: params.pointTokenAddress, value: 0n, data: burnCallData }
930
+ {
931
+ target: params.pointTokenAddress,
932
+ value: 0n,
933
+ data: burnCallData
934
+ }
957
935
  ],
958
936
  gasLimits: {
959
937
  callGasLimit: 1n,
@@ -967,11 +945,15 @@ var PLACEHOLDER_SIG_65 = `0x${"00".repeat(65)}`;
967
945
  function errorMessage(err) {
968
946
  return err instanceof Error ? err.message : String(err);
969
947
  }
948
+ __name(errorMessage, "errorMessage");
970
949
 
971
950
  // src/relay/feeManager.ts
972
951
  var DEFAULT_GAS_UNITS = 500000n;
973
952
  var DEFAULT_PREMIUM_BPS = 1e4;
974
953
  var FeeManager = class _FeeManager {
954
+ static {
955
+ __name(this, "FeeManager");
956
+ }
975
957
  provider;
976
958
  fallbackGasUnits;
977
959
  gasPremiumBps;
@@ -988,8 +970,7 @@ var FeeManager = class _FeeManager {
988
970
  static FEE_CACHE_TTL_MS = 1e4;
989
971
  constructor(config) {
990
972
  if (!config.provider) throw new Error("FeeManager: provider required");
991
- if (!config.quoteNativeToFee)
992
- throw new Error("FeeManager: quoteNativeToFee required");
973
+ if (!config.quoteNativeToFee) throw new Error("FeeManager: quoteNativeToFee required");
993
974
  this.provider = config.provider;
994
975
  this.fallbackGasUnits = config.gasUnits ?? DEFAULT_GAS_UNITS;
995
976
  this.gasPremiumBps = config.gasPremiumBps ?? DEFAULT_PREMIUM_BPS;
@@ -998,16 +979,16 @@ var FeeManager = class _FeeManager {
998
979
  this.metrics = config.metrics;
999
980
  }
1000
981
  /**
1001
- * Estimate the operator fee for the next sponsored UserOp.
1002
- *
1003
- * Without `opts` → legacy path: `gasUnits × gasPrice × premium →
1004
- * quoteNativeToFee`. Cached for 10 s to absorb bursts.
1005
- *
1006
- * With `opts` AND `bundlerClient` → estimator path. Each call may
1007
- * hit a different bundler-cached result; the SDK does NOT add its
1008
- * own value cache because the estimator's cache TTL is the source
1009
- * of truth for "how long is this estimate good for".
1010
- */
982
+ * Estimate the operator fee for the next sponsored UserOp.
983
+ *
984
+ * Without `opts` → legacy path: `gasUnits × gasPrice × premium →
985
+ * quoteNativeToFee`. Cached for 10 s to absorb bursts.
986
+ *
987
+ * With `opts` AND `bundlerClient` → estimator path. Each call may
988
+ * hit a different bundler-cached result; the SDK does NOT add its
989
+ * own value cache because the estimator's cache TTL is the source
990
+ * of truth for "how long is this estimate good for".
991
+ */
1011
992
  async estimateGasFee(opts = {}) {
1012
993
  const isLegacyCall = !opts.partialUserOp && !opts.scenario && !opts.contractAddress;
1013
994
  const now = Date.now();
@@ -1017,14 +998,12 @@ var FeeManager = class _FeeManager {
1017
998
  const t0 = Date.now();
1018
999
  const { gasUnits, source } = await this.resolveGasUnits(opts);
1019
1000
  const latencyMs = Date.now() - t0;
1020
- this.safeEmit(
1021
- () => this.metrics?.onEstimate?.({
1022
- source,
1023
- scenario: opts.scenario,
1024
- gasUnits,
1025
- latencyMs
1026
- })
1027
- );
1001
+ this.safeEmit(() => this.metrics?.onEstimate?.({
1002
+ source,
1003
+ scenario: opts.scenario,
1004
+ gasUnits,
1005
+ latencyMs
1006
+ }));
1028
1007
  const gasPrice = await this.provider.getGasPrice();
1029
1008
  const nativeCost = gasPrice * gasUnits;
1030
1009
  const withPremium = nativeCost * BigInt(this.gasPremiumBps) / 10000n;
@@ -1042,7 +1021,10 @@ var FeeManager = class _FeeManager {
1042
1021
  }
1043
1022
  async resolveGasUnits(opts) {
1044
1023
  if (!this.bundlerClient || !opts.partialUserOp || !opts.scenario || !opts.contractAddress) {
1045
- return { gasUnits: this.fallbackGasUnits, source: "fallback" };
1024
+ return {
1025
+ gasUnits: this.fallbackGasUnits,
1026
+ source: "fallback"
1027
+ };
1046
1028
  }
1047
1029
  try {
1048
1030
  const result = await this.bundlerClient.getGasUnits({
@@ -1051,16 +1033,20 @@ var FeeManager = class _FeeManager {
1051
1033
  paymasterAddress: opts.paymasterAddress,
1052
1034
  partialUserOp: opts.partialUserOp
1053
1035
  });
1054
- return { gasUnits: result.gasUnits, source: "estimator" };
1036
+ return {
1037
+ gasUnits: result.gasUnits,
1038
+ source: "estimator"
1039
+ };
1055
1040
  } catch (err) {
1056
1041
  const reason = err instanceof Error ? err.message : String(err);
1057
- this.safeEmit(
1058
- () => this.metrics?.onEstimatorError?.({
1059
- scenario: opts.scenario,
1060
- reason
1061
- })
1062
- );
1063
- return { gasUnits: this.fallbackGasUnits, source: "fallback" };
1042
+ this.safeEmit(() => this.metrics?.onEstimatorError?.({
1043
+ scenario: opts.scenario,
1044
+ reason
1045
+ }));
1046
+ return {
1047
+ gasUnits: this.fallbackGasUnits,
1048
+ source: "fallback"
1049
+ };
1064
1050
  }
1065
1051
  }
1066
1052
  safeEmit(fn) {
@@ -1073,6 +1059,9 @@ var FeeManager = class _FeeManager {
1073
1059
 
1074
1060
  // src/relay/bundlerEstimator.ts
1075
1061
  var PafiEstimatorHttpError = class extends Error {
1062
+ static {
1063
+ __name(this, "PafiEstimatorHttpError");
1064
+ }
1076
1065
  status;
1077
1066
  body;
1078
1067
  constructor(status, body, message) {
@@ -1088,9 +1077,7 @@ function createPafiEstimatorClient(config) {
1088
1077
  if (!issuerId) throw new Error("createPafiEstimatorClient: issuerId required");
1089
1078
  const fetchImpl = config.fetchImpl ?? globalThis.fetch;
1090
1079
  if (!fetchImpl) {
1091
- throw new Error(
1092
- "createPafiEstimatorClient: no fetch implementation available \u2014 pass `fetchImpl`"
1093
- );
1080
+ throw new Error("createPafiEstimatorClient: no fetch implementation available \u2014 pass `fetchImpl`");
1094
1081
  }
1095
1082
  const url = `${baseUrl.replace(/\/$/, "")}/v1/estimate-gas-fee`;
1096
1083
  return {
@@ -1134,15 +1121,19 @@ function createPafiEstimatorClient(config) {
1134
1121
  }
1135
1122
  };
1136
1123
  }
1124
+ __name(createPafiEstimatorClient, "createPafiEstimatorClient");
1137
1125
 
1138
1126
  // src/indexer/types.ts
1139
1127
  var InMemoryCursorStore = class _InMemoryCursorStore {
1128
+ static {
1129
+ __name(this, "InMemoryCursorStore");
1130
+ }
1140
1131
  cursor;
1141
1132
  /**
1142
- * Child stores keyed by `forKey()`. Each child has its own cursor,
1143
- * so a single InMemoryCursorStore can back N PointIndexers in tests
1144
- * / single-process callers.
1145
- */
1133
+ * Child stores keyed by `forKey()`. Each child has its own cursor,
1134
+ * so a single InMemoryCursorStore can back N PointIndexers in tests
1135
+ * / single-process callers.
1136
+ */
1146
1137
  children = /* @__PURE__ */ new Map();
1147
1138
  async load() {
1148
1139
  return this.cursor;
@@ -1163,21 +1154,18 @@ var InMemoryCursorStore = class _InMemoryCursorStore {
1163
1154
  // src/indexer/pointIndexer.ts
1164
1155
  import { getAddress as getAddress3, parseAbiItem } from "viem";
1165
1156
  var PointIndexerFinalizeError = class extends Error {
1166
- constructor(message, context, cause) {
1167
- super(message);
1168
- this.context = context;
1169
- this.cause = cause;
1170
- this.name = "PointIndexerFinalizeError";
1157
+ static {
1158
+ __name(this, "PointIndexerFinalizeError");
1171
1159
  }
1172
1160
  context;
1173
1161
  cause;
1162
+ constructor(message, context, cause) {
1163
+ super(message), this.context = context, this.cause = cause;
1164
+ this.name = "PointIndexerFinalizeError";
1165
+ }
1174
1166
  };
1175
- var TRANSFER_EVENT = parseAbiItem(
1176
- "event Transfer(address indexed from, address indexed to, uint256 value)"
1177
- );
1178
- var MINT_WITH_FEE_EVENT = parseAbiItem(
1179
- "event MintWithFee(address indexed pointToken, address indexed to, uint256 grossAmount, uint256 netAmount, uint256 feeAmount)"
1180
- );
1167
+ var TRANSFER_EVENT = parseAbiItem("event Transfer(address indexed from, address indexed to, uint256 value)");
1168
+ var MINT_WITH_FEE_EVENT = parseAbiItem("event MintWithFee(address indexed pointToken, address indexed to, uint256 grossAmount, uint256 netAmount, uint256 feeAmount)");
1181
1169
  var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
1182
1170
  var DEAD_ADDRESS = "0x000000000000000000000000000000000000dEaD";
1183
1171
  var DEFAULT_CONFIRMATIONS = 3;
@@ -1188,7 +1176,11 @@ function isNoWrapper(addr) {
1188
1176
  const checksummed = getAddress3(addr);
1189
1177
  return checksummed === ZERO_ADDRESS || checksummed === DEAD_ADDRESS;
1190
1178
  }
1179
+ __name(isNoWrapper, "isNoWrapper");
1191
1180
  var PointIndexer = class {
1181
+ static {
1182
+ __name(this, "PointIndexer");
1183
+ }
1192
1184
  provider;
1193
1185
  pointTokenAddress;
1194
1186
  mintFeeWrapperAddress;
@@ -1203,8 +1195,7 @@ var PointIndexer = class {
1203
1195
  timer;
1204
1196
  constructor(config) {
1205
1197
  if (!config.provider) throw new Error("PointIndexer: provider required");
1206
- if (!config.pointTokenAddress)
1207
- throw new Error("PointIndexer: pointTokenAddress required");
1198
+ if (!config.pointTokenAddress) throw new Error("PointIndexer: pointTokenAddress required");
1208
1199
  if (!config.ledger) throw new Error("PointIndexer: ledger required");
1209
1200
  this.provider = config.provider;
1210
1201
  this.pointTokenAddress = getAddress3(config.pointTokenAddress);
@@ -1235,10 +1226,10 @@ var PointIndexer = class {
1235
1226
  }
1236
1227
  }
1237
1228
  /**
1238
- * Run one poll cycle: load cursor → scan [cursor, safeHead] in
1239
- * `batchSize` chunks → persist new cursor. Swallows any error and
1240
- * schedules the next tick. Visible for test harnesses via a public name.
1241
- */
1229
+ * Run one poll cycle: load cursor → scan [cursor, safeHead] in
1230
+ * `batchSize` chunks → persist new cursor. Swallows any error and
1231
+ * schedules the next tick. Visible for test harnesses via a public name.
1232
+ */
1242
1233
  async tick() {
1243
1234
  if (!this.running) return;
1244
1235
  try {
@@ -1273,19 +1264,16 @@ var PointIndexer = class {
1273
1264
  }
1274
1265
  scheduleNext() {
1275
1266
  if (!this.running) return;
1276
- this.timer = setTimeout(
1277
- () => this.tick().catch((err) => this.handleTickError(err)),
1278
- this.pollIntervalMs
1279
- );
1267
+ this.timer = setTimeout(() => this.tick().catch((err) => this.handleTickError(err)), this.pollIntervalMs);
1280
1268
  }
1281
1269
  // -------------------------------------------------------------------------
1282
1270
  // Block scanning
1283
1271
  // -------------------------------------------------------------------------
1284
1272
  /**
1285
- * Scan `[from, to]` inclusive for mint events in `batchSize` chunks.
1286
- * Callers can use this directly to backfill a specific range without
1287
- * engaging `start()`. On completion, the cursor is advanced to `to + 1`.
1288
- */
1273
+ * Scan `[from, to]` inclusive for mint events in `batchSize` chunks.
1274
+ * Callers can use this directly to backfill a specific range without
1275
+ * engaging `start()`. On completion, the cursor is advanced to `to + 1`.
1276
+ */
1289
1277
  async processBlockRange(from, to) {
1290
1278
  if (from > to) return;
1291
1279
  let cursor = from;
@@ -1309,15 +1297,17 @@ var PointIndexer = class {
1309
1297
  // Event fetching — two modes (wrapper vs direct)
1310
1298
  // -------------------------------------------------------------------------
1311
1299
  /**
1312
- * Wrapper mode: listen for `MintWithFee` on the wrapper,
1313
- * filtered to events for THIS pointToken only. The event's `to` field
1314
- * is the actual end user, and `grossAmount` matches the lock amount.
1315
- */
1300
+ * Wrapper mode: listen for `MintWithFee` on the wrapper,
1301
+ * filtered to events for THIS pointToken only. The event's `to` field
1302
+ * is the actual end user, and `grossAmount` matches the lock amount.
1303
+ */
1316
1304
  async fetchWrapperMintEvents(fromBlock, toBlock) {
1317
1305
  const logs = await this.provider.getLogs({
1318
1306
  address: this.mintFeeWrapperAddress,
1319
1307
  event: MINT_WITH_FEE_EVENT,
1320
- args: { pointToken: this.pointTokenAddress },
1308
+ args: {
1309
+ pointToken: this.pointTokenAddress
1310
+ },
1321
1311
  fromBlock,
1322
1312
  toBlock
1323
1313
  });
@@ -1339,14 +1329,16 @@ var PointIndexer = class {
1339
1329
  return out;
1340
1330
  }
1341
1331
  /**
1342
- * Direct mode (legacy / chains without wrapper): listen for
1343
- * `Transfer(from=0x0 → to)` on the PointToken itself.
1344
- */
1332
+ * Direct mode (legacy / chains without wrapper): listen for
1333
+ * `Transfer(from=0x0 → to)` on the PointToken itself.
1334
+ */
1345
1335
  async fetchTransferMintEvents(fromBlock, toBlock) {
1346
1336
  const logs = await this.provider.getLogs({
1347
1337
  address: this.pointTokenAddress,
1348
1338
  event: TRANSFER_EVENT,
1349
- args: { from: ZERO_ADDRESS },
1339
+ args: {
1340
+ from: ZERO_ADDRESS
1341
+ },
1350
1342
  fromBlock,
1351
1343
  toBlock
1352
1344
  });
@@ -1373,42 +1365,30 @@ var PointIndexer = class {
1373
1365
  // Finalization
1374
1366
  // -------------------------------------------------------------------------
1375
1367
  /**
1376
- * Finalize a single mint event: match it to a PENDING lock in the
1377
- * ledger, then call `deductBalance` (which also resolves the lock in
1378
- * the default `MemoryPointLedger`).
1379
- *
1380
- * No-matching-lock is a valid state: it means either the lock already
1381
- * expired, or the mint was authorized out-of-band (e.g. a direct
1382
- * `PointToken.mint()` from an EOA minter for testing). In that case we
1383
- * do NOT touch the ledger — crediting here would silently allow the
1384
- * issuer to mint without going through the gateway.
1385
- */
1368
+ * Finalize a single mint event: match it to a PENDING lock in the
1369
+ * ledger, then call `deductBalance` (which also resolves the lock in
1370
+ * the default `MemoryPointLedger`).
1371
+ *
1372
+ * No-matching-lock is a valid state: it means either the lock already
1373
+ * expired, or the mint was authorized out-of-band (e.g. a direct
1374
+ * `PointToken.mint()` from an EOA minter for testing). In that case we
1375
+ * do NOT touch the ledger — crediting here would silently allow the
1376
+ * issuer to mint without going through the gateway.
1377
+ */
1386
1378
  async finalize(evt) {
1387
- const locks = await this.ledger.getLockedRequests(
1388
- evt.to,
1389
- this.pointTokenAddress
1390
- );
1379
+ const locks = await this.ledger.getLockedRequests(evt.to, this.pointTokenAddress);
1391
1380
  const match = pickMatchingLock(locks, evt.amount);
1392
1381
  if (!match) return;
1393
1382
  try {
1394
- await this.ledger.deductBalance(
1395
- evt.to,
1396
- evt.amount,
1397
- evt.txHash,
1398
- this.pointTokenAddress
1399
- );
1383
+ await this.ledger.deductBalance(evt.to, evt.amount, evt.txHash, this.pointTokenAddress);
1400
1384
  } catch (err) {
1401
- throw new PointIndexerFinalizeError(
1402
- `PointIndexer.deductBalance failed for tx ${evt.txHash} (to=${evt.to}, amount=${evt.amount}, block=${evt.blockNumber}); cursor will NOT advance, next tick retries.`,
1403
- {
1404
- pointToken: this.pointTokenAddress,
1405
- to: evt.to,
1406
- amount: evt.amount,
1407
- txHash: evt.txHash,
1408
- blockNumber: evt.blockNumber
1409
- },
1410
- err
1411
- );
1385
+ throw new PointIndexerFinalizeError(`PointIndexer.deductBalance failed for tx ${evt.txHash} (to=${evt.to}, amount=${evt.amount}, block=${evt.blockNumber}); cursor will NOT advance, next tick retries.`, {
1386
+ pointToken: this.pointTokenAddress,
1387
+ to: evt.to,
1388
+ amount: evt.amount,
1389
+ txHash: evt.txHash,
1390
+ blockNumber: evt.blockNumber
1391
+ }, err);
1412
1392
  }
1413
1393
  try {
1414
1394
  await this.ledger.updateMintStatus(match.lockId, "MINTED", evt.txHash);
@@ -1427,32 +1407,35 @@ function pickMatchingLock(locks, amount) {
1427
1407
  }
1428
1408
  return best;
1429
1409
  }
1410
+ __name(pickMatchingLock, "pickMatchingLock");
1430
1411
 
1431
1412
  // src/indexer/burnIndexer.ts
1432
1413
  import { getAddress as getAddress4, parseAbiItem as parseAbiItem2 } from "viem";
1433
1414
  var BurnIndexerFinalizeError = class extends Error {
1434
- constructor(message, context, cause) {
1435
- super(message);
1436
- this.context = context;
1437
- this.cause = cause;
1438
- this.name = "BurnIndexerFinalizeError";
1415
+ static {
1416
+ __name(this, "BurnIndexerFinalizeError");
1439
1417
  }
1440
1418
  context;
1441
1419
  cause;
1420
+ constructor(message, context, cause) {
1421
+ super(message), this.context = context, this.cause = cause;
1422
+ this.name = "BurnIndexerFinalizeError";
1423
+ }
1442
1424
  };
1443
- var TRANSFER_EVENT2 = parseAbiItem2(
1444
- "event Transfer(address indexed from, address indexed to, uint256 value)"
1445
- );
1425
+ var TRANSFER_EVENT2 = parseAbiItem2("event Transfer(address indexed from, address indexed to, uint256 value)");
1446
1426
  var ZERO_ADDRESS2 = "0x0000000000000000000000000000000000000000";
1447
1427
  var DEFAULT_CONFIRMATIONS2 = 3;
1448
1428
  var DEFAULT_BATCH_SIZE2 = 2000n;
1449
1429
  var DEFAULT_POLL_INTERVAL_MS2 = 5e3;
1450
1430
  var BurnIndexer = class {
1431
+ static {
1432
+ __name(this, "BurnIndexer");
1433
+ }
1451
1434
  provider;
1452
1435
  /**
1453
- * The PointToken this indexer watches. Exposed so callers can key
1454
- * leader-election locks / cursor stores by token
1455
- */
1436
+ * The PointToken this indexer watches. Exposed so callers can key
1437
+ * leader-election locks / cursor stores by token
1438
+ */
1456
1439
  pointTokenAddress;
1457
1440
  ledger;
1458
1441
  cursorStore;
@@ -1466,24 +1449,19 @@ var BurnIndexer = class {
1466
1449
  timer;
1467
1450
  constructor(config) {
1468
1451
  if (!config.provider) throw new Error("BurnIndexer: provider required");
1469
- if (!config.pointTokenAddress)
1470
- throw new Error("BurnIndexer: pointTokenAddress required");
1452
+ if (!config.pointTokenAddress) throw new Error("BurnIndexer: pointTokenAddress required");
1471
1453
  if (!config.ledger) throw new Error("BurnIndexer: ledger required");
1472
1454
  this.provider = config.provider;
1473
1455
  this.pointTokenAddress = config.pointTokenAddress;
1474
1456
  this.ledger = config.ledger;
1475
1457
  this.cursorStore = config.cursorStore ?? new InMemoryCursorStore();
1476
1458
  this.startBlock = config.fromBlock ?? 0n;
1477
- this.confirmations = BigInt(
1478
- config.confirmations ?? DEFAULT_CONFIRMATIONS2
1479
- );
1459
+ this.confirmations = BigInt(config.confirmations ?? DEFAULT_CONFIRMATIONS2);
1480
1460
  this.batchSize = BigInt(config.batchSize ?? Number(DEFAULT_BATCH_SIZE2));
1481
1461
  this.pollIntervalMs = config.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS2;
1482
1462
  if (config.onTickError) this.onTickError = config.onTickError;
1483
1463
  if (!config.matchLockId) {
1484
- throw new Error(
1485
- "BurnIndexer: matchLockId is required. Provide a function that maps a burn event to its pending credit lockId. Without it, no on-chain burns will ever grant off-chain credits."
1486
- );
1464
+ throw new Error("BurnIndexer: matchLockId is required. Provide a function that maps a burn event to its pending credit lockId. Without it, no on-chain burns will ever grant off-chain credits.");
1487
1465
  }
1488
1466
  this.matchLockId = config.matchLockId;
1489
1467
  }
@@ -1533,16 +1511,13 @@ var BurnIndexer = class {
1533
1511
  }
1534
1512
  scheduleNext() {
1535
1513
  if (!this.running) return;
1536
- this.timer = setTimeout(
1537
- () => this.tick().catch((err) => this.handleTickError(err)),
1538
- this.pollIntervalMs
1539
- );
1514
+ this.timer = setTimeout(() => this.tick().catch((err) => this.handleTickError(err)), this.pollIntervalMs);
1540
1515
  }
1541
1516
  /**
1542
- * Scan `[from, to]` inclusive for burn events. Callers can drive this
1543
- * directly to backfill a specific range without `start()`. Cursor is
1544
- * advanced to `to + 1` on completion.
1545
- */
1517
+ * Scan `[from, to]` inclusive for burn events. Callers can drive this
1518
+ * directly to backfill a specific range without `start()`. Cursor is
1519
+ * advanced to `to + 1` on completion.
1520
+ */
1546
1521
  async processBlockRange(from, to) {
1547
1522
  if (from > to) return;
1548
1523
  let cursor = from;
@@ -1551,8 +1526,9 @@ var BurnIndexer = class {
1551
1526
  const logs = await this.provider.getLogs({
1552
1527
  address: this.pointTokenAddress,
1553
1528
  event: TRANSFER_EVENT2,
1554
- args: { to: ZERO_ADDRESS2 },
1555
- // filter: burn = transfer to zero
1529
+ args: {
1530
+ to: ZERO_ADDRESS2
1531
+ },
1556
1532
  fromBlock: cursor,
1557
1533
  toBlock: chunkEnd
1558
1534
  });
@@ -1588,17 +1564,15 @@ var BurnIndexer = class {
1588
1564
  return out;
1589
1565
  }
1590
1566
  /**
1591
- * Resolve a matching pending credit for this burn event and call
1592
- * `ledger.resolveCreditByBurnTx(lockId, txHash)`. If no match found,
1593
- * log + skip.
1594
- */
1567
+ * Resolve a matching pending credit for this burn event and call
1568
+ * `ledger.resolveCreditByBurnTx(lockId, txHash)`. If no match found,
1569
+ * log + skip.
1570
+ */
1595
1571
  async finalize(evt) {
1596
1572
  const txHash = evt.txHash;
1597
1573
  const lockId = await this.matchLockId(evt);
1598
1574
  if (lockId === void 0) {
1599
- console.warn(
1600
- "[PAFI] BurnIndexer: matchLockId returned undefined for burn tx " + txHash + ". This burn will NOT be credited. Implement matchLockId to map burn events to lock IDs."
1601
- );
1575
+ console.warn("[PAFI] BurnIndexer: matchLockId returned undefined for burn tx " + txHash + ". This burn will NOT be credited. Implement matchLockId to map burn events to lock IDs.");
1602
1576
  return;
1603
1577
  }
1604
1578
  if (!this.ledger.resolveCreditByBurnTx) {
@@ -1607,18 +1581,14 @@ var BurnIndexer = class {
1607
1581
  try {
1608
1582
  await this.ledger.resolveCreditByBurnTx(lockId, evt.txHash);
1609
1583
  } catch (err) {
1610
- throw new BurnIndexerFinalizeError(
1611
- `BurnIndexer.resolveCreditByBurnTx failed for tx ${evt.txHash} (lockId=${lockId}, from=${evt.from}, amount=${evt.amount}, block=${evt.blockNumber}); cursor will NOT advance, next tick retries.`,
1612
- {
1613
- pointToken: this.pointTokenAddress,
1614
- from: evt.from,
1615
- amount: evt.amount,
1616
- txHash: evt.txHash,
1617
- blockNumber: evt.blockNumber,
1618
- lockId
1619
- },
1620
- err
1621
- );
1584
+ throw new BurnIndexerFinalizeError(`BurnIndexer.resolveCreditByBurnTx failed for tx ${evt.txHash} (lockId=${lockId}, from=${evt.from}, amount=${evt.amount}, block=${evt.blockNumber}); cursor will NOT advance, next tick retries.`, {
1585
+ pointToken: this.pointTokenAddress,
1586
+ from: evt.from,
1587
+ amount: evt.amount,
1588
+ txHash: evt.txHash,
1589
+ blockNumber: evt.blockNumber,
1590
+ lockId
1591
+ }, err);
1622
1592
  }
1623
1593
  }
1624
1594
  };
@@ -1628,10 +1598,9 @@ function makePostgresSingletonLock(runner) {
1628
1598
  return {
1629
1599
  async acquire(key) {
1630
1600
  const lockId = hashKeyToInt64(key);
1631
- const rows = await runner.query(
1632
- "SELECT pg_try_advisory_lock($1::bigint) AS got",
1633
- [lockId]
1634
- );
1601
+ const rows = await runner.query("SELECT pg_try_advisory_lock($1::bigint) AS got", [
1602
+ lockId
1603
+ ]);
1635
1604
  const got = rows[0]?.got === true;
1636
1605
  if (!got) return null;
1637
1606
  return {
@@ -1647,6 +1616,7 @@ function makePostgresSingletonLock(runner) {
1647
1616
  }
1648
1617
  };
1649
1618
  }
1619
+ __name(makePostgresSingletonLock, "makePostgresSingletonLock");
1650
1620
  function hashKeyToInt64(key) {
1651
1621
  const FNV_OFFSET = 0xcbf29ce484222325n;
1652
1622
  const FNV_PRIME = 0x100000001b3n;
@@ -1661,22 +1631,22 @@ function hashKeyToInt64(key) {
1661
1631
  const signed = hash > SIGNED_MAX ? hash - TWO64 : hash;
1662
1632
  return signed.toString();
1663
1633
  }
1634
+ __name(hashKeyToInt64, "hashKeyToInt64");
1664
1635
 
1665
1636
  // src/api/handlers.ts
1666
1637
  import { getAddress as getAddress5 } from "viem";
1667
- import {
1668
- getMintFeeBps,
1669
- getPointTokenBalance,
1670
- isMinter
1671
- } from "@pafi-dev/core";
1638
+ import { getMintFeeBps, getPointTokenBalance, isMinter } from "@pafi-dev/core";
1672
1639
  var IssuerApiHandlers = class _IssuerApiHandlers {
1640
+ static {
1641
+ __name(this, "IssuerApiHandlers");
1642
+ }
1673
1643
  authService;
1674
1644
  ledger;
1675
1645
  provider;
1676
1646
  /**
1677
- * Set of supported PointToken addresses (checksum-normalized). Handlers
1678
- * validate the request's `pointTokenAddress` against this set.
1679
- */
1647
+ * Set of supported PointToken addresses (checksum-normalized). Handlers
1648
+ * validate the request's `pointTokenAddress` against this set.
1649
+ */
1680
1650
  supportedTokens;
1681
1651
  chainId;
1682
1652
  contracts;
@@ -1687,10 +1657,10 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
1687
1657
  rateLimiter;
1688
1658
  mintFeeWrapperAddress;
1689
1659
  /**
1690
- * Per-token feeBps cache. Refreshed on /config when stale. feeBps
1691
- * changes only when ops calls `wrapper.setRecipients`, so 5-min TTL
1692
- * is more than safe for FE display purposes.
1693
- */
1660
+ * Per-token feeBps cache. Refreshed on /config when stale. feeBps
1661
+ * changes only when ops calls `wrapper.setRecipients`, so 5-min TTL
1662
+ * is more than safe for FE display purposes.
1663
+ */
1694
1664
  feeBpsCache = /* @__PURE__ */ new Map();
1695
1665
  static FEE_BPS_TTL_MS = 5 * 60 * 1e3;
1696
1666
  constructor(config) {
@@ -1698,11 +1668,11 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
1698
1668
  this.ledger = config.ledger;
1699
1669
  this.provider = config.provider;
1700
1670
  this.rateLimiter = config.rateLimiter ?? new NoopRateLimiter();
1701
- const raw = config.pointTokenAddresses && config.pointTokenAddresses.length > 0 ? config.pointTokenAddresses : config.pointTokenAddress ? [config.pointTokenAddress] : [];
1671
+ const raw = config.pointTokenAddresses && config.pointTokenAddresses.length > 0 ? config.pointTokenAddresses : config.pointTokenAddress ? [
1672
+ config.pointTokenAddress
1673
+ ] : [];
1702
1674
  if (raw.length === 0) {
1703
- throw new Error(
1704
- "IssuerApiHandlers: pointTokenAddress or pointTokenAddresses required"
1705
- );
1675
+ throw new Error("IssuerApiHandlers: pointTokenAddress or pointTokenAddresses required");
1706
1676
  }
1707
1677
  const normalized = raw.map((a) => getAddress5(a));
1708
1678
  this.supportedTokens = new Set(normalized);
@@ -1720,63 +1690,48 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
1720
1690
  // Public handlers (no auth required)
1721
1691
  // =========================================================================
1722
1692
  /**
1723
- * `GET /auth/nonce`
1724
- *
1725
- * @param rateLimitKey Caller-side rate-limit key (typically client IP).
1726
- * The HTTP layer (controller/middleware) extracts
1727
- * this from the request and passes it through.
1728
- * When omitted, no rate limit applies — production
1729
- * callers SHOULD always pass a key.
1730
- */
1693
+ * `GET /auth/nonce`
1694
+ *
1695
+ * @param rateLimitKey Caller-side rate-limit key (typically client IP).
1696
+ * The HTTP layer (controller/middleware) extracts
1697
+ * this from the request and passes it through.
1698
+ * When omitted, no rate limit applies — production
1699
+ * callers SHOULD always pass a key.
1700
+ */
1731
1701
  async handleGetNonce(rateLimitKey) {
1732
1702
  if (rateLimitKey) {
1733
- const result = await this.rateLimiter.consume(
1734
- rateLimitKey,
1735
- "auth_nonce"
1736
- );
1703
+ const result = await this.rateLimiter.consume(rateLimitKey, "auth_nonce");
1737
1704
  if (!result.allowed) {
1738
- throw new ValidationError(
1739
- "RATE_LIMIT_EXCEEDED",
1740
- "handleGetNonce: too many requests",
1741
- {
1742
- retryAfterMs: result.retryAfterMs ?? 0,
1743
- action: "auth_nonce"
1744
- }
1745
- );
1705
+ throw new ValidationError("RATE_LIMIT_EXCEEDED", "handleGetNonce: too many requests", {
1706
+ retryAfterMs: result.retryAfterMs ?? 0,
1707
+ action: "auth_nonce"
1708
+ });
1746
1709
  }
1747
1710
  }
1748
1711
  const nonce = await this.authService.getNonce();
1749
- return { nonce };
1712
+ return {
1713
+ nonce
1714
+ };
1750
1715
  }
1751
1716
  /**
1752
- * `POST /auth/login`
1753
- *
1754
- * @param body Login message + signature.
1755
- * @param rateLimitKey Caller-side rate-limit key (typically client IP
1756
- * or `body.userAddress` if known). See `handleGetNonce`.
1757
- */
1717
+ * `POST /auth/login`
1718
+ *
1719
+ * @param body Login message + signature.
1720
+ * @param rateLimitKey Caller-side rate-limit key (typically client IP
1721
+ * or `body.userAddress` if known). See `handleGetNonce`.
1722
+ */
1758
1723
  async handleLogin(body, rateLimitKey) {
1759
1724
  if (rateLimitKey) {
1760
- const result2 = await this.rateLimiter.consume(
1761
- rateLimitKey,
1762
- "auth_login"
1763
- );
1725
+ const result2 = await this.rateLimiter.consume(rateLimitKey, "auth_login");
1764
1726
  if (!result2.allowed) {
1765
- throw new ValidationError(
1766
- "RATE_LIMIT_EXCEEDED",
1767
- "handleLogin: too many requests",
1768
- {
1769
- retryAfterMs: result2.retryAfterMs ?? 0,
1770
- action: "auth_login"
1771
- }
1772
- );
1727
+ throw new ValidationError("RATE_LIMIT_EXCEEDED", "handleLogin: too many requests", {
1728
+ retryAfterMs: result2.retryAfterMs ?? 0,
1729
+ action: "auth_login"
1730
+ });
1773
1731
  }
1774
1732
  }
1775
1733
  if (!body || typeof body.message !== "string" || body.message.length === 0 || typeof body.signature !== "string" || body.signature.length <= 2) {
1776
- throw new ValidationError(
1777
- "INVALID_LOGIN_BODY",
1778
- "handleLogin: message and signature are required"
1779
- );
1734
+ throw new ValidationError("INVALID_LOGIN_BODY", "handleLogin: message and signature are required");
1780
1735
  }
1781
1736
  if (body.message.length > 4096) {
1782
1737
  throw new ValidationError("MESSAGE_TOO_LONG", "message too long");
@@ -1792,11 +1747,11 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
1792
1747
  };
1793
1748
  }
1794
1749
  /**
1795
- * `GET /config?chainId=<id>`
1796
- *
1797
- * Returns the contract addresses and chain id that the frontend SDK
1798
- * needs to build EIP-712 messages and interact with on-chain.
1799
- */
1750
+ * `GET /config?chainId=<id>`
1751
+ *
1752
+ * Returns the contract addresses and chain id that the frontend SDK
1753
+ * needs to build EIP-712 messages and interact with on-chain.
1754
+ */
1800
1755
  async handleConfig(chainId) {
1801
1756
  if (!Number.isInteger(chainId) || chainId <= 0) {
1802
1757
  throw new ValidationError("INVALID_CHAIN_ID", "invalid chainId", {
@@ -1804,11 +1759,10 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
1804
1759
  });
1805
1760
  }
1806
1761
  if (chainId !== this.chainId) {
1807
- throw new ValidationError(
1808
- "UNSUPPORTED_CHAIN_ID",
1809
- `handleConfig: unsupported chainId ${chainId}`,
1810
- { requested: chainId, supported: this.chainId }
1811
- );
1762
+ throw new ValidationError("UNSUPPORTED_CHAIN_ID", `handleConfig: unsupported chainId ${chainId}`, {
1763
+ requested: chainId,
1764
+ supported: this.chainId
1765
+ });
1812
1766
  }
1813
1767
  const contracts = {
1814
1768
  ...this.contracts,
@@ -1822,60 +1776,55 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
1822
1776
  contracts
1823
1777
  };
1824
1778
  if (this.mintFeeWrapperAddress) {
1825
- const byToken = await this.resolveFeeBpsByToken(
1826
- this.mintFeeWrapperAddress
1827
- );
1779
+ const byToken = await this.resolveFeeBpsByToken(this.mintFeeWrapperAddress);
1828
1780
  if (byToken) response.mintFeeBpsByToken = byToken;
1829
1781
  }
1830
1782
  if (this.pafiWebUrl) response.pafiWebUrl = this.pafiWebUrl;
1831
1783
  return response;
1832
1784
  }
1833
1785
  /**
1834
- * Read `totalFeeBps(pointToken)` for every supported PointToken from
1835
- * the wrapper. Cached per-token for 5 minutes. Returns `undefined`
1836
- * (caller drops the field) if every read fails — FE must treat
1837
- * "field missing" as "fee unknown, do not display".
1838
- */
1786
+ * Read `totalFeeBps(pointToken)` for every supported PointToken from
1787
+ * the wrapper. Cached per-token for 5 minutes. Returns `undefined`
1788
+ * (caller drops the field) if every read fails — FE must treat
1789
+ * "field missing" as "fee unknown, do not display".
1790
+ */
1839
1791
  async resolveFeeBpsByToken(wrapper) {
1840
1792
  const now = Date.now();
1841
1793
  const out = {};
1842
1794
  let anyFresh = false;
1843
- await Promise.all(
1844
- Array.from(this.supportedTokens).map(async (token) => {
1845
- const cached = this.feeBpsCache.get(token);
1846
- if (cached && cached.expiresAt > now) {
1795
+ await Promise.all(Array.from(this.supportedTokens).map(async (token) => {
1796
+ const cached = this.feeBpsCache.get(token);
1797
+ if (cached && cached.expiresAt > now) {
1798
+ out[token.toLowerCase()] = cached.value;
1799
+ anyFresh = true;
1800
+ return;
1801
+ }
1802
+ try {
1803
+ const bps = await getMintFeeBps(this.provider, wrapper, token);
1804
+ this.feeBpsCache.set(token, {
1805
+ value: bps,
1806
+ expiresAt: now + _IssuerApiHandlers.FEE_BPS_TTL_MS
1807
+ });
1808
+ out[token.toLowerCase()] = bps;
1809
+ anyFresh = true;
1810
+ } catch {
1811
+ if (cached) {
1847
1812
  out[token.toLowerCase()] = cached.value;
1848
1813
  anyFresh = true;
1849
- return;
1850
1814
  }
1851
- try {
1852
- const bps = await getMintFeeBps(this.provider, wrapper, token);
1853
- this.feeBpsCache.set(token, {
1854
- value: bps,
1855
- expiresAt: now + _IssuerApiHandlers.FEE_BPS_TTL_MS
1856
- });
1857
- out[token.toLowerCase()] = bps;
1858
- anyFresh = true;
1859
- } catch {
1860
- if (cached) {
1861
- out[token.toLowerCase()] = cached.value;
1862
- anyFresh = true;
1863
- }
1864
- }
1865
- })
1866
- );
1815
+ }
1816
+ }));
1867
1817
  return anyFresh ? out : void 0;
1868
1818
  }
1869
1819
  /** `GET /gas-fee` — quoted in USDT (6-decimal base units). */
1870
1820
  async handleGasFee() {
1871
1821
  if (!this.feeManager) {
1872
- throw new ConfigurationError(
1873
- "FEE_MANAGER_NOT_CONFIGURED",
1874
- "handleGasFee: feeManager is not configured on this issuer"
1875
- );
1822
+ throw new ConfigurationError("FEE_MANAGER_NOT_CONFIGURED", "handleGasFee: feeManager is not configured on this issuer");
1876
1823
  }
1877
1824
  const gasFeeUsdt = await this.feeManager.estimateGasFee();
1878
- return { gasFeeUsdt };
1825
+ return {
1826
+ gasFeeUsdt
1827
+ };
1879
1828
  }
1880
1829
  // =========================================================================
1881
1830
  // Protected handlers (JWT required — userAddress extracted by middleware)
@@ -1885,57 +1834,49 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
1885
1834
  await this.authService.logout(token);
1886
1835
  }
1887
1836
  /**
1888
- * `GET /pools?chainId=<id>&pointToken=<addr>`
1889
- *
1890
- * Delegates to the injected `PoolsProvider`. The handler itself does
1891
- * not know where pools come from — that's an issuer decision.
1892
- */
1837
+ * `GET /pools?chainId=<id>&pointToken=<addr>`
1838
+ *
1839
+ * Delegates to the injected `PoolsProvider`. The handler itself does
1840
+ * not know where pools come from — that's an issuer decision.
1841
+ */
1893
1842
  async handlePools(_userAddress, request) {
1894
1843
  if (!this.poolsProvider) {
1895
- throw new ConfigurationError(
1896
- "POOLS_PROVIDER_NOT_CONFIGURED",
1897
- "handlePools: poolsProvider is not configured on this issuer"
1898
- );
1844
+ throw new ConfigurationError("POOLS_PROVIDER_NOT_CONFIGURED", "handlePools: poolsProvider is not configured on this issuer");
1899
1845
  }
1900
1846
  if (request.chainId !== this.chainId) {
1901
- throw new ValidationError(
1902
- "UNSUPPORTED_CHAIN_ID",
1903
- `handlePools: unsupported chainId ${request.chainId}`,
1904
- { requested: request.chainId, supported: this.chainId }
1905
- );
1847
+ throw new ValidationError("UNSUPPORTED_CHAIN_ID", `handlePools: unsupported chainId ${request.chainId}`, {
1848
+ requested: request.chainId,
1849
+ supported: this.chainId
1850
+ });
1906
1851
  }
1907
1852
  return this.poolsProvider(request);
1908
1853
  }
1909
1854
  /**
1910
- * `GET /user?chainId=<id>&user=<addr>&pointToken=<addr>`
1911
- *
1912
- * Returns per-user state the frontend needs to build a fresh mint:
1913
- * on-chain nonces + minter status + off-chain balance.
1914
- */
1855
+ * `GET /user?chainId=<id>&user=<addr>&pointToken=<addr>`
1856
+ *
1857
+ * Returns per-user state the frontend needs to build a fresh mint:
1858
+ * on-chain nonces + minter status + off-chain balance.
1859
+ */
1915
1860
  async handleUser(userAddress, request) {
1916
1861
  if (request.chainId !== this.chainId) {
1917
- throw new ValidationError(
1918
- "UNSUPPORTED_CHAIN_ID",
1919
- `handleUser: unsupported chainId ${request.chainId}`,
1920
- { requested: request.chainId, supported: this.chainId }
1921
- );
1862
+ throw new ValidationError("UNSUPPORTED_CHAIN_ID", `handleUser: unsupported chainId ${request.chainId}`, {
1863
+ requested: request.chainId,
1864
+ supported: this.chainId
1865
+ });
1922
1866
  }
1923
1867
  const normalizedAuthed = getAddress5(userAddress);
1924
1868
  const normalizedRequest = getAddress5(request.userAddress);
1925
1869
  if (normalizedAuthed !== normalizedRequest) {
1926
- throw new ValidationError(
1927
- "USER_ADDRESS_MISMATCH",
1928
- "handleUser: request userAddress must match authenticated user",
1929
- { authenticated: normalizedAuthed, requested: normalizedRequest }
1930
- );
1870
+ throw new ValidationError("USER_ADDRESS_MISMATCH", "handleUser: request userAddress must match authenticated user", {
1871
+ authenticated: normalizedAuthed,
1872
+ requested: normalizedRequest
1873
+ });
1931
1874
  }
1932
1875
  const pointToken = getAddress5(request.pointTokenAddress);
1933
1876
  if (!this.supportedTokens.has(pointToken)) {
1934
- throw new ValidationError(
1935
- "UNSUPPORTED_POINT_TOKEN",
1936
- `handleUser: unsupported pointToken ${pointToken}`,
1937
- { requested: pointToken }
1938
- );
1877
+ throw new ValidationError("UNSUPPORTED_POINT_TOKEN", `handleUser: unsupported pointToken ${pointToken}`, {
1878
+ requested: pointToken
1879
+ });
1939
1880
  }
1940
1881
  const [offChainBalance, onChainBalance, minter] = await Promise.all([
1941
1882
  this.ledger.getBalance(normalizedAuthed, pointToken),
@@ -1947,7 +1888,6 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
1947
1888
  onChainBalance,
1948
1889
  totalBalance: offChainBalance + onChainBalance,
1949
1890
  balance: offChainBalance,
1950
- // deprecated alias
1951
1891
  isMinter: minter
1952
1892
  };
1953
1893
  }
@@ -1955,56 +1895,41 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
1955
1895
  // removed in 0.5.43 — callers should use `PTClaimHandler` directly or
1956
1896
  // wire `IssuerApiAdapter.claim()` which composes the full flow.
1957
1897
  /**
1958
- * `GET /redemption/preview?pointToken=<addr>`
1959
- *
1960
- * Returns the headroom currently available to `userAddress` under the
1961
- * configured RedemptionPolicy. Pure read — does not record anything.
1962
- * Use this for UI to render "X PT redeemable now / next available at …".
1963
- */
1898
+ * `GET /redemption/preview?pointToken=<addr>`
1899
+ *
1900
+ * Returns the headroom currently available to `userAddress` under the
1901
+ * configured RedemptionPolicy. Pure read — does not record anything.
1902
+ * Use this for UI to render "X PT redeemable now / next available at …".
1903
+ */
1964
1904
  async handleRedemptionPreview(userAddress, request) {
1965
1905
  if (!this.redemption) {
1966
- throw new ConfigurationError(
1967
- "REDEMPTION_NOT_CONFIGURED",
1968
- "handleRedemptionPreview: redemption is not configured on this issuer"
1969
- );
1906
+ throw new ConfigurationError("REDEMPTION_NOT_CONFIGURED", "handleRedemptionPreview: redemption is not configured on this issuer");
1970
1907
  }
1971
1908
  const tokenAddress = request.pointTokenAddress ? this.requireSupportedToken(getAddress5(request.pointTokenAddress), "handleRedemptionPreview") : void 0;
1972
- const preview = await this.redemption.preview(
1973
- getAddress5(userAddress),
1974
- tokenAddress
1975
- );
1909
+ const preview = await this.redemption.preview(getAddress5(userAddress), tokenAddress);
1976
1910
  return preview;
1977
1911
  }
1978
1912
  /**
1979
- * `POST /redemption/evaluate`
1980
- *
1981
- * Pre-flight check before the issuer signs a BurnRequest. Returns
1982
- * { allowed, denial?, preview }. Caller (the burn-orchestrator) MUST
1983
- * re-check on the actual initiate path — evaluate is read-only and a
1984
- * caller could race two requests under the same headroom. The intended
1985
- * write path is: evaluate → sign BurnRequest → reserve pending credit
1986
- * → call `service.redemption.recordSuccessfulInitiate()`.
1987
- */
1913
+ * `POST /redemption/evaluate`
1914
+ *
1915
+ * Pre-flight check before the issuer signs a BurnRequest. Returns
1916
+ * { allowed, denial?, preview }. Caller (the burn-orchestrator) MUST
1917
+ * re-check on the actual initiate path — evaluate is read-only and a
1918
+ * caller could race two requests under the same headroom. The intended
1919
+ * write path is: evaluate → sign BurnRequest → reserve pending credit
1920
+ * → call `service.redemption.recordSuccessfulInitiate()`.
1921
+ */
1988
1922
  async handleRedemptionEvaluate(userAddress, request) {
1989
1923
  if (!this.redemption) {
1990
- throw new ConfigurationError(
1991
- "REDEMPTION_NOT_CONFIGURED",
1992
- "handleRedemptionEvaluate: redemption is not configured on this issuer"
1993
- );
1924
+ throw new ConfigurationError("REDEMPTION_NOT_CONFIGURED", "handleRedemptionEvaluate: redemption is not configured on this issuer");
1994
1925
  }
1995
1926
  if (request.amountPt <= 0n) {
1996
- throw new ValidationError(
1997
- "INVALID_AMOUNT",
1998
- "handleRedemptionEvaluate: amountPt must be positive",
1999
- { amountPt: request.amountPt.toString() }
2000
- );
1927
+ throw new ValidationError("INVALID_AMOUNT", "handleRedemptionEvaluate: amountPt must be positive", {
1928
+ amountPt: request.amountPt.toString()
1929
+ });
2001
1930
  }
2002
1931
  const tokenAddress = request.pointTokenAddress ? this.requireSupportedToken(getAddress5(request.pointTokenAddress), "handleRedemptionEvaluate") : void 0;
2003
- const decision = await this.redemption.evaluate(
2004
- getAddress5(userAddress),
2005
- request.amountPt,
2006
- tokenAddress
2007
- );
1932
+ const decision = await this.redemption.evaluate(getAddress5(userAddress), request.amountPt, tokenAddress);
2008
1933
  const response = {
2009
1934
  allowed: decision.allowed,
2010
1935
  preview: decision.preview
@@ -2014,11 +1939,9 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
2014
1939
  }
2015
1940
  requireSupportedToken(pointToken, handler) {
2016
1941
  if (!this.supportedTokens.has(pointToken)) {
2017
- throw new ValidationError(
2018
- "UNSUPPORTED_POINT_TOKEN",
2019
- `${handler}: unsupported pointToken ${pointToken}`,
2020
- { requested: pointToken }
2021
- );
1942
+ throw new ValidationError("UNSUPPORTED_POINT_TOKEN", `${handler}: unsupported pointToken ${pointToken}`, {
1943
+ requested: pointToken
1944
+ });
2022
1945
  }
2023
1946
  return pointToken;
2024
1947
  }
@@ -2032,10 +1955,17 @@ var NAME_ABI = [
2032
1955
  name: "name",
2033
1956
  stateMutability: "view",
2034
1957
  inputs: [],
2035
- outputs: [{ type: "string" }]
1958
+ outputs: [
1959
+ {
1960
+ type: "string"
1961
+ }
1962
+ ]
2036
1963
  }
2037
1964
  ];
2038
1965
  var PointTokenDomainResolver = class {
1966
+ static {
1967
+ __name(this, "PointTokenDomainResolver");
1968
+ }
2039
1969
  provider;
2040
1970
  overrides;
2041
1971
  cache = /* @__PURE__ */ new Map();
@@ -2077,17 +2007,14 @@ var PointTokenDomainResolver = class {
2077
2007
 
2078
2008
  // src/api/handlers/ptRedeemHandler.ts
2079
2009
  import { getAddress as getAddress7 } from "viem";
2080
- import {
2081
- signBurnRequest,
2082
- POINT_TOKEN_ABI,
2083
- getPointTokenBalance as getPointTokenBalance2,
2084
- getContractAddresses as getContractAddresses2,
2085
- Source as Source2
2086
- } from "@pafi-dev/core";
2010
+ import { signBurnRequest, POINT_TOKEN_ABI, getPointTokenBalance as getPointTokenBalance2, getContractAddresses as getContractAddresses2, Source as Source2 } from "@pafi-dev/core";
2087
2011
  var DEFAULT_REDEEM_LOCK_MS = 15 * 60 * 1e3;
2088
2012
  var M11_SAFETY_MARGIN_MS = 30 * 1e3;
2089
2013
  var DEFAULT_SIG_DEADLINE_SEC = (DEFAULT_REDEEM_LOCK_MS - M11_SAFETY_MARGIN_MS) / 1e3;
2090
2014
  var PTRedeemError = class extends PafiSdkError {
2015
+ static {
2016
+ __name(this, "PTRedeemError");
2017
+ }
2091
2018
  httpStatus = "unprocessable";
2092
2019
  code;
2093
2020
  policyDenialCode;
@@ -2100,6 +2027,9 @@ var PTRedeemError = class extends PafiSdkError {
2100
2027
  }
2101
2028
  };
2102
2029
  var PTRedeemHandler = class {
2030
+ static {
2031
+ __name(this, "PTRedeemHandler");
2032
+ }
2103
2033
  ledger;
2104
2034
  relayService;
2105
2035
  provider;
@@ -2114,31 +2044,25 @@ var PTRedeemHandler = class {
2114
2044
  now;
2115
2045
  redemptionService;
2116
2046
  /**
2117
- * Per-user in-flight nonce guard (single-process only).
2118
- *
2119
- * Prevents two concurrent requests from reading the same on-chain
2120
- * burnRequestNonce before either has completed, which would produce two
2121
- * signed UserOps with the same nonce — only one succeeds on-chain; the
2122
- * other leaves an orphaned pending credit and a wasted signer call.
2123
- *
2124
- * NOTE: This guard is effective only within a single Node.js process. For
2125
- * multi-instance deployments (k8s, PM2 cluster), enforce mutual exclusion
2126
- * via a distributed lock (Redis SETNX / Postgres advisory lock) keyed on
2127
- * `(userAddress, pointTokenAddress)` BEFORE calling `handle()`.
2128
- */
2047
+ * Per-user in-flight nonce guard (single-process only).
2048
+ *
2049
+ * Prevents two concurrent requests from reading the same on-chain
2050
+ * burnRequestNonce before either has completed, which would produce two
2051
+ * signed UserOps with the same nonce — only one succeeds on-chain; the
2052
+ * other leaves an orphaned pending credit and a wasted signer call.
2053
+ *
2054
+ * NOTE: This guard is effective only within a single Node.js process. For
2055
+ * multi-instance deployments (k8s, PM2 cluster), enforce mutual exclusion
2056
+ * via a distributed lock (Redis SETNX / Postgres advisory lock) keyed on
2057
+ * `(userAddress, pointTokenAddress)` BEFORE calling `handle()`.
2058
+ */
2129
2059
  inFlightNonces = /* @__PURE__ */ new Map();
2130
2060
  constructor(config) {
2131
2061
  if (!config.ledger.reservePendingCredit) {
2132
- throw new PTRedeemError(
2133
- "LEDGER_NOT_SUPPORTED",
2134
- "PTRedeemHandler requires a ledger that implements reservePendingCredit() (v0.3.0+)"
2135
- );
2062
+ throw new PTRedeemError("LEDGER_NOT_SUPPORTED", "PTRedeemHandler requires a ledger that implements reservePendingCredit() (v0.3.0+)");
2136
2063
  }
2137
2064
  if (!config.burnerSignerWallet) {
2138
- throw new PTRedeemError(
2139
- "SIGNING_FAILED",
2140
- "PTRedeemHandler requires burnerSignerWallet (issuer burner signer)"
2141
- );
2065
+ throw new PTRedeemError("SIGNING_FAILED", "PTRedeemHandler requires burnerSignerWallet (issuer burner signer)");
2142
2066
  }
2143
2067
  this.ledger = config.ledger;
2144
2068
  this.relayService = config.relayService;
@@ -2149,10 +2073,7 @@ var PTRedeemHandler = class {
2149
2073
  this.domainResolver = config.domainResolver;
2150
2074
  this.burnerSignerWallet = config.burnerSignerWallet;
2151
2075
  if (!config.supportedTokens) {
2152
- throw new PTRedeemError(
2153
- "UNSUPPORTED_POINT_TOKEN",
2154
- "PTRedeemHandler requires `supportedTokens` (issuer's allow-listed PointToken contracts)."
2155
- );
2076
+ throw new PTRedeemError("UNSUPPORTED_POINT_TOKEN", "PTRedeemHandler requires `supportedTokens` (issuer's allow-listed PointToken contracts).");
2156
2077
  }
2157
2078
  this.supportedTokens = config.supportedTokens;
2158
2079
  if (this.burnerSignerWallet?.account?.type === "local") {
@@ -2163,10 +2084,7 @@ var PTRedeemHandler = class {
2163
2084
  this.now = config.now ?? (() => Date.now());
2164
2085
  const maxAllowedSignatureMs = this.redeemLockDurationMs - M11_SAFETY_MARGIN_MS;
2165
2086
  if (this.signatureDeadlineSeconds * 1e3 > maxAllowedSignatureMs) {
2166
- throw new PTRedeemError(
2167
- "INVALID_AMOUNT",
2168
- `PTRedeemHandler config: signatureDeadlineSeconds (${this.signatureDeadlineSeconds}s) must be at most redeemLockDurationMs - safety margin = ${maxAllowedSignatureMs / 1e3}s (redeemLockDurationMs=${this.redeemLockDurationMs / 1e3}s, safety=${M11_SAFETY_MARGIN_MS / 1e3}s).`
2169
- );
2087
+ throw new PTRedeemError("INVALID_AMOUNT", `PTRedeemHandler config: signatureDeadlineSeconds (${this.signatureDeadlineSeconds}s) must be at most redeemLockDurationMs - safety margin = ${maxAllowedSignatureMs / 1e3}s (redeemLockDurationMs=${this.redeemLockDurationMs / 1e3}s, safety=${M11_SAFETY_MARGIN_MS / 1e3}s).`);
2170
2088
  }
2171
2089
  if (config.redemptionService) {
2172
2090
  this.redemptionService = config.redemptionService;
@@ -2174,46 +2092,31 @@ var PTRedeemHandler = class {
2174
2092
  }
2175
2093
  async handle(request) {
2176
2094
  if (getAddress7(request.authenticatedAddress) !== getAddress7(request.userAddress)) {
2177
- throw new PTRedeemError(
2178
- "UNAUTHORIZED",
2179
- `userAddress (${request.userAddress}) does not match authenticated session (${request.authenticatedAddress})`
2180
- );
2095
+ throw new PTRedeemError("UNAUTHORIZED", `userAddress (${request.userAddress}) does not match authenticated session (${request.authenticatedAddress})`);
2181
2096
  }
2182
2097
  if (request.amount <= 0n) {
2183
2098
  throw new PTRedeemError("INVALID_AMOUNT", "redeem amount must be positive");
2184
2099
  }
2185
2100
  const pointTokenAddress = getAddress7(request.pointTokenAddress);
2186
2101
  if (!this.supportedTokens.has(pointTokenAddress)) {
2187
- throw new PTRedeemError(
2188
- "UNSUPPORTED_POINT_TOKEN",
2189
- `redeem: pointTokenAddress ${pointTokenAddress} is not in the issuer's supported-token allowlist. Check IssuerApiHandlers.supportedTokens and PTRedeemHandler.config.supportedTokens point at the same set.`
2190
- );
2102
+ throw new PTRedeemError("UNSUPPORTED_POINT_TOKEN", `redeem: pointTokenAddress ${pointTokenAddress} is not in the issuer's supported-token allowlist. Check IssuerApiHandlers.supportedTokens and PTRedeemHandler.config.supportedTokens point at the same set.`);
2191
2103
  }
2192
2104
  if (this.redemptionService) {
2193
2105
  let decision;
2194
2106
  try {
2195
- decision = await this.redemptionService.evaluate(
2196
- request.userAddress,
2197
- request.amount,
2198
- pointTokenAddress
2199
- );
2107
+ decision = await this.redemptionService.evaluate(request.userAddress, request.amount, pointTokenAddress);
2200
2108
  } catch (err) {
2201
2109
  const code = err && typeof err === "object" && "code" in err ? err.code : void 0;
2202
2110
  if (code === "POLICY_PROVIDER_UNAVAILABLE") {
2203
- throw new PTRedeemError(
2204
- "REDEMPTION_POLICY_UNAVAILABLE",
2205
- "Redemption policy temporarily unavailable \u2014 please try again shortly."
2206
- );
2111
+ throw new PTRedeemError("REDEMPTION_POLICY_UNAVAILABLE", "Redemption policy temporarily unavailable \u2014 please try again shortly.");
2207
2112
  }
2208
2113
  throw err;
2209
2114
  }
2210
2115
  if (!decision.allowed) {
2211
2116
  const denial = decision.denial;
2212
- throw new PTRedeemError(
2213
- "REDEMPTION_POLICY_DENIED",
2214
- `redemption denied: ${denial.message}`,
2215
- { policyDenialCode: denial.code }
2216
- );
2117
+ throw new PTRedeemError("REDEMPTION_POLICY_DENIED", `redemption denied: ${denial.message}`, {
2118
+ policyDenialCode: denial.code
2119
+ });
2217
2120
  }
2218
2121
  }
2219
2122
  let burnNonce;
@@ -2222,13 +2125,12 @@ var PTRedeemHandler = class {
2222
2125
  address: pointTokenAddress,
2223
2126
  abi: POINT_TOKEN_ABI,
2224
2127
  functionName: "burnRequestNonces",
2225
- args: [request.userAddress]
2128
+ args: [
2129
+ request.userAddress
2130
+ ]
2226
2131
  });
2227
2132
  } catch (err) {
2228
- throw new PTRedeemError(
2229
- "NONCE_READ_FAILED",
2230
- `failed to read burnRequestNonces(${request.userAddress}): ${err instanceof Error ? err.message : String(err)}`
2231
- );
2133
+ throw new PTRedeemError("NONCE_READ_FAILED", `failed to read burnRequestNonces(${request.userAddress}): ${err instanceof Error ? err.message : String(err)}`);
2232
2134
  }
2233
2135
  const nonceKey = `${getAddress7(request.userAddress).toLowerCase()}:${pointTokenAddress.toLowerCase()}`;
2234
2136
  let userNonces = this.inFlightNonces.get(nonceKey);
@@ -2237,10 +2139,7 @@ var PTRedeemHandler = class {
2237
2139
  this.inFlightNonces.set(nonceKey, userNonces);
2238
2140
  }
2239
2141
  if (userNonces.has(burnNonce)) {
2240
- throw new PTRedeemError(
2241
- "NONCE_IN_FLIGHT",
2242
- `A burn request for nonce ${burnNonce} is already in progress for ${request.userAddress} on ${pointTokenAddress}. Retry after the current request completes.`
2243
- );
2142
+ throw new PTRedeemError("NONCE_IN_FLIGHT", `A burn request for nonce ${burnNonce} is already in progress for ${request.userAddress} on ${pointTokenAddress}. Retry after the current request completes.`);
2244
2143
  }
2245
2144
  userNonces.add(burnNonce);
2246
2145
  try {
@@ -2254,12 +2153,8 @@ var PTRedeemHandler = class {
2254
2153
  const referenceMs = this.now();
2255
2154
  const projectedLockExpiresAtMs = referenceMs + this.redeemLockDurationMs;
2256
2155
  const requestedDeadlineSec = Math.floor(referenceMs / 1e3) + this.signatureDeadlineSeconds;
2257
- const lockBoundedDeadlineSec = Math.floor(
2258
- (projectedLockExpiresAtMs - M11_SAFETY_MARGIN_MS) / 1e3
2259
- );
2260
- const previewDeadline = BigInt(
2261
- Math.min(requestedDeadlineSec, lockBoundedDeadlineSec)
2262
- );
2156
+ const lockBoundedDeadlineSec = Math.floor((projectedLockExpiresAtMs - M11_SAFETY_MARGIN_MS) / 1e3);
2157
+ const previewDeadline = BigInt(Math.min(requestedDeadlineSec, lockBoundedDeadlineSec));
2263
2158
  let fee;
2264
2159
  if (request.feeAmount !== void 0) {
2265
2160
  fee = request.feeAmount > 0n ? request.feeAmount : 0n;
@@ -2285,21 +2180,11 @@ var PTRedeemHandler = class {
2285
2180
  }
2286
2181
  const feeRecipient = request.feeRecipient ?? (request.chainId !== void 0 ? getContractAddresses2(request.chainId).pafiFeeRecipient : getContractAddresses2(this.chainId).pafiFeeRecipient);
2287
2182
  if (fee > 0n && fee >= request.amount) {
2288
- throw new PTRedeemError(
2289
- "INVALID_AMOUNT",
2290
- `fee (${fee}) must be strictly less than redeem amount (${request.amount})`
2291
- );
2183
+ throw new PTRedeemError("INVALID_AMOUNT", `fee (${fee}) must be strictly less than redeem amount (${request.amount})`);
2292
2184
  }
2293
- const onChainBalance = await getPointTokenBalance2(
2294
- this.provider,
2295
- pointTokenAddress,
2296
- request.userAddress
2297
- );
2185
+ const onChainBalance = await getPointTokenBalance2(this.provider, pointTokenAddress, request.userAddress);
2298
2186
  if (onChainBalance < request.amount) {
2299
- throw new PTRedeemError(
2300
- "INVALID_AMOUNT",
2301
- `insufficient on-chain PT balance: have ${onChainBalance}, need ${request.amount}`
2302
- );
2187
+ throw new PTRedeemError("INVALID_AMOUNT", `insufficient on-chain PT balance: have ${onChainBalance}, need ${request.amount}`);
2303
2188
  }
2304
2189
  const deadline = previewDeadline;
2305
2190
  const domainName = await this.domainResolver.resolve(pointTokenAddress);
@@ -2321,17 +2206,9 @@ var PTRedeemHandler = class {
2321
2206
  try {
2322
2207
  sponsoredSig = (await signBurnRequest(this.burnerSignerWallet, domain, sponsoredBurnRequest)).serialized;
2323
2208
  } catch (err) {
2324
- throw new PTRedeemError(
2325
- "SIGNING_FAILED",
2326
- `failed to sign sponsored BurnRequest: ${err instanceof Error ? err.message : String(err)}`
2327
- );
2328
- }
2329
- const sponsoredLockId = await this.ledger.reservePendingCredit(
2330
- request.userAddress,
2331
- sponsoredBurnAmount,
2332
- this.redeemLockDurationMs,
2333
- pointTokenAddress
2334
- );
2209
+ throw new PTRedeemError("SIGNING_FAILED", `failed to sign sponsored BurnRequest: ${err instanceof Error ? err.message : String(err)}`);
2210
+ }
2211
+ const sponsoredLockId = await this.ledger.reservePendingCredit(request.userAddress, sponsoredBurnAmount, this.redeemLockDurationMs, pointTokenAddress);
2335
2212
  try {
2336
2213
  const sponsoredUserOp = await this.relayService.prepareBurn({
2337
2214
  mode: "burnWithSig",
@@ -2357,17 +2234,9 @@ var PTRedeemHandler = class {
2357
2234
  try {
2358
2235
  fallbackSig = (await signBurnRequest(this.burnerSignerWallet, domain, fallbackBurnRequest)).serialized;
2359
2236
  } catch (err) {
2360
- throw new PTRedeemError(
2361
- "SIGNING_FAILED",
2362
- `failed to sign fallback BurnRequest: ${err instanceof Error ? err.message : String(err)}`
2363
- );
2237
+ throw new PTRedeemError("SIGNING_FAILED", `failed to sign fallback BurnRequest: ${err instanceof Error ? err.message : String(err)}`);
2364
2238
  }
2365
- const fallbackLockId = await this.ledger.reservePendingCredit(
2366
- request.userAddress,
2367
- request.amount,
2368
- this.redeemLockDurationMs,
2369
- pointTokenAddress
2370
- );
2239
+ const fallbackLockId = await this.ledger.reservePendingCredit(request.userAddress, request.amount, this.redeemLockDurationMs, pointTokenAddress);
2371
2240
  let fallbackUserOp;
2372
2241
  try {
2373
2242
  fallbackUserOp = await this.relayService.prepareBurn({
@@ -2425,15 +2294,11 @@ var PTRedeemHandler = class {
2425
2294
  var DEFAULT_STATUS_CONFIRMATIONS = 3;
2426
2295
  async function isReceiptPastConfirmations(receipt, provider, confirmations, onWarning, handlerName) {
2427
2296
  if (!provider) {
2428
- onWarning?.(
2429
- `${handlerName}: provider missing \u2014 cannot enforce confirmation depth; deferring receipt fallback to on-chain indexer.`
2430
- );
2297
+ onWarning?.(`${handlerName}: provider missing \u2014 cannot enforce confirmation depth; deferring receipt fallback to on-chain indexer.`);
2431
2298
  return false;
2432
2299
  }
2433
2300
  if (!receipt.blockNumber) {
2434
- onWarning?.(
2435
- `${handlerName}: receipt has no blockNumber \u2014 cannot enforce confirmation depth; deferring to indexer.`
2436
- );
2301
+ onWarning?.(`${handlerName}: receipt has no blockNumber \u2014 cannot enforce confirmation depth; deferring to indexer.`);
2437
2302
  return false;
2438
2303
  }
2439
2304
  const requiredConfs = BigInt(confirmations ?? DEFAULT_STATUS_CONFIRMATIONS);
@@ -2441,18 +2306,14 @@ async function isReceiptPastConfirmations(receipt, provider, confirmations, onWa
2441
2306
  try {
2442
2307
  receiptBlock = BigInt(receipt.blockNumber);
2443
2308
  } catch {
2444
- onWarning?.(
2445
- `${handlerName}: malformed receipt blockNumber (${receipt.blockNumber}) \u2014 deferring to indexer.`
2446
- );
2309
+ onWarning?.(`${handlerName}: malformed receipt blockNumber (${receipt.blockNumber}) \u2014 deferring to indexer.`);
2447
2310
  return false;
2448
2311
  }
2449
2312
  let head;
2450
2313
  try {
2451
2314
  head = await provider.getBlockNumber();
2452
2315
  } catch (err) {
2453
- onWarning?.(
2454
- `${handlerName}: getBlockNumber failed (${err instanceof Error ? err.message : String(err)}) \u2014 deferring to indexer.`
2455
- );
2316
+ onWarning?.(`${handlerName}: getBlockNumber failed (${err instanceof Error ? err.message : String(err)}) \u2014 deferring to indexer.`);
2456
2317
  return false;
2457
2318
  }
2458
2319
  const depth = head - receiptBlock;
@@ -2461,7 +2322,11 @@ async function isReceiptPastConfirmations(receipt, provider, confirmations, onWa
2461
2322
  }
2462
2323
  return true;
2463
2324
  }
2464
- var LockNotFoundError = class extends PafiSdkError {
2325
+ __name(isReceiptPastConfirmations, "isReceiptPastConfirmations");
2326
+ var LockNotFoundError = class LockNotFoundError2 extends PafiSdkError {
2327
+ static {
2328
+ __name(this, "LockNotFoundError");
2329
+ }
2465
2330
  code = "LOCK_NOT_FOUND";
2466
2331
  httpStatus = "not_found";
2467
2332
  constructor() {
@@ -2470,14 +2335,9 @@ var LockNotFoundError = class extends PafiSdkError {
2470
2335
  };
2471
2336
  async function handleClaimStatus(params) {
2472
2337
  if (!params.ledger.getMintLock) {
2473
- throw new Error(
2474
- "handleClaimStatus: ledger does not implement `getMintLock` \u2014 implement the optional method on `IPointLedger` or write a custom status handler."
2475
- );
2476
- }
2477
- const lock = await params.ledger.getMintLock(
2478
- params.lockId,
2479
- params.userAddress
2480
- );
2338
+ throw new Error("handleClaimStatus: ledger does not implement `getMintLock` \u2014 implement the optional method on `IPointLedger` or write a custom status handler.");
2339
+ }
2340
+ const lock = await params.ledger.getMintLock(params.lockId, params.userAddress);
2481
2341
  if (!lock || lock.userAddress.toLowerCase() !== params.userAddress.toLowerCase()) {
2482
2342
  throw new LockNotFoundError();
2483
2343
  }
@@ -2485,17 +2345,9 @@ async function handleClaimStatus(params) {
2485
2345
  let txHash = lock.txHash ?? null;
2486
2346
  if (status === "PENDING" && lock.userOpHash && params.pafiBackendClient) {
2487
2347
  try {
2488
- const receipt = await params.pafiBackendClient.getUserOpReceipt(
2489
- lock.userOpHash
2490
- );
2348
+ const receipt = await params.pafiBackendClient.getUserOpReceipt(lock.userOpHash);
2491
2349
  if (receipt) {
2492
- const passesConfirmationDepth = await isReceiptPastConfirmations(
2493
- receipt,
2494
- params.provider,
2495
- params.confirmations,
2496
- params.onWarning,
2497
- "handleClaimStatus"
2498
- );
2350
+ const passesConfirmationDepth = await isReceiptPastConfirmations(receipt, params.provider, params.confirmations, params.onWarning, "handleClaimStatus");
2499
2351
  if (!passesConfirmationDepth) {
2500
2352
  return {
2501
2353
  lockId: lock.lockId,
@@ -2508,46 +2360,31 @@ async function handleClaimStatus(params) {
2508
2360
  }
2509
2361
  if (receipt.success && receipt.txHash) {
2510
2362
  if (!lock.tokenAddress) {
2511
- params.onWarning?.(
2512
- `handleClaimStatus: lock ${lock.lockId} has no tokenAddress; falling back to status-only flip \u2014 atomic debit+flip cannot run on a legacy single-token row. Migrate the ledger to the multi-token schema.`
2513
- );
2363
+ params.onWarning?.(`handleClaimStatus: lock ${lock.lockId} has no tokenAddress; falling back to status-only flip \u2014 atomic debit+flip cannot run on a legacy single-token row. Migrate the ledger to the multi-token schema.`);
2514
2364
  await params.ledger.updateMintStatus(lock.lockId, "MINTED", receipt.txHash).catch((err) => {
2515
- params.onWarning?.(
2516
- `handleClaimStatus: ledger updateMintStatus failed for lock ${lock.lockId}: ${err}`
2517
- );
2365
+ params.onWarning?.(`handleClaimStatus: ledger updateMintStatus failed for lock ${lock.lockId}: ${err}`);
2518
2366
  });
2519
2367
  status = "MINTED";
2520
2368
  txHash = receipt.txHash;
2521
2369
  } else {
2522
2370
  try {
2523
- await params.ledger.deductBalance(
2524
- lock.userAddress,
2525
- lock.amount,
2526
- receipt.txHash,
2527
- lock.tokenAddress
2528
- );
2371
+ await params.ledger.deductBalance(lock.userAddress, lock.amount, receipt.txHash, lock.tokenAddress);
2529
2372
  status = "MINTED";
2530
2373
  txHash = receipt.txHash;
2531
2374
  } catch (deductErr) {
2532
- params.onWarning?.(
2533
- `handleClaimStatus: deductBalance failed for lock ${lock.lockId}: ${deductErr}`
2534
- );
2375
+ params.onWarning?.(`handleClaimStatus: deductBalance failed for lock ${lock.lockId}: ${deductErr}`);
2535
2376
  }
2536
2377
  }
2537
2378
  } else {
2538
2379
  await params.ledger.updateMintStatus(lock.lockId, "FAILED", receipt.txHash).catch((err) => {
2539
- params.onWarning?.(
2540
- `handleClaimStatus: ledger updateMintStatus failed for lock ${lock.lockId}: ${err}`
2541
- );
2380
+ params.onWarning?.(`handleClaimStatus: ledger updateMintStatus failed for lock ${lock.lockId}: ${err}`);
2542
2381
  });
2543
2382
  status = "FAILED";
2544
2383
  txHash = receipt.txHash;
2545
2384
  }
2546
2385
  }
2547
2386
  } catch (err) {
2548
- params.onWarning?.(
2549
- `handleClaimStatus: bundler-receipt fallback failed for lock ${lock.lockId}: ${err}`
2550
- );
2387
+ params.onWarning?.(`handleClaimStatus: bundler-receipt fallback failed for lock ${lock.lockId}: ${err}`);
2551
2388
  }
2552
2389
  }
2553
2390
  return {
@@ -2559,16 +2396,12 @@ async function handleClaimStatus(params) {
2559
2396
  expiresAt: new Date(lock.expiresAt).toISOString()
2560
2397
  };
2561
2398
  }
2399
+ __name(handleClaimStatus, "handleClaimStatus");
2562
2400
  async function handleRedeemStatus(params) {
2563
2401
  if (!params.ledger.getPendingCredit) {
2564
- throw new Error(
2565
- "handleRedeemStatus: ledger does not implement `getPendingCredit` \u2014 implement the optional method on `IPointLedger` or write a custom status handler."
2566
- );
2567
- }
2568
- const credit = await params.ledger.getPendingCredit(
2569
- params.lockId,
2570
- params.userAddress
2571
- );
2402
+ throw new Error("handleRedeemStatus: ledger does not implement `getPendingCredit` \u2014 implement the optional method on `IPointLedger` or write a custom status handler.");
2403
+ }
2404
+ const credit = await params.ledger.getPendingCredit(params.lockId, params.userAddress);
2572
2405
  if (!credit || credit.userAddress.toLowerCase() !== params.userAddress.toLowerCase()) {
2573
2406
  throw new LockNotFoundError();
2574
2407
  }
@@ -2576,33 +2409,21 @@ async function handleRedeemStatus(params) {
2576
2409
  let txHash = credit.txHash ?? null;
2577
2410
  if (status === "PENDING" && credit.userOpHash && params.pafiBackendClient) {
2578
2411
  try {
2579
- const receipt = await params.pafiBackendClient.getUserOpReceipt(
2580
- credit.userOpHash
2581
- );
2412
+ const receipt = await params.pafiBackendClient.getUserOpReceipt(credit.userOpHash);
2582
2413
  if (receipt && receipt.success) {
2583
- const passesConfirmationDepth = await isReceiptPastConfirmations(
2584
- receipt,
2585
- params.provider,
2586
- params.confirmations,
2587
- params.onWarning,
2588
- "handleRedeemStatus"
2589
- );
2414
+ const passesConfirmationDepth = await isReceiptPastConfirmations(receipt, params.provider, params.confirmations, params.onWarning, "handleRedeemStatus");
2590
2415
  if (passesConfirmationDepth) {
2591
2416
  status = "RESOLVED";
2592
2417
  txHash = receipt.txHash;
2593
2418
  if (params.ledger.resolveCreditByBurnTx) {
2594
2419
  await params.ledger.resolveCreditByBurnTx(credit.lockId, receipt.txHash).catch((err) => {
2595
- params.onWarning?.(
2596
- `handleRedeemStatus: resolveCreditByBurnTx failed for lock ${credit.lockId}: ${err}`
2597
- );
2420
+ params.onWarning?.(`handleRedeemStatus: resolveCreditByBurnTx failed for lock ${credit.lockId}: ${err}`);
2598
2421
  });
2599
2422
  }
2600
2423
  }
2601
2424
  }
2602
2425
  } catch (err) {
2603
- params.onWarning?.(
2604
- `handleRedeemStatus: bundler-receipt fallback failed for lock ${credit.lockId}: ${err}`
2605
- );
2426
+ params.onWarning?.(`handleRedeemStatus: bundler-receipt fallback failed for lock ${credit.lockId}: ${err}`);
2606
2427
  }
2607
2428
  }
2608
2429
  return {
@@ -2615,59 +2436,52 @@ async function handleRedeemStatus(params) {
2615
2436
  resolvedAt: credit.resolvedAt ? new Date(credit.resolvedAt).toISOString() : null
2616
2437
  };
2617
2438
  }
2439
+ __name(handleRedeemStatus, "handleRedeemStatus");
2618
2440
 
2619
2441
  // src/api/mobileHandlers.ts
2620
2442
  import { getAddress as getAddress8 } from "viem";
2621
- import {
2622
- ENTRY_POINT_V08,
2623
- parseEip7702DelegatedAddress
2624
- } from "@pafi-dev/core";
2443
+ import { ENTRY_POINT_V08, parseEip7702DelegatedAddress } from "@pafi-dev/core";
2625
2444
 
2626
2445
  // src/userop-store/serialize.ts
2627
2446
  import { serializeUserOpToJsonRpc } from "@pafi-dev/core";
2628
2447
  function serializeEntryToJsonRpc(entry, signature, variant = "sponsored") {
2629
2448
  if (variant === "fallback") {
2630
2449
  if (!entry.fallback) {
2631
- throw new Error(
2632
- "serializeEntryToJsonRpc: variant=fallback requested but the stored entry has no `fallback` branch \u2014 caller should resubmit with variant='sponsored' or re-prepare with a fee configured."
2633
- );
2450
+ throw new Error("serializeEntryToJsonRpc: variant=fallback requested but the stored entry has no `fallback` branch \u2014 caller should resubmit with variant='sponsored' or re-prepare with a fee configured.");
2634
2451
  }
2635
- return serializeUserOpToJsonRpc(
2636
- {
2637
- sender: entry.sender,
2638
- nonce: BigInt(entry.nonce),
2639
- callData: entry.fallback.callData,
2640
- callGasLimit: BigInt(entry.fallback.callGasLimit),
2641
- verificationGasLimit: BigInt(entry.fallback.verificationGasLimit),
2642
- preVerificationGas: BigInt(entry.fallback.preVerificationGas),
2643
- maxFeePerGas: BigInt(entry.maxFeePerGas),
2644
- maxPriorityFeePerGas: BigInt(entry.maxPriorityFeePerGas)
2645
- // intentionally no paymaster — user pays ETH gas
2646
- },
2647
- signature
2648
- );
2649
- }
2650
- return serializeUserOpToJsonRpc(
2651
- {
2452
+ return serializeUserOpToJsonRpc({
2652
2453
  sender: entry.sender,
2653
2454
  nonce: BigInt(entry.nonce),
2654
- callData: entry.callData,
2655
- callGasLimit: BigInt(entry.callGasLimit),
2656
- verificationGasLimit: BigInt(entry.verificationGasLimit),
2657
- preVerificationGas: BigInt(entry.preVerificationGas),
2455
+ callData: entry.fallback.callData,
2456
+ callGasLimit: BigInt(entry.fallback.callGasLimit),
2457
+ verificationGasLimit: BigInt(entry.fallback.verificationGasLimit),
2458
+ preVerificationGas: BigInt(entry.fallback.preVerificationGas),
2658
2459
  maxFeePerGas: BigInt(entry.maxFeePerGas),
2659
- maxPriorityFeePerGas: BigInt(entry.maxPriorityFeePerGas),
2660
- paymaster: entry.paymaster,
2661
- paymasterVerificationGasLimit: entry.paymasterVerificationGasLimit != null ? BigInt(entry.paymasterVerificationGasLimit) : void 0,
2662
- paymasterPostOpGasLimit: entry.paymasterPostOpGasLimit != null ? BigInt(entry.paymasterPostOpGasLimit) : void 0,
2663
- paymasterData: entry.paymasterData
2664
- },
2665
- signature
2666
- );
2460
+ maxPriorityFeePerGas: BigInt(entry.maxPriorityFeePerGas)
2461
+ }, signature);
2462
+ }
2463
+ return serializeUserOpToJsonRpc({
2464
+ sender: entry.sender,
2465
+ nonce: BigInt(entry.nonce),
2466
+ callData: entry.callData,
2467
+ callGasLimit: BigInt(entry.callGasLimit),
2468
+ verificationGasLimit: BigInt(entry.verificationGasLimit),
2469
+ preVerificationGas: BigInt(entry.preVerificationGas),
2470
+ maxFeePerGas: BigInt(entry.maxFeePerGas),
2471
+ maxPriorityFeePerGas: BigInt(entry.maxPriorityFeePerGas),
2472
+ paymaster: entry.paymaster,
2473
+ paymasterVerificationGasLimit: entry.paymasterVerificationGasLimit != null ? BigInt(entry.paymasterVerificationGasLimit) : void 0,
2474
+ paymasterPostOpGasLimit: entry.paymasterPostOpGasLimit != null ? BigInt(entry.paymasterPostOpGasLimit) : void 0,
2475
+ paymasterData: entry.paymasterData
2476
+ }, signature);
2667
2477
  }
2478
+ __name(serializeEntryToJsonRpc, "serializeEntryToJsonRpc");
2668
2479
 
2669
2480
  // src/userop-store/memoryStore.ts
2670
2481
  var MemoryPendingUserOpStore = class {
2482
+ static {
2483
+ __name(this, "MemoryPendingUserOpStore");
2484
+ }
2671
2485
  entries = /* @__PURE__ */ new Map();
2672
2486
  now;
2673
2487
  constructor(now = () => Date.now()) {
@@ -2694,10 +2508,7 @@ var MemoryPendingUserOpStore = class {
2694
2508
  };
2695
2509
 
2696
2510
  // src/userop-store/prepareUserOp.ts
2697
- import {
2698
- buildUserOpTypedData,
2699
- computeUserOpHash
2700
- } from "@pafi-dev/core";
2511
+ import { buildUserOpTypedData, computeUserOpHash } from "@pafi-dev/core";
2701
2512
  function serializeUserOpTypedData(td) {
2702
2513
  return {
2703
2514
  domain: td.domain,
@@ -2709,14 +2520,13 @@ function serializeUserOpTypedData(td) {
2709
2520
  initCode: td.message.initCode,
2710
2521
  callData: td.message.callData,
2711
2522
  accountGasLimits: td.message.accountGasLimits,
2712
- preVerificationGas: `0x${td.message.preVerificationGas.toString(
2713
- 16
2714
- )}`,
2523
+ preVerificationGas: `0x${td.message.preVerificationGas.toString(16)}`,
2715
2524
  gasFees: td.message.gasFees,
2716
2525
  paymasterAndData: td.message.paymasterAndData
2717
2526
  }
2718
2527
  };
2719
2528
  }
2529
+ __name(serializeUserOpTypedData, "serializeUserOpTypedData");
2720
2530
  function mergePaymasterFields(userOp, paymasterFields) {
2721
2531
  if (!paymasterFields) return userOp;
2722
2532
  const merged = {
@@ -2727,36 +2537,27 @@ function mergePaymasterFields(userOp, paymasterFields) {
2727
2537
  }
2728
2538
  return merged;
2729
2539
  }
2540
+ __name(mergePaymasterFields, "mergePaymasterFields");
2730
2541
  function applyPaymasterGasEstimates(partialUserOp, paymasterFields, chainId) {
2731
- const userOp = mergePaymasterFields(
2732
- partialUserOp,
2733
- paymasterFields
2734
- );
2542
+ const userOp = mergePaymasterFields(partialUserOp, paymasterFields);
2735
2543
  return {
2736
2544
  userOp,
2737
2545
  userOpHash: computeUserOpHash(userOp, chainId),
2738
2546
  typedData: serializeUserOpTypedData(buildUserOpTypedData(userOp, chainId))
2739
2547
  };
2740
2548
  }
2549
+ __name(applyPaymasterGasEstimates, "applyPaymasterGasEstimates");
2741
2550
  async function prepareMobileUserOp(params) {
2742
- const sponsored = applyPaymasterGasEstimates(
2743
- params.partialUserOp,
2744
- params.paymasterFields,
2745
- params.chainId
2746
- );
2551
+ const sponsored = applyPaymasterGasEstimates(params.partialUserOp, params.paymasterFields, params.chainId);
2747
2552
  const { userOp, userOpHash } = sponsored;
2748
2553
  let fallback;
2749
2554
  let fallbackEntry;
2750
2555
  if (params.partialUserOpFallback) {
2751
- fallback = applyPaymasterGasEstimates(
2752
- {
2753
- ...params.partialUserOpFallback,
2754
- maxFeePerGas: userOp.maxFeePerGas,
2755
- maxPriorityFeePerGas: userOp.maxPriorityFeePerGas
2756
- },
2757
- void 0,
2758
- params.chainId
2759
- );
2556
+ fallback = applyPaymasterGasEstimates({
2557
+ ...params.partialUserOpFallback,
2558
+ maxFeePerGas: userOp.maxFeePerGas,
2559
+ maxPriorityFeePerGas: userOp.maxPriorityFeePerGas
2560
+ }, void 0, params.chainId);
2760
2561
  fallbackEntry = {
2761
2562
  callData: fallback.userOp.callData,
2762
2563
  callGasLimit: fallback.userOp.callGasLimit.toString(),
@@ -2793,23 +2594,24 @@ async function prepareMobileUserOp(params) {
2793
2594
  entry
2794
2595
  };
2795
2596
  }
2597
+ __name(prepareMobileUserOp, "prepareMobileUserOp");
2796
2598
 
2797
2599
  // src/pafi-backend/types.ts
2798
2600
  var PafiBackendError = class extends Error {
2799
- constructor(code, message, httpStatus, details, opts) {
2800
- super(message);
2801
- this.code = code;
2802
- this.httpStatus = httpStatus;
2803
- this.details = details;
2804
- this.name = "PafiBackendError";
2805
- if (opts?.retryAfter !== void 0) this.retryAfter = opts.retryAfter;
2806
- if (opts?.safeToRetry !== void 0) this.serverSafeToRetry = opts.safeToRetry;
2601
+ static {
2602
+ __name(this, "PafiBackendError");
2807
2603
  }
2808
2604
  code;
2809
2605
  httpStatus;
2810
2606
  details;
2811
2607
  retryAfter;
2812
2608
  serverSafeToRetry;
2609
+ constructor(code, message, httpStatus, details, opts) {
2610
+ super(message), this.code = code, this.httpStatus = httpStatus, this.details = details;
2611
+ this.name = "PafiBackendError";
2612
+ if (opts?.retryAfter !== void 0) this.retryAfter = opts.retryAfter;
2613
+ if (opts?.safeToRetry !== void 0) this.serverSafeToRetry = opts.safeToRetry;
2614
+ }
2813
2615
  get safeToRetry() {
2814
2616
  if (this.serverSafeToRetry !== void 0) return this.serverSafeToRetry;
2815
2617
  switch (this.code) {
@@ -2831,15 +2633,19 @@ var PafiBackendError = class extends Error {
2831
2633
 
2832
2634
  // src/pafi-backend/helpers.ts
2833
2635
  var BundlerNotConfiguredError = class extends PafiSdkError {
2636
+ static {
2637
+ __name(this, "BundlerNotConfiguredError");
2638
+ }
2834
2639
  code = "BUNDLER_NOT_CONFIGURED";
2835
2640
  httpStatus = "service_unavailable";
2836
2641
  constructor() {
2837
- super(
2838
- "PAFI backend client not configured \u2014 set PAFI_BACKEND_URL, PAFI_ISSUER_ID, PAFI_API_KEY to enable mobile submit."
2839
- );
2642
+ super("PAFI backend client not configured \u2014 set PAFI_BACKEND_URL, PAFI_ISSUER_ID, PAFI_API_KEY to enable mobile submit.");
2840
2643
  }
2841
2644
  };
2842
2645
  var BundlerRejectedError = class extends PafiSdkError {
2646
+ static {
2647
+ __name(this, "BundlerRejectedError");
2648
+ }
2843
2649
  code = "BUNDLER_REJECTED";
2844
2650
  httpStatus = "unprocessable";
2845
2651
  cause;
@@ -2861,7 +2667,9 @@ async function requestPaymaster(params) {
2861
2667
  function: fn,
2862
2668
  pointToken: params.pointTokenAddress
2863
2669
  },
2864
- ...params.eip7702Auth ? { eip7702Auth: params.eip7702Auth } : {}
2670
+ ...params.eip7702Auth ? {
2671
+ eip7702Auth: params.eip7702Auth
2672
+ } : {}
2865
2673
  });
2866
2674
  } catch (err) {
2867
2675
  const msg = err instanceof Error ? err.message : String(err);
@@ -2872,6 +2680,7 @@ async function requestPaymaster(params) {
2872
2680
  throw err;
2873
2681
  }
2874
2682
  }
2683
+ __name(requestPaymaster, "requestPaymaster");
2875
2684
  function isTransientPaymasterError(code) {
2876
2685
  switch (code) {
2877
2686
  case "NETWORK_ERROR":
@@ -2884,6 +2693,7 @@ function isTransientPaymasterError(code) {
2884
2693
  return false;
2885
2694
  }
2886
2695
  }
2696
+ __name(isTransientPaymasterError, "isTransientPaymasterError");
2887
2697
  function defaultFunctionForScenario(scenario) {
2888
2698
  switch (scenario) {
2889
2699
  case "mint":
@@ -2898,6 +2708,7 @@ function defaultFunctionForScenario(scenario) {
2898
2708
  return scenario;
2899
2709
  }
2900
2710
  }
2711
+ __name(defaultFunctionForScenario, "defaultFunctionForScenario");
2901
2712
  async function relayUserOp(params) {
2902
2713
  if (!params.client) {
2903
2714
  throw new BundlerNotConfiguredError();
@@ -2908,36 +2719,43 @@ async function relayUserOp(params) {
2908
2719
  entryPoint: params.entryPoint,
2909
2720
  eip7702Auth: params.eip7702Auth
2910
2721
  });
2911
- return { userOpHash: result.userOpHash };
2722
+ return {
2723
+ userOpHash: result.userOpHash
2724
+ };
2912
2725
  } catch (err) {
2913
2726
  const msg = err instanceof Error ? err.message : String(err);
2914
2727
  throw new BundlerRejectedError(msg, err);
2915
2728
  }
2916
2729
  }
2730
+ __name(relayUserOp, "relayUserOp");
2917
2731
 
2918
2732
  // src/api/mobileHandlers.ts
2919
2733
  var PendingUserOpNotFoundError = class extends PafiSdkError {
2734
+ static {
2735
+ __name(this, "PendingUserOpNotFoundError");
2736
+ }
2920
2737
  code = "PENDING_USEROP_NOT_FOUND";
2921
2738
  httpStatus = "not_found";
2922
2739
  constructor(lockId) {
2923
- super(
2924
- `No pending UserOp found for lockId ${lockId} \u2014 it may have expired or already been submitted.`
2925
- );
2740
+ super(`No pending UserOp found for lockId ${lockId} \u2014 it may have expired or already been submitted.`);
2926
2741
  }
2927
2742
  };
2928
2743
  var PendingUserOpForbiddenError = class extends PafiSdkError {
2744
+ static {
2745
+ __name(this, "PendingUserOpForbiddenError");
2746
+ }
2929
2747
  code = "PENDING_USEROP_FORBIDDEN";
2930
2748
  httpStatus = "forbidden";
2931
2749
  constructor(lockId) {
2932
- super(
2933
- `Pending UserOp ${lockId} does not belong to the authenticated user.`
2934
- );
2750
+ super(`Pending UserOp ${lockId} does not belong to the authenticated user.`);
2935
2751
  }
2936
2752
  };
2937
2753
  async function handleMobilePrepare(params) {
2938
2754
  const [fees, userCode] = await Promise.all([
2939
2755
  params.provider.estimateFeesPerGas(),
2940
- params.provider.getCode({ address: params.userAddress })
2756
+ params.provider.getCode({
2757
+ address: params.userAddress
2758
+ })
2941
2759
  ]);
2942
2760
  const needsDelegation = !params.eip7702Auth && parseEip7702DelegatedAddress(userCode) === null;
2943
2761
  const sponsoredOp = {
@@ -2971,6 +2789,7 @@ async function handleMobilePrepare(params) {
2971
2789
  needsDelegation
2972
2790
  };
2973
2791
  }
2792
+ __name(handleMobilePrepare, "handleMobilePrepare");
2974
2793
  async function handleMobileSubmit(params) {
2975
2794
  const entry = await params.store.get(params.lockId);
2976
2795
  if (!entry) {
@@ -2990,19 +2809,21 @@ async function handleMobileSubmit(params) {
2990
2809
  const targetLockId = variant === "fallback" && entry.fallback?.lockId ? entry.fallback.lockId : params.lockId;
2991
2810
  await params.bindUserOpHash(targetLockId, result.userOpHash);
2992
2811
  await params.store.delete(params.lockId);
2993
- return { userOpHash: result.userOpHash };
2812
+ return {
2813
+ userOpHash: result.userOpHash
2814
+ };
2994
2815
  }
2816
+ __name(handleMobileSubmit, "handleMobileSubmit");
2995
2817
 
2996
2818
  // src/api/handlers/ptClaimHandler.ts
2997
2819
  import { getAddress as getAddress9 } from "viem";
2998
- import {
2999
- POINT_TOKEN_ABI as POINT_TOKEN_ABI2,
3000
- decodeBatchExecuteCalls,
3001
- getContractAddresses as getContractAddresses3
3002
- } from "@pafi-dev/core";
2820
+ import { POINT_TOKEN_ABI as POINT_TOKEN_ABI2, decodeBatchExecuteCalls, getContractAddresses as getContractAddresses3 } from "@pafi-dev/core";
3003
2821
 
3004
2822
  // src/issuer-state/types.ts
3005
2823
  var IssuerStateError = class extends PafiSdkError {
2824
+ static {
2825
+ __name(this, "IssuerStateError");
2826
+ }
3006
2827
  httpStatus = "unprocessable";
3007
2828
  code;
3008
2829
  details;
@@ -3017,6 +2838,9 @@ var IssuerStateError = class extends PafiSdkError {
3017
2838
 
3018
2839
  // src/api/handlers/ptClaimHandler.ts
3019
2840
  var PTClaimError = class extends PafiSdkError {
2841
+ static {
2842
+ __name(this, "PTClaimError");
2843
+ }
3020
2844
  httpStatus = "unprocessable";
3021
2845
  code;
3022
2846
  details;
@@ -3031,32 +2855,29 @@ function isNoWrapper2(address) {
3031
2855
  const lower = address.toLowerCase();
3032
2856
  return lower === "0x0000000000000000000000000000000000000000" || lower === "0x000000000000000000000000000000000000dead";
3033
2857
  }
2858
+ __name(isNoWrapper2, "isNoWrapper");
3034
2859
  var DEFAULT_LOCK_MS = 15 * 60 * 1e3;
3035
2860
  var M11_SAFETY_MARGIN_MS2 = 30 * 1e3;
3036
2861
  var DEFAULT_SIG_DEADLINE_SEC2 = (DEFAULT_LOCK_MS - M11_SAFETY_MARGIN_MS2) / 1e3;
3037
2862
  var PTClaimHandler = class {
2863
+ static {
2864
+ __name(this, "PTClaimHandler");
2865
+ }
3038
2866
  cfg;
3039
2867
  inFlightNonces = /* @__PURE__ */ new Map();
3040
2868
  constructor(config) {
3041
2869
  if (!config.supportedTokens) {
3042
- throw new PTClaimError(
3043
- "UNSUPPORTED_POINT_TOKEN",
3044
- "PTClaimHandler requires `supportedTokens` (issuer's allow-listed PointToken contracts)."
3045
- );
2870
+ throw new PTClaimError("UNSUPPORTED_POINT_TOKEN", "PTClaimHandler requires `supportedTokens` (issuer's allow-listed PointToken contracts).");
3046
2871
  }
3047
2872
  const lockDurationMs = config.lockDurationMs ?? DEFAULT_LOCK_MS;
3048
2873
  const signatureDeadlineSeconds = config.signatureDeadlineSeconds ?? DEFAULT_SIG_DEADLINE_SEC2;
3049
2874
  const maxAllowedSignatureMs = lockDurationMs - M11_SAFETY_MARGIN_MS2;
3050
2875
  if (signatureDeadlineSeconds * 1e3 > maxAllowedSignatureMs) {
3051
- throw new PTClaimError(
3052
- "VALIDATION_FAILED",
3053
- `PTClaimHandler config: signatureDeadlineSeconds (${signatureDeadlineSeconds}s) must be at most lockDurationMs - safety margin = ${maxAllowedSignatureMs / 1e3}s (lockDurationMs=${lockDurationMs / 1e3}s, safety=${M11_SAFETY_MARGIN_MS2 / 1e3}s).`,
3054
- {
3055
- lockDurationMs,
3056
- signatureDeadlineSeconds,
3057
- maxAllowedSignatureSec: maxAllowedSignatureMs / 1e3
3058
- }
3059
- );
2876
+ throw new PTClaimError("VALIDATION_FAILED", `PTClaimHandler config: signatureDeadlineSeconds (${signatureDeadlineSeconds}s) must be at most lockDurationMs - safety margin = ${maxAllowedSignatureMs / 1e3}s (lockDurationMs=${lockDurationMs / 1e3}s, safety=${M11_SAFETY_MARGIN_MS2 / 1e3}s).`, {
2877
+ lockDurationMs,
2878
+ signatureDeadlineSeconds,
2879
+ maxAllowedSignatureSec: maxAllowedSignatureMs / 1e3
2880
+ });
3060
2881
  }
3061
2882
  this.cfg = {
3062
2883
  ...config,
@@ -3067,34 +2888,23 @@ var PTClaimHandler = class {
3067
2888
  }
3068
2889
  async handle(request) {
3069
2890
  if (getAddress9(request.authenticatedAddress) !== getAddress9(request.userAddress)) {
3070
- throw new PTClaimError(
3071
- "VALIDATION_FAILED",
3072
- `userAddress (${request.userAddress}) does not match authenticated session (${request.authenticatedAddress})`
3073
- );
2891
+ throw new PTClaimError("VALIDATION_FAILED", `userAddress (${request.userAddress}) does not match authenticated session (${request.authenticatedAddress})`);
3074
2892
  }
3075
2893
  if (request.amount <= 0n) {
3076
2894
  throw new PTClaimError("INVALID_AMOUNT", "claim amount must be positive");
3077
2895
  }
3078
2896
  const pointTokenAddress = getAddress9(request.pointTokenAddress);
3079
2897
  if (!this.cfg.supportedTokens.has(pointTokenAddress)) {
3080
- throw new PTClaimError(
3081
- "UNSUPPORTED_POINT_TOKEN",
3082
- `claim: pointTokenAddress ${pointTokenAddress} is not in the issuer's supported-token allowlist. Check IssuerApiHandlers.supportedTokens and PTClaimHandler.config.supportedTokens point at the same set.`,
3083
- { requested: pointTokenAddress }
3084
- );
2898
+ throw new PTClaimError("UNSUPPORTED_POINT_TOKEN", `claim: pointTokenAddress ${pointTokenAddress} is not in the issuer's supported-token allowlist. Check IssuerApiHandlers.supportedTokens and PTClaimHandler.config.supportedTokens point at the same set.`, {
2899
+ requested: pointTokenAddress
2900
+ });
3085
2901
  }
3086
2902
  if (this.cfg.issuerStateValidator) {
3087
2903
  try {
3088
- await this.cfg.issuerStateValidator.preValidateMint(
3089
- request.pointTokenAddress,
3090
- request.amount
3091
- );
2904
+ await this.cfg.issuerStateValidator.preValidateMint(request.pointTokenAddress, request.amount);
3092
2905
  } catch (err) {
3093
2906
  if (err instanceof IssuerStateError) throw err;
3094
- throw new PTClaimError(
3095
- "VALIDATION_FAILED",
3096
- `issuer-state pre-validate failed: ${err instanceof Error ? err.message : String(err)}`
3097
- );
2907
+ throw new PTClaimError("VALIDATION_FAILED", `issuer-state pre-validate failed: ${err instanceof Error ? err.message : String(err)}`);
3098
2908
  }
3099
2909
  }
3100
2910
  const chainAddresses = getContractAddresses3(request.chainId);
@@ -3105,13 +2915,12 @@ var PTClaimHandler = class {
3105
2915
  address: request.pointTokenAddress,
3106
2916
  abi: POINT_TOKEN_ABI2,
3107
2917
  functionName: "mintRequestNonces",
3108
- args: [request.userAddress]
2918
+ args: [
2919
+ request.userAddress
2920
+ ]
3109
2921
  });
3110
2922
  } catch (err) {
3111
- throw new PTClaimError(
3112
- "NONCE_READ_FAILED",
3113
- `failed to read mintRequestNonces(${request.userAddress}): ${err instanceof Error ? err.message : String(err)}`
3114
- );
2923
+ throw new PTClaimError("NONCE_READ_FAILED", `failed to read mintRequestNonces(${request.userAddress}): ${err instanceof Error ? err.message : String(err)}`);
3115
2924
  }
3116
2925
  const nonceKey = `${getAddress9(request.userAddress).toLowerCase()}:${request.pointTokenAddress.toLowerCase()}`;
3117
2926
  let userNonces = this.inFlightNonces.get(nonceKey);
@@ -3120,11 +2929,11 @@ var PTClaimHandler = class {
3120
2929
  this.inFlightNonces.set(nonceKey, userNonces);
3121
2930
  }
3122
2931
  if (userNonces.has(mintRequestNonce)) {
3123
- throw new PTClaimError(
3124
- "NONCE_IN_FLIGHT",
3125
- `concurrent claim for nonce ${mintRequestNonce} in progress; retry after the prior request completes`,
3126
- { userAddress: request.userAddress, pointToken: request.pointTokenAddress, nonce: mintRequestNonce.toString() }
3127
- );
2932
+ throw new PTClaimError("NONCE_IN_FLIGHT", `concurrent claim for nonce ${mintRequestNonce} in progress; retry after the prior request completes`, {
2933
+ userAddress: request.userAddress,
2934
+ pointToken: request.pointTokenAddress,
2935
+ nonce: mintRequestNonce.toString()
2936
+ });
3128
2937
  }
3129
2938
  userNonces.add(mintRequestNonce);
3130
2939
  const wrapperOverride = this.cfg.mintFeeWrapperAddress;
@@ -3133,20 +2942,11 @@ var PTClaimHandler = class {
3133
2942
  try {
3134
2943
  const lockCreatedAtMs = this.cfg.now();
3135
2944
  const lockExpiresAtMs = lockCreatedAtMs + this.cfg.lockDurationMs;
3136
- const lockId = await this.cfg.ledger.lockForMinting(
3137
- request.userAddress,
3138
- request.amount,
3139
- this.cfg.lockDurationMs,
3140
- request.pointTokenAddress
3141
- );
2945
+ const lockId = await this.cfg.ledger.lockForMinting(request.userAddress, request.amount, this.cfg.lockDurationMs, request.pointTokenAddress);
3142
2946
  try {
3143
2947
  const requestedDeadlineSec = Math.floor(lockCreatedAtMs / 1e3) + this.cfg.signatureDeadlineSeconds;
3144
- const lockBoundedDeadlineSec = Math.floor(
3145
- (lockExpiresAtMs - M11_SAFETY_MARGIN_MS2) / 1e3
3146
- );
3147
- const signatureDeadline = BigInt(
3148
- Math.min(requestedDeadlineSec, lockBoundedDeadlineSec)
3149
- );
2948
+ const lockBoundedDeadlineSec = Math.floor((lockExpiresAtMs - M11_SAFETY_MARGIN_MS2) / 1e3);
2949
+ const signatureDeadline = BigInt(Math.min(requestedDeadlineSec, lockBoundedDeadlineSec));
3150
2950
  const previewUserOp = this.cfg.relayService.previewMintUserOp({
3151
2951
  userAddress: request.userAddress,
3152
2952
  aaNonce: request.aaNonce,
@@ -3165,15 +2965,12 @@ var PTClaimHandler = class {
3165
2965
  }
3166
2966
  }) : 0n;
3167
2967
  if (feeAmount > 0n && feeAmount >= request.amount) {
3168
- throw new PTClaimError(
3169
- "INVALID_AMOUNT",
3170
- `fee (${feeAmount}) must be strictly less than claim amount (${request.amount})`,
3171
- { feeAmount: feeAmount.toString(), amount: request.amount.toString() }
3172
- );
2968
+ throw new PTClaimError("INVALID_AMOUNT", `fee (${feeAmount}) must be strictly less than claim amount (${request.amount})`, {
2969
+ feeAmount: feeAmount.toString(),
2970
+ amount: request.amount.toString()
2971
+ });
3173
2972
  }
3174
- const domainName = await this.cfg.domainResolver.resolve(
3175
- request.pointTokenAddress
3176
- );
2973
+ const domainName = await this.cfg.domainResolver.resolve(request.pointTokenAddress);
3177
2974
  const domain = {
3178
2975
  name: domainName,
3179
2976
  chainId: request.chainId,
@@ -3203,10 +3000,7 @@ var PTClaimHandler = class {
3203
3000
  feeAmount
3204
3001
  });
3205
3002
  } catch (err) {
3206
- throw new PTClaimError(
3207
- "BUILD_FAILED",
3208
- `prepareMint failed: ${err instanceof Error ? err.message : String(err)}`
3209
- );
3003
+ throw new PTClaimError("BUILD_FAILED", `prepareMint failed: ${err instanceof Error ? err.message : String(err)}`);
3210
3004
  }
3211
3005
  let fallback;
3212
3006
  if (feeAmount > 0n) {
@@ -3225,10 +3019,7 @@ var PTClaimHandler = class {
3225
3019
  mintFeeWrapperAddress: resolvedWrapper
3226
3020
  });
3227
3021
  } catch (err) {
3228
- throw new PTClaimError(
3229
- "BUILD_FAILED",
3230
- `prepareMint (fallback) failed: ${err instanceof Error ? err.message : String(err)}`
3231
- );
3022
+ throw new PTClaimError("BUILD_FAILED", `prepareMint (fallback) failed: ${err instanceof Error ? err.message : String(err)}`);
3232
3023
  }
3233
3024
  }
3234
3025
  const calls = decodeBatchExecuteCalls(userOp.callData);
@@ -3256,19 +3047,11 @@ var PTClaimHandler = class {
3256
3047
  };
3257
3048
 
3258
3049
  // src/api/handlers/perpDepositHandler.ts
3259
- import {
3260
- BROKER_HASHES,
3261
- ORDERLY_RELAY_ABI,
3262
- ORDERLY_VAULT_ABI,
3263
- ORDERLY_VAULT_ADDRESSES,
3264
- TOKEN_HASHES,
3265
- buildPerpDepositViaRelay,
3266
- computeAccountId,
3267
- decodeBatchExecuteCalls as decodeBatchExecuteCalls2,
3268
- getContractAddresses as getContractAddresses4,
3269
- quoteOperatorFeeUsdt
3270
- } from "@pafi-dev/core";
3050
+ import { BROKER_HASHES, ORDERLY_RELAY_ABI, ORDERLY_VAULT_ABI, ORDERLY_VAULT_ADDRESSES, TOKEN_HASHES, buildPerpDepositViaRelay, computeAccountId, decodeBatchExecuteCalls as decodeBatchExecuteCalls2, getContractAddresses as getContractAddresses4, quoteOperatorFeeUsdt } from "@pafi-dev/core";
3271
3051
  var PerpDepositError = class extends PafiSdkError {
3052
+ static {
3053
+ __name(this, "PerpDepositError");
3054
+ }
3272
3055
  httpStatus = "unprocessable";
3273
3056
  code;
3274
3057
  safeToRetry;
@@ -3280,6 +3063,9 @@ var PerpDepositError = class extends PafiSdkError {
3280
3063
  };
3281
3064
  var DEFAULT_MAX_FEE_PREMIUM_BPS = 5e3;
3282
3065
  var PerpDepositHandler = class {
3066
+ static {
3067
+ __name(this, "PerpDepositHandler");
3068
+ }
3283
3069
  cfg;
3284
3070
  constructor(config) {
3285
3071
  this.cfg = {
@@ -3295,10 +3081,7 @@ var PerpDepositHandler = class {
3295
3081
  const tokenHash = TOKEN_HASHES.USDC;
3296
3082
  const vault = ORDERLY_VAULT_ADDRESSES[request.chainId];
3297
3083
  if (!vault) {
3298
- throw new PerpDepositError(
3299
- "PERP_DEPOSIT_UNAVAILABLE",
3300
- `no Orderly Vault for chainId ${request.chainId}`
3301
- );
3084
+ throw new PerpDepositError("PERP_DEPOSIT_UNAVAILABLE", `no Orderly Vault for chainId ${request.chainId}`);
3302
3085
  }
3303
3086
  const { orderlyRelay: relayAddress, pafiFeeRecipient } = getContractAddresses4(request.chainId);
3304
3087
  const [usdcAddress, brokerAllowed] = await Promise.all([
@@ -3306,20 +3089,21 @@ var PerpDepositHandler = class {
3306
3089
  address: vault,
3307
3090
  abi: ORDERLY_VAULT_ABI,
3308
3091
  functionName: "getAllowedToken",
3309
- args: [tokenHash]
3092
+ args: [
3093
+ tokenHash
3094
+ ]
3310
3095
  }),
3311
3096
  this.cfg.provider.readContract({
3312
3097
  address: vault,
3313
3098
  abi: ORDERLY_VAULT_ABI,
3314
3099
  functionName: "getAllowedBroker",
3315
- args: [brokerHash]
3100
+ args: [
3101
+ brokerHash
3102
+ ]
3316
3103
  })
3317
3104
  ]);
3318
3105
  if (!brokerAllowed) {
3319
- throw new PerpDepositError(
3320
- "BROKER_NOT_WHITELISTED",
3321
- `broker "${request.brokerId}" is not whitelisted on Orderly Vault`
3322
- );
3106
+ throw new PerpDepositError("BROKER_NOT_WHITELISTED", `broker "${request.brokerId}" is not whitelisted on Orderly Vault`);
3323
3107
  }
3324
3108
  const accountId = computeAccountId(request.userAddress, brokerHash);
3325
3109
  const requestForQuote = {
@@ -3334,7 +3118,9 @@ var PerpDepositHandler = class {
3334
3118
  address: relayAddress,
3335
3119
  abi: ORDERLY_RELAY_ABI,
3336
3120
  functionName: "quoteTokenFee",
3337
- args: [requestForQuote]
3121
+ args: [
3122
+ requestForQuote
3123
+ ]
3338
3124
  }),
3339
3125
  quoteOperatorFeeUsdt({
3340
3126
  provider: this.cfg.provider,
@@ -3344,16 +3130,10 @@ var PerpDepositHandler = class {
3344
3130
  })
3345
3131
  ]);
3346
3132
  if (relayTokenFee >= request.amount) {
3347
- throw new PerpDepositError(
3348
- "RELAY_FEE_EXCEEDS_AMOUNT",
3349
- `Relay quoted fee ${relayTokenFee} >= deposit amount ${request.amount}`
3350
- );
3133
+ throw new PerpDepositError("RELAY_FEE_EXCEEDS_AMOUNT", `Relay quoted fee ${relayTokenFee} >= deposit amount ${request.amount}`);
3351
3134
  }
3352
3135
  if (usdcGasFee > 0n && usdcGasFee >= request.amount) {
3353
- throw new PerpDepositError(
3354
- "FEE_EXCEEDS_AMOUNT",
3355
- `USDC gas fee ${usdcGasFee} >= deposit amount ${request.amount}`
3356
- );
3136
+ throw new PerpDepositError("FEE_EXCEEDS_AMOUNT", `USDC gas fee ${usdcGasFee} >= deposit amount ${request.amount}`);
3357
3137
  }
3358
3138
  const maxFee = relayTokenFee * BigInt(1e4 + this.cfg.maxFeePremiumBps) / 10000n;
3359
3139
  const depositReq = {
@@ -3395,13 +3175,7 @@ var PerpDepositHandler = class {
3395
3175
  };
3396
3176
 
3397
3177
  // src/api/delegateHandler.ts
3398
- import {
3399
- ENTRY_POINT_V08 as ENTRY_POINT_V082,
3400
- buildDelegationUserOp,
3401
- buildEip7702Authorization,
3402
- getContractAddresses as getContractAddresses5,
3403
- serializeUserOpToJsonRpc as serializeUserOpToJsonRpc2
3404
- } from "@pafi-dev/core";
3178
+ import { ENTRY_POINT_V08 as ENTRY_POINT_V082, buildDelegationUserOp, buildEip7702Authorization, getContractAddresses as getContractAddresses5, serializeUserOpToJsonRpc as serializeUserOpToJsonRpc2 } from "@pafi-dev/core";
3405
3179
  import { getAddress as getAddress10 } from "viem";
3406
3180
  var DEFAULT_DELEGATE_GAS = {
3407
3181
  callGasLimit: 100000n,
@@ -3444,38 +3218,34 @@ async function handleDelegatePrepare(params) {
3444
3218
  eip7702Auth: authorization,
3445
3219
  onWarning: params.onWarning
3446
3220
  });
3447
- const prepared = applyPaymasterGasEstimates(
3448
- userOp,
3449
- paymasterFields,
3450
- params.chainId
3451
- );
3221
+ const prepared = applyPaymasterGasEstimates(userOp, paymasterFields, params.chainId);
3452
3222
  const merged = prepared.userOp;
3453
3223
  const userOpHash = prepared.userOpHash;
3454
- await params.store.save(
3455
- params.lockId,
3456
- {
3457
- sender: merged.sender,
3458
- nonce: merged.nonce.toString(10),
3459
- callData: merged.callData,
3460
- callGasLimit: merged.callGasLimit.toString(10),
3461
- verificationGasLimit: merged.verificationGasLimit.toString(10),
3462
- preVerificationGas: merged.preVerificationGas.toString(10),
3463
- maxFeePerGas: merged.maxFeePerGas.toString(10),
3464
- maxPriorityFeePerGas: merged.maxPriorityFeePerGas.toString(10),
3465
- ...merged.paymaster ? { paymaster: merged.paymaster } : {},
3466
- ...merged.paymasterVerificationGasLimit ? {
3467
- paymasterVerificationGasLimit: merged.paymasterVerificationGasLimit.toString(10)
3468
- } : {},
3469
- ...merged.paymasterPostOpGasLimit ? {
3470
- paymasterPostOpGasLimit: merged.paymasterPostOpGasLimit.toString(10)
3471
- } : {},
3472
- ...merged.paymasterData ? { paymasterData: merged.paymasterData } : {},
3473
- chainId: params.chainId,
3474
- userOpHash,
3475
- eip7702Auth: authorization
3476
- },
3477
- params.ttlSeconds
3478
- );
3224
+ await params.store.save(params.lockId, {
3225
+ sender: merged.sender,
3226
+ nonce: merged.nonce.toString(10),
3227
+ callData: merged.callData,
3228
+ callGasLimit: merged.callGasLimit.toString(10),
3229
+ verificationGasLimit: merged.verificationGasLimit.toString(10),
3230
+ preVerificationGas: merged.preVerificationGas.toString(10),
3231
+ maxFeePerGas: merged.maxFeePerGas.toString(10),
3232
+ maxPriorityFeePerGas: merged.maxPriorityFeePerGas.toString(10),
3233
+ ...merged.paymaster ? {
3234
+ paymaster: merged.paymaster
3235
+ } : {},
3236
+ ...merged.paymasterVerificationGasLimit ? {
3237
+ paymasterVerificationGasLimit: merged.paymasterVerificationGasLimit.toString(10)
3238
+ } : {},
3239
+ ...merged.paymasterPostOpGasLimit ? {
3240
+ paymasterPostOpGasLimit: merged.paymasterPostOpGasLimit.toString(10)
3241
+ } : {},
3242
+ ...merged.paymasterData ? {
3243
+ paymasterData: merged.paymasterData
3244
+ } : {},
3245
+ chainId: params.chainId,
3246
+ userOpHash,
3247
+ eip7702Auth: authorization
3248
+ }, params.ttlSeconds);
3479
3249
  return {
3480
3250
  lockId: params.lockId,
3481
3251
  userOpHash,
@@ -3484,6 +3254,7 @@ async function handleDelegatePrepare(params) {
3484
3254
  isSponsored: !!paymasterFields
3485
3255
  };
3486
3256
  }
3257
+ __name(handleDelegatePrepare, "handleDelegatePrepare");
3487
3258
  async function handleDelegateSubmit(params) {
3488
3259
  const entry = await params.store.get(params.lockId);
3489
3260
  if (!entry) {
@@ -3493,9 +3264,7 @@ async function handleDelegateSubmit(params) {
3493
3264
  throw new PendingUserOpForbiddenError(params.lockId);
3494
3265
  }
3495
3266
  if (!entry.eip7702Auth) {
3496
- throw new Error(
3497
- `delegate entry ${params.lockId} missing eip7702Auth \u2014 prepare step did not run correctly`
3498
- );
3267
+ throw new Error(`delegate entry ${params.lockId} missing eip7702Auth \u2014 prepare step did not run correctly`);
3499
3268
  }
3500
3269
  const userOpJson = serializeEntryToJsonRpc(entry, params.userOpSig, "sponsored");
3501
3270
  const result = await relayUserOp({
@@ -3505,21 +3274,20 @@ async function handleDelegateSubmit(params) {
3505
3274
  eip7702Auth: entry.eip7702Auth
3506
3275
  });
3507
3276
  await params.store.delete(params.lockId);
3508
- return { userOpHash: result.userOpHash };
3277
+ return {
3278
+ userOpHash: result.userOpHash
3279
+ };
3509
3280
  }
3281
+ __name(handleDelegateSubmit, "handleDelegateSubmit");
3510
3282
 
3511
3283
  // src/api/issuerApiAdapter.ts
3512
3284
  import { randomUUID } from "crypto";
3513
3285
  import { getAddress as getAddress11 } from "viem";
3514
- import {
3515
- buildAndSignSponsorAuth,
3516
- decodeBatchExecuteCalls as decodeBatchExecuteCalls3,
3517
- encodeBatchExecute,
3518
- ENTRY_POINT_V08 as ENTRY_POINT_V083,
3519
- getContractAddresses as getContractAddresses6,
3520
- parseEip7702DelegatedAddress as parseEip7702DelegatedAddress2
3521
- } from "@pafi-dev/core";
3286
+ import { buildAndSignSponsorAuth, decodeBatchExecuteCalls as decodeBatchExecuteCalls3, encodeBatchExecute, ENTRY_POINT_V08 as ENTRY_POINT_V083, getContractAddresses as getContractAddresses6, parseEip7702DelegatedAddress as parseEip7702DelegatedAddress2 } from "@pafi-dev/core";
3522
3287
  var AdapterMisconfiguredError = class extends Error {
3288
+ static {
3289
+ __name(this, "AdapterMisconfiguredError");
3290
+ }
3523
3291
  code = "ADAPTER_MISCONFIGURED";
3524
3292
  constructor(message) {
3525
3293
  super(message);
@@ -3527,35 +3295,28 @@ var AdapterMisconfiguredError = class extends Error {
3527
3295
  }
3528
3296
  };
3529
3297
  var IssuerApiAdapter = class {
3298
+ static {
3299
+ __name(this, "IssuerApiAdapter");
3300
+ }
3530
3301
  cfg;
3531
3302
  constructor(config) {
3532
3303
  if (config.ptClaimHandler) {
3533
3304
  if (typeof config.ledger.bindMintUserOpHash !== "function") {
3534
- throw new AdapterMisconfiguredError(
3535
- "ledger.bindMintUserOpHash is required when ptClaimHandler is wired (mobile claim flow). Implement it on your IPointLedger or omit ptClaimHandler from IssuerApiAdapter config."
3536
- );
3305
+ throw new AdapterMisconfiguredError("ledger.bindMintUserOpHash is required when ptClaimHandler is wired (mobile claim flow). Implement it on your IPointLedger or omit ptClaimHandler from IssuerApiAdapter config.");
3537
3306
  }
3538
3307
  if (typeof config.ledger.getMintLock !== "function") {
3539
- throw new AdapterMisconfiguredError(
3540
- "ledger.getMintLock is required when ptClaimHandler is wired \u2014 claimStatus uses it to look up the lock."
3541
- );
3308
+ throw new AdapterMisconfiguredError("ledger.getMintLock is required when ptClaimHandler is wired \u2014 claimStatus uses it to look up the lock.");
3542
3309
  }
3543
3310
  }
3544
3311
  if (config.ptRedeemHandler) {
3545
3312
  if (typeof config.ledger.reservePendingCredit !== "function") {
3546
- throw new AdapterMisconfiguredError(
3547
- "ledger.reservePendingCredit is required when ptRedeemHandler is wired (burn/redeem reverse flow). PTRedeemHandler also enforces this at construction; see ledger/types.ts comments."
3548
- );
3313
+ throw new AdapterMisconfiguredError("ledger.reservePendingCredit is required when ptRedeemHandler is wired (burn/redeem reverse flow). PTRedeemHandler also enforces this at construction; see ledger/types.ts comments.");
3549
3314
  }
3550
3315
  if (typeof config.ledger.bindCreditUserOpHash !== "function") {
3551
- throw new AdapterMisconfiguredError(
3552
- "ledger.bindCreditUserOpHash is required when ptRedeemHandler is wired (mobile redeem flow)."
3553
- );
3316
+ throw new AdapterMisconfiguredError("ledger.bindCreditUserOpHash is required when ptRedeemHandler is wired (mobile redeem flow).");
3554
3317
  }
3555
3318
  if (typeof config.ledger.getPendingCredit !== "function") {
3556
- throw new AdapterMisconfiguredError(
3557
- "ledger.getPendingCredit is required when ptRedeemHandler is wired \u2014 redeemStatus uses it to look up the credit."
3558
- );
3319
+ throw new AdapterMisconfiguredError("ledger.getPendingCredit is required when ptRedeemHandler is wired \u2014 redeemStatus uses it to look up the credit.");
3559
3320
  }
3560
3321
  }
3561
3322
  this.cfg = config;
@@ -3570,24 +3331,25 @@ var IssuerApiAdapter = class {
3570
3331
  }
3571
3332
  async gasFee() {
3572
3333
  const result = await this.cfg.issuerService.api.handleGasFee();
3573
- return { gasFeeUsdt: result.gasFeeUsdt.toString() };
3334
+ return {
3335
+ gasFeeUsdt: result.gasFeeUsdt.toString()
3336
+ };
3574
3337
  }
3575
3338
  async pools(authenticatedAddress, chainId, pointTokenAddress) {
3576
- const result = await this.cfg.issuerService.api.handlePools(
3577
- authenticatedAddress,
3578
- { chainId, pointTokenAddress: getAddress11(pointTokenAddress) }
3579
- );
3580
- return { pools: result.pools };
3339
+ const result = await this.cfg.issuerService.api.handlePools(authenticatedAddress, {
3340
+ chainId,
3341
+ pointTokenAddress: getAddress11(pointTokenAddress)
3342
+ });
3343
+ return {
3344
+ pools: result.pools
3345
+ };
3581
3346
  }
3582
3347
  async user(authenticatedAddress, chainId, userAddress, pointTokenAddress) {
3583
- const result = await this.cfg.issuerService.api.handleUser(
3584
- authenticatedAddress,
3585
- {
3586
- chainId,
3587
- userAddress: getAddress11(userAddress),
3588
- pointTokenAddress: getAddress11(pointTokenAddress)
3589
- }
3590
- );
3348
+ const result = await this.cfg.issuerService.api.handleUser(authenticatedAddress, {
3349
+ chainId,
3350
+ userAddress: getAddress11(userAddress),
3351
+ pointTokenAddress: getAddress11(pointTokenAddress)
3352
+ });
3591
3353
  return {
3592
3354
  offChainBalance: result.offChainBalance.toString(),
3593
3355
  onChainBalance: result.onChainBalance.toString(),
@@ -3600,11 +3362,7 @@ var IssuerApiAdapter = class {
3600
3362
  // directly. Issuer SDK doesn't ship swap/quote anymore.
3601
3363
  // ------------------------------ Action endpoints -------------------------
3602
3364
  async claim(input) {
3603
- const ptClaimHandler = this.assertHandler(
3604
- this.cfg.ptClaimHandler,
3605
- "ptClaimHandler",
3606
- "claim"
3607
- );
3365
+ const ptClaimHandler = this.assertHandler(this.cfg.ptClaimHandler, "ptClaimHandler", "claim");
3608
3366
  const pointTokenAddress = getAddress11(input.pointTokenAddress);
3609
3367
  const result = await ptClaimHandler.handle({
3610
3368
  authenticatedAddress: input.authenticatedAddress,
@@ -3614,12 +3372,7 @@ var IssuerApiAdapter = class {
3614
3372
  chainId: input.chainId,
3615
3373
  aaNonce: input.aaNonce
3616
3374
  });
3617
- const sponsorAuth = await this.buildSponsorAuth(
3618
- input.authenticatedAddress,
3619
- result.userOp.callData,
3620
- input.chainId,
3621
- "mint"
3622
- );
3375
+ const sponsorAuth = await this.buildSponsorAuth(input.authenticatedAddress, result.userOp.callData, input.chainId, "mint");
3623
3376
  return {
3624
3377
  calls: result.calls,
3625
3378
  callsFallback: result.callsFallback,
@@ -3640,12 +3393,7 @@ var IssuerApiAdapter = class {
3640
3393
  aaNonce: input.aaNonce,
3641
3394
  chainId: input.chainId
3642
3395
  });
3643
- const sponsorAuth = await this.buildSponsorAuth(
3644
- input.authenticatedAddress,
3645
- response.userOp.callData,
3646
- input.chainId,
3647
- "burn"
3648
- );
3396
+ const sponsorAuth = await this.buildSponsorAuth(input.authenticatedAddress, response.userOp.callData, input.chainId, "burn");
3649
3397
  return {
3650
3398
  calls: decodeBatchExecuteCalls3(response.userOp.callData),
3651
3399
  callsFallback: response.fallback ? decodeBatchExecuteCalls3(response.fallback.userOp.callData) : void 0,
@@ -3662,11 +3410,7 @@ var IssuerApiAdapter = class {
3662
3410
  // swap() removed (2026-04-27) — moved to @pafi-dev/trading.
3663
3411
  // PAFI's web FE calls TradingHandlers.handleSwap directly.
3664
3412
  async perpDeposit(input) {
3665
- const perpHandler = this.assertHandler(
3666
- this.cfg.perpHandler,
3667
- "perpHandler",
3668
- "perpDeposit"
3669
- );
3413
+ const perpHandler = this.assertHandler(this.cfg.perpHandler, "perpHandler", "perpDeposit");
3670
3414
  const result = await perpHandler.handle({
3671
3415
  userAddress: input.authenticatedAddress,
3672
3416
  chainId: input.chainId,
@@ -3674,12 +3418,7 @@ var IssuerApiAdapter = class {
3674
3418
  brokerId: input.brokerId,
3675
3419
  aaNonce: input.aaNonce
3676
3420
  });
3677
- const sponsorAuth = await this.buildSponsorAuth(
3678
- input.authenticatedAddress,
3679
- result.userOp.callData,
3680
- input.chainId,
3681
- "perp-deposit"
3682
- );
3421
+ const sponsorAuth = await this.buildSponsorAuth(input.authenticatedAddress, result.userOp.callData, input.chainId, "perp-deposit");
3683
3422
  return {
3684
3423
  calls: result.calls,
3685
3424
  callsFallback: result.callsFallback,
@@ -3696,11 +3435,7 @@ var IssuerApiAdapter = class {
3696
3435
  }
3697
3436
  // ------------------------------ Mobile endpoints -------------------------
3698
3437
  async claimPrepare(input) {
3699
- const ptClaimHandler = this.assertHandler(
3700
- this.cfg.ptClaimHandler,
3701
- "ptClaimHandler",
3702
- "claimPrepare"
3703
- );
3438
+ const ptClaimHandler = this.assertHandler(this.cfg.ptClaimHandler, "ptClaimHandler", "claimPrepare");
3704
3439
  const pointTokenAddress = getAddress11(input.pointTokenAddress);
3705
3440
  const claimResult = await ptClaimHandler.handle({
3706
3441
  authenticatedAddress: input.authenticatedAddress,
@@ -3710,17 +3445,7 @@ var IssuerApiAdapter = class {
3710
3445
  chainId: input.chainId,
3711
3446
  aaNonce: input.aaNonce
3712
3447
  });
3713
- const prepared = await this.runMobilePrepare(
3714
- input.authenticatedAddress,
3715
- input.chainId,
3716
- claimResult.lockId,
3717
- claimResult.userOp,
3718
- claimResult.fallback,
3719
- "mint",
3720
- pointTokenAddress,
3721
- claimResult.expiresInSeconds,
3722
- input.eip7702Auth
3723
- );
3448
+ const prepared = await this.runMobilePrepare(input.authenticatedAddress, input.chainId, claimResult.lockId, claimResult.userOp, claimResult.fallback, "mint", pointTokenAddress, claimResult.expiresInSeconds, input.eip7702Auth);
3724
3449
  return {
3725
3450
  lockId: claimResult.lockId,
3726
3451
  userOpHash: prepared.sponsored.userOpHash,
@@ -3741,7 +3466,7 @@ var IssuerApiAdapter = class {
3741
3466
  signature: input.signature,
3742
3467
  variant: input.variant,
3743
3468
  store: this.cfg.pendingUserOpStore,
3744
- bindUserOpHash: (lockId, hash) => this.cfg.ledger.bindMintUserOpHash(lockId, hash),
3469
+ bindUserOpHash: /* @__PURE__ */ __name((lockId, hash) => this.cfg.ledger.bindMintUserOpHash(lockId, hash), "bindUserOpHash"),
3745
3470
  pafiBackendClient: this.cfg.pafiBackendClient
3746
3471
  });
3747
3472
  }
@@ -3756,18 +3481,7 @@ var IssuerApiAdapter = class {
3756
3481
  aaNonce: input.aaNonce,
3757
3482
  chainId: input.chainId
3758
3483
  });
3759
- const prepared = await this.runMobilePrepare(
3760
- input.authenticatedAddress,
3761
- input.chainId,
3762
- redeemResponse.lockId,
3763
- redeemResponse.userOp,
3764
- redeemResponse.fallback?.userOp,
3765
- "burn",
3766
- pointTokenAddress,
3767
- redeemResponse.expiresInSeconds,
3768
- input.eip7702Auth,
3769
- redeemResponse.fallback?.lockId
3770
- );
3484
+ const prepared = await this.runMobilePrepare(input.authenticatedAddress, input.chainId, redeemResponse.lockId, redeemResponse.userOp, redeemResponse.fallback?.userOp, "burn", pointTokenAddress, redeemResponse.expiresInSeconds, input.eip7702Auth, redeemResponse.fallback?.lockId);
3771
3485
  return {
3772
3486
  lockId: redeemResponse.lockId,
3773
3487
  lockIdFallback: redeemResponse.fallback?.lockId,
@@ -3791,7 +3505,7 @@ var IssuerApiAdapter = class {
3791
3505
  signature: input.signature,
3792
3506
  variant: input.variant,
3793
3507
  store: this.cfg.pendingUserOpStore,
3794
- bindUserOpHash: (lockId, hash) => this.cfg.ledger.bindCreditUserOpHash(lockId, hash),
3508
+ bindUserOpHash: /* @__PURE__ */ __name((lockId, hash) => this.cfg.ledger.bindCreditUserOpHash(lockId, hash), "bindUserOpHash"),
3795
3509
  pafiBackendClient: this.cfg.pafiBackendClient
3796
3510
  });
3797
3511
  }
@@ -3819,7 +3533,9 @@ var IssuerApiAdapter = class {
3819
3533
  async delegateStatus(authenticatedAddress, chainId) {
3820
3534
  const { batchExecutor } = getContractAddresses6(chainId);
3821
3535
  const [code, nonce] = await Promise.all([
3822
- this.cfg.provider.getCode({ address: authenticatedAddress }),
3536
+ this.cfg.provider.getCode({
3537
+ address: authenticatedAddress
3538
+ }),
3823
3539
  this.cfg.provider.getTransactionCount({
3824
3540
  address: authenticatedAddress,
3825
3541
  blockTag: "pending"
@@ -3833,21 +3549,21 @@ var IssuerApiAdapter = class {
3833
3549
  };
3834
3550
  }
3835
3551
  /**
3836
- * Build the delegation-anchor UserOp + obtain paymaster sponsorship
3837
- * + persist as a pending entry. Mobile must:
3838
- *
3839
- * 1. Sign EIP-7702 authorization LOCALLY (Privy `signAuthorization`
3840
- * with `{contractAddress: batchExecutorAddress, chainId,
3841
- * nonce: delegationNonce}`) → 65-byte authSig hex.
3842
- * 2. POST `/delegate/prepare` with `{ chainId, delegationNonce,
3843
- * authSig }` → this method.
3844
- * 3. Sign returned `userOpHash` LOCALLY (`signTypedData(typedData)`).
3845
- * 4. POST `/delegate/submit` with `{ lockId, userOpSig }`.
3846
- *
3847
- * v0.7.7 — replaces single-shot delegateSubmit that tried to relay
3848
- * a UserOp with empty `signature: "0x"` (Simple7702Account's
3849
- * validateUserOp reverts `ECDSAInvalidSignatureLength` 0xfce698f7).
3850
- */
3552
+ * Build the delegation-anchor UserOp + obtain paymaster sponsorship
3553
+ * + persist as a pending entry. Mobile must:
3554
+ *
3555
+ * 1. Sign EIP-7702 authorization LOCALLY (Privy `signAuthorization`
3556
+ * with `{contractAddress: batchExecutorAddress, chainId,
3557
+ * nonce: delegationNonce}`) → 65-byte authSig hex.
3558
+ * 2. POST `/delegate/prepare` with `{ chainId, delegationNonce,
3559
+ * authSig }` → this method.
3560
+ * 3. Sign returned `userOpHash` LOCALLY (`signTypedData(typedData)`).
3561
+ * 4. POST `/delegate/submit` with `{ lockId, userOpSig }`.
3562
+ *
3563
+ * v0.7.7 — replaces single-shot delegateSubmit that tried to relay
3564
+ * a UserOp with empty `signature: "0x"` (Simple7702Account's
3565
+ * validateUserOp reverts `ECDSAInvalidSignatureLength` 0xfce698f7).
3566
+ */
3851
3567
  async delegatePrepare(authenticatedAddress, input) {
3852
3568
  const { batchExecutor } = getContractAddresses6(input.chainId);
3853
3569
  const fees = await this.cfg.provider.estimateFeesPerGas();
@@ -3862,7 +3578,6 @@ var IssuerApiAdapter = class {
3862
3578
  lockId,
3863
3579
  store: this.cfg.pendingUserOpStore,
3864
3580
  ttlSeconds: 15 * 60,
3865
- // 15min — match claim/redeem mobile lock duration
3866
3581
  pafiBackendClient: this.cfg.pafiBackendClient,
3867
3582
  onWarning: this.cfg.onWarning
3868
3583
  });
@@ -3885,13 +3600,15 @@ var IssuerApiAdapter = class {
3885
3600
  store: this.cfg.pendingUserOpStore,
3886
3601
  pafiBackendClient: this.cfg.pafiBackendClient
3887
3602
  });
3888
- return { userOpHash: result.userOpHash };
3603
+ return {
3604
+ userOpHash: result.userOpHash
3605
+ };
3889
3606
  }
3890
3607
  // ------------------------------ Internal helpers -------------------------
3891
3608
  /**
3892
- * Build + sign a SponsorAuth payload. Returns `undefined` when no
3893
- * issuer id is configured, so the controller can skip the field.
3894
- */
3609
+ * Build + sign a SponsorAuth payload. Returns `undefined` when no
3610
+ * issuer id is configured, so the controller can skip the field.
3611
+ */
3895
3612
  async buildSponsorAuth(authenticatedAddress, callData, chainId, scenario) {
3896
3613
  if (!this.cfg.pafiIssuerId) return void 0;
3897
3614
  return buildAndSignSponsorAuth({
@@ -3923,22 +3640,18 @@ var IssuerApiAdapter = class {
3923
3640
  }
3924
3641
  assertRedeemHandler() {
3925
3642
  if (!this.cfg.ptRedeemHandler) {
3926
- throw new Error(
3927
- "PTRedeemHandler not wired \u2014 IssuerApiAdapter.redeem* require a configured ptRedeemHandler."
3928
- );
3643
+ throw new Error("PTRedeemHandler not wired \u2014 IssuerApiAdapter.redeem* require a configured ptRedeemHandler.");
3929
3644
  }
3930
3645
  }
3931
3646
  /**
3932
- * Narrow an optional handler to non-null and throw a clear error when
3933
- * the issuer wired the adapter without it. Lets issuers opt out of
3934
- * flows they don't expose (gg56 ships only mobile claim/redeem, so
3935
- * `swapHandler` + `perpHandler` aren't constructed).
3936
- */
3647
+ * Narrow an optional handler to non-null and throw a clear error when
3648
+ * the issuer wired the adapter without it. Lets issuers opt out of
3649
+ * flows they don't expose (gg56 ships only mobile claim/redeem, so
3650
+ * `swapHandler` + `perpHandler` aren't constructed).
3651
+ */
3937
3652
  assertHandler(handler, fieldName, methodName) {
3938
3653
  if (handler === null || handler === void 0) {
3939
- throw new Error(
3940
- `${fieldName} not wired \u2014 IssuerApiAdapter.${methodName}() requires a configured ${fieldName}.`
3941
- );
3654
+ throw new Error(`${fieldName} not wired \u2014 IssuerApiAdapter.${methodName}() requires a configured ${fieldName}.`);
3942
3655
  }
3943
3656
  return handler;
3944
3657
  }
@@ -3971,9 +3684,7 @@ function createSubgraphPoolsProvider(config = {}) {
3971
3684
  }
3972
3685
  } catch (err) {
3973
3686
  if (err instanceof TypeError) {
3974
- throw new Error(
3975
- `subgraphPoolsProvider: invalid subgraphUrl: ${subgraphUrl}`
3976
- );
3687
+ throw new Error(`subgraphPoolsProvider: invalid subgraphUrl: ${subgraphUrl}`);
3977
3688
  }
3978
3689
  throw err;
3979
3690
  }
@@ -3983,64 +3694,61 @@ function createSubgraphPoolsProvider(config = {}) {
3983
3694
  const onError = config.onError;
3984
3695
  const cache = /* @__PURE__ */ new Map();
3985
3696
  if (!fetchImpl) {
3986
- throw new Error(
3987
- "createSubgraphPoolsProvider: no fetch implementation available \u2014 pass `fetchImpl` or run on Node 18+"
3988
- );
3697
+ throw new Error("createSubgraphPoolsProvider: no fetch implementation available \u2014 pass `fetchImpl` or run on Node 18+");
3989
3698
  }
3990
- const reportError = (err) => {
3699
+ const reportError = /* @__PURE__ */ __name((err) => {
3991
3700
  if (!onError) return;
3992
3701
  try {
3993
3702
  onError(err);
3994
3703
  } catch {
3995
3704
  }
3996
- };
3705
+ }, "reportError");
3997
3706
  return async (request) => {
3998
3707
  const cacheKey = `${request.chainId}:${request.pointTokenAddress.toLowerCase()}`;
3999
3708
  if (cacheTtl > 0) {
4000
3709
  const cached = cache.get(cacheKey);
4001
3710
  if (cached && cached.expiresAt > now()) {
4002
- return { pools: cached.pools };
3711
+ return {
3712
+ pools: cached.pools
3713
+ };
4003
3714
  }
4004
3715
  }
4005
- const pools = await fetchPoolsFromSubgraph(
4006
- fetchImpl,
4007
- subgraphUrl,
4008
- request.pointTokenAddress,
4009
- reportError
4010
- );
3716
+ const pools = await fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, request.pointTokenAddress, reportError);
4011
3717
  if (cacheTtl > 0) {
4012
3718
  cache.set(cacheKey, {
4013
3719
  expiresAt: now() + cacheTtl,
4014
3720
  pools
4015
3721
  });
4016
3722
  }
4017
- return { pools };
3723
+ return {
3724
+ pools
3725
+ };
4018
3726
  };
4019
3727
  }
3728
+ __name(createSubgraphPoolsProvider, "createSubgraphPoolsProvider");
4020
3729
  async function fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, pointTokenAddress, reportError) {
4021
3730
  let response;
4022
3731
  try {
4023
3732
  response = await fetchImpl(subgraphUrl, {
4024
3733
  method: "POST",
4025
- headers: { "Content-Type": "application/json" },
3734
+ headers: {
3735
+ "Content-Type": "application/json"
3736
+ },
4026
3737
  body: JSON.stringify({
4027
3738
  query: POOL_QUERY,
4028
- variables: { id: pointTokenAddress.toLowerCase() }
3739
+ variables: {
3740
+ id: pointTokenAddress.toLowerCase()
3741
+ }
4029
3742
  })
4030
3743
  });
4031
3744
  } catch (err) {
4032
3745
  const error = err instanceof Error ? err : new Error(String(err));
4033
- console.warn(
4034
- "[subgraphPoolsProvider] subgraph unreachable:",
4035
- error.message
4036
- );
3746
+ console.warn("[subgraphPoolsProvider] subgraph unreachable:", error.message);
4037
3747
  reportError(error);
4038
3748
  return [];
4039
3749
  }
4040
3750
  if (!response.ok) {
4041
- const error = new Error(
4042
- `subgraph returned HTTP ${response.status}`
4043
- );
3751
+ const error = new Error(`subgraph returned HTTP ${response.status}`);
4044
3752
  console.warn(`[subgraphPoolsProvider] ${error.message}`);
4045
3753
  reportError(error);
4046
3754
  return [];
@@ -4050,10 +3758,7 @@ async function fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, pointTokenAddress,
4050
3758
  json = await response.json();
4051
3759
  } catch (err) {
4052
3760
  const error = err instanceof Error ? err : new Error(String(err));
4053
- console.warn(
4054
- "[subgraphPoolsProvider] subgraph returned non-JSON:",
4055
- error.message
4056
- );
3761
+ console.warn("[subgraphPoolsProvider] subgraph returned non-JSON:", error.message);
4057
3762
  reportError(error);
4058
3763
  return [];
4059
3764
  }
@@ -4069,36 +3774,39 @@ async function fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, pointTokenAddress,
4069
3774
  }
4070
3775
  const { pool } = token;
4071
3776
  if (!isAddress(pool.token0.id) || !isAddress(pool.token1.id)) {
4072
- const error = new Error(
4073
- "[PAFI] SubgraphPoolsProvider: invalid token address in response"
4074
- );
3777
+ const error = new Error("[PAFI] SubgraphPoolsProvider: invalid token address in response");
4075
3778
  console.error(error.message, "\u2014 skipping pool");
4076
3779
  reportError(error);
4077
3780
  return [];
4078
3781
  }
4079
3782
  const feeNum = Number(pool.feeTier);
4080
3783
  if (!Number.isInteger(feeNum) || feeNum < 0 || feeNum >= MAX_REASONABLE_FEE_TIER) {
4081
- const error = new Error(
4082
- `[PAFI] SubgraphPoolsProvider: invalid feeTier value: ${pool.feeTier}`
4083
- );
3784
+ const error = new Error(`[PAFI] SubgraphPoolsProvider: invalid feeTier value: ${pool.feeTier}`);
4084
3785
  console.error(error.message, "\u2014 skipping pool");
4085
3786
  reportError(error);
4086
3787
  return [];
4087
3788
  }
4088
- const [token0, token1] = sortTokens(
4089
- pool.token0.id,
4090
- pool.token1.id
4091
- );
3789
+ const [token0, token1] = sortTokens(pool.token0.id, pool.token1.id);
4092
3790
  const poolKey = {
4093
3791
  token0,
4094
3792
  token1,
4095
3793
  fee: feeNum
4096
3794
  };
4097
- return [poolKey];
3795
+ return [
3796
+ poolKey
3797
+ ];
4098
3798
  }
3799
+ __name(fetchPoolsFromSubgraph, "fetchPoolsFromSubgraph");
4099
3800
  function sortTokens(a, b) {
4100
- return a.toLowerCase() < b.toLowerCase() ? [a, b] : [b, a];
3801
+ return a.toLowerCase() < b.toLowerCase() ? [
3802
+ a,
3803
+ b
3804
+ ] : [
3805
+ b,
3806
+ a
3807
+ ];
4101
3808
  }
3809
+ __name(sortTokens, "sortTokens");
4102
3810
 
4103
3811
  // src/pools/subgraphNativeUsdtQuoter.ts
4104
3812
  var DEFAULT_CACHE_TTL_MS2 = 3e4;
@@ -4121,9 +3829,7 @@ function createSubgraphNativeUsdtQuoter(config = {}) {
4121
3829
  }
4122
3830
  } catch (err) {
4123
3831
  if (err instanceof TypeError) {
4124
- throw new Error(
4125
- `createSubgraphNativeUsdtQuoter: invalid subgraphUrl: ${subgraphUrl}`
4126
- );
3832
+ throw new Error(`createSubgraphNativeUsdtQuoter: invalid subgraphUrl: ${subgraphUrl}`);
4127
3833
  }
4128
3834
  throw err;
4129
3835
  }
@@ -4134,23 +3840,15 @@ function createSubgraphNativeUsdtQuoter(config = {}) {
4134
3840
  const fetchImpl = config.fetchImpl ?? globalThis.fetch;
4135
3841
  const now = config.now ?? (() => Date.now());
4136
3842
  if (!fetchImpl) {
4137
- throw new Error(
4138
- "createSubgraphNativeUsdtQuoter: no fetch implementation available \u2014 pass `fetchImpl` or run on Node 18+"
4139
- );
3843
+ throw new Error("createSubgraphNativeUsdtQuoter: no fetch implementation available \u2014 pass `fetchImpl` or run on Node 18+");
4140
3844
  }
4141
3845
  let cached;
4142
3846
  async function getUsdtPerNative() {
4143
3847
  if (cacheTtl > 0 && cached && cached.expiresAt > now()) {
4144
3848
  return cached.usdtPerNative;
4145
3849
  }
4146
- const price = await fetchEthPriceFromSubgraph(
4147
- fetchImpl,
4148
- subgraphUrl
4149
- );
4150
- const usdtPerNative = toUsdtPerNative(
4151
- price ?? fallbackPrice,
4152
- usdtDecimals
4153
- );
3850
+ const price = await fetchEthPriceFromSubgraph(fetchImpl, subgraphUrl);
3851
+ const usdtPerNative = toUsdtPerNative(price ?? fallbackPrice, usdtDecimals);
4154
3852
  if (cacheTtl > 0) {
4155
3853
  cached = {
4156
3854
  usdtPerNative,
@@ -4159,66 +3857,62 @@ function createSubgraphNativeUsdtQuoter(config = {}) {
4159
3857
  }
4160
3858
  return usdtPerNative;
4161
3859
  }
3860
+ __name(getUsdtPerNative, "getUsdtPerNative");
4162
3861
  return async (amountNative) => {
4163
3862
  if (amountNative === 0n) return 0n;
4164
3863
  const usdtPerNative = await getUsdtPerNative();
4165
3864
  return amountNative * usdtPerNative / 10n ** BigInt(nativeDecimals);
4166
3865
  };
4167
3866
  }
3867
+ __name(createSubgraphNativeUsdtQuoter, "createSubgraphNativeUsdtQuoter");
4168
3868
  async function fetchEthPriceFromSubgraph(fetchImpl, subgraphUrl) {
4169
3869
  let response;
4170
3870
  try {
4171
3871
  response = await fetchImpl(subgraphUrl, {
4172
3872
  method: "POST",
4173
- headers: { "Content-Type": "application/json" },
4174
- body: JSON.stringify({ query: PRICE_QUERY })
3873
+ headers: {
3874
+ "Content-Type": "application/json"
3875
+ },
3876
+ body: JSON.stringify({
3877
+ query: PRICE_QUERY
3878
+ })
4175
3879
  });
4176
3880
  } catch (err) {
4177
- console.warn(
4178
- "[subgraphNativeUsdtQuoter] subgraph unreachable:",
4179
- err.message
4180
- );
3881
+ console.warn("[subgraphNativeUsdtQuoter] subgraph unreachable:", err.message);
4181
3882
  return null;
4182
3883
  }
4183
3884
  if (!response.ok) {
4184
- console.warn(
4185
- `[subgraphNativeUsdtQuoter] subgraph returned ${response.status}`
4186
- );
3885
+ console.warn(`[subgraphNativeUsdtQuoter] subgraph returned ${response.status}`);
4187
3886
  return null;
4188
3887
  }
4189
3888
  const json = await response.json();
4190
3889
  if (json.errors && json.errors.length > 0) {
4191
- console.warn(
4192
- "[subgraphNativeUsdtQuoter] subgraph errors:",
4193
- json.errors.map((e) => e.message).join("; ")
4194
- );
3890
+ console.warn("[subgraphNativeUsdtQuoter] subgraph errors:", json.errors.map((e) => e.message).join("; "));
4195
3891
  return null;
4196
3892
  }
4197
3893
  const raw = json.data?.bundle?.ethPriceUSD;
4198
3894
  if (!raw) return null;
4199
3895
  const parsed = Number(raw);
4200
3896
  if (!Number.isFinite(parsed) || parsed <= 0) {
4201
- console.warn(
4202
- `[subgraphNativeUsdtQuoter] invalid ethPriceUSD from subgraph: ${raw}`
4203
- );
3897
+ console.warn(`[subgraphNativeUsdtQuoter] invalid ethPriceUSD from subgraph: ${raw}`);
4204
3898
  return null;
4205
3899
  }
4206
3900
  const MIN_REASONABLE_ETH_PRICE = 100;
4207
3901
  const MAX_REASONABLE_ETH_PRICE = 1e5;
4208
3902
  if (parsed < MIN_REASONABLE_ETH_PRICE || parsed > MAX_REASONABLE_ETH_PRICE) {
4209
- console.warn(
4210
- `[PAFI] SubgraphNativeUsdtQuoter: ETH/USD price ${parsed} is outside reasonable range. Using fallback.`
4211
- );
3903
+ console.warn(`[PAFI] SubgraphNativeUsdtQuoter: ETH/USD price ${parsed} is outside reasonable range. Using fallback.`);
4212
3904
  return null;
4213
3905
  }
4214
3906
  return parsed;
4215
3907
  }
3908
+ __name(fetchEthPriceFromSubgraph, "fetchEthPriceFromSubgraph");
4216
3909
  function toUsdtPerNative(priceFloat, usdtDecimals) {
4217
3910
  const fixed = priceFloat.toFixed(usdtDecimals);
4218
3911
  const [whole, fraction = ""] = fixed.split(".");
4219
3912
  const padded = (fraction + "0".repeat(usdtDecimals)).slice(0, usdtDecimals);
4220
3913
  return BigInt(whole + padded);
4221
3914
  }
3915
+ __name(toUsdtPerNative, "toUsdtPerNative");
4222
3916
 
4223
3917
  // src/pools/nativePtQuoter.ts
4224
3918
  import { parseAbi } from "viem";
@@ -4239,18 +3933,7 @@ var POOL_PRICE_QUERY = `
4239
3933
  }
4240
3934
  `;
4241
3935
  function createNativePtQuoter(config) {
4242
- const {
4243
- provider,
4244
- pointTokenAddress,
4245
- chainlinkFeedAddress = "0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70",
4246
- subgraphUrl = PAFI_SUBGRAPH_URL,
4247
- cacheTtlMs = 3e4,
4248
- fallbackEthPriceUsd = 3e3,
4249
- fallbackPtPriceUsdt = 0.1,
4250
- failClosed = false,
4251
- fetchImpl = globalThis.fetch,
4252
- now = () => Date.now()
4253
- } = config;
3936
+ const { provider, pointTokenAddress, chainlinkFeedAddress = "0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70", subgraphUrl = PAFI_SUBGRAPH_URL, cacheTtlMs = 3e4, fallbackEthPriceUsd = 3e3, fallbackPtPriceUsdt = 0.1, failClosed = false, fetchImpl = globalThis.fetch, now = /* @__PURE__ */ __name(() => Date.now(), "now") } = config;
4254
3937
  let ethPriceCache;
4255
3938
  let ptPriceCache;
4256
3939
  async function getEthPrice8dec() {
@@ -4269,28 +3952,34 @@ function createNativePtQuoter(config) {
4269
3952
  if (ageS > CHAINLINK_MAX_AGE_S) {
4270
3953
  throw new Error(`Chainlink: price stale by ${ageS}s`);
4271
3954
  }
4272
- ethPriceCache = { value: answer, expiresAt: ts + cacheTtlMs };
3955
+ ethPriceCache = {
3956
+ value: answer,
3957
+ expiresAt: ts + cacheTtlMs
3958
+ };
4273
3959
  return answer;
4274
3960
  } catch (err) {
4275
3961
  if (failClosed) {
4276
- throw new Error(
4277
- `[nativePtQuoter] Chainlink unavailable in fail-closed mode: ${err.message}`
4278
- );
3962
+ throw new Error(`[nativePtQuoter] Chainlink unavailable in fail-closed mode: ${err.message}`);
4279
3963
  }
4280
3964
  console.warn("[nativePtQuoter] Chainlink unavailable, using fallback:", err.message);
4281
3965
  return BigInt(Math.round(fallbackEthPriceUsd * 1e8));
4282
3966
  }
4283
3967
  }
3968
+ __name(getEthPrice8dec, "getEthPrice8dec");
4284
3969
  async function getPtPerUsdt18dec() {
4285
3970
  const ts = now();
4286
3971
  if (ptPriceCache && ptPriceCache.expiresAt > ts) return ptPriceCache.value;
4287
3972
  try {
4288
3973
  const response = await fetchImpl(subgraphUrl, {
4289
3974
  method: "POST",
4290
- headers: { "Content-Type": "application/json" },
3975
+ headers: {
3976
+ "Content-Type": "application/json"
3977
+ },
4291
3978
  body: JSON.stringify({
4292
3979
  query: POOL_PRICE_QUERY,
4293
- variables: { id: pointTokenAddress.toLowerCase() }
3980
+ variables: {
3981
+ id: pointTokenAddress.toLowerCase()
3982
+ }
4294
3983
  })
4295
3984
  });
4296
3985
  if (!response.ok) throw new Error(`subgraph HTTP ${response.status}`);
@@ -4306,19 +3995,21 @@ function createNativePtQuoter(config) {
4306
3995
  const raw = parseBigDecimalTo18(ptPerUsdtStr);
4307
3996
  if (raw === 0n) throw new Error(`pool price parsed to zero: ${ptPerUsdtStr}`);
4308
3997
  const value = 10n ** 24n / raw;
4309
- ptPriceCache = { value, expiresAt: ts + cacheTtlMs };
3998
+ ptPriceCache = {
3999
+ value,
4000
+ expiresAt: ts + cacheTtlMs
4001
+ };
4310
4002
  return value;
4311
4003
  } catch (err) {
4312
4004
  if (failClosed) {
4313
- throw new Error(
4314
- `[nativePtQuoter] subgraph miss for ${pointTokenAddress} in fail-closed mode: ${err.message}`
4315
- );
4005
+ throw new Error(`[nativePtQuoter] subgraph miss for ${pointTokenAddress} in fail-closed mode: ${err.message}`);
4316
4006
  }
4317
4007
  console.warn("[nativePtQuoter] subgraph unavailable, using fallback:", err.message);
4318
4008
  const ptPerUsdtHuman = 1 / fallbackPtPriceUsdt;
4319
4009
  return parseBigDecimalTo18(ptPerUsdtHuman.toFixed(18));
4320
4010
  }
4321
4011
  }
4012
+ __name(getPtPerUsdt18dec, "getPtPerUsdt18dec");
4322
4013
  return async (amountNative) => {
4323
4014
  if (amountNative === 0n) return 0n;
4324
4015
  const [ethPrice8dec, ptPerUsdt18dec] = await Promise.all([
@@ -4328,12 +4019,14 @@ function createNativePtQuoter(config) {
4328
4019
  return amountNative * ethPrice8dec * ptPerUsdt18dec / 10n ** 26n;
4329
4020
  };
4330
4021
  }
4022
+ __name(createNativePtQuoter, "createNativePtQuoter");
4331
4023
  function parseBigDecimalTo18(s) {
4332
4024
  const SCALE = 18;
4333
4025
  const [whole = "0", frac = ""] = s.split(".");
4334
4026
  const padded = (frac + "0".repeat(SCALE)).slice(0, SCALE);
4335
4027
  return BigInt(whole + padded);
4336
4028
  }
4029
+ __name(parseBigDecimalTo18, "parseBigDecimalTo18");
4337
4030
 
4338
4031
  // src/pafi-backend/client.ts
4339
4032
  import { getPafiServiceUrls } from "@pafi-dev/core";
@@ -4341,15 +4034,24 @@ function extractPafiErrorFields(json, status) {
4341
4034
  const inner = typeof json.error === "object" && json.error !== null ? json.error : null;
4342
4035
  const code = inner?.code ?? json.code ?? "INTERNAL_ERROR";
4343
4036
  const message = inner?.message ?? json.message ?? `HTTP ${status}`;
4344
- return { code, message };
4037
+ return {
4038
+ code,
4039
+ message
4040
+ };
4345
4041
  }
4042
+ __name(extractPafiErrorFields, "extractPafiErrorFields");
4346
4043
  function serializeBigInt(_key, value) {
4347
4044
  return typeof value === "bigint" ? value.toString(10) : value;
4348
4045
  }
4046
+ __name(serializeBigInt, "serializeBigInt");
4349
4047
  function sleep(ms) {
4350
4048
  return new Promise((resolve) => setTimeout(resolve, ms));
4351
4049
  }
4050
+ __name(sleep, "sleep");
4352
4051
  var PafiBackendClient = class {
4052
+ static {
4053
+ __name(this, "PafiBackendClient");
4054
+ }
4353
4055
  config;
4354
4056
  baseUrl;
4355
4057
  constructor(config) {
@@ -4387,11 +4089,11 @@ var PafiBackendClient = class {
4387
4089
  throw lastError;
4388
4090
  }
4389
4091
  /**
4390
- * Fetch ERC-4337 UserOp receipt via PAFI's authenticated bundler proxy.
4391
- * Returns `null` when the bundler hasn't seen the userOp yet — caller
4392
- * should keep polling. Used by status endpoints to short-circuit the
4393
- * on-chain indexer when several PENDING locks share the same amount.
4394
- */
4092
+ * Fetch ERC-4337 UserOp receipt via PAFI's authenticated bundler proxy.
4093
+ * Returns `null` when the bundler hasn't seen the userOp yet — caller
4094
+ * should keep polling. Used by status endpoints to short-circuit the
4095
+ * on-chain indexer when several PENDING locks share the same amount.
4096
+ */
4395
4097
  async getUserOpReceipt(userOpHash) {
4396
4098
  const fetchFn = this.config.fetchImpl ?? fetch;
4397
4099
  const url = `${this.baseUrl}/bundler/receipt`;
@@ -4404,14 +4106,12 @@ var PafiBackendClient = class {
4404
4106
  Authorization: `Bearer ${this.config.apiKey}`,
4405
4107
  "X-Issuer-Id": this.config.issuerId
4406
4108
  },
4407
- body: JSON.stringify({ userOpHash })
4109
+ body: JSON.stringify({
4110
+ userOpHash
4111
+ })
4408
4112
  });
4409
4113
  } catch (err) {
4410
- throw new PafiBackendError(
4411
- "NETWORK_ERROR",
4412
- `Network error: ${err instanceof Error ? err.message : String(err)}`,
4413
- 0
4414
- );
4114
+ throw new PafiBackendError("NETWORK_ERROR", `Network error: ${err instanceof Error ? err.message : String(err)}`, 0);
4415
4115
  }
4416
4116
  const text = await response.text();
4417
4117
  let json = {};
@@ -4445,11 +4145,7 @@ var PafiBackendClient = class {
4445
4145
  body: JSON.stringify(request)
4446
4146
  });
4447
4147
  } catch (err) {
4448
- throw new PafiBackendError(
4449
- "NETWORK_ERROR",
4450
- `Network error: ${err instanceof Error ? err.message : String(err)}`,
4451
- 0
4452
- );
4148
+ throw new PafiBackendError("NETWORK_ERROR", `Network error: ${err instanceof Error ? err.message : String(err)}`, 0);
4453
4149
  }
4454
4150
  const text = await response.text();
4455
4151
  let json = {};
@@ -4461,7 +4157,9 @@ var PafiBackendClient = class {
4461
4157
  const { code, message } = extractPafiErrorFields(json, response.status);
4462
4158
  throw new PafiBackendError(code, message, response.status, json);
4463
4159
  }
4464
- return { userOpHash: json.userOpHash };
4160
+ return {
4161
+ userOpHash: json.userOpHash
4162
+ };
4465
4163
  }
4466
4164
  async _doRequest(request) {
4467
4165
  const fetchFn = this.config.fetchImpl ?? fetch;
@@ -4479,11 +4177,7 @@ var PafiBackendClient = class {
4479
4177
  body
4480
4178
  });
4481
4179
  } catch (err) {
4482
- throw new PafiBackendError(
4483
- "NETWORK_ERROR",
4484
- `Network error: ${err instanceof Error ? err.message : String(err)}`,
4485
- 0
4486
- );
4180
+ throw new PafiBackendError("NETWORK_ERROR", `Network error: ${err instanceof Error ? err.message : String(err)}`, 0);
4487
4181
  }
4488
4182
  const text = await response.text();
4489
4183
  let json = {};
@@ -4504,9 +4198,7 @@ var PafiBackendClient = class {
4504
4198
  return {
4505
4199
  paymaster: json.paymaster,
4506
4200
  paymasterData: json.paymasterData,
4507
- paymasterVerificationGasLimit: BigInt(
4508
- json.paymasterVerificationGasLimit
4509
- ),
4201
+ paymasterVerificationGasLimit: BigInt(json.paymasterVerificationGasLimit),
4510
4202
  paymasterPostOpGasLimit: BigInt(json.paymasterPostOpGasLimit),
4511
4203
  callGasLimit: json.callGasLimit != null ? BigInt(json.callGasLimit) : void 0,
4512
4204
  verificationGasLimit: json.verificationGasLimit != null ? BigInt(json.verificationGasLimit) : void 0,
@@ -4530,10 +4222,7 @@ function evaluateRedemption(input) {
4530
4222
  const cooldownUntilUnixSec = history.lastRedeemedAtUnixSec !== null ? history.lastRedeemedAtUnixSec + policy.cooldownSec : null;
4531
4223
  const inCooldown = cooldownUntilUnixSec !== null && cooldownUntilUnixSec > nowUnixSec;
4532
4224
  const activeBlackout = findActiveBlackout(policy.blackoutWindows, nowUnixSec);
4533
- const nextBlackoutEnd = nextBlackoutEndAfter(
4534
- policy.blackoutWindows,
4535
- nowUnixSec
4536
- );
4225
+ const nextBlackoutEnd = nextBlackoutEndAfter(policy.blackoutWindows, nowUnixSec);
4537
4226
  let availableAmountPt = 0n;
4538
4227
  if (!inCooldown && !activeBlackout) {
4539
4228
  const headroom = dailyRemaining < policy.perTxMaxPt ? dailyRemaining : policy.perTxMaxPt;
@@ -4550,7 +4239,11 @@ function evaluateRedemption(input) {
4550
4239
  policySource
4551
4240
  };
4552
4241
  if (amountPt <= 0n) {
4553
- return { allowed: false, preview, denial: rejectAmountBelowMin(policy) };
4242
+ return {
4243
+ allowed: false,
4244
+ preview,
4245
+ denial: rejectAmountBelowMin(policy)
4246
+ };
4554
4247
  }
4555
4248
  const denial = firstDenial({
4556
4249
  amountPt,
@@ -4560,25 +4253,29 @@ function evaluateRedemption(input) {
4560
4253
  cooldownUntilUnixSec,
4561
4254
  activeBlackout
4562
4255
  });
4563
- if (denial) return { allowed: false, denial, preview };
4564
- return { allowed: true, preview };
4256
+ if (denial) return {
4257
+ allowed: false,
4258
+ denial,
4259
+ preview
4260
+ };
4261
+ return {
4262
+ allowed: true,
4263
+ preview
4264
+ };
4565
4265
  }
4266
+ __name(evaluateRedemption, "evaluateRedemption");
4566
4267
  function firstDenial(args) {
4567
4268
  const { amountPt, policy, dailyRemaining, inCooldown, cooldownUntilUnixSec, activeBlackout } = args;
4568
4269
  if (activeBlackout) {
4569
4270
  return {
4570
4271
  code: "BLACKOUT_WINDOW",
4571
- message: `Redemption is blocked until ${new Date(
4572
- activeBlackout.endUnixSec * 1e3
4573
- ).toISOString()}${activeBlackout.reason ? ` (${activeBlackout.reason})` : ""}`
4272
+ message: `Redemption is blocked until ${new Date(activeBlackout.endUnixSec * 1e3).toISOString()}${activeBlackout.reason ? ` (${activeBlackout.reason})` : ""}`
4574
4273
  };
4575
4274
  }
4576
4275
  if (inCooldown && cooldownUntilUnixSec !== null) {
4577
4276
  return {
4578
4277
  code: "COOLDOWN_ACTIVE",
4579
- message: `Cooldown active until ${new Date(
4580
- cooldownUntilUnixSec * 1e3
4581
- ).toISOString()}`
4278
+ message: `Cooldown active until ${new Date(cooldownUntilUnixSec * 1e3).toISOString()}`
4582
4279
  };
4583
4280
  }
4584
4281
  if (amountPt < policy.perTxMinPt) {
@@ -4601,18 +4298,21 @@ function firstDenial(args) {
4601
4298
  }
4602
4299
  return null;
4603
4300
  }
4301
+ __name(firstDenial, "firstDenial");
4604
4302
  function rejectAmountBelowMin(policy) {
4605
4303
  return {
4606
4304
  code: "AMOUNT_BELOW_MIN",
4607
4305
  message: `amount must be >= ${policy.perTxMinPt}`
4608
4306
  };
4609
4307
  }
4308
+ __name(rejectAmountBelowMin, "rejectAmountBelowMin");
4610
4309
  function findActiveBlackout(windows, nowUnixSec) {
4611
4310
  for (const w of windows) {
4612
4311
  if (w.startUnixSec <= nowUnixSec && nowUnixSec < w.endUnixSec) return w;
4613
4312
  }
4614
4313
  return null;
4615
4314
  }
4315
+ __name(findActiveBlackout, "findActiveBlackout");
4616
4316
  function nextBlackoutEndAfter(windows, nowUnixSec) {
4617
4317
  let earliest = null;
4618
4318
  for (const w of windows) {
@@ -4622,17 +4322,19 @@ function nextBlackoutEndAfter(windows, nowUnixSec) {
4622
4322
  }
4623
4323
  return earliest;
4624
4324
  }
4325
+ __name(nextBlackoutEndAfter, "nextBlackoutEndAfter");
4625
4326
  var REDEMPTION_HISTORY_WINDOW_SEC = SECONDS_PER_DAY;
4626
4327
 
4627
4328
  // src/redemption/policyProvider.ts
4628
4329
  import { PafiSdkError as PafiSdkError2 } from "@pafi-dev/core";
4629
4330
 
4630
4331
  // src/redemption/settlementClient.ts
4631
- import {
4632
- getPafiServiceUrls as getPafiServiceUrls2
4633
- } from "@pafi-dev/core";
4332
+ import { getPafiServiceUrls as getPafiServiceUrls2 } from "@pafi-dev/core";
4634
4333
  var DEFAULT_TIMEOUT_MS = 1e3;
4635
4334
  var SettlementClient = class {
4335
+ static {
4336
+ __name(this, "SettlementClient");
4337
+ }
4636
4338
  config;
4637
4339
  constructor(config) {
4638
4340
  if (!config.chainId) throw new Error("SettlementClient: chainId is required");
@@ -4652,10 +4354,7 @@ var SettlementClient = class {
4652
4354
  const fetchFn = this.config.fetchImpl ?? fetch;
4653
4355
  const url = `${this.config.baseUrl}/issuers/${encodeURIComponent(this.config.issuerId)}/redemption-policy`;
4654
4356
  const controller = new AbortController();
4655
- const timer = setTimeout(
4656
- () => controller.abort(),
4657
- this.config.fetchTimeoutMs
4658
- );
4357
+ const timer = setTimeout(() => controller.abort(), this.config.fetchTimeoutMs);
4659
4358
  let response;
4660
4359
  try {
4661
4360
  response = await fetchFn(url, {
@@ -4669,30 +4368,56 @@ var SettlementClient = class {
4669
4368
  });
4670
4369
  } catch (err) {
4671
4370
  const isAbort = err instanceof Error && (err.name === "AbortError" || /aborted|timeout/i.test(err.message ?? ""));
4672
- return { ok: false, reason: isAbort ? "TIMEOUT" : "NETWORK" };
4371
+ return {
4372
+ ok: false,
4373
+ reason: isAbort ? "TIMEOUT" : "NETWORK"
4374
+ };
4673
4375
  } finally {
4674
4376
  clearTimeout(timer);
4675
4377
  }
4676
4378
  if (response.status === 404) {
4677
- return { ok: false, reason: "NOT_FOUND", status: 404 };
4379
+ return {
4380
+ ok: false,
4381
+ reason: "NOT_FOUND",
4382
+ status: 404
4383
+ };
4678
4384
  }
4679
4385
  if (response.status === 401 || response.status === 403) {
4680
- return { ok: false, reason: "UNAUTHORIZED", status: response.status };
4386
+ return {
4387
+ ok: false,
4388
+ reason: "UNAUTHORIZED",
4389
+ status: response.status
4390
+ };
4681
4391
  }
4682
4392
  if (!response.ok) {
4683
- return { ok: false, reason: "SERVER_ERROR", status: response.status };
4393
+ return {
4394
+ ok: false,
4395
+ reason: "SERVER_ERROR",
4396
+ status: response.status
4397
+ };
4684
4398
  }
4685
4399
  let raw;
4686
4400
  try {
4687
4401
  raw = await response.json();
4688
4402
  } catch {
4689
- return { ok: false, reason: "INVALID_RESPONSE", status: response.status };
4403
+ return {
4404
+ ok: false,
4405
+ reason: "INVALID_RESPONSE",
4406
+ status: response.status
4407
+ };
4690
4408
  }
4691
4409
  const parsed = parsePolicyDto(raw);
4692
4410
  if (!parsed) {
4693
- return { ok: false, reason: "INVALID_RESPONSE", status: response.status };
4411
+ return {
4412
+ ok: false,
4413
+ reason: "INVALID_RESPONSE",
4414
+ status: response.status
4415
+ };
4694
4416
  }
4695
- return { ok: true, policy: parsed };
4417
+ return {
4418
+ ok: true,
4419
+ policy: parsed
4420
+ };
4696
4421
  }
4697
4422
  };
4698
4423
  function parsePolicyDto(raw) {
@@ -4715,6 +4440,7 @@ function parsePolicyDto(raw) {
4715
4440
  return null;
4716
4441
  }
4717
4442
  }
4443
+ __name(parsePolicyDto, "parsePolicyDto");
4718
4444
  function normalizeBlackout(raw) {
4719
4445
  if (!raw || typeof raw !== "object") return null;
4720
4446
  const win = raw;
@@ -4727,6 +4453,7 @@ function normalizeBlackout(raw) {
4727
4453
  reason: typeof win.reason === "string" ? win.reason : void 0
4728
4454
  };
4729
4455
  }
4456
+ __name(normalizeBlackout, "normalizeBlackout");
4730
4457
 
4731
4458
  // src/redemption/defaults.ts
4732
4459
  var PT_DECIMALS = 10n ** 18n;
@@ -4740,23 +4467,34 @@ var DEFAULT_REDEMPTION_POLICY = {
4740
4467
  version: "default-v1"
4741
4468
  };
4742
4469
  function defaultPolicyFor(issuerId) {
4743
- return { ...DEFAULT_REDEMPTION_POLICY, issuerId };
4470
+ return {
4471
+ ...DEFAULT_REDEMPTION_POLICY,
4472
+ issuerId
4473
+ };
4744
4474
  }
4475
+ __name(defaultPolicyFor, "defaultPolicyFor");
4745
4476
 
4746
4477
  // src/redemption/policyProvider.ts
4747
4478
  var DEFAULT_CACHE_TTL_MS3 = 5 * 60 * 1e3;
4748
4479
  var PolicyProviderUnavailableError = class extends PafiSdkError2 {
4480
+ static {
4481
+ __name(this, "PolicyProviderUnavailableError");
4482
+ }
4749
4483
  code = "POLICY_PROVIDER_UNAVAILABLE";
4750
4484
  httpStatus = "service_unavailable";
4751
4485
  details;
4752
4486
  constructor(issuerId, reason) {
4753
- super(
4754
- `Redemption policy provider unavailable for issuer ${issuerId}: ${reason}. Pre-flight redeem limit cannot be enforced \u2014 refusing to sign BurnRequest. Mobile FE: surface "try again shortly" and retry with backoff.`
4755
- );
4756
- this.details = { issuerId, reason };
4487
+ super(`Redemption policy provider unavailable for issuer ${issuerId}: ${reason}. Pre-flight redeem limit cannot be enforced \u2014 refusing to sign BurnRequest. Mobile FE: surface "try again shortly" and retry with backoff.`);
4488
+ this.details = {
4489
+ issuerId,
4490
+ reason
4491
+ };
4757
4492
  }
4758
4493
  };
4759
4494
  var PolicyProvider = class {
4495
+ static {
4496
+ __name(this, "PolicyProvider");
4497
+ }
4760
4498
  client;
4761
4499
  issuerId;
4762
4500
  cacheTtlMs;
@@ -4775,7 +4513,10 @@ var PolicyProvider = class {
4775
4513
  }
4776
4514
  async getPolicy() {
4777
4515
  const fresh = this.readCache();
4778
- if (fresh) return { policy: fresh, source: "cache" };
4516
+ if (fresh) return {
4517
+ policy: fresh,
4518
+ source: "cache"
4519
+ };
4779
4520
  if (this.inflight) return this.inflight;
4780
4521
  this.inflight = this.fetchAndStore().finally(() => {
4781
4522
  this.inflight = null;
@@ -4801,19 +4542,22 @@ var PolicyProvider = class {
4801
4542
  policy: result.policy,
4802
4543
  expiresAtMs: this.now() + this.cacheTtlMs
4803
4544
  };
4804
- return { policy: result.policy, source: "settlement" };
4545
+ return {
4546
+ policy: result.policy,
4547
+ source: "settlement"
4548
+ };
4805
4549
  }
4806
4550
  const reason = "reason" in result && typeof result.reason === "string" ? result.reason : "unknown";
4807
4551
  if (this.onFetchFailure === "permissive-default") {
4808
- this.onWarning?.(
4809
- "PolicyProvider: settlement-api unreachable, falling back to permissive default. Pre-flight redeem limit is DEGRADED until settlement-api recovers.",
4810
- {
4811
- event: "policy_provider_fallback",
4812
- issuerId: this.issuerId,
4813
- reason
4814
- }
4815
- );
4816
- return { policy: defaultPolicyFor(this.issuerId), source: "default" };
4552
+ this.onWarning?.("PolicyProvider: settlement-api unreachable, falling back to permissive default. Pre-flight redeem limit is DEGRADED until settlement-api recovers.", {
4553
+ event: "policy_provider_fallback",
4554
+ issuerId: this.issuerId,
4555
+ reason
4556
+ });
4557
+ return {
4558
+ policy: defaultPolicyFor(this.issuerId),
4559
+ source: "default"
4560
+ };
4817
4561
  }
4818
4562
  throw new PolicyProviderUnavailableError(this.issuerId, reason);
4819
4563
  }
@@ -4821,6 +4565,9 @@ var PolicyProvider = class {
4821
4565
 
4822
4566
  // src/redemption/service.ts
4823
4567
  var RedemptionService = class {
4568
+ static {
4569
+ __name(this, "RedemptionService");
4570
+ }
4824
4571
  policyProvider;
4825
4572
  historyStore;
4826
4573
  nowUnixSec;
@@ -4837,17 +4584,16 @@ var RedemptionService = class {
4837
4584
  const { policy, source } = await this.policyProvider.getPolicy();
4838
4585
  const now = this.nowUnixSec();
4839
4586
  const [redeemedLast24hPt, lastRedeemedAtUnixSec] = await Promise.all([
4840
- this.historyStore.sumRedeemedSince(
4841
- user,
4842
- now - REDEMPTION_HISTORY_WINDOW_SEC,
4843
- pointTokenAddress
4844
- ),
4587
+ this.historyStore.sumRedeemedSince(user, now - REDEMPTION_HISTORY_WINDOW_SEC, pointTokenAddress),
4845
4588
  this.historyStore.getLastRedeemedAtUnixSec(user, pointTokenAddress)
4846
4589
  ]);
4847
4590
  return evaluateRedemption({
4848
4591
  policy,
4849
4592
  policySource: source,
4850
- history: { redeemedLast24hPt, lastRedeemedAtUnixSec },
4593
+ history: {
4594
+ redeemedLast24hPt,
4595
+ lastRedeemedAtUnixSec
4596
+ },
4851
4597
  amountPt,
4852
4598
  nowUnixSec: now
4853
4599
  });
@@ -4874,16 +4620,18 @@ async function createIssuerService(config) {
4874
4620
  if (!config.auth?.domain) {
4875
4621
  throw new Error("createIssuerService: auth.domain is required");
4876
4622
  }
4877
- const rawAddresses = config.pointTokenAddresses && config.pointTokenAddresses.length > 0 ? config.pointTokenAddresses : config.pointTokenAddress ? [config.pointTokenAddress] : [];
4623
+ const rawAddresses = config.pointTokenAddresses && config.pointTokenAddresses.length > 0 ? config.pointTokenAddresses : config.pointTokenAddress ? [
4624
+ config.pointTokenAddress
4625
+ ] : [];
4878
4626
  if (rawAddresses.length === 0) {
4879
- throw new Error(
4880
- "createIssuerService: at least one of pointTokenAddress / pointTokenAddresses is required"
4881
- );
4627
+ throw new Error("createIssuerService: at least one of pointTokenAddress / pointTokenAddresses is required");
4882
4628
  }
4883
4629
  const tokenAddresses = rawAddresses.map((a) => getAddress12(a));
4884
4630
  const ledger = config.ledger;
4885
4631
  const sessionStore = config.sessionStore ?? new MemorySessionStore();
4886
- const policy = config.policy ?? new DefaultPolicyEngine({ ledger });
4632
+ const policy = config.policy ?? new DefaultPolicyEngine({
4633
+ ledger
4634
+ });
4887
4635
  const authServiceConfig = {
4888
4636
  sessionStore,
4889
4637
  jwtSecret: config.auth.jwtSecret,
@@ -4911,9 +4659,7 @@ async function createIssuerService(config) {
4911
4659
  const baseCursorStore = config.indexer?.cursorStore;
4912
4660
  const sharedCursorWithMultipleTokens = baseCursorStore !== void 0 && typeof baseCursorStore.forKey !== "function" && tokenAddresses.length > 1;
4913
4661
  if (sharedCursorWithMultipleTokens) {
4914
- console.warn(
4915
- `[@pafi-dev/issuer] cursorStore lacks forKey() and ${tokenAddresses.length} PointTokens are configured. All PointIndexers will share one cursor row, causing token-skipping. Implement IIndexerCursorStore.forKey to return per-token derived stores. This permissive path will be removed in a future major release.`
4916
- );
4662
+ console.warn(`[@pafi-dev/issuer] cursorStore lacks forKey() and ${tokenAddresses.length} PointTokens are configured. All PointIndexers will share one cursor row, causing token-skipping. Implement IIndexerCursorStore.forKey to return per-token derived stores. This permissive path will be removed in a future major release.`);
4917
4663
  }
4918
4664
  const indexers = /* @__PURE__ */ new Map();
4919
4665
  for (const tokenAddress of tokenAddresses) {
@@ -4929,9 +4675,7 @@ async function createIssuerService(config) {
4929
4675
  indexerConfig.fromBlock = config.indexer.fromBlock;
4930
4676
  }
4931
4677
  if (baseCursorStore) {
4932
- indexerConfig.cursorStore = typeof baseCursorStore.forKey === "function" ? baseCursorStore.forKey(
4933
- `point-indexer:${tokenAddress.toLowerCase()}`
4934
- ) : baseCursorStore;
4678
+ indexerConfig.cursorStore = typeof baseCursorStore.forKey === "function" ? baseCursorStore.forKey(`point-indexer:${tokenAddress.toLowerCase()}`) : baseCursorStore;
4935
4679
  }
4936
4680
  if (config.indexer?.confirmations !== void 0) {
4937
4681
  indexerConfig.confirmations = config.indexer.confirmations;
@@ -5002,9 +4746,7 @@ async function createIssuerService(config) {
5002
4746
  if (config.indexer?.autoStart) {
5003
4747
  const lock = config.indexer.singletonLock;
5004
4748
  if (!lock) {
5005
- console.warn(
5006
- "[@pafi-dev/issuer] indexer.autoStart=true without singletonLock \u2014 this is UNSAFE in multi-replica deployments. Either set replicas=1 + INDEXER_AUTOSTART=false on non-leader pods, or pass `singletonLock: makePostgresSingletonLock(dataSource)`. This permissive path will be removed in a future major release."
5007
- );
4749
+ console.warn("[@pafi-dev/issuer] indexer.autoStart=true without singletonLock \u2014 this is UNSAFE in multi-replica deployments. Either set replicas=1 + INDEXER_AUTOSTART=false on non-leader pods, or pass `singletonLock: makePostgresSingletonLock(dataSource)`. This permissive path will be removed in a future major release.");
5008
4750
  for (const idx of indexers.values()) {
5009
4751
  idx.start();
5010
4752
  }
@@ -5033,39 +4775,39 @@ async function createIssuerService(config) {
5033
4775
  redemption
5034
4776
  };
5035
4777
  }
4778
+ __name(createIssuerService, "createIssuerService");
5036
4779
 
5037
4780
  // src/issuer-state/validator.ts
5038
4781
  import { getAddress as getAddress13 } from "viem";
5039
- import {
5040
- POINT_TOKEN_ABI as POINT_TOKEN_ABI3,
5041
- issuerRegistryAbi,
5042
- getContractAddresses as getContractAddresses8
5043
- } from "@pafi-dev/core";
4782
+ import { POINT_TOKEN_ABI as POINT_TOKEN_ABI3, issuerRegistryAbi, getContractAddresses as getContractAddresses8 } from "@pafi-dev/core";
5044
4783
  var ISSUER_RECORD_TTL_MS = 1e4;
5045
4784
  var IssuerStateValidator = class _IssuerStateValidator {
5046
- constructor(provider, registryAddress) {
5047
- this.provider = provider;
5048
- this.registryAddress = registryAddress;
4785
+ static {
4786
+ __name(this, "IssuerStateValidator");
5049
4787
  }
5050
4788
  provider;
5051
4789
  registryAddress;
5052
4790
  pointTokenIssuerCache = /* @__PURE__ */ new Map();
5053
4791
  stateCache = /* @__PURE__ */ new Map();
5054
4792
  inflight = /* @__PURE__ */ new Map();
4793
+ constructor(provider, registryAddress) {
4794
+ this.provider = provider;
4795
+ this.registryAddress = registryAddress;
4796
+ }
5055
4797
  /**
5056
- * Convenience factory — reads `registryAddress` from the SDK
5057
- * `CONTRACT_ADDRESSES` map for the given chain.
5058
- */
4798
+ * Convenience factory — reads `registryAddress` from the SDK
4799
+ * `CONTRACT_ADDRESSES` map for the given chain.
4800
+ */
5059
4801
  static forChain(provider, chainId) {
5060
4802
  const { issuerRegistry } = getContractAddresses8(chainId);
5061
4803
  return new _IssuerStateValidator(provider, issuerRegistry);
5062
4804
  }
5063
4805
  /**
5064
- * Invalidate cached state for one PointToken, or everything if omitted.
5065
- * Call after admin txs that change registry or cap settings — closes
5066
- * the split-brain window described
5067
- * passive TTL. Idempotent: safe to call when no entry exists.
5068
- */
4806
+ * Invalidate cached state for one PointToken, or everything if omitted.
4807
+ * Call after admin txs that change registry or cap settings — closes
4808
+ * the split-brain window described
4809
+ * passive TTL. Idempotent: safe to call when no entry exists.
4810
+ */
5069
4811
  invalidate(pointToken) {
5070
4812
  if (pointToken) {
5071
4813
  const key = getAddress13(pointToken);
@@ -5079,9 +4821,9 @@ var IssuerStateValidator = class _IssuerStateValidator {
5079
4821
  }
5080
4822
  }
5081
4823
  /**
5082
- * Resolve `PointToken.issuer()` once per token and memoize.
5083
- * The issuer field is set at `initialize()` and never changes.
5084
- */
4824
+ * Resolve `PointToken.issuer()` once per token and memoize.
4825
+ * The issuer field is set at `initialize()` and never changes.
4826
+ */
5085
4827
  async getIssuerAddressForPointToken(pointToken) {
5086
4828
  const key = getAddress13(pointToken);
5087
4829
  const cached = this.pointTokenIssuerCache.get(key);
@@ -5095,9 +4837,9 @@ var IssuerStateValidator = class _IssuerStateValidator {
5095
4837
  return getAddress13(issuer);
5096
4838
  }
5097
4839
  /**
5098
- * Read registry record + totalSupply, with 30s cache and in-flight
5099
- * deduplication. Does NOT throw on inactive/missing — returns raw state.
5100
- */
4840
+ * Read registry record + totalSupply, with 30s cache and in-flight
4841
+ * deduplication. Does NOT throw on inactive/missing — returns raw state.
4842
+ */
5101
4843
  async getIssuerState(pointToken) {
5102
4844
  const tokenAddr = getAddress13(pointToken);
5103
4845
  const now = Date.now();
@@ -5118,49 +4860,41 @@ var IssuerStateValidator = class _IssuerStateValidator {
5118
4860
  return promise;
5119
4861
  }
5120
4862
  /**
5121
- * Validate that `amount` PT can be minted on `pointToken` right now.
5122
- *
5123
- * Throws `IssuerStateError` with:
5124
- * - `ISSUER_NOT_REGISTERED` — registry has no record for this issuer
5125
- * - `ISSUER_INACTIVE` — issuer.active is false
5126
- * - `MINT_CAP_EXCEEDED` — totalSupply + amount would exceed hardCap
5127
- *
5128
- * Returns the fetched state on success so callers can log without a
5129
- * second RPC round-trip.
5130
- */
4863
+ * Validate that `amount` PT can be minted on `pointToken` right now.
4864
+ *
4865
+ * Throws `IssuerStateError` with:
4866
+ * - `ISSUER_NOT_REGISTERED` — registry has no record for this issuer
4867
+ * - `ISSUER_INACTIVE` — issuer.active is false
4868
+ * - `MINT_CAP_EXCEEDED` — totalSupply + amount would exceed hardCap
4869
+ *
4870
+ * Returns the fetched state on success so callers can log without a
4871
+ * second RPC round-trip.
4872
+ */
5131
4873
  async preValidateMint(pointToken, amount) {
5132
4874
  let state;
5133
4875
  try {
5134
4876
  state = await this.getIssuerState(pointToken);
5135
4877
  } catch (err) {
5136
4878
  if (err.message.includes("IssuerNotFound")) {
5137
- throw new IssuerStateError(
5138
- "ISSUER_NOT_REGISTERED",
5139
- `IssuerRegistry has no record for PointToken ${pointToken}`,
5140
- { pointToken }
5141
- );
4879
+ throw new IssuerStateError("ISSUER_NOT_REGISTERED", `IssuerRegistry has no record for PointToken ${pointToken}`, {
4880
+ pointToken
4881
+ });
5142
4882
  }
5143
4883
  throw err;
5144
4884
  }
5145
4885
  const { issuer, equityCap, equitySupply, remaining } = state;
5146
4886
  if (!issuer.active) {
5147
- throw new IssuerStateError(
5148
- "ISSUER_INACTIVE",
5149
- `Issuer "${issuer.name}" is deactivated on IssuerRegistry`,
5150
- { pointToken }
5151
- );
4887
+ throw new IssuerStateError("ISSUER_INACTIVE", `Issuer "${issuer.name}" is deactivated on IssuerRegistry`, {
4888
+ pointToken
4889
+ });
5152
4890
  }
5153
4891
  if (equitySupply + amount > equityCap.hardCap) {
5154
- throw new IssuerStateError(
5155
- "MINT_CAP_EXCEEDED",
5156
- `Requested ${amount} PT would exceed EQUITY mint cap. Cap=${equityCap.hardCap}, equityMinted=${equitySupply}, remaining=${remaining}`,
5157
- {
5158
- requested: amount.toString(),
5159
- cap: equityCap.hardCap.toString(),
5160
- equityMinted: equitySupply.toString(),
5161
- remaining: remaining.toString()
5162
- }
5163
- );
4892
+ throw new IssuerStateError("MINT_CAP_EXCEEDED", `Requested ${amount} PT would exceed EQUITY mint cap. Cap=${equityCap.hardCap}, equityMinted=${equitySupply}, remaining=${remaining}`, {
4893
+ requested: amount.toString(),
4894
+ cap: equityCap.hardCap.toString(),
4895
+ equityMinted: equitySupply.toString(),
4896
+ remaining: remaining.toString()
4897
+ });
5164
4898
  }
5165
4899
  return state;
5166
4900
  }
@@ -5170,7 +4904,9 @@ var IssuerStateValidator = class _IssuerStateValidator {
5170
4904
  address: this.registryAddress,
5171
4905
  abi: issuerRegistryAbi,
5172
4906
  functionName: "getIssuer",
5173
- args: [issuerAddr]
4907
+ args: [
4908
+ issuerAddr
4909
+ ]
5174
4910
  });
5175
4911
  const issuer = {
5176
4912
  signerAddress: issuerStruct.signerAddress,
@@ -5202,6 +4938,9 @@ var IssuerStateValidator = class _IssuerStateValidator {
5202
4938
 
5203
4939
  // src/redemption/memoryHistoryStore.ts
5204
4940
  var MemoryRedemptionHistoryStore = class {
4941
+ static {
4942
+ __name(this, "MemoryRedemptionHistoryStore");
4943
+ }
5205
4944
  entries = [];
5206
4945
  async sumRedeemedSince(user, sinceUnixSec, pointTokenAddress) {
5207
4946
  const userKey = user.toLowerCase();
@@ -5237,7 +4976,7 @@ var MemoryRedemptionHistoryStore = class {
5237
4976
  };
5238
4977
 
5239
4978
  // src/index.ts
5240
- var PAFI_ISSUER_SDK_VERSION = true ? "0.39.2" : "dev";
4979
+ var PAFI_ISSUER_SDK_VERSION = true ? "0.39.3" : "dev";
5241
4980
  export {
5242
4981
  AdapterMisconfiguredError,
5243
4982
  AuthError,