@pafi-dev/issuer 0.5.10 → 0.5.12
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 +144 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -1
- package/dist/index.d.ts +52 -1
- package/dist/index.js +128 -13
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -45,8 +45,10 @@ __export(index_exports, {
|
|
|
45
45
|
TopUpRedemptionHandler: () => TopUpRedemptionHandler,
|
|
46
46
|
authenticateRequest: () => authenticateRequest,
|
|
47
47
|
createIssuerService: () => createIssuerService,
|
|
48
|
+
createNativePtQuoter: () => createNativePtQuoter,
|
|
48
49
|
createSubgraphNativeUsdtQuoter: () => createSubgraphNativeUsdtQuoter,
|
|
49
|
-
createSubgraphPoolsProvider: () => createSubgraphPoolsProvider
|
|
50
|
+
createSubgraphPoolsProvider: () => createSubgraphPoolsProvider,
|
|
51
|
+
serializeEntryToJsonRpc: () => serializeEntryToJsonRpc
|
|
50
52
|
});
|
|
51
53
|
module.exports = __toCommonJS(index_exports);
|
|
52
54
|
|
|
@@ -1775,6 +1777,107 @@ function toUsdtPerNative(priceFloat, usdtDecimals) {
|
|
|
1775
1777
|
return BigInt(whole + padded);
|
|
1776
1778
|
}
|
|
1777
1779
|
|
|
1780
|
+
// src/pools/nativePtQuoter.ts
|
|
1781
|
+
var import_viem10 = require("viem");
|
|
1782
|
+
var CHAINLINK_ABI = (0, import_viem10.parseAbi)([
|
|
1783
|
+
"function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)"
|
|
1784
|
+
]);
|
|
1785
|
+
var CHAINLINK_MAX_AGE_S = 3600n;
|
|
1786
|
+
var POOL_PRICE_QUERY = `
|
|
1787
|
+
query GetPoolPrice($id: ID!) {
|
|
1788
|
+
pafiToken(id: $id) {
|
|
1789
|
+
pool {
|
|
1790
|
+
token0 { id }
|
|
1791
|
+
token1 { id }
|
|
1792
|
+
token0Price
|
|
1793
|
+
token1Price
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
`;
|
|
1798
|
+
function createNativePtQuoter(config) {
|
|
1799
|
+
const {
|
|
1800
|
+
provider,
|
|
1801
|
+
pointTokenAddress,
|
|
1802
|
+
chainlinkFeedAddress = "0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70",
|
|
1803
|
+
subgraphUrl = import_core6.PAFI_SUBGRAPH_URL,
|
|
1804
|
+
cacheTtlMs = 3e4,
|
|
1805
|
+
fallbackEthPriceUsd = 3e3,
|
|
1806
|
+
fallbackPtPriceUsdt = 0.1,
|
|
1807
|
+
fetchImpl = globalThis.fetch,
|
|
1808
|
+
now = () => Date.now()
|
|
1809
|
+
} = config;
|
|
1810
|
+
let ethPriceCache;
|
|
1811
|
+
let ptPriceCache;
|
|
1812
|
+
async function getEthPrice8dec() {
|
|
1813
|
+
const ts = now();
|
|
1814
|
+
if (ethPriceCache && ethPriceCache.expiresAt > ts) return ethPriceCache.value;
|
|
1815
|
+
try {
|
|
1816
|
+
const result = await provider.readContract({
|
|
1817
|
+
address: chainlinkFeedAddress,
|
|
1818
|
+
abi: CHAINLINK_ABI,
|
|
1819
|
+
functionName: "latestRoundData"
|
|
1820
|
+
});
|
|
1821
|
+
const answer = result[1];
|
|
1822
|
+
const updatedAt = result[3];
|
|
1823
|
+
if (answer <= 0n) throw new Error("Chainlink: non-positive price");
|
|
1824
|
+
const ageS = BigInt(Math.floor(ts / 1e3)) - updatedAt;
|
|
1825
|
+
if (ageS > CHAINLINK_MAX_AGE_S) {
|
|
1826
|
+
throw new Error(`Chainlink: price stale by ${ageS}s`);
|
|
1827
|
+
}
|
|
1828
|
+
ethPriceCache = { value: answer, expiresAt: ts + cacheTtlMs };
|
|
1829
|
+
return answer;
|
|
1830
|
+
} catch (err) {
|
|
1831
|
+
console.warn("[nativePtQuoter] Chainlink unavailable, using fallback:", err.message);
|
|
1832
|
+
return BigInt(Math.round(fallbackEthPriceUsd * 1e8));
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
async function getPtPerUsdt18dec() {
|
|
1836
|
+
const ts = now();
|
|
1837
|
+
if (ptPriceCache && ptPriceCache.expiresAt > ts) return ptPriceCache.value;
|
|
1838
|
+
try {
|
|
1839
|
+
const response = await fetchImpl(subgraphUrl, {
|
|
1840
|
+
method: "POST",
|
|
1841
|
+
headers: { "Content-Type": "application/json" },
|
|
1842
|
+
body: JSON.stringify({
|
|
1843
|
+
query: POOL_PRICE_QUERY,
|
|
1844
|
+
variables: { id: pointTokenAddress.toLowerCase() }
|
|
1845
|
+
})
|
|
1846
|
+
});
|
|
1847
|
+
if (!response.ok) throw new Error(`subgraph HTTP ${response.status}`);
|
|
1848
|
+
const json = await response.json();
|
|
1849
|
+
if (json.errors?.length) throw new Error(json.errors.map((e) => e.message).join("; "));
|
|
1850
|
+
const pool = json.data?.pafiToken?.pool;
|
|
1851
|
+
if (!pool) throw new Error("pafiToken or pool not found in subgraph");
|
|
1852
|
+
const isPtToken0 = pool.token0.id.toLowerCase() === pointTokenAddress.toLowerCase();
|
|
1853
|
+
const ptPerUsdtStr = isPtToken0 ? pool.token0Price : pool.token1Price;
|
|
1854
|
+
if (!ptPerUsdtStr || Number(ptPerUsdtStr) <= 0) {
|
|
1855
|
+
throw new Error(`invalid PT/USDT price from subgraph: ${ptPerUsdtStr}`);
|
|
1856
|
+
}
|
|
1857
|
+
const value = parseBigDecimalTo18(ptPerUsdtStr);
|
|
1858
|
+
ptPriceCache = { value, expiresAt: ts + cacheTtlMs };
|
|
1859
|
+
return value;
|
|
1860
|
+
} catch (err) {
|
|
1861
|
+
console.warn("[nativePtQuoter] subgraph unavailable, using fallback:", err.message);
|
|
1862
|
+
return parseBigDecimalTo18(fallbackPtPriceUsdt.toString());
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
return async (amountNative) => {
|
|
1866
|
+
if (amountNative === 0n) return 0n;
|
|
1867
|
+
const [ethPrice8dec, ptPerUsdt18dec] = await Promise.all([
|
|
1868
|
+
getEthPrice8dec(),
|
|
1869
|
+
getPtPerUsdt18dec()
|
|
1870
|
+
]);
|
|
1871
|
+
return amountNative * ethPrice8dec * ptPerUsdt18dec / 10n ** 26n;
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1874
|
+
function parseBigDecimalTo18(s) {
|
|
1875
|
+
const SCALE = 18;
|
|
1876
|
+
const [whole = "0", frac = ""] = s.split(".");
|
|
1877
|
+
const padded = (frac + "0".repeat(SCALE)).slice(0, SCALE);
|
|
1878
|
+
return BigInt(whole + padded);
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1778
1881
|
// src/balance/balanceAggregator.ts
|
|
1779
1882
|
var import_core7 = require("@pafi-dev/core");
|
|
1780
1883
|
var BalanceAggregator = class {
|
|
@@ -1980,7 +2083,7 @@ var PafiBackendClient = class {
|
|
|
1980
2083
|
};
|
|
1981
2084
|
|
|
1982
2085
|
// src/config.ts
|
|
1983
|
-
var
|
|
2086
|
+
var import_viem11 = require("viem");
|
|
1984
2087
|
var import_core8 = require("@pafi-dev/core");
|
|
1985
2088
|
function createIssuerService(config) {
|
|
1986
2089
|
if (!config.provider) {
|
|
@@ -2001,7 +2104,7 @@ function createIssuerService(config) {
|
|
|
2001
2104
|
"createIssuerService: at least one of pointTokenAddress / pointTokenAddresses is required"
|
|
2002
2105
|
);
|
|
2003
2106
|
}
|
|
2004
|
-
const tokenAddresses = rawAddresses.map((a) => (0,
|
|
2107
|
+
const tokenAddresses = rawAddresses.map((a) => (0, import_viem11.getAddress)(a));
|
|
2005
2108
|
const ledger = config.ledger;
|
|
2006
2109
|
const sessionStore = config.sessionStore ?? new MemorySessionStore();
|
|
2007
2110
|
const policy = config.policy ?? new DefaultPolicyEngine({ ledger });
|
|
@@ -2095,9 +2198,31 @@ function createIssuerService(config) {
|
|
|
2095
2198
|
};
|
|
2096
2199
|
}
|
|
2097
2200
|
|
|
2098
|
-
// src/
|
|
2099
|
-
var import_viem11 = require("viem");
|
|
2201
|
+
// src/userop-store/serialize.ts
|
|
2100
2202
|
var import_core9 = require("@pafi-dev/core");
|
|
2203
|
+
function serializeEntryToJsonRpc(entry, signature) {
|
|
2204
|
+
return (0, import_core9.serializeUserOpToJsonRpc)(
|
|
2205
|
+
{
|
|
2206
|
+
sender: entry.sender,
|
|
2207
|
+
nonce: BigInt(entry.nonce),
|
|
2208
|
+
callData: entry.callData,
|
|
2209
|
+
callGasLimit: BigInt(entry.callGasLimit),
|
|
2210
|
+
verificationGasLimit: BigInt(entry.verificationGasLimit),
|
|
2211
|
+
preVerificationGas: BigInt(entry.preVerificationGas),
|
|
2212
|
+
maxFeePerGas: BigInt(entry.maxFeePerGas),
|
|
2213
|
+
maxPriorityFeePerGas: BigInt(entry.maxPriorityFeePerGas),
|
|
2214
|
+
paymaster: entry.paymaster,
|
|
2215
|
+
paymasterVerificationGasLimit: entry.paymasterVerificationGasLimit != null ? BigInt(entry.paymasterVerificationGasLimit) : void 0,
|
|
2216
|
+
paymasterPostOpGasLimit: entry.paymasterPostOpGasLimit != null ? BigInt(entry.paymasterPostOpGasLimit) : void 0,
|
|
2217
|
+
paymasterData: entry.paymasterData
|
|
2218
|
+
},
|
|
2219
|
+
signature
|
|
2220
|
+
);
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
// src/issuer-state/validator.ts
|
|
2224
|
+
var import_viem12 = require("viem");
|
|
2225
|
+
var import_core10 = require("@pafi-dev/core");
|
|
2101
2226
|
|
|
2102
2227
|
// src/issuer-state/types.ts
|
|
2103
2228
|
var IssuerStateError = class extends Error {
|
|
@@ -2128,7 +2253,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
|
|
|
2128
2253
|
* `CONTRACT_ADDRESSES` map for the given chain.
|
|
2129
2254
|
*/
|
|
2130
2255
|
static forChain(provider, chainId) {
|
|
2131
|
-
const { issuerRegistry } = (0,
|
|
2256
|
+
const { issuerRegistry } = (0, import_core10.getContractAddresses)(chainId);
|
|
2132
2257
|
return new _IssuerStateValidator(provider, issuerRegistry);
|
|
2133
2258
|
}
|
|
2134
2259
|
/**
|
|
@@ -2137,7 +2262,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
|
|
|
2137
2262
|
*/
|
|
2138
2263
|
invalidate(pointToken) {
|
|
2139
2264
|
if (pointToken) {
|
|
2140
|
-
const key = (0,
|
|
2265
|
+
const key = (0, import_viem12.getAddress)(pointToken);
|
|
2141
2266
|
this.pointTokenIssuerCache.delete(key);
|
|
2142
2267
|
this.stateCache.delete(key);
|
|
2143
2268
|
this.inflight.delete(key);
|
|
@@ -2152,23 +2277,23 @@ var IssuerStateValidator = class _IssuerStateValidator {
|
|
|
2152
2277
|
* The issuer field is set at `initialize()` and never changes.
|
|
2153
2278
|
*/
|
|
2154
2279
|
async getIssuerAddressForPointToken(pointToken) {
|
|
2155
|
-
const key = (0,
|
|
2280
|
+
const key = (0, import_viem12.getAddress)(pointToken);
|
|
2156
2281
|
const cached = this.pointTokenIssuerCache.get(key);
|
|
2157
2282
|
if (cached) return cached;
|
|
2158
2283
|
const issuer = await this.provider.readContract({
|
|
2159
2284
|
address: key,
|
|
2160
|
-
abi:
|
|
2285
|
+
abi: import_core10.POINT_TOKEN_V2_ABI,
|
|
2161
2286
|
functionName: "issuer"
|
|
2162
2287
|
});
|
|
2163
|
-
this.pointTokenIssuerCache.set(key, (0,
|
|
2164
|
-
return (0,
|
|
2288
|
+
this.pointTokenIssuerCache.set(key, (0, import_viem12.getAddress)(issuer));
|
|
2289
|
+
return (0, import_viem12.getAddress)(issuer);
|
|
2165
2290
|
}
|
|
2166
2291
|
/**
|
|
2167
2292
|
* Read registry record + totalSupply, with 30s cache and in-flight
|
|
2168
2293
|
* deduplication. Does NOT throw on inactive/missing — returns raw state.
|
|
2169
2294
|
*/
|
|
2170
2295
|
async getIssuerState(pointToken) {
|
|
2171
|
-
const tokenAddr = (0,
|
|
2296
|
+
const tokenAddr = (0, import_viem12.getAddress)(pointToken);
|
|
2172
2297
|
const now = Date.now();
|
|
2173
2298
|
const cached = this.stateCache.get(tokenAddr);
|
|
2174
2299
|
if (cached && cached.expiresAt > now) return cached.value;
|
|
@@ -2235,30 +2360,20 @@ var IssuerStateValidator = class _IssuerStateValidator {
|
|
|
2235
2360
|
}
|
|
2236
2361
|
async fetchIssuerState(tokenAddr) {
|
|
2237
2362
|
const issuerAddr = await this.getIssuerAddressForPointToken(tokenAddr);
|
|
2238
|
-
const [
|
|
2363
|
+
const [issuerStruct, totalSupply] = await Promise.all([
|
|
2239
2364
|
this.provider.readContract({
|
|
2240
2365
|
address: this.registryAddress,
|
|
2241
|
-
abi:
|
|
2366
|
+
abi: import_core10.issuerRegistryAbi,
|
|
2242
2367
|
functionName: "getIssuer",
|
|
2243
2368
|
args: [issuerAddr]
|
|
2244
2369
|
}),
|
|
2245
2370
|
this.provider.readContract({
|
|
2246
2371
|
address: tokenAddr,
|
|
2247
|
-
abi:
|
|
2372
|
+
abi: import_core10.POINT_TOKEN_V2_ABI,
|
|
2248
2373
|
functionName: "totalSupply"
|
|
2249
2374
|
})
|
|
2250
2375
|
]);
|
|
2251
|
-
const issuer =
|
|
2252
|
-
issuerAddress: tuple[0],
|
|
2253
|
-
signerAddress: tuple[1],
|
|
2254
|
-
name: tuple[2],
|
|
2255
|
-
symbol: tuple[3],
|
|
2256
|
-
declaredTotalSupply: tuple[4],
|
|
2257
|
-
capBasisPoints: tuple[5],
|
|
2258
|
-
active: tuple[6],
|
|
2259
|
-
pointToken: tuple[7],
|
|
2260
|
-
mintingOracle: tuple[8]
|
|
2261
|
-
};
|
|
2376
|
+
const issuer = issuerStruct;
|
|
2262
2377
|
const hardCap = issuer.declaredTotalSupply * BigInt(issuer.capBasisPoints) / 10000n;
|
|
2263
2378
|
const remaining = hardCap > totalSupply ? hardCap - totalSupply : 0n;
|
|
2264
2379
|
return { issuer, totalSupply, hardCap, remaining };
|
|
@@ -2294,7 +2409,9 @@ var PAFI_ISSUER_SDK_VERSION = "0.4.0";
|
|
|
2294
2409
|
TopUpRedemptionHandler,
|
|
2295
2410
|
authenticateRequest,
|
|
2296
2411
|
createIssuerService,
|
|
2412
|
+
createNativePtQuoter,
|
|
2297
2413
|
createSubgraphNativeUsdtQuoter,
|
|
2298
|
-
createSubgraphPoolsProvider
|
|
2414
|
+
createSubgraphPoolsProvider,
|
|
2415
|
+
serializeEntryToJsonRpc
|
|
2299
2416
|
});
|
|
2300
2417
|
//# sourceMappingURL=index.cjs.map
|