@w3lib/evm-batch-call 0.6.0 → 0.8.0
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/CHANGELOG.md +54 -0
- package/README.md +367 -3
- package/contracts/TokenProbe.sol +103 -0
- package/dist/aggregate.d.ts.map +1 -1
- package/dist/aggregate.js +114 -3
- package/dist/aggregate.js.map +1 -1
- package/dist/approvals.d.ts +169 -0
- package/dist/approvals.d.ts.map +1 -0
- package/dist/approvals.js +310 -0
- package/dist/approvals.js.map +1 -0
- package/dist/chains.d.ts.map +1 -1
- package/dist/chains.js +4 -0
- package/dist/chains.js.map +1 -1
- package/dist/dividends.d.ts +135 -0
- package/dist/dividends.d.ts.map +1 -0
- package/dist/dividends.js +253 -0
- package/dist/dividends.js.map +1 -0
- package/dist/fees.d.ts +97 -0
- package/dist/fees.d.ts.map +1 -0
- package/dist/fees.js +115 -0
- package/dist/fees.js.map +1 -0
- package/dist/history.d.ts +154 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +247 -0
- package/dist/history.js.map +1 -0
- package/dist/historySources.d.ts +32 -0
- package/dist/historySources.d.ts.map +1 -0
- package/dist/historySources.js +319 -0
- package/dist/historySources.js.map +1 -0
- package/dist/http.d.ts +10 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +30 -0
- package/dist/http.js.map +1 -0
- package/dist/liquidity/v3.d.ts +2 -0
- package/dist/liquidity/v3.d.ts.map +1 -1
- package/dist/liquidity/v3.js +1 -1
- package/dist/liquidity/v3.js.map +1 -1
- package/dist/liquidity/v4.d.ts +21 -0
- package/dist/liquidity/v4.d.ts.map +1 -1
- package/dist/liquidity/v4.js +4 -3
- package/dist/liquidity/v4.js.map +1 -1
- package/dist/lp.d.ts +10 -1
- package/dist/lp.d.ts.map +1 -1
- package/dist/lp.js +19 -2
- package/dist/lp.js.map +1 -1
- package/dist/lpV4.d.ts +4 -0
- package/dist/lpV4.d.ts.map +1 -1
- package/dist/lpV4.js +27 -3
- package/dist/lpV4.js.map +1 -1
- package/dist/multicall.d.ts.map +1 -1
- package/dist/multicall.js +3 -0
- package/dist/multicall.js.map +1 -1
- package/dist/names.d.ts +55 -0
- package/dist/names.d.ts.map +1 -0
- package/dist/names.js +93 -0
- package/dist/names.js.map +1 -0
- package/dist/owner.d.ts +4 -26
- package/dist/owner.d.ts.map +1 -1
- package/dist/owner.js +7 -112
- package/dist/owner.js.map +1 -1
- package/dist/permit.d.ts +137 -0
- package/dist/permit.d.ts.map +1 -0
- package/dist/permit.js +355 -0
- package/dist/permit.js.map +1 -0
- package/dist/portfolio.d.ts +56 -0
- package/dist/portfolio.d.ts.map +1 -0
- package/dist/portfolio.js +54 -0
- package/dist/portfolio.js.map +1 -0
- package/dist/price.d.ts +95 -0
- package/dist/price.d.ts.map +1 -0
- package/dist/price.js +329 -0
- package/dist/price.js.map +1 -0
- package/dist/rewards/farms.d.ts +26 -0
- package/dist/rewards/farms.d.ts.map +1 -0
- package/dist/rewards/farms.js +210 -0
- package/dist/rewards/farms.js.map +1 -0
- package/dist/rewards/index.d.ts +42 -0
- package/dist/rewards/index.d.ts.map +1 -0
- package/dist/rewards/index.js +382 -0
- package/dist/rewards/index.js.map +1 -0
- package/dist/rewards/types.d.ts +170 -0
- package/dist/rewards/types.d.ts.map +1 -0
- package/dist/rewards/types.js +2 -0
- package/dist/rewards/types.js.map +1 -0
- package/dist/risk.d.ts +42 -0
- package/dist/risk.d.ts.map +1 -0
- package/dist/risk.js +134 -0
- package/dist/risk.js.map +1 -0
- package/dist/rpcNodes.d.ts.map +1 -1
- package/dist/rpcNodes.js +18 -0
- package/dist/rpcNodes.js.map +1 -1
- package/dist/simulate.d.ts +186 -0
- package/dist/simulate.d.ts.map +1 -0
- package/dist/simulate.js +559 -0
- package/dist/simulate.js.map +1 -0
- package/dist/simulateDecode.d.ts +33 -0
- package/dist/simulateDecode.d.ts.map +1 -0
- package/dist/simulateDecode.js +321 -0
- package/dist/simulateDecode.js.map +1 -0
- package/dist/smartAccount/account.d.ts +31 -0
- package/dist/smartAccount/account.d.ts.map +1 -0
- package/dist/smartAccount/account.js +33 -0
- package/dist/smartAccount/account.js.map +1 -0
- package/dist/smartAccount/clients.d.ts +77 -0
- package/dist/smartAccount/clients.d.ts.map +1 -0
- package/dist/smartAccount/clients.js +122 -0
- package/dist/smartAccount/clients.js.map +1 -0
- package/dist/smartAccount/eip5792.d.ts +77 -0
- package/dist/smartAccount/eip5792.d.ts.map +1 -0
- package/dist/smartAccount/eip5792.js +152 -0
- package/dist/smartAccount/eip5792.js.map +1 -0
- package/dist/smartAccount/send.d.ts +40 -0
- package/dist/smartAccount/send.d.ts.map +1 -0
- package/dist/smartAccount/send.js +271 -0
- package/dist/smartAccount/send.js.map +1 -0
- package/dist/smartAccount/userOp.d.ts +91 -0
- package/dist/smartAccount/userOp.d.ts.map +1 -0
- package/dist/smartAccount/userOp.js +124 -0
- package/dist/smartAccount/userOp.js.map +1 -0
- package/dist/subpaths/approvals.d.ts +26 -0
- package/dist/subpaths/approvals.d.ts.map +1 -0
- package/dist/subpaths/approvals.js +27 -0
- package/dist/subpaths/approvals.js.map +1 -0
- package/dist/subpaths/dividends.d.ts +28 -0
- package/dist/subpaths/dividends.d.ts.map +1 -0
- package/dist/subpaths/dividends.js +29 -0
- package/dist/subpaths/dividends.js.map +1 -0
- package/dist/subpaths/fees.d.ts +23 -0
- package/dist/subpaths/fees.d.ts.map +1 -0
- package/dist/subpaths/fees.js +25 -0
- package/dist/subpaths/fees.js.map +1 -0
- package/dist/subpaths/history.d.ts +22 -0
- package/dist/subpaths/history.d.ts.map +1 -0
- package/dist/subpaths/history.js +23 -0
- package/dist/subpaths/history.js.map +1 -0
- package/dist/subpaths/names.d.ts +35 -0
- package/dist/subpaths/names.d.ts.map +1 -0
- package/dist/subpaths/names.js +39 -0
- package/dist/subpaths/names.js.map +1 -0
- package/dist/subpaths/permit.d.ts +14 -0
- package/dist/subpaths/permit.d.ts.map +1 -0
- package/dist/subpaths/permit.js +14 -0
- package/dist/subpaths/permit.js.map +1 -0
- package/dist/subpaths/price.d.ts +38 -0
- package/dist/subpaths/price.d.ts.map +1 -0
- package/dist/subpaths/price.js +40 -0
- package/dist/subpaths/price.js.map +1 -0
- package/dist/subpaths/rewards.d.ts +27 -0
- package/dist/subpaths/rewards.d.ts.map +1 -0
- package/dist/subpaths/rewards.js +25 -0
- package/dist/subpaths/rewards.js.map +1 -0
- package/dist/subpaths/risk.d.ts +19 -0
- package/dist/subpaths/risk.d.ts.map +1 -0
- package/dist/subpaths/risk.js +20 -0
- package/dist/subpaths/risk.js.map +1 -0
- package/dist/subpaths/simulate.d.ts +25 -0
- package/dist/subpaths/simulate.d.ts.map +1 -0
- package/dist/subpaths/simulate.js +28 -0
- package/dist/subpaths/simulate.js.map +1 -0
- package/dist/subpaths/smart-account.d.ts +24 -0
- package/dist/subpaths/smart-account.d.ts.map +1 -0
- package/dist/subpaths/smart-account.js +24 -0
- package/dist/subpaths/smart-account.js.map +1 -0
- package/dist/subpaths/swap.d.ts +19 -0
- package/dist/subpaths/swap.d.ts.map +1 -0
- package/dist/subpaths/swap.js +20 -0
- package/dist/subpaths/swap.js.map +1 -0
- package/dist/swap.d.ts +168 -0
- package/dist/swap.d.ts.map +1 -0
- package/dist/swap.js +387 -0
- package/dist/swap.js.map +1 -0
- package/dist/tokenProbe.d.ts +3 -0
- package/dist/tokenProbe.d.ts.map +1 -0
- package/dist/tokenProbe.js +4 -0
- package/dist/tokenProbe.js.map +1 -0
- package/dist/write/batch.d.ts +34 -2
- package/dist/write/batch.d.ts.map +1 -1
- package/dist/write/batch.js +22 -3
- package/dist/write/batch.js.map +1 -1
- package/dist/write/collect.d.ts +9 -0
- package/dist/write/collect.d.ts.map +1 -1
- package/dist/write/collect.js +41 -1
- package/dist/write/collect.js.map +1 -1
- package/dist/write/send.d.ts +4 -0
- package/dist/write/send.d.ts.map +1 -1
- package/dist/write/send.js.map +1 -1
- package/dist/write/signer.d.ts +5 -1
- package/dist/write/signer.d.ts.map +1 -1
- package/dist/write/signer.js.map +1 -1
- package/dist/write/transfer.d.ts +5 -3
- package/dist/write/transfer.d.ts.map +1 -1
- package/dist/write/transfer.js +12 -6
- package/dist/write/transfer.js.map +1 -1
- package/dist/write/tron.d.ts +25 -0
- package/dist/write/tron.d.ts.map +1 -1
- package/dist/write/tron.js +26 -0
- package/dist/write/tron.js.map +1 -1
- package/package.json +73 -16
- package/src/aggregate.ts +110 -3
- package/src/approvals.ts +462 -0
- package/src/chains.ts +4 -0
- package/src/dividends.ts +360 -0
- package/src/fees.ts +201 -0
- package/src/history.ts +367 -0
- package/src/historySources.ts +360 -0
- package/src/http.ts +34 -0
- package/src/liquidity/v3.ts +1 -1
- package/src/liquidity/v4.ts +4 -3
- package/src/lp.ts +21 -2
- package/src/lpV4.ts +32 -2
- package/src/multicall.ts +3 -0
- package/src/names.ts +141 -0
- package/src/owner.ts +7 -138
- package/src/permit.ts +457 -0
- package/src/portfolio.ts +98 -0
- package/src/price.ts +415 -0
- package/src/rewards/farms.ts +229 -0
- package/src/rewards/index.ts +431 -0
- package/src/rewards/types.ts +179 -0
- package/src/risk.ts +166 -0
- package/src/rpcNodes.ts +18 -0
- package/src/simulate.ts +727 -0
- package/src/simulateDecode.ts +352 -0
- package/src/smartAccount/account.ts +63 -0
- package/src/smartAccount/clients.ts +180 -0
- package/src/smartAccount/eip5792.ts +187 -0
- package/src/smartAccount/send.ts +341 -0
- package/src/smartAccount/userOp.ts +180 -0
- package/src/subpaths/approvals.ts +48 -0
- package/src/subpaths/dividends.ts +47 -0
- package/src/subpaths/fees.ts +43 -0
- package/src/subpaths/history.ts +41 -0
- package/src/subpaths/names.ts +43 -0
- package/src/subpaths/permit.ts +39 -0
- package/src/subpaths/price.ts +60 -0
- package/src/subpaths/rewards.ts +46 -0
- package/src/subpaths/risk.ts +23 -0
- package/src/subpaths/simulate.ts +51 -0
- package/src/subpaths/smart-account.ts +40 -0
- package/src/subpaths/swap.ts +36 -0
- package/src/swap.ts +534 -0
- package/src/tokenProbe.ts +5 -0
- package/src/write/batch.ts +44 -5
- package/src/write/collect.ts +60 -1
- package/src/write/send.ts +4 -0
- package/src/write/signer.ts +5 -1
- package/src/write/transfer.ts +17 -10
- package/src/write/tron.ts +43 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flap(flap.sh,BNB Chain 发币平台)的分红:持有带分红的 Flap 税收代币(FlapTaxToken)的地址按持仓比例分到税收,
|
|
3
|
+
* 分红放在每个代币自己的 Dividend 合约里,持有人(或任何人替持有人)调用 withdrawDividendsFor 领取。
|
|
4
|
+
*
|
|
5
|
+
* 核实过的合约(BSC 主网,2026-10 在主网分叉上实测):
|
|
6
|
+
* - 代币:`dividendContract()` 返回它的 Dividend 合约(Tax Token V3 总是部署;V2 只在 dividendBps > 0 时部署)
|
|
7
|
+
* - Dividend 合约(EIP-1167 克隆,实现 0xd67447C2…5905,Sourcify / BscScan 上未验证源码,函数靠官方文档 + 链上调用核对):
|
|
8
|
+
* `dividendToken()`、`weth()`、`minimumShareBalance()`、`withdrawableDividends(address)`、`withdrawnDividends(address)`、
|
|
9
|
+
* `withdrawDividendsFor(address)`(任何人可调,款项直接到持有人)
|
|
10
|
+
* - 官方 TaxTokenHelper(0x53841c73…8346)的 `getDividendInfo(token, user) → (claimed, pending)` 与上面两个函数结果一致(测试里交叉核对)
|
|
11
|
+
*
|
|
12
|
+
* 只有一种合约形态,所以只有一个适配器(flap);识别不了的代币(没有 dividendContract() 或 Dividend 合约缺函数)放进 unsupported,
|
|
13
|
+
* 不猜函数。
|
|
14
|
+
*/
|
|
15
|
+
import { Interface, getAddress } from 'ethers';
|
|
16
|
+
import { NATIVE_TOKEN, formatUnits } from './erc20.js';
|
|
17
|
+
import { runLogScan } from './scan.js';
|
|
18
|
+
import { isTronChain } from './tron.js';
|
|
19
|
+
/** 支持的链:目前只有 BSC(Flap 在 Base、X Layer 等链上也有部署,但没有核实过,不开放) */
|
|
20
|
+
export const FLAP_DIVIDEND_CHAINS = {
|
|
21
|
+
56: {
|
|
22
|
+
portal: '0xe2cE6ab80874Fa9Fa2aAE65D277Dd6B8e65C9De0',
|
|
23
|
+
taxTokenHelper: '0x53841c73217735F37BC1775538b03b23feFD8346',
|
|
24
|
+
swapRegistry: '0x644A8f560138418bAD4EdEFC7c17878a3c2fBEB6',
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
/** Flap 代币地址的靓号后缀(Portal 创建时用):税收代币是 7777,普通代币是 8888(实测也有 8888 的代币带分红合约);发现持仓时只收这类地址 */
|
|
28
|
+
export const FLAP_TOKEN_SUFFIXES = ['7777', '8888'];
|
|
29
|
+
const TOKEN_ABI = [
|
|
30
|
+
'function dividendContract() view returns (address)',
|
|
31
|
+
'function balanceOf(address) view returns (uint256)',
|
|
32
|
+
'function symbol() view returns (string)',
|
|
33
|
+
'function decimals() view returns (uint8)',
|
|
34
|
+
];
|
|
35
|
+
const DIVIDEND_ABI = [
|
|
36
|
+
'function dividendToken() view returns (address)',
|
|
37
|
+
'function weth() view returns (address)',
|
|
38
|
+
'function minimumShareBalance() view returns (uint256)',
|
|
39
|
+
'function withdrawableDividends(address) view returns (uint256)',
|
|
40
|
+
'function withdrawnDividends(address) view returns (uint256)',
|
|
41
|
+
];
|
|
42
|
+
const ERC20_META_ABI = ['function symbol() view returns (string)', 'function decimals() view returns (uint8)'];
|
|
43
|
+
const claimInterface = new Interface(['function withdrawDividendsFor(address user)']);
|
|
44
|
+
const ZERO = '0x0000000000000000000000000000000000000000';
|
|
45
|
+
const TRANSFER_TOPIC = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';
|
|
46
|
+
/** 一次最多检查的代币数(防止传入或发现的列表无限大) */
|
|
47
|
+
const MAX_TOKENS = 200;
|
|
48
|
+
function assertChain(chainId) {
|
|
49
|
+
if (isTronChain(chainId) || !FLAP_DIVIDEND_CHAINS[chainId]) {
|
|
50
|
+
throw new Error(`Flap dividends are only supported on BNB Chain (56), got chain ${chainId}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** 发现持有人收到过的 Flap 税收代币(只发现,不核对有没有分红:把 tokens 交给 dividends) */
|
|
54
|
+
export async function scanDividendTokens(provider, owner, options = {}) {
|
|
55
|
+
assertChain(await provider.getChainId());
|
|
56
|
+
const ownerTopic = `0x${getAddress(owner).slice(2).toLowerCase().padStart(64, '0')}`;
|
|
57
|
+
const lookback = Math.max(0, Math.floor(options.lookbackBlocks ?? 5000));
|
|
58
|
+
const suffixes = (options.suffixes ?? FLAP_TOKEN_SUFFIXES).map((x) => x.toLowerCase());
|
|
59
|
+
const progress = await runLogScan({
|
|
60
|
+
provider,
|
|
61
|
+
saved: options.progress,
|
|
62
|
+
initialCursor: (target) => (options.fromBlock !== undefined ? options.fromBlock - 1 : target - lookback),
|
|
63
|
+
filter: { topics: [TRANSFER_TOPIC, null, ownerTopic] },
|
|
64
|
+
// 只收 ERC20 的 Transfer(3 个 topic)里靓号后缀的合约
|
|
65
|
+
collect: (log) => (log.topics.length === 3 && suffixes.some((s) => log.address.toLowerCase().endsWith(s)) ? log.address.toLowerCase() : null),
|
|
66
|
+
maxRange: Math.max(1, Math.floor(options.blockRange ?? 1000)),
|
|
67
|
+
maxRequests: Math.max(1, Math.floor(options.maxRequests ?? 10)),
|
|
68
|
+
timeBudget: options.timeBudget ?? 10_000,
|
|
69
|
+
confirmations: 0,
|
|
70
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
71
|
+
});
|
|
72
|
+
return { tokens: (progress?.items ?? []).map((a) => getAddress(a)), cursor: progress?.cursor ?? -1, progress };
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 查持有人在 Flap 代币上的分红:余额、可领取数量、已领取数量、分红资产和美元价值。
|
|
76
|
+
* 代币来自 tokens 和 discover(扫描收到过的 Transfer),每个代币都在链上核对(dividendContract() + Dividend 合约的函数),
|
|
77
|
+
* 核对不过的放进 unsupported。不发送交易
|
|
78
|
+
*/
|
|
79
|
+
export async function dividends(provider, owner, options = {}) {
|
|
80
|
+
const chainId = await provider.getChainId();
|
|
81
|
+
assertChain(chainId);
|
|
82
|
+
const holder = getAddress(owner);
|
|
83
|
+
let scan;
|
|
84
|
+
const found = new Map();
|
|
85
|
+
const explicit = new Set();
|
|
86
|
+
for (const t of options.tokens ?? []) {
|
|
87
|
+
found.set(getAddress(t).toLowerCase(), getAddress(t));
|
|
88
|
+
explicit.add(getAddress(t).toLowerCase());
|
|
89
|
+
}
|
|
90
|
+
if (options.discover) {
|
|
91
|
+
const r = await scanDividendTokens(provider, holder, options.discover === true ? {} : options.discover);
|
|
92
|
+
scan = { cursor: r.cursor, progress: r.progress, tokens: r.tokens };
|
|
93
|
+
for (const t of r.tokens)
|
|
94
|
+
found.set(t.toLowerCase(), t);
|
|
95
|
+
}
|
|
96
|
+
const tokens = [...found.values()];
|
|
97
|
+
if (tokens.length > MAX_TOKENS)
|
|
98
|
+
throw new Error(`Too many tokens (${tokens.length}), at most ${MAX_TOKENS} per call`);
|
|
99
|
+
const result = { items: [], unsupported: [], ...(scan ? { scan } : {}) };
|
|
100
|
+
if (!tokens.length)
|
|
101
|
+
return result;
|
|
102
|
+
// 第一步:代币本身(余额、精度、Dividend 合约地址)
|
|
103
|
+
const stage1 = await provider.tryAll(tokens.flatMap((t) => [provider.contract(t, TOKEN_ABI).dividendContract(), provider.contract(t, TOKEN_ABI).balanceOf(holder), provider.contract(t, TOKEN_ABI).symbol(), provider.contract(t, TOKEN_ABI).decimals()]));
|
|
104
|
+
const valid = [];
|
|
105
|
+
tokens.forEach((token, i) => {
|
|
106
|
+
const [dividend, balance, symbol, decimals] = stage1.slice(i * 4, i * 4 + 4);
|
|
107
|
+
if (dividend === null || dividend === ZERO) {
|
|
108
|
+
// 发现来的代币大多不是分红代币(普通 8888 代币等),只报告用户明确传入的
|
|
109
|
+
if (explicit.has(token.toLowerCase()))
|
|
110
|
+
result.unsupported.push({ token, reason: dividend === null ? 'no dividendContract() (not a Flap tax token V2/V3)' : 'token has no dividend contract' });
|
|
111
|
+
}
|
|
112
|
+
else if (balance === null || decimals === null) {
|
|
113
|
+
result.unsupported.push({ token, reason: 'not an ERC20 token' });
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
valid.push({ token, dividend, balance, symbol: typeof symbol === 'string' ? symbol : null, decimals: Number(decimals) });
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
// 第二步:Dividend 合约(分红代币、可领取、已领取、最低持仓)
|
|
120
|
+
const stage2 = valid.length
|
|
121
|
+
? await provider.tryAll(valid.flatMap((v) => {
|
|
122
|
+
const d = provider.contract(v.dividend, DIVIDEND_ABI);
|
|
123
|
+
return [d.dividendToken(), d.weth(), d.withdrawableDividends(holder), d.withdrawnDividends(holder), d.minimumShareBalance()];
|
|
124
|
+
}))
|
|
125
|
+
: [];
|
|
126
|
+
const rows = [];
|
|
127
|
+
valid.forEach((v, i) => {
|
|
128
|
+
const [dividendToken, weth, claimable, claimed, min] = stage2.slice(i * 5, i * 5 + 5);
|
|
129
|
+
if (dividendToken === null || claimable === null || claimed === null || min === null) {
|
|
130
|
+
result.unsupported.push({ token: v.token, reason: 'dividend contract does not expose the expected functions (unknown generation)' });
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
rows.push({ v, dividendToken, weth, claimable, claimed, min });
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
// 第三步:分红资产的 symbol / decimals(WBNB 作为 BNB 领取:按主币处理)
|
|
137
|
+
const isNative = (r) => r.dividendToken === ZERO || (r.weth !== null && r.dividendToken.toLowerCase() === r.weth.toLowerCase());
|
|
138
|
+
const assetTokens = [...new Set(rows.filter((r) => !isNative(r)).map((r) => r.dividendToken))];
|
|
139
|
+
const meta = new Map();
|
|
140
|
+
if (assetTokens.length) {
|
|
141
|
+
const res = await provider.tryAll(assetTokens.flatMap((a) => [provider.contract(a, ERC20_META_ABI).symbol(), provider.contract(a, ERC20_META_ABI).decimals()]));
|
|
142
|
+
assetTokens.forEach((a, i) => meta.set(a, { symbol: typeof res[i * 2] === 'string' ? res[i * 2] : null, decimals: res[i * 2 + 1] === null ? 18 : Number(res[i * 2 + 1]), known: res[i * 2 + 1] !== null }));
|
|
143
|
+
}
|
|
144
|
+
const nativeMeta = { symbol: 'BNB', decimals: 18, known: true };
|
|
145
|
+
const items = rows.map((r) => {
|
|
146
|
+
const native = isNative(r);
|
|
147
|
+
const m = native ? nativeMeta : (meta.get(r.dividendToken) ?? { symbol: null, decimals: 18, known: false });
|
|
148
|
+
return {
|
|
149
|
+
owner: holder,
|
|
150
|
+
token: r.v.token,
|
|
151
|
+
symbol: r.v.symbol,
|
|
152
|
+
decimals: r.v.decimals,
|
|
153
|
+
balance: r.v.balance.toString(),
|
|
154
|
+
dividendContract: getAddress(r.v.dividend),
|
|
155
|
+
dividendToken: getAddress(r.dividendToken),
|
|
156
|
+
asset: native ? 'native' : getAddress(r.dividendToken),
|
|
157
|
+
assetSymbol: m.symbol,
|
|
158
|
+
assetDecimals: m.decimals,
|
|
159
|
+
...(m.known ? {} : { decimalsUnknown: true }),
|
|
160
|
+
claimable: r.claimable.toString(),
|
|
161
|
+
claimableFormatted: formatUnits(r.claimable, m.decimals),
|
|
162
|
+
claimed: r.claimed.toString(),
|
|
163
|
+
claimedFormatted: formatUnits(r.claimed, m.decimals),
|
|
164
|
+
usd: null,
|
|
165
|
+
minimumShareBalance: r.min.toString(),
|
|
166
|
+
accruing: r.v.balance >= r.min && r.v.balance > 0n,
|
|
167
|
+
adapter: 'flap',
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
const shown = options.includeZero ? items : items.filter((i) => BigInt(i.claimable) > 0n);
|
|
171
|
+
if (options.prices !== false && shown.length) {
|
|
172
|
+
try {
|
|
173
|
+
const { tokenPrices } = await import('./price.js');
|
|
174
|
+
const assets = [...new Set(shown.map((i) => (i.asset === 'native' ? NATIVE_TOKEN : i.asset)))];
|
|
175
|
+
const prices = await tokenPrices(provider, assets, { ...(typeof options.prices === 'object' ? { sources: [options.prices] } : {}), ...(options.fetch ? { fetch: options.fetch } : {}) });
|
|
176
|
+
const byAsset = new Map(prices.map((p) => [p.token.toLowerCase(), p.price]));
|
|
177
|
+
for (const i of shown) {
|
|
178
|
+
if (i.decimalsUnknown)
|
|
179
|
+
continue; // 精度未知,换算不出可信的美元价值
|
|
180
|
+
const price = byAsset.get((i.asset === 'native' ? NATIVE_TOKEN : i.asset).toLowerCase());
|
|
181
|
+
i.usd = price === null || price === undefined ? null : Number(i.claimableFormatted) * price;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
result.priceError = err instanceof Error ? err.message : String(err);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
result.items = shown;
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* 领取分红要发的交易(不签名):每个代币一笔 `withdrawDividendsFor(owner)`,发给它的 Dividend 合约,款项直接到 owner。
|
|
193
|
+
* 只包含 claimable > 0 的项。只校验 owner / dividendContract 是合法地址,不连链:items 来自调用方,
|
|
194
|
+
* 要确认 dividendContract 确实是代币自己的 Dividend 合约,用 claimDividends(发送前会在链上核对)
|
|
195
|
+
*/
|
|
196
|
+
export function buildClaimDividends(items) {
|
|
197
|
+
return items
|
|
198
|
+
.filter((item) => BigInt(item.claimable) > 0n)
|
|
199
|
+
.map((item) => {
|
|
200
|
+
if (item.adapter !== 'flap')
|
|
201
|
+
throw new Error(`Unsupported dividend adapter for ${item.token}`);
|
|
202
|
+
let to;
|
|
203
|
+
let owner;
|
|
204
|
+
try {
|
|
205
|
+
to = getAddress(item.dividendContract);
|
|
206
|
+
owner = getAddress(item.owner);
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
throw new Error(`Invalid dividendContract / owner address for ${item.token}`);
|
|
210
|
+
}
|
|
211
|
+
return { to, data: claimInterface.encodeFunctionData('withdrawDividendsFor', [owner]), value: '0', item };
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* 领取分红:构建(同 buildClaimDividends)后用 from 签名发送,钱包和选项同 batchCall
|
|
216
|
+
* (mode: '7702' / '4337' / '5792' 时合成一笔原子交易)。任何人都可以替持有人领取,款项直接到 item.owner,所以 from 不必是持有人(如代付 gas)。
|
|
217
|
+
*
|
|
218
|
+
* ```ts
|
|
219
|
+
* const { items } = await getDividends(user, { chainId: 56, discover: true })
|
|
220
|
+
* await claimDividends(provider, key, items, { mode: '7702' })
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
export async function claimDividends(provider, from, items, options = {}) {
|
|
224
|
+
assertChain(await provider.getChainId());
|
|
225
|
+
const { simulate: preCheck = true, ...sendOptions } = options;
|
|
226
|
+
const txs = buildClaimDividends(items);
|
|
227
|
+
if (!txs.length)
|
|
228
|
+
return [];
|
|
229
|
+
const skipped = new Map();
|
|
230
|
+
// 核对 items 里的 dividendContract 确实是代币自己的 Dividend 合约(items 来自调用方,不能直接信)
|
|
231
|
+
const onChain = await provider.tryAll(txs.map((tx) => provider.contract(tx.item.token, TOKEN_ABI).dividendContract()));
|
|
232
|
+
onChain.forEach((d, i) => {
|
|
233
|
+
if (d === null || txs[i].to.toLowerCase() !== d.toLowerCase()) {
|
|
234
|
+
skipped.set(i, `dividendContract mismatch: ${txs[i].to} is not the dividend contract of ${txs[i].item.token}`);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
if (preCheck) {
|
|
238
|
+
const { simulate } = await import('./simulate.js');
|
|
239
|
+
const sims = await Promise.all(txs.map((tx, i) => skipped.has(i) ? Promise.resolve({ success: true }) : simulate(provider, { to: tx.to, data: tx.data, from: tx.item.owner }, { usd: false, risk: false }).catch((err) => ({ success: false, error: err instanceof Error ? err.message : String(err) }))));
|
|
240
|
+
sims.forEach((s, i) => !s.success && skipped.set(i, s.error ?? 'simulation failed'));
|
|
241
|
+
}
|
|
242
|
+
const send = txs.map((tx, i) => ({ tx, i })).filter(({ i }) => !skipped.has(i));
|
|
243
|
+
const { batchCall } = await import('./write/batch.js');
|
|
244
|
+
const sent = send.length ? await batchCall(provider, send.map(({ tx }) => ({ from, to: tx.to, data: tx.data })), { continueOnError: true, ...sendOptions }) : [];
|
|
245
|
+
const sentBy = new Map(send.map(({ i }, k) => [i, sent[k]]));
|
|
246
|
+
return txs.map((tx, i) => {
|
|
247
|
+
const r = sentBy.get(i);
|
|
248
|
+
if (r)
|
|
249
|
+
return { ...r, index: i, item: tx.item };
|
|
250
|
+
return { index: i, from: tx.item.owner, to: tx.to, status: 'skipped', hash: null, nonce: null, gasLimit: null, gasUsed: null, fee: null, blockNumber: null, error: skipped.get(i) ?? null, item: tx.item };
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=dividends.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dividends.js","sourceRoot":"","sources":["../src/dividends.ts"],"names":[],"mappings":"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"}
|
package/dist/fees.d.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 手续费估算(子路径 `@w3lib/evm-batch-call/fees`):EIP-1559 的 baseFee 和三档优先费(按最近区块的 eth_feeHistory),
|
|
3
|
+
* 一笔交易的手续费(含 OP Stack / Scroll 的 L1 数据费);Tron 按能量 / 带宽和账户剩余的资源算要烧的 TRX
|
|
4
|
+
*/
|
|
5
|
+
import type { BigNumberish } from 'ethers';
|
|
6
|
+
import type { Provider } from './provider.js';
|
|
7
|
+
export type FeeLevel = 'slow' | 'normal' | 'fast';
|
|
8
|
+
/** 一档费用(wei 的十进制字符串):EIP-1559 链是 maxFeePerGas / maxPriorityFeePerGas,legacy 链是 gasPrice */
|
|
9
|
+
export type FeeLevelEstimate = {
|
|
10
|
+
maxFeePerGas: string;
|
|
11
|
+
maxPriorityFeePerGas: string;
|
|
12
|
+
} | {
|
|
13
|
+
gasPrice: string;
|
|
14
|
+
};
|
|
15
|
+
export interface FeeEstimate {
|
|
16
|
+
type: 'eip1559' | 'legacy';
|
|
17
|
+
/** 下一个区块的 baseFee(wei);legacy 链为 null */
|
|
18
|
+
baseFee: string | null;
|
|
19
|
+
slow: FeeLevelEstimate;
|
|
20
|
+
normal: FeeLevelEstimate;
|
|
21
|
+
fast: FeeLevelEstimate;
|
|
22
|
+
}
|
|
23
|
+
export interface EstimateFeesOptions {
|
|
24
|
+
/** 看最近多少个区块,默认 20 */
|
|
25
|
+
blocks?: number;
|
|
26
|
+
/** 三档优先费取各区块交易优先费的百分位,默认 [10, 50, 90] */
|
|
27
|
+
percentiles?: readonly [number, number, number];
|
|
28
|
+
/** maxFeePerGas = baseFee × baseFeeMultiplier + 优先费,默认 2(baseFee 连涨几个区块也够) */
|
|
29
|
+
baseFeeMultiplier?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 当前的手续费建议(EVM 链):baseFee 取下一个区块的,三档优先费是最近区块里交易优先费的百分位的中位数;
|
|
33
|
+
* 节点不支持 eth_feeHistory 或链上没有 baseFee 时按 eth_gasPrice(三档为 1、1、1.2 倍)。Tron 用 estimateCost
|
|
34
|
+
*
|
|
35
|
+
* ```ts
|
|
36
|
+
* const fees = await estimateFees(provider)
|
|
37
|
+
* // { type: 'eip1559', baseFee: '1200000000', slow: { maxFeePerGas, maxPriorityFeePerGas }, normal: {…}, fast: {…} }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function estimateFees(provider: Provider, options?: EstimateFeesOptions): Promise<FeeEstimate>;
|
|
41
|
+
export interface CostCall {
|
|
42
|
+
/** 发送者(预估 gas、Tron 上按它剩余的资源算) */
|
|
43
|
+
from: string;
|
|
44
|
+
to: string;
|
|
45
|
+
data?: string;
|
|
46
|
+
value?: BigNumberish;
|
|
47
|
+
}
|
|
48
|
+
export interface EvmCostEstimate {
|
|
49
|
+
type: 'evm';
|
|
50
|
+
gasLimit: string;
|
|
51
|
+
/** 这一档的每 gas 价格:EIP-1559 是 baseFee + 优先费(预计实际付的),legacy 是 gasPrice */
|
|
52
|
+
gasPrice: string;
|
|
53
|
+
/** gasLimit × gasPrice(wei) */
|
|
54
|
+
fee: string;
|
|
55
|
+
/** 最多付多少:gasLimit × maxFeePerGas(legacy 同 fee) */
|
|
56
|
+
maxFee: string;
|
|
57
|
+
/** OP Stack / Scroll 的 L1 数据费(wei,含 25% 余量),其他链为 0 */
|
|
58
|
+
l1Fee: string;
|
|
59
|
+
/** fee + l1Fee(wei)和按主币精度换算的值 */
|
|
60
|
+
total: string;
|
|
61
|
+
totalFormatted: string;
|
|
62
|
+
symbol: string | null;
|
|
63
|
+
}
|
|
64
|
+
export interface TronCost {
|
|
65
|
+
type: 'tron';
|
|
66
|
+
energy: number;
|
|
67
|
+
bandwidth: number;
|
|
68
|
+
/** 剩余能量 / 带宽不够时要烧的 TRX(sun) */
|
|
69
|
+
energyBurn: string;
|
|
70
|
+
bandwidthBurn: string;
|
|
71
|
+
/** 转 TRX 给没激活的地址(激活费算在 bandwidthBurn 里) */
|
|
72
|
+
activates: boolean;
|
|
73
|
+
energyPrice: string;
|
|
74
|
+
bandwidthPrice: string;
|
|
75
|
+
/** energyBurn + bandwidthBurn(sun)和按 TRX 换算的值 */
|
|
76
|
+
total: string;
|
|
77
|
+
totalFormatted: string;
|
|
78
|
+
symbol: 'TRX';
|
|
79
|
+
}
|
|
80
|
+
export type CostEstimate = EvmCostEstimate | TronCost;
|
|
81
|
+
export interface EstimateCostOptions extends EstimateFeesOptions {
|
|
82
|
+
/** 用哪一档,默认 'normal' */
|
|
83
|
+
level?: FeeLevel;
|
|
84
|
+
/** 已经查好的费用建议(多笔交易共用,不再查一次) */
|
|
85
|
+
fees?: FeeEstimate;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 估算一笔交易的手续费:EVM 预估 gas × 这一档的价格(+ L1 数据费);Tron 模拟能量,按发送者剩余的资源算要烧的 TRX。
|
|
89
|
+
* 预估 gas 会执行一遍交易,revert 时抛出
|
|
90
|
+
*
|
|
91
|
+
* ```ts
|
|
92
|
+
* await estimateCost(provider, { from: user, to: USDT, data }) // { type: 'evm', gasLimit, fee, total, totalFormatted: '0.00042', symbol: 'BNB', … }
|
|
93
|
+
* await estimateCost(tronProvider, { from, to: USDT, data }) // { type: 'tron', energy: 64285, energyBurn: '6750000', totalFormatted: '7.0', … }
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function estimateCost(provider: Provider, call: CostCall, options?: EstimateCostOptions): Promise<CostEstimate>;
|
|
97
|
+
//# sourceMappingURL=fees.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fees.d.ts","sourceRoot":"","sources":["../src/fees.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAI1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAG7C,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEjD,2FAA2F;AAC3F,MAAM,MAAM,gBAAgB,GAAG;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AAE5G,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAA;IAC1B,yCAAyC;IACzC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,IAAI,EAAE,gBAAgB,CAAA;IACtB,MAAM,EAAE,gBAAgB,CAAA;IACxB,IAAI,EAAE,gBAAgB,CAAA;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,qBAAqB;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,yCAAyC;IACzC,WAAW,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAwBD;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,WAAW,CAAC,CA6B9G;AAED,MAAM,WAAW,QAAQ;IACvB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,YAAY,CAAA;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,KAAK,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAA;IAChB,+BAA+B;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAA;IACd,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAA;IACb,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,SAAS,EAAE,OAAO,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,KAAK,CAAA;CACd;AAED,MAAM,MAAM,YAAY,GAAG,eAAe,GAAG,QAAQ,CAAA;AAErD,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB;IAC9D,uBAAuB;IACvB,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,WAAW,CAAA;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,YAAY,CAAC,CA4C/H"}
|
package/dist/fees.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { getNativeCurrency } from './chains.js';
|
|
2
|
+
import { formatUnits } from './erc20.js';
|
|
3
|
+
import { isTronChain } from './tron.js';
|
|
4
|
+
async function send(provider, method, params) {
|
|
5
|
+
const { runOnNodes } = await import('./write/rpc.js');
|
|
6
|
+
return runOnNodes(provider.rpc, method, async (node) => {
|
|
7
|
+
if (typeof node.send !== 'function')
|
|
8
|
+
throw new Error(`${method} is not supported by this node; pass an RPC URL or an ethers Provider`);
|
|
9
|
+
return (await node.send(method, params));
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
const median = (values) => {
|
|
13
|
+
if (!values.length)
|
|
14
|
+
return 0n;
|
|
15
|
+
const sorted = [...values].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
16
|
+
return sorted[Math.floor(sorted.length / 2)];
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* 当前的手续费建议(EVM 链):baseFee 取下一个区块的,三档优先费是最近区块里交易优先费的百分位的中位数;
|
|
20
|
+
* 节点不支持 eth_feeHistory 或链上没有 baseFee 时按 eth_gasPrice(三档为 1、1、1.2 倍)。Tron 用 estimateCost
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* const fees = await estimateFees(provider)
|
|
24
|
+
* // { type: 'eip1559', baseFee: '1200000000', slow: { maxFeePerGas, maxPriorityFeePerGas }, normal: {…}, fast: {…} }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export async function estimateFees(provider, options = {}) {
|
|
28
|
+
if (isTronChain(await provider.getChainId()))
|
|
29
|
+
throw new Error('estimateFees is for EVM chains; use estimateCost on Tron');
|
|
30
|
+
const blocks = Math.max(1, Math.min(1024, Math.floor(options.blocks ?? 20)));
|
|
31
|
+
const percentiles = options.percentiles ?? [10, 50, 90];
|
|
32
|
+
if (!percentiles.every((p, i) => p >= 0 && p <= 100 && (i === 0 || p >= percentiles[i - 1])))
|
|
33
|
+
throw new RangeError('percentiles must be ascending numbers in [0, 100]');
|
|
34
|
+
const multiplier = options.baseFeeMultiplier ?? 2;
|
|
35
|
+
let history = null;
|
|
36
|
+
try {
|
|
37
|
+
history = await send(provider, 'eth_feeHistory', [`0x${blocks.toString(16)}`, 'latest', [...percentiles]]);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
// 只有节点 / 链不支持 feeHistory 时才按 gasPrice;网络等其他错误照常抛出(不要在 EIP-1559 链上悄悄退回 legacy)
|
|
41
|
+
if (!/not (supported|available|found)|unsupported|does not exist|unknown method|-32601|method.*not/i.test(err instanceof Error ? err.message : String(err)))
|
|
42
|
+
throw err;
|
|
43
|
+
history = null;
|
|
44
|
+
}
|
|
45
|
+
const baseFees = history?.baseFeePerGas ?? [];
|
|
46
|
+
const next = baseFees.length ? BigInt(baseFees[baseFees.length - 1]) : 0n;
|
|
47
|
+
if (!history || !baseFees.length || next === 0n) {
|
|
48
|
+
const gasPrice = BigInt(await send(provider, 'eth_gasPrice', []));
|
|
49
|
+
const level = (n, d) => ({ gasPrice: ((gasPrice * n) / d).toString() });
|
|
50
|
+
return { type: 'legacy', baseFee: null, slow: level(1n, 1n), normal: level(1n, 1n), fast: level(6n, 5n) };
|
|
51
|
+
}
|
|
52
|
+
const rewards = history.reward ?? [];
|
|
53
|
+
// 每档:各区块这个百分位的优先费取中位数(空区块的 0 不算)
|
|
54
|
+
const tip = (k) => median(rewards.map((r) => BigInt(r[k] ?? '0')).filter((v) => v > 0n));
|
|
55
|
+
const base = (next * BigInt(Math.round(multiplier * 1000))) / 1000n;
|
|
56
|
+
const level = (priority) => ({ maxFeePerGas: (base + priority).toString(), maxPriorityFeePerGas: priority.toString() });
|
|
57
|
+
const [slow, normal, fast] = [tip(0), tip(1), tip(2)];
|
|
58
|
+
// 优先费不递减(区块很空时三档可能相同)
|
|
59
|
+
return { type: 'eip1559', baseFee: next.toString(), slow: level(slow), normal: level(normal > slow ? normal : slow), fast: level(fast > normal ? fast : normal > slow ? normal : slow) };
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 估算一笔交易的手续费:EVM 预估 gas × 这一档的价格(+ L1 数据费);Tron 模拟能量,按发送者剩余的资源算要烧的 TRX。
|
|
63
|
+
* 预估 gas 会执行一遍交易,revert 时抛出
|
|
64
|
+
*
|
|
65
|
+
* ```ts
|
|
66
|
+
* await estimateCost(provider, { from: user, to: USDT, data }) // { type: 'evm', gasLimit, fee, total, totalFormatted: '0.00042', symbol: 'BNB', … }
|
|
67
|
+
* await estimateCost(tronProvider, { from, to: USDT, data }) // { type: 'tron', energy: 64285, energyBurn: '6750000', totalFormatted: '7.0', … }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export async function estimateCost(provider, call, options = {}) {
|
|
71
|
+
const chainId = await provider.getChainId();
|
|
72
|
+
const value = BigInt(call.value ?? 0);
|
|
73
|
+
if (isTronChain(chainId)) {
|
|
74
|
+
const { tronEstimateCost } = await import('./write/tron.js');
|
|
75
|
+
const c = await tronEstimateCost(provider, { from: call.from, to: call.to, ...(call.data ? { data: call.data } : {}), value });
|
|
76
|
+
const total = c.energyBurn + c.bandwidthBurn;
|
|
77
|
+
return {
|
|
78
|
+
type: 'tron',
|
|
79
|
+
energy: c.energy,
|
|
80
|
+
bandwidth: c.bandwidth,
|
|
81
|
+
energyBurn: c.energyBurn.toString(),
|
|
82
|
+
bandwidthBurn: c.bandwidthBurn.toString(),
|
|
83
|
+
activates: c.activates,
|
|
84
|
+
energyPrice: c.energyPrice.toString(),
|
|
85
|
+
bandwidthPrice: c.bandwidthPrice.toString(),
|
|
86
|
+
total: total.toString(),
|
|
87
|
+
totalFormatted: formatUnits(total, 6),
|
|
88
|
+
symbol: 'TRX',
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const { WriteRpc, l1Fee } = await import('./write/rpc.js');
|
|
92
|
+
const rpc = await WriteRpc.from(provider);
|
|
93
|
+
const tx = { from: call.from, to: call.to, data: call.data ?? '0x', value };
|
|
94
|
+
const [gasLimit, fees] = await Promise.all([rpc.estimateGas(tx), options.fees ? Promise.resolve(options.fees) : estimateFees(provider, options)]);
|
|
95
|
+
const level = fees[options.level ?? 'normal'];
|
|
96
|
+
const perGas = 'gasPrice' in level ? BigInt(level.gasPrice) : BigInt(fees.baseFee ?? '0') + BigInt(level.maxPriorityFeePerGas);
|
|
97
|
+
const maxPerGas = 'gasPrice' in level ? perGas : BigInt(level.maxFeePerGas);
|
|
98
|
+
const feeFields = 'gasPrice' in level ? { type: 0, gasPrice: perGas } : { type: 2, maxFeePerGas: maxPerGas, maxPriorityFeePerGas: BigInt(level.maxPriorityFeePerGas) };
|
|
99
|
+
const l1 = await l1Fee(rpc, { ...tx, from: undefined, gasLimit, ...feeFields });
|
|
100
|
+
const fee = gasLimit * perGas;
|
|
101
|
+
const total = fee + l1;
|
|
102
|
+
const native = getNativeCurrency(chainId);
|
|
103
|
+
return {
|
|
104
|
+
type: 'evm',
|
|
105
|
+
gasLimit: gasLimit.toString(),
|
|
106
|
+
gasPrice: perGas.toString(),
|
|
107
|
+
fee: fee.toString(),
|
|
108
|
+
maxFee: (gasLimit * maxPerGas).toString(),
|
|
109
|
+
l1Fee: l1.toString(),
|
|
110
|
+
total: total.toString(),
|
|
111
|
+
totalFormatted: formatUnits(total, native?.decimals ?? 18),
|
|
112
|
+
symbol: native?.symbol ?? null,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=fees.js.map
|
package/dist/fees.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fees.js","sourceRoot":"","sources":["../src/fees.ts"],"names":[],"mappings":"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"}
|