@pafi-dev/issuer 0.39.2 → 0.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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,29 +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";
2701
- function serializeUserOpTypedData(td) {
2702
- return {
2703
- domain: td.domain,
2704
- types: td.types,
2705
- primaryType: td.primaryType,
2706
- message: {
2707
- sender: td.message.sender,
2708
- nonce: `0x${td.message.nonce.toString(16)}`,
2709
- initCode: td.message.initCode,
2710
- callData: td.message.callData,
2711
- accountGasLimits: td.message.accountGasLimits,
2712
- preVerificationGas: `0x${td.message.preVerificationGas.toString(
2713
- 16
2714
- )}`,
2715
- gasFees: td.message.gasFees,
2716
- paymasterAndData: td.message.paymasterAndData
2717
- }
2718
- };
2719
- }
2511
+ import { computeUserOpHash } from "@pafi-dev/core";
2720
2512
  function mergePaymasterFields(userOp, paymasterFields) {
2721
2513
  if (!paymasterFields) return userOp;
2722
2514
  const merged = {
@@ -2727,36 +2519,26 @@ function mergePaymasterFields(userOp, paymasterFields) {
2727
2519
  }
2728
2520
  return merged;
2729
2521
  }
2522
+ __name(mergePaymasterFields, "mergePaymasterFields");
2730
2523
  function applyPaymasterGasEstimates(partialUserOp, paymasterFields, chainId) {
2731
- const userOp = mergePaymasterFields(
2732
- partialUserOp,
2733
- paymasterFields
2734
- );
2524
+ const userOp = mergePaymasterFields(partialUserOp, paymasterFields);
2735
2525
  return {
2736
2526
  userOp,
2737
- userOpHash: computeUserOpHash(userOp, chainId),
2738
- typedData: serializeUserOpTypedData(buildUserOpTypedData(userOp, chainId))
2527
+ userOpHash: computeUserOpHash(userOp, chainId)
2739
2528
  };
2740
2529
  }
2530
+ __name(applyPaymasterGasEstimates, "applyPaymasterGasEstimates");
2741
2531
  async function prepareMobileUserOp(params) {
2742
- const sponsored = applyPaymasterGasEstimates(
2743
- params.partialUserOp,
2744
- params.paymasterFields,
2745
- params.chainId
2746
- );
2532
+ const sponsored = applyPaymasterGasEstimates(params.partialUserOp, params.paymasterFields, params.chainId);
2747
2533
  const { userOp, userOpHash } = sponsored;
2748
2534
  let fallback;
2749
2535
  let fallbackEntry;
2750
2536
  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
- );
2537
+ fallback = applyPaymasterGasEstimates({
2538
+ ...params.partialUserOpFallback,
2539
+ maxFeePerGas: userOp.maxFeePerGas,
2540
+ maxPriorityFeePerGas: userOp.maxPriorityFeePerGas
2541
+ }, void 0, params.chainId);
2760
2542
  fallbackEntry = {
2761
2543
  callData: fallback.userOp.callData,
2762
2544
  callGasLimit: fallback.userOp.callGasLimit.toString(),
@@ -2793,23 +2575,24 @@ async function prepareMobileUserOp(params) {
2793
2575
  entry
2794
2576
  };
2795
2577
  }
2578
+ __name(prepareMobileUserOp, "prepareMobileUserOp");
2796
2579
 
2797
2580
  // src/pafi-backend/types.ts
2798
2581
  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;
2582
+ static {
2583
+ __name(this, "PafiBackendError");
2807
2584
  }
2808
2585
  code;
2809
2586
  httpStatus;
2810
2587
  details;
2811
2588
  retryAfter;
2812
2589
  serverSafeToRetry;
2590
+ constructor(code, message, httpStatus, details, opts) {
2591
+ super(message), this.code = code, this.httpStatus = httpStatus, this.details = details;
2592
+ this.name = "PafiBackendError";
2593
+ if (opts?.retryAfter !== void 0) this.retryAfter = opts.retryAfter;
2594
+ if (opts?.safeToRetry !== void 0) this.serverSafeToRetry = opts.safeToRetry;
2595
+ }
2813
2596
  get safeToRetry() {
2814
2597
  if (this.serverSafeToRetry !== void 0) return this.serverSafeToRetry;
2815
2598
  switch (this.code) {
@@ -2831,15 +2614,19 @@ var PafiBackendError = class extends Error {
2831
2614
 
2832
2615
  // src/pafi-backend/helpers.ts
2833
2616
  var BundlerNotConfiguredError = class extends PafiSdkError {
2617
+ static {
2618
+ __name(this, "BundlerNotConfiguredError");
2619
+ }
2834
2620
  code = "BUNDLER_NOT_CONFIGURED";
2835
2621
  httpStatus = "service_unavailable";
2836
2622
  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
- );
2623
+ super("PAFI backend client not configured \u2014 set PAFI_BACKEND_URL, PAFI_ISSUER_ID, PAFI_API_KEY to enable mobile submit.");
2840
2624
  }
2841
2625
  };
2842
2626
  var BundlerRejectedError = class extends PafiSdkError {
2627
+ static {
2628
+ __name(this, "BundlerRejectedError");
2629
+ }
2843
2630
  code = "BUNDLER_REJECTED";
2844
2631
  httpStatus = "unprocessable";
2845
2632
  cause;
@@ -2861,7 +2648,9 @@ async function requestPaymaster(params) {
2861
2648
  function: fn,
2862
2649
  pointToken: params.pointTokenAddress
2863
2650
  },
2864
- ...params.eip7702Auth ? { eip7702Auth: params.eip7702Auth } : {}
2651
+ ...params.eip7702Auth ? {
2652
+ eip7702Auth: params.eip7702Auth
2653
+ } : {}
2865
2654
  });
2866
2655
  } catch (err) {
2867
2656
  const msg = err instanceof Error ? err.message : String(err);
@@ -2872,6 +2661,7 @@ async function requestPaymaster(params) {
2872
2661
  throw err;
2873
2662
  }
2874
2663
  }
2664
+ __name(requestPaymaster, "requestPaymaster");
2875
2665
  function isTransientPaymasterError(code) {
2876
2666
  switch (code) {
2877
2667
  case "NETWORK_ERROR":
@@ -2884,6 +2674,7 @@ function isTransientPaymasterError(code) {
2884
2674
  return false;
2885
2675
  }
2886
2676
  }
2677
+ __name(isTransientPaymasterError, "isTransientPaymasterError");
2887
2678
  function defaultFunctionForScenario(scenario) {
2888
2679
  switch (scenario) {
2889
2680
  case "mint":
@@ -2898,6 +2689,7 @@ function defaultFunctionForScenario(scenario) {
2898
2689
  return scenario;
2899
2690
  }
2900
2691
  }
2692
+ __name(defaultFunctionForScenario, "defaultFunctionForScenario");
2901
2693
  async function relayUserOp(params) {
2902
2694
  if (!params.client) {
2903
2695
  throw new BundlerNotConfiguredError();
@@ -2908,36 +2700,43 @@ async function relayUserOp(params) {
2908
2700
  entryPoint: params.entryPoint,
2909
2701
  eip7702Auth: params.eip7702Auth
2910
2702
  });
2911
- return { userOpHash: result.userOpHash };
2703
+ return {
2704
+ userOpHash: result.userOpHash
2705
+ };
2912
2706
  } catch (err) {
2913
2707
  const msg = err instanceof Error ? err.message : String(err);
2914
2708
  throw new BundlerRejectedError(msg, err);
2915
2709
  }
2916
2710
  }
2711
+ __name(relayUserOp, "relayUserOp");
2917
2712
 
2918
2713
  // src/api/mobileHandlers.ts
2919
2714
  var PendingUserOpNotFoundError = class extends PafiSdkError {
2715
+ static {
2716
+ __name(this, "PendingUserOpNotFoundError");
2717
+ }
2920
2718
  code = "PENDING_USEROP_NOT_FOUND";
2921
2719
  httpStatus = "not_found";
2922
2720
  constructor(lockId) {
2923
- super(
2924
- `No pending UserOp found for lockId ${lockId} \u2014 it may have expired or already been submitted.`
2925
- );
2721
+ super(`No pending UserOp found for lockId ${lockId} \u2014 it may have expired or already been submitted.`);
2926
2722
  }
2927
2723
  };
2928
2724
  var PendingUserOpForbiddenError = class extends PafiSdkError {
2725
+ static {
2726
+ __name(this, "PendingUserOpForbiddenError");
2727
+ }
2929
2728
  code = "PENDING_USEROP_FORBIDDEN";
2930
2729
  httpStatus = "forbidden";
2931
2730
  constructor(lockId) {
2932
- super(
2933
- `Pending UserOp ${lockId} does not belong to the authenticated user.`
2934
- );
2731
+ super(`Pending UserOp ${lockId} does not belong to the authenticated user.`);
2935
2732
  }
2936
2733
  };
2937
2734
  async function handleMobilePrepare(params) {
2938
2735
  const [fees, userCode] = await Promise.all([
2939
2736
  params.provider.estimateFeesPerGas(),
2940
- params.provider.getCode({ address: params.userAddress })
2737
+ params.provider.getCode({
2738
+ address: params.userAddress
2739
+ })
2941
2740
  ]);
2942
2741
  const needsDelegation = !params.eip7702Auth && parseEip7702DelegatedAddress(userCode) === null;
2943
2742
  const sponsoredOp = {
@@ -2971,6 +2770,7 @@ async function handleMobilePrepare(params) {
2971
2770
  needsDelegation
2972
2771
  };
2973
2772
  }
2773
+ __name(handleMobilePrepare, "handleMobilePrepare");
2974
2774
  async function handleMobileSubmit(params) {
2975
2775
  const entry = await params.store.get(params.lockId);
2976
2776
  if (!entry) {
@@ -2990,19 +2790,21 @@ async function handleMobileSubmit(params) {
2990
2790
  const targetLockId = variant === "fallback" && entry.fallback?.lockId ? entry.fallback.lockId : params.lockId;
2991
2791
  await params.bindUserOpHash(targetLockId, result.userOpHash);
2992
2792
  await params.store.delete(params.lockId);
2993
- return { userOpHash: result.userOpHash };
2793
+ return {
2794
+ userOpHash: result.userOpHash
2795
+ };
2994
2796
  }
2797
+ __name(handleMobileSubmit, "handleMobileSubmit");
2995
2798
 
2996
2799
  // src/api/handlers/ptClaimHandler.ts
2997
2800
  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";
2801
+ import { POINT_TOKEN_ABI as POINT_TOKEN_ABI2, decodeKernelExecuteCalls, getContractAddresses as getContractAddresses3 } from "@pafi-dev/core";
3003
2802
 
3004
2803
  // src/issuer-state/types.ts
3005
2804
  var IssuerStateError = class extends PafiSdkError {
2805
+ static {
2806
+ __name(this, "IssuerStateError");
2807
+ }
3006
2808
  httpStatus = "unprocessable";
3007
2809
  code;
3008
2810
  details;
@@ -3017,6 +2819,9 @@ var IssuerStateError = class extends PafiSdkError {
3017
2819
 
3018
2820
  // src/api/handlers/ptClaimHandler.ts
3019
2821
  var PTClaimError = class extends PafiSdkError {
2822
+ static {
2823
+ __name(this, "PTClaimError");
2824
+ }
3020
2825
  httpStatus = "unprocessable";
3021
2826
  code;
3022
2827
  details;
@@ -3031,32 +2836,29 @@ function isNoWrapper2(address) {
3031
2836
  const lower = address.toLowerCase();
3032
2837
  return lower === "0x0000000000000000000000000000000000000000" || lower === "0x000000000000000000000000000000000000dead";
3033
2838
  }
2839
+ __name(isNoWrapper2, "isNoWrapper");
3034
2840
  var DEFAULT_LOCK_MS = 15 * 60 * 1e3;
3035
2841
  var M11_SAFETY_MARGIN_MS2 = 30 * 1e3;
3036
2842
  var DEFAULT_SIG_DEADLINE_SEC2 = (DEFAULT_LOCK_MS - M11_SAFETY_MARGIN_MS2) / 1e3;
3037
2843
  var PTClaimHandler = class {
2844
+ static {
2845
+ __name(this, "PTClaimHandler");
2846
+ }
3038
2847
  cfg;
3039
2848
  inFlightNonces = /* @__PURE__ */ new Map();
3040
2849
  constructor(config) {
3041
2850
  if (!config.supportedTokens) {
3042
- throw new PTClaimError(
3043
- "UNSUPPORTED_POINT_TOKEN",
3044
- "PTClaimHandler requires `supportedTokens` (issuer's allow-listed PointToken contracts)."
3045
- );
2851
+ throw new PTClaimError("UNSUPPORTED_POINT_TOKEN", "PTClaimHandler requires `supportedTokens` (issuer's allow-listed PointToken contracts).");
3046
2852
  }
3047
2853
  const lockDurationMs = config.lockDurationMs ?? DEFAULT_LOCK_MS;
3048
2854
  const signatureDeadlineSeconds = config.signatureDeadlineSeconds ?? DEFAULT_SIG_DEADLINE_SEC2;
3049
2855
  const maxAllowedSignatureMs = lockDurationMs - M11_SAFETY_MARGIN_MS2;
3050
2856
  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
- );
2857
+ 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).`, {
2858
+ lockDurationMs,
2859
+ signatureDeadlineSeconds,
2860
+ maxAllowedSignatureSec: maxAllowedSignatureMs / 1e3
2861
+ });
3060
2862
  }
3061
2863
  this.cfg = {
3062
2864
  ...config,
@@ -3067,51 +2869,39 @@ var PTClaimHandler = class {
3067
2869
  }
3068
2870
  async handle(request) {
3069
2871
  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
- );
2872
+ throw new PTClaimError("VALIDATION_FAILED", `userAddress (${request.userAddress}) does not match authenticated session (${request.authenticatedAddress})`);
3074
2873
  }
3075
2874
  if (request.amount <= 0n) {
3076
2875
  throw new PTClaimError("INVALID_AMOUNT", "claim amount must be positive");
3077
2876
  }
3078
2877
  const pointTokenAddress = getAddress9(request.pointTokenAddress);
3079
2878
  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
- );
2879
+ 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.`, {
2880
+ requested: pointTokenAddress
2881
+ });
3085
2882
  }
3086
2883
  if (this.cfg.issuerStateValidator) {
3087
2884
  try {
3088
- await this.cfg.issuerStateValidator.preValidateMint(
3089
- request.pointTokenAddress,
3090
- request.amount
3091
- );
2885
+ await this.cfg.issuerStateValidator.preValidateMint(request.pointTokenAddress, request.amount);
3092
2886
  } catch (err) {
3093
2887
  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
- );
2888
+ throw new PTClaimError("VALIDATION_FAILED", `issuer-state pre-validate failed: ${err instanceof Error ? err.message : String(err)}`);
3098
2889
  }
3099
2890
  }
3100
2891
  const chainAddresses = getContractAddresses3(request.chainId);
3101
- const { batchExecutor: batchExecutorAddress } = chainAddresses;
2892
+ const { kernel: batchExecutorAddress } = chainAddresses;
3102
2893
  let mintRequestNonce;
3103
2894
  try {
3104
2895
  mintRequestNonce = await this.cfg.provider.readContract({
3105
2896
  address: request.pointTokenAddress,
3106
2897
  abi: POINT_TOKEN_ABI2,
3107
2898
  functionName: "mintRequestNonces",
3108
- args: [request.userAddress]
2899
+ args: [
2900
+ request.userAddress
2901
+ ]
3109
2902
  });
3110
2903
  } 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
- );
2904
+ throw new PTClaimError("NONCE_READ_FAILED", `failed to read mintRequestNonces(${request.userAddress}): ${err instanceof Error ? err.message : String(err)}`);
3115
2905
  }
3116
2906
  const nonceKey = `${getAddress9(request.userAddress).toLowerCase()}:${request.pointTokenAddress.toLowerCase()}`;
3117
2907
  let userNonces = this.inFlightNonces.get(nonceKey);
@@ -3120,11 +2910,11 @@ var PTClaimHandler = class {
3120
2910
  this.inFlightNonces.set(nonceKey, userNonces);
3121
2911
  }
3122
2912
  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
- );
2913
+ throw new PTClaimError("NONCE_IN_FLIGHT", `concurrent claim for nonce ${mintRequestNonce} in progress; retry after the prior request completes`, {
2914
+ userAddress: request.userAddress,
2915
+ pointToken: request.pointTokenAddress,
2916
+ nonce: mintRequestNonce.toString()
2917
+ });
3128
2918
  }
