@pafi-dev/issuer 0.5.34 → 0.5.36

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
@@ -36,14 +36,21 @@ __export(index_exports, {
36
36
  MemorySessionStore: () => MemorySessionStore,
37
37
  NonceManager: () => NonceManager,
38
38
  PAFI_ISSUER_SDK_VERSION: () => PAFI_ISSUER_SDK_VERSION,
39
- PAFI_SUBGRAPH_URL: () => import_core6.PAFI_SUBGRAPH_URL,
39
+ PAFI_SUBGRAPH_URL: () => import_core12.PAFI_SUBGRAPH_URL,
40
+ PTClaimError: () => PTClaimError,
41
+ PTClaimHandler: () => PTClaimHandler,
40
42
  PTRedeemError: () => PTRedeemError,
41
43
  PTRedeemHandler: () => PTRedeemHandler,
42
44
  PafiBackendClient: () => PafiBackendClient,
43
45
  PafiBackendError: () => PafiBackendError,
46
+ PendingUserOpNotFoundError: () => PendingUserOpNotFoundError,
47
+ PerpDepositError: () => PerpDepositError,
48
+ PerpDepositHandler: () => PerpDepositHandler,
44
49
  PointIndexer: () => PointIndexer,
45
50
  RelayError: () => RelayError,
46
51
  RelayService: () => RelayService,
52
+ SwapError: () => SwapError,
53
+ SwapHandler: () => SwapHandler,
47
54
  TopUpRedemptionError: () => TopUpRedemptionError,
48
55
  TopUpRedemptionHandler: () => TopUpRedemptionHandler,
49
56
  authenticateRequest: () => authenticateRequest,
@@ -52,6 +59,8 @@ __export(index_exports, {
52
59
  createSubgraphNativeUsdtQuoter: () => createSubgraphNativeUsdtQuoter,
53
60
  createSubgraphPoolsProvider: () => createSubgraphPoolsProvider,
54
61
  handleClaimStatus: () => handleClaimStatus,
62
+ handleMobilePrepare: () => handleMobilePrepare,
63
+ handleMobileSubmit: () => handleMobileSubmit,
55
64
  handleRedeemStatus: () => handleRedeemStatus,
56
65
  mergePaymasterFields: () => mergePaymasterFields,
57
66
  prepareMobileUserOp: () => prepareMobileUserOp,
@@ -1747,9 +1756,662 @@ async function handleRedeemStatus(params) {
1747
1756
  };
1748
1757
  }
1749
1758
 
1759
+ // src/api/mobileHandlers.ts
1760
+ var import_core8 = require("@pafi-dev/core");
1761
+
1762
+ // src/userop-store/serialize.ts
1763
+ var import_core6 = require("@pafi-dev/core");
1764
+ function serializeEntryToJsonRpc(entry, signature, variant = "sponsored") {
1765
+ if (variant === "fallback") {
1766
+ if (!entry.fallback) {
1767
+ throw new Error(
1768
+ "serializeEntryToJsonRpc: variant=fallback requested but the stored entry has no `fallback` branch \u2014 caller should resubmit with variant='sponsored' or re-prepare with a fee configured."
1769
+ );
1770
+ }
1771
+ return (0, import_core6.serializeUserOpToJsonRpc)(
1772
+ {
1773
+ sender: entry.sender,
1774
+ nonce: BigInt(entry.nonce),
1775
+ callData: entry.fallback.callData,
1776
+ callGasLimit: BigInt(entry.fallback.callGasLimit),
1777
+ verificationGasLimit: BigInt(entry.fallback.verificationGasLimit),
1778
+ preVerificationGas: BigInt(entry.fallback.preVerificationGas),
1779
+ maxFeePerGas: BigInt(entry.maxFeePerGas),
1780
+ maxPriorityFeePerGas: BigInt(entry.maxPriorityFeePerGas)
1781
+ // intentionally no paymaster — user pays ETH gas
1782
+ },
1783
+ signature
1784
+ );
1785
+ }
1786
+ return (0, import_core6.serializeUserOpToJsonRpc)(
1787
+ {
1788
+ sender: entry.sender,
1789
+ nonce: BigInt(entry.nonce),
1790
+ callData: entry.callData,
1791
+ callGasLimit: BigInt(entry.callGasLimit),
1792
+ verificationGasLimit: BigInt(entry.verificationGasLimit),
1793
+ preVerificationGas: BigInt(entry.preVerificationGas),
1794
+ maxFeePerGas: BigInt(entry.maxFeePerGas),
1795
+ maxPriorityFeePerGas: BigInt(entry.maxPriorityFeePerGas),
1796
+ paymaster: entry.paymaster,
1797
+ paymasterVerificationGasLimit: entry.paymasterVerificationGasLimit != null ? BigInt(entry.paymasterVerificationGasLimit) : void 0,
1798
+ paymasterPostOpGasLimit: entry.paymasterPostOpGasLimit != null ? BigInt(entry.paymasterPostOpGasLimit) : void 0,
1799
+ paymasterData: entry.paymasterData
1800
+ },
1801
+ signature
1802
+ );
1803
+ }
1804
+
1805
+ // src/userop-store/prepareUserOp.ts
1806
+ var import_core7 = require("@pafi-dev/core");
1807
+ function serializeUserOpTypedData(td) {
1808
+ return {
1809
+ domain: td.domain,
1810
+ types: td.types,
1811
+ primaryType: td.primaryType,
1812
+ message: {
1813
+ sender: td.message.sender,
1814
+ nonce: `0x${td.message.nonce.toString(16)}`,
1815
+ initCode: td.message.initCode,
1816
+ callData: td.message.callData,
1817
+ accountGasLimits: td.message.accountGasLimits,
1818
+ preVerificationGas: `0x${td.message.preVerificationGas.toString(
1819
+ 16
1820
+ )}`,
1821
+ gasFees: td.message.gasFees,
1822
+ paymasterAndData: td.message.paymasterAndData
1823
+ }
1824
+ };
1825
+ }
1826
+ function mergePaymasterFields(userOp, paymasterFields) {
1827
+ if (!paymasterFields) return userOp;
1828
+ const merged = {
1829
+ ...userOp
1830
+ };
1831
+ for (const [k, v] of Object.entries(paymasterFields)) {
1832
+ if (v !== void 0) merged[k] = v;
1833
+ }
1834
+ return merged;
1835
+ }
1836
+ async function prepareMobileUserOp(params) {
1837
+ const userOp = mergePaymasterFields(
1838
+ params.partialUserOp,
1839
+ params.paymasterFields
1840
+ );
1841
+ const userOpHash = (0, import_core7.computeUserOpHash)(userOp, params.chainId);
1842
+ const typedData = serializeUserOpTypedData(
1843
+ (0, import_core7.buildUserOpTypedData)(userOp, params.chainId)
1844
+ );
1845
+ let fallback;
1846
+ let fallbackEntry;
1847
+ if (params.partialUserOpFallback) {
1848
+ const fallbackUserOp = {
1849
+ ...params.partialUserOpFallback,
1850
+ maxFeePerGas: userOp.maxFeePerGas,
1851
+ maxPriorityFeePerGas: userOp.maxPriorityFeePerGas
1852
+ };
1853
+ const fallbackHash = (0, import_core7.computeUserOpHash)(fallbackUserOp, params.chainId);
1854
+ const fallbackTypedData = serializeUserOpTypedData(
1855
+ (0, import_core7.buildUserOpTypedData)(fallbackUserOp, params.chainId)
1856
+ );
1857
+ fallback = {
1858
+ userOp: fallbackUserOp,
1859
+ userOpHash: fallbackHash,
1860
+ typedData: fallbackTypedData
1861
+ };
1862
+ fallbackEntry = {
1863
+ callData: fallbackUserOp.callData,
1864
+ callGasLimit: fallbackUserOp.callGasLimit.toString(),
1865
+ verificationGasLimit: fallbackUserOp.verificationGasLimit.toString(),
1866
+ preVerificationGas: fallbackUserOp.preVerificationGas.toString(),
1867
+ userOpHash: fallbackHash
1868
+ };
1869
+ }
1870
+ const entry = {
1871
+ sender: userOp.sender,
1872
+ nonce: userOp.nonce.toString(),
1873
+ callData: userOp.callData,
1874
+ callGasLimit: userOp.callGasLimit.toString(),
1875
+ verificationGasLimit: userOp.verificationGasLimit.toString(),
1876
+ preVerificationGas: userOp.preVerificationGas.toString(),
1877
+ maxFeePerGas: userOp.maxFeePerGas.toString(),
1878
+ maxPriorityFeePerGas: userOp.maxPriorityFeePerGas.toString(),
1879
+ paymaster: userOp.paymaster,
1880
+ paymasterVerificationGasLimit: userOp.paymasterVerificationGasLimit?.toString(),
1881
+ paymasterPostOpGasLimit: userOp.paymasterPostOpGasLimit?.toString(),
1882
+ paymasterData: userOp.paymasterData,
1883
+ chainId: params.chainId,
1884
+ userOpHash,
1885
+ fallback: fallbackEntry
1886
+ };
1887
+ await params.store.save(params.lockId, entry, params.ttlSeconds);
1888
+ return {
1889
+ sponsored: { userOp, userOpHash, typedData },
1890
+ fallback,
1891
+ entry
1892
+ };
1893
+ }
1894
+
1895
+ // src/pafi-backend/helpers.ts
1896
+ var BundlerNotConfiguredError = class extends Error {
1897
+ code = "BUNDLER_NOT_CONFIGURED";
1898
+ constructor() {
1899
+ super(
1900
+ "PAFI backend client not configured \u2014 set PAFI_BACKEND_URL, PAFI_ISSUER_ID, PAFI_API_KEY to enable mobile submit."
1901
+ );
1902
+ this.name = "BundlerNotConfiguredError";
1903
+ }
1904
+ };
1905
+ var BundlerRejectedError = class extends Error {
1906
+ code = "BUNDLER_REJECTED";
1907
+ cause;
1908
+ constructor(message, cause) {
1909
+ super(message);
1910
+ this.name = "BundlerRejectedError";
1911
+ this.cause = cause;
1912
+ }
1913
+ };
1914
+ async function requestPaymaster(params) {
1915
+ if (!params.client) return void 0;
1916
+ const fn = params.functionName ?? defaultFunctionForScenario(params.scenario);
1917
+ try {
1918
+ return await params.client.requestSponsorship({
1919
+ chainId: params.chainId,
1920
+ scenario: params.scenario,
1921
+ userOp: params.userOp,
1922
+ target: {
1923
+ contract: params.pointTokenAddress,
1924
+ function: fn,
1925
+ pointToken: params.pointTokenAddress
1926
+ }
1927
+ });
1928
+ } catch (err) {
1929
+ const msg = err instanceof Error ? err.message : String(err);
1930
+ params.onWarning?.(`Paymaster sponsorship declined: ${msg}`);
1931
+ return void 0;
1932
+ }
1933
+ }
1934
+ function defaultFunctionForScenario(scenario) {
1935
+ switch (scenario) {
1936
+ case "mint":
1937
+ return "mint";
1938
+ case "burn":
1939
+ return "burn";
1940
+ case "swap":
1941
+ return "swap";
1942
+ case "perp-deposit":
1943
+ return "deposit";
1944
+ default:
1945
+ return scenario;
1946
+ }
1947
+ }
1948
+ async function relayUserOp(params) {
1949
+ if (!params.client) {
1950
+ throw new BundlerNotConfiguredError();
1951
+ }
1952
+ try {
1953
+ const result = await params.client.relayUserOperation({
1954
+ userOp: params.userOp,
1955
+ entryPoint: params.entryPoint,
1956
+ eip7702Auth: params.eip7702Auth
1957
+ });
1958
+ return { userOpHash: result.userOpHash };
1959
+ } catch (err) {
1960
+ const msg = err instanceof Error ? err.message : String(err);
1961
+ throw new BundlerRejectedError(msg, err);
1962
+ }
1963
+ }
1964
+
1965
+ // src/api/mobileHandlers.ts
1966
+ var PendingUserOpNotFoundError = class extends Error {
1967
+ code = "PENDING_USEROP_NOT_FOUND";
1968
+ constructor(lockId) {
1969
+ super(
1970
+ `No pending UserOp found for lockId ${lockId} \u2014 it may have expired or already been submitted.`
1971
+ );
1972
+ this.name = "PendingUserOpNotFoundError";
1973
+ }
1974
+ };
1975
+ async function handleMobilePrepare(params) {
1976
+ const [fees, userCode] = await Promise.all([
1977
+ params.provider.estimateFeesPerGas(),
1978
+ params.provider.getCode({ address: params.userAddress })
1979
+ ]);
1980
+ const needsDelegation = (0, import_core8.parseEip7702DelegatedAddress)(userCode) === null;
1981
+ const sponsoredOp = {
1982
+ ...params.partialUserOp,
1983
+ maxFeePerGas: fees.maxFeePerGas ?? params.partialUserOp.maxFeePerGas ?? 0n,
1984
+ maxPriorityFeePerGas: fees.maxPriorityFeePerGas ?? params.partialUserOp.maxPriorityFeePerGas ?? 0n
1985
+ };
1986
+ const paymasterFields = await requestPaymaster({
1987
+ client: params.pafiBackendClient,
1988
+ chainId: params.chainId,
1989
+ scenario: params.scenario,
1990
+ userOp: sponsoredOp,
1991
+ pointTokenAddress: params.pointTokenAddress,
1992
+ onWarning: params.onWarning
1993
+ });
1994
+ const prepared = await prepareMobileUserOp({
1995
+ lockId: params.lockId,
1996
+ partialUserOp: sponsoredOp,
1997
+ partialUserOpFallback: params.partialUserOpFallback,
1998
+ paymasterFields,
1999
+ chainId: params.chainId,
2000
+ store: params.store,
2001
+ ttlSeconds: params.ttlSeconds
2002
+ });
2003
+ return {
2004
+ ...prepared,
2005
+ isSponsored: !!paymasterFields,
2006
+ needsDelegation
2007
+ };
2008
+ }
2009
+ async function handleMobileSubmit(params) {
2010
+ const entry = await params.store.get(params.lockId);
2011
+ if (!entry) {
2012
+ throw new PendingUserOpNotFoundError(params.lockId);
2013
+ }
2014
+ const variant = params.variant ?? "sponsored";
2015
+ const userOpJson = serializeEntryToJsonRpc(entry, params.signature, variant);
2016
+ const result = await relayUserOp({
2017
+ client: params.pafiBackendClient,
2018
+ userOp: userOpJson,
2019
+ entryPoint: params.entryPoint ?? import_core8.ENTRY_POINT_V08
2020
+ });
2021
+ await params.bindUserOpHash(params.lockId, result.userOpHash);
2022
+ await params.store.delete(params.lockId);
2023
+ return { userOpHash: result.userOpHash };
2024
+ }
2025
+
2026
+ // src/api/handlers/ptClaimHandler.ts
2027
+ var import_viem9 = require("viem");
2028
+ var import_core9 = require("@pafi-dev/core");
2029
+
2030
+ // src/issuer-state/types.ts
2031
+ var IssuerStateError = class extends Error {
2032
+ constructor(code, message, details) {
2033
+ super(message);
2034
+ this.code = code;
2035
+ this.details = details;
2036
+ this.name = "IssuerStateError";
2037
+ }
2038
+ code;
2039
+ details;
2040
+ };
2041
+
2042
+ // src/api/handlers/ptClaimHandler.ts
2043
+ var PTClaimError = class extends Error {
2044
+ constructor(code, message, details) {
2045
+ super(message);
2046
+ this.code = code;
2047
+ this.details = details;
2048
+ this.name = "PTClaimError";
2049
+ }
2050
+ code;
2051
+ details;
2052
+ };
2053
+ var DEFAULT_LOCK_MS = 15 * 60 * 1e3;
2054
+ var DEFAULT_SIG_DEADLINE_SEC2 = 15 * 60;
2055
+ var PTClaimHandler = class {
2056
+ cfg;
2057
+ constructor(config) {
2058
+ this.cfg = {
2059
+ ...config,
2060
+ lockDurationMs: config.lockDurationMs ?? DEFAULT_LOCK_MS,
2061
+ signatureDeadlineSeconds: config.signatureDeadlineSeconds ?? DEFAULT_SIG_DEADLINE_SEC2,
2062
+ now: config.now ?? (() => Date.now())
2063
+ };
2064
+ }
2065
+ async handle(request) {
2066
+ if ((0, import_viem9.getAddress)(request.authenticatedAddress) !== (0, import_viem9.getAddress)(request.userAddress)) {
2067
+ throw new PTClaimError(
2068
+ "VALIDATION_FAILED",
2069
+ `userAddress (${request.userAddress}) does not match authenticated session (${request.authenticatedAddress})`
2070
+ );
2071
+ }
2072
+ if (request.amount <= 0n) {
2073
+ throw new PTClaimError("INVALID_AMOUNT", "claim amount must be positive");
2074
+ }
2075
+ if (this.cfg.issuerStateValidator) {
2076
+ try {
2077
+ await this.cfg.issuerStateValidator.preValidateMint(
2078
+ request.pointTokenAddress,
2079
+ request.amount
2080
+ );
2081
+ } catch (err) {
2082
+ if (err instanceof IssuerStateError) throw err;
2083
+ throw new PTClaimError(
2084
+ "VALIDATION_FAILED",
2085
+ `issuer-state pre-validate failed: ${err instanceof Error ? err.message : String(err)}`
2086
+ );
2087
+ }
2088
+ }
2089
+ const { batchExecutor: batchExecutorAddress } = (0, import_core9.getContractAddresses)(
2090
+ request.chainId
2091
+ );
2092
+ const lockId = await this.cfg.ledger.lockForMinting(
2093
+ request.userAddress,
2094
+ request.amount,
2095
+ this.cfg.lockDurationMs,
2096
+ request.pointTokenAddress
2097
+ );
2098
+ const signatureDeadline = BigInt(
2099
+ Math.floor(this.cfg.now() / 1e3) + this.cfg.signatureDeadlineSeconds
2100
+ );
2101
+ const feeAmount = this.cfg.feeService ? await this.cfg.feeService.estimateGasFee() : 0n;
2102
+ const domain = {
2103
+ name: this.cfg.pointTokenDomainName,
2104
+ chainId: request.chainId,
2105
+ verifyingContract: request.pointTokenAddress
2106
+ };
2107
+ let userOp;
2108
+ try {
2109
+ userOp = await this.cfg.relayService.prepareMint({
2110
+ userAddress: request.userAddress,
2111
+ aaNonce: request.aaNonce,
2112
+ batchExecutorAddress,
2113
+ pointTokenAddress: request.pointTokenAddress,
2114
+ amount: request.amount,
2115
+ issuerSignerWallet: this.cfg.issuerSignerWallet,
2116
+ domain,
2117
+ mintRequestNonce: request.mintRequestNonce,
2118
+ deadline: signatureDeadline
2119
+ // No feeAmount/feeRecipient — RelayService auto-resolves.
2120
+ });
2121
+ } catch (err) {
2122
+ throw new PTClaimError(
2123
+ "BUILD_FAILED",
2124
+ `prepareMint failed: ${err instanceof Error ? err.message : String(err)}`
2125
+ );
2126
+ }
2127
+ let fallback;
2128
+ if (feeAmount > 0n) {
2129
+ try {
2130
+ fallback = await this.cfg.relayService.prepareMint({
2131
+ userAddress: request.userAddress,
2132
+ aaNonce: request.aaNonce,
2133
+ batchExecutorAddress,
2134
+ pointTokenAddress: request.pointTokenAddress,
2135
+ amount: request.amount,
2136
+ issuerSignerWallet: this.cfg.issuerSignerWallet,
2137
+ domain,
2138
+ mintRequestNonce: request.mintRequestNonce,
2139
+ deadline: signatureDeadline,
2140
+ feeAmount: 0n
2141
+ });
2142
+ } catch (err) {
2143
+ throw new PTClaimError(
2144
+ "BUILD_FAILED",
2145
+ `prepareMint (fallback) failed: ${err instanceof Error ? err.message : String(err)}`
2146
+ );
2147
+ }
2148
+ }
2149
+ const calls = (0, import_core9.decodeBatchExecuteCalls)(userOp.callData);
2150
+ const callsFallback = fallback ? (0, import_core9.decodeBatchExecuteCalls)(fallback.callData) : void 0;
2151
+ return {
2152
+ userOp,
2153
+ fallback,
2154
+ lockId,
2155
+ feeAmount,
2156
+ signatureDeadline,
2157
+ expiresInSeconds: Math.floor(this.cfg.lockDurationMs / 1e3),
2158
+ calls,
2159
+ callsFallback
2160
+ };
2161
+ }
2162
+ };
2163
+
2164
+ // src/api/handlers/swapHandler.ts
2165
+ var import_core10 = require("@pafi-dev/core");
2166
+ var SwapError = class extends Error {
2167
+ constructor(code, message) {
2168
+ super(message);
2169
+ this.code = code;
2170
+ this.name = "SwapError";
2171
+ }
2172
+ code;
2173
+ };
2174
+ var DEFAULT_SLIPPAGE_BPS = 50;
2175
+ var DEFAULT_SWAP_DEADLINE_SEC = 5 * 60;
2176
+ var SwapHandler = class {
2177
+ cfg;
2178
+ constructor(config) {
2179
+ this.cfg = {
2180
+ ...config,
2181
+ defaultSlippageBps: config.defaultSlippageBps ?? DEFAULT_SLIPPAGE_BPS,
2182
+ defaultSwapDeadlineSeconds: config.defaultSwapDeadlineSeconds ?? DEFAULT_SWAP_DEADLINE_SEC,
2183
+ now: config.now ?? (() => Date.now())
2184
+ };
2185
+ }
2186
+ async handle(request) {
2187
+ if (request.amountIn <= 0n) {
2188
+ throw new SwapError("INVALID_AMOUNT", "amountIn must be positive");
2189
+ }
2190
+ const slippageBps = request.slippageBps ?? this.cfg.defaultSlippageBps;
2191
+ const { usdt, pafiFeeRecipient, universalRouter } = (0, import_core10.getContractAddresses)(
2192
+ request.chainId
2193
+ );
2194
+ const poolsResponse = await this.cfg.poolsProvider({
2195
+ chainId: request.chainId,
2196
+ pointTokenAddress: request.pointTokenAddress
2197
+ });
2198
+ if (poolsResponse.pools.length === 0) {
2199
+ throw new SwapError(
2200
+ "QUOTE_UNAVAILABLE",
2201
+ "no liquidity pool found for this point token"
2202
+ );
2203
+ }
2204
+ let fallbackQuote;
2205
+ try {
2206
+ fallbackQuote = await (0, import_core10.findBestQuote)(
2207
+ this.cfg.provider,
2208
+ request.chainId,
2209
+ request.pointTokenAddress,
2210
+ usdt,
2211
+ request.amountIn,
2212
+ poolsResponse.pools
2213
+ );
2214
+ } catch {
2215
+ throw new SwapError(
2216
+ "QUOTE_UNAVAILABLE",
2217
+ "no swap path found for this point token"
2218
+ );
2219
+ }
2220
+ const estimatedUsdtOutFallback = fallbackQuote.bestRoute.amountOut;
2221
+ const minAmountOutFallback = estimatedUsdtOutFallback * BigInt(1e4 - slippageBps) / 10000n;
2222
+ const deadline = request.deadline ?? BigInt(
2223
+ Math.floor(this.cfg.now() / 1e3) + this.cfg.defaultSwapDeadlineSeconds
2224
+ );
2225
+ const feeAmount = this.cfg.feeService ? await this.cfg.feeService.estimateGasFee() : 0n;
2226
+ if (feeAmount > 0n && feeAmount >= request.amountIn) {
2227
+ throw new SwapError(
2228
+ "FEE_EXCEEDS_AMOUNT",
2229
+ `gas fee (${feeAmount}) must be strictly less than swap amount (${request.amountIn})`
2230
+ );
2231
+ }
2232
+ const sponsoredAmountIn = request.amountIn - feeAmount;
2233
+ let estimatedUsdtOutSponsored = estimatedUsdtOutFallback;
2234
+ let sponsoredPath = fallbackQuote.bestRoute.path;
2235
+ if (feeAmount > 0n) {
2236
+ try {
2237
+ const sponsoredQuote = await (0, import_core10.findBestQuote)(
2238
+ this.cfg.provider,
2239
+ request.chainId,
2240
+ request.pointTokenAddress,
2241
+ usdt,
2242
+ sponsoredAmountIn,
2243
+ poolsResponse.pools
2244
+ );
2245
+ estimatedUsdtOutSponsored = sponsoredQuote.bestRoute.amountOut;
2246
+ sponsoredPath = sponsoredQuote.bestRoute.path;
2247
+ } catch {
2248
+ throw new SwapError(
2249
+ "QUOTE_UNAVAILABLE",
2250
+ "no swap path found for sponsored amount (after fee deduction)"
2251
+ );
2252
+ }
2253
+ }
2254
+ const minAmountOutSponsored = estimatedUsdtOutSponsored * BigInt(1e4 - slippageBps) / 10000n;
2255
+ const sponsoredOp = (0, import_core10.buildSwapWithGasDeduction)({
2256
+ userAddress: request.userAddress,
2257
+ aaNonce: request.aaNonce,
2258
+ pointTokenAddress: request.pointTokenAddress,
2259
+ outputTokenAddress: usdt,
2260
+ universalRouterAddress: universalRouter,
2261
+ amountIn: sponsoredAmountIn,
2262
+ minAmountOut: minAmountOutSponsored,
2263
+ swapPath: sponsoredPath,
2264
+ deadline,
2265
+ gasFeePt: feeAmount,
2266
+ feeRecipient: pafiFeeRecipient
2267
+ });
2268
+ const fallbackOp = feeAmount > 0n ? (0, import_core10.buildSwapWithGasDeduction)({
2269
+ userAddress: request.userAddress,
2270
+ aaNonce: request.aaNonce,
2271
+ pointTokenAddress: request.pointTokenAddress,
2272
+ outputTokenAddress: usdt,
2273
+ universalRouterAddress: universalRouter,
2274
+ amountIn: request.amountIn,
2275
+ minAmountOut: minAmountOutFallback,
2276
+ swapPath: fallbackQuote.bestRoute.path,
2277
+ deadline,
2278
+ gasFeePt: 0n,
2279
+ feeRecipient: pafiFeeRecipient
2280
+ }) : void 0;
2281
+ return {
2282
+ userOp: sponsoredOp,
2283
+ fallback: fallbackOp,
2284
+ feeAmount,
2285
+ estimatedUsdtOut: estimatedUsdtOutSponsored,
2286
+ minAmountOut: minAmountOutSponsored,
2287
+ estimatedUsdtOutFallback: fallbackOp ? estimatedUsdtOutFallback : void 0,
2288
+ minAmountOutFallback: fallbackOp ? minAmountOutFallback : void 0,
2289
+ deadline,
2290
+ calls: (0, import_core10.decodeBatchExecuteCalls)(sponsoredOp.callData),
2291
+ callsFallback: fallbackOp ? (0, import_core10.decodeBatchExecuteCalls)(fallbackOp.callData) : void 0
2292
+ };
2293
+ }
2294
+ };
2295
+
2296
+ // src/api/handlers/perpDepositHandler.ts
2297
+ var import_core11 = require("@pafi-dev/core");
2298
+ var PerpDepositError = class extends Error {
2299
+ constructor(code, message) {
2300
+ super(message);
2301
+ this.code = code;
2302
+ this.name = "PerpDepositError";
2303
+ }
2304
+ code;
2305
+ };
2306
+ var DEFAULT_MAX_FEE_PREMIUM_BPS = 5e3;
2307
+ var PerpDepositHandler = class {
2308
+ cfg;
2309
+ constructor(config) {
2310
+ this.cfg = {
2311
+ ...config,
2312
+ maxFeePremiumBps: config.maxFeePremiumBps ?? DEFAULT_MAX_FEE_PREMIUM_BPS
2313
+ };
2314
+ }
2315
+ async handle(request) {
2316
+ if (request.amount <= 0n) {
2317
+ throw new PerpDepositError("INVALID_AMOUNT", "amount must be positive");
2318
+ }
2319
+ const brokerHash = import_core11.BROKER_HASHES[request.brokerId];
2320
+ const tokenHash = import_core11.TOKEN_HASHES.USDC;
2321
+ const vault = import_core11.ORDERLY_VAULT_ADDRESSES[request.chainId];
2322
+ if (!vault) {
2323
+ throw new PerpDepositError(
2324
+ "PERP_DEPOSIT_UNAVAILABLE",
2325
+ `no Orderly Vault for chainId ${request.chainId}`
2326
+ );
2327
+ }
2328
+ const { orderlyRelay: relayAddress, pafiFeeRecipient } = (0, import_core11.getContractAddresses)(request.chainId);
2329
+ const [usdcAddress, brokerAllowed] = await Promise.all([
2330
+ this.cfg.provider.readContract({
2331
+ address: vault,
2332
+ abi: import_core11.ORDERLY_VAULT_ABI,
2333
+ functionName: "getAllowedToken",
2334
+ args: [tokenHash]
2335
+ }),
2336
+ this.cfg.provider.readContract({
2337
+ address: vault,
2338
+ abi: import_core11.ORDERLY_VAULT_ABI,
2339
+ functionName: "getAllowedBroker",
2340
+ args: [brokerHash]
2341
+ })
2342
+ ]);
2343
+ if (!brokerAllowed) {
2344
+ throw new PerpDepositError(
2345
+ "BROKER_NOT_WHITELISTED",
2346
+ `broker "${request.brokerId}" is not whitelisted on Orderly Vault`
2347
+ );
2348
+ }
2349
+ const accountId = (0, import_core11.computeAccountId)(request.userAddress, brokerHash);
2350
+ const requestForQuote = {
2351
+ token: usdcAddress,
2352
+ receiver: request.userAddress,
2353
+ brokerHash,
2354
+ totalAmount: request.amount,
2355
+ maxFee: 0n
2356
+ };
2357
+ const [relayTokenFee, ptGasFee] = await Promise.all([
2358
+ this.cfg.provider.readContract({
2359
+ address: relayAddress,
2360
+ abi: import_core11.ORDERLY_RELAY_ABI,
2361
+ functionName: "quoteTokenFee",
2362
+ args: [requestForQuote]
2363
+ }),
2364
+ this.cfg.feeService ? this.cfg.feeService.estimateGasFee() : Promise.resolve(0n)
2365
+ ]);
2366
+ if (relayTokenFee >= request.amount) {
2367
+ throw new PerpDepositError(
2368
+ "RELAY_FEE_EXCEEDS_AMOUNT",
2369
+ `Relay quoted fee ${relayTokenFee} >= deposit amount ${request.amount}`
2370
+ );
2371
+ }
2372
+ const maxFee = relayTokenFee * BigInt(1e4 + this.cfg.maxFeePremiumBps) / 10000n;
2373
+ const depositReq = {
2374
+ token: usdcAddress,
2375
+ receiver: request.userAddress,
2376
+ brokerHash,
2377
+ totalAmount: request.amount,
2378
+ maxFee
2379
+ };
2380
+ const sponsoredOp = (0, import_core11.buildPerpDepositViaRelay)({
2381
+ userAddress: request.userAddress,
2382
+ aaNonce: request.aaNonce,
2383
+ relayAddress,
2384
+ request: depositReq,
2385
+ pointTokenAddress: this.cfg.pointTokenAddress,
2386
+ gasFeePt: ptGasFee,
2387
+ gasFeePtRecipient: pafiFeeRecipient
2388
+ });
2389
+ const fallbackOp = ptGasFee > 0n ? (0, import_core11.buildPerpDepositViaRelay)({
2390
+ userAddress: request.userAddress,
2391
+ aaNonce: request.aaNonce,
2392
+ relayAddress,
2393
+ request: depositReq
2394
+ }) : void 0;
2395
+ return {
2396
+ userOp: sponsoredOp,
2397
+ fallback: fallbackOp,
2398
+ feeAmount: ptGasFee,
2399
+ relayTokenFee,
2400
+ maxFee,
2401
+ netDeposit: request.amount - relayTokenFee,
2402
+ accountId,
2403
+ brokerHash,
2404
+ usdcAddress,
2405
+ relayAddress,
2406
+ calls: (0, import_core11.decodeBatchExecuteCalls)(sponsoredOp.callData),
2407
+ callsFallback: fallbackOp ? (0, import_core11.decodeBatchExecuteCalls)(fallbackOp.callData) : void 0
2408
+ };
2409
+ }
2410
+ };
2411
+
1750
2412
  // src/pools/subgraphPoolsProvider.ts
1751
- var import_viem9 = require("viem");
1752
- var import_core6 = require("@pafi-dev/core");
2413
+ var import_viem10 = require("viem");
2414
+ var import_core12 = require("@pafi-dev/core");
1753
2415
  var DEFAULT_CACHE_TTL_MS = 3e4;
1754
2416
  var POOL_QUERY = `
1755
2417
  query GetPoolForPointToken($id: ID!) {
@@ -1767,7 +2429,7 @@ var POOL_QUERY = `
1767
2429
  }
1768
2430
  `;
1769
2431
  function createSubgraphPoolsProvider(config = {}) {
1770
- const subgraphUrl = config.subgraphUrl ?? import_core6.PAFI_SUBGRAPH_URL;
2432
+ const subgraphUrl = config.subgraphUrl ?? import_core12.PAFI_SUBGRAPH_URL;
1771
2433
  try {
1772
2434
  const parsed = new URL(subgraphUrl);
1773
2435
  if (process.env.NODE_ENV === "production" && parsed.protocol !== "https:") {
@@ -1849,7 +2511,7 @@ async function fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, pointTokenAddress)
1849
2511
  return [];
1850
2512
  }
1851
2513
  const { pool } = token;
1852
- if (!(0, import_viem9.isAddress)(pool.hooks)) {
2514
+ if (!(0, import_viem10.isAddress)(pool.hooks)) {
1853
2515
  console.error(
1854
2516
  "[PAFI] SubgraphPoolsProvider: invalid hooks address in response:",
1855
2517
  pool.hooks,
@@ -1857,7 +2519,7 @@ async function fetchPoolsFromSubgraph(fetchImpl, subgraphUrl, pointTokenAddress)
1857
2519
  );
1858
2520
  return [];
1859
2521
  }
1860
- if (!(0, import_viem9.isAddress)(pool.token0.id) || !(0, import_viem9.isAddress)(pool.token1.id)) {
2522
+ if (!(0, import_viem10.isAddress)(pool.token0.id) || !(0, import_viem10.isAddress)(pool.token1.id)) {
1861
2523
  console.error(
1862
2524
  "[PAFI] SubgraphPoolsProvider: invalid token address in response \u2014 skipping pool"
1863
2525
  );
@@ -1899,7 +2561,7 @@ var PRICE_QUERY = `
1899
2561
  }
1900
2562
  `;
1901
2563
  function createSubgraphNativeUsdtQuoter(config = {}) {
1902
- const subgraphUrl = config.subgraphUrl ?? import_core6.PAFI_SUBGRAPH_URL;
2564
+ const subgraphUrl = config.subgraphUrl ?? import_core12.PAFI_SUBGRAPH_URL;
1903
2565
  try {
1904
2566
  const parsed = new URL(subgraphUrl);
1905
2567
  if (process.env.NODE_ENV === "production" && parsed.protocol !== "https:") {
@@ -2007,8 +2669,8 @@ function toUsdtPerNative(priceFloat, usdtDecimals) {
2007
2669
  }
2008
2670
 
2009
2671
  // src/pools/nativePtQuoter.ts
2010
- var import_viem10 = require("viem");
2011
- var CHAINLINK_ABI = (0, import_viem10.parseAbi)([
2672
+ var import_viem11 = require("viem");
2673
+ var CHAINLINK_ABI = (0, import_viem11.parseAbi)([
2012
2674
  "function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)"
2013
2675
  ]);
2014
2676
  var CHAINLINK_MAX_AGE_S = 3600n;
@@ -2029,7 +2691,7 @@ function createNativePtQuoter(config) {
2029
2691
  provider,
2030
2692
  pointTokenAddress,
2031
2693
  chainlinkFeedAddress = "0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70",
2032
- subgraphUrl = import_core6.PAFI_SUBGRAPH_URL,
2694
+ subgraphUrl = import_core12.PAFI_SUBGRAPH_URL,
2033
2695
  cacheTtlMs = 3e4,
2034
2696
  fallbackEthPriceUsd = 3e3,
2035
2697
  fallbackPtPriceUsdt = 0.1,
@@ -2111,7 +2773,7 @@ function parseBigDecimalTo18(s) {
2111
2773
  }
2112
2774
 
2113
2775
  // src/balance/balanceAggregator.ts
2114
- var import_core7 = require("@pafi-dev/core");
2776
+ var import_core13 = require("@pafi-dev/core");
2115
2777
  var BalanceAggregator = class {
2116
2778
  provider;
2117
2779
  ledger;
@@ -2132,7 +2794,7 @@ var BalanceAggregator = class {
2132
2794
  async getCombinedBalance(user, pointToken) {
2133
2795
  const [offChain, onChain] = await Promise.all([
2134
2796
  this.ledger.getBalance(user, pointToken),
2135
- (0, import_core7.getPointTokenBalance)(this.provider, pointToken, user)
2797
+ (0, import_core13.getPointTokenBalance)(this.provider, pointToken, user)
2136
2798
  ]);
2137
2799
  return {
2138
2800
  offChain,
@@ -2364,79 +3026,9 @@ var PafiBackendClient = class {
2364
3026
  }
2365
3027
  };
2366
3028
 
2367
- // src/pafi-backend/helpers.ts
2368
- var BundlerNotConfiguredError = class extends Error {
2369
- code = "BUNDLER_NOT_CONFIGURED";
2370
- constructor() {
2371
- super(
2372
- "PAFI backend client not configured \u2014 set PAFI_BACKEND_URL, PAFI_ISSUER_ID, PAFI_API_KEY to enable mobile submit."
2373
- );
2374
- this.name = "BundlerNotConfiguredError";
2375
- }
2376
- };
2377
- var BundlerRejectedError = class extends Error {
2378
- code = "BUNDLER_REJECTED";
2379
- cause;
2380
- constructor(message, cause) {
2381
- super(message);
2382
- this.name = "BundlerRejectedError";
2383
- this.cause = cause;
2384
- }
2385
- };
2386
- async function requestPaymaster(params) {
2387
- if (!params.client) return void 0;
2388
- const fn = params.functionName ?? defaultFunctionForScenario(params.scenario);
2389
- try {
2390
- return await params.client.requestSponsorship({
2391
- chainId: params.chainId,
2392
- scenario: params.scenario,
2393
- userOp: params.userOp,
2394
- target: {
2395
- contract: params.pointTokenAddress,
2396
- function: fn,
2397
- pointToken: params.pointTokenAddress
2398
- }
2399
- });
2400
- } catch (err) {
2401
- const msg = err instanceof Error ? err.message : String(err);
2402
- params.onWarning?.(`Paymaster sponsorship declined: ${msg}`);
2403
- return void 0;
2404
- }
2405
- }
2406
- function defaultFunctionForScenario(scenario) {
2407
- switch (scenario) {
2408
- case "mint":
2409
- return "mint";
2410
- case "burn":
2411
- return "burn";
2412
- case "swap":
2413
- return "swap";
2414
- case "perp-deposit":
2415
- return "deposit";
2416
- default:
2417
- return scenario;
2418
- }
2419
- }
2420
- async function relayUserOp(params) {
2421
- if (!params.client) {
2422
- throw new BundlerNotConfiguredError();
2423
- }
2424
- try {
2425
- const result = await params.client.relayUserOperation({
2426
- userOp: params.userOp,
2427
- entryPoint: params.entryPoint,
2428
- eip7702Auth: params.eip7702Auth
2429
- });
2430
- return { userOpHash: result.userOpHash };
2431
- } catch (err) {
2432
- const msg = err instanceof Error ? err.message : String(err);
2433
- throw new BundlerRejectedError(msg, err);
2434
- }
2435
- }
2436
-
2437
3029
  // src/config.ts
2438
- var import_viem11 = require("viem");
2439
- var import_core8 = require("@pafi-dev/core");
3030
+ var import_viem12 = require("viem");
3031
+ var import_core14 = require("@pafi-dev/core");
2440
3032
  function createIssuerService(config) {
2441
3033
  if (!config.provider) {
2442
3034
  throw new Error("createIssuerService: provider is required");
@@ -2456,7 +3048,7 @@ function createIssuerService(config) {
2456
3048
  "createIssuerService: at least one of pointTokenAddress / pointTokenAddresses is required"
2457
3049
  );
2458
3050
  }
2459
- const tokenAddresses = rawAddresses.map((a) => (0, import_viem11.getAddress)(a));
3051
+ const tokenAddresses = rawAddresses.map((a) => (0, import_viem12.getAddress)(a));
2460
3052
  const ledger = config.ledger;
2461
3053
  const sessionStore = config.sessionStore ?? new MemorySessionStore();
2462
3054
  const policy = config.policy ?? new DefaultPolicyEngine({ ledger });
@@ -2506,7 +3098,7 @@ function createIssuerService(config) {
2506
3098
  indexers.set(tokenAddress, new PointIndexer(indexerConfig));
2507
3099
  }
2508
3100
  const firstIndexer = indexers.get(tokenAddresses[0]);
2509
- const chainAddresses = (0, import_core8.getContractAddresses)(config.chainId);
3101
+ const chainAddresses = (0, import_core14.getContractAddresses)(config.chainId);
2510
3102
  const resolvedContracts = {
2511
3103
  batchExecutor: chainAddresses.batchExecutor,
2512
3104
  usdt: chainAddresses.usdt,
@@ -2553,156 +3145,9 @@ function createIssuerService(config) {
2553
3145
  };
2554
3146
  }
2555
3147
 
2556
- // src/userop-store/serialize.ts
2557
- var import_core9 = require("@pafi-dev/core");
2558
- function serializeEntryToJsonRpc(entry, signature, variant = "sponsored") {
2559
- if (variant === "fallback") {
2560
- if (!entry.fallback) {
2561
- throw new Error(
2562
- "serializeEntryToJsonRpc: variant=fallback requested but the stored entry has no `fallback` branch \u2014 caller should resubmit with variant='sponsored' or re-prepare with a fee configured."
2563
- );
2564
- }
2565
- return (0, import_core9.serializeUserOpToJsonRpc)(
2566
- {
2567
- sender: entry.sender,
2568
- nonce: BigInt(entry.nonce),
2569
- callData: entry.fallback.callData,
2570
- callGasLimit: BigInt(entry.fallback.callGasLimit),
2571
- verificationGasLimit: BigInt(entry.fallback.verificationGasLimit),
2572
- preVerificationGas: BigInt(entry.fallback.preVerificationGas),
2573
- maxFeePerGas: BigInt(entry.maxFeePerGas),
2574
- maxPriorityFeePerGas: BigInt(entry.maxPriorityFeePerGas)
2575
- // intentionally no paymaster — user pays ETH gas
2576
- },
2577
- signature
2578
- );
2579
- }
2580
- return (0, import_core9.serializeUserOpToJsonRpc)(
2581
- {
2582
- sender: entry.sender,
2583
- nonce: BigInt(entry.nonce),
2584
- callData: entry.callData,
2585
- callGasLimit: BigInt(entry.callGasLimit),
2586
- verificationGasLimit: BigInt(entry.verificationGasLimit),
2587
- preVerificationGas: BigInt(entry.preVerificationGas),
2588
- maxFeePerGas: BigInt(entry.maxFeePerGas),
2589
- maxPriorityFeePerGas: BigInt(entry.maxPriorityFeePerGas),
2590
- paymaster: entry.paymaster,
2591
- paymasterVerificationGasLimit: entry.paymasterVerificationGasLimit != null ? BigInt(entry.paymasterVerificationGasLimit) : void 0,
2592
- paymasterPostOpGasLimit: entry.paymasterPostOpGasLimit != null ? BigInt(entry.paymasterPostOpGasLimit) : void 0,
2593
- paymasterData: entry.paymasterData
2594
- },
2595
- signature
2596
- );
2597
- }
2598
-
2599
- // src/userop-store/prepareUserOp.ts
2600
- var import_core10 = require("@pafi-dev/core");
2601
- function serializeUserOpTypedData(td) {
2602
- return {
2603
- domain: td.domain,
2604
- types: td.types,
2605
- primaryType: td.primaryType,
2606
- message: {
2607
- sender: td.message.sender,
2608
- nonce: `0x${td.message.nonce.toString(16)}`,
2609
- initCode: td.message.initCode,
2610
- callData: td.message.callData,
2611
- accountGasLimits: td.message.accountGasLimits,
2612
- preVerificationGas: `0x${td.message.preVerificationGas.toString(
2613
- 16
2614
- )}`,
2615
- gasFees: td.message.gasFees,
2616
- paymasterAndData: td.message.paymasterAndData
2617
- }
2618
- };
2619
- }
2620
- function mergePaymasterFields(userOp, paymasterFields) {
2621
- if (!paymasterFields) return userOp;
2622
- const merged = {
2623
- ...userOp
2624
- };
2625
- for (const [k, v] of Object.entries(paymasterFields)) {
2626
- if (v !== void 0) merged[k] = v;
2627
- }
2628
- return merged;
2629
- }
2630
- async function prepareMobileUserOp(params) {
2631
- const userOp = mergePaymasterFields(
2632
- params.partialUserOp,
2633
- params.paymasterFields
2634
- );
2635
- const userOpHash = (0, import_core10.computeUserOpHash)(userOp, params.chainId);
2636
- const typedData = serializeUserOpTypedData(
2637
- (0, import_core10.buildUserOpTypedData)(userOp, params.chainId)
2638
- );
2639
- let fallback;
2640
- let fallbackEntry;
2641
- if (params.partialUserOpFallback) {
2642
- const fallbackUserOp = {
2643
- ...params.partialUserOpFallback,
2644
- maxFeePerGas: userOp.maxFeePerGas,
2645
- maxPriorityFeePerGas: userOp.maxPriorityFeePerGas
2646
- };
2647
- const fallbackHash = (0, import_core10.computeUserOpHash)(fallbackUserOp, params.chainId);
2648
- const fallbackTypedData = serializeUserOpTypedData(
2649
- (0, import_core10.buildUserOpTypedData)(fallbackUserOp, params.chainId)
2650
- );
2651
- fallback = {
2652
- userOp: fallbackUserOp,
2653
- userOpHash: fallbackHash,
2654
- typedData: fallbackTypedData
2655
- };
2656
- fallbackEntry = {
2657
- callData: fallbackUserOp.callData,
2658
- callGasLimit: fallbackUserOp.callGasLimit.toString(),
2659
- verificationGasLimit: fallbackUserOp.verificationGasLimit.toString(),
2660
- preVerificationGas: fallbackUserOp.preVerificationGas.toString(),
2661
- userOpHash: fallbackHash
2662
- };
2663
- }
2664
- const entry = {
2665
- sender: userOp.sender,
2666
- nonce: userOp.nonce.toString(),
2667
- callData: userOp.callData,
2668
- callGasLimit: userOp.callGasLimit.toString(),
2669
- verificationGasLimit: userOp.verificationGasLimit.toString(),
2670
- preVerificationGas: userOp.preVerificationGas.toString(),
2671
- maxFeePerGas: userOp.maxFeePerGas.toString(),
2672
- maxPriorityFeePerGas: userOp.maxPriorityFeePerGas.toString(),
2673
- paymaster: userOp.paymaster,
2674
- paymasterVerificationGasLimit: userOp.paymasterVerificationGasLimit?.toString(),
2675
- paymasterPostOpGasLimit: userOp.paymasterPostOpGasLimit?.toString(),
2676
- paymasterData: userOp.paymasterData,
2677
- chainId: params.chainId,
2678
- userOpHash,
2679
- fallback: fallbackEntry
2680
- };
2681
- await params.store.save(params.lockId, entry, params.ttlSeconds);
2682
- return {
2683
- sponsored: { userOp, userOpHash, typedData },
2684
- fallback,
2685
- entry
2686
- };
2687
- }
2688
-
2689
- // src/issuer-state/validator.ts
2690
- var import_viem12 = require("viem");
2691
- var import_core11 = require("@pafi-dev/core");
2692
-
2693
- // src/issuer-state/types.ts
2694
- var IssuerStateError = class extends Error {
2695
- constructor(code, message, details) {
2696
- super(message);
2697
- this.code = code;
2698
- this.details = details;
2699
- this.name = "IssuerStateError";
2700
- }
2701
- code;
2702
- details;
2703
- };
2704
-
2705
3148
  // src/issuer-state/validator.ts
3149
+ var import_viem13 = require("viem");
3150
+ var import_core15 = require("@pafi-dev/core");
2706
3151
  var ISSUER_RECORD_TTL_MS = 3e4;
2707
3152
  var IssuerStateValidator = class _IssuerStateValidator {
2708
3153
  constructor(provider, registryAddress) {
@@ -2719,7 +3164,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
2719
3164
  * `CONTRACT_ADDRESSES` map for the given chain.
2720
3165
  */
2721
3166
  static forChain(provider, chainId) {
2722
- const { issuerRegistry } = (0, import_core11.getContractAddresses)(chainId);
3167
+ const { issuerRegistry } = (0, import_core15.getContractAddresses)(chainId);
2723
3168
  return new _IssuerStateValidator(provider, issuerRegistry);
2724
3169
  }
2725
3170
  /**
@@ -2728,7 +3173,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
2728
3173
  */
2729
3174
  invalidate(pointToken) {
2730
3175
  if (pointToken) {
2731
- const key = (0, import_viem12.getAddress)(pointToken);
3176
+ const key = (0, import_viem13.getAddress)(pointToken);
2732
3177
  this.pointTokenIssuerCache.delete(key);
2733
3178
  this.stateCache.delete(key);
2734
3179
  this.inflight.delete(key);
@@ -2743,23 +3188,23 @@ var IssuerStateValidator = class _IssuerStateValidator {
2743
3188
  * The issuer field is set at `initialize()` and never changes.
2744
3189
  */
2745
3190
  async getIssuerAddressForPointToken(pointToken) {
2746
- const key = (0, import_viem12.getAddress)(pointToken);
3191
+ const key = (0, import_viem13.getAddress)(pointToken);
2747
3192
  const cached = this.pointTokenIssuerCache.get(key);
2748
3193
  if (cached) return cached;
2749
3194
  const issuer = await this.provider.readContract({
2750
3195
  address: key,
2751
- abi: import_core11.POINT_TOKEN_V2_ABI,
3196
+ abi: import_core15.POINT_TOKEN_V2_ABI,
2752
3197
  functionName: "issuer"
2753
3198
  });
2754
- this.pointTokenIssuerCache.set(key, (0, import_viem12.getAddress)(issuer));
2755
- return (0, import_viem12.getAddress)(issuer);
3199
+ this.pointTokenIssuerCache.set(key, (0, import_viem13.getAddress)(issuer));
3200
+ return (0, import_viem13.getAddress)(issuer);
2756
3201
  }
2757
3202
  /**
2758
3203
  * Read registry record + totalSupply, with 30s cache and in-flight
2759
3204
  * deduplication. Does NOT throw on inactive/missing — returns raw state.
2760
3205
  */
2761
3206
  async getIssuerState(pointToken) {
2762
- const tokenAddr = (0, import_viem12.getAddress)(pointToken);
3207
+ const tokenAddr = (0, import_viem13.getAddress)(pointToken);
2763
3208
  const now = Date.now();
2764
3209
  const cached = this.stateCache.get(tokenAddr);
2765
3210
  if (cached && cached.expiresAt > now) return cached.value;
@@ -2829,13 +3274,13 @@ var IssuerStateValidator = class _IssuerStateValidator {
2829
3274
  const [issuerTuple, totalSupply] = await Promise.all([
2830
3275
  this.provider.readContract({
2831
3276
  address: this.registryAddress,
2832
- abi: import_core11.issuerRegistryGetIssuerFlatAbi,
3277
+ abi: import_core15.issuerRegistryGetIssuerFlatAbi,
2833
3278
  functionName: "getIssuer",
2834
3279
  args: [issuerAddr]
2835
3280
  }),
2836
3281
  this.provider.readContract({
2837
3282
  address: tokenAddr,
2838
- abi: import_core11.POINT_TOKEN_V2_ABI,
3283
+ abi: import_core15.POINT_TOKEN_V2_ABI,
2839
3284
  functionName: "totalSupply"
2840
3285
  })
2841
3286
  ]);
@@ -2877,13 +3322,20 @@ var PAFI_ISSUER_SDK_VERSION = "0.4.0";
2877
3322
  NonceManager,
2878
3323
  PAFI_ISSUER_SDK_VERSION,
2879
3324
  PAFI_SUBGRAPH_URL,
3325
+ PTClaimError,
3326
+ PTClaimHandler,
2880
3327
  PTRedeemError,
2881
3328
  PTRedeemHandler,
2882
3329
  PafiBackendClient,
2883
3330
  PafiBackendError,
3331
+ PendingUserOpNotFoundError,
3332
+ PerpDepositError,
3333
+ PerpDepositHandler,
2884
3334
  PointIndexer,
2885
3335
  RelayError,
2886
3336
  RelayService,
3337
+ SwapError,
3338
+ SwapHandler,
2887
3339
  TopUpRedemptionError,
2888
3340
  TopUpRedemptionHandler,
2889
3341
  authenticateRequest,
@@ -2892,6 +3344,8 @@ var PAFI_ISSUER_SDK_VERSION = "0.4.0";
2892
3344
  createSubgraphNativeUsdtQuoter,
2893
3345
  createSubgraphPoolsProvider,
2894
3346
  handleClaimStatus,
3347
+ handleMobilePrepare,
3348
+ handleMobileSubmit,
2895
3349
  handleRedeemStatus,
2896
3350
  mergePaymasterFields,
2897
3351
  prepareMobileUserOp,