@pafi-dev/issuer 0.30.0 → 0.32.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
@@ -2414,11 +2414,23 @@ var PTRedeemHandler = class {
2414
2414
  );
2415
2415
  }
2416
2416
  if (this.redemptionService) {
2417
- const decision = await this.redemptionService.evaluate(
2418
- request.userAddress,
2419
- request.amount,
2420
- pointTokenAddress
2421
- );
2417
+ let decision;
2418
+ try {
2419
+ decision = await this.redemptionService.evaluate(
2420
+ request.userAddress,
2421
+ request.amount,
2422
+ pointTokenAddress
2423
+ );
2424
+ } catch (err) {
2425
+ const code = err && typeof err === "object" && "code" in err ? err.code : void 0;
2426
+ if (code === "POLICY_PROVIDER_UNAVAILABLE") {
2427
+ throw new PTRedeemError(
2428
+ "REDEMPTION_POLICY_UNAVAILABLE",
2429
+ "Redemption policy temporarily unavailable \u2014 please try again shortly."
2430
+ );
2431
+ }
2432
+ throw err;
2433
+ }
2422
2434
  if (!decision.allowed) {
2423
2435
  const denial = decision.denial;
2424
2436
  throw new PTRedeemError(
@@ -2903,7 +2915,10 @@ async function prepareMobileUserOp(params) {
2903
2915
  callGasLimit: fallback.userOp.callGasLimit.toString(),
2904
2916
  verificationGasLimit: fallback.userOp.verificationGasLimit.toString(),
2905
2917
  preVerificationGas: fallback.userOp.preVerificationGas.toString(),
2906
- userOpHash: fallback.userOpHash
2918
+ userOpHash: fallback.userOpHash,
2919
+ // Audit PACI5-21 — carry the fallback-specific lockId so submit
2920
+ // can bind the fallback userOpHash to the correct ledger row.
2921
+ lockId: params.lockIdFallback
2907
2922
  };
2908
2923
  }
2909
2924
  const entry = {
@@ -3096,6 +3111,7 @@ async function handleMobilePrepare(params) {
3096
3111
  lockId: params.lockId,
3097
3112
  partialUserOp: sponsoredOp,
3098
3113
  partialUserOpFallback: params.partialUserOpFallback,
3114
+ lockIdFallback: params.lockIdFallback,
3099
3115
  paymasterFields,
3100
3116
  chainId: params.chainId,
3101
3117
  store: params.store,
@@ -3124,7 +3140,8 @@ async function handleMobileSubmit(params) {
3124
3140
  entryPoint: params.entryPoint ?? import_core10.ENTRY_POINT_V08,
3125
3141
  eip7702Auth: entry.eip7702Auth
3126
3142
  });
3127
- await params.bindUserOpHash(params.lockId, result.userOpHash);
3143
+ const targetLockId = variant === "fallback" && entry.fallback?.lockId ? entry.fallback.lockId : params.lockId;
3144
+ await params.bindUserOpHash(targetLockId, result.userOpHash);
3128
3145
  await params.store.delete(params.lockId);
3129
3146
  return { userOpHash: result.userOpHash };
3130
3147
  }
@@ -3866,10 +3883,12 @@ var IssuerApiAdapter = class {
3866
3883
  "burn",
3867
3884
  pointTokenAddress,
3868
3885
  redeemResponse.expiresInSeconds,
3869
- input.eip7702Auth
3886
+ input.eip7702Auth,
3887
+ redeemResponse.fallback?.lockId
3870
3888
  );
3871
3889
  return {
3872
3890
  lockId: redeemResponse.lockId,
3891
+ lockIdFallback: redeemResponse.fallback?.lockId,
3873
3892
  userOpHash: prepared.sponsored.userOpHash,
3874
3893
  typedData: prepared.sponsored.typedData,
3875
3894
  userOpHashFallback: prepared.fallback?.userOpHash,
@@ -4000,13 +4019,14 @@ var IssuerApiAdapter = class {
4000
4019
  issuerSignerWallet: this.cfg.issuerSignerWallet
4001
4020
  });
4002
4021
  }
4003
- async runMobilePrepare(authenticatedAddress, chainId, lockId, partialUserOp, partialUserOpFallback, scenario, pointTokenAddress, ttlSeconds, eip7702Auth) {
4022
+ async runMobilePrepare(authenticatedAddress, chainId, lockId, partialUserOp, partialUserOpFallback, scenario, pointTokenAddress, ttlSeconds, eip7702Auth, lockIdFallback) {
4004
4023
  return await handleMobilePrepare({
4005
4024
  userAddress: authenticatedAddress,
4006
4025
  chainId,
4007
4026
  lockId,
4008
4027
  partialUserOp,
4009
4028
  partialUserOpFallback,
4029
+ lockIdFallback,
4010
4030
  scenario,
4011
4031
  pointTokenAddress,
4012
4032
  ttlSeconds,
@@ -4442,7 +4462,9 @@ var PafiBackendClient = class {
4442
4462
  if (!config.issuerId) throw new Error("PafiBackendClient: issuerId is required");
4443
4463
  if (!config.apiKey) throw new Error("PafiBackendClient: apiKey is required");
4444
4464
  this.config = config;
4445
- this.baseUrl = (0, import_core16.getPafiServiceUrls)(config.chainId).sponsorRelayer;
4465
+ this.baseUrl = (0, import_core16.getPafiServiceUrls)(config.chainId, {
4466
+ sponsorRelayer: config.baseUrl
4467
+ }).sponsorRelayer;
4446
4468
  }
4447
4469
  async requestSponsorship(request) {
4448
4470
  const maxAttempts = this.config.retry?.maxAttempts ?? 1;
@@ -4603,7 +4625,7 @@ var PafiBackendClient = class {
4603
4625
 
4604
4626
  // src/config.ts
4605
4627
  var import_viem15 = require("viem");
4606
- var import_core18 = require("@pafi-dev/core");
4628
+ var import_core19 = require("@pafi-dev/core");
4607
4629
 
4608
4630
  // src/redemption/evaluator.ts
4609
4631
  var SECONDS_PER_DAY = 24 * 60 * 60;
@@ -4707,6 +4729,9 @@ function nextBlackoutEndAfter(windows, nowUnixSec) {
4707
4729
  }
4708
4730
  var REDEMPTION_HISTORY_WINDOW_SEC = SECONDS_PER_DAY;
4709
4731
 
4732
+ // src/redemption/policyProvider.ts
4733
+ var import_core18 = require("@pafi-dev/core");
4734
+
4710
4735
  // src/redemption/settlementClient.ts
4711
4736
  var import_core17 = require("@pafi-dev/core");
4712
4737
  var DEFAULT_TIMEOUT_MS = 1e3;
@@ -4717,7 +4742,12 @@ var SettlementClient = class {
4717
4742
  if (!config.issuerId) throw new Error("SettlementClient: issuerId is required");
4718
4743
  if (!config.apiKey) throw new Error("SettlementClient: apiKey is required");
4719
4744
  this.config = {
4720
- baseUrl: (0, import_core17.getPafiServiceUrls)(config.chainId).issuerApi.replace(/\/+$/, ""),
4745
+ // Audit PACI5-17 — honor optional baseUrl override wired from
4746
+ // an env var (e.g. PAFI_ISSUER_API_URL). Empty / undefined →
4747
+ // ship-default for chainId.
4748
+ baseUrl: (0, import_core17.getPafiServiceUrls)(config.chainId, {
4749
+ issuerApi: config.baseUrl
4750
+ }).issuerApi.replace(/\/+$/, ""),
4721
4751
  issuerId: config.issuerId,
4722
4752
  apiKey: config.apiKey,
4723
4753
  fetchTimeoutMs: config.fetchTimeoutMs ?? DEFAULT_TIMEOUT_MS,
@@ -4821,10 +4851,23 @@ function defaultPolicyFor(issuerId) {
4821
4851
 
4822
4852
  // src/redemption/policyProvider.ts
4823
4853
  var DEFAULT_CACHE_TTL_MS3 = 5 * 60 * 1e3;
4854
+ var PolicyProviderUnavailableError = class extends import_core18.PafiSdkError {
4855
+ code = "POLICY_PROVIDER_UNAVAILABLE";
4856
+ httpStatus = "service_unavailable";
4857
+ details;
4858
+ constructor(issuerId, reason) {
4859
+ super(
4860
+ `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.`
4861
+ );
4862
+ this.details = { issuerId, reason };
4863
+ }
4864
+ };
4824
4865
  var PolicyProvider = class {
4825
4866
  client;
4826
4867
  issuerId;
4827
4868
  cacheTtlMs;
4869
+ onFetchFailure;
4870
+ onWarning;
4828
4871
  now;
4829
4872
  cache = null;
4830
4873
  inflight = null;
@@ -4832,6 +4875,8 @@ var PolicyProvider = class {
4832
4875
  this.client = new SettlementClient(config);
4833
4876
  this.issuerId = config.issuerId;
4834
4877
  this.cacheTtlMs = config.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS3;
4878
+ this.onFetchFailure = config.onFetchFailure ?? "fail-closed";
4879
+ this.onWarning = config.onWarning;
4835
4880
  this.now = config.now ?? (() => Date.now());
4836
4881
  }
4837
4882
  async getPolicy() {
@@ -4864,7 +4909,19 @@ var PolicyProvider = class {
4864
4909
  };
4865
4910
  return { policy: result.policy, source: "settlement" };
4866
4911
  }
4867
- return { policy: defaultPolicyFor(this.issuerId), source: "default" };
4912
+ const reason = "reason" in result && typeof result.reason === "string" ? result.reason : "unknown";
4913
+ if (this.onFetchFailure === "permissive-default") {
4914
+ this.onWarning?.(
4915
+ "PolicyProvider: settlement-api unreachable, falling back to permissive default. Pre-flight redeem limit is DEGRADED until settlement-api recovers.",
4916
+ {
4917
+ event: "policy_provider_fallback",
4918
+ issuerId: this.issuerId,
4919
+ reason
4920
+ }
4921
+ );
4922
+ return { policy: defaultPolicyFor(this.issuerId), source: "default" };
4923
+ }
4924
+ throw new PolicyProviderUnavailableError(this.issuerId, reason);
4868
4925
  }
4869
4926
  };
4870
4927
 
@@ -4954,7 +5011,7 @@ async function createIssuerService(config) {
4954
5011
  provider: config.provider
4955
5012
  });
4956
5013
  }
4957
- const sdkWrapperAddress = (0, import_core18.getContractAddresses)(config.chainId).mintFeeWrapper;
5014
+ const sdkWrapperAddress = (0, import_core19.getContractAddresses)(config.chainId).mintFeeWrapper;
4958
5015
  const wrapperOverride = config.indexer?.mintFeeWrapperAddress;
4959
5016
  const resolvedWrapperAddress = wrapperOverride !== void 0 ? wrapperOverride : sdkWrapperAddress;
4960
5017
  const baseCursorStore = config.indexer?.cursorStore;
@@ -4993,7 +5050,7 @@ async function createIssuerService(config) {
4993
5050
  }
4994
5051
  indexers.set(tokenAddress, new PointIndexer(indexerConfig));
4995
5052
  }
4996
- const chainAddresses = (0, import_core18.getContractAddresses)(config.chainId);
5053
+ const chainAddresses = (0, import_core19.getContractAddresses)(config.chainId);
4997
5054
  const resolvedContracts = {
4998
5055
  batchExecutor: chainAddresses.batchExecutor,
4999
5056
  usdt: chainAddresses.usdt,
@@ -5011,6 +5068,15 @@ async function createIssuerService(config) {
5011
5068
  issuerId: config.redemption.issuerId,
5012
5069
  apiKey: config.redemption.apiKey
5013
5070
  };
5071
+ if (config.redemption.baseUrl) {
5072
+ policyConfig.baseUrl = config.redemption.baseUrl;
5073
+ }
5074
+ if (config.redemption.onFetchFailure) {
5075
+ policyConfig.onFetchFailure = config.redemption.onFetchFailure;
5076
+ }
5077
+ if (config.redemption.onPolicyWarning) {
5078
+ policyConfig.onWarning = config.redemption.onPolicyWarning;
5079
+ }
5014
5080
  if (config.redemption.fetchImpl) policyConfig.fetchImpl = config.redemption.fetchImpl;
5015
5081
  if (config.redemption.fetchTimeoutMs !== void 0) {
5016
5082
  policyConfig.fetchTimeoutMs = config.redemption.fetchTimeoutMs;
@@ -5076,7 +5142,7 @@ async function createIssuerService(config) {
5076
5142
 
5077
5143
  // src/issuer-state/validator.ts
5078
5144
  var import_viem16 = require("viem");
5079
- var import_core19 = require("@pafi-dev/core");
5145
+ var import_core20 = require("@pafi-dev/core");
5080
5146
  var ISSUER_RECORD_TTL_MS = 3e4;
5081
5147
  var IssuerStateValidator = class _IssuerStateValidator {
5082
5148
  constructor(provider, registryAddress) {
@@ -5093,7 +5159,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
5093
5159
  * `CONTRACT_ADDRESSES` map for the given chain.
5094
5160
  */
5095
5161
  static forChain(provider, chainId) {
5096
- const { issuerRegistry } = (0, import_core19.getContractAddresses)(chainId);
5162
+ const { issuerRegistry } = (0, import_core20.getContractAddresses)(chainId);
5097
5163
  return new _IssuerStateValidator(provider, issuerRegistry);
5098
5164
  }
5099
5165
  /**
@@ -5122,7 +5188,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
5122
5188
  if (cached) return cached;
5123
5189
  const issuer = await this.provider.readContract({
5124
5190
  address: key,
5125
- abi: import_core19.POINT_TOKEN_ABI,
5191
+ abi: import_core20.POINT_TOKEN_ABI,
5126
5192
  functionName: "issuer"
5127
5193
  });
5128
5194
  this.pointTokenIssuerCache.set(key, (0, import_viem16.getAddress)(issuer));
@@ -5202,7 +5268,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
5202
5268
  const issuerAddr = await this.getIssuerAddressForPointToken(tokenAddr);
5203
5269
  const issuerStruct = await this.provider.readContract({
5204
5270
  address: this.registryAddress,
5205
- abi: import_core19.issuerRegistryAbi,
5271
+ abi: import_core20.issuerRegistryAbi,
5206
5272
  functionName: "getIssuer",
5207
5273
  args: [issuerAddr]
5208
5274
  });
@@ -5215,7 +5281,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
5215
5281
  };
5216
5282
  const equitySupply = await this.provider.readContract({
5217
5283
  address: tokenAddr,
5218
- abi: import_core19.POINT_TOKEN_ABI,
5284
+ abi: import_core20.POINT_TOKEN_ABI,
5219
5285
  functionName: "equitySupply"
5220
5286
  });
5221
5287
  const hardCap = issuer.capitalBase * BigInt(issuer.basisPoints) / 10000n;
@@ -5271,7 +5337,7 @@ var MemoryRedemptionHistoryStore = class {
5271
5337
  };
5272
5338
 
5273
5339
  // src/index.ts
5274
- var PAFI_ISSUER_SDK_VERSION = true ? "0.30.0" : "dev";
5340
+ var PAFI_ISSUER_SDK_VERSION = true ? "0.32.0" : "dev";
5275
5341
  // Annotate the CommonJS export names for ESM import in node:
5276
5342
  0 && (module.exports = {
5277
5343
  AdapterMisconfiguredError,