3129
2919
  userNonces.add(mintRequestNonce);
3130
2920
  const wrapperOverride = this.cfg.mintFeeWrapperAddress;
@@ -3133,20 +2923,11 @@ var PTClaimHandler = class {
3133
2923
  try {
3134
2924
  const lockCreatedAtMs = this.cfg.now();
3135
2925
  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
- );
2926
+ const lockId = await this.cfg.ledger.lockForMinting(request.userAddress, request.amount, this.cfg.lockDurationMs, request.pointTokenAddress);
3142
2927
  try {
3143
2928
  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
- );
2929
+ const lockBoundedDeadlineSec = Math.floor((lockExpiresAtMs - M11_SAFETY_MARGIN_MS2) / 1e3);
2930
+ const signatureDeadline = BigInt(Math.min(requestedDeadlineSec, lockBoundedDeadlineSec));
3150
2931
  const previewUserOp = this.cfg.relayService.previewMintUserOp({
3151
2932
  userAddress: request.userAddress,
3152
2933
  aaNonce: request.aaNonce,
@@ -3165,15 +2946,12 @@ var PTClaimHandler = class {
3165
2946
  }
3166
2947
  }) : 0n;
3167
2948
  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
- );
2949
+ throw new PTClaimError("INVALID_AMOUNT", `fee (${feeAmount}) must be strictly less than claim amount (${request.amount})`, {
2950
+ feeAmount: feeAmount.toString(),
2951
+ amount: request.amount.toString()
2952
+ });
3173
2953
  }
3174
- const domainName = await this.cfg.domainResolver.resolve(
3175
- request.pointTokenAddress
3176
- );
2954
+ const domainName = await this.cfg.domainResolver.resolve(request.pointTokenAddress);
3177
2955
  const domain = {
3178
2956
  name: domainName,
3179
2957
  chainId: request.chainId,
@@ -3203,10 +2981,7 @@ var PTClaimHandler = class {
3203
2981
  feeAmount
3204
2982
  });
3205
2983
  } catch (err) {
3206
- throw new PTClaimError(
3207
- "BUILD_FAILED",
3208
- `prepareMint failed: ${err instanceof Error ? err.message : String(err)}`
3209
- );
2984
+ throw new PTClaimError("BUILD_FAILED", `prepareMint failed: ${err instanceof Error ? err.message : String(err)}`);
3210
2985
  }
3211
2986
  let fallback;
3212
2987
  if (feeAmount > 0n) {
@@ -3225,14 +3000,11 @@ var PTClaimHandler = class {
3225
3000
  mintFeeWrapperAddress: resolvedWrapper
3226
3001
  });
3227
3002
  } catch (err) {
3228
- throw new PTClaimError(
3229
- "BUILD_FAILED",
3230
- `prepareMint (fallback) failed: ${err instanceof Error ? err.message : String(err)}`
3231
- );
3003
+ throw new PTClaimError("BUILD_FAILED", `prepareMint (fallback) failed: ${err instanceof Error ? err.message : String(err)}`);
3232
3004
  }
3233
3005
  }
