@pafi-dev/issuer 0.5.38 → 0.5.39

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
@@ -1,3 +1,19 @@
1
+ // src/errors.ts
2
+ var PafiSdkError = class extends Error {
3
+ /**
4
+ * `true` when the FE should consider a retry safe — typically because
5
+ * the failure is transient (`MINT_CAP_EXCEEDED` may free up,
6
+ * `RELAY_FEE_EXCEEDS_AMOUNT` may drop on next quote). Defaults to
7
+ * `false` — subclasses opt in per-code.
8
+ */
9
+ safeToRetry = false;
10
+ details;
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = new.target.name;
14
+ }
15
+ };
16
+
1
17
  // src/policy/defaultPolicy.ts
2
18
  var DefaultPolicyEngine = class {
3
19
  ledger;
@@ -1311,21 +1327,27 @@ var IssuerApiHandlers = class {
1311
1327
 
1312
1328
  // src/api/handlers/ptRedeemHandler.ts
1313
1329
  import { getAddress as getAddress6 } from "viem";
1314
- import { signBurnRequest, POINT_TOKEN_V2_ABI as POINT_TOKEN_V2_ABI2, getPointTokenBalance as getPointTokenBalance2 } from "@pafi-dev/core";
1330
+ import {
1331
+ signBurnRequest,
1332
+ POINT_TOKEN_V2_ABI as POINT_TOKEN_V2_ABI2,
1333
+ getPointTokenBalance as getPointTokenBalance2,
1334
+ getContractAddresses as getContractAddresses2
1335
+ } from "@pafi-dev/core";
1315
1336
  var DEFAULT_REDEEM_LOCK_MS = 15 * 60 * 1e3;
1316
1337
  var DEFAULT_SIG_DEADLINE_SEC = 15 * 60;
1317
- var PTRedeemError = class extends Error {
1338
+ var PTRedeemError = class extends PafiSdkError {
1339
+ httpStatus = "unprocessable";
1340
+ code;
1318
1341
  constructor(code, message) {
1319
1342
  super(message);
1320
1343
  this.code = code;
1321
- this.name = "PTRedeemError";
1322
1344
  }
1323
- code;
1324
1345
  };
1325
1346
  var PTRedeemHandler = class {
1326
1347
  ledger;
1327
1348
  relayService;
1328
1349
  provider;
1350
+ feeService;
1329
1351
  pointTokenAddress;
1330
1352
  batchExecutorAddress;
1331
1353
  chainId;
@@ -1364,6 +1386,7 @@ var PTRedeemHandler = class {
1364
1386
  this.ledger = config.ledger;
1365
1387
  this.relayService = config.relayService;
1366
1388
  this.provider = config.provider;
1389
+ this.feeService = config.feeService;
1367
1390
  this.pointTokenAddress = getAddress6(config.pointTokenAddress);
1368
1391
  this.batchExecutorAddress = getAddress6(config.batchExecutorAddress);
1369
1392
  this.chainId = config.chainId;
@@ -1421,7 +1444,15 @@ var PTRedeemHandler = class {
1421
1444
  }
1422
1445
  }
1423
1446
  async _handleAfterNonceLock(request, burnNonce) {
1424
- const fee = request.feeAmount && request.feeAmount > 0n ? request.feeAmount : 0n;
1447
+ let fee;
1448
+ if (request.feeAmount !== void 0) {
1449
+ fee = request.feeAmount > 0n ? request.feeAmount : 0n;
1450
+ } else if (this.feeService) {
1451
+ fee = await this.feeService.estimateGasFee();
1452
+ } else {
1453
+ fee = 0n;
1454
+ }
1455
+ const feeRecipient = request.feeRecipient ?? (request.chainId !== void 0 ? getContractAddresses2(request.chainId).pafiFeeRecipient : getContractAddresses2(this.chainId).pafiFeeRecipient);
1425
1456
  if (fee > 0n && fee >= request.amount) {
1426
1457
  throw new PTRedeemError(
1427
1458
  "INVALID_AMOUNT",
@@ -1478,7 +1509,7 @@ var PTRedeemHandler = class {
1478
1509
  burnRequest: sponsoredBurnRequest,
1479
1510
  burnerSignature: sponsoredSig,
1480
1511
  feeAmount: fee,
1481
- feeRecipient: request.feeRecipient
1512
+ feeRecipient
1482
1513
  });
1483
1514
  let fallback = void 0;
1484
1515
  if (fee > 0n) {
@@ -1527,6 +1558,7 @@ var PTRedeemHandler = class {
1527
1558
  lockId: sponsoredLockId,
1528
1559
  userOp: sponsoredUserOp,
1529
1560
  netCreditAmount: sponsoredBurnAmount,
1561
+ feeAmount: fee,
1530
1562
  fallback,
1531
1563
  expiresInSeconds: Math.floor(this.redeemLockDurationMs / 1e3),
1532
1564
  signatureDeadline: deadline
@@ -1599,11 +1631,11 @@ var TopUpRedemptionHandler = class {
1599
1631
  };
1600
1632
 
1601
1633
  // src/api/statusHandlers.ts
1602
- var LockNotFoundError = class extends Error {
1634
+ var LockNotFoundError = class extends PafiSdkError {
1603
1635
  code = "LOCK_NOT_FOUND";
1636
+ httpStatus = "not_found";
1604
1637
  constructor() {
1605
1638
  super("Lock not found or does not belong to authenticated user");
1606
- this.name = "LockNotFoundError";
1607
1639
  }
1608
1640
  };
1609
1641
  async function handleClaimStatus(params) {
@@ -1699,6 +1731,7 @@ async function handleRedeemStatus(params) {
1699
1731
  }
1700
1732
 
1701
1733
  // src/api/mobileHandlers.ts
1734
+ import { getAddress as getAddress8 } from "viem";
1702
1735
  import {
1703
1736
  ENTRY_POINT_V08,
1704
1737
  parseEip7702DelegatedAddress
@@ -1841,21 +1874,21 @@ async function prepareMobileUserOp(params) {
1841
1874
  }
1842
1875
 
1843
1876
  // src/pafi-backend/helpers.ts
1844
- var BundlerNotConfiguredError = class extends Error {
1877
+ var BundlerNotConfiguredError = class extends PafiSdkError {
1845
1878
  code = "BUNDLER_NOT_CONFIGURED";
1879
+ httpStatus = "service_unavailable";
1846
1880
  constructor() {
1847
1881
  super(
1848
1882
  "PAFI backend client not configured \u2014 set PAFI_BACKEND_URL, PAFI_ISSUER_ID, PAFI_API_KEY to enable mobile submit."
1849
1883
  );
1850
- this.name = "BundlerNotConfiguredError";
1851
1884
  }
1852
1885
  };
1853
- var BundlerRejectedError = class extends Error {
1886
+ var BundlerRejectedError = class extends PafiSdkError {
1854
1887
  code = "BUNDLER_REJECTED";
1888
+ httpStatus = "unprocessable";
1855
1889
  cause;
1856
1890
  constructor(message, cause) {
1857
1891
  super(message);
1858
- this.name = "BundlerRejectedError";
1859
1892
  this.cause = cause;
1860
1893
  }
1861
1894
  };
@@ -1911,13 +1944,22 @@ async function relayUserOp(params) {
1911
1944
  }
1912
1945
 
1913
1946
  // src/api/mobileHandlers.ts
1914
- var PendingUserOpNotFoundError = class extends Error {
1947
+ var PendingUserOpNotFoundError = class extends PafiSdkError {
1915
1948
  code = "PENDING_USEROP_NOT_FOUND";
1949
+ httpStatus = "not_found";
1916
1950
  constructor(lockId) {
1917
1951
  super(
1918
1952
  `No pending UserOp found for lockId ${lockId} \u2014 it may have expired or already been submitted.`
1919
1953
  );
1920
- this.name = "PendingUserOpNotFoundError";
1954
+ }
1955
+ };
1956
+ var PendingUserOpForbiddenError = class extends PafiSdkError {
1957
+ code = "PENDING_USEROP_FORBIDDEN";
1958
+ httpStatus = "forbidden";
1959
+ constructor(lockId) {
1960
+ super(
1961
+ `Pending UserOp ${lockId} does not belong to the authenticated user.`
1962
+ );
1921
1963
  }
1922
1964
  };
1923
1965
  async function handleMobilePrepare(params) {
@@ -1959,6 +2001,9 @@ async function handleMobileSubmit(params) {
1959
2001
  if (!entry) {
1960
2002
  throw new PendingUserOpNotFoundError(params.lockId);
1961
2003
  }
2004
+ if (getAddress8(entry.sender) !== getAddress8(params.authenticatedAddress)) {
2005
+ throw new PendingUserOpForbiddenError(params.lockId);
2006
+ }
1962
2007
  const variant = params.variant ?? "sponsored";
1963
2008
  const userOpJson = serializeEntryToJsonRpc(entry, params.signature, variant);
1964
2009
  const result = await relayUserOp({
@@ -1972,34 +2017,36 @@ async function handleMobileSubmit(params) {
1972
2017
  }
1973
2018
 
1974
2019
  // src/api/handlers/ptClaimHandler.ts
1975
- import { getAddress as getAddress8 } from "viem";
2020
+ import { getAddress as getAddress9 } from "viem";
1976
2021
  import {
1977
2022
  decodeBatchExecuteCalls,
1978
- getContractAddresses as getContractAddresses2
2023
+ getContractAddresses as getContractAddresses3
1979
2024
  } from "@pafi-dev/core";
1980
2025
 
1981
2026
  // src/issuer-state/types.ts
1982
- var IssuerStateError = class extends Error {
2027
+ var IssuerStateError = class extends PafiSdkError {
2028
+ httpStatus = "unprocessable";
2029
+ code;
2030
+ details;
2031
+ safeToRetry;
1983
2032
  constructor(code, message, details) {
1984
2033
  super(message);
1985
2034
  this.code = code;
1986
2035
  this.details = details;
1987
- this.name = "IssuerStateError";
2036
+ this.safeToRetry = code === "MINT_CAP_EXCEEDED";
1988
2037
  }
1989
- code;
1990
- details;
1991
2038
  };
1992
2039
 
1993
2040
  // src/api/handlers/ptClaimHandler.ts
1994
- var PTClaimError = class extends Error {
2041
+ var PTClaimError = class extends PafiSdkError {
2042
+ httpStatus = "unprocessable";
2043
+ code;
2044
+ details;
1995
2045
  constructor(code, message, details) {
1996
2046
  super(message);
1997
2047
  this.code = code;
1998
2048
  this.details = details;
1999
- this.name = "PTClaimError";
2000
2049
  }
2001
- code;
2002
- details;
2003
2050
  };
2004
2051
  var DEFAULT_LOCK_MS = 15 * 60 * 1e3;
2005
2052
  var DEFAULT_SIG_DEADLINE_SEC2 = 15 * 60;
@@ -2014,7 +2061,7 @@ var PTClaimHandler = class {
2014
2061
  };
2015
2062
  }
2016
2063
  async handle(request) {
2017
- if (getAddress8(request.authenticatedAddress) !== getAddress8(request.userAddress)) {
2064
+ if (getAddress9(request.authenticatedAddress) !== getAddress9(request.userAddress)) {
2018
2065
  throw new PTClaimError(
2019
2066
  "VALIDATION_FAILED",
2020
2067
  `userAddress (${request.userAddress}) does not match authenticated session (${request.authenticatedAddress})`
@@ -2037,7 +2084,7 @@ var PTClaimHandler = class {
2037
2084
  );
2038
2085
  }
2039
2086
  }
2040
- const { batchExecutor: batchExecutorAddress } = getContractAddresses2(
2087
+ const { batchExecutor: batchExecutorAddress } = getContractAddresses3(
2041
2088
  request.chainId
2042
2089
  );
2043
2090
  const lockId = await this.cfg.ledger.lockForMinting(
@@ -2117,15 +2164,15 @@ import {
2117
2164
  buildSwapWithGasDeduction,
2118
2165
  decodeBatchExecuteCalls as decodeBatchExecuteCalls2,
2119
2166
  findBestQuote,
2120
- getContractAddresses as getContractAddresses3
2167
+ getContractAddresses as getContractAddresses4
2121
2168
  } from "@pafi-dev/core";
2122
- var SwapError = class extends Error {
2169
+ var SwapError = class extends PafiSdkError {
2170
+ httpStatus = "unprocessable";
2171
+ code;
2123
2172
  constructor(code, message) {
2124
2173
  super(message);
2125
2174
  this.code = code;
2126
- this.name = "SwapError";
2127
2175
  }
2128
- code;
2129
2176
  };
2130
2177
  var DEFAULT_SLIPPAGE_BPS = 50;
2131
2178
  var DEFAULT_SWAP_DEADLINE_SEC = 5 * 60;
@@ -2144,7 +2191,7 @@ var SwapHandler = class {
2144
2191
  throw new SwapError("INVALID_AMOUNT", "amountIn must be positive");
2145
2192
  }
2146
2193
  const slippageBps = request.slippageBps ?? this.cfg.defaultSlippageBps;
2147
- const { usdt, pafiFeeRecipient, universalRouter } = getContractAddresses3(
2194
+ const { usdt, pafiFeeRecipient, universalRouter } = getContractAddresses4(
2148
2195
  request.chainId
2149
2196
  );
2150
2197
  const poolsResponse = await this.cfg.poolsProvider({
@@ -2259,15 +2306,17 @@ import {
2259
2306
  buildPerpDepositViaRelay,
2260
2307
  computeAccountId,
2261
2308
  decodeBatchExecuteCalls as decodeBatchExecuteCalls3,
2262
- getContractAddresses as getContractAddresses4
2309
+ getContractAddresses as getContractAddresses5
2263
2310
  } from "@pafi-dev/core";
2264
- var PerpDepositError = class extends Error {
2311
+ var PerpDepositError = class extends PafiSdkError {
2312
+ httpStatus = "unprocessable";
2313
+ code;
2314
+ safeToRetry;
2265
2315
  constructor(code, message) {
2266
2316
  super(message);
2267
2317
  this.code = code;
2268
- this.name = "PerpDepositError";
2318
+ this.safeToRetry = code === "RELAY_FEE_EXCEEDS_AMOUNT";
2269
2319
  }
2270
- code;
2271
2320
  };
2272
2321
  var DEFAULT_MAX_FEE_PREMIUM_BPS = 5e3;
2273
2322
  var PerpDepositHandler = class {
@@ -2291,7 +2340,7 @@ var PerpDepositHandler = class {
2291
2340
  `no Orderly Vault for chainId ${request.chainId}`
2292
2341
  );
2293
2342
  }
2294
- const { orderlyRelay: relayAddress, pafiFeeRecipient } = getContractAddresses4(request.chainId);
2343
+ const { orderlyRelay: relayAddress, pafiFeeRecipient } = getContractAddresses5(request.chainId);
2295
2344
  const [usdcAddress, brokerAllowed] = await Promise.all([
2296
2345
  this.cfg.provider.readContract({
2297
2346
  address: vault,
@@ -2380,7 +2429,7 @@ import {
2380
2429
  ENTRY_POINT_V08 as ENTRY_POINT_V082,
2381
2430
  buildEip7702Authorization,
2382
2431
  encodeBatchExecute,
2383
- getContractAddresses as getContractAddresses5,
2432
+ getContractAddresses as getContractAddresses6,
2384
2433
  serializeUserOpToJsonRpc as serializeUserOpToJsonRpc2
2385
2434
  } from "@pafi-dev/core";
2386
2435
  var DEFAULT_DELEGATE_GAS = {
@@ -2389,7 +2438,7 @@ var DEFAULT_DELEGATE_GAS = {
2389
2438
  preVerificationGas: 50000n
2390
2439
  };
2391
2440
  async function handleDelegateSubmit(params) {
2392
- const { batchExecutor } = getContractAddresses5(params.chainId);
2441
+ const { batchExecutor } = getContractAddresses6(params.chainId);
2393
2442
  const callData = encodeBatchExecute([]);
2394
2443
  const userOp = {
2395
2444
  sender: params.userAddress,
@@ -2454,7 +2503,7 @@ async function handleDelegateSubmit(params) {
2454
2503
  // src/api/quoteHelper.ts
2455
2504
  import {
2456
2505
  findBestQuote as findBestQuote2,
2457
- getContractAddresses as getContractAddresses6
2506
+ getContractAddresses as getContractAddresses7
2458
2507
  } from "@pafi-dev/core";
2459
2508
  var DEFAULT_DEADLINE_SECONDS = 300;
2460
2509
  async function quotePointTokenToUsdt(params) {
@@ -2479,7 +2528,7 @@ async function quotePointTokenToUsdt(params) {
2479
2528
  quoteError: "QUOTE_UNAVAILABLE"
2480
2529
  };
2481
2530
  }
2482
- const { usdt: usdtAddress } = getContractAddresses6(params.chainId);
2531
+ const { usdt: usdtAddress } = getContractAddresses7(params.chainId);
2483
2532
  let estimatedUsdtOut = 0n;
2484
2533
  let gasEstimate = 0n;
2485
2534
  try {
@@ -2522,44 +2571,25 @@ async function quotePointTokenToUsdt(params) {
2522
2571
  // src/api/errorMapper.ts
2523
2572
  function createSdkErrorMapper(factories) {
2524
2573
  return (err) => {
2525
- if (err instanceof PendingUserOpNotFoundError) {
2526
- throw factories.notFound({
2527
- code: err.code,
2528
- message: err.message,
2529
- safeToRetry: false
2530
- });
2531
- }
2532
- if (err instanceof BundlerNotConfiguredError) {
2533
- throw factories.serviceUnavailable({
2534
- code: err.code,
2535
- message: err.message,
2536
- safeToRetry: false
2537
- });
2538
- }
2539
- if (err instanceof IssuerStateError) {
2540
- throw factories.unprocessable({
2541
- code: err.code,
2542
- message: err.message,
2543
- details: err.details,
2544
- safeToRetry: err.code === "MINT_CAP_EXCEEDED"
2545
- });
2546
- }
2547
- if (err instanceof PerpDepositError) {
2548
- throw factories.unprocessable({
2549
- code: err.code,
2550
- message: err.message,
2551
- safeToRetry: err.code === "RELAY_FEE_EXCEEDS_AMOUNT"
2552
- });
2574
+ if (!(err instanceof PafiSdkError)) {
2575
+ throw err;
2553
2576
  }
2554
- if (err instanceof PTClaimError || err instanceof PTRedeemError || err instanceof SwapError || err instanceof BundlerRejectedError) {
2555
- throw factories.unprocessable({
2556
- code: err.code,
2557
- message: err.message,
2558
- details: "details" in err ? err.details : void 0,
2559
- safeToRetry: false
2560
- });
2577
+ const body = {
2578
+ code: err.code,
2579
+ message: err.message,
2580
+ details: err.details,
2581
+ safeToRetry: err.safeToRetry
2582
+ };
2583
+ switch (err.httpStatus) {
2584
+ case "not_found":
2585
+ throw factories.notFound(body);
2586
+ case "forbidden":
2587
+ throw factories.forbidden(body);
2588
+ case "unprocessable":
2589
+ throw factories.unprocessable(body);
2590
+ case "service_unavailable":
2591
+ throw factories.serviceUnavailable(body);
2561
2592
  }
2562
- throw err;
2563
2593
  };
2564
2594
  }
2565
2595
 
@@ -3181,8 +3211,8 @@ var PafiBackendClient = class {
3181
3211
  };
3182
3212
 
3183
3213
  // src/config.ts
3184
- import { getAddress as getAddress9 } from "viem";
3185
- import { getContractAddresses as getContractAddresses7 } from "@pafi-dev/core";
3214
+ import { getAddress as getAddress10 } from "viem";
3215
+ import { getContractAddresses as getContractAddresses8 } from "@pafi-dev/core";
3186
3216
  function createIssuerService(config) {
3187
3217
  if (!config.provider) {
3188
3218
  throw new Error("createIssuerService: provider is required");
@@ -3202,7 +3232,7 @@ function createIssuerService(config) {
3202
3232
  "createIssuerService: at least one of pointTokenAddress / pointTokenAddresses is required"
3203
3233
  );
3204
3234
  }
3205
- const tokenAddresses = rawAddresses.map((a) => getAddress9(a));
3235
+ const tokenAddresses = rawAddresses.map((a) => getAddress10(a));
3206
3236
  const ledger = config.ledger;
3207
3237
  const sessionStore = config.sessionStore ?? new MemorySessionStore();
3208
3238
  const policy = config.policy ?? new DefaultPolicyEngine({ ledger });
@@ -3252,7 +3282,7 @@ function createIssuerService(config) {
3252
3282
  indexers.set(tokenAddress, new PointIndexer(indexerConfig));
3253
3283
  }
3254
3284
  const firstIndexer = indexers.get(tokenAddresses[0]);
3255
- const chainAddresses = getContractAddresses7(config.chainId);
3285
+ const chainAddresses = getContractAddresses8(config.chainId);
3256
3286
  const resolvedContracts = {
3257
3287
  batchExecutor: chainAddresses.batchExecutor,
3258
3288
  usdt: chainAddresses.usdt,
@@ -3300,11 +3330,11 @@ function createIssuerService(config) {
3300
3330
  }
3301
3331
 
3302
3332
  // src/issuer-state/validator.ts
3303
- import { getAddress as getAddress10 } from "viem";
3333
+ import { getAddress as getAddress11 } from "viem";
3304
3334
  import {
3305
3335
  POINT_TOKEN_V2_ABI as POINT_TOKEN_V2_ABI3,
3306
3336
  issuerRegistryGetIssuerFlatAbi,
3307
- getContractAddresses as getContractAddresses8
3337
+ getContractAddresses as getContractAddresses9
3308
3338
  } from "@pafi-dev/core";
3309
3339
  var ISSUER_RECORD_TTL_MS = 3e4;
3310
3340
  var IssuerStateValidator = class _IssuerStateValidator {
@@ -3322,7 +3352,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
3322
3352
  * `CONTRACT_ADDRESSES` map for the given chain.
3323
3353
  */
3324
3354
  static forChain(provider, chainId) {
3325
- const { issuerRegistry } = getContractAddresses8(chainId);
3355
+ const { issuerRegistry } = getContractAddresses9(chainId);
3326
3356
  return new _IssuerStateValidator(provider, issuerRegistry);
3327
3357
  }
3328
3358
  /**
@@ -3331,7 +3361,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
3331
3361
  */
3332
3362
  invalidate(pointToken) {
3333
3363
  if (pointToken) {
3334
- const key = getAddress10(pointToken);
3364
+ const key = getAddress11(pointToken);
3335
3365
  this.pointTokenIssuerCache.delete(key);
3336
3366
  this.stateCache.delete(key);
3337
3367
  this.inflight.delete(key);
@@ -3346,7 +3376,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
3346
3376
  * The issuer field is set at `initialize()` and never changes.
3347
3377
  */
3348
3378
  async getIssuerAddressForPointToken(pointToken) {
3349
- const key = getAddress10(pointToken);
3379
+ const key = getAddress11(pointToken);
3350
3380
  const cached = this.pointTokenIssuerCache.get(key);
3351
3381
  if (cached) return cached;
3352
3382
  const issuer = await this.provider.readContract({
@@ -3354,15 +3384,15 @@ var IssuerStateValidator = class _IssuerStateValidator {
3354
3384
  abi: POINT_TOKEN_V2_ABI3,
3355
3385
  functionName: "issuer"
3356
3386
  });
3357
- this.pointTokenIssuerCache.set(key, getAddress10(issuer));
3358
- return getAddress10(issuer);
3387
+ this.pointTokenIssuerCache.set(key, getAddress11(issuer));
3388
+ return getAddress11(issuer);
3359
3389
  }
3360
3390
  /**
3361
3391
  * Read registry record + totalSupply, with 30s cache and in-flight
3362
3392
  * deduplication. Does NOT throw on inactive/missing — returns raw state.
3363
3393
  */
3364
3394
  async getIssuerState(pointToken) {
3365
- const tokenAddr = getAddress10(pointToken);
3395
+ const tokenAddr = getAddress11(pointToken);
3366
3396
  const now = Date.now();
3367
3397
  const cached = this.stateCache.get(tokenAddr);
3368
3398
  if (cached && cached.expiresAt > now) return cached.value;
@@ -3485,6 +3515,8 @@ export {
3485
3515
  PTRedeemHandler,
3486
3516
  PafiBackendClient,
3487
3517
  PafiBackendError,
3518
+ PafiSdkError,
3519
+ PendingUserOpForbiddenError,
3488
3520
  PendingUserOpNotFoundError,
3489
3521
  PerpDepositError,
3490
3522
  PerpDepositHandler,