@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 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 import_viem10 = require("viem");
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, import_viem10.getAddress)(a));
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/issuer-state/validator.ts
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, import_core9.getContractAddresses)(chainId);
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, import_viem11.getAddress)(pointToken);
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, import_viem11.getAddress)(pointToken);
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: import_core9.POINT_TOKEN_V2_ABI,
2285
+ abi: import_core10.POINT_TOKEN_V2_ABI,
2161
2286
  functionName: "issuer"
2162
2287
  });
2163
- this.pointTokenIssuerCache.set(key, (0, import_viem11.getAddress)(issuer));
2164
- return (0, import_viem11.getAddress)(issuer);
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, import_viem11.getAddress)(pointToken);
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 [tuple, totalSupply] = await Promise.all([
2363
+ const [issuerStruct, totalSupply] = await Promise.all([
2239
2364
  this.provider.readContract({
2240
2365
  address: this.registryAddress,
2241
- abi: import_core9.issuerRegistryAbi,
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: import_core9.POINT_TOKEN_V2_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