3234
- const calls = decodeBatchExecuteCalls(userOp.callData);
3235
- const callsFallback = fallback ? decodeBatchExecuteCalls(fallback.callData) : void 0;
3006
+ const calls = decodeKernelExecuteCalls(userOp.callData);
3007
+ const callsFallback = fallback ? decodeKernelExecuteCalls(fallback.callData) : void 0;
3236
3008
  return {
3237
3009
  userOp,
3238
3010
  fallback,
@@ -3256,19 +3028,11 @@ var PTClaimHandler = class {
3256
3028
  };
3257
3029
 
3258
3030
  // 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";
3031
+ import { BROKER_HASHES, ORDERLY_RELAY_ABI, ORDERLY_VAULT_ABI, ORDERLY_VAULT_ADDRESSES, TOKEN_HASHES, buildPerpDepositViaRelay, computeAccountId, decodeKernelExecuteCalls as decodeKernelExecuteCalls2, getContractAddresses as getContractAddresses4, quoteOperatorFeeUsdt } from "@pafi-dev/core";
3271
3032
  var PerpDepositError = class extends PafiSdkError {
3033
+ static {
3034
+ __name(this, "PerpDepositError");
3035
+ }
3272
3036
  httpStatus = "unprocessable";
3273
3037
  code;
3274
3038
  safeToRetry;
@@ -3280,6 +3044,9 @@ var PerpDepositError = class extends PafiSdkError {
3280
3044
  };
3281
3045
  var DEFAULT_MAX_FEE_PREMIUM_BPS = 5e3;
3282
3046
  var PerpDepositHandler = class {
3047
+ static {
3048
+ __name(this, "PerpDepositHandler");
3049
+ }
3283
3050
  cfg;
3284
3051
  constructor(config) {
3285
3052
  this.cfg = {
@@ -3295,10 +3062,7 @@ var PerpDepositHandler = class {
3295
3062
  const tokenHash = TOKEN_HASHES.USDC;
3296
3063
  const vault = ORDERLY_VAULT_ADDRESSES[request.chainId];
3297
3064
  if (!vault) {
3298
- throw new PerpDepositError(
3299
- "PERP_DEPOSIT_UNAVAILABLE",
3300
- `no Orderly Vault for chainId ${request.chainId}`
3301
- );
3065
+ throw new PerpDepositError("PERP_DEPOSIT_UNAVAILABLE", `no Orderly Vault for chainId ${request.chainId}`);
3302
3066
  }
3303
3067
  const { orderlyRelay: relayAddress, pafiFeeRecipient } = getContractAddresses4(request.chainId);
3304
3068
  const [usdcAddress, brokerAllowed] = await Promise.all([
@@ -3306,20 +3070,21 @@ var PerpDepositHandler = class {
3306
3070
  address: vault,
3307
3071
  abi: ORDERLY_VAULT_ABI,
3308
3072
  functionName: "getAllowedToken",
3309
- args: [tokenHash]
3073
+ args: [
3074
+ tokenHash
3075
+ ]
3310
3076
  }),
3311
3077
  this.cfg.provider.readContract({
3312
3078
  address: vault,
3313
3079
  abi: ORDERLY_VAULT_ABI,
3314
3080
  functionName: "getAllowedBroker",
3315
- args: [brokerHash]
3081
+ args: [
3082
+ brokerHash
3083
+ ]
3316
3084
  })
3317
3085
  ]);
3318
3086
  if (!brokerAllowed) {
3319
- throw new PerpDepositError(
3320
- "BROKER_NOT_WHITELISTED",
3321
- `broker "${request.brokerId}" is not whitelisted on Orderly Vault`
3322
- );
3087
+ throw new PerpDepositError("BROKER_NOT_WHITELISTED", `broker "${request.brokerId}" is not whitelisted on Orderly Vault`);
3323
3088
  }
3324
3089
  const accountId = computeAccountId(request.userAddress, brokerHash);
3325
3090
  const requestForQuote = {
@@ -3334,7 +3099,9 @@ var PerpDepositHandler = class {
3334
3099
  address: relayAddress,
3335
3100
  abi: ORDERLY_RELAY_ABI,
3336
3101
  functionName: "quoteTokenFee",
3337
- args: [requestForQuote]
3102
+ args: [
3103
+ requestForQuote
3104
+ ]
3338
3105
  }),
3339
3106
  quoteOperatorFeeUsdt({
3340
3107
  provider: this.cfg.provider,
@@ -3344,16 +3111,10 @@ var PerpDepositHandler = class {
3344
3111
  })
3345
3112
  ]);
3346
3113
  if (relayTokenFee >= request.amount) {
3347
- throw new PerpDepositError(
3348
- "RELAY_FEE_EXCEEDS_AMOUNT",
3349
- `Relay quoted fee ${relayTokenFee} >= deposit amount ${request.amount}`
3350
- );
3114
+ throw new PerpDepositError("RELAY_FEE_EXCEEDS_AMOUNT", `Relay quoted fee ${relayTokenFee} >= deposit amount ${request.amount}`);
3351
3115
  }
3352
3116
  if (usdcGasFee > 0n && usdcGasFee >= request.amount) {
3353
- throw new PerpDepositError(
3354
- "FEE_EXCEEDS_AMOUNT",
3355
- `USDC gas fee ${usdcGasFee} >= deposit amount ${request.amount}`
3356
- );
3117
+ throw new PerpDepositError("FEE_EXCEEDS_AMOUNT", `USDC gas fee ${usdcGasFee} >= deposit amount ${request.amount}`);
3357
3118
  }
3358
3119
  const maxFee = relayTokenFee * BigInt(1e4 + this.cfg.maxFeePremiumBps) / 10000n;
3359
3120
  const depositReq = {
@@ -3388,138 +3149,19 @@ var PerpDepositHandler = class {
3388
3149
  brokerHash,
3389
3150
  usdcAddress,
3390
3151
  relayAddress,
3391
- calls: decodeBatchExecuteCalls2(sponsoredOp.callData),
3392
- callsFallback: fallbackOp ? decodeBatchExecuteCalls2(fallbackOp.callData) : void 0
3152
+ calls: decodeKernelExecuteCalls2(sponsoredOp.callData),
3153
+ callsFallback: fallbackOp ? decodeKernelExecuteCalls2(fallbackOp.callData) : void 0
3393
3154
  };
3394
3155
  }
3395
3156
  };
3396
3157
 
3397
- // 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";
3405
- import { getAddress as getAddress10 } from "viem";
3406
- var DEFAULT_DELEGATE_GAS = {
3407
- callGasLimit: 100000n,
3408
- verificationGasLimit: 150000n,
3409
- preVerificationGas: 50000n
3410
- };
3411
- async function handleDelegatePrepare(params) {
3412
- const { batchExecutor } = getContractAddresses5(params.chainId);
3413
- const partial = buildDelegationUserOp({
3414
- userAddress: params.userAddress,
3415
- aaNonce: params.aaNonce,
3416
- gasLimits: {
3417
- callGasLimit: params.gasLimits?.callGasLimit ?? DEFAULT_DELEGATE_GAS.callGasLimit,
3418
- verificationGasLimit: params.gasLimits?.verificationGasLimit ?? DEFAULT_DELEGATE_GAS.verificationGasLimit,
3419
- preVerificationGas: params.gasLimits?.preVerificationGas ?? DEFAULT_DELEGATE_GAS.preVerificationGas
3420
- }
3421
- });
3422
- const userOp = {
3423
- sender: partial.sender,
3424
- nonce: partial.nonce,
3425
- callData: partial.callData,
3426
- callGasLimit: partial.callGasLimit,
3427
- verificationGasLimit: partial.verificationGasLimit,
3428
- preVerificationGas: partial.preVerificationGas,
3429
- maxFeePerGas: params.fees.maxFeePerGas ?? 0n,
3430
- maxPriorityFeePerGas: params.fees.maxPriorityFeePerGas ?? 0n
3431
- };
3432
- const authorization = buildEip7702Authorization({
3433
- chainId: params.chainId,
3434
- address: batchExecutor,
3435
- nonce: params.delegationNonce,
3436
- authSig: params.authSig
3437
- });
3438
- const paymasterFields = await requestPaymaster({
3439
- client: params.pafiBackendClient,
3440
- chainId: params.chainId,
3441
- scenario: "delegate",
3442
- userOp,
3443
- pointTokenAddress: batchExecutor,
3444
- eip7702Auth: authorization,
3445
- onWarning: params.onWarning
3446
- });
3447
- const prepared = applyPaymasterGasEstimates(
3448
- userOp,
3449
- paymasterFields,
3450
- params.chainId
3451
- );
3452
- const merged = prepared.userOp;
3453
- 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
- );
3479
- return {
3480
- lockId: params.lockId,
3481
- userOpHash,
3482
- typedData: prepared.typedData,
3483
- expiresInSeconds: params.ttlSeconds,
3484
- isSponsored: !!paymasterFields
3485
- };
3486
- }
3487
- async function handleDelegateSubmit(params) {
3488
- const entry = await params.store.get(params.lockId);
3489
- if (!entry) {
3490
- throw new PendingUserOpNotFoundError(params.lockId);
3491
- }
3492
- if (getAddress10(entry.sender) !== getAddress10(params.authenticatedAddress)) {
3493
- throw new PendingUserOpForbiddenError(params.lockId);
3494
- }
3495
- if (!entry.eip7702Auth) {
3496
- throw new Error(
3497
- `delegate entry ${params.lockId} missing eip7702Auth \u2014 prepare step did not run correctly`
3498
- );
3499
- }
3500
- const userOpJson = serializeEntryToJsonRpc(entry, params.userOpSig, "sponsored");
3501
- const result = await relayUserOp({
3502
- client: params.pafiBackendClient,
3503
- userOp: userOpJson,
3504
- entryPoint: params.entryPoint ?? ENTRY_POINT_V082,
3505
- eip7702Auth: entry.eip7702Auth
3506
- });
3507
- await params.store.delete(params.lockId);
3508
- return { userOpHash: result.userOpHash };
3509
- }
3510
-
3511
3158
  // src/api/issuerApiAdapter.ts
3512
- import { randomUUID } from "crypto";
3513
- 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";
3159
+ import { getAddress as getAddress10 } from "viem";
3160
+ import { buildAndSignSponsorAuth, decodeKernelExecuteCalls as decodeKernelExecuteCalls3 } from "@pafi-dev/core";
3522
3161
  var AdapterMisconfiguredError = class extends Error {
3162
+ static {
3163
+ __name(this, "AdapterMisconfiguredError");
3164
+ }
3523
3165
  code = "ADAPTER_MISCONFIGURED";
3524
3166
  constructor(message) {
3525
3167
  super(message);
@@ -3527,35 +3169,28 @@ var AdapterMisconfiguredError = class extends Error {
3527
3169
  }
3528
3170
  };
3529
3171
  var IssuerApiAdapter = class {
3172
+ static {
3173
+ __name(this, "IssuerApiAdapter");
3174
+ }
3530
3175
  cfg;
3531
3176
  constructor(config) {
3532
3177
  if (config.ptClaimHandler) {
3533
3178
  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
- );
3179
+ 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
3180
  }
3538
3181
  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
- );
3182
+ throw new AdapterMisconfiguredError("ledger.getMintLock is required when ptClaimHandler is wired \u2014 claimStatus uses it to look up the lock.");
3542
3183
  }
3543
3184
  }
3544
3185
  if (config.ptRedeemHandler) {
3545
3186
  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
- );
3187
+ 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
3188
  }
3550
3189
  if (typeof config.ledger.bindCreditUserOpHash !== "function") {
3551
- throw new AdapterMisconfiguredError(
3552
- "ledger.bindCreditUserOpHash is required when ptRedeemHandler is wired (mobile redeem flow)."
3553
- );
3190
+ throw new AdapterMisconfiguredError("ledger.bindCreditUserOpHash is required when ptRedeemHandler is wired (mobile redeem flow).");
3554
3191
  }
3555
3192
  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
- );
3193
+ throw new AdapterMisconfiguredError("ledger.getPendingCredit is required when ptRedeemHandler is wired \u2014 redeemStatus uses it to look up the credit.");
3559
3194
  }
3560
3195
  }
3561
3196
  this.cfg = config;
@@ -3570,24 +3205,25 @@ var IssuerApiAdapter = class {
3570
3205
  }
3571
3206
  async gasFee() {
3572
3207
  const result = await this.cfg.issuerService.api.handleGasFee();
3573
- return { gasFeeUsdt: result.gasFeeUsdt.toString() };
3208
+ return {
3209
+ gasFeeUsdt: result.gasFeeUsdt.toString()
3210
+ };
3574
3211
  }
3575
3212
  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 };
3213
+ const result = await this.cfg.issuerService.api.handlePools(authenticatedAddress, {
3214
+ chainId,
3215
+ pointTokenAddress: getAddress10(pointTokenAddress)
3216
+ });
3217
+ return {
3218
+ pools: result.pools
3219
+ };
3581
3220
  }
3582
3221
  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
