@pafi-dev/issuer 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -30,7 +30,6 @@ __export(index_exports, {
30
30
  DEFAULT_REDEMPTION_POLICY: () => DEFAULT_REDEMPTION_POLICY,
31
31
  DefaultPolicyEngine: () => DefaultPolicyEngine,
32
32
  FeeManager: () => FeeManager,
33
- GasUnitsCache: () => GasUnitsCache,
34
33
  InMemoryCursorStore: () => InMemoryCursorStore,
35
34
  IssuerApiAdapter: () => IssuerApiAdapter,
36
35
  IssuerApiHandlers: () => IssuerApiHandlers,
@@ -1094,172 +1093,22 @@ var RelayService = class {
1094
1093
  }
1095
1094
  });
1096
1095
  }
1097
- // =========================================================================
1098
- // Preview methods — produce bundler-ready partial UserOps WITHOUT signing.
1099
- //
1100
- // These exist so callers can compute an accurate gas estimate via
1101
- // `bundlerClient.estimateUserOperationGas(...)` BEFORE committing to a
1102
- // signed MintRequest / BurnRequest (signing is HSM-backed and expensive
1103
- // in prod). The returned `callData` matches the SHAPE of the real call;
1104
- // the EIP-712 signature bytes are placeholder. Bundler simulation
1105
- // doesn't validate the signature, so the gas units come back accurate.
1106
- //
1107
- // Cache-wise: same SC version + same scenario → same calldata shape →
1108
- // same bundler-returned gas units. The first call seeds the cache; the
1109
- // rest hit it.
1110
- // =========================================================================
1111
- /**
1112
- * Build a dummy `PartialUserOperation` for the mint scenario, suitable
1113
- * for `feeManager.estimateGasFee({ partialUserOp, ... })`. NO signing —
1114
- * uses a 65-byte zero signature in place of the real minter sig.
1115
- */
1116
- previewMintUserOp(params) {
1117
- const useWrapper = params.mintFeeWrapperAddress !== void 0;
1118
- let mintCallData;
1119
- let mintTarget;
1120
- if (useWrapper) {
1121
- mintCallData = (0, import_viem3.encodeFunctionData)({
1122
- abi: import_core5.mintFeeWrapperAbi,
1123
- functionName: "mintWithFee",
1124
- args: [
1125
- params.pointTokenAddress,
1126
- params.userAddress,
1127
- params.amount,
1128
- params.deadline,
1129
- PLACEHOLDER_SIG_65
1130
- ]
1131
- });
1132
- mintTarget = params.mintFeeWrapperAddress;
1133
- } else {
1134
- mintCallData = (0, import_viem3.encodeFunctionData)({
1135
- abi: import_core5.POINT_TOKEN_ABI,
1136
- functionName: "mint",
1137
- args: [
1138
- params.userAddress,
1139
- params.amount,
1140
- params.deadline,
1141
- PLACEHOLDER_SIG_65
1142
- ]
1143
- });
1144
- mintTarget = params.pointTokenAddress;
1145
- }
1146
- return (0, import_core5.buildPartialUserOperation)({
1147
- sender: params.userAddress,
1148
- nonce: params.aaNonce,
1149
- operations: [{ target: mintTarget, value: 0n, data: mintCallData }],
1150
- // Gas limits ignored by bundler estimate — it computes them.
1151
- gasLimits: { callGasLimit: 1n, verificationGasLimit: 1n, preVerificationGas: 1n }
1152
- });
1153
- }
1154
- /** Burn-side mirror of `previewMintUserOp`. */
1155
- previewBurnUserOp(params) {
1156
- const burnCallData = (0, import_viem3.encodeFunctionData)({
1157
- abi: import_core5.POINT_TOKEN_ABI,
1158
- functionName: "burn",
1159
- args: [
1160
- params.userAddress,
1161
- params.amount,
1162
- params.deadline,
1163
- PLACEHOLDER_SIG_65
1164
- ]
1165
- });
1166
- return (0, import_core5.buildPartialUserOperation)({
1167
- sender: params.userAddress,
1168
- nonce: params.aaNonce,
1169
- operations: [
1170
- { target: params.pointTokenAddress, value: 0n, data: burnCallData }
1171
- ],
1172
- gasLimits: { callGasLimit: 1n, verificationGasLimit: 1n, preVerificationGas: 1n }
1173
- });
1174
- }
1175
1096
  };
1176
- var PLACEHOLDER_SIG_65 = `0x${"00".repeat(65)}`;
1177
1097
  function errorMessage(err) {
1178
1098
  return err instanceof Error ? err.message : String(err);
1179
1099
  }
1180
1100
 
