@continuumdao/ctm-mpc-defi 0.2.0 → 0.2.1
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/README.md +20 -78
- package/dist/agent/catalog.cjs +511 -4
- package/dist/agent/catalog.cjs.map +1 -1
- package/dist/agent/catalog.d.ts +140 -20
- package/dist/agent/catalog.js +501 -6
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/skills/aave-v4/SKILL.md +43 -0
- package/dist/agent/skills/curve-dao/SKILL.md +12 -0
- package/dist/agent/skills/ethena/SKILL.md +10 -0
- package/dist/agent/skills/euler-v2/SKILL.md +10 -0
- package/dist/agent/skills/lido/SKILL.md +22 -0
- package/dist/agent/skills/maple-syrup/SKILL.md +10 -0
- package/dist/agent/skills/sky/SKILL.md +10 -0
- package/dist/agent/skills/uniswap-v4/SKILL.md +22 -0
- package/dist/chains/evm/index.cjs +27 -226
- package/dist/chains/evm/index.cjs.map +1 -1
- package/dist/chains/evm/index.d.ts +14 -26
- package/dist/chains/evm/index.js +21 -211
- package/dist/chains/evm/index.js.map +1 -1
- package/dist/chains/near/index.d.ts +1 -1
- package/dist/chains/solana/index.d.ts +1 -1
- package/dist/core/index.cjs +8 -110
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +5 -39
- package/dist/core/index.js +6 -100
- package/dist/core/index.js.map +1 -1
- package/dist/{envelope-CcE5Cz_q.d.ts → envelope-CpBUh9eP.d.ts} +1 -1
- package/dist/index.cjs +238 -1868
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +7 -11
- package/dist/index.js +227 -1839
- package/dist/index.js.map +1 -1
- package/dist/protocols/evm/aave-v4/index.cjs +385 -662
- package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/aave-v4/index.d.ts +1 -2
- package/dist/protocols/evm/aave-v4/index.js +385 -662
- package/dist/protocols/evm/aave-v4/index.js.map +1 -1
- package/dist/protocols/evm/curve-dao/index.cjs +24 -124
- package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
- package/dist/protocols/evm/curve-dao/index.d.ts +3 -4
- package/dist/protocols/evm/curve-dao/index.js +15 -115
- package/dist/protocols/evm/curve-dao/index.js.map +1 -1
- package/dist/protocols/evm/ethena/index.cjs +290 -402
- package/dist/protocols/evm/ethena/index.cjs.map +1 -1
- package/dist/protocols/evm/ethena/index.d.ts +1 -2
- package/dist/protocols/evm/ethena/index.js +291 -403
- package/dist/protocols/evm/ethena/index.js.map +1 -1
- package/dist/protocols/evm/euler-v2/index.cjs +485 -1163
- package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
- package/dist/protocols/evm/euler-v2/index.d.ts +1 -2
- package/dist/protocols/evm/euler-v2/index.js +486 -1164
- package/dist/protocols/evm/euler-v2/index.js.map +1 -1
- package/dist/protocols/evm/lido/index.cjs +241 -236
- package/dist/protocols/evm/lido/index.cjs.map +1 -1
- package/dist/protocols/evm/lido/index.d.ts +1 -2
- package/dist/protocols/evm/lido/index.js +242 -237
- package/dist/protocols/evm/lido/index.js.map +1 -1
- package/dist/protocols/evm/maple/index.cjs +310 -398
- package/dist/protocols/evm/maple/index.cjs.map +1 -1
- package/dist/protocols/evm/maple/index.d.ts +1 -2
- package/dist/protocols/evm/maple/index.js +311 -399
- package/dist/protocols/evm/maple/index.js.map +1 -1
- package/dist/protocols/evm/sky/index.cjs +238 -233
- package/dist/protocols/evm/sky/index.cjs.map +1 -1
- package/dist/protocols/evm/sky/index.d.ts +1 -2
- package/dist/protocols/evm/sky/index.js +236 -231
- package/dist/protocols/evm/sky/index.js.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.cjs +423 -658
- package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.d.ts +3 -4
- package/dist/protocols/evm/uniswap-v4/index.js +422 -657
- package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
- package/dist/{registry-oMKlO_5z.d.ts → registry-Bv5o37_w.d.ts} +1 -1
- package/dist/{types-Ce2qNHai.d.cts → types-BfjWdw1j.d.ts} +3 -1
- package/dist/{types-5u863Fd9.d.ts → types-DUeNJLr9.d.ts} +1 -1
- package/package.json +7 -6
- package/dist/agent/catalog.d.cts +0 -939
- package/dist/chains/evm/index.d.cts +0 -64
- package/dist/chains/near/index.d.cts +0 -37
- package/dist/chains/solana/index.d.cts +0 -40
- package/dist/core/index.d.cts +0 -43
- package/dist/envelope-DYDPnrHZ.d.cts +0 -35
- package/dist/index.d.cts +0 -16
- package/dist/keygen-CfNp8yKJ.d.cts +0 -9
- package/dist/keygen-DsINazx8.d.ts +0 -9
- package/dist/nodeRead-BnmSaMGO.d.cts +0 -8
- package/dist/nodeRead-BnmSaMGO.d.ts +0 -8
- package/dist/protocols/evm/aave-v4/index.d.cts +0 -500
- package/dist/protocols/evm/curve-dao/index.d.cts +0 -147
- package/dist/protocols/evm/ethena/index.d.cts +0 -161
- package/dist/protocols/evm/euler-v2/index.d.cts +0 -317
- package/dist/protocols/evm/lido/index.d.cts +0 -120
- package/dist/protocols/evm/maple/index.d.cts +0 -109
- package/dist/protocols/evm/sky/index.d.cts +0 -218
- package/dist/protocols/evm/uniswap-v4/index.d.cts +0 -324
- package/dist/registry-BwZoE668.d.cts +0 -8
- package/dist/txParams-BC7ogvdR.d.cts +0 -19
- package/dist/txParams-BC7ogvdR.d.ts +0 -19
- package/dist/types-B8idm_gu.d.cts +0 -34
- package/dist/types-Ce2qNHai.d.ts +0 -57
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var viem = require('viem');
|
|
4
|
+
var continuumNodeSdk = require('@continuumdao/continuum-node-sdk');
|
|
4
5
|
|
|
5
6
|
// src/core/registry.ts
|
|
6
7
|
var modules = [];
|
|
@@ -25,87 +26,234 @@ function isEthereumMainnetChainId(chainIdStr) {
|
|
|
25
26
|
return String(chainIdStr ?? "").trim() === String(LIDO_ETHEREUM_MAINNET_CHAIN_ID);
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
// src/core/
|
|
29
|
-
function
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
// src/core/purpose.ts
|
|
30
|
+
function mergePurposeText(purposeText, purposeSuffix) {
|
|
31
|
+
const t = purposeText.trim();
|
|
32
|
+
const suffix = (purposeSuffix ?? "").trim();
|
|
33
|
+
if (!suffix) return t;
|
|
34
|
+
return t ? `${t}
|
|
35
|
+
|
|
36
|
+
${suffix}` : suffix;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
// src/
|
|
39
|
-
function
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
// src/core/envelope.ts
|
|
40
|
+
function finalizeMultisign(input) {
|
|
41
|
+
const { keyGen, destinationChainID, legs } = input;
|
|
42
|
+
if (legs.length === 0) {
|
|
43
|
+
throw new Error("finalizeMultisign requires at least one leg");
|
|
42
44
|
}
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
+
const ph = (keyGen.pubkeyhex ?? "").trim();
|
|
46
|
+
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
47
|
+
const keyList = keyGen.keylist ?? [];
|
|
48
|
+
const clientId = continuumNodeSdk.getClientIdFromKeyGenResult(keyGen);
|
|
49
|
+
const first = legs[0];
|
|
50
|
+
const messageHashes = legs.map((l) => l.msgHash);
|
|
51
|
+
const messageRawBatch = legs.map((l) => l.msgRaw);
|
|
52
|
+
const batchMeta = legs.map((l) => ({
|
|
53
|
+
destinationAddress: l.destinationAddress,
|
|
54
|
+
signatureText: l.signatureText,
|
|
55
|
+
...l.audit
|
|
56
|
+
}));
|
|
57
|
+
const proposalTxParams = legs.map((l) => l.proposalTxParams).filter((p) => p != null && typeof p === "object");
|
|
58
|
+
const extraPayload = {
|
|
59
|
+
batchMeta,
|
|
60
|
+
...input.extraJSON ?? {}
|
|
61
|
+
};
|
|
62
|
+
const extraJSON = JSON.stringify(extraPayload);
|
|
63
|
+
const bodyForSign = {
|
|
64
|
+
keyList,
|
|
65
|
+
pubKey: ph,
|
|
66
|
+
msgHash: messageHashes[0],
|
|
67
|
+
msgRaw: first.msgRaw,
|
|
68
|
+
destinationChainID,
|
|
69
|
+
destinationAddress: input.destinationAddress ?? first.destinationAddress,
|
|
70
|
+
extraJSON,
|
|
71
|
+
signatureText: first.signatureText,
|
|
72
|
+
purpose: mergePurposeText(input.purposeText, input.purposeSuffix),
|
|
73
|
+
...first.feeSnapshot
|
|
74
|
+
};
|
|
75
|
+
if (legs.length > 1) {
|
|
76
|
+
bodyForSign.messageHashes = messageHashes;
|
|
77
|
+
bodyForSign.messageRawBatch = messageRawBatch;
|
|
78
|
+
}
|
|
79
|
+
if (proposalTxParams.length > 0) {
|
|
80
|
+
bodyForSign.proposalTxParams = proposalTxParams;
|
|
81
|
+
}
|
|
82
|
+
const valueWei = first.valueWei;
|
|
83
|
+
if (valueWei != null && valueWei > 0n) {
|
|
84
|
+
bodyForSign.value = valueWei.toString();
|
|
85
|
+
}
|
|
86
|
+
if (clientId) bodyForSign.clientId = clientId;
|
|
87
|
+
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
88
|
+
}
|
|
89
|
+
function routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimit) {
|
|
90
|
+
if (chainGasLimit != null && Number.isFinite(chainGasLimit) && chainGasLimit > 0) {
|
|
91
|
+
return continuumNodeSdk.gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit);
|
|
92
|
+
}
|
|
93
|
+
return (estimatedGas * 12n + 9n) / 10n;
|
|
45
94
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
95
|
+
|
|
96
|
+
// src/chains/evm/buildBatch.ts
|
|
97
|
+
async function buildEvmMultisignBatch(args) {
|
|
98
|
+
const { context, steps } = args;
|
|
99
|
+
const {
|
|
100
|
+
chainId,
|
|
101
|
+
rpcUrl,
|
|
102
|
+
executorAddress,
|
|
103
|
+
chainDetail,
|
|
104
|
+
useCustomGas,
|
|
105
|
+
customGasChainDetails,
|
|
106
|
+
keyGen,
|
|
107
|
+
purposeText
|
|
108
|
+
} = context;
|
|
109
|
+
if (steps.length === 0) throw new Error("buildEvmMultisignBatch requires at least one step");
|
|
110
|
+
const ch = viem.defineChain({
|
|
111
|
+
id: chainId,
|
|
112
|
+
name: "Destination",
|
|
54
113
|
nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
|
|
55
|
-
rpcUrls: { default: { http: [
|
|
114
|
+
rpcUrls: { default: { http: [rpcUrl] } }
|
|
56
115
|
});
|
|
57
|
-
const publicClient = viem.createPublicClient({
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
});
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
116
|
+
const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(rpcUrl) });
|
|
117
|
+
const feeParams = await continuumNodeSdk.fetchChainFeeParams(rpcUrl, chainId);
|
|
118
|
+
const legacy = Boolean(chainDetail?.legacy) || !feeParams.isEip1559;
|
|
119
|
+
const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
120
|
+
const gasLimitConfig = useCustomGas && chainDetail?.gasLimit != null ? Number(chainDetail.gasLimit) : void 0;
|
|
121
|
+
const chainGasLimitRouter = chainDetail?.gasLimit != null && Number.isFinite(Number(chainDetail.gasLimit)) && Number(chainDetail.gasLimit) > 0 ? Number(chainDetail.gasLimit) : void 0;
|
|
122
|
+
const gasFeeMultiplier = useCustomGas && chainDetail?.gasMultiplier != null ? Number(chainDetail.gasMultiplier) : void 0;
|
|
123
|
+
const executor = viem.getAddress(executorAddress);
|
|
124
|
+
const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: "pending" });
|
|
125
|
+
const legs = [];
|
|
126
|
+
for (let i = 0; i < steps.length; i++) {
|
|
127
|
+
const step = steps[i];
|
|
128
|
+
const currentNonce = baseNonce + i;
|
|
129
|
+
let estimatedGas;
|
|
130
|
+
if (args.estimateGasForStep) {
|
|
131
|
+
estimatedGas = await args.estimateGasForStep({ step, index: i, publicClient, executor });
|
|
132
|
+
} else {
|
|
133
|
+
try {
|
|
134
|
+
estimatedGas = await publicClient.estimateGas({
|
|
135
|
+
to: step.to,
|
|
136
|
+
data: step.data,
|
|
137
|
+
value: step.value,
|
|
138
|
+
account: executor
|
|
139
|
+
});
|
|
140
|
+
} catch {
|
|
141
|
+
estimatedGas = step.fallbackGas ?? 100000n;
|
|
142
|
+
}
|
|
71
143
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
144
|
+
let gasLimitI;
|
|
145
|
+
if (args.resolveGasLimit) {
|
|
146
|
+
gasLimitI = await args.resolveGasLimit({ step, index: i, estimatedGas, publicClient });
|
|
147
|
+
} else if (step.routerSwap) {
|
|
148
|
+
gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter);
|
|
149
|
+
} else {
|
|
150
|
+
gasLimitI = useCustomGas ? continuumNodeSdk.gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig) : estimatedGas;
|
|
78
151
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
152
|
+
let proposalTxParams;
|
|
153
|
+
let feeSnapshot;
|
|
154
|
+
let serialized;
|
|
155
|
+
if (legacy) {
|
|
156
|
+
let gasPriceWei = await publicClient.getGasPrice();
|
|
157
|
+
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
158
|
+
gasPriceWei = gasPriceWei * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
159
|
+
}
|
|
160
|
+
if (useCustomGas && chainDetail?.gasPrice != null && chainDetail.gasPrice > 0) {
|
|
161
|
+
const configured = viem.parseGwei(continuumNodeSdk.gweiToDecimalString(Number(chainDetail.gasPrice)));
|
|
162
|
+
if (configured > gasPriceWei) gasPriceWei = configured;
|
|
163
|
+
}
|
|
164
|
+
serialized = viem.serializeTransaction({
|
|
165
|
+
type: "legacy",
|
|
166
|
+
to: step.to,
|
|
167
|
+
data: step.data,
|
|
168
|
+
value: step.value,
|
|
169
|
+
gas: gasLimitI,
|
|
170
|
+
gasPrice: gasPriceWei,
|
|
171
|
+
nonce: currentNonce,
|
|
172
|
+
chainId
|
|
173
|
+
});
|
|
174
|
+
proposalTxParams = {
|
|
175
|
+
nonce: currentNonce,
|
|
176
|
+
gasLimit: gasLimitI.toString(),
|
|
177
|
+
txType: "legacy",
|
|
178
|
+
gasPrice: gasPriceWei.toString()
|
|
179
|
+
};
|
|
180
|
+
feeSnapshot = continuumNodeSdk.proposalTxParamsToFeeSnapshot(proposalTxParams);
|
|
181
|
+
} else {
|
|
182
|
+
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
183
|
+
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
184
|
+
const configuredBase = useCustomGas && chainDetail?.baseFee != null ? Number(chainDetail.baseFee) : 0;
|
|
185
|
+
const configuredPriority = useCustomGas && chainDetail?.priorityFee != null ? Number(chainDetail.priorityFee) : 0;
|
|
186
|
+
const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
|
|
187
|
+
const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
|
|
188
|
+
const baseFeeMultiplierPct = useCustomGas && chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(chainDetail.baseFeeMultiplier)) : 100;
|
|
189
|
+
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
190
|
+
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
191
|
+
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(continuumNodeSdk.gweiToDecimalString(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
192
|
+
let maxFeePerGas = viem.parseGwei(continuumNodeSdk.gweiToDecimalString(maxFeePerGasGwei));
|
|
193
|
+
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
194
|
+
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
195
|
+
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
196
|
+
}
|
|
197
|
+
({ maxFeePerGas, maxPriorityFeePerGas } = continuumNodeSdk.alignEip1559FeesWithLatestBase(
|
|
198
|
+
maxFeePerGas,
|
|
199
|
+
maxPriorityFeePerGas,
|
|
200
|
+
latestBaseFeeWei
|
|
201
|
+
));
|
|
202
|
+
serialized = viem.serializeTransaction({
|
|
203
|
+
type: "eip1559",
|
|
204
|
+
to: step.to,
|
|
205
|
+
data: step.data,
|
|
206
|
+
value: step.value,
|
|
207
|
+
gas: gasLimitI,
|
|
208
|
+
maxFeePerGas,
|
|
209
|
+
maxPriorityFeePerGas,
|
|
210
|
+
nonce: currentNonce,
|
|
211
|
+
chainId
|
|
212
|
+
});
|
|
213
|
+
proposalTxParams = {
|
|
214
|
+
nonce: currentNonce,
|
|
215
|
+
gasLimit: gasLimitI.toString(),
|
|
216
|
+
txType: "eip1559",
|
|
217
|
+
maxFeePerGas: maxFeePerGas.toString(),
|
|
218
|
+
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
219
|
+
};
|
|
220
|
+
feeSnapshot = i === 0 ? continuumNodeSdk.proposalTxParamsToFeeSnapshot(proposalTxParams) : {};
|
|
221
|
+
}
|
|
222
|
+
const h = viem.keccak256(serialized);
|
|
223
|
+
const msgHash = h.startsWith("0x") ? h.slice(2) : h;
|
|
224
|
+
const batchMetaExtra = args.buildBatchMeta({ step, index: i, gasLimit: gasLimitI });
|
|
225
|
+
legs.push({
|
|
226
|
+
msgHash,
|
|
227
|
+
msgRaw: i === 0 && args.firstMsgRawNo0x != null ? args.firstMsgRawNo0x : serialized,
|
|
228
|
+
destinationAddress: step.to,
|
|
229
|
+
signatureText: typeof batchMetaExtra.signatureText === "string" ? batchMetaExtra.signatureText : JSON.stringify(batchMetaExtra.signatureText ?? {}),
|
|
230
|
+
audit: batchMetaExtra,
|
|
231
|
+
feeSnapshot: i === 0 ? feeSnapshot : {},
|
|
232
|
+
proposalTxParams,
|
|
233
|
+
valueWei: i === 0 ? step.value : void 0
|
|
234
|
+
});
|
|
235
|
+
if (i === 0 && args.firstMsgRawNo0x != null) {
|
|
236
|
+
legs[0].msgRaw = args.firstMsgRawNo0x;
|
|
93
237
|
}
|
|
94
238
|
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
let maxF = maxFeePerGas;
|
|
99
|
-
if (baseWei > 0n && maxF < baseWei + maxP) {
|
|
100
|
-
maxF = baseWei + maxP + viem.parseGwei("0.001");
|
|
239
|
+
const extraJSON = {};
|
|
240
|
+
if (useCustomGas && customGasChainDetails && Object.keys(customGasChainDetails).length > 0) {
|
|
241
|
+
extraJSON.customGasChainDetails = customGasChainDetails;
|
|
101
242
|
}
|
|
102
|
-
|
|
103
|
-
|
|
243
|
+
const result = finalizeMultisign({
|
|
244
|
+
keyGen,
|
|
245
|
+
purposeText,
|
|
246
|
+
purposeSuffix: args.purposeSuffix,
|
|
247
|
+
destinationChainID: String(chainId),
|
|
248
|
+
destinationAddress: args.destinationAddress ?? steps[0].to,
|
|
249
|
+
legs,
|
|
250
|
+
extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : void 0
|
|
251
|
+
});
|
|
252
|
+
const pv = args.payableValueWei;
|
|
253
|
+
if (pv != null && pv > 0n) {
|
|
254
|
+
result.bodyForSign.value = pv.toString();
|
|
104
255
|
}
|
|
105
|
-
return
|
|
106
|
-
}
|
|
107
|
-
function alignEip1559FeesWithLatestBase(maxFeePerGas, maxPriorityFeePerGas, latestBlockBaseFeeWei) {
|
|
108
|
-
return finalizeEip1559Fees(maxFeePerGas, maxPriorityFeePerGas, null, latestBlockBaseFeeWei);
|
|
256
|
+
return result;
|
|
109
257
|
}
|
|
110
258
|
|
|
111
259
|
// src/protocols/evm/lido/multisign.ts
|
|
@@ -134,13 +282,6 @@ var wstethAbi = viem.parseAbi([
|
|
|
134
282
|
"function wrap(uint256 stETHAmount) returns (uint256)",
|
|
135
283
|
"function unwrap(uint256 wstETHAmount) returns (uint256)"
|
|
136
284
|
]);
|
|
137
|
-
function gweiToDecimalString(n) {
|
|
138
|
-
if (!Number.isFinite(n)) return "0";
|
|
139
|
-
if (n === 0) return "0";
|
|
140
|
-
const s = String(n);
|
|
141
|
-
if (s.indexOf("e") !== -1 || s.indexOf("E") !== -1) return n.toFixed(9).replace(/\.?0+$/, "") || "0";
|
|
142
|
-
return s;
|
|
143
|
-
}
|
|
144
285
|
function parseExtraJsonObject(detail) {
|
|
145
286
|
const raw = detail?.ExtraJSON ?? detail?.extraJSON;
|
|
146
287
|
if (raw == null) return null;
|
|
@@ -228,167 +369,31 @@ function resolveLidoBatchStepGasFromSignRequest(detail, batchIndex) {
|
|
|
228
369
|
return null;
|
|
229
370
|
}
|
|
230
371
|
async function finalizeLidoMultipart(steps, args) {
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
let firstTxFeePayload = {};
|
|
254
|
-
let firstDataNo0x = "";
|
|
255
|
-
const batchMeta = [];
|
|
256
|
-
for (let i = 0; i < steps.length; i++) {
|
|
257
|
-
const s = steps[i];
|
|
258
|
-
const v = viem.getAddress(s.to);
|
|
259
|
-
const data = s.data;
|
|
260
|
-
const currentNonce = baseNonce + i;
|
|
261
|
-
let estimatedGas;
|
|
262
|
-
try {
|
|
263
|
-
estimatedGas = await publicClient.estimateGas({
|
|
264
|
-
to: v,
|
|
265
|
-
data,
|
|
266
|
-
value: s.value,
|
|
267
|
-
account: executor
|
|
268
|
-
});
|
|
269
|
-
} catch {
|
|
270
|
-
estimatedGas = s.fallbackGas;
|
|
271
|
-
}
|
|
272
|
-
const gasLimitI = useCustomGas ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig) : estimatedGas;
|
|
273
|
-
if (legacy) {
|
|
274
|
-
let gasPriceWei = await publicClient.getGasPrice();
|
|
275
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
276
|
-
gasPriceWei = gasPriceWei * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
277
|
-
}
|
|
278
|
-
if (useCustomGas && args.chainDetail?.gasPrice != null && args.chainDetail.gasPrice > 0) {
|
|
279
|
-
const configured = viem.parseGwei(gweiToDecimalString(Number(args.chainDetail.gasPrice)));
|
|
280
|
-
if (configured > gasPriceWei) gasPriceWei = configured;
|
|
281
|
-
}
|
|
282
|
-
const ser = viem.serializeTransaction({
|
|
283
|
-
type: "legacy",
|
|
284
|
-
to: v,
|
|
285
|
-
data,
|
|
286
|
-
value: s.value,
|
|
287
|
-
gas: gasLimitI,
|
|
288
|
-
gasPrice: gasPriceWei,
|
|
289
|
-
nonce: currentNonce,
|
|
290
|
-
chainId: LIDO_ETHEREUM_MAINNET_CHAIN_ID
|
|
291
|
-
});
|
|
292
|
-
const h = viem.keccak256(ser);
|
|
293
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
294
|
-
messageRawBatch.push(ser);
|
|
295
|
-
proposalTxParamsBatch.push({
|
|
296
|
-
nonce: currentNonce,
|
|
297
|
-
gasLimit: gasLimitI.toString(),
|
|
298
|
-
txType: "legacy",
|
|
299
|
-
gasPrice: gasPriceWei.toString()
|
|
300
|
-
});
|
|
301
|
-
if (i === 0) {
|
|
302
|
-
firstTxFeePayload = { txNonce: currentNonce, txGasLimit: gasLimitI.toString(), txGasPrice: gasPriceWei.toString() };
|
|
303
|
-
firstDataNo0x = data.startsWith("0x") ? data.slice(2) : data;
|
|
304
|
-
}
|
|
305
|
-
} else {
|
|
306
|
-
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
307
|
-
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
308
|
-
const configuredBase = useCustomGas && args.chainDetail?.baseFee != null ? Number(args.chainDetail.baseFee) : 0;
|
|
309
|
-
const configuredPriority = useCustomGas && args.chainDetail?.priorityFee != null ? Number(args.chainDetail.priorityFee) : 0;
|
|
310
|
-
const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
|
|
311
|
-
const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
|
|
312
|
-
const baseFeeMultiplierPct = useCustomGas && args.chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(args.chainDetail.baseFeeMultiplier)) : 100;
|
|
313
|
-
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
314
|
-
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
315
|
-
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(gweiToDecimalString(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
316
|
-
let maxFeePerGas = viem.parseGwei(gweiToDecimalString(maxFeePerGasGwei));
|
|
317
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
318
|
-
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
319
|
-
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
320
|
-
}
|
|
321
|
-
({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(
|
|
322
|
-
maxFeePerGas,
|
|
323
|
-
maxPriorityFeePerGas,
|
|
324
|
-
latestBaseFeeWei
|
|
325
|
-
));
|
|
326
|
-
const ser = viem.serializeTransaction({
|
|
327
|
-
type: "eip1559",
|
|
328
|
-
to: v,
|
|
329
|
-
data,
|
|
330
|
-
value: s.value,
|
|
331
|
-
gas: gasLimitI,
|
|
332
|
-
maxFeePerGas,
|
|
333
|
-
maxPriorityFeePerGas,
|
|
334
|
-
nonce: currentNonce,
|
|
335
|
-
chainId: LIDO_ETHEREUM_MAINNET_CHAIN_ID
|
|
336
|
-
});
|
|
337
|
-
const h = viem.keccak256(ser);
|
|
338
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
339
|
-
messageRawBatch.push(ser);
|
|
340
|
-
proposalTxParamsBatch.push({
|
|
341
|
-
nonce: currentNonce,
|
|
342
|
-
gasLimit: gasLimitI.toString(),
|
|
343
|
-
txType: "eip1559",
|
|
344
|
-
maxFeePerGas: maxFeePerGas.toString(),
|
|
345
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
346
|
-
});
|
|
347
|
-
if (i === 0) {
|
|
348
|
-
firstTxFeePayload = {
|
|
349
|
-
txNonce: currentNonce,
|
|
350
|
-
txGasLimit: gasLimitI.toString(),
|
|
351
|
-
txMaxFeePerGas: maxFeePerGas.toString(),
|
|
352
|
-
txMaxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
353
|
-
};
|
|
354
|
-
firstDataNo0x = data.startsWith("0x") ? data.slice(2) : data;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
batchMeta.push(s.buildBatchMeta({ gasLimit: gasLimitI }));
|
|
358
|
-
}
|
|
359
|
-
const extraPayload = { batchMeta };
|
|
360
|
-
if (useCustomGas && args.customGasChainDetails && Object.keys(args.customGasChainDetails).length > 0) {
|
|
361
|
-
extraPayload.customGasChainDetails = args.customGasChainDetails;
|
|
362
|
-
}
|
|
363
|
-
const extraJSON = JSON.stringify(extraPayload);
|
|
364
|
-
const firstSigText = batchMeta[0].signatureText;
|
|
365
|
-
const firstValue = steps[0].value;
|
|
366
|
-
const bodyForSign = {
|
|
367
|
-
keyList,
|
|
368
|
-
pubKey: ph,
|
|
369
|
-
msgHash: messageHashes[0],
|
|
370
|
-
msgRaw: firstDataNo0x,
|
|
371
|
-
messageHashes,
|
|
372
|
-
messageRawBatch,
|
|
373
|
-
destinationChainID: String(LIDO_ETHEREUM_MAINNET_CHAIN_ID),
|
|
372
|
+
const evmSteps = steps.map((s) => ({
|
|
373
|
+
to: s.to,
|
|
374
|
+
data: s.data,
|
|
375
|
+
value: s.value,
|
|
376
|
+
fallbackGas: s.fallbackGas
|
|
377
|
+
}));
|
|
378
|
+
const firstDataNo0x = evmSteps[0].data.startsWith("0x") ? evmSteps[0].data.slice(2) : evmSteps[0].data;
|
|
379
|
+
return buildEvmMultisignBatch({
|
|
380
|
+
context: {
|
|
381
|
+
chainCategory: "evm",
|
|
382
|
+
keyGen: args.keyGen,
|
|
383
|
+
purposeText: args.purposeText,
|
|
384
|
+
chainId: LIDO_ETHEREUM_MAINNET_CHAIN_ID,
|
|
385
|
+
rpcUrl: args.rpcUrl.trim(),
|
|
386
|
+
executorAddress: args.executorAddress,
|
|
387
|
+
chainDetail: args.chainDetail,
|
|
388
|
+
useCustomGas: args.useCustomGas,
|
|
389
|
+
customGasChainDetails: args.customGasChainDetails
|
|
390
|
+
},
|
|
391
|
+
steps: evmSteps,
|
|
392
|
+
purposeSuffix: args.purposeSuffix,
|
|
393
|
+
firstMsgRawNo0x: firstDataNo0x,
|
|
374
394
|
destinationAddress: steps[0].to,
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
purpose: (() => {
|
|
378
|
-
const t = args.purposeText.trim();
|
|
379
|
-
const suffix = args.purposeSuffix.trim();
|
|
380
|
-
return (t ? `${t}
|
|
381
|
-
|
|
382
|
-
` : "") + suffix;
|
|
383
|
-
})(),
|
|
384
|
-
...firstTxFeePayload,
|
|
385
|
-
proposalTxParams: proposalTxParamsBatch
|
|
386
|
-
};
|
|
387
|
-
if (firstValue > 0n) {
|
|
388
|
-
bodyForSign.value = firstValue.toString();
|
|
389
|
-
}
|
|
390
|
-
if (clientId) bodyForSign.clientId = clientId;
|
|
391
|
-
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
395
|
+
buildBatchMeta: ({ index, gasLimit }) => steps[index].buildBatchMeta({ gasLimit })
|
|
396
|
+
});
|
|
392
397
|
}
|
|
393
398
|
async function buildEvmMultisignBodyLidoSubmit(args) {
|
|
394
399
|
if (args.chainId !== LIDO_ETHEREUM_MAINNET_CHAIN_ID) {
|