- );
3222
+ const result = await this.cfg.issuerService.api.handleUser(authenticatedAddress, {
3223
+ chainId,
3224
+ userAddress: getAddress10(userAddress),
3225
+ pointTokenAddress: getAddress10(pointTokenAddress)
3226
+ });
3591
3227
  return {
3592
3228
  offChainBalance: result.offChainBalance.toString(),
3593
3229
  onChainBalance: result.onChainBalance.toString(),
@@ -3600,12 +3236,8 @@ var IssuerApiAdapter = class {
3600
3236
  // directly. Issuer SDK doesn't ship swap/quote anymore.
3601
3237
  // ------------------------------ Action endpoints -------------------------
3602
3238
  async claim(input) {
3603
- const ptClaimHandler = this.assertHandler(
3604
- this.cfg.ptClaimHandler,
3605
- "ptClaimHandler",
3606
- "claim"
3607
- );
3608
- const pointTokenAddress = getAddress11(input.pointTokenAddress);
3239
+ const ptClaimHandler = this.assertHandler(this.cfg.ptClaimHandler, "ptClaimHandler", "claim");
3240
+ const pointTokenAddress = getAddress10(input.pointTokenAddress);
3609
3241
  const result = await ptClaimHandler.handle({
3610
3242
  authenticatedAddress: input.authenticatedAddress,
3611
3243
  userAddress: input.authenticatedAddress,
@@ -3614,12 +3246,7 @@ var IssuerApiAdapter = class {
3614
3246
  chainId: input.chainId,
3615
3247
  aaNonce: input.aaNonce
3616
3248
  });
3617
- const sponsorAuth = await this.buildSponsorAuth(
3618
- input.authenticatedAddress,
3619
- result.userOp.callData,
3620
- input.chainId,
3621
- "mint"
3622
- );
3249
+ const sponsorAuth = await this.buildSponsorAuth(input.authenticatedAddress, result.userOp.callData, input.chainId, "mint");
3623
3250
  return {
3624
3251
  calls: result.calls,
3625
3252
  callsFallback: result.callsFallback,
@@ -3631,7 +3258,7 @@ var IssuerApiAdapter = class {
3631
3258
  }
3632
3259
  async redeem(input) {
3633
3260
  this.assertRedeemHandler();
3634
- const pointTokenAddress = getAddress11(input.pointTokenAddress);
3261
+ const pointTokenAddress = getAddress10(input.pointTokenAddress);
3635
3262
  const response = await this.cfg.ptRedeemHandler.handle({
3636
3263
  userAddress: input.authenticatedAddress,
3637
3264
  authenticatedAddress: input.authenticatedAddress,
@@ -3640,15 +3267,10 @@ var IssuerApiAdapter = class {
3640
3267
  aaNonce: input.aaNonce,
3641
3268
  chainId: input.chainId
3642
3269
  });
3643
- const sponsorAuth = await this.buildSponsorAuth(
3644
- input.authenticatedAddress,
3645
- response.userOp.callData,
3646
- input.chainId,
3647
- "burn"
3648
- );
3270
+ const sponsorAuth = await this.buildSponsorAuth(input.authenticatedAddress, response.userOp.callData, input.chainId, "burn");
3649
3271
  return {
3650
- calls: decodeBatchExecuteCalls3(response.userOp.callData),
3651
- callsFallback: response.fallback ? decodeBatchExecuteCalls3(response.fallback.userOp.callData) : void 0,
3272
+ calls: decodeKernelExecuteCalls3(response.userOp.callData),
3273
+ callsFallback: response.fallback ? decodeKernelExecuteCalls3(response.fallback.userOp.callData) : void 0,
3652
3274
  feeAmount: response.feeAmount.toString(),
3653
3275
  lockId: response.lockId,
3654
3276
  lockIdFallback: response.fallback?.lockId,
@@ -3662,11 +3284,7 @@ var IssuerApiAdapter = class {
3662
3284
  // swap() removed (2026-04-27) — moved to @pafi-dev/trading.
3663
3285
  // PAFI's web FE calls TradingHandlers.handleSwap directly.
3664
3286
  async perpDeposit(input) {
3665
- const perpHandler = this.assertHandler(
3666
- this.cfg.perpHandler,
3667
- "perpHandler",
3668
- "perpDeposit"
3669
- );
3287
+ const perpHandler = this.assertHandler(this.cfg.perpHandler, "perpHandler", "perpDeposit");
3670
3288
  const result = await perpHandler.handle({
3671
3289
  userAddress: input.authenticatedAddress,
3672
3290
  chainId: input.chainId,
@@ -3674,12 +3292,7 @@ var IssuerApiAdapter = class {
3674
3292
  brokerId: input.brokerId,
3675
3293
  aaNonce: input.aaNonce
3676
3294
  });
3677
- const sponsorAuth = await this.buildSponsorAuth(
3678
- input.authenticatedAddress,
3679
- result.userOp.callData,
3680
- input.chainId,
3681
- "perp-deposit"
3682
- );
3295
+ const sponsorAuth = await this.buildSponsorAuth(input.authenticatedAddress, result.userOp.callData, input.chainId, "perp-deposit");
3683
3296
  return {
3684
3297
  calls: result.calls,
3685
3298
  callsFallback: result.callsFallback,
@@ -3696,12 +3309,8 @@ var IssuerApiAdapter = class {
3696
3309
  }
3697
3310
  // ------------------------------ Mobile endpoints -------------------------
3698
3311
  async claimPrepare(input) {
3699
- const ptClaimHandler = this.assertHandler(
3700
- this.cfg.ptClaimHandler,
3701
- "ptClaimHandler",
3702
- "claimPrepare"
3703
- );
3704
- const pointTokenAddress = getAddress11(input.pointTokenAddress);
3312
+ const ptClaimHandler = this.assertHandler(this.cfg.ptClaimHandler, "ptClaimHandler", "claimPrepare");
3313
+ const pointTokenAddress = getAddress10(input.pointTokenAddress);
3705
3314
  const claimResult = await ptClaimHandler.handle({
3706
3315
  authenticatedAddress: input.authenticatedAddress,
3707
3316
  userAddress: input.authenticatedAddress,
@@ -3710,23 +3319,11 @@ var IssuerApiAdapter = class {
3710
3319
  chainId: input.chainId,
3711
3320
  aaNonce: input.aaNonce
3712
3321
  });
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
- );
3322
+ const prepared = await this.runMobilePrepare(input.authenticatedAddress, input.chainId, claimResult.lockId, claimResult.userOp, claimResult.fallback, "mint", pointTokenAddress, claimResult.expiresInSeconds, input.eip7702Auth);
3724
3323
  return {
3725
3324
  lockId: claimResult.lockId,
3726
3325
  userOpHash: prepared.sponsored.userOpHash,
3727
- typedData: prepared.sponsored.typedData,
3728
3326
  userOpHashFallback: prepared.fallback?.userOpHash,
3729
- typedDataFallback: prepared.fallback?.typedData,
3730
3327
  feeAmount: claimResult.feeAmount.toString(),
3731
3328
  signatureDeadline: claimResult.signatureDeadline.toString(),
3732
3329
  expiresInSeconds: claimResult.expiresInSeconds,
@@ -3741,13 +3338,13 @@ var IssuerApiAdapter = class {
3741
3338
  signature: input.signature,
3742
3339
  variant: input.variant,
3743
3340
  store: this.cfg.pendingUserOpStore,
3744
- bindUserOpHash: (lockId, hash) => this.cfg.ledger.bindMintUserOpHash(lockId, hash),
3341
+ bindUserOpHash: /* @__PURE__ */ __name((lockId, hash) => this.cfg.ledger.bindMintUserOpHash(lockId, hash), "bindUserOpHash"),
3745
3342
  pafiBackendClient: this.cfg.pafiBackendClient
3746
3343
  });
3747
3344
  }
3748
3345
  async redeemPrepare(input) {
3749
3346
  this.assertRedeemHandler();
3750
- const pointTokenAddress = getAddress11(input.pointTokenAddress);
3347
+ const pointTokenAddress = getAddress10(input.pointTokenAddress);
3751
3348
  const redeemResponse = await this.cfg.ptRedeemHandler.handle({
3752
3349
  userAddress: input.authenticatedAddress,
3753
3350
  authenticatedAddress: input.authenticatedAddress,
@@ -3756,25 +3353,12 @@ var IssuerApiAdapter = class {
3756
3353
  aaNonce: input.aaNonce,
3757
3354
  chainId: input.chainId
3758
3355
  });
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
- );
3356
+ 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
3357
  return {
3772
3358
  lockId: redeemResponse.lockId,
3773
3359
  lockIdFallback: redeemResponse.fallback?.lockId,
3774
3360
  userOpHash: prepared.sponsored.userOpHash,
3775
- typedData: prepared.sponsored.typedData,
3776
3361
  userOpHashFallback: prepared.fallback?.userOpHash,
3777
- typedDataFallback: prepared.fallback?.typedData,
3778
3362
  netCreditAmount: redeemResponse.netCreditAmount.toString(),
3779
3363
  netCreditAmountFallback: redeemResponse.fallback?.netCreditAmount.toString(),
3780
3364
  feeAmount: redeemResponse.feeAmount.toString(),
@@ -3791,7 +3375,7 @@ var IssuerApiAdapter = class {
3791
3375
  signature: input.signature,
3792
3376
  variant: input.variant,
3793
3377
  store: this.cfg.pendingUserOpStore,
3794
- bindUserOpHash: (lockId, hash) => this.cfg.ledger.bindCreditUserOpHash(lockId, hash),
3378
+ bindUserOpHash: /* @__PURE__ */ __name((lockId, hash) => this.cfg.ledger.bindCreditUserOpHash(lockId, hash), "bindUserOpHash"),
3795
3379
  pafiBackendClient: this.cfg.pafiBackendClient
3796
3380
  });
3797
3381
  }
@@ -3815,83 +3399,15 @@ var IssuerApiAdapter = class {
3815
3399
  onWarning: this.cfg.onWarning
3816
3400
  });
3817
3401
  }
3818
- // ------------------------------ Delegate endpoints -----------------------
3819
- async delegateStatus(authenticatedAddress, chainId) {
3820
- const { batchExecutor } = getContractAddresses6(chainId);
3821
- const [code, nonce] = await Promise.all([
3822
- this.cfg.provider.getCode({ address: authenticatedAddress }),
3823
- this.cfg.provider.getTransactionCount({
3824
- address: authenticatedAddress,
3825
- blockTag: "pending"
3826
- })
3827
- ]);
3828
- return {
3829
- isDelegated: parseEip7702DelegatedAddress2(code) !== null,
3830
- batchExecutorAddress: batchExecutor,
3831
- delegationNonce: nonce.toString(),
3832
- chainId
3833
- };
3834
- }
3835
- /**
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
- */
3851
- async delegatePrepare(authenticatedAddress, input) {
3852
- const { batchExecutor } = getContractAddresses6(input.chainId);
3853
- const fees = await this.cfg.provider.estimateFeesPerGas();
3854
- const lockId = randomUUID();
3855
- const result = await handleDelegatePrepare({
3856
- userAddress: authenticatedAddress,
3857
- chainId: input.chainId,
3858
- delegationNonce: input.delegationNonce,
3859
- aaNonce: input.aaNonce,
3860
- authSig: input.authSig,
3861
- fees,
3862
- lockId,
3863
- store: this.cfg.pendingUserOpStore,
3864
- ttlSeconds: 15 * 60,
3865
- // 15min — match claim/redeem mobile lock duration
3866
- pafiBackendClient: this.cfg.pafiBackendClient,
3867
- onWarning: this.cfg.onWarning
3868
- });
3869
- return {
3870
- lockId: result.lockId,
3871
- userOpHash: result.userOpHash,
3872
- typedData: result.typedData,
3873
- expiresInSeconds: result.expiresInSeconds,
3874
- isSponsored: result.isSponsored,
3875
- delegationNonce: input.delegationNonce.toString(),
3876
- batchExecutorAddress: batchExecutor,
3877
- chainId: input.chainId
3878
- };
3879
- }
3880
- async delegateSubmit(input) {
3881
- const result = await handleDelegateSubmit({
3882
- lockId: input.lockId,
3883
- authenticatedAddress: input.authenticatedAddress,
3884
- userOpSig: input.userOpSig,
3885
- store: this.cfg.pendingUserOpStore,
3886
- pafiBackendClient: this.cfg.pafiBackendClient
3887
- });
3888
- return { userOpHash: result.userOpHash };
3889
- }
3402
+ // Delegate endpoints removed — folded-in delegation (via
3403
+ // `eip7702Auth` on claim/redeem prepare) is now the only path. The
3404
+ // bundler applies SetCode + handleOps in one tx, so there is no
3405
+ // separate `/delegate/*` flow. See `handleMobilePrepare`.
3890
3406
  // ------------------------------ Internal helpers -------------------------
3891
3407
  /**
3892
- * Build + sign a SponsorAuth payload. Returns `undefined` when no
3893
- * issuer id is configured, so the controller can skip the field.
3894
- */
3408
+ * Build + sign a SponsorAuth payload. Returns `undefined` when no
3409
+ * issuer id is configured, so the controller can skip the field.
3410
+ */
3895
3411
  async buildSponsorAuth(authenticatedAddress, callData, chainId, scenario) {
3896
3412
  if (!this.cfg.pafiIssuerId) return void 0;
3897
3413
  return buildAndSignSponsorAuth({
@@ -3923,22 +3439,18 @@ var IssuerApiAdapter = class {
3923
3439
  }
3924
3440
  assertRedeemHandler() {
3925
3441
  if (!this.cfg.ptRedeemHandler) {
3926
- throw new Error(
3927
- "PTRedeemHandler not wired \u2014 IssuerApiAdapter.redeem* require a configured ptRedeemHandler."
3928
- );
3442
+ throw new Error("PTRedeemHandler not wired \u2014 IssuerApiAdapter.redeem* require a configured ptRedeemHandler.");
3929
3443
  }
3930
3444
  }
3931
3445
  /**
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
- */
3446
+ * Narrow an optional handler to non-null and throw a clear error when
3447
+ * the issuer wired the adapter without it. Lets issuers opt out of
3448
+ * flows they don't expose (gg56 ships only mobile claim/redeem, so
3449
+ * `swapHandler` + `perpHandler` aren't constructed).
3450
+ */
3937
3451
  assertHandler(handler, fieldName, methodName) {
3938
3452
  if (handler === null || handler === void 0) {
3939
- throw new Error(
3940
- `${fieldName} not wired \u2014 IssuerApiAdapter.${methodName}() requires a configured ${fieldName}.`
3941
- );
3453
+ throw new Error(`${fieldName} not wired \u2014 IssuerApiAdapter.${methodName}() requires a configured ${fieldName}.`);
3942
3454
  }
3943
3455
  return handler;
3944
3456
  }
@@ -3971,9 +3483,7 @@ function createSubgraphPoolsProvider(config = {}) {
3971
3483
  }
3972
3484
  } catch (err) {
3973
3485
  if (err instanceof TypeError) {
3974
- throw new Error(
3975
- `subgraphPoolsProvider: invalid subgraphUrl: ${subgraphUrl}`
3976
- );
3486
+ throw new Error(`subgraphPoolsProvider: invalid subgraphUrl: ${subgraphUrl}`);
3977
3487
  }
3978
3488
  throw err;
3979
3489
  }
@@ -3983,64 +3493,61 @@ function createSubgraphPoolsProvider(config = {}) {
3983
3493
  const onError = config.onError;
3984
3494
  const cache = /* @__PURE__ */ new Map();
3985
3495
  if (!fetchImpl) {
3986
- throw new Error(
3987
- "createSubgraphPoolsProvider: no fetch implementation available \u2014 pass `fetchImpl` or run on Node 18+"
3988
- );
3496
+ throw new Error("createSubgraphPoolsProvider: no fetch implementation available \u2014 pass `fetchImpl` or run on Node 18+");
3989
3497
  }
3990
- const reportError = (err) => {
3498
+ const reportError = /* @__PURE__ */ __name((err) => {
3991
3499
  if (!onError) return;
3992
3500
  try {
3993
3501
  onError(err);
3994
3502
  } catch {
3995
3503
  }
3996
- };
3504
+ }, "reportError");
3997
3505
  return async (request) => {
3998
3506
  const cacheKey = `${request.chainId}:${request.pointTokenAddress.toLowerCase()}`;
3999
3507
  if (cacheTtl > 0) {
4000
3508
  const cached = cache.get(cacheKey);
4001
3509
  if (cached && cached.expiresAt > now()) {
4002
- return { pools: cached.pools };
3510
+ return {
3511
+ pools: cached.pools
3512
+ };
4003
3513
  }
4004
3514
  }
4005
- const pools = await fetchPoolsFromSubgraph(
4006
- fetchImpl,
4007
- subgraphUrl,
4008
- request.pointTokenAddress,
4009
- reportError
4010
- );
3515
+ const pools = await fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, request.pointTokenAddress, reportError);
4011
3516
  if (cacheTtl > 0) {
4012
3517
  cache.set(cacheKey, {
4013
3518
  expiresAt: now() + cacheTtl,
4014
3519
  pools
4015
3520
  });
4016
3521
  }
4017
- return { pools };
3522
+ return {
3523
+ pools
3524
+ };
4018
3525
  };
4019
3526
  }
3527
+ __name(createSubgraphPoolsProvider, "createSubgraphPoolsProvider");
4020
3528
  async function fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, pointTokenAddress, reportError) {
4021
3529
  let response;
4022
3530
  try {
4023
3531
  response = await fetchImpl(subgraphUrl, {
4024
3532
  method: "POST",
4025
- headers: { "Content-Type": "application/json" },
3533
+ headers: {
3534
+ "Content-Type": "application/json"
3535
+ },
4026
3536
  body: JSON.stringify({
4027
3537
  query: POOL_QUERY,
4028
- variables: { id: pointTokenAddress.toLowerCase() }
3538
+ variables: {
3539
+ id: pointTokenAddress.toLowerCase()
3540
+ }
4029
3541
  })
4030
3542
  });
4031
3543
  } catch (err) {
4032
3544
  const error = err instanceof Error ? err : new Error(String(err));
4033
- console.warn(
4034
- "[subgraphPoolsProvider] subgraph unreachable:",
4035
- error.message
4036
- );
3545
+ console.warn("[subgraphPoolsProvider] subgraph unreachable:", error.message);
4037
3546
  reportError(error);
4038
3547
  return [];
4039
3548
  }
4040
3549
  if (!response.ok) {
4041
- const error = new Error(
4042
- `subgraph returned HTTP ${response.status}`
4043
- );
3550
+ const error = new Error(`subgraph returned HTTP ${response.status}`);
4044
3551
  console.warn(`[subgraphPoolsProvider] ${error.message}`);
4045
3552
  reportError(error);
4046
3553
  return [];
@@ -4050,10 +3557,7 @@ async function fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, pointTokenAddress,
4050
3557
  json = await response.json();
4051
3558
  } catch (err) {
4052
3559
  const error = err instanceof Error ? err : new Error(String(err));
4053
- console.warn(
4054
- "[subgraphPoolsProvider] subgraph returned non-JSON:",
4055
- error.message
4056
- );
3560
+ console.warn("[subgraphPoolsProvider] subgraph returned non-JSON:", error.message);
4057
3561
  reportError(error);
4058
3562
  return [];
4059
3563
  }
@@ -4069,36 +3573,39 @@ async function fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, pointTokenAddress,
4069
3573
  }
4070
3574
  const { pool } = token;
4071
3575
  if (!isAddress(pool.token0.id) || !isAddress(pool.token1.id)) {
4072
- const error = new Error(
4073
- "[PAFI] SubgraphPoolsProvider: invalid token address in response"
4074
- );
3576
+ const error = new Error("[PAFI] SubgraphPoolsProvider: invalid token address in response");
4075
3577
  console.error(error.message, "\u2014 skipping pool");
4076
3578
  reportError(error);
4077
3579
  return [];
4078
3580
  }
4079
3581
  const feeNum = Number(pool.feeTier);
4080
3582
  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
- );
3583
+ const error = new Error(`[PAFI] SubgraphPoolsProvider: invalid feeTier value: ${pool.feeTier}`);
4084
3584
  console.error(error.message, "\u2014 skipping pool");
4085
3585
  reportError(error);
4086
3586
  return [];
4087
3587
  }
4088
- const [token0, token1] = sortTokens(
4089
- pool.token0.id,
4090
- pool.token1.id
4091
- );
3588
+ const [token0, token1] = sortTokens(pool.token0.id, pool.token1.id);
4092
3589
  const poolKey = {
4093
3590
  token0,
4094
3591
  token1,
4095
3592
  fee: feeNum
4096
3593
  };
4097
- return [poolKey];
3594
+ return [
3595
+ poolKey
3596
+ ];
4098
3597
  }
3598
+ __name(fetchPoolsFromSubgraph, "fetchPoolsFromSubgraph");
4099
3599
  function sortTokens(a, b) {
4100
- return a.toLowerCase() < b.toLowerCase() ? [a, b] : [b, a];
3600
+ return a.toLowerCase() < b.toLowerCase() ? [
3601
+ a,
3602
+ b
3603
+ ] : [
3604
+ b,
3605
+ a
3606
+ ];
4101
3607
  }
3608
+ __name(sortTokens, "sortTokens");
4102
3609
 
4103
3610
  // src/pools/subgraphNativeUsdtQuoter.ts
4104
3611
  var DEFAULT_CACHE_TTL_MS2 = 3e4;
@@ -4121,9 +3628,7 @@ function createSubgraphNativeUsdtQuoter(config = {}) {
4121
3628
  }
4122
3629
  } catch (err) {
4123
3630
  if (err instanceof TypeError) {
4124
- throw new Error(
4125
- `createSubgraphNativeUsdtQuoter: invalid subgraphUrl: ${subgraphUrl}`
4126
- );
3631
+ throw new Error(`createSubgraphNativeUsdtQuoter: invalid subgraphUrl: ${subgraphUrl}`);
4127
3632
  }
4128
3633
  throw err;
4129
3634
  }
@@ -4134,23 +3639,15 @@ function createSubgraphNativeUsdtQuoter(config = {}) {
4134
3639
  const fetchImpl = config.fetchImpl ?? globalThis.fetch;
4135
3640
  const now = config.now ?? (() => Date.now());
4136
3641
  if (!fetchImpl) {
4137
- throw new Error(
4138
- "createSubgraphNativeUsdtQuoter: no fetch implementation available \u2014 pass `fetchImpl` or run on Node 18+"
4139
- );
3642
+ throw new Error("createSubgraphNativeUsdtQuoter: no fetch implementation available \u2014 pass `fetchImpl` or run on Node 18+");
4140
3643
  }
4141
3644
  let cached;
4142
3645
  async function getUsdtPerNative() {
4143
3646
  if (cacheTtl > 0 && cached && cached.expiresAt > now()) {
4144
3647
  return cached.usdtPerNative;
4145
3648
  }
4146
- const price = await fetchEthPriceFromSubgraph(
4147
- fetchImpl,
4148
- subgraphUrl
4149
- );
4150
- const usdtPerNative = toUsdtPerNative(
4151
- price ?? fallbackPrice,
4152
- usdtDecimals
4153
- );
3649
+ const price = await fetchEthPriceFromSubgraph(fetchImpl, subgraphUrl);
3650
+ const usdtPerNative = toUsdtPerNative(price ?? fallbackPrice, usdtDecimals);
4154
3651
  if (cacheTtl > 0) {
4155
3652
  cached = {
4156
3653
  usdtPerNative,
@@ -4159,66 +3656,62 @@ function createSubgraphNativeUsdtQuoter(config = {}) {
4159
3656
  }
4160
3657
  return usdtPerNative;
4161
3658
  }
3659
+ __name(getUsdtPerNative, "getUsdtPerNative");
4162
3660
  return async (amountNative) => {
4163
3661
  if (amountNative === 0n) return 0n;
4164
3662
  const usdtPerNative = await getUsdtPerNative();
4165
3663
  return amountNative * usdtPerNative / 10n ** BigInt(nativeDecimals);
4166
3664
  };
4167
3665
  }
3666
+ __name(createSubgraphNativeUsdtQuoter, "createSubgraphNativeUsdtQuoter");
4168
3667
  async function fetchEthPriceFromSubgraph(fetchImpl, subgraphUrl) {
4169
3668
  let response;
4170
3669
  try {
4171
3670
  response = await fetchImpl(subgraphUrl, {
4172
3671
  method: "POST",
4173
- headers: { "Content-Type": "application/json" },
4174
- body: JSON.stringify({ query: PRICE_QUERY })
3672
+ headers: {
3673
+ "Content-Type": "application/json"
3674
+ },
3675
+ body: JSON.stringify({
3676
+ query: PRICE_QUERY
3677
+ })
4175
3678
  });
4176
3679
  } catch (err) {
4177
- console.warn(
4178
- "[subgraphNativeUsdtQuoter] subgraph unreachable:",
4179
- err.message
4180
- );
3680
+ console.warn("[subgraphNativeUsdtQuoter] subgraph unreachable:", err.message);
4181
3681
  return null;
4182
3682
  }
4183
3683
  if (!response.ok) {
4184
- console.warn(
4185
- `[subgraphNativeUsdtQuoter] subgraph returned ${response.status}`
4186
- );
3684
+ console.warn(`[subgraphNativeUsdtQuoter] subgraph returned ${response.status}`);
4187
3685
  return null;
4188
3686
  }
4189
3687
  const json = await response.json();
4190
3688
  if (json.errors && json.errors.length > 0) {
4191
- console.warn(
4192
- "[subgraphNativeUsdtQuoter] subgraph errors:",
4193
- json.errors.map((e) => e.message).join("; ")
4194
- );
3689
+ console.warn("[subgraphNativeUsdtQuoter] subgraph errors:", json.errors.map((e) => e.message).join("; "));
4195
3690
  return null;
4196
3691
  }
4197
3692
  const raw = json.data?.bundle?.ethPriceUSD;
4198
3693
  if (!raw) return null;
4199
3694
  const parsed = Number(raw);
4200
3695
  if (!Number.isFinite(parsed) || parsed <= 0) {
4201
- console.warn(
4202
- `[subgraphNativeUsdtQuoter] invalid ethPriceUSD from subgraph: ${raw}`
4203
- );
3696
+ console.warn(`[subgraphNativeUsdtQuoter] invalid ethPriceUSD from subgraph: ${raw}`);
4204
3697
  return null;
4205
3698
  }
4206
3699
  const MIN_REASONABLE_ETH_PRICE = 100;
4207
3700
  const MAX_REASONABLE_ETH_PRICE = 1e5;
4208
3701
  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
- );
3702
+ console.warn(`[PAFI] SubgraphNativeUsdtQuoter: ETH/USD price ${parsed} is outside reasonable range. Using fallback.`);
4212
3703
  return null;
4213
3704
  }
4214
3705
  return parsed;
4215
3706
  }
3707
+ __name(fetchEthPriceFromSubgraph, "fetchEthPriceFromSubgraph");
4216
3708
  function toUsdtPerNative(priceFloat, usdtDecimals) {
4217
3709
  const fixed = priceFloat.toFixed(usdtDecimals);
4218
3710
  const [whole, fraction = ""] = fixed.split(".");
4219
3711
  const padded = (fraction + "0".repeat(usdtDecimals)).slice(0, usdtDecimals);
4220
3712
  return BigInt(whole + padded);
4221
3713
  }
3714
+ __name(toUsdtPerNative, "toUsdtPerNative");
4222
3715
 
4223
3716
  // src/pools/nativePtQuoter.ts
4224
3717
  import { parseAbi } from "viem";
@@ -4239,18 +3732,7 @@ var POOL_PRICE_QUERY = `
4239
3732
  }
4240
3733
  `;
4241
3734
  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;
3735
+ 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
3736
  let ethPriceCache;
4255
3737
  let ptPriceCache;
4256
3738
  async function getEthPrice8dec() {
@@ -4269,28 +3751,34 @@ function createNativePtQuoter(config) {
4269
3751
  if (ageS > CHAINLINK_MAX_AGE_S) {
4270
3752
  throw new Error(`Chainlink: price stale by ${ageS}s`);
4271
3753
  }
4272
- ethPriceCache = { value: answer, expiresAt: ts + cacheTtlMs };
3754
+ ethPriceCache = {
3755
+ value: answer,
3756
+ expiresAt: ts + cacheTtlMs
3757
+ };
4273
3758
  return answer;
4274
3759
  } catch (err) {
4275
3760
  if (failClosed) {
4276
- throw new Error(
4277
- `[nativePtQuoter] Chainlink unavailable in fail-closed mode: ${err.message}`
4278
- );
3761
+ throw new Error(`[nativePtQuoter] Chainlink unavailable in fail-closed mode: ${err.message}`);
4279
3762
  }
4280
3763
  console.warn("[nativePtQuoter] Chainlink unavailable, using fallback:", err.message);
4281
3764
  return BigInt(Math.round(fallbackEthPriceUsd * 1e8));
4282
3765
  }
4283
3766
  }
3767
+ __name(getEthPrice8dec, "getEthPrice8dec");
4284
3768
  async function getPtPerUsdt18dec() {
4285
3769
  const ts = now();
4286
3770
  if (ptPriceCache && ptPriceCache.expiresAt > ts) return ptPriceCache.value;
4287
3771
  try {
4288
3772
  const response = await fetchImpl(subgraphUrl, {
4289
3773
  method: "POST",
4290
- headers: { "Content-Type": "application/json" },
3774
+ headers: {
3775
+ "Content-Type": "application/json"
3776
+ },
4291
3777
  body: JSON.stringify({
4292
3778
  query: POOL_PRICE_QUERY,
4293
- variables: { id: pointTokenAddress.toLowerCase() }
3779
+ variables: {
3780
+ id: pointTokenAddress.toLowerCase()
3781
+ }
4294
3782
  })
4295
3783
  });
4296
3784
  if (!response.ok) throw new Error(`subgraph HTTP ${response.status}`);
@@ -4306,19 +3794,21 @@ function createNativePtQuoter(config) {
4306
3794
  const raw = parseBigDecimalTo18(ptPerUsdtStr);
4307
3795
  if (raw === 0n) throw new Error(`pool price parsed to zero: ${ptPerUsdtStr}`);
4308
3796
  const value = 10n ** 24n / raw;
4309
- ptPriceCache = { value, expiresAt: ts + cacheTtlMs };
3797
+ ptPriceCache = {
3798
+ value,
3799
+ expiresAt: ts + cacheTtlMs
3800
+ };
4310
3801
  return value;
4311
3802
  } catch (err) {
4312
3803
  if (failClosed) {
4313
- throw new Error(
4314
- `[nativePtQuoter] subgraph miss for ${pointTokenAddress} in fail-closed mode: ${err.message}`
4315
- );
3804
+ throw new Error(`[nativePtQuoter] subgraph miss for ${pointTokenAddress} in fail-closed mode: ${err.message}`);
4316
3805
  }
4317
3806
  console.warn("[nativePtQuoter] subgraph unavailable, using fallback:", err.message);
4318
3807
  const ptPerUsdtHuman = 1 / fallbackPtPriceUsdt;
4319
3808
  return parseBigDecimalTo18(ptPerUsdtHuman.toFixed(18));
4320
3809
  }
4321
3810
  }
3811
+ __name(getPtPerUsdt18dec, "getPtPerUsdt18dec");
4322
3812
  return async (amountNative) => {
4323
3813
  if (amountNative === 0n) return 0n;
4324
3814
  const [ethPrice8dec, ptPerUsdt18dec] = await Promise.all([
@@ -4328,12 +3818,14 @@ function createNativePtQuoter(config) {
4328
3818
  return amountNative * ethPrice8dec * ptPerUsdt18dec / 10n ** 26n;
4329
3819
  };
4330
3820
  }
3821
+ __name(createNativePtQuoter, "createNativePtQuoter");
4331
3822
  function parseBigDecimalTo18(s) {
4332
3823
  const SCALE = 18;
4333
3824
  const [whole = "0", frac = ""] = s.split(".");
4334
3825
  const padded = (frac + "0".repeat(SCALE)).slice(0, SCALE);
4335
3826
  return BigInt(whole + padded);
4336
3827
  }
3828
+ __name(parseBigDecimalTo18, "parseBigDecimalTo18");
4337
3829
 
4338
3830
  // src/pafi-backend/client.ts
4339
3831
  import { getPafiServiceUrls } from "@pafi-dev/core";
@@ -4341,15 +3833,24 @@ function extractPafiErrorFields(json, status) {
4341
3833
  const inner = typeof json.error === "object" && json.error !== null ? json.error : null;
4342
3834
  const code = inner?.code ?? json.code ?? "INTERNAL_ERROR";
4343
3835
  const message = inner?.message ?? json.message ?? `HTTP ${status}`;
4344
- return { code, message };
3836
+ return {
3837
+ code,
3838
+ message
3839
+ };
4345
3840
  }
3841
+ __name(extractPafiErrorFields, "extractPafiErrorFields");
4346
3842
  function serializeBigInt(_key, value) {
4347
3843
  return typeof value === "bigint" ? value.toString(10) : value;
4348
3844
  }
3845
+ __name(serializeBigInt, "serializeBigInt");
4349
3846
  function sleep(ms) {
4350
3847
  return new Promise((resolve) => setTimeout(resolve, ms));
4351
3848
  }
3849
+ __name(sleep, "sleep");
4352
3850
  var PafiBackendClient = class {
3851
+ static {
3852
+ __name(this, "PafiBackendClient");
3853
+ }
4353
3854
  config;
4354
3855
  baseUrl;
4355
3856
  constructor(config) {
@@ -4387,11 +3888,11 @@ var PafiBackendClient = class {
4387
3888
  throw lastError;
4388
3889
  }
4389
3890
  /**
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
- */
3891
+ * Fetch ERC-4337 UserOp receipt via PAFI's authenticated bundler proxy.
3892
+ * Returns `null` when the bundler hasn't seen the userOp yet — caller
3893
+ * should keep polling. Used by status endpoints to short-circuit the
3894
+ * on-chain indexer when several PENDING locks share the same amount.
3895
+ */
4395
3896
  async getUserOpReceipt(userOpHash) {
4396
3897
  const fetchFn = this.config.fetchImpl ?? fetch;
4397
3898
  const url = `${this.baseUrl}/bundler/receipt`;
@@ -4404,14 +3905,12 @@ var PafiBackendClient = class {
4404
3905
  Authorization: `Bearer ${this.config.apiKey}`,
4405
3906
  "X-Issuer-Id": this.config.issuerId
4406
3907
  },
4407
- body: JSON.stringify({ userOpHash })
3908
+ body: JSON.stringify({
3909
+ userOpHash
3910
+ })
4408
3911
  });
4409
3912
  } catch (err) {
4410
- throw new PafiBackendError(
4411
- "NETWORK_ERROR",
4412
- `Network error: ${err instanceof Error ? err.message : String(err)}`,
4413
- 0
4414
- );
3913
+ throw new PafiBackendError("NETWORK_ERROR", `Network error: ${err instanceof Error ? err.message : String(err)}`, 0);
4415
3914
  }
4416
3915
  const text = await response.text();
4417
3916
  let json = {};
@@ -4445,11 +3944,7 @@ var PafiBackendClient = class {
4445
3944
  body: JSON.stringify(request)
4446
3945
  });
4447
3946
  } catch (err) {
4448
- throw new PafiBackendError(
4449
- "NETWORK_ERROR",
4450
- `Network error: ${err instanceof Error ? err.message : String(err)}`,
4451
- 0
4452
- );
3947
+ throw new PafiBackendError("NETWORK_ERROR", `Network error: ${err instanceof Error ? err.message : String(err)}`, 0);
4453
3948
  }
4454
3949
  const text = await response.text();
4455
3950
  let json = {};
@@ -4461,7 +3956,9 @@ var PafiBackendClient = class {
4461
3956
  const { code, message } = extractPafiErrorFields(json, response.status);
4462
3957
  throw new PafiBackendError(code, message, response.status, json);
4463
3958
  }
4464
- return { userOpHash: json.userOpHash };
3959
+ return {
3960
+ userOpHash: json.userOpHash
3961
+ };
4465
3962
  }
4466
3963
  async _doRequest(request) {
4467
3964
  const fetchFn = this.config.fetchImpl ?? fetch;
@@ -4479,11 +3976,7 @@ var PafiBackendClient = class {
4479
3976
  body
4480
3977
  });
4481
3978
  } catch (err) {
4482
- throw new PafiBackendError(
4483
- "NETWORK_ERROR",
4484
- `Network error: ${err instanceof Error ? err.message : String(err)}`,
4485
- 0
4486
- );
3979
+ throw new PafiBackendError("NETWORK_ERROR", `Network error: ${err instanceof Error ? err.message : String(err)}`, 0);
4487
3980
  }
4488
3981
  const text = await response.text();
4489
3982
  let json = {};
@@ -4504,9 +3997,7 @@ var PafiBackendClient = class {
4504
3997
  return {
4505
3998
  paymaster: json.paymaster,
4506
3999
  paymasterData: json.paymasterData,
4507
- paymasterVerificationGasLimit: BigInt(
4508
- json.paymasterVerificationGasLimit
4509
- ),
4000
+ paymasterVerificationGasLimit: BigInt(json.paymasterVerificationGasLimit),
4510
4001
  paymasterPostOpGasLimit: BigInt(json.paymasterPostOpGasLimit),
4511
4002
  callGasLimit: json.callGasLimit != null ? BigInt(json.callGasLimit) : void 0,
4512
4003
  verificationGasLimit: json.verificationGasLimit != null ? BigInt(json.verificationGasLimit) : void 0,
@@ -4519,8 +4010,8 @@ var PafiBackendClient = class {
4519
4010
  };
4520
4011
 
4521
4012
  // src/config.ts
4522
- import { getAddress as getAddress12 } from "viem";
4523
- import { getContractAddresses as getContractAddresses7 } from "@pafi-dev/core";
4013
+ import { getAddress as getAddress11 } from "viem";
4014
+ import { getContractAddresses as getContractAddresses5 } from "@pafi-dev/core";
4524
4015
 
4525
4016
  // src/redemption/evaluator.ts
4526
4017
  var SECONDS_PER_DAY = 24 * 60 * 60;
@@ -4530,10 +4021,7 @@ function evaluateRedemption(input) {
4530
4021
  const cooldownUntilUnixSec = history.lastRedeemedAtUnixSec !== null ? history.lastRedeemedAtUnixSec + policy.cooldownSec : null;
4531
4022
  const inCooldown = cooldownUntilUnixSec !== null && cooldownUntilUnixSec > nowUnixSec;
4532
4023
  const activeBlackout = findActiveBlackout(policy.blackoutWindows, nowUnixSec);
4533
- const nextBlackoutEnd = nextBlackoutEndAfter(
4534
- policy.blackoutWindows,
4535
- nowUnixSec
4536
- );
4024
+ const nextBlackoutEnd = nextBlackoutEndAfter(policy.blackoutWindows, nowUnixSec);
4537
4025
  let availableAmountPt = 0n;
4538
4026
  if (!inCooldown && !activeBlackout) {
4539
4027
  const headroom = dailyRemaining < policy.perTxMaxPt ? dailyRemaining : policy.perTxMaxPt;
@@ -4550,7 +4038,11 @@ function evaluateRedemption(input) {
4550
4038
  policySource
4551
4039
  };
4552
4040
  if (amountPt <= 0n) {
4553
- return { allowed: false, preview, denial: rejectAmountBelowMin(policy) };
4041
+ return {
4042
+ allowed: false,
4043
+ preview,
4044
+ denial: rejectAmountBelowMin(policy)
4045
+ };
4554
4046
  }
4555
4047
  const denial = firstDenial({
4556
4048
  amountPt,
@@ -4560,25 +4052,29 @@ function evaluateRedemption(input) {
4560
4052
  cooldownUntilUnixSec,
4561
4053
  activeBlackout
4562
4054
  });
4563
- if (denial) return { allowed: false, denial, preview };
4564
- return { allowed: true, preview };
4055
+ if (denial) return {
4056
+ allowed: false,
4057
+ denial,
4058
+ preview
4059
+ };
4060
+ return {
4061
+ allowed: true,
4062
+ preview
4063
+ };
4565
4064
  }
4065
+ __name(evaluateRedemption, "evaluateRedemption");
4566
4066
  function firstDenial(args) {
4567
4067
  const { amountPt, policy, dailyRemaining, inCooldown, cooldownUntilUnixSec, activeBlackout } = args;
4568
4068
  if (activeBlackout) {
4569
4069
  return {
4570
4070
  code: "BLACKOUT_WINDOW",
4571
- message: `Redemption is blocked until ${new Date(
4572
- activeBlackout.endUnixSec * 1e3
4573
- ).toISOString()}${activeBlackout.reason ? ` (${activeBlackout.reason})` : ""}`
4071
+ message: `Redemption is blocked until ${new Date(activeBlackout.endUnixSec * 1e3).toISOString()}${activeBlackout.reason ? ` (${activeBlackout.reason})` : ""}`
4574
4072
  };
4575
4073
  }
4576
4074
  if (inCooldown && cooldownUntilUnixSec !== null) {
4577
4075
  return {
4578
4076
  code: "COOLDOWN_ACTIVE",
4579
- message: `Cooldown active until ${new Date(
4580
- cooldownUntilUnixSec * 1e3
4581
- ).toISOString()}`
4077
+ message: `Cooldown active until ${new Date(cooldownUntilUnixSec * 1e3).toISOString()}`
4582
4078
  };
4583
4079
  }
4584
4080
  if (amountPt < policy.perTxMinPt) {
@@ -4601,18 +4097,21 @@ function firstDenial(args) {
4601
4097
  }
4602
4098
  return null;
4603
4099
  }
4100
+ __name(firstDenial, "firstDenial");
4604
4101
  function rejectAmountBelowMin(policy) {
4605
4102
  return {
4606
4103
  code: "AMOUNT_BELOW_MIN",
4607
4104
  message: `amount must be >= ${policy.perTxMinPt}`
4608
4105
  };
4609
4106
  }
4107
+ __name(rejectAmountBelowMin, "rejectAmountBelowMin");
4610
4108
  function findActiveBlackout(windows, nowUnixSec) {
4611
4109
  for (const w of windows) {
4612
4110
  if (w.startUnixSec <= nowUnixSec && nowUnixSec < w.endUnixSec) return w;
4613
4111
  }
4614
4112
  return null;
4615
4113
  }
4114
+ __name(findActiveBlackout, "findActiveBlackout");
4616
4115
  function nextBlackoutEndAfter(windows, nowUnixSec) {
4617
4116
  let earliest = null;
4618
4117
  for (const w of windows) {
@@ -4622,17 +4121,19 @@ function nextBlackoutEndAfter(windows, nowUnixSec) {
4622
4121
  }
4623
4122
  return earliest;
4624
4123
  }
4124
+ __name(nextBlackoutEndAfter, "nextBlackoutEndAfter");
4625
4125
  var REDEMPTION_HISTORY_WINDOW_SEC = SECONDS_PER_DAY;
4626
4126
 
4627
4127
  // src/redemption/policyProvider.ts
4628
4128
  import { PafiSdkError as PafiSdkError2 } from "@pafi-dev/core";
4629
4129
 
4630
4130
  // src/redemption/settlementClient.ts
4631
- import {
4632
- getPafiServiceUrls as getPafiServiceUrls2
4633
- } from "@pafi-dev/core";
4131
+ import { getPafiServiceUrls as getPafiServiceUrls2 } from "@pafi-dev/core";
4634
4132
  var DEFAULT_TIMEOUT_MS = 1e3;
4635
4133
  var SettlementClient = class {
4134
+ static {
4135
+ __name(this, "SettlementClient");
4136
+ }
4636
4137
  config;
4637
4138
  constructor(config) {
4638
4139
  if (!config.chainId) throw new Error("SettlementClient: chainId is required");
@@ -4652,10 +4153,7 @@ var SettlementClient = class {
4652
4153
  const fetchFn = this.config.fetchImpl ?? fetch;
4653
4154
  const url = `${this.config.baseUrl}/issuers/${encodeURIComponent(this.config.issuerId)}/redemption-policy`;
4654
4155
  const controller = new AbortController();
4655
- const timer = setTimeout(
4656
- () => controller.abort(),
4657
- this.config.fetchTimeoutMs
4658
- );
4156
+ const timer = setTimeout(() => controller.abort(), this.config.fetchTimeoutMs);
4659
4157
  let response;
4660
4158
  try {
4661
4159
  response = await fetchFn(url, {
@@ -4669,30 +4167,56 @@ var SettlementClient = class {
4669
4167
  });
4670
4168
  } catch (err) {
4671
4169
  const isAbort = err instanceof Error && (err.name === "AbortError" || /aborted|timeout/i.test(err.message ?? ""));
4672
- return { ok: false, reason: isAbort ? "TIMEOUT" : "NETWORK" };
4170
+ return {
4171
+ ok: false,
4172
+ reason: isAbort ? "TIMEOUT" : "NETWORK"
4173
+ };
4673
4174
  } finally {
4674
4175
  clearTimeout(timer);
4675
4176
  }
4676
4177
  if (response.status === 404) {
4677
- return { ok: false, reason: "NOT_FOUND", status: 404 };
4178
+ return {
4179
+ ok: false,
4180
+ reason: "NOT_FOUND",
4181
+ status: 404
4182
+ };
4678
4183
  }
4679
4184
  if (response.status === 401 || response.status === 403) {
4680
- return { ok: false, reason: "UNAUTHORIZED", status: response.status };
4185
+ return {
4186
+ ok: false,
4187
+ reason: "UNAUTHORIZED",
4188
+ status: response.status
4189
+ };
4681
4190
  }
4682
4191
  if (!response.ok) {
4683
- return { ok: false, reason: "SERVER_ERROR", status: response.status };
4192
+ return {
4193
+ ok: false,
4194
+ reason: "SERVER_ERROR",
4195
+ status: response.status
4196
+ };
4684
4197
  }
4685
4198
  let raw;
4686
4199
  try {
4687
4200
  raw = await response.json();
4688
4201
  } catch {
4689
- return { ok: false, reason: "INVALID_RESPONSE", status: response.status };
4202
+ return {
4203
+ ok: false,
4204
+ reason: "INVALID_RESPONSE",
4205
+ status: response.status
4206
+ };
4690
4207
  }
4691
4208
  const parsed = parsePolicyDto(raw);
4692
4209
  if (!parsed) {
4693
- return { ok: false, reason: "INVALID_RESPONSE", status: response.status };
4210
+ return {
4211
+ ok: false,
4212
+ reason: "INVALID_RESPONSE",
4213
+ status: response.status
4214
+ };
4694
4215
  }
4695
- return { ok: true, policy: parsed };
4216
+ return {
4217
+ ok: true,
4218
+ policy: parsed
4219
+ };
4696
4220
  }
4697
4221
  };
4698
4222
  function parsePolicyDto(raw) {
@@ -4715,6 +4239,7 @@ function parsePolicyDto(raw) {
4715
4239
  return null;
4716
4240
  }
4717
4241
  }
4242
+ __name(parsePolicyDto, "parsePolicyDto");
4718
4243
  function normalizeBlackout(raw) {
4719
4244
  if (!raw || typeof raw !== "object") return null;
4720
4245
  const win = raw;
@@ -4727,6 +4252,7 @@ function normalizeBlackout(raw) {
4727
4252
  reason: typeof win.reason === "string" ? win.reason : void 0
4728
4253
  };
4729
4254
  }
4255
+ __name(normalizeBlackout, "normalizeBlackout");
4730
4256
 
4731
4257
  // src/redemption/defaults.ts
4732
4258
  var PT_DECIMALS = 10n ** 18n;
@@ -4740,23 +4266,34 @@ var DEFAULT_REDEMPTION_POLICY = {
4740
4266
  version: "default-v1"
4741
4267
  };
4742
4268
  function defaultPolicyFor(issuerId) {
4743
- return { ...DEFAULT_REDEMPTION_POLICY, issuerId };
4269
+ return {
4270
+ ...DEFAULT_REDEMPTION_POLICY,
4271
+ issuerId
4272
+ };
4744
4273
  }
4274
+ __name(defaultPolicyFor, "defaultPolicyFor");
4745
4275
 
4746
4276
  // src/redemption/policyProvider.ts
4747
4277
  var DEFAULT_CACHE_TTL_MS3 = 5 * 60 * 1e3;
4748
4278
  var PolicyProviderUnavailableError = class extends PafiSdkError2 {
4279
+ static {
4280
+ __name(this, "PolicyProviderUnavailableError");
4281
+ }
4749
4282
  code = "POLICY_PROVIDER_UNAVAILABLE";
4750
4283
  httpStatus = "service_unavailable";
4751
4284
  details;
4752
4285
  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 };
4286
+ 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.`);
4287
+ this.details = {
4288
+ issuerId,
4289
+ reason
4290
+ };
4757
4291
  }
4758
4292
  };
4759
4293
  var PolicyProvider = class {
4294
+ static {
4295
+ __name(this, "PolicyProvider");
4296
+ }
4760
4297
  client;
4761
4298
  issuerId;
4762
4299
  cacheTtlMs;
@@ -4775,7 +4312,10 @@ var PolicyProvider = class {
4775
4312
  }
4776
4313
  async getPolicy() {
4777
4314
  const fresh = this.readCache();
4778
- if (fresh) return { policy: fresh, source: "cache" };
4315
+ if (fresh) return {
4316
+ policy: fresh,
4317
+ source: "cache"
4318
+ };
4779
4319
  if (this.inflight) return this.inflight;
4780
4320
  this.inflight = this.fetchAndStore().finally(() => {
4781
4321
  this.inflight = null;
@@ -4801,19 +4341,22 @@ var PolicyProvider = class {
4801
4341
  policy: result.policy,
4802
4342
  expiresAtMs: this.now() + this.cacheTtlMs
4803
4343
  };
4804
- return { policy: result.policy, source: "settlement" };
4344
+ return {
4345
+ policy: result.policy,
4346
+ source: "settlement"
4347
+ };
4805
4348
  }
4806
4349
  const reason = "reason" in result && typeof result.reason === "string" ? result.reason : "unknown";
4807
4350
  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" };
4351
+ this.onWarning?.("PolicyProvider: settlement-api unreachable, falling back to permissive default. Pre-flight redeem limit is DEGRADED until settlement-api recovers.", {
4352
+ event: "policy_provider_fallback",
4353
+ issuerId: this.issuerId,
4354
+ reason
4355
+ });
4356
+ return {
4357
+ policy: defaultPolicyFor(this.issuerId),
4358
+ source: "default"
4359
+ };
4817
4360
  }
4818
4361
  throw new PolicyProviderUnavailableError(this.issuerId, reason);
4819
4362
  }
@@ -4821,6 +4364,9 @@ var PolicyProvider = class {
4821
4364
 
4822
4365
  // src/redemption/service.ts
4823
4366
  var RedemptionService = class {
4367
+ static {
4368
+ __name(this, "RedemptionService");
4369
+ }
4824
4370
  policyProvider;
4825
4371
  historyStore;
4826
4372
  nowUnixSec;
@@ -4837,17 +4383,16 @@ var RedemptionService = class {
4837
4383
  const { policy, source } = await this.policyProvider.getPolicy();
4838
4384
  const now = this.nowUnixSec();
4839
4385
  const [redeemedLast24hPt, lastRedeemedAtUnixSec] = await Promise.all([
4840
- this.historyStore.sumRedeemedSince(
4841
- user,
4842
- now - REDEMPTION_HISTORY_WINDOW_SEC,
4843
- pointTokenAddress
4844
- ),
4386
+ this.historyStore.sumRedeemedSince(user, now - REDEMPTION_HISTORY_WINDOW_SEC, pointTokenAddress),
4845
4387
  this.historyStore.getLastRedeemedAtUnixSec(user, pointTokenAddress)
4846
4388
  ]);
4847
4389
  return evaluateRedemption({
4848
4390
  policy,
4849
4391
  policySource: source,
4850
- history: { redeemedLast24hPt, lastRedeemedAtUnixSec },
4392
+ history: {
4393
+ redeemedLast24hPt,
4394
+ lastRedeemedAtUnixSec
4395
+ },
4851
4396
  amountPt,
4852
4397
  nowUnixSec: now
4853
4398
  });
@@ -4874,16 +4419,18 @@ async function createIssuerService(config) {
4874
4419
  if (!config.auth?.domain) {
4875
4420
  throw new Error("createIssuerService: auth.domain is required");
4876
4421
  }
4877
- const rawAddresses = config.pointTokenAddresses && config.pointTokenAddresses.length > 0 ? config.pointTokenAddresses : config.pointTokenAddress ? [config.pointTokenAddress] : [];
4422
+ const rawAddresses = config.pointTokenAddresses && config.pointTokenAddresses.length > 0 ? config.pointTokenAddresses : config.pointTokenAddress ? [
4423
+ config.pointTokenAddress
4424
+ ] : [];
4878
4425
  if (rawAddresses.length === 0) {
4879
- throw new Error(
4880
- "createIssuerService: at least one of pointTokenAddress / pointTokenAddresses is required"
4881
- );
4426
+ throw new Error("createIssuerService: at least one of pointTokenAddress / pointTokenAddresses is required");
4882
4427
  }
4883
- const tokenAddresses = rawAddresses.map((a) => getAddress12(a));
4428
+ const tokenAddresses = rawAddresses.map((a) => getAddress11(a));
4884
4429
  const ledger = config.ledger;
4885
4430
  const sessionStore = config.sessionStore ?? new MemorySessionStore();
4886
- const policy = config.policy ?? new DefaultPolicyEngine({ ledger });
4431
+ const policy = config.policy ?? new DefaultPolicyEngine({
4432
+ ledger
4433
+ });
4887
4434
  const authServiceConfig = {
4888
4435
  sessionStore,
4889
4436
  jwtSecret: config.auth.jwtSecret,
@@ -4905,15 +4452,13 @@ async function createIssuerService(config) {
4905
4452
  provider: config.provider
4906
4453
  });
4907
4454
  }
4908
- const sdkWrapperAddress = getContractAddresses7(config.chainId).mintFeeWrapper;
4455
+ const sdkWrapperAddress = getContractAddresses5(config.chainId).mintFeeWrapper;
4909
4456
  const wrapperOverride = config.indexer?.mintFeeWrapperAddress;
4910
4457
  const resolvedWrapperAddress = wrapperOverride !== void 0 ? wrapperOverride : sdkWrapperAddress;
4911
4458
  const baseCursorStore = config.indexer?.cursorStore;
4912
4459
  const sharedCursorWithMultipleTokens = baseCursorStore !== void 0 && typeof baseCursorStore.forKey !== "function" && tokenAddresses.length > 1;
4913
4460
  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
- );
4461
+ 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
4462
  }
4918
4463
  const indexers = /* @__PURE__ */ new Map();
4919
4464
  for (const tokenAddress of tokenAddresses) {
@@ -4929,9 +4474,7 @@ async function createIssuerService(config) {
4929
4474
  indexerConfig.fromBlock = config.indexer.fromBlock;
4930
4475
  }
4931
4476
  if (baseCursorStore) {
4932
- indexerConfig.cursorStore = typeof baseCursorStore.forKey === "function" ? baseCursorStore.forKey(
4933
- `point-indexer:${tokenAddress.toLowerCase()}`
4934
- ) : baseCursorStore;
4477
+ indexerConfig.cursorStore = typeof baseCursorStore.forKey === "function" ? baseCursorStore.forKey(`point-indexer:${tokenAddress.toLowerCase()}`) : baseCursorStore;
4935
4478
  }
4936
4479
  if (config.indexer?.confirmations !== void 0) {
4937
4480
  indexerConfig.confirmations = config.indexer.confirmations;
@@ -4944,9 +4487,9 @@ async function createIssuerService(config) {
4944
4487
  }
4945
4488
  indexers.set(tokenAddress, new PointIndexer(indexerConfig));
4946
4489
  }
4947
- const chainAddresses = getContractAddresses7(config.chainId);
4490
+ const chainAddresses = getContractAddresses5(config.chainId);
4948
4491
  const resolvedContracts = {
4949
- batchExecutor: chainAddresses.batchExecutor,
4492
+ kernel: chainAddresses.kernel,
4950
4493
  usdt: chainAddresses.usdt,
4951
4494
  issuerRegistry: chainAddresses.issuerRegistry,
4952
4495
  mintingOracle: chainAddresses.mintingOracle,
@@ -5002,9 +4545,7 @@ async function createIssuerService(config) {
5002
4545
  if (config.indexer?.autoStart) {
5003
4546
  const lock = config.indexer.singletonLock;
5004
4547
  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
- );
4548
+ 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
4549
  for (const idx of indexers.values()) {
5009
4550
  idx.start();
5010
4551
  }
@@ -5033,42 +4574,42 @@ async function createIssuerService(config) {
5033
4574
  redemption
5034
4575
  };
5035
4576
  }
4577
+ __name(createIssuerService, "createIssuerService");
5036
4578
 
5037
4579
  // src/issuer-state/validator.ts
5038
- 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";
4580
+ import { getAddress as getAddress12 } from "viem";
4581
+ import { POINT_TOKEN_ABI as POINT_TOKEN_ABI3, issuerRegistryAbi, getContractAddresses as getContractAddresses6 } from "@pafi-dev/core";
5044
4582
  var ISSUER_RECORD_TTL_MS = 1e4;
5045
4583
  var IssuerStateValidator = class _IssuerStateValidator {
5046
- constructor(provider, registryAddress) {
5047
- this.provider = provider;
5048
- this.registryAddress = registryAddress;
4584
+ static {
4585
+ __name(this, "IssuerStateValidator");
5049
4586
  }
5050
4587
  provider;
5051
4588
  registryAddress;
5052
4589
  pointTokenIssuerCache = /* @__PURE__ */ new Map();
5053
4590
  stateCache = /* @__PURE__ */ new Map();
5054
4591
  inflight = /* @__PURE__ */ new Map();
4592
+ constructor(provider, registryAddress) {
4593
+ this.provider = provider;
4594
+ this.registryAddress = registryAddress;
4595
+ }
5055
4596
  /**
5056
- * Convenience factory — reads `registryAddress` from the SDK
5057
- * `CONTRACT_ADDRESSES` map for the given chain.
5058
- */
4597
+ * Convenience factory — reads `registryAddress` from the SDK
4598
+ * `CONTRACT_ADDRESSES` map for the given chain.
4599
+ */
5059
4600
  static forChain(provider, chainId) {
5060
- const { issuerRegistry } = getContractAddresses8(chainId);
4601
+ const { issuerRegistry } = getContractAddresses6(chainId);
5061
4602
  return new _IssuerStateValidator(provider, issuerRegistry);
5062
4603
  }
5063
4604
  /**
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
- */
4605
+ * Invalidate cached state for one PointToken, or everything if omitted.
4606
+ * Call after admin txs that change registry or cap settings — closes
4607
+ * the split-brain window described
4608
+ * passive TTL. Idempotent: safe to call when no entry exists.
4609
+ */
5069
4610
  invalidate(pointToken) {
5070
4611
  if (pointToken) {
5071
- const key = getAddress13(pointToken);
4612
+ const key = getAddress12(pointToken);
5072
4613
  this.pointTokenIssuerCache.delete(key);
5073
4614
  this.stateCache.delete(key);
5074
4615
  this.inflight.delete(key);
@@ -5079,11 +4620,11 @@ var IssuerStateValidator = class _IssuerStateValidator {
5079
4620
  }
5080
4621
  }
5081
4622
  /**
5082
- * Resolve `PointToken.issuer()` once per token and memoize.
5083
- * The issuer field is set at `initialize()` and never changes.
5084
- */
4623
+ * Resolve `PointToken.issuer()` once per token and memoize.
4624
+ * The issuer field is set at `initialize()` and never changes.
4625
+ */
5085
4626
  async getIssuerAddressForPointToken(pointToken) {
5086
- const key = getAddress13(pointToken);
4627
+ const key = getAddress12(pointToken);
5087
4628
  const cached = this.pointTokenIssuerCache.get(key);
5088
4629
  if (cached) return cached;
5089
4630
  const issuer = await this.provider.readContract({
@@ -5091,15 +4632,15 @@ var IssuerStateValidator = class _IssuerStateValidator {
5091
4632
  abi: POINT_TOKEN_ABI3,
5092
4633
  functionName: "issuer"
5093
4634
  });
5094
- this.pointTokenIssuerCache.set(key, getAddress13(issuer));
5095
- return getAddress13(issuer);
4635
+ this.pointTokenIssuerCache.set(key, getAddress12(issuer));
4636
+ return getAddress12(issuer);
5096
4637
  }
5097
4638
  /**
5098
- * Read registry record + totalSupply, with 30s cache and in-flight
5099
- * deduplication. Does NOT throw on inactive/missing — returns raw state.
5100
- */
4639
+ * Read registry record + totalSupply, with 30s cache and in-flight
4640
+ * deduplication. Does NOT throw on inactive/missing — returns raw state.
4641
+ */
5101
4642
  async getIssuerState(pointToken) {
5102
- const tokenAddr = getAddress13(pointToken);
4643
+ const tokenAddr = getAddress12(pointToken);
5103
4644
  const now = Date.now();
5104
4645
  const cached = this.stateCache.get(tokenAddr);
5105
4646
  if (cached && cached.expiresAt > now) return cached.value;
@@ -5118,49 +4659,41 @@ var IssuerStateValidator = class _IssuerStateValidator {
5118
4659
  return promise;
5119
4660
  }
5120
4661
  /**
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
- */
4662
+ * Validate that `amount` PT can be minted on `pointToken` right now.
4663
+ *
4664
+ * Throws `IssuerStateError` with:
4665
+ * - `ISSUER_NOT_REGISTERED` — registry has no record for this issuer
4666
+ * - `ISSUER_INACTIVE` — issuer.active is false
4667
+ * - `MINT_CAP_EXCEEDED` — totalSupply + amount would exceed hardCap
4668
+ *
4669
+ * Returns the fetched state on success so callers can log without a
4670
+ * second RPC round-trip.
4671
+ */
5131
4672
  async preValidateMint(pointToken, amount) {
5132
4673
  let state;
5133
4674
  try {
5134
4675
  state = await this.getIssuerState(pointToken);
5135
4676
  } catch (err) {
5136
4677
  if (err.message.includes("IssuerNotFound")) {
5137
- throw new IssuerStateError(
5138
- "ISSUER_NOT_REGISTERED",
5139
- `IssuerRegistry has no record for PointToken ${pointToken}`,
5140
- { pointToken }
5141
- );
4678
+ throw new IssuerStateError("ISSUER_NOT_REGISTERED", `IssuerRegistry has no record for PointToken ${pointToken}`, {
4679
+ pointToken
4680
+ });
5142
4681
  }
5143
4682
  throw err;
5144
4683
  }
5145
4684
  const { issuer, equityCap, equitySupply, remaining } = state;
5146
4685
  if (!issuer.active) {
5147
- throw new IssuerStateError(
5148
- "ISSUER_INACTIVE",
5149
- `Issuer "${issuer.name}" is deactivated on IssuerRegistry`,
5150
- { pointToken }
5151
- );
4686
+ throw new IssuerStateError("ISSUER_INACTIVE", `Issuer "${issuer.name}" is deactivated on IssuerRegistry`, {
4687
+ pointToken
4688
+ });
5152
4689
  }
5153
4690
  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
- );
4691
+ throw new IssuerStateError("MINT_CAP_EXCEEDED", `Requested ${amount} PT would exceed EQUITY mint cap. Cap=${equityCap.hardCap}, equityMinted=${equitySupply}, remaining=${remaining}`, {
4692
+ requested: amount.toString(),
4693
+ cap: equityCap.hardCap.toString(),
4694
+ equityMinted: equitySupply.toString(),
4695
+ remaining: remaining.toString()
4696
+ });
5164
4697
  }
5165
4698
  return state;
5166
4699
  }
@@ -5170,7 +4703,9 @@ var IssuerStateValidator = class _IssuerStateValidator {
5170
4703
  address: this.registryAddress,
5171
4704
  abi: issuerRegistryAbi,
5172
4705
  functionName: "getIssuer",
5173
- args: [issuerAddr]
4706
+ args: [
4707
+ issuerAddr
4708
+ ]
5174
4709
  });
5175
4710
  const issuer = {
5176
4711
  signerAddress: issuerStruct.signerAddress,
@@ -5202,6 +4737,9 @@ var IssuerStateValidator = class _IssuerStateValidator {
5202
4737
 
5203
4738
  // src/redemption/memoryHistoryStore.ts
5204
4739
  var MemoryRedemptionHistoryStore = class {
4740
+ static {
4741
+ __name(this, "MemoryRedemptionHistoryStore");
4742
+ }
5205
4743
  entries = [];
5206
4744
  async sumRedeemedSince(user, sinceUnixSec, pointTokenAddress) {
5207
4745
  const userKey = user.toLowerCase();
@@ -5237,7 +4775,7 @@ var MemoryRedemptionHistoryStore = class {
5237
4775
  };
5238
4776
 
5239
4777
  // src/index.ts
5240
- var PAFI_ISSUER_SDK_VERSION = true ? "0.39.2" : "dev";
4778
+ var PAFI_ISSUER_SDK_VERSION = true ? "0.40.0" : "dev";
5241
4779
  export {
5242
4780
  AdapterMisconfiguredError,
5243
4781
  AuthError,
@@ -5301,7 +4839,6 @@ export {
5301
4839
  defaultPolicyFor,
5302
4840
  evaluateRedemption,
5303
4841
  handleClaimStatus,
5304
- handleDelegateSubmit,
5305
4842
  handleMobilePrepare,
5306
4843
  handleMobileSubmit,
5307
4844
  handleRedeemStatus,
@@ -5313,7 +4850,6 @@ export {
5313
4850
  prepareMobileUserOp,
5314
4851
  relayUserOp,
5315
4852
  requestPaymaster,
5316
- serializeEntryToJsonRpc,
5317
- serializeUserOpTypedData
4853
+ serializeEntryToJsonRpc
5318
4854
  };
5319
4855
  //# sourceMappingURL=index.js.map