@pafi-dev/core 0.5.18 → 0.5.19
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 +191 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.js +188 -70
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
pointTokenFactoryAbi
|
|
3
|
+
} from "./chunk-Y2MZ7MKJ.js";
|
|
1
4
|
import {
|
|
2
5
|
SPONSOR_AUTH_DOMAIN_NAME,
|
|
3
6
|
SPONSOR_AUTH_TYPES,
|
|
@@ -10,9 +13,6 @@ import {
|
|
|
10
13
|
verifyLoginMessage,
|
|
11
14
|
verifySponsorAuth
|
|
12
15
|
} from "./chunk-W6VULMCO.js";
|
|
13
|
-
import {
|
|
14
|
-
pointTokenFactoryAbi
|
|
15
|
-
} from "./chunk-Y2MZ7MKJ.js";
|
|
16
16
|
import {
|
|
17
17
|
getBurnRequestNonce,
|
|
18
18
|
getIssuer,
|
|
@@ -624,6 +624,76 @@ async function sendWithPaymasterFallback(params) {
|
|
|
624
624
|
}
|
|
625
625
|
}
|
|
626
626
|
|
|
627
|
+
// src/fee/operatorFeeQuoter.ts
|
|
628
|
+
import { parseAbi } from "viem";
|
|
629
|
+
|
|
630
|
+
// src/subgraph/pools.ts
|
|
631
|
+
import { isAddress } from "viem";
|
|
632
|
+
var PAFI_SUBGRAPH_URL = "https://graph-base-mainnet.pacificfinance.org/subgraphs/name/pafi-subgraph-v2";
|
|
633
|
+
var POOL_QUERY = `
|
|
634
|
+
query GetPoolForPointToken($id: ID!) {
|
|
635
|
+
pafiToken(id: $id) {
|
|
636
|
+
id
|
|
637
|
+
pool {
|
|
638
|
+
id
|
|
639
|
+
feeTier
|
|
640
|
+
tickSpacing
|
|
641
|
+
hooks
|
|
642
|
+
token0 { id }
|
|
643
|
+
token1 { id }
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
`;
|
|
648
|
+
function sortCurrencies(a, b) {
|
|
649
|
+
return a.toLowerCase() < b.toLowerCase() ? [a, b] : [b, a];
|
|
650
|
+
}
|
|
651
|
+
async function fetchPafiPools(_chainId, pointTokenAddress, subgraphUrl = PAFI_SUBGRAPH_URL) {
|
|
652
|
+
let response;
|
|
653
|
+
try {
|
|
654
|
+
response = await fetch(subgraphUrl, {
|
|
655
|
+
method: "POST",
|
|
656
|
+
headers: { "Content-Type": "application/json" },
|
|
657
|
+
body: JSON.stringify({
|
|
658
|
+
query: POOL_QUERY,
|
|
659
|
+
variables: { id: pointTokenAddress.toLowerCase() }
|
|
660
|
+
})
|
|
661
|
+
});
|
|
662
|
+
} catch (err) {
|
|
663
|
+
console.warn("[fetchPafiPools] subgraph unreachable:", err.message);
|
|
664
|
+
return [];
|
|
665
|
+
}
|
|
666
|
+
if (!response.ok) {
|
|
667
|
+
console.warn(`[fetchPafiPools] subgraph returned ${response.status}`);
|
|
668
|
+
return [];
|
|
669
|
+
}
|
|
670
|
+
const json = await response.json();
|
|
671
|
+
if (json.errors && json.errors.length > 0) {
|
|
672
|
+
console.warn(
|
|
673
|
+
"[fetchPafiPools] subgraph errors:",
|
|
674
|
+
json.errors.map((e) => e.message).join("; ")
|
|
675
|
+
);
|
|
676
|
+
return [];
|
|
677
|
+
}
|
|
678
|
+
const pool = json.data?.pafiToken?.pool;
|
|
679
|
+
if (!pool) return [];
|
|
680
|
+
if (!isAddress(pool.hooks) || !isAddress(pool.token0.id) || !isAddress(pool.token1.id) || !Number.isFinite(Number(pool.feeTier)) || !Number.isFinite(Number(pool.tickSpacing))) {
|
|
681
|
+
console.error("[fetchPafiPools] invalid pool data in subgraph response \u2014 skipping");
|
|
682
|
+
return [];
|
|
683
|
+
}
|
|
684
|
+
const [currency0, currency1] = sortCurrencies(
|
|
685
|
+
pool.token0.id,
|
|
686
|
+
pool.token1.id
|
|
687
|
+
);
|
|
688
|
+
return [{
|
|
689
|
+
currency0,
|
|
690
|
+
currency1,
|
|
691
|
+
fee: Number(pool.feeTier),
|
|
692
|
+
tickSpacing: Number(pool.tickSpacing),
|
|
693
|
+
hooks: pool.hooks
|
|
694
|
+
}];
|
|
695
|
+
}
|
|
696
|
+
|
|
627
697
|
// src/contracts/real/addresses.ts
|
|
628
698
|
var PLACEHOLDER_DEAD = (suffix) => `0x000000000000000000000000000000000000${suffix.toLowerCase().padStart(4, "0")}`;
|
|
629
699
|
var CONTRACT_ADDRESSES = {
|
|
@@ -679,6 +749,120 @@ function getContractAddresses(chainId) {
|
|
|
679
749
|
return addrs;
|
|
680
750
|
}
|
|
681
751
|
|
|
752
|
+
// src/fee/operatorFeeQuoter.ts
|
|
753
|
+
var CHAINLINK_ABI = parseAbi([
|
|
754
|
+
"function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80)"
|
|
755
|
+
]);
|
|
756
|
+
var CHAINLINK_MAX_AGE_S = 3600n;
|
|
757
|
+
var POOL_PRICE_QUERY = `
|
|
758
|
+
query GetPoolPrice($id: ID!) {
|
|
759
|
+
pafiToken(id: $id) {
|
|
760
|
+
pool {
|
|
761
|
+
token0 { id }
|
|
762
|
+
token1 { id }
|
|
763
|
+
token0Price
|
|
764
|
+
token1Price
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
`;
|
|
769
|
+
var DEFAULT_GAS_UNITS = 500000n;
|
|
770
|
+
var DEFAULT_PREMIUM_BPS = 12e3;
|
|
771
|
+
var DEFAULT_USDT_DECIMALS = 6;
|
|
772
|
+
async function quoteOperatorFeePt(config) {
|
|
773
|
+
const {
|
|
774
|
+
provider,
|
|
775
|
+
chainId,
|
|
776
|
+
pointTokenAddress,
|
|
777
|
+
gasUnits = DEFAULT_GAS_UNITS,
|
|
778
|
+
premiumBps = DEFAULT_PREMIUM_BPS,
|
|
779
|
+
subgraphUrl = PAFI_SUBGRAPH_URL,
|
|
780
|
+
usdtDecimals = DEFAULT_USDT_DECIMALS,
|
|
781
|
+
fallbackEthPriceUsd = 3e3,
|
|
782
|
+
fallbackPtPriceUsdt = 0.1,
|
|
783
|
+
fetchImpl = globalThis.fetch
|
|
784
|
+
} = config;
|
|
785
|
+
const chainlinkFeedAddress = config.chainlinkFeedAddress ?? getContractAddresses(chainId).chainlinkEthUsd;
|
|
786
|
+
const gasPrice = await provider.getGasPrice();
|
|
787
|
+
const nativeCost = gasPrice * gasUnits;
|
|
788
|
+
const withPremium = nativeCost * BigInt(premiumBps) / 10000n;
|
|
789
|
+
const [ethPrice8dec, ptPerUsdt18dec] = await Promise.all([
|
|
790
|
+
getEthPrice8dec(provider, chainlinkFeedAddress, fallbackEthPriceUsd),
|
|
791
|
+
getPtPerUsdt18dec(
|
|
792
|
+
fetchImpl,
|
|
793
|
+
subgraphUrl,
|
|
794
|
+
pointTokenAddress,
|
|
795
|
+
fallbackPtPriceUsdt
|
|
796
|
+
)
|
|
797
|
+
]);
|
|
798
|
+
return withPremium * ethPrice8dec * ptPerUsdt18dec / 10n ** 26n;
|
|
799
|
+
}
|
|
800
|
+
async function getEthPrice8dec(provider, feed, fallback) {
|
|
801
|
+
try {
|
|
802
|
+
const result = await provider.readContract({
|
|
803
|
+
address: feed,
|
|
804
|
+
abi: CHAINLINK_ABI,
|
|
805
|
+
functionName: "latestRoundData"
|
|
806
|
+
});
|
|
807
|
+
const answer = result[1];
|
|
808
|
+
const updatedAt = result[3];
|
|
809
|
+
if (answer <= 0n) throw new Error("Chainlink: non-positive price");
|
|
810
|
+
const ageS = BigInt(Math.floor(Date.now() / 1e3)) - updatedAt;
|
|
811
|
+
if (ageS > CHAINLINK_MAX_AGE_S) {
|
|
812
|
+
throw new Error(`Chainlink: price stale by ${ageS}s`);
|
|
813
|
+
}
|
|
814
|
+
return answer;
|
|
815
|
+
} catch (err) {
|
|
816
|
+
console.warn(
|
|
817
|
+
"[quoteOperatorFeePt] Chainlink unavailable, using fallback:",
|
|
818
|
+
err.message
|
|
819
|
+
);
|
|
820
|
+
return BigInt(Math.round(fallback * 1e8));
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
async function getPtPerUsdt18dec(fetchImpl, subgraphUrl, pointTokenAddress, fallbackPtPriceUsdt) {
|
|
824
|
+
try {
|
|
825
|
+
const response = await fetchImpl(subgraphUrl, {
|
|
826
|
+
method: "POST",
|
|
827
|
+
headers: { "Content-Type": "application/json" },
|
|
828
|
+
body: JSON.stringify({
|
|
829
|
+
query: POOL_PRICE_QUERY,
|
|
830
|
+
variables: { id: pointTokenAddress.toLowerCase() }
|
|
831
|
+
})
|
|
832
|
+
});
|
|
833
|
+
if (!response.ok) throw new Error(`subgraph HTTP ${response.status}`);
|
|
834
|
+
const json = await response.json();
|
|
835
|
+
if (json.errors?.length) {
|
|
836
|
+
throw new Error(json.errors.map((e) => e.message).join("; "));
|
|
837
|
+
}
|
|
838
|
+
const pool = json.data?.pafiToken?.pool;
|
|
839
|
+
if (!pool) throw new Error("pafiToken or pool not found");
|
|
840
|
+
const isPtToken0 = pool.token0.id.toLowerCase() === pointTokenAddress.toLowerCase();
|
|
841
|
+
const priceStr = isPtToken0 ? pool.token0Price : pool.token1Price;
|
|
842
|
+
if (!priceStr || Number(priceStr) <= 0) {
|
|
843
|
+
throw new Error(`invalid pool price from subgraph: ${priceStr}`);
|
|
844
|
+
}
|
|
845
|
+
const raw = parseBigDecimalTo18(priceStr);
|
|
846
|
+
if (raw === 0n) {
|
|
847
|
+
throw new Error(`pool price parsed to zero: ${priceStr}`);
|
|
848
|
+
}
|
|
849
|
+
return 10n ** 24n / raw;
|
|
850
|
+
} catch (err) {
|
|
851
|
+
console.warn(
|
|
852
|
+
"[quoteOperatorFeePt] subgraph unavailable, using fallback:",
|
|
853
|
+
err.message
|
|
854
|
+
);
|
|
855
|
+
const ptPerUsdtHuman = 1 / fallbackPtPriceUsdt;
|
|
856
|
+
return parseBigDecimalTo18(ptPerUsdtHuman.toFixed(18));
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
function parseBigDecimalTo18(s) {
|
|
860
|
+
const SCALE = 18;
|
|
861
|
+
const [whole = "0", frac = ""] = s.split(".");
|
|
862
|
+
const padded = (frac + "0".repeat(SCALE)).slice(0, SCALE);
|
|
863
|
+
return BigInt(whole + padded);
|
|
864
|
+
}
|
|
865
|
+
|
|
682
866
|
// src/contracts/real/batchExecutor.ts
|
|
683
867
|
var BATCH_EXECUTOR_ADDRESS_BASE_MAINNET = getContractAddresses(8453).batchExecutor;
|
|
684
868
|
var BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA = getContractAddresses(84532).batchExecutor;
|
|
@@ -804,73 +988,6 @@ async function openPafiWebModal(url, options = {}) {
|
|
|
804
988
|
);
|
|
805
989
|
}
|
|
806
990
|
|
|
807
|
-
// src/subgraph/pools.ts
|
|
808
|
-
import { isAddress } from "viem";
|
|
809
|
-
var PAFI_SUBGRAPH_URL = "https://graph-base-mainnet.pacificfinance.org/subgraphs/name/pafi-subgraph-v2";
|
|
810
|
-
var POOL_QUERY = `
|
|
811
|
-
query GetPoolForPointToken($id: ID!) {
|
|
812
|
-
pafiToken(id: $id) {
|
|
813
|
-
id
|
|
814
|
-
pool {
|
|
815
|
-
id
|
|
816
|
-
feeTier
|
|
817
|
-
tickSpacing
|
|
818
|
-
hooks
|
|
819
|
-
token0 { id }
|
|
820
|
-
token1 { id }
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
`;
|
|
825
|
-
function sortCurrencies(a, b) {
|
|
826
|
-
return a.toLowerCase() < b.toLowerCase() ? [a, b] : [b, a];
|
|
827
|
-
}
|
|
828
|
-
async function fetchPafiPools(_chainId, pointTokenAddress, subgraphUrl = PAFI_SUBGRAPH_URL) {
|
|
829
|
-
let response;
|
|
830
|
-
try {
|
|
831
|
-
response = await fetch(subgraphUrl, {
|
|
832
|
-
method: "POST",
|
|
833
|
-
headers: { "Content-Type": "application/json" },
|
|
834
|
-
body: JSON.stringify({
|
|
835
|
-
query: POOL_QUERY,
|
|
836
|
-
variables: { id: pointTokenAddress.toLowerCase() }
|
|
837
|
-
})
|
|
838
|
-
});
|
|
839
|
-
} catch (err) {
|
|
840
|
-
console.warn("[fetchPafiPools] subgraph unreachable:", err.message);
|
|
841
|
-
return [];
|
|
842
|
-
}
|
|
843
|
-
if (!response.ok) {
|
|
844
|
-
console.warn(`[fetchPafiPools] subgraph returned ${response.status}`);
|
|
845
|
-
return [];
|
|
846
|
-
}
|
|
847
|
-
const json = await response.json();
|
|
848
|
-
if (json.errors && json.errors.length > 0) {
|
|
849
|
-
console.warn(
|
|
850
|
-
"[fetchPafiPools] subgraph errors:",
|
|
851
|
-
json.errors.map((e) => e.message).join("; ")
|
|
852
|
-
);
|
|
853
|
-
return [];
|
|
854
|
-
}
|
|
855
|
-
const pool = json.data?.pafiToken?.pool;
|
|
856
|
-
if (!pool) return [];
|
|
857
|
-
if (!isAddress(pool.hooks) || !isAddress(pool.token0.id) || !isAddress(pool.token1.id) || !Number.isFinite(Number(pool.feeTier)) || !Number.isFinite(Number(pool.tickSpacing))) {
|
|
858
|
-
console.error("[fetchPafiPools] invalid pool data in subgraph response \u2014 skipping");
|
|
859
|
-
return [];
|
|
860
|
-
}
|
|
861
|
-
const [currency0, currency1] = sortCurrencies(
|
|
862
|
-
pool.token0.id,
|
|
863
|
-
pool.token1.id
|
|
864
|
-
);
|
|
865
|
-
return [{
|
|
866
|
-
currency0,
|
|
867
|
-
currency1,
|
|
868
|
-
fee: Number(pool.feeTier),
|
|
869
|
-
tickSpacing: Number(pool.tickSpacing),
|
|
870
|
-
hooks: pool.hooks
|
|
871
|
-
}];
|
|
872
|
-
}
|
|
873
|
-
|
|
874
991
|
// src/index.ts
|
|
875
992
|
var PafiSDK = class {
|
|
876
993
|
_pointTokenAddress;
|
|
@@ -1203,6 +1320,7 @@ export {
|
|
|
1203
1320
|
quoteBestRoute,
|
|
1204
1321
|
quoteExactInput,
|
|
1205
1322
|
quoteExactInputSingle,
|
|
1323
|
+
quoteOperatorFeePt,
|
|
1206
1324
|
rawCallOp,
|
|
1207
1325
|
receiverConsentTypes,
|
|
1208
1326
|
sendWithPaymasterFallback,
|