@pafi-dev/issuer 0.3.0-beta.4 → 0.3.0-beta.5

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
@@ -587,145 +587,14 @@ import {
587
587
  erc20Abi
588
588
  } from "viem";
589
589
  import {
590
- relayAbi,
591
- encodeMintAndSwap,
592
- simulateMintAndSwap as coreSimulateMintAndSwap,
593
- SimulationError,
594
590
  POINT_TOKEN_V2_ABI,
595
591
  buildPartialUserOperation,
596
592
  signMintRequest as signMintRequest2
597
593
  } from "@pafi-dev/core";
598
- var DEFAULT_CONFIRMATION_TIMEOUT_MS = 6e4;
599
594
  var RelayService = class {
600
- relayAddress;
601
- operatorWallet;
602
- provider;
603
- confirmationTimeoutMs;
604
- simulateBeforeSubmit;
605
- constructor(config) {
606
- if (!config.relayAddress) {
607
- throw new Error("RelayService: relayAddress is required");
608
- }
609
- if (!config.operatorWallet) {
610
- throw new Error("RelayService: operatorWallet is required");
611
- }
612
- this.relayAddress = config.relayAddress;
613
- this.operatorWallet = config.operatorWallet;
614
- if (config.provider) this.provider = config.provider;
615
- this.confirmationTimeoutMs = config.confirmationTimeoutMs ?? DEFAULT_CONFIRMATION_TIMEOUT_MS;
616
- this.simulateBeforeSubmit = config.simulateBeforeSubmit ?? config.provider !== void 0;
617
- }
618
- /** Address the operator wallet is broadcasting from (for logging). */
619
- operatorAddress() {
620
- return this.operatorWallet.account?.address;
621
- }
622
- /**
623
- * Build calldata for the Relay `mintAndSwap` function. Kept public so
624
- * callers (e.g. the MintingGateway) can log or persist the encoded call
625
- * for audit before broadcasting.
626
- */
627
- encodeCall(params) {
628
- try {
629
- return encodeMintAndSwap(params.mint, params.swap);
630
- } catch (err) {
631
- throw new RelayError(
632
- "ENCODE_FAILED",
633
- `Failed to encode mintAndSwap calldata: ${errorMessage(err)}`,
634
- err
635
- );
636
- }
637
- }
638
- /**
639
- * Submit a `mintAndSwap` transaction (legacy v0.2 `/claim-and-swap`).
640
- *
641
- * @deprecated Since 0.3.0 — replaced by `prepareMint` / `prepareBurn`
642
- * in the v1.4 sponsored-UserOp flow. Kept for v0.2.x consumers;
643
- * scheduled removal in 2.0.
644
- */
645
- async submitMintAndSwap(params) {
646
- if (this.simulateBeforeSubmit && this.provider) {
647
- const operatorAddr = this.operatorWallet.account?.address;
648
- if (operatorAddr) {
649
- try {
650
- await coreSimulateMintAndSwap(
651
- this.provider,
652
- this.relayAddress,
653
- params.mint,
654
- params.swap,
655
- operatorAddr
656
- );
657
- } catch (err) {
658
- const reason = err instanceof SimulationError ? err.reason : errorMessage(err);
659
- throw new RelayError(
660
- "SIMULATION_FAILED",
661
- `mintAndSwap would revert: ${reason}`,
662
- err
663
- );
664
- }
665
- }
666
- }
667
- let txHash;
668
- try {
669
- txHash = await this.operatorWallet.writeContract({
670
- address: this.relayAddress,
671
- abi: relayAbi,
672
- functionName: "mintAndSwap",
673
- args: [params.mint, params.swap],
674
- ...this.operatorWallet.account ? { account: this.operatorWallet.account } : {}
675
- });
676
- } catch (err) {
677
- throw new RelayError(
678
- "SUBMIT_FAILED",
679
- `Failed to broadcast mintAndSwap: ${errorMessage(err)}`,
680
- err
681
- );
682
- }
683
- if (!this.provider) {
684
- return { txHash };
685
- }
686
- try {
687
- const receipt = await this.provider.waitForTransactionReceipt({
688
- hash: txHash,
689
- timeout: this.confirmationTimeoutMs
690
- });
691
- if (receipt.status !== "success") {
692
- throw new RelayError(
693
- "TX_REVERTED",
694
- `mintAndSwap reverted on-chain (tx=${txHash})`
695
- );
696
- }
697
- return {
698
- txHash,
699
- blockNumber: receipt.blockNumber,
700
- gasUsed: receipt.gasUsed,
701
- status: receipt.status
702
- };
703
- } catch (err) {
704
- if (err instanceof RelayError) throw err;
705
- throw new RelayError(
706
- "TIMEOUT",
707
- `Timed out waiting for mintAndSwap receipt (tx=${txHash}): ${errorMessage(err)}`,
708
- err
709
- );
710
- }
711
- }
712
- // ==========================================================================
713
- // v1.4 — Sponsored UserOp preparation (sig-gated mint + burn)
714
- // ==========================================================================
715
595
  /**
716
596
  * Build an unsigned UserOp for Scenario 1 (Mint) — sig-gated
717
597
  * `PointToken.mint(to, amount, deadline, minterSig)`.
718
- *
719
- * Flow:
720
- * 1. Issuer backend signs `MintRequest(to=user, amount, nonce, deadline)`
721
- * with its minter signer (HSM/KMS) → `minterSig`.
722
- * 2. Encode `PointToken.mint(user, amount, deadline, minterSig)`.
723
- * On-chain, `msg.sender` must equal `to` — satisfied by EIP-7702
724
- * delegating the user EOA to BatchExecutor.
725
- * 3. Optional PT fee transfer appended after mint (application-level
726
- * fee recovery since Relayer v2 no longer exists).
727
- * 4. Return `PartialUserOperation` ready for Bundler gas estimate +
728
- * Paymaster sponsorship + user signature.
729
598
  */
730
599
  async prepareMint(params) {
731
600
  if (!params.batchExecutorAddress) {
@@ -829,12 +698,11 @@ var RelayService = class {
829
698
  *
830
699
  * Two modes:
831
700
  * - `mode: 'burn'` — direct `PointToken.burn(from, amount)`; only
832
- * usable if the user is a whitelisted burner. Not the typical
833
- * v1.4 path (users aren't burners); kept for admin/operator tools.
701
+ * usable if the caller (via EIP-7702) is whitelisted as a burner.
702
+ * Rare in v1.4; kept for admin/operator tools.
834
703
  * - `mode: 'burnWithSig'` — `PointToken.burn(from, amount, deadline,
835
- * burnerSig)`. Issuer signs `BurnRequest` off-chain; user submits
836
- * via EIP-7702. `msg.sender == from` enforced on-chain. This is
837
- * the user-initiated redeem path in v1.4.
704
+ * burnerSig)`. Caller provides a pre-signed `BurnRequest` + sig
705
+ * bytes (typically from `PTRedeemHandler`).
838
706
  */
839
707
  prepareBurn(params) {
840
708
  if (!params.pointTokenAddress) {
@@ -936,255 +804,6 @@ var FeeManager = class {
936
804
  }
937
805
  };
938
806
 
939
- // src/gateway/types.ts
940
- var MintingGatewayError = class extends Error {
941
- code;
942
- /**
943
- * True if the ledger lock was released before this error was thrown,
944
- * meaning the user can safely retry. False means the funds are still
945
- * locked (e.g. tx may still land on-chain) and retry would double-spend.
946
- */
947
- safeToRetry;
948
- cause;
949
- constructor(code, message, opts) {
950
- super(message);
951
- this.name = "MintingGatewayError";
952
- this.code = code;
953
- this.safeToRetry = opts.safeToRetry;
954
- if (opts.cause !== void 0) this.cause = opts.cause;
955
- }
956
- };
957
-
958
- // src/gateway/mintingGateway.ts
959
- import {
960
- verifyReceiverConsent,
961
- encodeExtData
962
- } from "@pafi-dev/core";
963
- var DEFAULT_LOCK_BUFFER_MS = 6e4;
964
- var MintingGateway = class {
965
- ledger;
966
- policy;
967
- signer;
968
- relayService;
969
- now;
970
- defaultLockBufferMs;
971
- constructor(config) {
972
- if (!config.ledger) throw new Error("MintingGateway: ledger required");
973
- if (!config.policy) throw new Error("MintingGateway: policy required");
974
- if (!config.signer) throw new Error("MintingGateway: signer required");
975
- if (!config.relayService)
976
- throw new Error("MintingGateway: relayService required");
977
- this.ledger = config.ledger;
978
- this.policy = config.policy;
979
- this.signer = config.signer;
980
- this.relayService = config.relayService;
981
- this.now = config.now ?? (() => Date.now());
982
- this.defaultLockBufferMs = config.defaultLockBufferMs ?? DEFAULT_LOCK_BUFFER_MS;
983
- }
984
- /**
985
- * @deprecated Since 0.3.0 — will be renamed to `processMint()` once
986
- * the SC team finalizes Relayer v2 ABI. The new flow drops the
987
- * swap steps entirely (no more single-call mint+swap); users swap
988
- * separately on PAFI Web. Kept here for v0.2.x consumers. Removed in 2.0.
989
- */
990
- async processMintAndCashOut(request) {
991
- const { receiverConsent, receiverSignature } = request;
992
- if (!receiverConsent || !receiverSignature) {
993
- throw new MintingGatewayError(
994
- "INVALID_REQUEST",
995
- "receiverConsent and receiverSignature are required",
996
- { safeToRetry: true }
997
- );
998
- }
999
- if (receiverConsent.amount <= 0n) {
1000
- throw new MintingGatewayError(
1001
- "INVALID_REQUEST",
1002
- "consent amount must be positive",
1003
- { safeToRetry: true }
1004
- );
1005
- }
1006
- if (receiverConsent.originalReceiver !== request.userAddress) {
1007
- throw new MintingGatewayError(
1008
- "INVALID_REQUEST",
1009
- "consent.originalReceiver must equal request.userAddress",
1010
- { safeToRetry: true }
1011
- );
1012
- }
1013
- const nowSec = BigInt(Math.floor(this.now() / 1e3));
1014
- if (receiverConsent.deadline <= nowSec) {
1015
- throw new MintingGatewayError(
1016
- "CONSENT_EXPIRED",
1017
- "ReceiverConsent deadline has already passed",
1018
- { safeToRetry: true }
1019
- );
1020
- }
1021
- const consentResult = await verifyReceiverConsent(
1022
- request.domain,
1023
- receiverConsent,
1024
- receiverSignature,
1025
- request.userAddress
1026
- );
1027
- if (!consentResult.isValid) {
1028
- throw new MintingGatewayError(
1029
- "INVALID_CONSENT_SIGNATURE",
1030
- `ReceiverConsent signature did not recover to ${request.userAddress}`,
1031
- { safeToRetry: true }
1032
- );
1033
- }
1034
- const policyDecision = await this.policy.evaluate({
1035
- userAddress: request.userAddress,
1036
- amount: receiverConsent.amount,
1037
- pointTokenAddress: request.pointTokenAddress,
1038
- chainId: request.chainId
1039
- });
1040
- if (!policyDecision.approved) {
1041
- const code = policyDecision.reason?.toLowerCase().includes("insufficient") ? "INSUFFICIENT_BALANCE" : "POLICY_REJECTED";
1042
- throw new MintingGatewayError(
1043
- code,
1044
- policyDecision.reason ?? "Minting request rejected by policy engine",
1045
- { safeToRetry: true }
1046
- );
1047
- }
1048
- const lockDurationMs = request.lockDurationMs ?? this.computeLockDurationMs(receiverConsent.deadline);
1049
- let lockId;
1050
- try {
1051
- lockId = await this.ledger.lockForMinting(
1052
- request.userAddress,
1053
- receiverConsent.amount,
1054
- lockDurationMs,
1055
- request.pointTokenAddress
1056
- );
1057
- } catch (err) {
1058
- throw new MintingGatewayError(
1059
- "INSUFFICIENT_BALANCE",
1060
- `Failed to lock ledger balance: ${errorMessage2(err)}`,
1061
- { safeToRetry: true, cause: err }
1062
- );
1063
- }
1064
- try {
1065
- let minterSignature;
1066
- try {
1067
- minterSignature = await this.signer.signMintRequest(request.domain, {
1068
- to: request.userAddress,
1069
- amount: receiverConsent.amount,
1070
- nonce: receiverConsent.nonce,
1071
- deadline: receiverConsent.deadline
1072
- });
1073
- } catch (err) {
1074
- await this.releaseLockSafely(lockId);
1075
- throw new MintingGatewayError(
1076
- "SIGNER_FAILED",
1077
- `Issuer signer failed: ${errorMessage2(err)}`,
1078
- { safeToRetry: true, cause: err }
1079
- );
1080
- }
1081
- const mintParams = {
1082
- pointToken: request.pointTokenAddress,
1083
- receiver: request.userAddress,
1084
- amount: receiverConsent.amount,
1085
- deadline: receiverConsent.deadline,
1086
- minterSig: minterSignature.serialized,
1087
- receiverSig: receiverSignature,
1088
- extData: receiverConsent.extData
1089
- };
1090
- const swapParams = {
1091
- path: request.swapPath,
1092
- deadline: request.swapDeadline
1093
- };
1094
- let relayResult;
1095
- try {
1096
- relayResult = await this.relayService.submitMintAndSwap({
1097
- mint: mintParams,
1098
- swap: swapParams
1099
- });
1100
- } catch (err) {
1101
- await this.handleRelayFailure(err, lockId);
1102
- }
1103
- const result = {
1104
- txHash: relayResult.txHash,
1105
- lockId
1106
- };
1107
- if (relayResult.blockNumber !== void 0) {
1108
- result.blockNumber = relayResult.blockNumber;
1109
- }
1110
- if (relayResult.gasUsed !== void 0) {
1111
- result.gasUsed = relayResult.gasUsed;
1112
- }
1113
- return result;
1114
- } catch (err) {
1115
- if (err instanceof MintingGatewayError) throw err;
1116
- await this.releaseLockSafely(lockId);
1117
- throw new MintingGatewayError(
1118
- "RELAY_SUBMIT_FAILED",
1119
- `Unexpected error: ${errorMessage2(err)}`,
1120
- { safeToRetry: true, cause: err }
1121
- );
1122
- }
1123
- }
1124
- // ---------------------------------------------------------------------------
1125
- // Internals
1126
- // ---------------------------------------------------------------------------
1127
- computeLockDurationMs(consentDeadlineSec) {
1128
- const nowMs = this.now();
1129
- const deadlineMs = Number(consentDeadlineSec) * 1e3;
1130
- const remaining = Math.max(0, deadlineMs - nowMs);
1131
- return remaining + this.defaultLockBufferMs;
1132
- }
1133
- /**
1134
- * Map a RelayError to a MintingGatewayError, releasing the lock only
1135
- * when the tx definitely did not land. `TX_REVERTED` and `TIMEOUT`
1136
- * leave the lock in place because the tx may still be in the mempool
1137
- * or already mined — releasing would enable a double-spend on retry.
1138
- * Always throws.
1139
- */
1140
- async handleRelayFailure(err, lockId) {
1141
- if (err instanceof RelayError) {
1142
- switch (err.code) {
1143
- case "ENCODE_FAILED":
1144
- case "SIMULATION_FAILED":
1145
- case "SUBMIT_FAILED":
1146
- case "NOT_CONFIGURED":
1147
- await this.releaseLockSafely(lockId);
1148
- throw new MintingGatewayError(
1149
- err.code === "SIMULATION_FAILED" ? "RELAY_SIMULATION_FAILED" : "RELAY_SUBMIT_FAILED",
1150
- err.message,
1151
- { safeToRetry: true, cause: err }
1152
- );
1153
- case "TX_REVERTED":
1154
- throw new MintingGatewayError("RELAY_REVERTED", err.message, {
1155
- safeToRetry: false,
1156
- cause: err
1157
- });
1158
- case "TIMEOUT":
1159
- throw new MintingGatewayError("RELAY_TIMEOUT", err.message, {
1160
- safeToRetry: false,
1161
- cause: err
1162
- });
1163
- }
1164
- }
1165
- await this.releaseLockSafely(lockId);
1166
- throw new MintingGatewayError(
1167
- "RELAY_SUBMIT_FAILED",
1168
- `Unexpected relay error: ${errorMessage2(err)}`,
1169
- { safeToRetry: true, cause: err }
1170
- );
1171
- }
1172
- /**
1173
- * Release a lock, swallowing any secondary error. We never want a lock
1174
- * release failure to mask the original error — the lock will auto-expire
1175
- * via TTL anyway.
1176
- */
1177
- async releaseLockSafely(lockId) {
1178
- try {
1179
- await this.ledger.releaseLock(lockId);
1180
- } catch {
1181
- }
1182
- }
1183
- };
1184
- function errorMessage2(err) {
1185
- return err instanceof Error ? err.message : String(err);
1186
- }
1187
-
1188
807
  // src/indexer/types.ts
1189
808
  var InMemoryCursorStore = class {
1190
809
  cursor;
@@ -1539,7 +1158,6 @@ import {
1539
1158
  } from "@pafi-dev/core";
1540
1159
  var IssuerApiHandlers = class {
1541
1160
  authService;
1542
- gateway;
1543
1161
  ledger;
1544
1162
  provider;
1545
1163
  /**
@@ -1558,7 +1176,6 @@ var IssuerApiHandlers = class {
1558
1176
  poolsProvider;
1559
1177
  constructor(config) {
1560
1178
  this.authService = config.authService;
1561
- this.gateway = config.gateway;
1562
1179
  this.ledger = config.ledger;
1563
1180
  this.provider = config.provider;
1564
1181
  const raw = config.pointTokenAddresses && config.pointTokenAddresses.length > 0 ? config.pointTokenAddresses : config.pointTokenAddress ? [config.pointTokenAddress] : [];
@@ -1740,49 +1357,6 @@ var IssuerApiHandlers = class {
1740
1357
  }
1741
1358
  };
1742
1359
  }
1743
- /**
1744
- * `POST /claim-and-swap`
1745
- *
1746
- * @deprecated Since 0.3.0 — the single-call mint-then-swap flow is
1747
- * retired in v1.4. Use the new `handleClaim()` (mint only) and let
1748
- * the user swap separately on PAFI Web. See
1749
- * [V1.4_V1.5_OVERVIEW.md §4] for the new scenario model. Will be
1750
- * removed in 2.0.
1751
- *
1752
- * Legacy behavior: the terminal handler forwards the verified
1753
- * consent to the MintingGateway, which runs the 11-step flow.
1754
- */
1755
- async handleClaimAndSwap(userAddress, request) {
1756
- if (request.chainId !== this.chainId) {
1757
- throw new Error(
1758
- `handleClaimAndSwap: unsupported chainId ${request.chainId}`
1759
- );
1760
- }
1761
- const pointToken = getAddress6(request.pointTokenAddress);
1762
- if (!this.supportedTokens.has(pointToken)) {
1763
- throw new Error(
1764
- `handleClaimAndSwap: unsupported pointToken ${pointToken}`
1765
- );
1766
- }
1767
- const result = await this.gateway.processMintAndCashOut({
1768
- userAddress: getAddress6(userAddress),
1769
- pointTokenAddress: pointToken,
1770
- chainId: request.chainId,
1771
- domain: request.domain,
1772
- receiverConsent: request.receiverConsent,
1773
- receiverSignature: request.receiverSignature,
1774
- swapPath: request.swapPath,
1775
- swapDeadline: request.swapDeadline
1776
- });
1777
- const response = {
1778
- txHash: result.txHash,
1779
- lockId: result.lockId
1780
- };
1781
- if (result.blockNumber !== void 0)
1782
- response.blockNumber = result.blockNumber;
1783
- if (result.gasUsed !== void 0) response.gasUsed = result.gasUsed;
1784
- return response;
1785
- }
1786
1360
  };
1787
1361
 
1788
1362
  // src/api/handlers/ptRedeemHandler.ts
@@ -2445,15 +2019,6 @@ function createIssuerService(config) {
2445
2019
  if (!config.provider) {
2446
2020
  throw new Error("createIssuerService: provider is required");
2447
2021
  }
2448
- if (!config.operatorWallet) {
2449
- throw new Error("createIssuerService: operatorWallet is required");
2450
- }
2451
- if (!config.signer) {
2452
- throw new Error("createIssuerService: signer is required");
2453
- }
2454
- if (!config.relayAddress) {
2455
- throw new Error("createIssuerService: relayAddress is required");
2456
- }
2457
2022
  if (!config.auth?.jwtSecret) {
2458
2023
  throw new Error("createIssuerService: auth.jwtSecret is required");
2459
2024
  }
@@ -2480,18 +2045,7 @@ function createIssuerService(config) {
2480
2045
  authServiceConfig.jwtExpiresIn = config.auth.jwtExpiresIn;
2481
2046
  }
2482
2047
  const authService = new AuthService(authServiceConfig);
2483
- const relayServiceConfig = {
2484
- relayAddress: config.relayAddress,
2485
- operatorWallet: config.operatorWallet,
2486
- provider: config.provider
2487
- };
2488
- if (config.relay?.simulateBeforeSubmit !== void 0) {
2489
- relayServiceConfig.simulateBeforeSubmit = config.relay.simulateBeforeSubmit;
2490
- }
2491
- if (config.relay?.confirmationTimeoutMs !== void 0) {
2492
- relayServiceConfig.confirmationTimeoutMs = config.relay.confirmationTimeoutMs;
2493
- }
2494
- const relayService = new RelayService(relayServiceConfig);
2048
+ const relayService = new RelayService();
2495
2049
  let feeManager;
2496
2050
  if (config.fee) {
2497
2051
  feeManager = new FeeManager({
@@ -2499,16 +2053,6 @@ function createIssuerService(config) {
2499
2053
  provider: config.provider
2500
2054
  });
2501
2055
  }
2502
- const gatewayConfig = {
2503
- ledger,
2504
- policy,
2505
- signer: config.signer,
2506
- relayService
2507
- };
2508
- if (config.gateway?.defaultLockBufferMs !== void 0) {
2509
- gatewayConfig.defaultLockBufferMs = config.gateway.defaultLockBufferMs;
2510
- }
2511
- const gateway = new MintingGateway(gatewayConfig);
2512
2056
  const indexers = /* @__PURE__ */ new Map();
2513
2057
  for (const tokenAddress of tokenAddresses) {
2514
2058
  const indexerConfig = {
@@ -2536,7 +2080,6 @@ function createIssuerService(config) {
2536
2080
  const firstIndexer = indexers.get(tokenAddresses[0]);
2537
2081
  const handlersConfig = {
2538
2082
  authService,
2539
- gateway,
2540
2083
  ledger,
2541
2084
  provider: config.provider,
2542
2085
  pointTokenAddresses: tokenAddresses,
@@ -2556,10 +2099,8 @@ function createIssuerService(config) {
2556
2099
  sessionStore,
2557
2100
  ledger,
2558
2101
  policy,
2559
- signer: config.signer,
2560
2102
  relayService,
2561
2103
  feeManager,
2562
- gateway,
2563
2104
  indexers,
2564
2105
  indexer: firstIndexer,
2565
2106
  handlers
@@ -2579,8 +2120,6 @@ export {
2579
2120
  IssuerApiHandlers,
2580
2121
  MemoryPointLedger,
2581
2122
  MemorySessionStore,
2582
- MintingGateway,
2583
- MintingGatewayError,
2584
2123
  NonceManager,
2585
2124
  PAFI_ISSUER_SDK_VERSION,
2586
2125
  PTRedeemError,
@@ -2596,7 +2135,6 @@ export {
2596
2135
  authenticateRequest,
2597
2136
  createIssuerService,
2598
2137
  createSubgraphNativeUsdtQuoter,
2599
- createSubgraphPoolsProvider,
2600
- encodeExtData
2138
+ createSubgraphPoolsProvider
2601
2139
  };
2602
2140
  //# sourceMappingURL=index.js.map