1181
- // src/relay/gasUnitsCache.ts
1182
- var import_viem4 = require("viem");
1183
- var DEFAULT_TTL_MS = 5 * 6e4;
1184
- var DEFAULT_CODEHASH_TTL_MS = 60 * 6e4;
1185
- var DEFAULT_MAX_ENTRIES = 100;
1186
- var GasUnitsCache = class {
1187
- entries = /* @__PURE__ */ new Map();
1188
- codehashEntries = /* @__PURE__ */ new Map();
1189
- ttlMs;
1190
- codehashTtlMs;
1191
- maxEntries;
1192
- constructor(config = {}) {
1193
- this.ttlMs = config.ttlMs ?? DEFAULT_TTL_MS;
1194
- this.codehashTtlMs = config.codehashTtlMs ?? DEFAULT_CODEHASH_TTL_MS;
1195
- this.maxEntries = config.maxEntries ?? DEFAULT_MAX_ENTRIES;
1196
- }
1197
- async buildKey(params) {
1198
- const codehash = await this.getCodehash(
1199
- params.provider,
1200
- params.contractAddress
1201
- );
1202
- const pm = params.paymasterAddress?.toLowerCase() ?? "0x0";
1203
- return `${params.scenario}:${codehash}:${pm}`;
1204
- }
1205
- get(key, now = Date.now()) {
1206
- const entry = this.entries.get(key);
1207
- if (!entry) return null;
1208
- if (entry.expiresAt <= now) {
1209
- this.entries.delete(key);
1210
- return null;
1211
- }
1212
- return entry.gasUnits;
1213
- }
1214
- set(key, gasUnits, now = Date.now()) {
1215
- if (this.entries.size >= this.maxEntries && !this.entries.has(key)) {
1216
- const eldest = this.entries.keys().next().value;
1217
- if (eldest !== void 0) this.entries.delete(eldest);
1218
- }
1219
- this.entries.set(key, { gasUnits, expiresAt: now + this.ttlMs });
1220
- }
1221
- invalidate() {
1222
- this.entries.clear();
1223
- this.codehashEntries.clear();
1224
- }
1225
- size() {
1226
- return this.entries.size;
1227
- }
1228
- async getCodehash(provider, address) {
1229
- const lower = address.toLowerCase();
1230
- const now = Date.now();
1231
- const cached = this.codehashEntries.get(lower);
1232
- if (cached && cached.expiresAt > now) return cached.codehash;
1233
- const code = await provider.getCode({ address });
1234
- const codehash = code ? (0, import_viem4.keccak256)(code) : "0x0";
1235
- this.codehashEntries.set(lower, {
1236
- codehash,
1237
- expiresAt: now + this.codehashTtlMs
1238
- });
1239
- return codehash;
1240
- }
1241
- };
1242
-
1243
1101
  // src/relay/feeManager.ts
1244
1102
  var DEFAULT_GAS_UNITS = 500000n;
