@pafi-dev/issuer 0.22.1 → 0.24.1

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
@@ -26,6 +26,7 @@ __export(index_exports, {
26
26
  BundlerNotConfiguredError: () => BundlerNotConfiguredError,
27
27
  BundlerRejectedError: () => BundlerRejectedError,
28
28
  BurnIndexer: () => BurnIndexer,
29
+ BurnIndexerFinalizeError: () => BurnIndexerFinalizeError,
29
30
  ConfigurationError: () => ConfigurationError,
30
31
  DEFAULT_REDEMPTION_POLICY: () => DEFAULT_REDEMPTION_POLICY,
31
32
  DefaultPolicyEngine: () => DefaultPolicyEngine,
@@ -57,6 +58,7 @@ __export(index_exports, {
57
58
  PerpDepositError: () => PerpDepositError,
58
59
  PerpDepositHandler: () => PerpDepositHandler,
59
60
  PointIndexer: () => PointIndexer,
61
+ PointIndexerFinalizeError: () => PointIndexerFinalizeError,
60
62
  PointTokenDomainResolver: () => PointTokenDomainResolver,
61
63
  PolicyProvider: () => PolicyProvider,
62
64
  REDEMPTION_HISTORY_WINDOW_SEC: () => REDEMPTION_HISTORY_WINDOW_SEC,
@@ -908,6 +910,7 @@ var RelayService = class {
908
910
  "prepareMint: deadline exceeds maximum allowed window (1 hour)"
909
911
  );
910
912
  }
913
+ const MINT_SOURCE = import_core5.Source.EQUITY;
911
914
  const useWrapper = params.mintFeeWrapperAddress !== void 0;
912
915
  const receiverForSig = useWrapper ? params.mintFeeWrapperAddress : params.userAddress;
913
916
  let minterSig;
@@ -919,6 +922,7 @@ var RelayService = class {
919
922
  user: params.userAddress,
920
923
  receiver: receiverForSig,
921
924
  amount: params.amount,
925
+ source: MINT_SOURCE,
922
926
  nonce: params.mintRequestNonce,
923
927
  deadline: params.deadline
924
928
  }
@@ -949,9 +953,15 @@ var RelayService = class {
949
953
  mintTarget = params.mintFeeWrapperAddress;
950
954
  } else {
951
955
  mintCallData = (0, import_viem3.encodeFunctionData)({
952
- abi: import_core5.POINT_TOKEN_ABI,
956
+ abi: import_core5.POINT_TOKEN_MINT_SIG_ABI,
953
957
  functionName: "mint",
954
- args: [params.userAddress, params.amount, params.deadline, minterSig]
958
+ args: [
959
+ params.userAddress,
960
+ params.amount,
961
+ MINT_SOURCE,
962
+ params.deadline,
963
+ minterSig
964
+ ]
955
965
  });
956
966
  mintTarget = params.pointTokenAddress;
957
967
  }
@@ -1036,11 +1046,12 @@ var RelayService = class {
1036
1046
  let burnCallData;
1037
1047
  try {
1038
1048
  burnCallData = (0, import_viem3.encodeFunctionData)({
1039
- abi: import_core5.POINT_TOKEN_ABI,
1049
+ abi: import_core5.POINT_TOKEN_BURN_SIG_ABI,
1040
1050
  functionName: "burn",
1041
1051
  args: [
1042
1052
  params.burnRequest.from,
1043
1053
  params.burnRequest.amount,
1054
+ params.burnRequest.source,
1044
1055
  params.burnRequest.deadline,
1045
1056
  params.burnerSignature
1046
1057
  ]
@@ -1135,11 +1146,12 @@ var RelayService = class {
1135
1146
  mintTarget = params.mintFeeWrapperAddress;
1136
1147
  } else {
1137
1148
  mintCallData = (0, import_viem3.encodeFunctionData)({
1138
- abi: import_core5.POINT_TOKEN_ABI,
1149
+ abi: import_core5.POINT_TOKEN_MINT_SIG_ABI,
1139
1150
  functionName: "mint",
1140
1151
  args: [
1141
1152
  params.userAddress,
1142
1153
  params.amount,
1154
+ import_core5.Source.EQUITY,
1143
1155
  params.deadline,
1144
1156
  PLACEHOLDER_SIG_65
1145
1157
  ]
@@ -1161,11 +1173,12 @@ var RelayService = class {
1161
1173
  /** Burn-side mirror of `previewMintUserOp`. */
1162
1174
  previewBurnUserOp(params) {
1163
1175
  const burnCallData = (0, import_viem3.encodeFunctionData)({
1164
- abi: import_core5.POINT_TOKEN_ABI,
1176
+ abi: import_core5.POINT_TOKEN_BURN_SIG_ABI,
1165
1177
  functionName: "burn",
1166
1178
  args: [
1167
1179
  params.userAddress,
1168
1180
  params.amount,
1181
+ import_core5.Source.EQUITY,
1169
1182
  params.deadline,
1170
1183
  PLACEHOLDER_SIG_65
1171
1184
  ]
@@ -1357,18 +1370,42 @@ function createPafiEstimatorClient(config) {
1357
1370
  }
1358
1371
 
1359
1372
  // src/indexer/types.ts
1360
- var InMemoryCursorStore = class {
1373
+ var InMemoryCursorStore = class _InMemoryCursorStore {
1361
1374
  cursor;
1375
+ /**
1376
+ * Child stores keyed by `forKey()`. Each child has its own cursor
1377
+ * (the H-05 fix), so a single InMemoryCursorStore can back N
1378
+ * PointIndexers in tests / single-process callers.
1379
+ */
1380
+ children = /* @__PURE__ */ new Map();
1362
1381
  async load() {
1363
1382
  return this.cursor;
1364
1383
  }
1365
1384
  async save(blockNumber) {
1366
1385
  this.cursor = blockNumber;
1367
1386
  }
1387
+ forKey(key) {
1388
+ let child = this.children.get(key);
1389
+ if (!child) {
1390
+ child = new _InMemoryCursorStore();
1391
+ this.children.set(key, child);
1392
+ }
1393
+ return child;
1394
+ }
1368
1395
  };
1369
1396
 
1370
1397
  // src/indexer/pointIndexer.ts
1371
1398
  var import_viem4 = require("viem");
1399
+ var PointIndexerFinalizeError = class extends Error {
1400
+ constructor(message, context, cause) {
1401
+ super(message);
1402
+ this.context = context;
1403
+ this.cause = cause;
1404
+ this.name = "PointIndexerFinalizeError";
1405
+ }
1406
+ context;
1407
+ cause;
1408
+ };
1372
1409
  var TRANSFER_EVENT = (0, import_viem4.parseAbiItem)(
1373
1410
  "event Transfer(address indexed from, address indexed to, uint256 value)"
1374
1411
  );
@@ -1594,8 +1631,18 @@ var PointIndexer = class {
1594
1631
  evt.txHash,
1595
1632
  this.pointTokenAddress
1596
1633
  );
1597
- } catch {
1598
- return;
1634
+ } catch (err) {
1635
+ throw new PointIndexerFinalizeError(
1636
+ `PointIndexer.deductBalance failed for tx ${evt.txHash} (to=${evt.to}, amount=${evt.amount}, block=${evt.blockNumber}); cursor will NOT advance, next tick retries.`,
1637
+ {
1638
+ pointToken: this.pointTokenAddress,
1639
+ to: evt.to,
1640
+ amount: evt.amount,
1641
+ txHash: evt.txHash,
1642
+ blockNumber: evt.blockNumber
1643
+ },
1644
+ err
1645
+ );
1599
1646
  }
1600
1647
  try {
1601
1648
  await this.ledger.updateMintStatus(match.lockId, "MINTED", evt.txHash);
@@ -1617,6 +1664,16 @@ function pickMatchingLock(locks, amount) {
1617
1664
 
1618
1665
  // src/indexer/burnIndexer.ts
1619
1666
  var import_viem5 = require("viem");
1667
+ var BurnIndexerFinalizeError = class extends Error {
1668
+ constructor(message, context, cause) {
1669
+ super(message);
1670
+ this.context = context;
1671
+ this.cause = cause;
1672
+ this.name = "BurnIndexerFinalizeError";
1673
+ }
1674
+ context;
1675
+ cause;
1676
+ };
1620
1677
  var TRANSFER_EVENT2 = (0, import_viem5.parseAbiItem)(
1621
1678
  "event Transfer(address indexed from, address indexed to, uint256 value)"
1622
1679
  );
@@ -1628,7 +1685,7 @@ var BurnIndexer = class {
1628
1685
  provider;
1629
1686
  /**
1630
1687
  * The PointToken this indexer watches. Exposed so callers can key
1631
- * leader-election locks / cursor stores by token (audit H-04 fix).
1688
+ * leader-election locks / cursor stores by token
1632
1689
  */
1633
1690
  pointTokenAddress;
1634
1691
  ledger;
@@ -1784,7 +1841,18 @@ var BurnIndexer = class {
1784
1841
  try {
1785
1842
  await this.ledger.resolveCreditByBurnTx(lockId, evt.txHash);
1786
1843
  } catch (err) {
1787
- console.error("[PAFI] BurnIndexer finalize error \u2014 credit may be lost:", err);
1844
+ throw new BurnIndexerFinalizeError(
1845
+ `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.`,
1846
+ {
1847
+ pointToken: this.pointTokenAddress,
1848
+ from: evt.from,
1849
+ amount: evt.amount,
1850
+ txHash: evt.txHash,
1851
+ blockNumber: evt.blockNumber,
1852
+ lockId
1853
+ },
1854
+ err
1855
+ );
1788
1856
  }
1789
1857
  }
1790
1858
  };
@@ -2426,10 +2494,12 @@ var PTRedeemHandler = class {
2426
2494
  chainId: this.chainId,
2427
2495
  verifyingContract: pointTokenAddress
2428
2496
  };
2497
+ const BURN_SOURCE = import_core7.Source.EQUITY;
2429
2498
  const sponsoredBurnAmount = request.amount - fee;
2430
2499
  const sponsoredBurnRequest = {
2431
2500
  from: request.userAddress,
2432
2501
  amount: sponsoredBurnAmount,
2502
+ source: BURN_SOURCE,
2433
2503
  nonce: burnNonce,
2434
2504
  deadline
2435
2505
  };
@@ -2465,6 +2535,7 @@ var PTRedeemHandler = class {
2465
2535
  const fallbackBurnRequest = {
2466
2536
  from: request.userAddress,
2467
2537
  amount: request.amount,
2538
+ source: BURN_SOURCE,
2468
2539
  nonce: burnNonce,
2469
2540
  deadline
2470
2541
  };
@@ -4757,6 +4828,13 @@ async function createIssuerService(config) {
4757
4828
  const sdkWrapperAddress = (0, import_core18.getContractAddresses)(config.chainId).mintFeeWrapper;
4758
4829
  const wrapperOverride = config.indexer?.mintFeeWrapperAddress;
4759
4830
  const resolvedWrapperAddress = wrapperOverride !== void 0 ? wrapperOverride : sdkWrapperAddress;
4831
+ const baseCursorStore = config.indexer?.cursorStore;
4832
+ const sharedCursorWithMultipleTokens = baseCursorStore !== void 0 && typeof baseCursorStore.forKey !== "function" && tokenAddresses.length > 1;
4833
+ if (sharedCursorWithMultipleTokens) {
4834
+ console.warn(
4835
+ `[@pafi-dev/issuer] cursorStore lacks forKey() and ${tokenAddresses.length} PointTokens are configured. All PointIndexers will share one cursor row, causing token-skipping (audit finding H-05). Implement IIndexerCursorStore.forKey to return per-token derived stores. This permissive path will be removed in a future major release.`
4836
+ );
4837
+ }
4760
4838
  const indexers = /* @__PURE__ */ new Map();
4761
4839
  for (const tokenAddress of tokenAddresses) {
4762
4840
  const indexerConfig = {
@@ -4770,8 +4848,10 @@ async function createIssuerService(config) {
4770
4848
  if (config.indexer?.fromBlock !== void 0) {
4771
4849
  indexerConfig.fromBlock = config.indexer.fromBlock;
4772
4850
  }
4773
- if (config.indexer?.cursorStore) {
4774
- indexerConfig.cursorStore = config.indexer.cursorStore;
4851
+ if (baseCursorStore) {
4852
+ indexerConfig.cursorStore = typeof baseCursorStore.forKey === "function" ? baseCursorStore.forKey(
4853
+ `point-indexer:${tokenAddress.toLowerCase()}`
4854
+ ) : baseCursorStore;
4775
4855
  }
4776
4856
  if (config.indexer?.confirmations !== void 0) {
4777
4857
  indexerConfig.confirmations = config.indexer.confirmations;
@@ -4967,22 +5047,22 @@ var IssuerStateValidator = class _IssuerStateValidator {
4967
5047
  }
4968
5048
  throw err;
4969
5049
  }
4970
- const { issuer, totalSupply, hardCap, remaining } = state;
5050
+ const { issuer, equityCap, equitySupply, remaining } = state;
4971
5051
  if (!issuer.active) {
4972
5052
  throw new IssuerStateError(
4973
5053
  "ISSUER_INACTIVE",
4974
- `Issuer ${issuer.issuerAddress} is deactivated on IssuerRegistry`,
4975
- { issuer: issuer.issuerAddress, pointToken: issuer.pointToken }
5054
+ `Issuer "${issuer.name}" is deactivated on IssuerRegistry`,
5055
+ { pointToken }
4976
5056
  );
4977
5057
  }
4978
- if (totalSupply + amount > hardCap) {
5058
+ if (equitySupply + amount > equityCap.hardCap) {
4979
5059
  throw new IssuerStateError(
4980
5060
  "MINT_CAP_EXCEEDED",
4981
- `Requested ${amount} PT would exceed mint cap. Cap=${hardCap}, minted=${totalSupply}, remaining=${remaining}`,
5061
+ `Requested ${amount} PT would exceed EQUITY mint cap. Cap=${equityCap.hardCap}, equityMinted=${equitySupply}, remaining=${remaining}`,
4982
5062
  {
4983
5063
  requested: amount.toString(),
4984
- cap: hardCap.toString(),
4985
- minted: totalSupply.toString(),
5064
+ cap: equityCap.hardCap.toString(),
5065
+ equityMinted: equitySupply.toString(),
4986
5066
  remaining: remaining.toString()
4987
5067
  }
4988
5068
  );
@@ -4998,33 +5078,28 @@ var IssuerStateValidator = class _IssuerStateValidator {
4998
5078
  args: [issuerAddr]
4999
5079
  });
5000
5080
  const issuer = {
5001
- issuerAddress: issuerStruct.issuerAddress,
5002
5081
  signerAddress: issuerStruct.signerAddress,
5003
5082
  name: issuerStruct.name,
5004
- symbol: issuerStruct.symbol,
5005
5083
  active: issuerStruct.active,
5006
- pointToken: issuerStruct.pointToken,
5007
- mintingOracle: issuerStruct.mintingOracle
5084
+ capitalBase: issuerStruct.capitalBase,
5085
+ basisPoints: Number(issuerStruct.basisPoints)
5008
5086
  };
5009
- const [tokenCap, totalSupply] = await Promise.all([
5010
- (0, import_core19.getTokenCap)(this.provider, issuer.mintingOracle, tokenAddr),
5011
- this.provider.readContract({
5012
- address: tokenAddr,
5013
- abi: import_core19.POINT_TOKEN_ABI,
5014
- functionName: "totalSupply"
5015
- })
5016
- ]);
5017
- const tokenCapRecord = {
5018
- declaredTotalSupply: tokenCap.declaredTotalSupply,
5019
- capBasisPoints: tokenCap.capBasisPoints
5087
+ const equitySupply = await this.provider.readContract({
5088
+ address: tokenAddr,
5089
+ abi: import_core19.POINT_TOKEN_ABI,
5090
+ functionName: "equitySupply"
5091
+ });
5092
+ const hardCap = issuer.capitalBase * BigInt(issuer.basisPoints) / 10000n;
5093
+ const equityCap = {
5094
+ capitalBase: issuer.capitalBase,
5095
+ basisPoints: issuer.basisPoints,
5096
+ hardCap
5020
5097
  };
5021
- const hardCap = tokenCapRecord.declaredTotalSupply * BigInt(tokenCapRecord.capBasisPoints) / 10000n;
5022
- const remaining = hardCap > totalSupply ? hardCap - totalSupply : 0n;
5098
+ const remaining = hardCap > equitySupply ? hardCap - equitySupply : 0n;
5023
5099
  return {
5024
5100
  issuer,
5025
- tokenCap: tokenCapRecord,
5026
- totalSupply,
5027
- hardCap,
5101
+ equityCap,
5102
+ equitySupply,
5028
5103
  remaining
5029
5104
  };
5030
5105
  }
@@ -5067,7 +5142,7 @@ var MemoryRedemptionHistoryStore = class {
5067
5142
  };
5068
5143
 
5069
5144
  // src/index.ts
5070
- var PAFI_ISSUER_SDK_VERSION = true ? "0.22.1" : "dev";
5145
+ var PAFI_ISSUER_SDK_VERSION = true ? "0.24.1" : "dev";
5071
5146
  // Annotate the CommonJS export names for ESM import in node:
5072
5147
  0 && (module.exports = {
5073
5148
  AdapterMisconfiguredError,
@@ -5076,6 +5151,7 @@ var PAFI_ISSUER_SDK_VERSION = true ? "0.22.1" : "dev";
5076
5151
  BundlerNotConfiguredError,
5077
5152
  BundlerRejectedError,
5078
5153
  BurnIndexer,
5154
+ BurnIndexerFinalizeError,
5079
5155
  ConfigurationError,
5080
5156
  DEFAULT_REDEMPTION_POLICY,
5081
5157
  DefaultPolicyEngine,
@@ -5107,6 +5183,7 @@ var PAFI_ISSUER_SDK_VERSION = true ? "0.22.1" : "dev";
5107
5183
  PerpDepositError,
5108
5184
  PerpDepositHandler,
5109
5185
  PointIndexer,
5186
+ PointIndexerFinalizeError,
5110
5187
  PointTokenDomainResolver,
5111
5188
  PolicyProvider,
5112
5189
  REDEMPTION_HISTORY_WINDOW_SEC,