@pafi-dev/issuer 0.5.5 → 0.5.7
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 +77 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -5
- package/dist/index.d.ts +35 -5
- package/dist/index.js +70 -1
- package/dist/index.js.map +1 -1
- package/package.json +11 -11
package/dist/index.cjs
CHANGED
|
@@ -31,7 +31,7 @@ __export(index_exports, {
|
|
|
31
31
|
MemorySessionStore: () => MemorySessionStore,
|
|
32
32
|
NonceManager: () => NonceManager,
|
|
33
33
|
PAFI_ISSUER_SDK_VERSION: () => PAFI_ISSUER_SDK_VERSION,
|
|
34
|
-
PAFI_SUBGRAPH_URL: () => PAFI_SUBGRAPH_URL,
|
|
34
|
+
PAFI_SUBGRAPH_URL: () => import_core6.PAFI_SUBGRAPH_URL,
|
|
35
35
|
PTRedeemError: () => PTRedeemError,
|
|
36
36
|
PTRedeemHandler: () => PTRedeemHandler,
|
|
37
37
|
PafiBackendClient: () => PafiBackendClient,
|
|
@@ -1300,6 +1300,20 @@ var PTRedeemHandler = class {
|
|
|
1300
1300
|
redeemLockDurationMs;
|
|
1301
1301
|
signatureDeadlineSeconds;
|
|
1302
1302
|
now;
|
|
1303
|
+
/**
|
|
1304
|
+
* Per-user in-flight nonce guard (single-process only).
|
|
1305
|
+
*
|
|
1306
|
+
* Prevents two concurrent requests from reading the same on-chain
|
|
1307
|
+
* burnRequestNonce before either has completed, which would produce two
|
|
1308
|
+
* signed UserOps with the same nonce — only one succeeds on-chain; the
|
|
1309
|
+
* other leaves an orphaned pending credit and a wasted signer call.
|
|
1310
|
+
*
|
|
1311
|
+
* NOTE: This guard is effective only within a single Node.js process. For
|
|
1312
|
+
* multi-instance deployments (k8s, PM2 cluster), enforce mutual exclusion
|
|
1313
|
+
* via a distributed lock (Redis SETNX / Postgres advisory lock) keyed on
|
|
1314
|
+
* `(userAddress, pointTokenAddress)` BEFORE calling `handle()`.
|
|
1315
|
+
*/
|
|
1316
|
+
inFlightNonces = /* @__PURE__ */ new Map();
|
|
1303
1317
|
constructor(config) {
|
|
1304
1318
|
if (!config.ledger.reservePendingCredit) {
|
|
1305
1319
|
throw new PTRedeemError(
|
|
@@ -1352,6 +1366,27 @@ var PTRedeemHandler = class {
|
|
|
1352
1366
|
`failed to read burnRequestNonces(${request.userAddress}): ${err instanceof Error ? err.message : String(err)}`
|
|
1353
1367
|
);
|
|
1354
1368
|
}
|
|
1369
|
+
const userKey = (0, import_viem7.getAddress)(request.userAddress).toLowerCase();
|
|
1370
|
+
let userNonces = this.inFlightNonces.get(userKey);
|
|
1371
|
+
if (!userNonces) {
|
|
1372
|
+
userNonces = /* @__PURE__ */ new Set();
|
|
1373
|
+
this.inFlightNonces.set(userKey, userNonces);
|
|
1374
|
+
}
|
|
1375
|
+
if (userNonces.has(burnNonce)) {
|
|
1376
|
+
throw new PTRedeemError(
|
|
1377
|
+
"NONCE_IN_FLIGHT",
|
|
1378
|
+
`A burn request for nonce ${burnNonce} is already in progress for ${request.userAddress}. Retry after the current request completes.`
|
|
1379
|
+
);
|
|
1380
|
+
}
|
|
1381
|
+
userNonces.add(burnNonce);
|
|
1382
|
+
try {
|
|
1383
|
+
return await this._handleAfterNonceLock(request, burnNonce);
|
|
1384
|
+
} finally {
|
|
1385
|
+
userNonces.delete(burnNonce);
|
|
1386
|
+
if (userNonces.size === 0) this.inFlightNonces.delete(userKey);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
async _handleAfterNonceLock(request, burnNonce) {
|
|
1355
1390
|
const onChainBalance = await (0, import_core4.getPointTokenBalance)(
|
|
1356
1391
|
this.provider,
|
|
1357
1392
|
this.pointTokenAddress,
|
|
@@ -1481,7 +1516,7 @@ var TopUpRedemptionHandler = class {
|
|
|
1481
1516
|
|
|
1482
1517
|
// src/pools/subgraphPoolsProvider.ts
|
|
1483
1518
|
var import_viem9 = require("viem");
|
|
1484
|
-
var
|
|
1519
|
+
var import_core6 = require("@pafi-dev/core");
|
|
1485
1520
|
var DEFAULT_CACHE_TTL_MS = 3e4;
|
|
1486
1521
|
var POOL_QUERY = `
|
|
1487
1522
|
query GetPoolForPointToken($id: ID!) {
|
|
@@ -1499,7 +1534,7 @@ var POOL_QUERY = `
|
|
|
1499
1534
|
}
|
|
1500
1535
|
`;
|
|
1501
1536
|
function createSubgraphPoolsProvider(config = {}) {
|
|
1502
|
-
const subgraphUrl = config.subgraphUrl ?? PAFI_SUBGRAPH_URL;
|
|
1537
|
+
const subgraphUrl = config.subgraphUrl ?? import_core6.PAFI_SUBGRAPH_URL;
|
|
1503
1538
|
try {
|
|
1504
1539
|
const parsed = new URL(subgraphUrl);
|
|
1505
1540
|
if (process.env.NODE_ENV === "production" && parsed.protocol !== "https:") {
|
|
@@ -1631,7 +1666,7 @@ var PRICE_QUERY = `
|
|
|
1631
1666
|
}
|
|
1632
1667
|
`;
|
|
1633
1668
|
function createSubgraphNativeUsdtQuoter(config = {}) {
|
|
1634
|
-
const subgraphUrl = config.subgraphUrl ?? PAFI_SUBGRAPH_URL;
|
|
1669
|
+
const subgraphUrl = config.subgraphUrl ?? import_core6.PAFI_SUBGRAPH_URL;
|
|
1635
1670
|
try {
|
|
1636
1671
|
const parsed = new URL(subgraphUrl);
|
|
1637
1672
|
if (process.env.NODE_ENV === "production" && parsed.protocol !== "https:") {
|
|
@@ -1739,7 +1774,7 @@ function toUsdtPerNative(priceFloat, usdtDecimals) {
|
|
|
1739
1774
|
}
|
|
1740
1775
|
|
|
1741
1776
|
// src/balance/balanceAggregator.ts
|
|
1742
|
-
var
|
|
1777
|
+
var import_core7 = require("@pafi-dev/core");
|
|
1743
1778
|
var BalanceAggregator = class {
|
|
1744
1779
|
provider;
|
|
1745
1780
|
ledger;
|
|
@@ -1760,7 +1795,7 @@ var BalanceAggregator = class {
|
|
|
1760
1795
|
async getCombinedBalance(user, pointToken) {
|
|
1761
1796
|
const [offChain, onChain] = await Promise.all([
|
|
1762
1797
|
this.ledger.getBalance(user, pointToken),
|
|
1763
|
-
(0,
|
|
1798
|
+
(0, import_core7.getPointTokenBalance)(this.provider, pointToken, user)
|
|
1764
1799
|
]);
|
|
1765
1800
|
return {
|
|
1766
1801
|
offChain,
|
|
@@ -1858,6 +1893,40 @@ var PafiBackendClient = class {
|
|
|
1858
1893
|
}
|
|
1859
1894
|
throw lastError;
|
|
1860
1895
|
}
|
|
1896
|
+
async relayUserOperation(request) {
|
|
1897
|
+
const fetchFn = this.config.fetchImpl ?? fetch;
|
|
1898
|
+
const url = `${this.config.url}/bundler/relay`;
|
|
1899
|
+
let response;
|
|
1900
|
+
try {
|
|
1901
|
+
response = await fetchFn(url, {
|
|
1902
|
+
method: "POST",
|
|
1903
|
+
headers: {
|
|
1904
|
+
"Content-Type": "application/json",
|
|
1905
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
1906
|
+
"X-Issuer-Id": this.config.issuerId
|
|
1907
|
+
},
|
|
1908
|
+
body: JSON.stringify(request)
|
|
1909
|
+
});
|
|
1910
|
+
} catch (err) {
|
|
1911
|
+
throw new PafiBackendError(
|
|
1912
|
+
"NETWORK_ERROR",
|
|
1913
|
+
`Network error: ${err instanceof Error ? err.message : String(err)}`,
|
|
1914
|
+
0
|
|
1915
|
+
);
|
|
1916
|
+
}
|
|
1917
|
+
const text = await response.text();
|
|
1918
|
+
let json = {};
|
|
1919
|
+
try {
|
|
1920
|
+
json = JSON.parse(text);
|
|
1921
|
+
} catch {
|
|
1922
|
+
}
|
|
1923
|
+
if (!response.ok) {
|
|
1924
|
+
const code = json.code ?? "INTERNAL_ERROR";
|
|
1925
|
+
const message = json.message ?? `HTTP ${response.status}`;
|
|
1926
|
+
throw new PafiBackendError(code, message, response.status, json);
|
|
1927
|
+
}
|
|
1928
|
+
return { userOpHash: json.userOpHash };
|
|
1929
|
+
}
|
|
1861
1930
|
async _doRequest(request) {
|
|
1862
1931
|
const fetchFn = this.config.fetchImpl ?? fetch;
|
|
1863
1932
|
const url = `${this.config.url}/paymaster/sponsor`;
|
|
@@ -1910,7 +1979,7 @@ var PafiBackendClient = class {
|
|
|
1910
1979
|
|
|
1911
1980
|
// src/config.ts
|
|
1912
1981
|
var import_viem10 = require("viem");
|
|
1913
|
-
var
|
|
1982
|
+
var import_core8 = require("@pafi-dev/core");
|
|
1914
1983
|
function createIssuerService(config) {
|
|
1915
1984
|
if (!config.provider) {
|
|
1916
1985
|
throw new Error("createIssuerService: provider is required");
|
|
@@ -1977,7 +2046,7 @@ function createIssuerService(config) {
|
|
|
1977
2046
|
indexers.set(tokenAddress, new PointIndexer(indexerConfig));
|
|
1978
2047
|
}
|
|
1979
2048
|
const firstIndexer = indexers.get(tokenAddresses[0]);
|
|
1980
|
-
const chainAddresses = (0,
|
|
2049
|
+
const chainAddresses = (0, import_core8.getContractAddresses)(config.chainId);
|
|
1981
2050
|
const resolvedContracts = {
|
|
1982
2051
|
batchExecutor: chainAddresses.batchExecutor,
|
|
1983
2052
|
usdt: chainAddresses.usdt,
|