@pafi-dev/issuer 0.3.0-beta.0 → 0.3.0-beta.10

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,13 +30,10 @@ __export(index_exports, {
30
30
  IssuerApiHandlers: () => IssuerApiHandlers,
31
31
  MemoryPointLedger: () => MemoryPointLedger,
32
32
  MemorySessionStore: () => MemorySessionStore,
33
- MintingGateway: () => MintingGateway,
34
- MintingGatewayError: () => MintingGatewayError,
35
33
  NonceManager: () => NonceManager,
36
34
  PAFI_ISSUER_SDK_VERSION: () => PAFI_ISSUER_SDK_VERSION,
37
35
  PTRedeemError: () => PTRedeemError,
38
36
  PTRedeemHandler: () => PTRedeemHandler,
39
- PafiBackendClient: () => PafiBackendClient,
40
37
  PafiBackendError: () => PafiBackendError,
41
38
  PointIndexer: () => PointIndexer,
42
39
  PrivateKeySigner: () => PrivateKeySigner,
@@ -47,8 +44,7 @@ __export(index_exports, {
47
44
  authenticateRequest: () => authenticateRequest,
48
45
  createIssuerService: () => createIssuerService,
49
46
  createSubgraphNativeUsdtQuoter: () => createSubgraphNativeUsdtQuoter,
50
- createSubgraphPoolsProvider: () => createSubgraphPoolsProvider,
51
- encodeExtData: () => import_core4.encodeExtData
47
+ createSubgraphPoolsProvider: () => createSubgraphPoolsProvider
52
48
  });
53
49
  module.exports = __toCommonJS(index_exports);
54
50
 
@@ -636,199 +632,94 @@ var RelayError = class extends Error {
636
632
  // src/relay/relayService.ts
637
633
  var import_viem5 = require("viem");
638
634
  var import_core3 = require("@pafi-dev/core");
639
- var DEFAULT_CONFIRMATION_TIMEOUT_MS = 6e4;
640
635
  var RelayService = class {
641
- relayAddress;
642
- operatorWallet;
643
- provider;
644
- confirmationTimeoutMs;
645
- simulateBeforeSubmit;
646
- constructor(config) {
647
- if (!config.relayAddress) {
648
- throw new Error("RelayService: relayAddress is required");
649
- }
650
- if (!config.operatorWallet) {
651
- throw new Error("RelayService: operatorWallet is required");
652
- }
653
- this.relayAddress = config.relayAddress;
654
- this.operatorWallet = config.operatorWallet;
655
- if (config.provider) this.provider = config.provider;
656
- this.confirmationTimeoutMs = config.confirmationTimeoutMs ?? DEFAULT_CONFIRMATION_TIMEOUT_MS;
657
- this.simulateBeforeSubmit = config.simulateBeforeSubmit ?? config.provider !== void 0;
658
- }
659
- /** Address the operator wallet is broadcasting from (for logging). */
660
- operatorAddress() {
661
- return this.operatorWallet.account?.address;
662
- }
663
636
  /**
664
- * Build calldata for the Relay `mintAndSwap` function. Kept public so
665
- * callers (e.g. the MintingGateway) can log or persist the encoded call
666
- * for audit before broadcasting.
637
+ * Build an unsigned UserOp for Scenario 1 (Mint) sig-gated
638
+ * `PointToken.mint(to, amount, deadline, minterSig)`.
667
639
  */
668
- encodeCall(params) {
669
- try {
670
- return (0, import_core3.encodeMintAndSwap)(params.mint, params.swap);
671
- } catch (err) {
640
+ async prepareMint(params) {
641
+ if (!params.batchExecutorAddress) {
672
642
  throw new RelayError(
673
643
  "ENCODE_FAILED",
674
- `Failed to encode mintAndSwap calldata: ${errorMessage(err)}`,
675
- err
644
+ "prepareMint: batchExecutorAddress required"
676
645
  );
677
646
  }
678
- }
679
- /**
680
- * Submit a `mintAndSwap` transaction. Flow:
681
- *
682
- * 1. (optional) pre-flight simulate via provider
683
- * 2. writeContract through the operator wallet
684
- * 3. (optional) wait for the receipt and surface gasUsed / status
685
- *
686
- * Throws a typed `RelayError` on any failure so the MintingGateway can
687
- * decide whether to release the ledger lock (`SUBMIT_FAILED` and
688
- * `SIMULATION_FAILED` are safe to release; `TX_REVERTED` and `TIMEOUT`
689
- * need manual review because the tx may still land).
690
- *
691
- * @deprecated Since 0.3.0 — will be replaced by `prepareMint()` +
692
- * `prepareBurn()` in the v1.4 sponsored-UserOp flow. The SC team
693
- * still needs to finalize Relayer v2 ABI before the replacements
694
- * can ship (blocker B1). Kept for v0.2.x consumers. Removed in 2.0.
695
- */
696
- async submitMintAndSwap(params) {
697
- if (this.simulateBeforeSubmit && this.provider) {
698
- const operatorAddr = this.operatorWallet.account?.address;
699
- if (operatorAddr) {
700
- try {
701
- await (0, import_core3.simulateMintAndSwap)(
702
- this.provider,
703
- this.relayAddress,
704
- params.mint,
705
- params.swap,
706
- operatorAddr
707
- );
708
- } catch (err) {
709
- const reason = err instanceof import_core3.SimulationError ? err.reason : errorMessage(err);
710
- throw new RelayError(
711
- "SIMULATION_FAILED",
712
- `mintAndSwap would revert: ${reason}`,
713
- err
714
- );
715
- }
716
- }
647
+ if (!params.userAddress) {
648
+ throw new RelayError("ENCODE_FAILED", "prepareMint: userAddress required");
717
649
  }
718
- let txHash;
719
- try {
720
- txHash = await this.operatorWallet.writeContract({
721
- address: this.relayAddress,
722
- abi: import_core3.relayAbi,
723
- functionName: "mintAndSwap",
724
- args: [params.mint, params.swap],
725
- ...this.operatorWallet.account ? { account: this.operatorWallet.account } : {}
726
- });
727
- } catch (err) {
650
+ if (!params.pointTokenAddress) {
728
651
  throw new RelayError(
729
- "SUBMIT_FAILED",
730
- `Failed to broadcast mintAndSwap: ${errorMessage(err)}`,
731
- err
652
+ "ENCODE_FAILED",
653
+ "prepareMint: pointTokenAddress required"
732
654
  );
733
655
  }
734
- if (!this.provider) {
735
- return { txHash };
656
+ if (params.amount <= 0n) {
657
+ throw new RelayError("ENCODE_FAILED", "prepareMint: amount must be positive");
736
658
  }
737
- try {
738
- const receipt = await this.provider.waitForTransactionReceipt({
739
- hash: txHash,
740
- timeout: this.confirmationTimeoutMs
741
- });
742
- if (receipt.status !== "success") {
743
- throw new RelayError(
744
- "TX_REVERTED",
745
- `mintAndSwap reverted on-chain (tx=${txHash})`
746
- );
747
- }
748
- return {
749
- txHash,
750
- blockNumber: receipt.blockNumber,
751
- gasUsed: receipt.gasUsed,
752
- status: receipt.status
753
- };
754
- } catch (err) {
755
- if (err instanceof RelayError) throw err;
659
+ if (!params.issuerSignerWallet) {
756
660
  throw new RelayError(
757
- "TIMEOUT",
758
- `Timed out waiting for mintAndSwap receipt (tx=${txHash}): ${errorMessage(err)}`,
759
- err
661
+ "ENCODE_FAILED",
662
+ "prepareMint: issuerSignerWallet required (for MintRequest EIP-712 signature)"
760
663
  );
761
664
  }
762
- }
763
- // ==========================================================================
764
- // v1.4 — Sponsored UserOp preparation (beta with mocked SC contracts)
765
- // ==========================================================================
766
- //
767
- // These two methods build unsigned `PartialUserOperation` payloads for
768
- // the Frontend to sign (via Privy) and submit to the Bundler. The
769
- // Issuer Backend no longer broadcasts — that's the Frontend's job.
770
- //
771
- // Uses mocked Relayer v2 + PointToken ABIs from `@pafi-dev/core/contracts`.
772
- // When SC delivers real ABIs, the imports swap but these method bodies
773
- // stay the same (calldata encoder is ABI-driven).
774
- // ==========================================================================
775
- /**
776
- * Build an unsigned UserOp for Scenario 1 (Mint).
777
- *
778
- * Flow:
779
- * 1. Encode `Relayer.mint(request, userSig, issuerSig)` as the inner call
780
- * 2. Optionally append a PT fee transfer from user → feeRecipient
781
- * (fee recovery happens on-chain via BatchExecutor, not via an
782
- * operator wallet)
783
- * 3. Wrap all inner calls into `BatchExecutor.execute(calls[])`
784
- * 4. Return a `PartialUserOperation` ready for:
785
- * - gas estimation (Bundler)
786
- * - paymaster sponsorship (PAFI Backend)
787
- * - user signature (Privy)
788
- */
789
- prepareMint(params) {
790
- if (!params.relayerAddress) {
791
- throw new RelayError("ENCODE_FAILED", "prepareMint: relayerAddress required");
665
+ if (params.deadline <= 0n) {
666
+ throw new RelayError("ENCODE_FAILED", "prepareMint: deadline must be positive");
792
667
  }
793
- if (!params.batchExecutorAddress) {
668
+ let minterSig;
669
+ try {
670
+ const sig = await (0, import_core3.signMintRequest)(
671
+ params.issuerSignerWallet,
672
+ params.domain,
673
+ {
674
+ to: params.userAddress,
675
+ amount: params.amount,
676
+ nonce: params.mintRequestNonce,
677
+ deadline: params.deadline
678
+ }
679
+ );
680
+ minterSig = sig.serialized;
681
+ } catch (err) {
794
682
  throw new RelayError(
795
683
  "ENCODE_FAILED",
796
- "prepareMint: batchExecutorAddress required"
684
+ `prepareMint: failed to sign MintRequest: ${errorMessage(err)}`,
685
+ err
797
686
  );
798
687
  }
799
- if (!params.userAddress) {
800
- throw new RelayError("ENCODE_FAILED", "prepareMint: userAddress required");
801
- }
802
688
  let mintCallData;
803
689
  try {
804
690
  mintCallData = (0, import_viem5.encodeFunctionData)({
805
- abi: import_core3.RELAYER_V2_ABI,
691
+ abi: import_core3.POINT_TOKEN_V2_ABI,
806
692
  functionName: "mint",
807
- args: [params.mintRequest, params.userSignature, params.issuerSignature]
693
+ args: [params.userAddress, params.amount, params.deadline, minterSig]
808
694
  });
809
695
  } catch (err) {
810
696
  throw new RelayError(
811
697
  "ENCODE_FAILED",
812
- `prepareMint: failed to encode Relayer.mint: ${errorMessage(err)}`,
698
+ `prepareMint: failed to encode PointToken.mint: ${errorMessage(err)}`,
813
699
  err
814
700
  );
815
701
  }
816
702
  const operations = [
817
703
  {
818
- target: params.relayerAddress,
704
+ target: params.pointTokenAddress,
819
705
  value: 0n,
820
706
  data: mintCallData
821
707
  }
822
708
  ];
823
- if (params.mintRequest.feeAmount > 0n) {
709
+ if (params.feeAmount && params.feeAmount > 0n) {
710
+ if (!params.feeRecipient) {
711
+ throw new RelayError(
712
+ "ENCODE_FAILED",
713
+ "prepareMint: feeRecipient required when feeAmount > 0"
714
+ );
715
+ }
824
716
  operations.push({
825
717
  target: params.pointTokenAddress,
826
718
  value: 0n,
827
719
  data: (0, import_viem5.encodeFunctionData)({
828
- abi: import_core3.POINT_TOKEN_V2_ABI,
829
- functionName: "balanceOf",
830
- // placeholder — real impl uses transfer
831
- args: [params.mintRequest.feeRecipient]
720
+ abi: import_viem5.erc20Abi,
721
+ functionName: "transfer",
722
+ args: [params.feeRecipient, params.feeAmount]
832
723
  })
833
724
  });
834
725
  }
@@ -837,7 +728,7 @@ var RelayService = class {
837
728
  nonce: params.aaNonce,
838
729
  operations,
839
730
  gasLimits: {
840
- callGasLimit: params.callGasLimit ?? 500000n,
731
+ callGasLimit: params.callGasLimit ?? 300000n,
841
732
  verificationGasLimit: params.verificationGasLimit ?? 150000n,
842
733
  preVerificationGas: params.preVerificationGas ?? 50000n
843
734
  }
@@ -847,13 +738,12 @@ var RelayService = class {
847
738
  * Build an unsigned UserOp for Scenario 2 (Burn/Redeem).
848
739
  *
849
740
  * Two modes:
850
- * - `mode: 'burn'` — direct `PointToken.burn(amount)`; `msg.sender`
851
- * via EIP-7702 delegation is the user, so no signature needed
852
- * on-chain (the BurnConsent was already verified off-chain by
853
- * the issuer backend before we got here)
854
- * - `mode: 'burnWithSig'` `PointToken.burnWithSig(consent, sig)`;
855
- * used when the issuer hasn't verified the consent and the
856
- * contract has to do it on-chain
741
+ * - `mode: 'burn'` — direct `PointToken.burn(from, amount)`; only
742
+ * usable if the caller (via EIP-7702) is whitelisted as a burner.
743
+ * Rare in v1.4; kept for admin/operator tools.
744
+ * - `mode: 'burnWithSig'` `PointToken.burn(from, amount, deadline,
745
+ * burnerSig)`. Caller provides a pre-signed `BurnRequest` + sig
746
+ * bytes (typically from `PTRedeemHandler`).
857
747
  */
858
748
  prepareBurn(params) {
859
749
  if (!params.pointTokenAddress) {
@@ -868,19 +758,24 @@ var RelayService = class {
868
758
  let burnCallData;
869
759
  try {
870
760
  if (params.mode === "burnWithSig") {
871
- if (!params.burnConsent || !params.consentSignature) {
872
- throw new Error("burnWithSig requires burnConsent + consentSignature");
761
+ if (!params.burnRequest || !params.burnerSignature) {
762
+ throw new Error("burnWithSig requires burnRequest + burnerSignature");
873
763
  }
874
764
  burnCallData = (0, import_viem5.encodeFunctionData)({
875
765
  abi: import_core3.POINT_TOKEN_V2_ABI,
876
- functionName: "burnWithSig",
877
- args: [params.burnConsent, params.consentSignature]
766
+ functionName: "burn",
767
+ args: [
768
+ params.burnRequest.from,
769
+ params.burnRequest.amount,
770
+ params.burnRequest.deadline,
771
+ params.burnerSignature
772
+ ]
878
773
  });
879
774
  } else {
880
775
  burnCallData = (0, import_viem5.encodeFunctionData)({
881
776
  abi: import_core3.POINT_TOKEN_V2_ABI,
882
777
  functionName: "burn",
883
- args: [params.amount]
778
+ args: [params.userAddress, params.amount]
884
779
  });
885
780
  }
886
781
  } catch (err) {
@@ -950,252 +845,6 @@ var FeeManager = class {
950
845
  }
951
846
  };
952
847
 
953
- // src/gateway/types.ts
954
- var MintingGatewayError = class extends Error {
955
- code;
956
- /**
957
- * True if the ledger lock was released before this error was thrown,
958
- * meaning the user can safely retry. False means the funds are still
959
- * locked (e.g. tx may still land on-chain) and retry would double-spend.
960
- */
961
- safeToRetry;
962
- cause;
963
- constructor(code, message, opts) {
964
- super(message);
965
- this.name = "MintingGatewayError";
966
- this.code = code;
967
- this.safeToRetry = opts.safeToRetry;
968
- if (opts.cause !== void 0) this.cause = opts.cause;
969
- }
970
- };
971
-
972
- // src/gateway/mintingGateway.ts
973
- var import_core4 = require("@pafi-dev/core");
974
- var DEFAULT_LOCK_BUFFER_MS = 6e4;
975
- var MintingGateway = class {
976
- ledger;
977
- policy;
978
- signer;
979
- relayService;
980
- now;
981
- defaultLockBufferMs;
982
- constructor(config) {
983
- if (!config.ledger) throw new Error("MintingGateway: ledger required");
984
- if (!config.policy) throw new Error("MintingGateway: policy required");
985
- if (!config.signer) throw new Error("MintingGateway: signer required");
986
- if (!config.relayService)
987
- throw new Error("MintingGateway: relayService required");
988
- this.ledger = config.ledger;
989
- this.policy = config.policy;
990
- this.signer = config.signer;
991
- this.relayService = config.relayService;
992
- this.now = config.now ?? (() => Date.now());
993
- this.defaultLockBufferMs = config.defaultLockBufferMs ?? DEFAULT_LOCK_BUFFER_MS;
994
- }
995
- /**
996
- * @deprecated Since 0.3.0 — will be renamed to `processMint()` once
997
- * the SC team finalizes Relayer v2 ABI. The new flow drops the
998
- * swap steps entirely (no more single-call mint+swap); users swap
999
- * separately on PAFI Web. Kept here for v0.2.x consumers. Removed in 2.0.
1000
- */
1001
- async processMintAndCashOut(request) {
1002
- const { receiverConsent, receiverSignature } = request;
1003
- if (!receiverConsent || !receiverSignature) {
1004
- throw new MintingGatewayError(
1005
- "INVALID_REQUEST",
1006
- "receiverConsent and receiverSignature are required",
1007
- { safeToRetry: true }
1008
- );
1009
- }
1010
- if (receiverConsent.amount <= 0n) {
1011
- throw new MintingGatewayError(
1012
- "INVALID_REQUEST",
1013
- "consent amount must be positive",
1014
- { safeToRetry: true }
1015
- );
1016
- }
1017
- if (receiverConsent.originalReceiver !== request.userAddress) {
1018
- throw new MintingGatewayError(
1019
- "INVALID_REQUEST",
1020
- "consent.originalReceiver must equal request.userAddress",
1021
- { safeToRetry: true }
1022
- );
1023
- }
1024
- const nowSec = BigInt(Math.floor(this.now() / 1e3));
1025
- if (receiverConsent.deadline <= nowSec) {
1026
- throw new MintingGatewayError(
1027
- "CONSENT_EXPIRED",
1028
- "ReceiverConsent deadline has already passed",
1029
- { safeToRetry: true }
1030
- );
1031
- }
1032
- const consentResult = await (0, import_core4.verifyReceiverConsent)(
1033
- request.domain,
1034
- receiverConsent,
1035
- receiverSignature,
1036
- request.userAddress
1037
- );
1038
- if (!consentResult.isValid) {
1039
- throw new MintingGatewayError(
1040
- "INVALID_CONSENT_SIGNATURE",
1041
- `ReceiverConsent signature did not recover to ${request.userAddress}`,
1042
- { safeToRetry: true }
1043
- );
1044
- }
1045
- const policyDecision = await this.policy.evaluate({
1046
- userAddress: request.userAddress,
1047
- amount: receiverConsent.amount,
1048
- pointTokenAddress: request.pointTokenAddress,
1049
- chainId: request.chainId
1050
- });
1051
- if (!policyDecision.approved) {
1052
- const code = policyDecision.reason?.toLowerCase().includes("insufficient") ? "INSUFFICIENT_BALANCE" : "POLICY_REJECTED";
1053
- throw new MintingGatewayError(
1054
- code,
1055
- policyDecision.reason ?? "Minting request rejected by policy engine",
1056
- { safeToRetry: true }
1057
- );
1058
- }
1059
- const lockDurationMs = request.lockDurationMs ?? this.computeLockDurationMs(receiverConsent.deadline);
1060
- let lockId;
1061
- try {
1062
- lockId = await this.ledger.lockForMinting(
1063
- request.userAddress,
1064
- receiverConsent.amount,
1065
- lockDurationMs,
1066
- request.pointTokenAddress
1067
- );
1068
- } catch (err) {
1069
- throw new MintingGatewayError(
1070
- "INSUFFICIENT_BALANCE",
1071
- `Failed to lock ledger balance: ${errorMessage2(err)}`,
1072
- { safeToRetry: true, cause: err }
1073
- );
1074
- }
1075
- try {
1076
- let minterSignature;
1077
- try {
1078
- minterSignature = await this.signer.signMintRequest(request.domain, {
1079
- to: request.userAddress,
1080
- amount: receiverConsent.amount,
1081
- nonce: receiverConsent.nonce,
1082
- deadline: receiverConsent.deadline
1083
- });
1084
- } catch (err) {
1085
- await this.releaseLockSafely(lockId);
1086
- throw new MintingGatewayError(
1087
- "SIGNER_FAILED",
1088
- `Issuer signer failed: ${errorMessage2(err)}`,
1089
- { safeToRetry: true, cause: err }
1090
- );
1091
- }
1092
- const mintParams = {
1093
- pointToken: request.pointTokenAddress,
1094
- receiver: request.userAddress,
1095
- amount: receiverConsent.amount,
1096
- deadline: receiverConsent.deadline,
1097
- minterSig: minterSignature.serialized,
1098
- receiverSig: receiverSignature,
1099
- extData: receiverConsent.extData
1100
- };
1101
- const swapParams = {
1102
- path: request.swapPath,
1103
- deadline: request.swapDeadline
1104
- };
1105
- let relayResult;
1106
- try {
1107
- relayResult = await this.relayService.submitMintAndSwap({
1108
- mint: mintParams,
1109
- swap: swapParams
1110
- });
1111
- } catch (err) {
1112
- await this.handleRelayFailure(err, lockId);
1113
- }
1114
- const result = {
1115
- txHash: relayResult.txHash,
1116
- lockId
1117
- };
1118
- if (relayResult.blockNumber !== void 0) {
1119
- result.blockNumber = relayResult.blockNumber;
1120
- }
1121
- if (relayResult.gasUsed !== void 0) {
1122
- result.gasUsed = relayResult.gasUsed;
1123
- }
1124
- return result;
1125
- } catch (err) {
1126
- if (err instanceof MintingGatewayError) throw err;
1127
- await this.releaseLockSafely(lockId);
1128
- throw new MintingGatewayError(
1129
- "RELAY_SUBMIT_FAILED",
1130
- `Unexpected error: ${errorMessage2(err)}`,
1131
- { safeToRetry: true, cause: err }
1132
- );
1133
- }
1134
- }
1135
- // ---------------------------------------------------------------------------
1136
- // Internals
1137
- // ---------------------------------------------------------------------------
1138
- computeLockDurationMs(consentDeadlineSec) {
1139
- const nowMs = this.now();
1140
- const deadlineMs = Number(consentDeadlineSec) * 1e3;
1141
- const remaining = Math.max(0, deadlineMs - nowMs);
1142
- return remaining + this.defaultLockBufferMs;
1143
- }
1144
- /**
1145
- * Map a RelayError to a MintingGatewayError, releasing the lock only
1146
- * when the tx definitely did not land. `TX_REVERTED` and `TIMEOUT`
1147
- * leave the lock in place because the tx may still be in the mempool
1148
- * or already mined — releasing would enable a double-spend on retry.
1149
- * Always throws.
1150
- */
1151
- async handleRelayFailure(err, lockId) {
1152
- if (err instanceof RelayError) {
1153
- switch (err.code) {
1154
- case "ENCODE_FAILED":
1155
- case "SIMULATION_FAILED":
1156
- case "SUBMIT_FAILED":
1157
- case "NOT_CONFIGURED":
1158
- await this.releaseLockSafely(lockId);
1159
- throw new MintingGatewayError(
1160
- err.code === "SIMULATION_FAILED" ? "RELAY_SIMULATION_FAILED" : "RELAY_SUBMIT_FAILED",
1161
- err.message,
1162
- { safeToRetry: true, cause: err }
1163
- );
1164
- case "TX_REVERTED":
1165
- throw new MintingGatewayError("RELAY_REVERTED", err.message, {
1166
- safeToRetry: false,
1167
- cause: err
1168
- });
1169
- case "TIMEOUT":
1170
- throw new MintingGatewayError("RELAY_TIMEOUT", err.message, {
1171
- safeToRetry: false,
1172
- cause: err
1173
- });
1174
- }
1175
- }
1176
- await this.releaseLockSafely(lockId);
1177
- throw new MintingGatewayError(
1178
- "RELAY_SUBMIT_FAILED",
1179
- `Unexpected relay error: ${errorMessage2(err)}`,
1180
- { safeToRetry: true, cause: err }
1181
- );
1182
- }
1183
- /**
1184
- * Release a lock, swallowing any secondary error. We never want a lock
1185
- * release failure to mask the original error — the lock will auto-expire
1186
- * via TTL anyway.
1187
- */
1188
- async releaseLockSafely(lockId) {
1189
- try {
1190
- await this.ledger.releaseLock(lockId);
1191
- } catch {
1192
- }
1193
- }
1194
- };
1195
- function errorMessage2(err) {
1196
- return err instanceof Error ? err.message : String(err);
1197
- }
1198
-
1199
848
  // src/indexer/types.ts
1200
849
  var InMemoryCursorStore = class {
1201
850
  cursor;
@@ -1540,10 +1189,9 @@ var BurnIndexer = class {
1540
1189
 
1541
1190
  // src/api/handlers.ts
1542
1191
  var import_viem8 = require("viem");
1543
- var import_core5 = require("@pafi-dev/core");
1192
+ var import_core4 = require("@pafi-dev/core");
1544
1193
  var IssuerApiHandlers = class {
1545
1194
  authService;
1546
- gateway;
1547
1195
  ledger;
1548
1196
  provider;
1549
1197
  /**
@@ -1562,7 +1210,6 @@ var IssuerApiHandlers = class {
1562
1210
  poolsProvider;
1563
1211
  constructor(config) {
1564
1212
  this.authService = config.authService;
1565
- this.gateway = config.gateway;
1566
1213
  this.ledger = config.ledger;
1567
1214
  this.provider = config.provider;
1568
1215
  const raw = config.pointTokenAddresses && config.pointTokenAddresses.length > 0 ? config.pointTokenAddresses : config.pointTokenAddress ? [config.pointTokenAddress] : [];
@@ -1686,11 +1333,11 @@ var IssuerApiHandlers = class {
1686
1333
  );
1687
1334
  }
1688
1335
  const [mintRequestNonce, receiverConsentNonce, offChainBalance, onChainBalance, minter] = await Promise.all([
1689
- (0, import_core5.getMintRequestNonce)(this.provider, pointToken, normalizedAuthed),
1690
- (0, import_core5.getReceiverConsentNonce)(this.provider, pointToken, normalizedAuthed),
1336
+ (0, import_core4.getMintRequestNonce)(this.provider, pointToken, normalizedAuthed),
1337
+ (0, import_core4.getReceiverConsentNonce)(this.provider, pointToken, normalizedAuthed),
1691
1338
  this.ledger.getBalance(normalizedAuthed, pointToken),
1692
- (0, import_core5.getPointTokenBalance)(this.provider, pointToken, normalizedAuthed),
1693
- (0, import_core5.isMinter)(this.provider, pointToken, normalizedAuthed)
1339
+ (0, import_core4.getPointTokenBalance)(this.provider, pointToken, normalizedAuthed),
1340
+ (0, import_core4.isMinter)(this.provider, pointToken, normalizedAuthed)
1694
1341
  ]);
1695
1342
  return {
1696
1343
  mintRequestNonce,
@@ -1728,13 +1375,13 @@ var IssuerApiHandlers = class {
1728
1375
  `handleBuildConsentTypedData: unsupported pointToken ${pointToken}`
1729
1376
  );
1730
1377
  }
1731
- const name = await (0, import_core5.getTokenName)(this.provider, pointToken);
1378
+ const name = await (0, import_core4.getTokenName)(this.provider, pointToken);
1732
1379
  const domain = {
1733
1380
  name,
1734
1381
  verifyingContract: pointToken,
1735
1382
  chainId: this.chainId
1736
1383
  };
1737
- const typedData = (0, import_core5.buildReceiverConsentTypedData)(domain, request.receiverConsent);
1384
+ const typedData = (0, import_core4.buildReceiverConsentTypedData)(domain, request.receiverConsent);
1738
1385
  return {
1739
1386
  typedData: {
1740
1387
  domain: typedData.domain,
@@ -1744,55 +1391,13 @@ var IssuerApiHandlers = class {
1744
1391
  }
1745
1392
  };
1746
1393
  }
1747
- /**
1748
- * `POST /claim-and-swap`
1749
- *
1750
- * @deprecated Since 0.3.0 — the single-call mint-then-swap flow is
1751
- * retired in v1.4. Use the new `handleClaim()` (mint only) and let
1752
- * the user swap separately on PAFI Web. See
1753
- * [V1.4_V1.5_OVERVIEW.md §4] for the new scenario model. Will be
1754
- * removed in 2.0.
1755
- *
1756
- * Legacy behavior: the terminal handler forwards the verified
1757
- * consent to the MintingGateway, which runs the 11-step flow.
1758
- */
1759
- async handleClaimAndSwap(userAddress, request) {
1760
- if (request.chainId !== this.chainId) {
1761
- throw new Error(
1762
- `handleClaimAndSwap: unsupported chainId ${request.chainId}`
1763
- );
1764
- }
1765
- const pointToken = (0, import_viem8.getAddress)(request.pointTokenAddress);
1766
- if (!this.supportedTokens.has(pointToken)) {
1767
- throw new Error(
1768
- `handleClaimAndSwap: unsupported pointToken ${pointToken}`
1769
- );
1770
- }
1771
- const result = await this.gateway.processMintAndCashOut({
1772
- userAddress: (0, import_viem8.getAddress)(userAddress),
1773
- pointTokenAddress: pointToken,
1774
- chainId: request.chainId,
1775
- domain: request.domain,
1776
- receiverConsent: request.receiverConsent,
1777
- receiverSignature: request.receiverSignature,
1778
- swapPath: request.swapPath,
1779
- swapDeadline: request.swapDeadline
1780
- });
1781
- const response = {
1782
- txHash: result.txHash,
1783
- lockId: result.lockId
1784
- };
1785
- if (result.blockNumber !== void 0)
1786
- response.blockNumber = result.blockNumber;
1787
- if (result.gasUsed !== void 0) response.gasUsed = result.gasUsed;
1788
- return response;
1789
- }
1790
1394
  };
1791
1395
 
1792
1396
  // src/api/handlers/ptRedeemHandler.ts
1793
1397
  var import_viem9 = require("viem");
1794
- var import_core6 = require("@pafi-dev/core");
1398
+ var import_core5 = require("@pafi-dev/core");
1795
1399
  var DEFAULT_REDEEM_LOCK_MS = 15 * 60 * 1e3;
1400
+ var DEFAULT_SIG_DEADLINE_SEC = 15 * 60;
1796
1401
  var PTRedeemError = class extends Error {
1797
1402
  constructor(code, message) {
1798
1403
  super(message);
@@ -1804,11 +1409,14 @@ var PTRedeemError = class extends Error {
1804
1409
  var PTRedeemHandler = class {
1805
1410
  ledger;
1806
1411
  relayService;
1412
+ provider;
1807
1413
  pointTokenAddress;
1808
1414
  batchExecutorAddress;
1809
1415
  chainId;
1810
1416
  domain;
1417
+ burnerSignerWallet;
1811
1418
  redeemLockDurationMs;
1419
+ signatureDeadlineSeconds;
1812
1420
  now;
1813
1421
  constructor(config) {
1814
1422
  if (!config.ledger.reservePendingCredit) {
@@ -1817,46 +1425,68 @@ var PTRedeemHandler = class {
1817
1425
  "PTRedeemHandler requires a ledger that implements reservePendingCredit() (v0.3.0+)"
1818
1426
  );
1819
1427
  }
1428
+ if (!config.burnerSignerWallet) {
1429
+ throw new PTRedeemError(
1430
+ "SIGNING_FAILED",
1431
+ "PTRedeemHandler requires burnerSignerWallet (issuer burner signer)"
1432
+ );
1433
+ }
1820
1434
  this.ledger = config.ledger;
1821
1435
  this.relayService = config.relayService;
1436
+ this.provider = config.provider;
1822
1437
  this.pointTokenAddress = (0, import_viem9.getAddress)(config.pointTokenAddress);
1823
1438
  this.batchExecutorAddress = (0, import_viem9.getAddress)(config.batchExecutorAddress);
1824
1439
  this.chainId = config.chainId;
1825
1440
  this.domain = config.domain;
1441
+ this.burnerSignerWallet = config.burnerSignerWallet;
1826
1442
  this.redeemLockDurationMs = config.redeemLockDurationMs ?? DEFAULT_REDEEM_LOCK_MS;
1443
+ this.signatureDeadlineSeconds = config.signatureDeadlineSeconds ?? DEFAULT_SIG_DEADLINE_SEC;
1827
1444
  this.now = config.now ?? (() => Date.now());
1828
1445
  }
1829
1446
  async handle(request) {
1830
1447
  if (request.amount <= 0n) {
1831
- throw new PTRedeemError("INVALID_CONSENT", "redeem amount must be positive");
1448
+ throw new PTRedeemError("INVALID_AMOUNT", "redeem amount must be positive");
1832
1449
  }
1833
- if (request.consent.amount !== request.amount) {
1834
- throw new PTRedeemError(
1835
- "AMOUNT_MISMATCH",
1836
- `consent.amount (${request.consent.amount}) must match request.amount (${request.amount})`
1837
- );
1838
- }
1839
- const nowSeconds = BigInt(Math.floor(this.now() / 1e3));
1840
- if (request.consent.deadline <= nowSeconds) {
1450
+ let burnNonce;
1451
+ try {
1452
+ burnNonce = await this.provider.readContract({
1453
+ address: this.pointTokenAddress,
1454
+ abi: import_core5.POINT_TOKEN_V2_ABI,
1455
+ functionName: "burnRequestNonces",
1456
+ args: [request.userAddress]
1457
+ });
1458
+ } catch (err) {
1841
1459
  throw new PTRedeemError(
1842
- "EXPIRED_CONSENT",
1843
- `consent deadline (${request.consent.deadline}) already passed`
1460
+ "NONCE_READ_FAILED",
1461
+ `failed to read burnRequestNonces(${request.userAddress}): ${err instanceof Error ? err.message : String(err)}`
1844
1462
  );
1845
1463
  }
1846
- const verification = await (0, import_core6.verifyBurnConsent)(
1847
- {
1848
- name: this.domain.name,
1849
- chainId: this.chainId,
1850
- verifyingContract: this.domain.verifyingContract ?? this.pointTokenAddress
1851
- },
1852
- request.consent,
1853
- request.consentSignature,
1854
- request.userAddress
1464
+ const deadline = BigInt(
1465
+ Math.floor(this.now() / 1e3) + this.signatureDeadlineSeconds
1855
1466
  );
1856
- if (!verification.isValid) {
1467
+ const domain = {
1468
+ name: this.domain.name,
1469
+ chainId: this.chainId,
1470
+ verifyingContract: this.domain.verifyingContract ?? this.pointTokenAddress
1471
+ };
1472
+ const burnRequest = {
1473
+ from: request.userAddress,
1474
+ amount: request.amount,
1475
+ nonce: burnNonce,
1476
+ deadline
1477
+ };
1478
+ let burnerSignature;
1479
+ try {
1480
+ const sig = await (0, import_core5.signBurnRequest)(
1481
+ this.burnerSignerWallet,
1482
+ domain,
1483
+ burnRequest
1484
+ );
1485
+ burnerSignature = sig.serialized;
1486
+ } catch (err) {
1857
1487
  throw new PTRedeemError(
1858
- "SIGNATURE_MISMATCH",
1859
- `signer mismatch \u2014 expected ${request.userAddress}, got ${verification.recoveredAddress}`
1488
+ "SIGNING_FAILED",
1489
+ `failed to sign BurnRequest: ${err instanceof Error ? err.message : String(err)}`
1860
1490
  );
1861
1491
  }
1862
1492
  const lockId = await this.ledger.reservePendingCredit(
@@ -1871,33 +1501,21 @@ var PTRedeemHandler = class {
1871
1501
  aaNonce: request.aaNonce,
1872
1502
  pointTokenAddress: this.pointTokenAddress,
1873
1503
  batchExecutorAddress: this.batchExecutorAddress,
1874
- burnConsent: request.consent,
1875
- consentSignature: parseSigStruct(request.consentSignature)
1504
+ burnRequest,
1505
+ burnerSignature
1876
1506
  });
1877
1507
  return {
1878
1508
  lockId,
1879
1509
  userOp,
1880
- expiresInSeconds: Math.floor(this.redeemLockDurationMs / 1e3)
1510
+ expiresInSeconds: Math.floor(this.redeemLockDurationMs / 1e3),
1511
+ signatureDeadline: deadline
1881
1512
  };
1882
1513
  }
1883
1514
  };
1884
- function parseSigStruct(serialized) {
1885
- const raw = serialized.slice(2);
1886
- if (raw.length !== 130) {
1887
- throw new PTRedeemError(
1888
- "INVALID_CONSENT",
1889
- `signature must be 65 bytes, got ${raw.length / 2}`
1890
- );
1891
- }
1892
- const r = `0x${raw.slice(0, 64)}`;
1893
- const s = `0x${raw.slice(64, 128)}`;
1894
- const v = parseInt(raw.slice(128, 130), 16);
1895
- return { v, r, s };
1896
- }
1897
1515
 
1898
1516
  // src/api/handlers/topUpRedemptionHandler.ts
1899
1517
  var import_viem10 = require("viem");
1900
- var import_core7 = require("@pafi-dev/core");
1518
+ var import_core6 = require("@pafi-dev/core");
1901
1519
  var TopUpRedemptionError = class extends Error {
1902
1520
  constructor(code, message) {
1903
1521
  super(message);
@@ -1926,7 +1544,7 @@ var TopUpRedemptionHandler = class {
1926
1544
  return { action: "NO_TOP_UP_NEEDED", offChainBalance };
1927
1545
  }
1928
1546
  const shortfall = request.requiredAmount - offChainBalance;
1929
- const onChainBalance = await (0, import_core7.getPointTokenBalance)(
1547
+ const onChainBalance = await (0, import_core6.getPointTokenBalance)(
1930
1548
  this.provider,
1931
1549
  this.pointTokenAddress,
1932
1550
  request.userAddress
@@ -1939,24 +1557,10 @@ var TopUpRedemptionHandler = class {
1939
1557
  shortfall
1940
1558
  };
1941
1559
  }
1942
- if (request.redeemRequest.consent.amount < shortfall) {
1943
- throw new TopUpRedemptionError(
1944
- "CONSENT_AMOUNT_TOO_LOW",
1945
- `consent.amount (${request.redeemRequest.consent.amount}) must cover shortfall (${shortfall})`
1946
- );
1947
- }
1948
- if (request.redeemRequest.consent.amount !== shortfall) {
1949
- throw new TopUpRedemptionError(
1950
- "CONSENT_AMOUNT_TOO_LOW",
1951
- `consent.amount (${request.redeemRequest.consent.amount}) must equal shortfall (${shortfall}) exactly \u2014 re-sign with correct amount`
1952
- );
1953
- }
1954
1560
  const redeem = await this.ptRedeemHandler.handle({
1955
1561
  userAddress: request.userAddress,
1956
1562
  amount: shortfall,
1957
- consent: request.redeemRequest.consent,
1958
- consentSignature: request.redeemRequest.consentSignature,
1959
- aaNonce: request.redeemRequest.aaNonce
1563
+ aaNonce: request.aaNonce
1960
1564
  });
1961
1565
  return {
1962
1566
  action: "TOP_UP_STARTED",
@@ -2178,7 +1782,7 @@ function toUsdtPerNative(priceFloat, usdtDecimals) {
2178
1782
  }
2179
1783
 
2180
1784
  // src/balance/balanceAggregator.ts
2181
- var import_core8 = require("@pafi-dev/core");
1785
+ var import_core7 = require("@pafi-dev/core");
2182
1786
  var BalanceAggregator = class {
2183
1787
  provider;
2184
1788
  ledger;
@@ -2199,7 +1803,7 @@ var BalanceAggregator = class {
2199
1803
  async getCombinedBalance(user, pointToken) {
2200
1804
  const [offChain, onChain] = await Promise.all([
2201
1805
  this.ledger.getBalance(user, pointToken),
2202
- (0, import_core8.getPointTokenBalance)(this.provider, pointToken, user)
1806
+ (0, import_core7.getPointTokenBalance)(this.provider, pointToken, user)
2203
1807
  ]);
2204
1808
  return {
2205
1809
  offChain,
@@ -2237,28 +1841,11 @@ var PafiBackendError = class extends Error {
2237
1841
  code;
2238
1842
  httpStatus;
2239
1843
  details;
2240
- /**
2241
- * Seconds to wait before retry. Populated from the server body
2242
- * (e.g. rate limit returns the number of seconds until UTC midnight).
2243
- */
2244
1844
  retryAfter;
2245
- /**
2246
- * `safeToRetry` as reported by the server body. Prefer this over the
2247
- * code-based heuristic when available — the server knows more about
2248
- * whether the same request will succeed on retry.
2249
- */
2250
1845
  serverSafeToRetry;
2251
- /**
2252
- * Whether the caller can safely retry the same request.
2253
- *
2254
- * If the server provided `safeToRetry` in the body, trust that.
2255
- * Otherwise fall back to a code-based heuristic.
2256
- */
2257
1846
  get safeToRetry() {
2258
1847
  if (this.serverSafeToRetry !== void 0) return this.serverSafeToRetry;
2259
1848
  switch (this.code) {
2260
- case "PAYMASTER_UNAVAILABLE":
2261
- case "PAYMASTER_TIMEOUT":
2262
1849
  case "RATE_LIMITER_UNAVAILABLE":
2263
1850
  case "INTERNAL_ERROR":
2264
1851
  case "TIMEOUT":
@@ -2267,197 +1854,20 @@ var PafiBackendError = class extends Error {
2267
1854
  case "RATE_LIMIT_EXCEEDED":
2268
1855
  case "RATE_LIMIT_EXCEEDED_DAILY":
2269
1856
  case "RATE_LIMIT_EXCEEDED_PER_USER":
1857
+ case "ISSUER_BUDGET_EXCEEDED":
2270
1858
  return true;
2271
- // after retryAfter
2272
1859
  default:
2273
1860
  return false;
2274
1861
  }
2275
1862
  }
2276
1863
  };
2277
1864
 
2278
- // src/pafi-backend/pafiBackendClient.ts
2279
- var DEFAULT_TIMEOUT_MS = 1e4;
2280
- var RETRY_DEFAULTS = {
2281
- maxAttempts: 1,
2282
- initialDelayMs: 500,
2283
- maxDelayMs: 1e4,
2284
- maxRetryAfterMs: 3e4
2285
- };
2286
- var PafiBackendClient = class {
2287
- url;
2288
- issuerId;
2289
- apiKey;
2290
- fetchImpl;
2291
- timeoutMs;
2292
- retry;
2293
- constructor(config) {
2294
- if (!config.url) {
2295
- throw new Error("PafiBackendClient: url is required");
2296
- }
2297
- if (!config.issuerId) {
2298
- throw new Error("PafiBackendClient: issuerId is required");
2299
- }
2300
- if (!config.apiKey) {
2301
- throw new Error("PafiBackendClient: apiKey is required");
2302
- }
2303
- this.url = config.url.replace(/\/+$/, "");
2304
- this.issuerId = config.issuerId;
2305
- this.apiKey = config.apiKey;
2306
- this.fetchImpl = config.fetchImpl ?? globalThis.fetch;
2307
- this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
2308
- this.retry = { ...RETRY_DEFAULTS, ...config.retry ?? {} };
2309
- if (!this.fetchImpl) {
2310
- throw new Error(
2311
- "PafiBackendClient: no fetch implementation available \u2014 pass `fetchImpl` or run on Node 18+"
2312
- );
2313
- }
2314
- if (this.retry.maxAttempts < 1) {
2315
- throw new Error("PafiBackendClient: retry.maxAttempts must be >= 1");
2316
- }
2317
- }
2318
- /**
2319
- * Request paymaster sponsorship for a pre-built UserOperation.
2320
- * See [SPONSORED_PATH_FLOW.md §4.1] for the API contract.
2321
- *
2322
- * Retries automatically on transient failures (5xx, timeouts, network
2323
- * errors, and errors the server flags with `safeToRetry: true`) up to
2324
- * `retry.maxAttempts`. 4xx errors that are not `safeToRetry` fail fast.
2325
- *
2326
- * @throws PafiBackendError on final failure after exhausting retries
2327
- */
2328
- async requestSponsorship(req) {
2329
- return this.postWithRetry(
2330
- "/paymaster/sponsor",
2331
- req
2332
- );
2333
- }
2334
- // -------------------------------------------------------------------------
2335
- // Internals
2336
- // -------------------------------------------------------------------------
2337
- async postWithRetry(path, body) {
2338
- let lastError;
2339
- for (let attempt = 1; attempt <= this.retry.maxAttempts; attempt++) {
2340
- try {
2341
- return await this.post(path, body);
2342
- } catch (err) {
2343
- if (!(err instanceof PafiBackendError)) throw err;
2344
- lastError = err;
2345
- const isLastAttempt = attempt >= this.retry.maxAttempts;
2346
- if (isLastAttempt || !err.safeToRetry) throw err;
2347
- const delay = this.computeBackoff(attempt, err.retryAfter);
2348
- if (delay === null) throw err;
2349
- await this.sleep(delay);
2350
- }
2351
- }
2352
- throw lastError;
2353
- }
2354
- /**
2355
- * Pick the delay before the next retry.
2356
- * - If the server sent `retryAfter` (seconds), honor it (capped by
2357
- * `maxRetryAfterMs`) — returns null if the server wait exceeds the
2358
- * cap, signalling the caller should give up.
2359
- * - Otherwise: exponential backoff with ±20% jitter, capped at
2360
- * `maxDelayMs`.
2361
- */
2362
- computeBackoff(attempt, retryAfter) {
2363
- if (retryAfter !== void 0) {
2364
- const serverMs = retryAfter * 1e3;
2365
- if (serverMs > this.retry.maxRetryAfterMs) return null;
2366
- return serverMs;
2367
- }
2368
- const exp = this.retry.initialDelayMs * 2 ** (attempt - 1);
2369
- const capped = Math.min(exp, this.retry.maxDelayMs);
2370
- const jitter = capped * (0.8 + Math.random() * 0.4);
2371
- return Math.round(jitter);
2372
- }
2373
- sleep(ms) {
2374
- return new Promise((resolve) => setTimeout(resolve, ms));
2375
- }
2376
- async post(path, body) {
2377
- const controller = new AbortController();
2378
- const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
2379
- let response;
2380
- try {
2381
- response = await this.fetchImpl(`${this.url}${path}`, {
2382
- method: "POST",
2383
- headers: {
2384
- "Content-Type": "application/json",
2385
- "Authorization": `Bearer ${this.apiKey}`,
2386
- "X-Issuer-Id": this.issuerId
2387
- },
2388
- body: JSON.stringify(body, this.bigintReplacer),
2389
- signal: controller.signal
2390
- });
2391
- } catch (err) {
2392
- if (err.name === "AbortError") {
2393
- throw new PafiBackendError(
2394
- "TIMEOUT",
2395
- `PAFI Backend request timed out after ${this.timeoutMs}ms`,
2396
- 0
2397
- );
2398
- }
2399
- throw new PafiBackendError(
2400
- "NETWORK_ERROR",
2401
- `PAFI Backend unreachable: ${err.message}`,
2402
- 0
2403
- );
2404
- } finally {
2405
- clearTimeout(timeoutId);
2406
- }
2407
- const text = await response.text();
2408
- if (!response.ok) {
2409
- let code = "INTERNAL_ERROR";
2410
- let message = text || response.statusText;
2411
- let details;
2412
- let retryAfter;
2413
- let serverSafeToRetry;
2414
- try {
2415
- const parsed = JSON.parse(text);
2416
- code = parsed.code ?? code;
2417
- message = parsed.message ?? message;
2418
- details = parsed.details;
2419
- if (typeof parsed.retryAfter === "number") retryAfter = parsed.retryAfter;
2420
- if (typeof parsed.safeToRetry === "boolean") serverSafeToRetry = parsed.safeToRetry;
2421
- } catch {
2422
- }
2423
- throw new PafiBackendError(code, message, response.status, details, {
2424
- ...retryAfter !== void 0 ? { retryAfter } : {},
2425
- ...serverSafeToRetry !== void 0 ? { safeToRetry: serverSafeToRetry } : {}
2426
- });
2427
- }
2428
- return JSON.parse(text, this.bigintReviver);
2429
- }
2430
- /** JSON replacer that stringifies bigints. Paired with bigintReviver. */
2431
- bigintReplacer = (_key, value) => {
2432
- return typeof value === "bigint" ? value.toString() : value;
2433
- };
2434
- /**
2435
- * JSON reviver that coerces specific numeric-string fields back to
2436
- * bigint. The server must send these fields as decimal strings.
2437
- */
2438
- bigintReviver = (key, value) => {
2439
- if (typeof value === "string" && (key.endsWith("GasLimit") || key === "nonce" || key === "callGasLimit" || key === "verificationGasLimit" || key === "preVerificationGas" || key === "maxFeePerGas" || key === "maxPriorityFeePerGas" || key === "paymasterVerificationGasLimit" || key === "paymasterPostOpGasLimit") && /^\d+$/.test(value)) {
2440
- return BigInt(value);
2441
- }
2442
- return value;
2443
- };
2444
- };
2445
-
2446
1865
  // src/config.ts
2447
1866
  var import_viem11 = require("viem");
2448
1867
  function createIssuerService(config) {
2449
1868
  if (!config.provider) {
2450
1869
  throw new Error("createIssuerService: provider is required");
2451
1870
  }
2452
- if (!config.operatorWallet) {
2453
- throw new Error("createIssuerService: operatorWallet is required");
2454
- }
2455
- if (!config.signer) {
2456
- throw new Error("createIssuerService: signer is required");
2457
- }
2458
- if (!config.relayAddress) {
2459
- throw new Error("createIssuerService: relayAddress is required");
2460
- }
2461
1871
  if (!config.auth?.jwtSecret) {
2462
1872
  throw new Error("createIssuerService: auth.jwtSecret is required");
2463
1873
  }
@@ -2484,18 +1894,7 @@ function createIssuerService(config) {
2484
1894
  authServiceConfig.jwtExpiresIn = config.auth.jwtExpiresIn;
2485
1895
  }
2486
1896
  const authService = new AuthService(authServiceConfig);
2487
- const relayServiceConfig = {
2488
- relayAddress: config.relayAddress,
2489
- operatorWallet: config.operatorWallet,
2490
- provider: config.provider
2491
- };
2492
- if (config.relay?.simulateBeforeSubmit !== void 0) {
2493
- relayServiceConfig.simulateBeforeSubmit = config.relay.simulateBeforeSubmit;
2494
- }
2495
- if (config.relay?.confirmationTimeoutMs !== void 0) {
2496
- relayServiceConfig.confirmationTimeoutMs = config.relay.confirmationTimeoutMs;
2497
- }
2498
- const relayService = new RelayService(relayServiceConfig);
1897
+ const relayService = new RelayService();
2499
1898
  let feeManager;
2500
1899
  if (config.fee) {
2501
1900
  feeManager = new FeeManager({
@@ -2503,16 +1902,6 @@ function createIssuerService(config) {
2503
1902
  provider: config.provider
2504
1903
  });
2505
1904
  }
2506
- const gatewayConfig = {
2507
- ledger,
2508
- policy,
2509
- signer: config.signer,
2510
- relayService
2511
- };
2512
- if (config.gateway?.defaultLockBufferMs !== void 0) {
2513
- gatewayConfig.defaultLockBufferMs = config.gateway.defaultLockBufferMs;
2514
- }
2515
- const gateway = new MintingGateway(gatewayConfig);
2516
1905
  const indexers = /* @__PURE__ */ new Map();
2517
1906
  for (const tokenAddress of tokenAddresses) {
2518
1907
  const indexerConfig = {
@@ -2540,7 +1929,6 @@ function createIssuerService(config) {
2540
1929
  const firstIndexer = indexers.get(tokenAddresses[0]);
2541
1930
  const handlersConfig = {
2542
1931
  authService,
2543
- gateway,
2544
1932
  ledger,
2545
1933
  provider: config.provider,
2546
1934
  pointTokenAddresses: tokenAddresses,
@@ -2560,10 +1948,8 @@ function createIssuerService(config) {
2560
1948
  sessionStore,
2561
1949
  ledger,
2562
1950
  policy,
2563
- signer: config.signer,
2564
1951
  relayService,
2565
1952
  feeManager,
2566
- gateway,
2567
1953
  indexers,
2568
1954
  indexer: firstIndexer,
2569
1955
  handlers
@@ -2584,13 +1970,10 @@ var PAFI_ISSUER_SDK_VERSION = "0.1.0";
2584
1970
  IssuerApiHandlers,
2585
1971
  MemoryPointLedger,
2586
1972
  MemorySessionStore,
2587
- MintingGateway,
2588
- MintingGatewayError,
2589
1973
  NonceManager,
2590
1974
  PAFI_ISSUER_SDK_VERSION,
2591
1975
  PTRedeemError,
2592
1976
  PTRedeemHandler,
2593
- PafiBackendClient,
2594
1977
  PafiBackendError,
2595
1978
  PointIndexer,
2596
1979
  PrivateKeySigner,
@@ -2601,7 +1984,6 @@ var PAFI_ISSUER_SDK_VERSION = "0.1.0";
2601
1984
  authenticateRequest,
2602
1985
  createIssuerService,
2603
1986
  createSubgraphNativeUsdtQuoter,
2604
- createSubgraphPoolsProvider,
2605
- encodeExtData
1987
+ createSubgraphPoolsProvider
2606
1988
  });
2607
1989
  //# sourceMappingURL=index.cjs.map