@pafi-dev/issuer 0.13.0 → 0.15.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
@@ -779,8 +779,8 @@ var RelayService = class {
779
779
  * provides a pre-signed `BurnRequest` + sig bytes (typically from
780
780
  * `PTRedeemHandler`).
781
781
  *
782
- * Direct burn (no sig) was dropped in v1.4 — every burn now goes
783
- * through the issuer-signed `BurnRequest` path.
782
+ * Direct burn (no sig) is not used — every burn goes through the
783
+ * issuer-signed `BurnRequest` path.
784
784
  */
785
785
  async prepareBurn(params) {
786
786
  if (!params.pointTokenAddress) {
@@ -1064,7 +1064,7 @@ var PointIndexer = class {
1064
1064
  // Event fetching — two modes (wrapper vs direct)
1065
1065
  // -------------------------------------------------------------------------
1066
1066
  /**
1067
- * Wrapper mode (v1.6): listen for `MintWithFee` on the wrapper,
1067
+ * Wrapper mode: listen for `MintWithFee` on the wrapper,
1068
1068
  * filtered to events for THIS pointToken only. The event's `to` field
1069
1069
  * is the actual end user, and `grossAmount` matches the lock amount.
1070
1070
  */
@@ -1591,9 +1591,8 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
1591
1591
  /**
1592
1592
  * `GET /user?chainId=<id>&user=<addr>&pointToken=<addr>`
1593
1593
  *
1594
- * Returns per-user state the frontend needs to build a fresh
1595
- * `ReceiverConsent`: on-chain nonces + minter status + off-chain
1596
- * balance.
1594
+ * Returns per-user state the frontend needs to build a fresh mint:
1595
+ * on-chain nonces + minter status + off-chain balance.
1597
1596
  */
1598
1597
  async handleUser(userAddress, request) {
1599
1598
  if (request.chainId !== this.chainId) {
@@ -2206,38 +2205,42 @@ function mergePaymasterFields(userOp, paymasterFields) {
2206
2205
  }
2207
2206
  return merged;
2208
2207
  }
2209
- async function prepareMobileUserOp(params) {
2208
+ function applyPaymasterGasEstimates(partialUserOp, paymasterFields, chainId) {
2210
2209
  const userOp = mergePaymasterFields(
2211
- params.partialUserOp,
2212
- params.paymasterFields
2210
+ partialUserOp,
2211
+ paymasterFields
2213
2212
  );
2214
- const userOpHash = computeUserOpHash(userOp, params.chainId);
2215
- const typedData = serializeUserOpTypedData(
2216
- buildUserOpTypedData(userOp, params.chainId)
2213
+ return {
2214
+ userOp,
2215
+ userOpHash: computeUserOpHash(userOp, chainId),
2216
+ typedData: serializeUserOpTypedData(buildUserOpTypedData(userOp, chainId))
2217
+ };
2218
+ }
2219
+ async function prepareMobileUserOp(params) {
2220
+ const sponsored = applyPaymasterGasEstimates(
2221
+ params.partialUserOp,
2222
+ params.paymasterFields,
2223
+ params.chainId
2217
2224
  );
2225
+ const { userOp, userOpHash } = sponsored;
2218
2226
  let fallback;
2219
2227
  let fallbackEntry;
2220
2228
  if (params.partialUserOpFallback) {
2221
- const fallbackUserOp = {
2222
- ...params.partialUserOpFallback,
2223
- maxFeePerGas: userOp.maxFeePerGas,
2224
- maxPriorityFeePerGas: userOp.maxPriorityFeePerGas
2225
- };
2226
- const fallbackHash = computeUserOpHash(fallbackUserOp, params.chainId);
2227
- const fallbackTypedData = serializeUserOpTypedData(
2228
- buildUserOpTypedData(fallbackUserOp, params.chainId)
2229
+ fallback = applyPaymasterGasEstimates(
2230
+ {
2231
+ ...params.partialUserOpFallback,
2232
+ maxFeePerGas: userOp.maxFeePerGas,
2233
+ maxPriorityFeePerGas: userOp.maxPriorityFeePerGas
2234
+ },
2235
+ void 0,
2236
+ params.chainId
2229
2237
  );
2230
- fallback = {
2231
- userOp: fallbackUserOp,
2232
- userOpHash: fallbackHash,
2233
- typedData: fallbackTypedData
2234
- };
2235
2238
  fallbackEntry = {
2236
- callData: fallbackUserOp.callData,
2237
- callGasLimit: fallbackUserOp.callGasLimit.toString(),
2238
- verificationGasLimit: fallbackUserOp.verificationGasLimit.toString(),
2239
- preVerificationGas: fallbackUserOp.preVerificationGas.toString(),
2240
- userOpHash: fallbackHash
2239
+ callData: fallback.userOp.callData,
2240
+ callGasLimit: fallback.userOp.callGasLimit.toString(),
2241
+ verificationGasLimit: fallback.userOp.verificationGasLimit.toString(),
2242
+ preVerificationGas: fallback.userOp.preVerificationGas.toString(),
2243
+ userOpHash: fallback.userOpHash
2241
2244
  };
2242
2245
  }
2243
2246
  const entry = {
@@ -2259,7 +2262,7 @@ async function prepareMobileUserOp(params) {
2259
2262
  };
2260
2263
  await params.store.save(params.lockId, entry, params.ttlSeconds);
2261
2264
  return {
2262
- sponsored: { userOp, userOpHash, typedData },
2265
+ sponsored,
2263
2266
  fallback,
2264
2267
  entry
2265
2268
  };
@@ -2761,8 +2764,6 @@ import {
2761
2764
  ENTRY_POINT_V08 as ENTRY_POINT_V082,
2762
2765
  buildDelegationUserOp,
2763
2766
  buildEip7702Authorization,
2764
- computeUserOpHash as computeUserOpHash2,
2765
- buildUserOpTypedData as buildUserOpTypedData2,
2766
2767
  getContractAddresses as getContractAddresses5,
2767
2768
  serializeUserOpToJsonRpc as serializeUserOpToJsonRpc2
2768
2769
  } from "@pafi-dev/core";
@@ -2808,22 +2809,13 @@ async function handleDelegatePrepare(params) {
2808
2809
  eip7702Auth: authorization,
2809
2810
  onWarning: params.onWarning
2810
2811
  });
2811
- const merged = {
2812
- sender: userOp.sender,
2813
- nonce: userOp.nonce,
2814
- callData: userOp.callData,
2815
- callGasLimit: paymasterFields?.callGasLimit ?? userOp.callGasLimit,
2816
- verificationGasLimit: paymasterFields?.verificationGasLimit ?? userOp.verificationGasLimit,
2817
- preVerificationGas: paymasterFields?.preVerificationGas ?? userOp.preVerificationGas,
2818
- maxFeePerGas: paymasterFields?.maxFeePerGas ?? userOp.maxFeePerGas,
2819
- maxPriorityFeePerGas: paymasterFields?.maxPriorityFeePerGas ?? userOp.maxPriorityFeePerGas,
2820
- paymaster: paymasterFields?.paymaster,
2821
- paymasterVerificationGasLimit: paymasterFields?.paymasterVerificationGasLimit,
2822
- paymasterPostOpGasLimit: paymasterFields?.paymasterPostOpGasLimit,
2823
- paymasterData: paymasterFields?.paymasterData
2824
- };
2825
- const userOpHash = computeUserOpHash2(merged, params.chainId);
2826
- const typed = buildUserOpTypedData2(merged, params.chainId);
2812
+ const prepared = applyPaymasterGasEstimates(
2813
+ userOp,
2814
+ paymasterFields,
2815
+ params.chainId
2816
+ );
2817
+ const merged = prepared.userOp;
2818
+ const userOpHash = prepared.userOpHash;
2827
2819
  await params.store.save(
2828
2820
  params.lockId,
2829
2821
  {
@@ -2852,7 +2844,7 @@ async function handleDelegatePrepare(params) {
2852
2844
  return {
2853
2845
  lockId: params.lockId,
2854
2846
  userOpHash,
2855
- typedData: serializeUserOpTypedData(typed),
2847
+ typedData: prepared.typedData,
2856
2848
  expiresInSeconds: params.ttlSeconds,
2857
2849
  isSponsored: !!paymasterFields
2858
2850
  };
@@ -3313,6 +3305,7 @@ var IssuerApiAdapter = class {
3313
3305
  import { isAddress } from "viem";
3314
3306
  import { PAFI_SUBGRAPH_URL } from "@pafi-dev/core";
3315
3307
  var DEFAULT_CACHE_TTL_MS = 3e4;
3308
+ var MAX_REASONABLE_FEE_TIER = 1e6;
3316
3309
  var POOL_QUERY = `
3317
3310
  query GetPoolForPointToken($id: ID!) {
3318
3311
  pafiToken(id: $id) {
@@ -3320,8 +3313,6 @@ var POOL_QUERY = `
3320
3313
  pool {
3321
3314
  id
3322
3315
  feeTier
3323
- tickSpacing
3324
- hooks
3325
3316
  token0 { id }
3326
3317
  token1 { id }
3327
3318
  }
@@ -3346,12 +3337,20 @@ function createSubgraphPoolsProvider(config = {}) {
3346
3337
  const cacheTtl = config.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;
3347
3338
  const fetchImpl = config.fetchImpl ?? globalThis.fetch;
3348
3339
  const now = config.now ?? (() => Date.now());
3340
+ const onError = config.onError;
3349
3341
  const cache = /* @__PURE__ */ new Map();
3350
3342
  if (!fetchImpl) {
3351
3343
  throw new Error(
3352
3344
  "createSubgraphPoolsProvider: no fetch implementation available \u2014 pass `fetchImpl` or run on Node 18+"
3353
3345
  );
3354
3346
  }
3347
+ const reportError = (err) => {
3348
+ if (!onError) return;
3349
+ try {
3350
+ onError(err);
3351
+ } catch {
3352
+ }
3353
+ };
3355
3354
  return async (request) => {
3356
3355
  const cacheKey = `${request.chainId}:${request.pointTokenAddress.toLowerCase()}`;
3357
3356
  if (cacheTtl > 0) {
@@ -3363,7 +3362,8 @@ function createSubgraphPoolsProvider(config = {}) {
3363
3362
  const pools = await fetchPoolsFromSubgraph(
3364
3363
  fetchImpl,
3365
3364
  subgraphUrl,
3366
- request.pointTokenAddress
3365
+ request.pointTokenAddress,
3366
+ reportError
3367
3367
  );
3368
3368
  if (cacheTtl > 0) {
3369
3369
  cache.set(cacheKey, {
@@ -3374,7 +3374,7 @@ function createSubgraphPoolsProvider(config = {}) {
3374
3374
  return { pools };
3375
3375
  };
3376
3376
  }
3377
- async function fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, pointTokenAddress) {
3377
+ async function fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, pointTokenAddress, reportError) {
3378
3378
  let response;
3379
3379
  try {
3380
3380
  response = await fetchImpl(subgraphUrl, {
@@ -3386,24 +3386,38 @@ async function fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, pointTokenAddress)
3386
3386
  })
3387
3387
  });
3388
3388
  } catch (err) {
3389
+ const error = err instanceof Error ? err : new Error(String(err));
3389
3390
  console.warn(
3390
3391
  "[subgraphPoolsProvider] subgraph unreachable:",
3391
- err.message
3392
+ error.message
3392
3393
  );
3394
+ reportError(error);
3393
3395
  return [];
3394
3396
  }
3395
3397
  if (!response.ok) {
3396
- console.warn(
3397
- `[subgraphPoolsProvider] subgraph returned ${response.status}`
3398
+ const error = new Error(
3399
+ `subgraph returned HTTP ${response.status}`
3398
3400
  );
3401
+ console.warn(`[subgraphPoolsProvider] ${error.message}`);
3402
+ reportError(error);
3399
3403
  return [];
3400
3404
  }
3401
- const json = await response.json();
3402
- if (json.errors && json.errors.length > 0) {
3405
+ let json;
3406
+ try {
3407
+ json = await response.json();
3408
+ } catch (err) {
3409
+ const error = err instanceof Error ? err : new Error(String(err));
3403
3410
  console.warn(
3404
- "[subgraphPoolsProvider] subgraph errors:",
3405
- json.errors.map((e) => e.message).join("; ")
3411
+ "[subgraphPoolsProvider] subgraph returned non-JSON:",
3412
+ error.message
3406
3413
  );
3414
+ reportError(error);
3415
+ return [];
3416
+ }
3417
+ if (json.errors && json.errors.length > 0) {
3418
+ const msg = json.errors.map((e) => e.message).join("; ");
3419
+ console.warn("[subgraphPoolsProvider] subgraph errors:", msg);
3420
+ reportError(new Error(`subgraph GraphQL errors: ${msg}`));
3407
3421
  return [];
3408
3422
  }
3409
3423
  const token = json.data?.pafiToken;
@@ -3411,40 +3425,35 @@ async function fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, pointTokenAddress)
3411
3425
  return [];
3412
3426
  }
3413
3427
  const { pool } = token;
3414
- if (!isAddress(pool.hooks)) {
3415
- console.error(
3416
- "[PAFI] SubgraphPoolsProvider: invalid hooks address in response:",
3417
- pool.hooks,
3418
- "\u2014 skipping pool"
3419
- );
3420
- return [];
3421
- }
3422
3428
  if (!isAddress(pool.token0.id) || !isAddress(pool.token1.id)) {
3423
- console.error(
3424
- "[PAFI] SubgraphPoolsProvider: invalid token address in response \u2014 skipping pool"
3429
+ const error = new Error(
3430
+ "[PAFI] SubgraphPoolsProvider: invalid token address in response"
3425
3431
  );
3432
+ console.error(error.message, "\u2014 skipping pool");
3433
+ reportError(error);
3426
3434
  return [];
3427
3435
  }
3428
- if (!Number.isFinite(Number(pool.feeTier)) || !Number.isFinite(Number(pool.tickSpacing))) {
3429
- console.error(
3430
- "[PAFI] SubgraphPoolsProvider: invalid feeTier/tickSpacing \u2014 skipping pool"
3436
+ const feeNum = Number(pool.feeTier);
3437
+ if (!Number.isInteger(feeNum) || feeNum < 0 || feeNum >= MAX_REASONABLE_FEE_TIER) {
3438
+ const error = new Error(
3439
+ `[PAFI] SubgraphPoolsProvider: invalid feeTier value: ${pool.feeTier}`
3431
3440
  );
3441
+ console.error(error.message, "\u2014 skipping pool");
3442
+ reportError(error);
3432
3443
  return [];
3433
3444
  }
3434
- const [currency0, currency1] = sortCurrencies(
3445
+ const [token0, token1] = sortTokens(
3435
3446
  pool.token0.id,
3436
3447
  pool.token1.id
3437
3448
  );
3438
3449
  const poolKey = {
3439
- currency0,
3440
- currency1,
3441
- fee: Number(pool.feeTier),
3442
- tickSpacing: Number(pool.tickSpacing),
3443
- hooks: pool.hooks
3450
+ token0,
3451
+ token1,
3452
+ fee: feeNum
3444
3453
  };
3445
3454
  return [poolKey];
3446
3455
  }
3447
- function sortCurrencies(a, b) {
3456
+ function sortTokens(a, b) {
3448
3457
  return a.toLowerCase() < b.toLowerCase() ? [a, b] : [b, a];
3449
3458
  }
3450
3459
 
@@ -3672,52 +3681,6 @@ function parseBigDecimalTo18(s) {
3672
3681
  return BigInt(whole + padded);
3673
3682
  }
3674
3683
 
3675
- // src/balance/balanceAggregator.ts
3676
- import { getPointTokenBalance as getPointTokenBalance3 } from "@pafi-dev/core";
3677
- var BalanceAggregator = class {
3678
- provider;
3679
- ledger;
3680
- constructor(config) {
3681
- if (!config.provider) {
3682
- throw new Error("BalanceAggregator: provider is required");
3683
- }
3684
- if (!config.ledger) {
3685
- throw new Error("BalanceAggregator: ledger is required");
3686
- }
3687
- this.provider = config.provider;
3688
- this.ledger = config.ledger;
3689
- }
3690
- /**
3691
- * Combined balance for a single (user, token) pair. Fetches off-chain
3692
- * + on-chain in parallel.
3693
- */
3694
- async getCombinedBalance(user, pointToken) {
3695
- const [offChain, onChain] = await Promise.all([
3696
- this.ledger.getBalance(user, pointToken),
3697
- getPointTokenBalance3(this.provider, pointToken, user)
3698
- ]);
3699
- return {
3700
- offChain,
3701
- onChain,
3702
- total: offChain + onChain
3703
- };
3704
- }
3705
- /**
3706
- * Combined balance for multiple tokens owned by the same user. Runs
3707
- * all lookups in parallel. Returns a Map keyed by the token address
3708
- * (same casing as supplied — caller should normalize if needed).
3709
- */
3710
- async getCombinedBalanceMulti(user, pointTokens) {
3711
- const entries = await Promise.all(
3712
- pointTokens.map(async (token) => {
3713
- const balance = await this.getCombinedBalance(user, token);
3714
- return [token, balance];
3715
- })
3716
- );
3717
- return new Map(entries);
3718
- }
3719
- };
3720
-
3721
3684
  // src/pafi-backend/client.ts
3722
3685
  import { getPafiServiceUrls } from "@pafi-dev/core";
3723
3686
  function extractPafiErrorFields(json, status) {
@@ -4284,14 +4247,12 @@ function createIssuerService(config) {
4284
4247
  }
4285
4248
  indexers.set(tokenAddress, new PointIndexer(indexerConfig));
4286
4249
  }
4287
- const firstIndexer = indexers.get(tokenAddresses[0]);
4288
4250
  const chainAddresses = getContractAddresses7(config.chainId);
4289
4251
  const resolvedContracts = {
4290
4252
  batchExecutor: chainAddresses.batchExecutor,
4291
4253
  usdt: chainAddresses.usdt,
4292
4254
  issuerRegistry: chainAddresses.issuerRegistry,
4293
4255
  mintingOracle: chainAddresses.mintingOracle,
4294
- pafiHook: chainAddresses.pafiHook,
4295
4256
  ...config.contracts
4296
4257
  };
4297
4258
  if (resolvedWrapperAddress !== void 0) {
@@ -4344,7 +4305,6 @@ function createIssuerService(config) {
4344
4305
  relay: relayService,
4345
4306
  fee: feeManager,
4346
4307
  indexers,
4347
- indexer: firstIndexer,
4348
4308
  api: handlers,
4349
4309
  redemption
4350
4310
  };
@@ -4557,12 +4517,11 @@ var MemoryRedemptionHistoryStore = class {
4557
4517
  };
4558
4518
 
4559
4519
  // src/index.ts
4560
- var PAFI_ISSUER_SDK_VERSION = true ? "0.13.0" : "dev";
4520
+ var PAFI_ISSUER_SDK_VERSION = true ? "0.15.0" : "dev";
4561
4521
  export {
4562
4522
  AdapterMisconfiguredError,
4563
4523
  AuthError,
4564
4524
  AuthService,
4565
- BalanceAggregator,
4566
4525
  BundlerNotConfiguredError,
4567
4526
  BundlerRejectedError,
4568
4527
  BurnIndexer,
@@ -4604,6 +4563,7 @@ export {
4604
4563
  SDK_ERROR_HTTP_STATUS_CODE,
4605
4564
  SettlementClient,
4606
4565
  ValidationError,
4566
+ applyPaymasterGasEstimates,
4607
4567
  authenticateRequest,
4608
4568
  buildErrorEnvelope,
4609
4569
  buildSdkErrorBody,