1245
- var DEFAULT_PREMIUM_BPS = 1e4;
1246
- var DEFAULT_PAYMASTER_OVERHEAD = 80000n;
1247
- var DUMMY_SIGNATURE = "0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c";
1103
+ var DEFAULT_PREMIUM_BPS = 12e3;
1248
1104
  var FeeManager = class _FeeManager {
1249
1105
  provider;
1250
1106
  gasUnits;
1251
1107
  gasPremiumBps;
1252
1108
  quoteNativeToFee;
1253
- bundlerClient;
1254
- cache;
1255
- paymasterOverheadGas;
1256
- metrics;
1257
- // Short-lived in-flight fee cache (legacy behavior). Distinct from
1258
- // `cache` — that one stores gasUnits per scenario; this one stores the
1259
- // FULL computed fee value, valid for 10s to absorb burst calls.
1260
1109
  cachedFee = null;
1261
1110
  cacheExpiresAt = 0;
1262
- static FEE_CACHE_TTL_MS = 1e4;
1111
+ static CACHE_TTL_MS = 1e4;
1263
1112
  constructor(config) {
1264
1113
  if (!config.provider) throw new Error("FeeManager: provider required");
1265
1114
  if (!config.quoteNativeToFee)
@@ -1268,101 +1117,32 @@ var FeeManager = class _FeeManager {
1268
1117
  this.gasUnits = config.gasUnits ?? DEFAULT_GAS_UNITS;
1269
1118
  this.gasPremiumBps = config.gasPremiumBps ?? DEFAULT_PREMIUM_BPS;
1270
1119
  this.quoteNativeToFee = config.quoteNativeToFee;
1271
- this.bundlerClient = config.bundlerClient;
1272
- this.cache = new GasUnitsCache(config.cache);
1273
- this.paymasterOverheadGas = config.paymasterOverheadGas ?? DEFAULT_PAYMASTER_OVERHEAD;
1274
- this.metrics = config.metrics;
1275
1120
  }
1276
1121
  /**
1277
1122
  * Estimate the fee (in the caller's fee currency) to charge for the
1278
- * next sponsored UserOp.
1123
+ * next sponsored UserOp:
1279
1124
  *
1280
- * gasUnits = bundler-estimated (cached) or hardcoded fallback
1281
1125
  * nativeCost = gasUnits × gasPrice
1282
1126
  * withPremium = nativeCost × premiumBps / 10_000
1283
1127
  * fee = quoteNativeToFee(withPremium)
1284
1128
  *
1285
- * When `opts.partialUserOp` is omitted, behaves exactly like v0.16.x:
1286
- * uses the hardcoded `gasUnits` default.
1129
+ * For backward compatibility with v0.2.x code that reads `gasFeeUsdt`
1130
+ * from the response, the name `estimateGasFee` is kept — but the
1131
+ * currency depends on how the caller wired `quoteNativeToFee`.
1287
1132
  */
1288
- async estimateGasFee(opts = {}) {
1133
+ async estimateGasFee() {
1289
1134
  const now = Date.now();
1290
- const isLegacyCall = !opts.partialUserOp && !opts.scenario && !opts.contractAddress;
1291
- if (isLegacyCall && this.cachedFee !== null && now < this.cacheExpiresAt) {
1135
+ if (this.cachedFee !== null && now < this.cacheExpiresAt) {
1292
1136
  return this.cachedFee;
1293
1137
  }
1294
- const t0 = Date.now();
1295
- const { gasUnits, source } = await this.resolveGasUnits(opts);
1296
- const latencyMs = Date.now() - t0;
1297
- this.safeEmit(
1298
- () => this.metrics?.onEstimate?.({
1299
- source,
1300
- scenario: opts.scenario,
1301
- gasUnits,
1302
- latencyMs
1303
- })
1304
- );
1305
1138
  const gasPrice = await this.provider.getGasPrice();
1306
- const nativeCost = gasPrice * gasUnits;
1139
+ const nativeCost = gasPrice * this.gasUnits;
1307
1140
  const withPremium = nativeCost * BigInt(this.gasPremiumBps) / 10000n;
1308
1141
  const fee = await this.quoteNativeToFee(withPremium);
1309
- if (isLegacyCall) {
1310
- this.cachedFee = fee;
1311
- this.cacheExpiresAt = now + _FeeManager.FEE_CACHE_TTL_MS;
1312
- }
1142
+ this.cachedFee = fee;
1143
+ this.cacheExpiresAt = now + _FeeManager.CACHE_TTL_MS;
1313
1144
  return fee;
1314
1145
  }
1315
- /**
1316
- * Manually purge the per-scenario gas-units cache. Useful after an SC
1317
- * upgrade when ops wants the next estimate to refresh immediately
1318
- * (the codehash check would catch it on the NEXT call anyway, but
1319
- * this forces it now).
1320
- */
1321
- invalidateCache() {
1322
- this.cache.invalidate();
1323
- this.cachedFee = null;
1324
- this.cacheExpiresAt = 0;
1325
- }
1326
- async resolveGasUnits(opts) {
1327
- if (!this.bundlerClient || !opts.partialUserOp || !opts.scenario || !opts.contractAddress) {
1328
- return { gasUnits: this.gasUnits, source: "fallback" };
1329
- }
1330
- try {
1331
- const cacheKey = await this.cache.buildKey({
1332
- scenario: opts.scenario,
1333
- contractAddress: opts.contractAddress,
1334
- paymasterAddress: opts.paymasterAddress,
1335
- provider: this.provider
1336
- });
1337
- const cached = this.cache.get(cacheKey);
1338
- if (cached !== null) {
1339
- return { gasUnits: cached, source: "cache" };
1340
- }
1341
- const estimate = await this.bundlerClient.estimateUserOperationGas({
1342
- sender: opts.partialUserOp.sender,
1343
- nonce: opts.partialUserOp.nonce,
1344
- callData: opts.partialUserOp.callData,
1345
- signature: opts.partialUserOp.signature ?? DUMMY_SIGNATURE
1346
- // Intentionally NO paymaster fields — avoids chicken-and-egg
1347
- // (paymasterData depends on gasLimits). Overhead added below.
1348
- });
1349
- const gasUnits = estimate.callGasLimit + estimate.verificationGasLimit + estimate.preVerificationGas + (estimate.paymasterVerificationGasLimit ?? 0n) + (estimate.paymasterPostOpGasLimit ?? 0n) + this.paymasterOverheadGas;
1350
- this.cache.set(cacheKey, gasUnits);
1351
- return { gasUnits, source: "bundler" };
1352
- } catch (err) {
1353
- const reason = err instanceof Error ? err.message : String(err);
1354
- this.safeEmit(
1355
- () => this.metrics?.onBundlerError?.({ scenario: opts.scenario, reason })
1356
- );
1357
- return { gasUnits: this.gasUnits, source: "fallback" };
1358
- }
1359
- }
1360
- safeEmit(fn) {
1361
- try {
1362
- fn();
1363
- } catch {
1364
- }
1365
- }
1366
1146
  };
1367
1147
 
1368
1148
  // src/indexer/types.ts
@@ -1377,11 +1157,11 @@ var InMemoryCursorStore = class {
1377
1157
  };
1378
1158
 
1379
1159
  // src/indexer/pointIndexer.ts
1380
- var import_viem5 = require("viem");
1381
- var TRANSFER_EVENT = (0, import_viem5.parseAbiItem)(
1160
+ var import_viem4 = require("viem");
1161
+ var TRANSFER_EVENT = (0, import_viem4.parseAbiItem)(
1382
1162
  "event Transfer(address indexed from, address indexed to, uint256 value)"
1383
1163
  );
1384
- var MINT_WITH_FEE_EVENT = (0, import_viem5.parseAbiItem)(
1164
+ var MINT_WITH_FEE_EVENT = (0, import_viem4.parseAbiItem)(
1385
1165
  "event MintWithFee(address indexed pointToken, address indexed to, uint256 grossAmount, uint256 netAmount, uint256 feeAmount)"
1386
1166
  );
1387
1167
  var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
@@ -1391,7 +1171,7 @@ var DEFAULT_BATCH_SIZE = 2000n;
1391
1171
  var DEFAULT_POLL_INTERVAL_MS = 5e3;
1392
1172
  function isNoWrapper(addr) {
1393
1173
  if (!addr) return true;
1394
- const checksummed = (0, import_viem5.getAddress)(addr);
1174
+ const checksummed = (0, import_viem4.getAddress)(addr);
1395
1175
  return checksummed === ZERO_ADDRESS || checksummed === DEAD_ADDRESS;
1396
1176
  }
1397
1177
  var PointIndexer = class {
@@ -1413,8 +1193,8 @@ var PointIndexer = class {
1413
1193
  throw new Error("PointIndexer: pointTokenAddress required");
1414
1194
  if (!config.ledger) throw new Error("PointIndexer: ledger required");
1415
1195
  this.provider = config.provider;
1416
- this.pointTokenAddress = (0, import_viem5.getAddress)(config.pointTokenAddress);
1417
- this.mintFeeWrapperAddress = isNoWrapper(config.mintFeeWrapperAddress) ? void 0 : (0, import_viem5.getAddress)(config.mintFeeWrapperAddress);
1196
+ this.pointTokenAddress = (0, import_viem4.getAddress)(config.pointTokenAddress);
1197
+ this.mintFeeWrapperAddress = isNoWrapper(config.mintFeeWrapperAddress) ? void 0 : (0, import_viem4.getAddress)(config.mintFeeWrapperAddress);
1418
1198
  this.ledger = config.ledger;
1419
1199
  this.cursorStore = config.cursorStore ?? new InMemoryCursorStore();
1420
1200
  this.startBlock = config.fromBlock ?? 0n;
@@ -1533,9 +1313,9 @@ var PointIndexer = class {
1533
1313
  if (!args.pointToken || !args.to || args.grossAmount === void 0 || log.blockNumber === null || log.transactionHash === null) {
1534
1314
  continue;
1535
1315
  }
1536
- if ((0, import_viem5.getAddress)(args.pointToken) !== this.pointTokenAddress) continue;
1316
+ if ((0, import_viem4.getAddress)(args.pointToken) !== this.pointTokenAddress) continue;
1537
1317
  out.push({
1538
- to: (0, import_viem5.getAddress)(args.to),
1318
+ to: (0, import_viem4.getAddress)(args.to),
1539
1319
  amount: args.grossAmount,
1540
1320
  blockNumber: log.blockNumber,
1541
1321
  txHash: log.transactionHash,
@@ -1563,10 +1343,10 @@ var PointIndexer = class {
1563
1343
  for (const log of logs) {
1564
1344
  const args = log.args;
1565
1345
  if (!args.from || !args.to || args.value === void 0) continue;
1566
- if ((0, import_viem5.getAddress)(args.from) !== ZERO_ADDRESS) continue;
1346
+ if ((0, import_viem4.getAddress)(args.from) !== ZERO_ADDRESS) continue;
1567
1347
  if (log.blockNumber === null || log.transactionHash === null) continue;
1568
1348
  out.push({
1569
- to: (0, import_viem5.getAddress)(args.to),
1349
+ to: (0, import_viem4.getAddress)(args.to),
1570
1350
  amount: args.value,
1571
1351
  blockNumber: log.blockNumber,
1572
1352
  txHash: log.transactionHash,
@@ -1625,8 +1405,8 @@ function pickMatchingLock(locks, amount) {
1625
1405
  }
1626
1406
 
1627
1407
  // src/indexer/burnIndexer.ts
1628
- var import_viem6 = require("viem");
1629
- var TRANSFER_EVENT2 = (0, import_viem6.parseAbiItem)(
1408
+ var import_viem5 = require("viem");
1409
+ var TRANSFER_EVENT2 = (0, import_viem5.parseAbiItem)(
1630
1410
  "event Transfer(address indexed from, address indexed to, uint256 value)"
1631
1411
  );
1632
1412
  var ZERO_ADDRESS2 = "0x0000000000000000000000000000000000000000";
@@ -1757,10 +1537,10 @@ var BurnIndexer = class {
1757
1537
  for (const log of logs) {
1758
1538
  const args = log.args;
1759
1539
  if (!args.from || !args.to || args.value === void 0) continue;
1760
- if ((0, import_viem6.getAddress)(args.to) !== ZERO_ADDRESS2) continue;
1540
+ if ((0, import_viem5.getAddress)(args.to) !== ZERO_ADDRESS2) continue;
1761
1541
  if (log.blockNumber === null || log.transactionHash === null) continue;
1762
1542
  out.push({
1763
- from: (0, import_viem6.getAddress)(args.from),
1543
+ from: (0, import_viem5.getAddress)(args.from),
1764
1544
  amount: args.value,
1765
1545
  blockNumber: log.blockNumber,
1766
1546
  txHash: log.transactionHash,
@@ -1795,7 +1575,7 @@ var BurnIndexer = class {
1795
1575
  };
1796
1576
 
1797
1577
  // src/api/handlers.ts
1798
- var import_viem7 = require("viem");
1578
+ var import_viem6 = require("viem");
1799
1579
  var import_core6 = require("@pafi-dev/core");
1800
1580
  var IssuerApiHandlers = class _IssuerApiHandlers {
1801
1581
  authService;
@@ -1832,7 +1612,7 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
1832
1612
  "IssuerApiHandlers: pointTokenAddress or pointTokenAddresses required"
1833
1613
  );
1834
1614
  }
1835
- const normalized = raw.map((a) => (0, import_viem7.getAddress)(a));
1615
+ const normalized = raw.map((a) => (0, import_viem6.getAddress)(a));
1836
1616
  this.supportedTokens = new Set(normalized);
1837
1617
  this.chainId = config.chainId;
1838
1618
  this.contracts = config.contracts;
@@ -1841,7 +1621,7 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
1841
1621
  if (config.poolsProvider) this.poolsProvider = config.poolsProvider;
1842
1622
  if (config.redemption) this.redemption = config.redemption;
1843
1623
  if (config.mintFeeWrapperAddress) {
1844
- this.mintFeeWrapperAddress = (0, import_viem7.getAddress)(config.mintFeeWrapperAddress);
1624
+ this.mintFeeWrapperAddress = (0, import_viem6.getAddress)(config.mintFeeWrapperAddress);
1845
1625
  }
1846
1626
  }
1847
1627
  // =========================================================================
@@ -2048,8 +1828,8 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
2048
1828
  { requested: request.chainId, supported: this.chainId }
2049
1829
  );
2050
1830
  }
2051
- const normalizedAuthed = (0, import_viem7.getAddress)(userAddress);
2052
- const normalizedRequest = (0, import_viem7.getAddress)(request.userAddress);
1831
+ const normalizedAuthed = (0, import_viem6.getAddress)(userAddress);
1832
+ const normalizedRequest = (0, import_viem6.getAddress)(request.userAddress);
2053
1833
  if (normalizedAuthed !== normalizedRequest) {
2054
1834
  throw new import_core3.ValidationError(
2055
1835
  "USER_ADDRESS_MISMATCH",
@@ -2057,7 +1837,7 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
2057
1837
  { authenticated: normalizedAuthed, requested: normalizedRequest }
2058
1838
  );
2059
1839
  }
2060
- const pointToken = (0, import_viem7.getAddress)(request.pointTokenAddress);
1840
+ const pointToken = (0, import_viem6.getAddress)(request.pointTokenAddress);
2061
1841
  if (!this.supportedTokens.has(pointToken)) {
2062
1842
  throw new import_core3.ValidationError(
2063
1843
  "UNSUPPORTED_POINT_TOKEN",
@@ -2098,9 +1878,9 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
2098
1878
  "handleRedemptionPreview: redemption is not configured on this issuer"
2099
1879
  );
2100
1880
  }
2101
- const tokenAddress = request.pointTokenAddress ? this.requireSupportedToken((0, import_viem7.getAddress)(request.pointTokenAddress), "handleRedemptionPreview") : void 0;
1881
+ const tokenAddress = request.pointTokenAddress ? this.requireSupportedToken((0, import_viem6.getAddress)(request.pointTokenAddress), "handleRedemptionPreview") : void 0;
2102
1882
  const preview = await this.redemption.preview(
2103
- (0, import_viem7.getAddress)(userAddress),
1883
+ (0, import_viem6.getAddress)(userAddress),
2104
1884
  tokenAddress
2105
1885
  );
2106
1886
  return preview;
@@ -2129,9 +1909,9 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
2129
1909
  { amountPt: request.amountPt.toString() }
2130
1910
  );
2131
1911
  }
2132
- const tokenAddress = request.pointTokenAddress ? this.requireSupportedToken((0, import_viem7.getAddress)(request.pointTokenAddress), "handleRedemptionEvaluate") : void 0;
1912
+ const tokenAddress = request.pointTokenAddress ? this.requireSupportedToken((0, import_viem6.getAddress)(request.pointTokenAddress), "handleRedemptionEvaluate") : void 0;
2133
1913
  const decision = await this.redemption.evaluate(
2134
- (0, import_viem7.getAddress)(userAddress),
1914
+ (0, import_viem6.getAddress)(userAddress),
2135
1915
  request.amountPt,
2136
1916
  tokenAddress
2137
1917
  );
@@ -2155,7 +1935,7 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
2155
1935
  };
2156
1936
 
2157
1937
  // src/api/handlers/ptRedeemHandler.ts
2158
- var import_viem8 = require("viem");
1938
+ var import_viem7 = require("viem");
2159
1939
  var import_core7 = require("@pafi-dev/core");
2160
1940
  var DEFAULT_REDEEM_LOCK_MS = 15 * 60 * 1e3;
2161
1941
  var DEFAULT_SIG_DEADLINE_SEC = 15 * 60;
@@ -2216,8 +1996,8 @@ var PTRedeemHandler = class {
2216
1996
  this.relayService = config.relayService;
2217
1997
  this.provider = config.provider;
2218
1998
  this.feeService = config.feeService;
2219
- this.pointTokenAddress = (0, import_viem8.getAddress)(config.pointTokenAddress);
2220
- this.batchExecutorAddress = (0, import_viem8.getAddress)(config.batchExecutorAddress);
1999
+ this.pointTokenAddress = (0, import_viem7.getAddress)(config.pointTokenAddress);
2000
+ this.batchExecutorAddress = (0, import_viem7.getAddress)(config.batchExecutorAddress);
2221
2001
  this.chainId = config.chainId;
2222
2002
  this.domain = config.domain;
2223
2003
  this.burnerSignerWallet = config.burnerSignerWallet;
@@ -2232,7 +2012,7 @@ var PTRedeemHandler = class {
2232
2012
  }
2233
2013
  }
2234
2014
  async handle(request) {
2235
- if ((0, import_viem8.getAddress)(request.authenticatedAddress) !== (0, import_viem8.getAddress)(request.userAddress)) {
2015
+ if ((0, import_viem7.getAddress)(request.authenticatedAddress) !== (0, import_viem7.getAddress)(request.userAddress)) {
2236
2016
  throw new PTRedeemError(
2237
2017
  "UNAUTHORIZED",
2238
2018
  `userAddress (${request.userAddress}) does not match authenticated session (${request.authenticatedAddress})`
@@ -2270,7 +2050,7 @@ var PTRedeemHandler = class {
2270
2050
  `failed to read burnRequestNonces(${request.userAddress}): ${err instanceof Error ? err.message : String(err)}`
2271
2051
  );
2272
2052
  }
2273
- const userKey = (0, import_viem8.getAddress)(request.userAddress).toLowerCase();
2053
+ const userKey = (0, import_viem7.getAddress)(request.userAddress).toLowerCase();
2274
2054
  let userNonces = this.inFlightNonces.get(userKey);
2275
2055
  if (!userNonces) {
2276
2056
  userNonces = /* @__PURE__ */ new Set();
@@ -2291,29 +2071,11 @@ var PTRedeemHandler = class {
2291
2071
  }
2292
2072
  }
2293
2073
  async _handleAfterNonceLock(request, burnNonce) {
2294
- const previewDeadline = BigInt(
2295
- Math.floor(this.now() / 1e3) + this.signatureDeadlineSeconds
2296
- );
2297
2074
  let fee;
2298
2075
  if (request.feeAmount !== void 0) {
2299
2076
  fee = request.feeAmount > 0n ? request.feeAmount : 0n;
2300
2077
  } else if (this.feeService) {
2301
- const previewUserOp = this.relayService.previewBurnUserOp({
2302
- userAddress: request.userAddress,
2303
- aaNonce: burnNonce,
2304
- pointTokenAddress: this.pointTokenAddress,
2305
- amount: request.amount,
2306
- deadline: previewDeadline
2307
- });
2308
- fee = await this.feeService.estimateGasFee({
2309
- scenario: "burn",
2310
- contractAddress: this.pointTokenAddress,
2311
- partialUserOp: {
2312
- sender: previewUserOp.sender,
2313
- nonce: previewUserOp.nonce,
2314
- callData: previewUserOp.callData
2315
- }
2316
- });
2078
+ fee = await this.feeService.estimateGasFee();
2317
2079
  } else {
2318
2080
  fee = 0n;
2319
2081
  }
@@ -2335,7 +2097,9 @@ var PTRedeemHandler = class {
2335
2097
  `insufficient on-chain PT balance: have ${onChainBalance}, need ${request.amount}`
2336
2098
  );
2337
2099
  }
2338
- const deadline = previewDeadline;
2100
+ const deadline = BigInt(
2101
+ Math.floor(this.now() / 1e3) + this.signatureDeadlineSeconds
2102
+ );
2339
2103
  const domain = {
2340
2104
  name: this.domain.name,
2341
2105
  chainId: this.chainId,
@@ -2552,7 +2316,7 @@ async function handleRedeemStatus(params) {
2552
2316
  }
2553
2317
 
2554
2318
  // src/api/mobileHandlers.ts
2555
- var import_viem9 = require("viem");
2319
+ var import_viem8 = require("viem");
2556
2320
  var import_core10 = require("@pafi-dev/core");
2557
2321
 
2558
2322
  // src/userop-store/serialize.ts
@@ -2898,7 +2662,7 @@ async function handleMobileSubmit(params) {
2898
2662
  if (!entry) {
2899
2663
  throw new PendingUserOpNotFoundError(params.lockId);
2900
2664
  }
2901
- if ((0, import_viem9.getAddress)(entry.sender) !== (0, import_viem9.getAddress)(params.authenticatedAddress)) {
2665
+ if ((0, import_viem8.getAddress)(entry.sender) !== (0, import_viem8.getAddress)(params.authenticatedAddress)) {
2902
2666
  throw new PendingUserOpForbiddenError(params.lockId);
2903
2667
  }
2904
2668
  const variant = params.variant ?? "sponsored";
@@ -2914,7 +2678,7 @@ async function handleMobileSubmit(params) {
2914
2678
  }
2915
2679
 
2916
2680
  // src/api/handlers/ptClaimHandler.ts
2917
- var import_viem10 = require("viem");
2681
+ var import_viem9 = require("viem");
2918
2682
  var import_core11 = require("@pafi-dev/core");
2919
2683
 
2920
2684
  // src/issuer-state/types.ts
@@ -2960,7 +2724,7 @@ var PTClaimHandler = class {
2960
2724
  };
2961
2725
  }
2962
2726
  async handle(request) {
2963
- if ((0, import_viem10.getAddress)(request.authenticatedAddress) !== (0, import_viem10.getAddress)(request.userAddress)) {
2727
+ if ((0, import_viem9.getAddress)(request.authenticatedAddress) !== (0, import_viem9.getAddress)(request.userAddress)) {
2964
2728
  throw new PTClaimError(
2965
2729
  "VALIDATION_FAILED",
2966
2730
  `userAddress (${request.userAddress}) does not match authenticated session (${request.authenticatedAddress})`
@@ -2998,23 +2762,7 @@ var PTClaimHandler = class {
2998
2762
  const signatureDeadline = BigInt(
2999
2763
  Math.floor(this.cfg.now() / 1e3) + this.cfg.signatureDeadlineSeconds
3000
2764
  );
3001
- const previewUserOp = this.cfg.relayService.previewMintUserOp({
3002
- userAddress: request.userAddress,
3003
- aaNonce: request.aaNonce,
3004
- pointTokenAddress: request.pointTokenAddress,
3005
- amount: request.amount,
3006
- deadline: signatureDeadline,
3007
- mintFeeWrapperAddress: resolvedWrapper
3008
- });
3009
- const feeAmount = this.cfg.feeService ? await this.cfg.feeService.estimateGasFee({
3010
- scenario: resolvedWrapper ? "mint-wrapped" : "mint",
3011
- contractAddress: request.pointTokenAddress,
3012
- partialUserOp: {
3013
- sender: previewUserOp.sender,
3014
- nonce: previewUserOp.nonce,
3015
- callData: previewUserOp.callData
3016
- }
3017
- }) : 0n;
2765
+ const feeAmount = this.cfg.feeService ? await this.cfg.feeService.estimateGasFee() : 0n;
3018
2766
  const domain = {
3019
2767
  name: this.cfg.pointTokenDomainName,
3020
2768
  chainId: request.chainId,
@@ -3214,7 +2962,7 @@ var PerpDepositHandler = class {
3214
2962
 
3215
2963
  // src/api/delegateHandler.ts
3216
2964
  var import_core13 = require("@pafi-dev/core");
3217
- var import_viem11 = require("viem");
2965
+ var import_viem10 = require("viem");
3218
2966
  var DEFAULT_DELEGATE_GAS = {
3219
2967
  callGasLimit: 100000n,
3220
2968
  verificationGasLimit: 150000n,
@@ -3301,7 +3049,7 @@ async function handleDelegateSubmit(params) {
3301
3049
  if (!entry) {
3302
3050
  throw new PendingUserOpNotFoundError(params.lockId);
3303
3051
  }
3304
- if ((0, import_viem11.getAddress)(entry.sender) !== (0, import_viem11.getAddress)(params.authenticatedAddress)) {
3052
+ if ((0, import_viem10.getAddress)(entry.sender) !== (0, import_viem10.getAddress)(params.authenticatedAddress)) {
3305
3053
  throw new PendingUserOpForbiddenError(params.lockId);
3306
3054
  }
3307
3055
  if (!entry.eip7702Auth) {
@@ -3322,7 +3070,7 @@ async function handleDelegateSubmit(params) {
3322
3070
 
3323
3071
  // src/api/issuerApiAdapter.ts
3324
3072
  var import_node_crypto3 = require("crypto");
3325
- var import_viem12 = require("viem");
3073
+ var import_viem11 = require("viem");
3326
3074
  var import_core14 = require("@pafi-dev/core");
3327
3075
  var AdapterMisconfiguredError = class extends Error {
3328
3076
  code = "ADAPTER_MISCONFIGURED";
@@ -3380,7 +3128,7 @@ var IssuerApiAdapter = class {
3380
3128
  async pools(authenticatedAddress, chainId, pointTokenAddress) {
3381
3129
  const result = await this.cfg.issuerService.api.handlePools(
3382
3130
  authenticatedAddress,
3383
- { chainId, pointTokenAddress: (0, import_viem12.getAddress)(pointTokenAddress) }
3131
+ { chainId, pointTokenAddress: (0, import_viem11.getAddress)(pointTokenAddress) }
3384
3132
  );
3385
3133
  return { pools: result.pools };
3386
3134
  }
@@ -3389,8 +3137,8 @@ var IssuerApiAdapter = class {
3389
3137
  authenticatedAddress,
3390
3138
  {
3391
3139
  chainId,
3392
- userAddress: (0, import_viem12.getAddress)(userAddress),
3393
- pointTokenAddress: (0, import_viem12.getAddress)(pointTokenAddress)
3140
+ userAddress: (0, import_viem11.getAddress)(userAddress),
3141
+ pointTokenAddress: (0, import_viem11.getAddress)(pointTokenAddress)
3394
3142
  }
3395
3143
  );
3396
3144
  return {
@@ -3411,7 +3159,7 @@ var IssuerApiAdapter = class {
3411
3159
  "ptClaimHandler",
3412
3160
  "claim"
3413
3161
  );
3414
- const pointTokenAddress = (0, import_viem12.getAddress)(input.pointTokenAddress);
3162
+ const pointTokenAddress = (0, import_viem11.getAddress)(input.pointTokenAddress);
3415
3163
  const result = await ptClaimHandler.handle({
3416
3164
  authenticatedAddress: input.authenticatedAddress,
3417
3165
  userAddress: input.authenticatedAddress,
@@ -3506,7 +3254,7 @@ var IssuerApiAdapter = class {
3506
3254
  "ptClaimHandler",
3507
3255
  "claimPrepare"
3508
3256
  );
3509
- const pointTokenAddress = (0, import_viem12.getAddress)(input.pointTokenAddress);
3257
+ const pointTokenAddress = (0, import_viem11.getAddress)(input.pointTokenAddress);
3510
3258
  const claimResult = await ptClaimHandler.handle({
3511
3259
  authenticatedAddress: input.authenticatedAddress,
3512
3260
  userAddress: input.authenticatedAddress,
@@ -3552,7 +3300,7 @@ var IssuerApiAdapter = class {
3552
3300
  }
3553
3301
  async redeemPrepare(input) {
3554
3302
  this.assertRedeemHandler();
3555
- const pointTokenAddress = (0, import_viem12.getAddress)(input.pointTokenAddress);
3303
+ const pointTokenAddress = (0, import_viem11.getAddress)(input.pointTokenAddress);
3556
3304
  const redeemResponse = await this.cfg.ptRedeemHandler.handle({
3557
3305
  userAddress: input.authenticatedAddress,
3558
3306
  authenticatedAddress: input.authenticatedAddress,
@@ -3742,7 +3490,7 @@ var IssuerApiAdapter = class {
3742
3490
  };
3743
3491
 
3744
3492
  // src/pools/subgraphPoolsProvider.ts
3745
- var import_viem13 = require("viem");
3493
+ var import_viem12 = require("viem");
3746
3494
  var import_core15 = require("@pafi-dev/core");
3747
3495
  var DEFAULT_CACHE_TTL_MS = 3e4;
3748
3496
  var MAX_REASONABLE_FEE_TIER = 1e6;
@@ -3865,7 +3613,7 @@ async function fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, pointTokenAddress,
3865
3613
  return [];
3866
3614
  }
3867
3615
  const { pool } = token;
3868
- if (!(0, import_viem13.isAddress)(pool.token0.id) || !(0, import_viem13.isAddress)(pool.token1.id)) {
3616
+ if (!(0, import_viem12.isAddress)(pool.token0.id) || !(0, import_viem12.isAddress)(pool.token1.id)) {
3869
3617
  const error = new Error(
3870
3618
  "[PAFI] SubgraphPoolsProvider: invalid token address in response"
3871
3619
  );
@@ -4018,8 +3766,8 @@ function toUsdtPerNative(priceFloat, usdtDecimals) {
4018
3766
  }
4019
3767
 
4020
3768
  // src/pools/nativePtQuoter.ts
4021
- var import_viem14 = require("viem");
4022
- var CHAINLINK_ABI = (0, import_viem14.parseAbi)([
3769
+ var import_viem13 = require("viem");
3770
+ var CHAINLINK_ABI = (0, import_viem13.parseAbi)([
4023
3771
  "function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)"
4024
3772
  ]);
4025
3773
  var CHAINLINK_MAX_AGE_S = 3600n;
@@ -4303,7 +4051,7 @@ var PafiBackendClient = class {
4303
4051
  };
4304
4052
 
4305
4053
  // src/config.ts
4306
- var import_viem15 = require("viem");
4054
+ var import_viem14 = require("viem");
4307
4055
  var import_core18 = require("@pafi-dev/core");
4308
4056
 
4309
4057
  // src/redemption/evaluator.ts
@@ -4630,7 +4378,7 @@ function createIssuerService(config) {
4630
4378
  "createIssuerService: at least one of pointTokenAddress / pointTokenAddresses is required"
4631
4379
  );
4632
4380
  }
4633
- const tokenAddresses = rawAddresses.map((a) => (0, import_viem15.getAddress)(a));
4381
+ const tokenAddresses = rawAddresses.map((a) => (0, import_viem14.getAddress)(a));
4634
4382
  const ledger = config.ledger;
4635
4383
  const sessionStore = config.sessionStore ?? new MemorySessionStore();
4636
4384
  const policy = config.policy ?? new DefaultPolicyEngine({ ledger });
@@ -4749,7 +4497,7 @@ function createIssuerService(config) {
4749
4497
  }
4750
4498
 
4751
4499
  // src/issuer-state/validator.ts
4752
- var import_viem16 = require("viem");
4500
+ var import_viem15 = require("viem");
4753
4501
  var import_core19 = require("@pafi-dev/core");
4754
4502
  var ISSUER_RECORD_TTL_MS = 3e4;
4755
4503
  var IssuerStateValidator = class _IssuerStateValidator {
@@ -4776,7 +4524,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
4776
4524
  */
4777
4525
  invalidate(pointToken) {
4778
4526
  if (pointToken) {
4779
- const key = (0, import_viem16.getAddress)(pointToken);
4527
+ const key = (0, import_viem15.getAddress)(pointToken);
4780
4528
  this.pointTokenIssuerCache.delete(key);
4781
4529
  this.stateCache.delete(key);
4782
4530
  this.inflight.delete(key);
@@ -4791,7 +4539,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
4791
4539
  * The issuer field is set at `initialize()` and never changes.
4792
4540
  */
4793
4541
  async getIssuerAddressForPointToken(pointToken) {
4794
- const key = (0, import_viem16.getAddress)(pointToken);
4542
+ const key = (0, import_viem15.getAddress)(pointToken);
4795
4543
  const cached = this.pointTokenIssuerCache.get(key);
4796
4544
  if (cached) return cached;
4797
4545
  const issuer = await this.provider.readContract({
@@ -4799,15 +4547,15 @@ var IssuerStateValidator = class _IssuerStateValidator {
4799
4547
  abi: import_core19.POINT_TOKEN_ABI,
4800
4548
  functionName: "issuer"
4801
4549
  });
4802
- this.pointTokenIssuerCache.set(key, (0, import_viem16.getAddress)(issuer));
4803
- return (0, import_viem16.getAddress)(issuer);
4550
+ this.pointTokenIssuerCache.set(key, (0, import_viem15.getAddress)(issuer));
4551
+ return (0, import_viem15.getAddress)(issuer);
4804
4552
  }
4805
4553
  /**
4806
4554
  * Read registry record + totalSupply, with 30s cache and in-flight
4807
4555
  * deduplication. Does NOT throw on inactive/missing — returns raw state.
4808
4556
  */
4809
4557
  async getIssuerState(pointToken) {
4810
- const tokenAddr = (0, import_viem16.getAddress)(pointToken);
4558
+ const tokenAddr = (0, import_viem15.getAddress)(pointToken);
4811
4559
  const now = Date.now();
4812
4560
  const cached = this.stateCache.get(tokenAddr);
4813
4561
  if (cached && cached.expiresAt > now) return cached.value;
@@ -4950,7 +4698,7 @@ var MemoryRedemptionHistoryStore = class {
4950
4698
  };
4951
4699
 
4952
4700
  // src/index.ts
4953
- var PAFI_ISSUER_SDK_VERSION = true ? "0.18.0" : "dev";
4701
+ var PAFI_ISSUER_SDK_VERSION = true ? "0.19.0" : "dev";
4954
4702
  // Annotate the CommonJS export names for ESM import in node:
4955
4703
  0 && (module.exports = {
4956
4704
  AdapterMisconfiguredError,
@@ -4963,7 +4711,6 @@ var PAFI_ISSUER_SDK_VERSION = true ? "0.18.0" : "dev";
4963
4711
  DEFAULT_REDEMPTION_POLICY,
4964
4712
  DefaultPolicyEngine,
4965
4713
  FeeManager,
4966
- GasUnitsCache,
4967
4714
  InMemoryCursorStore,
4968
4715
  IssuerApiAdapter,
4969
4716
  IssuerApiHandlers,