@pafi-dev/issuer 0.5.42 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -570,15 +570,13 @@ var RelayService = class {
570
570
  });
571
571
  }
572
572
  /**
573
- * Build an unsigned UserOp for Scenario 2 (Burn/Redeem).
573
+ * Build an unsigned UserOp for Scenario 2 (Burn/Redeem) — sig-gated
574
+ * `PointToken.burn(from, amount, deadline, burnerSig)`. Caller
575
+ * provides a pre-signed `BurnRequest` + sig bytes (typically from
576
+ * `PTRedeemHandler`).
574
577
  *
575
- * Two modes:
576
- * - `mode: 'burn'` — direct `PointToken.burn(from, amount)`; only
577
- * usable if the caller (via EIP-7702) is whitelisted as a burner.
578
- * Rare in v1.4; kept for admin/operator tools.
579
- * - `mode: 'burnWithSig'` — `PointToken.burn(from, amount, deadline,
580
- * burnerSig)`. Caller provides a pre-signed `BurnRequest` + sig
581
- * bytes (typically from `PTRedeemHandler`).
578
+ * Direct burn (no sig) was dropped in v1.4 — every burn now goes
579
+ * through the issuer-signed `BurnRequest` path.
582
580
  */
583
581
  async prepareBurn(params) {
584
582
  if (!params.pointTokenAddress) {
@@ -590,29 +588,24 @@ var RelayService = class {
590
588
  "prepareBurn: batchExecutorAddress required"
591
589
  );
592
590
  }
591
+ if (!params.burnRequest || !params.burnerSignature) {
592
+ throw new RelayError(
593
+ "ENCODE_FAILED",
594
+ "prepareBurn: burnRequest + burnerSignature required"
595
+ );
596
+ }
593
597
  let burnCallData;
594
598
  try {
595
- if (params.mode === "burnWithSig") {
596
- if (!params.burnRequest || !params.burnerSignature) {
597
- throw new Error("burnWithSig requires burnRequest + burnerSignature");
598
- }
599
- burnCallData = encodeFunctionData({
600
- abi: POINT_TOKEN_V2_ABI,
601
- functionName: "burn",
602
- args: [
603
- params.burnRequest.from,
604
- params.burnRequest.amount,
605
- params.burnRequest.deadline,
606
- params.burnerSignature
607
- ]
608
- });
609
- } else {
610
- burnCallData = encodeFunctionData({
611
- abi: POINT_TOKEN_V2_ABI,
612
- functionName: "burn",
613
- args: [params.userAddress, params.amount]
614
- });
615
- }
599
+ burnCallData = encodeFunctionData({
600
+ abi: POINT_TOKEN_V2_ABI,
601
+ functionName: "burn",
602
+ args: [
603
+ params.burnRequest.from,
604
+ params.burnRequest.amount,
605
+ params.burnRequest.deadline,
606
+ params.burnerSignature
607
+ ]
608
+ });
616
609
  } catch (err) {
617
610
  throw new RelayError(
618
611
  "ENCODE_FAILED",
@@ -1069,7 +1062,6 @@ import {
1069
1062
  getMintRequestNonce,
1070
1063
  getPointTokenBalance,
1071
1064
  getReceiverConsentNonce,
1072
- getTokenName,
1073
1065
  isMinter
1074
1066
  } from "@pafi-dev/core";
1075
1067
  var IssuerApiHandlers = class {
@@ -1086,7 +1078,6 @@ var IssuerApiHandlers = class {
1086
1078
  pafiWebUrl;
1087
1079
  feeManager;
1088
1080
  poolsProvider;
1089
- claim;
1090
1081
  constructor(config) {
1091
1082
  this.authService = config.authService;
1092
1083
  this.ledger = config.ledger;
@@ -1104,7 +1095,6 @@ var IssuerApiHandlers = class {
1104
1095
  if (config.pafiWebUrl) this.pafiWebUrl = config.pafiWebUrl;
1105
1096
  if (config.feeManager) this.feeManager = config.feeManager;
1106
1097
  if (config.poolsProvider) this.poolsProvider = config.poolsProvider;
1107
- if (config.claim) this.claim = config.claim;
1108
1098
  }
1109
1099
  // =========================================================================
1110
1100
  // Public handlers (no auth required)
@@ -1238,91 +1228,9 @@ var IssuerApiHandlers = class {
1238
1228
  isMinter: minter
1239
1229
  };
1240
1230
  }
1241
- /**
1242
- * `POST /claim`
1243
- *
1244
- * Policy gate + ledger lock + MintRequest signing in a single atomic
1245
- * step. Returns an unsigned UserOp the frontend attaches paymaster data
1246
- * to and submits via EIP-7702 + Bundler.
1247
- *
1248
- * Order of operations:
1249
- * 1. Validate request fields.
1250
- * 2. policy.evaluate() — throws if denied; cannot be bypassed.
1251
- * 3. ledger.lockForMinting() — reserves the balance.
1252
- * 4. Read on-chain mintRequestNonce + token name in parallel.
1253
- * 5. relayService.prepareMint() — sign MintRequest + encode UserOp.
1254
- * 6. On any error after step 3, release the lock before re-throwing.
1255
- */
1256
- async handleClaim(userAddress, request) {
1257
- if (!this.claim) {
1258
- throw new Error("handleClaim: claim is not configured on this issuer");
1259
- }
1260
- if (request.chainId !== this.chainId) {
1261
- throw new Error(`handleClaim: unsupported chainId ${request.chainId}`);
1262
- }
1263
- const pointToken = getAddress5(request.pointTokenAddress);
1264
- if (!this.supportedTokens.has(pointToken)) {
1265
- throw new Error(`handleClaim: unsupported pointToken ${pointToken}`);
1266
- }
1267
- if (request.amount <= 0n) {
1268
- throw new Error("handleClaim: amount must be positive");
1269
- }
1270
- const nowSecs = BigInt(Math.floor(Date.now() / 1e3));
1271
- if (request.deadline <= nowSecs) {
1272
- throw new Error("handleClaim: deadline is in the past");
1273
- }
1274
- const { policy, relayService, issuerSignerWallet, batchExecutorAddress } = this.claim;
1275
- const lockDurationMs = this.claim.lockDurationMs ?? 15 * 60 * 1e3;
1276
- const normalizedUser = getAddress5(userAddress);
1277
- const decision = await policy.evaluate({
1278
- userAddress: normalizedUser,
1279
- amount: request.amount,
1280
- pointTokenAddress: pointToken,
1281
- chainId: this.chainId
1282
- });
1283
- if (!decision.approved) {
1284
- throw new Error(`handleClaim: policy denied \u2014 ${decision.reason ?? "no reason given"}`);
1285
- }
1286
- const lockId = await this.ledger.lockForMinting(
1287
- normalizedUser,
1288
- request.amount,
1289
- lockDurationMs,
1290
- pointToken
1291
- );
1292
- try {
1293
- const [mintRequestNonce, tokenName] = await Promise.all([
1294
- getMintRequestNonce(this.provider, pointToken, normalizedUser),
1295
- getTokenName(this.provider, pointToken)
1296
- ]);
1297
- const domain = {
1298
- name: tokenName,
1299
- verifyingContract: pointToken,
1300
- chainId: this.chainId
1301
- };
1302
- const userOp = await relayService.prepareMint({
1303
- userAddress: normalizedUser,
1304
- aaNonce: request.aaNonce,
1305
- batchExecutorAddress,
1306
- pointTokenAddress: pointToken,
1307
- amount: request.amount,
1308
- issuerSignerWallet,
1309
- domain,
1310
- mintRequestNonce,
1311
- deadline: request.deadline,
1312
- feeAmount: request.feeAmount,
1313
- feeRecipient: request.feeRecipient
1314
- });
1315
- return {
1316
- lockId,
1317
- userOp,
1318
- expiresInSeconds: Math.floor(lockDurationMs / 1e3)
1319
- };
1320
- } catch (err) {
1321
- await this.ledger.releaseLock(lockId).catch(() => {
1322
- });
1323
- throw err;
1324
- }
1325
- }
1231
+ // Note: legacy `handleClaim` (sync sponsored-claim returning calls[]) was
1232
+ // removed in 0.5.43 — callers should use `PTClaimHandler` directly or
1233
+ // wire `IssuerApiAdapter.claim()` which composes the full flow.
1326
1234
  };
1327
1235
 
1328
1236
  // src/api/handlers/ptRedeemHandler.ts
@@ -1566,70 +1474,6 @@ var PTRedeemHandler = class {
1566
1474
  }
1567
1475
  };
1568
1476
 
1569
- // src/api/handlers/topUpRedemptionHandler.ts
1570
- import { getAddress as getAddress7 } from "viem";
1571
- import { getPointTokenBalance as getPointTokenBalance3 } from "@pafi-dev/core";
1572
- var TopUpRedemptionError = class extends Error {
1573
- constructor(code, message) {
1574
- super(message);
1575
- this.code = code;
1576
- this.name = "TopUpRedemptionError";
1577
- }
1578
- code;
1579
- };
1580
- var TopUpRedemptionHandler = class {
1581
- ledger;
1582
- ptRedeemHandler;
1583
- provider;
1584
- pointTokenAddress;
1585
- constructor(config) {
1586
- this.ledger = config.ledger;
1587
- this.ptRedeemHandler = config.ptRedeemHandler;
1588
- this.provider = config.provider;
1589
- this.pointTokenAddress = getAddress7(config.pointTokenAddress);
1590
- }
1591
- async handle(request) {
1592
- if (getAddress7(request.authenticatedAddress) !== getAddress7(request.userAddress)) {
1593
- throw new TopUpRedemptionError(
1594
- "UNAUTHORIZED",
1595
- `userAddress (${request.userAddress}) does not match authenticated session (${request.authenticatedAddress})`
1596
- );
1597
- }
1598
- const offChainBalance = await this.ledger.getBalance(
1599
- request.userAddress,
1600
- this.pointTokenAddress
1601
- );
1602
- if (offChainBalance >= request.requiredAmount) {
1603
- return { action: "NO_TOP_UP_NEEDED", offChainBalance };
1604
- }
1605
- const shortfall = request.requiredAmount - offChainBalance;
1606
- const onChainBalance = await getPointTokenBalance3(
1607
- this.provider,
1608
- this.pointTokenAddress,
1609
- request.userAddress
1610
- );
1611
- if (onChainBalance < shortfall) {
1612
- return {
1613
- action: "INSUFFICIENT_ONCHAIN",
1614
- offChainBalance,
1615
- onChainBalance,
1616
- shortfall
1617
- };
1618
- }
1619
- const redeem = await this.ptRedeemHandler.handle({
1620
- authenticatedAddress: request.authenticatedAddress,
1621
- userAddress: request.userAddress,
1622
- amount: shortfall,
1623
- aaNonce: request.aaNonce
1624
- });
1625
- return {
1626
- action: "TOP_UP_STARTED",
1627
- shortfall,
1628
- redeem
1629
- };
1630
- }
1631
- };
1632
-
1633
1477
  // src/api/statusHandlers.ts
1634
1478
  var LockNotFoundError = class extends PafiSdkError {
1635
1479
  code = "LOCK_NOT_FOUND";
@@ -1731,7 +1575,7 @@ async function handleRedeemStatus(params) {
1731
1575
  }
1732
1576
 
1733
1577
  // src/api/mobileHandlers.ts
1734
- import { getAddress as getAddress8 } from "viem";
1578
+ import { getAddress as getAddress7 } from "viem";
1735
1579
  import {
1736
1580
  ENTRY_POINT_V08,
1737
1581
  parseEip7702DelegatedAddress
@@ -1780,6 +1624,33 @@ function serializeEntryToJsonRpc(entry, signature, variant = "sponsored") {
1780
1624
  );
1781
1625
  }
1782
1626
 
1627
+ // src/userop-store/memoryStore.ts
1628
+ var MemoryPendingUserOpStore = class {
1629
+ entries = /* @__PURE__ */ new Map();
1630
+ now;
1631
+ constructor(now = () => Date.now()) {
1632
+ this.now = now;
1633
+ }
1634
+ async save(lockId, entry, ttlSeconds) {
1635
+ this.entries.set(lockId, {
1636
+ entry,
1637
+ expiresAt: this.now() + ttlSeconds * 1e3
1638
+ });
1639
+ }
1640
+ async get(lockId) {
1641
+ const hit = this.entries.get(lockId);
1642
+ if (!hit) return null;
1643
+ if (hit.expiresAt <= this.now()) {
1644
+ this.entries.delete(lockId);
1645
+ return null;
1646
+ }
1647
+ return hit.entry;
1648
+ }
1649
+ async delete(lockId) {
1650
+ this.entries.delete(lockId);
1651
+ }
1652
+ };
1653
+
1783
1654
  // src/userop-store/prepareUserOp.ts
1784
1655
  import {
1785
1656
  buildUserOpTypedData,
@@ -2001,7 +1872,7 @@ async function handleMobileSubmit(params) {
2001
1872
  if (!entry) {
2002
1873
  throw new PendingUserOpNotFoundError(params.lockId);
2003
1874
  }
2004
- if (getAddress8(entry.sender) !== getAddress8(params.authenticatedAddress)) {
1875
+ if (getAddress7(entry.sender) !== getAddress7(params.authenticatedAddress)) {
2005
1876
  throw new PendingUserOpForbiddenError(params.lockId);
2006
1877
  }
2007
1878
  const variant = params.variant ?? "sponsored";
@@ -2017,7 +1888,7 @@ async function handleMobileSubmit(params) {
2017
1888
  }
2018
1889
 
2019
1890
  // src/api/handlers/ptClaimHandler.ts
2020
- import { getAddress as getAddress9 } from "viem";
1891
+ import { getAddress as getAddress8 } from "viem";
2021
1892
  import {
2022
1893
  decodeBatchExecuteCalls,
2023
1894
  getContractAddresses as getContractAddresses3
@@ -2061,7 +1932,7 @@ var PTClaimHandler = class {
2061
1932
  };
2062
1933
  }
2063
1934
  async handle(request) {
2064
- if (getAddress9(request.authenticatedAddress) !== getAddress9(request.userAddress)) {
1935
+ if (getAddress8(request.authenticatedAddress) !== getAddress8(request.userAddress)) {
2065
1936
  throw new PTClaimError(
2066
1937
  "VALIDATION_FAILED",
2067
1938
  `userAddress (${request.userAddress}) does not match authenticated session (${request.authenticatedAddress})`
@@ -2159,143 +2030,6 @@ var PTClaimHandler = class {
2159
2030
  }
2160
2031
  };
2161
2032
 
2162
- // src/api/handlers/swapHandler.ts
2163
- import {
2164
- buildSwapWithGasDeduction,
2165
- decodeBatchExecuteCalls as decodeBatchExecuteCalls2,
2166
- findBestQuote,
2167
- getContractAddresses as getContractAddresses4
2168
- } from "@pafi-dev/core";
2169
- var SwapError = class extends PafiSdkError {
2170
- httpStatus = "unprocessable";
2171
- code;
2172
- constructor(code, message) {
2173
- super(message);
2174
- this.code = code;
2175
- }
2176
- };
2177
- var DEFAULT_SLIPPAGE_BPS = 50;
2178
- var DEFAULT_SWAP_DEADLINE_SEC = 5 * 60;
2179
- var SwapHandler = class {
2180
- cfg;
2181
- constructor(config) {
2182
- this.cfg = {
2183
- ...config,
2184
- defaultSlippageBps: config.defaultSlippageBps ?? DEFAULT_SLIPPAGE_BPS,
2185
- defaultSwapDeadlineSeconds: config.defaultSwapDeadlineSeconds ?? DEFAULT_SWAP_DEADLINE_SEC,
2186
- now: config.now ?? (() => Date.now())
2187
- };
2188
- }
2189
- async handle(request) {
2190
- if (request.amountIn <= 0n) {
2191
- throw new SwapError("INVALID_AMOUNT", "amountIn must be positive");
2192
- }
2193
- const slippageBps = request.slippageBps ?? this.cfg.defaultSlippageBps;
2194
- const { usdt, pafiFeeRecipient, universalRouter } = getContractAddresses4(
2195
- request.chainId
2196
- );
2197
- const poolsResponse = await this.cfg.poolsProvider({
2198
- chainId: request.chainId,
2199
- pointTokenAddress: request.pointTokenAddress
2200
- });
2201
- if (poolsResponse.pools.length === 0) {
2202
- throw new SwapError(
2203
- "QUOTE_UNAVAILABLE",
2204
- "no liquidity pool found for this point token"
2205
- );
2206
- }
2207
- let fallbackQuote;
2208
- try {
2209
- fallbackQuote = await findBestQuote(
2210
- this.cfg.provider,
2211
- request.chainId,
2212
- request.pointTokenAddress,
2213
- usdt,
2214
- request.amountIn,
2215
- poolsResponse.pools
2216
- );
2217
- } catch {
2218
- throw new SwapError(
2219
- "QUOTE_UNAVAILABLE",
2220
- "no swap path found for this point token"
2221
- );
2222
- }
2223
- const estimatedUsdtOutFallback = fallbackQuote.bestRoute.amountOut;
2224
- const minAmountOutFallback = estimatedUsdtOutFallback * BigInt(1e4 - slippageBps) / 10000n;
2225
- const deadline = request.deadline ?? BigInt(
2226
- Math.floor(this.cfg.now() / 1e3) + this.cfg.defaultSwapDeadlineSeconds
2227
- );
2228
- const feeAmount = this.cfg.feeService ? await this.cfg.feeService.estimateGasFee() : 0n;
2229
- if (feeAmount > 0n && feeAmount >= request.amountIn) {
2230
- throw new SwapError(
2231
- "FEE_EXCEEDS_AMOUNT",
2232
- `gas fee (${feeAmount}) must be strictly less than swap amount (${request.amountIn})`
2233
- );
2234
- }
2235
- const sponsoredAmountIn = request.amountIn - feeAmount;
2236
- let estimatedUsdtOutSponsored = estimatedUsdtOutFallback;
2237
- let sponsoredPath = fallbackQuote.bestRoute.path;
2238
- if (feeAmount > 0n) {
2239
- try {
2240
- const sponsoredQuote = await findBestQuote(
2241
- this.cfg.provider,
2242
- request.chainId,
2243
- request.pointTokenAddress,
2244
- usdt,
2245
- sponsoredAmountIn,
2246
- poolsResponse.pools
2247
- );
2248
- estimatedUsdtOutSponsored = sponsoredQuote.bestRoute.amountOut;
2249
- sponsoredPath = sponsoredQuote.bestRoute.path;
2250
- } catch {
2251
- throw new SwapError(
2252
- "QUOTE_UNAVAILABLE",
2253
- "no swap path found for sponsored amount (after fee deduction)"
2254
- );
2255
- }
2256
- }
2257
- const minAmountOutSponsored = estimatedUsdtOutSponsored * BigInt(1e4 - slippageBps) / 10000n;
2258
- const sponsoredOp = buildSwapWithGasDeduction({
2259
- userAddress: request.userAddress,
2260
- aaNonce: request.aaNonce,
2261
- pointTokenAddress: request.pointTokenAddress,
2262
- outputTokenAddress: usdt,
2263
- universalRouterAddress: universalRouter,
2264
- amountIn: sponsoredAmountIn,
2265
- minAmountOut: minAmountOutSponsored,
2266
- swapPath: sponsoredPath,
2267
- deadline,
2268
- gasFeePt: feeAmount,
2269
- feeRecipient: pafiFeeRecipient
2270
- });
2271
- const fallbackOp = feeAmount > 0n ? buildSwapWithGasDeduction({
2272
- userAddress: request.userAddress,
2273
- aaNonce: request.aaNonce,
2274
- pointTokenAddress: request.pointTokenAddress,
2275
- outputTokenAddress: usdt,
2276
- universalRouterAddress: universalRouter,
2277
- amountIn: request.amountIn,
2278
- minAmountOut: minAmountOutFallback,
2279
- swapPath: fallbackQuote.bestRoute.path,
2280
- deadline,
2281
- gasFeePt: 0n,
2282
- feeRecipient: pafiFeeRecipient
2283
- }) : void 0;
2284
- return {
2285
- userOp: sponsoredOp,
2286
- fallback: fallbackOp,
2287
- feeAmount,
2288
- estimatedUsdtOut: estimatedUsdtOutSponsored,
2289
- minAmountOut: minAmountOutSponsored,
2290
- estimatedUsdtOutFallback: fallbackOp ? estimatedUsdtOutFallback : void 0,
2291
- minAmountOutFallback: fallbackOp ? minAmountOutFallback : void 0,
2292
- deadline,
2293
- calls: decodeBatchExecuteCalls2(sponsoredOp.callData),
2294
- callsFallback: fallbackOp ? decodeBatchExecuteCalls2(fallbackOp.callData) : void 0
2295
- };
2296
- }
2297
- };
2298
-
2299
2033
  // src/api/handlers/perpDepositHandler.ts
2300
2034
  import {
2301
2035
  BROKER_HASHES,
@@ -2305,8 +2039,8 @@ import {
2305
2039
  TOKEN_HASHES,
2306
2040
  buildPerpDepositViaRelay,
2307
2041
  computeAccountId,
2308
- decodeBatchExecuteCalls as decodeBatchExecuteCalls3,
2309
- getContractAddresses as getContractAddresses5
2042
+ decodeBatchExecuteCalls as decodeBatchExecuteCalls2,
2043
+ getContractAddresses as getContractAddresses4
2310
2044
  } from "@pafi-dev/core";
2311
2045
  var PerpDepositError = class extends PafiSdkError {
2312
2046
  httpStatus = "unprocessable";
@@ -2340,7 +2074,7 @@ var PerpDepositHandler = class {
2340
2074
  `no Orderly Vault for chainId ${request.chainId}`
2341
2075
  );
2342
2076
  }
2343
- const { orderlyRelay: relayAddress, pafiFeeRecipient } = getContractAddresses5(request.chainId);
2077
+ const { orderlyRelay: relayAddress, pafiFeeRecipient } = getContractAddresses4(request.chainId);
2344
2078
  const [usdcAddress, brokerAllowed] = await Promise.all([
2345
2079
  this.cfg.provider.readContract({
2346
2080
  address: vault,
@@ -2418,8 +2152,8 @@ var PerpDepositHandler = class {
2418
2152
  brokerHash,
2419
2153
  usdcAddress,
2420
2154
  relayAddress,
2421
- calls: decodeBatchExecuteCalls3(sponsoredOp.callData),
2422
- callsFallback: fallbackOp ? decodeBatchExecuteCalls3(fallbackOp.callData) : void 0
2155
+ calls: decodeBatchExecuteCalls2(sponsoredOp.callData),
2156
+ callsFallback: fallbackOp ? decodeBatchExecuteCalls2(fallbackOp.callData) : void 0
2423
2157
  };
2424
2158
  }
2425
2159
  };
@@ -2429,7 +2163,7 @@ import {
2429
2163
  ENTRY_POINT_V08 as ENTRY_POINT_V082,
2430
2164
  buildEip7702Authorization,
2431
2165
  encodeBatchExecute,
2432
- getContractAddresses as getContractAddresses6,
2166
+ getContractAddresses as getContractAddresses5,
2433
2167
  serializeUserOpToJsonRpc as serializeUserOpToJsonRpc2
2434
2168
  } from "@pafi-dev/core";
2435
2169
  var DEFAULT_DELEGATE_GAS = {
@@ -2438,7 +2172,7 @@ var DEFAULT_DELEGATE_GAS = {
2438
2172
  preVerificationGas: 50000n
2439
2173
  };
2440
2174
  async function handleDelegateSubmit(params) {
2441
- const { batchExecutor } = getContractAddresses6(params.chainId);
2175
+ const { batchExecutor } = getContractAddresses5(params.chainId);
2442
2176
  const callData = encodeBatchExecute([]);
2443
2177
  const userOp = {
2444
2178
  sender: params.userAddress,
@@ -2500,74 +2234,6 @@ async function handleDelegateSubmit(params) {
2500
2234
  };
2501
2235
  }
2502
2236
 
2503
- // src/api/quoteHelper.ts
2504
- import {
2505
- findBestQuote as findBestQuote2,
2506
- getContractAddresses as getContractAddresses7
2507
- } from "@pafi-dev/core";
2508
- var DEFAULT_DEADLINE_SECONDS = 300;
2509
- async function quotePointTokenToUsdt(params) {
2510
- const now = params.now ?? (() => Date.now());
2511
- const suggestedDeadline = Math.floor(now() / 1e3) + (params.deadlineSeconds ?? DEFAULT_DEADLINE_SECONDS);
2512
- if (params.pointAmount === 0n) {
2513
- return {
2514
- estimatedUsdtOut: 0n,
2515
- netUsdtOut: 0n,
2516
- exchangeRate: "0.00000000",
2517
- gasEstimate: 0n,
2518
- suggestedDeadline
2519
- };
2520
- }
2521
- if (params.pools.length === 0) {
2522
- return {
2523
- estimatedUsdtOut: 0n,
2524
- netUsdtOut: 0n,
2525
- exchangeRate: "0.00000000",
2526
- gasEstimate: 0n,
2527
- suggestedDeadline,
2528
- quoteError: "QUOTE_UNAVAILABLE"
2529
- };
2530
- }
2531
- const { usdt: usdtAddress } = getContractAddresses7(params.chainId);
2532
- let estimatedUsdtOut = 0n;
2533
- let gasEstimate = 0n;
2534
- try {
2535
- const best = await findBestQuote2(
2536
- params.provider,
2537
- params.chainId,
2538
- params.pointTokenAddress,
2539
- usdtAddress,
2540
- params.pointAmount,
2541
- params.pools
2542
- );
2543
- estimatedUsdtOut = best.bestRoute.amountOut;
2544
- gasEstimate = best.bestRoute.gasEstimate;
2545
- } catch {
2546
- return {
2547
- estimatedUsdtOut: 0n,
2548
- netUsdtOut: 0n,
2549
- exchangeRate: "0.00000000",
2550
- gasEstimate: 0n,
2551
- suggestedDeadline,
2552
- quoteError: "QUOTE_UNAVAILABLE"
2553
- };
2554
- }
2555
- const netUsdtOut = estimatedUsdtOut > params.gasFeeUsdt ? estimatedUsdtOut - params.gasFeeUsdt : 0n;
2556
- const quoteError = estimatedUsdtOut > 0n && netUsdtOut === 0n ? "AMOUNT_TOO_SMALL_FOR_GAS" : void 0;
2557
- const rateNum = estimatedUsdtOut > 0n ? Number(
2558
- estimatedUsdtOut * 1000000n * 10n ** 18n / params.pointAmount
2559
- ) / 1e6 : 0;
2560
- const exchangeRate = rateNum.toFixed(8);
2561
- return {
2562
- estimatedUsdtOut,
2563
- netUsdtOut,
2564
- exchangeRate,
2565
- gasEstimate,
2566
- suggestedDeadline,
2567
- ...quoteError ? { quoteError } : {}
2568
- };
2569
- }
2570
-
2571
2237
  // src/api/errorMapper.ts
2572
2238
  function createSdkErrorMapper(factories) {
2573
2239
  return (err) => {
@@ -2594,14 +2260,14 @@ function createSdkErrorMapper(factories) {
2594
2260
  }
2595
2261
 
2596
2262
  // src/api/issuerApiAdapter.ts
2597
- import { getAddress as getAddress10 } from "viem";
2263
+ import { getAddress as getAddress9 } from "viem";
2598
2264
  import {
2599
2265
  buildAndSignSponsorAuth,
2600
2266
  computeAuthorizationHash,
2601
- decodeBatchExecuteCalls as decodeBatchExecuteCalls4,
2267
+ decodeBatchExecuteCalls as decodeBatchExecuteCalls3,
2602
2268
  encodeBatchExecute as encodeBatchExecute2,
2603
2269
  ENTRY_POINT_V08 as ENTRY_POINT_V083,
2604
- getContractAddresses as getContractAddresses8,
2270
+ getContractAddresses as getContractAddresses6,
2605
2271
  parseEip7702DelegatedAddress as parseEip7702DelegatedAddress2
2606
2272
  } from "@pafi-dev/core";
2607
2273
  var IssuerApiAdapter = class {
@@ -2624,7 +2290,7 @@ var IssuerApiAdapter = class {
2624
2290
  async pools(authenticatedAddress, chainId, pointTokenAddress) {
2625
2291
  const result = await this.cfg.issuerService.api.handlePools(
2626
2292
  authenticatedAddress,
2627
- { chainId, pointTokenAddress: getAddress10(pointTokenAddress) }
2293
+ { chainId, pointTokenAddress: getAddress9(pointTokenAddress) }
2628
2294
  );
2629
2295
  return { pools: result.pools };
2630
2296
  }
@@ -2633,8 +2299,8 @@ var IssuerApiAdapter = class {
2633
2299
  authenticatedAddress,
2634
2300
  {
2635
2301
  chainId,
2636
- userAddress: getAddress10(userAddress),
2637
- pointTokenAddress: getAddress10(pointTokenAddress)
2302
+ userAddress: getAddress9(userAddress),
2303
+ pointTokenAddress: getAddress9(pointTokenAddress)
2638
2304
  }
2639
2305
  );
2640
2306
  return {
@@ -2647,34 +2313,8 @@ var IssuerApiAdapter = class {
2647
2313
  isMinter: result.isMinter
2648
2314
  };
2649
2315
  }
2650
- async quote(authenticatedAddress, chainId, pointTokenAddress, pointAmount) {
2651
- const [gasFeeResult, poolsResult] = await Promise.all([
2652
- this.cfg.issuerService.api.handleGasFee(),
2653
- this.cfg.issuerService.api.handlePools(authenticatedAddress, {
2654
- chainId,
2655
- pointTokenAddress: getAddress10(pointTokenAddress)
2656
- })
2657
- ]);
2658
- const quote = await quotePointTokenToUsdt({
2659
- provider: this.cfg.provider,
2660
- chainId,
2661
- pointTokenAddress: getAddress10(pointTokenAddress),
2662
- pointAmount,
2663
- pools: poolsResult.pools,
2664
- gasFeeUsdt: gasFeeResult.gasFeeUsdt
2665
- });
2666
- const dto = {
2667
- pointAmount: pointAmount.toString(),
2668
- estimatedUsdtOut: quote.estimatedUsdtOut.toString(),
2669
- gasFeeUsdt: gasFeeResult.gasFeeUsdt.toString(),
2670
- netUsdtOut: quote.netUsdtOut.toString(),
2671
- exchangeRate: quote.exchangeRate,
2672
- suggestedDeadline: quote.suggestedDeadline.toString(),
2673
- gasEstimate: quote.gasEstimate.toString()
2674
- };
2675
- if (quote.quoteError) dto.quoteError = quote.quoteError;
2676
- return dto;
2677
- }
2316
+ // quote() removed (2026-04-27) — FE PAFI calls @pafi-dev/trading
2317
+ // directly. Issuer SDK doesn't ship swap/quote anymore.
2678
2318
  // ------------------------------ Action endpoints -------------------------
2679
2319
  async claim(input) {
2680
2320
  const ptClaimHandler = this.assertHandler(
@@ -2682,7 +2322,7 @@ var IssuerApiAdapter = class {
2682
2322
  "ptClaimHandler",
2683
2323
  "claim"
2684
2324
  );
2685
- const pointTokenAddress = getAddress10(input.pointTokenAddress);
2325
+ const pointTokenAddress = getAddress9(input.pointTokenAddress);
2686
2326
  const result = await ptClaimHandler.handle({
2687
2327
  authenticatedAddress: input.authenticatedAddress,
2688
2328
  userAddress: input.authenticatedAddress,
@@ -2723,8 +2363,8 @@ var IssuerApiAdapter = class {
2723
2363
  "burn"
2724
2364
  );
2725
2365
  return {
2726
- calls: decodeBatchExecuteCalls4(response.userOp.callData),
2727
- callsFallback: response.fallback ? decodeBatchExecuteCalls4(response.fallback.userOp.callData) : void 0,
2366
+ calls: decodeBatchExecuteCalls3(response.userOp.callData),
2367
+ callsFallback: response.fallback ? decodeBatchExecuteCalls3(response.fallback.userOp.callData) : void 0,
2728
2368
  feeAmount: response.feeAmount.toString(),
2729
2369
  lockId: response.lockId,
2730
2370
  lockIdFallback: response.fallback?.lockId,
@@ -2735,38 +2375,8 @@ var IssuerApiAdapter = class {
2735
2375
  sponsorAuth
2736
2376
  };
2737
2377
  }
2738
- async swap(input) {
2739
- const swapHandler = this.assertHandler(
2740
- this.cfg.swapHandler,
2741
- "swapHandler",
2742
- "swap"
2743
- );
2744
- const result = await swapHandler.handle({
2745
- userAddress: input.authenticatedAddress,
2746
- chainId: input.chainId,
2747
- pointTokenAddress: getAddress10(input.pointTokenAddress),
2748
- amountIn: input.amountIn,
2749
- aaNonce: input.aaNonce,
2750
- slippageBps: input.slippageBps
2751
- });
2752
- const sponsorAuth = await this.buildSponsorAuth(
2753
- input.authenticatedAddress,
2754
- result.userOp.callData,
2755
- input.chainId,
2756
- "swap"
2757
- );
2758
- return {
2759
- calls: result.calls,
2760
- callsFallback: result.callsFallback,
2761
- feeAmount: result.feeAmount.toString(),
2762
- estimatedUsdtOut: result.estimatedUsdtOut.toString(),
2763
- minAmountOut: result.minAmountOut.toString(),
2764
- estimatedUsdtOutFallback: result.estimatedUsdtOutFallback?.toString(),
2765
- minAmountOutFallback: result.minAmountOutFallback?.toString(),
2766
- deadline: result.deadline.toString(),
2767
- sponsorAuth
2768
- };
2769
- }
2378
+ // swap() removed (2026-04-27) — moved to @pafi-dev/trading.
2379
+ // PAFI's web FE calls TradingHandlers.handleSwap directly.
2770
2380
  async perpDeposit(input) {
2771
2381
  const perpHandler = this.assertHandler(
2772
2382
  this.cfg.perpHandler,
@@ -2807,7 +2417,7 @@ var IssuerApiAdapter = class {
2807
2417
  "ptClaimHandler",
2808
2418
  "claimPrepare"
2809
2419
  );
2810
- const pointTokenAddress = getAddress10(input.pointTokenAddress);
2420
+ const pointTokenAddress = getAddress9(input.pointTokenAddress);
2811
2421
  const claimResult = await ptClaimHandler.handle({
2812
2422
  authenticatedAddress: input.authenticatedAddress,
2813
2423
  userAddress: input.authenticatedAddress,
@@ -2853,7 +2463,7 @@ var IssuerApiAdapter = class {
2853
2463
  }
2854
2464
  async redeemPrepare(input) {
2855
2465
  this.assertRedeemHandler();
2856
- const pointTokenAddress = getAddress10(input.pointTokenAddress);
2466
+ const pointTokenAddress = getAddress9(input.pointTokenAddress);
2857
2467
  const redeemResponse = await this.cfg.ptRedeemHandler.handle({
2858
2468
  userAddress: input.authenticatedAddress,
2859
2469
  authenticatedAddress: input.authenticatedAddress,
@@ -2917,7 +2527,7 @@ var IssuerApiAdapter = class {
2917
2527
  }
2918
2528
  // ------------------------------ Delegate endpoints -----------------------
2919
2529
  async delegateStatus(authenticatedAddress, chainId) {
2920
- const { batchExecutor } = getContractAddresses8(chainId);
2530
+ const { batchExecutor } = getContractAddresses6(chainId);
2921
2531
  const code = await this.cfg.provider.getCode({
2922
2532
  address: authenticatedAddress
2923
2533
  });
@@ -2927,7 +2537,7 @@ var IssuerApiAdapter = class {
2927
2537
  };
2928
2538
  }
2929
2539
  async delegatePrepare(authenticatedAddress, chainId) {
2930
- const { batchExecutor } = getContractAddresses8(chainId);
2540
+ const { batchExecutor } = getContractAddresses6(chainId);
2931
2541
  const accountNonce = BigInt(
2932
2542
  await this.cfg.provider.getTransactionCount({
2933
2543
  address: authenticatedAddress
@@ -3378,7 +2988,7 @@ function parseBigDecimalTo18(s) {
3378
2988
  }
3379
2989
 
3380
2990
  // src/balance/balanceAggregator.ts
3381
- import { getPointTokenBalance as getPointTokenBalance4 } from "@pafi-dev/core";
2991
+ import { getPointTokenBalance as getPointTokenBalance3 } from "@pafi-dev/core";
3382
2992
  var BalanceAggregator = class {
3383
2993
  provider;
3384
2994
  ledger;
@@ -3399,7 +3009,7 @@ var BalanceAggregator = class {
3399
3009
  async getCombinedBalance(user, pointToken) {
3400
3010
  const [offChain, onChain] = await Promise.all([
3401
3011
  this.ledger.getBalance(user, pointToken),
3402
- getPointTokenBalance4(this.provider, pointToken, user)
3012
+ getPointTokenBalance3(this.provider, pointToken, user)
3403
3013
  ]);
3404
3014
  return {
3405
3015
  offChain,
@@ -3632,8 +3242,8 @@ var PafiBackendClient = class {
3632
3242
  };
3633
3243
 
3634
3244
  // src/config.ts
3635
- import { getAddress as getAddress11 } from "viem";
3636
- import { getContractAddresses as getContractAddresses9 } from "@pafi-dev/core";
3245
+ import { getAddress as getAddress10 } from "viem";
3246
+ import { getContractAddresses as getContractAddresses7 } from "@pafi-dev/core";
3637
3247
  function createIssuerService(config) {
3638
3248
  if (!config.provider) {
3639
3249
  throw new Error("createIssuerService: provider is required");
@@ -3653,7 +3263,7 @@ function createIssuerService(config) {
3653
3263
  "createIssuerService: at least one of pointTokenAddress / pointTokenAddresses is required"
3654
3264
  );
3655
3265
  }
3656
- const tokenAddresses = rawAddresses.map((a) => getAddress11(a));
3266
+ const tokenAddresses = rawAddresses.map((a) => getAddress10(a));
3657
3267
  const ledger = config.ledger;
3658
3268
  const sessionStore = config.sessionStore ?? new MemorySessionStore();
3659
3269
  const policy = config.policy ?? new DefaultPolicyEngine({ ledger });
@@ -3703,7 +3313,7 @@ function createIssuerService(config) {
3703
3313
  indexers.set(tokenAddress, new PointIndexer(indexerConfig));
3704
3314
  }
3705
3315
  const firstIndexer = indexers.get(tokenAddresses[0]);
3706
- const chainAddresses = getContractAddresses9(config.chainId);
3316
+ const chainAddresses = getContractAddresses7(config.chainId);
3707
3317
  const resolvedContracts = {
3708
3318
  batchExecutor: chainAddresses.batchExecutor,
3709
3319
  usdt: chainAddresses.usdt,
@@ -3722,15 +3332,6 @@ function createIssuerService(config) {
3722
3332
  };
3723
3333
  if (feeManager) handlersConfig.feeManager = feeManager;
3724
3334
  if (config.poolsProvider) handlersConfig.poolsProvider = config.poolsProvider;
3725
- if (config.claim) {
3726
- handlersConfig.claim = {
3727
- policy,
3728
- relayService,
3729
- issuerSignerWallet: config.claim.issuerSignerWallet,
3730
- batchExecutorAddress: config.claim.batchExecutorAddress ?? chainAddresses.batchExecutor,
3731
- lockDurationMs: config.claim.lockDurationMs
3732
- };
3733
- }
3734
3335
  const handlers = new IssuerApiHandlers(handlersConfig);
3735
3336
  if (config.indexer?.autoStart) {
3736
3337
  for (const idx of indexers.values()) {
@@ -3751,11 +3352,11 @@ function createIssuerService(config) {
3751
3352
  }
3752
3353
 
3753
3354
  // src/issuer-state/validator.ts
3754
- import { getAddress as getAddress12 } from "viem";
3355
+ import { getAddress as getAddress11 } from "viem";
3755
3356
  import {
3756
3357
  POINT_TOKEN_V2_ABI as POINT_TOKEN_V2_ABI3,
3757
3358
  issuerRegistryGetIssuerFlatAbi,
3758
- getContractAddresses as getContractAddresses10
3359
+ getContractAddresses as getContractAddresses8
3759
3360
  } from "@pafi-dev/core";
3760
3361
  var ISSUER_RECORD_TTL_MS = 3e4;
3761
3362
  var IssuerStateValidator = class _IssuerStateValidator {
@@ -3773,7 +3374,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
3773
3374
  * `CONTRACT_ADDRESSES` map for the given chain.
3774
3375
  */
3775
3376
  static forChain(provider, chainId) {
3776
- const { issuerRegistry } = getContractAddresses10(chainId);
3377
+ const { issuerRegistry } = getContractAddresses8(chainId);
3777
3378
  return new _IssuerStateValidator(provider, issuerRegistry);
3778
3379
  }
3779
3380
  /**
@@ -3782,7 +3383,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
3782
3383
  */
3783
3384
  invalidate(pointToken) {
3784
3385
  if (pointToken) {
3785
- const key = getAddress12(pointToken);
3386
+ const key = getAddress11(pointToken);
3786
3387
  this.pointTokenIssuerCache.delete(key);
3787
3388
  this.stateCache.delete(key);
3788
3389
  this.inflight.delete(key);
@@ -3797,7 +3398,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
3797
3398
  * The issuer field is set at `initialize()` and never changes.
3798
3399
  */
3799
3400
  async getIssuerAddressForPointToken(pointToken) {
3800
- const key = getAddress12(pointToken);
3401
+ const key = getAddress11(pointToken);
3801
3402
  const cached = this.pointTokenIssuerCache.get(key);
3802
3403
  if (cached) return cached;
3803
3404
  const issuer = await this.provider.readContract({
@@ -3805,15 +3406,15 @@ var IssuerStateValidator = class _IssuerStateValidator {
3805
3406
  abi: POINT_TOKEN_V2_ABI3,
3806
3407
  functionName: "issuer"
3807
3408
  });
3808
- this.pointTokenIssuerCache.set(key, getAddress12(issuer));
3809
- return getAddress12(issuer);
3409
+ this.pointTokenIssuerCache.set(key, getAddress11(issuer));
3410
+ return getAddress11(issuer);
3810
3411
  }
3811
3412
  /**
3812
3413
  * Read registry record + totalSupply, with 30s cache and in-flight
3813
3414
  * deduplication. Does NOT throw on inactive/missing — returns raw state.
3814
3415
  */
3815
3416
  async getIssuerState(pointToken) {
3816
- const tokenAddr = getAddress12(pointToken);
3417
+ const tokenAddr = getAddress11(pointToken);
3817
3418
  const now = Date.now();
3818
3419
  const cached = this.stateCache.get(tokenAddr);
3819
3420
  if (cached && cached.expiresAt > now) return cached.value;
@@ -3927,6 +3528,7 @@ export {
3927
3528
  IssuerStateError,
3928
3529
  IssuerStateValidator,
3929
3530
  LockNotFoundError,
3531
+ MemoryPendingUserOpStore,
3930
3532
  MemorySessionStore,
3931
3533
  NonceManager,
3932
3534
  PAFI_ISSUER_SDK_VERSION,
@@ -3945,10 +3547,6 @@ export {
3945
3547
  PointIndexer,
3946
3548
  RelayError,
3947
3549
  RelayService,
3948
- SwapError,
3949
- SwapHandler,
3950
- TopUpRedemptionError,
3951
- TopUpRedemptionHandler,
3952
3550
  authenticateRequest,
3953
3551
  createIssuerService,
3954
3552
  createNativePtQuoter,
@@ -3962,7 +3560,6 @@ export {
3962
3560
  handleRedeemStatus,
3963
3561
  mergePaymasterFields,
3964
3562
  prepareMobileUserOp,
3965
- quotePointTokenToUsdt,
3966
3563
  relayUserOp,
3967
3564
  requestPaymaster,
3968
3565
  serializeEntryToJsonRpc,