@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 = [];
|
|
@@ -144,101 +145,239 @@ function isEvmChainInEthenaUsdeList(chainId) {
|
|
|
144
145
|
return usdeTokenAddressOnEvmChain(chainId) != null;
|
|
145
146
|
}
|
|
146
147
|
|
|
147
|
-
// src/core/
|
|
148
|
-
function
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
148
|
+
// src/core/purpose.ts
|
|
149
|
+
function mergePurposeText(purposeText, purposeSuffix) {
|
|
150
|
+
const t = purposeText.trim();
|
|
151
|
+
const suffix = (purposeSuffix ?? "").trim();
|
|
152
|
+
if (!suffix) return t;
|
|
153
|
+
return t ? `${t}
|
|
154
|
+
|
|
155
|
+
${suffix}` : suffix;
|
|
155
156
|
}
|
|
156
157
|
|
|
157
|
-
// src/
|
|
158
|
-
function
|
|
159
|
-
|
|
160
|
-
|
|
158
|
+
// src/core/envelope.ts
|
|
159
|
+
function finalizeMultisign(input) {
|
|
160
|
+
const { keyGen, destinationChainID, legs } = input;
|
|
161
|
+
if (legs.length === 0) {
|
|
162
|
+
throw new Error("finalizeMultisign requires at least one leg");
|
|
163
|
+
}
|
|
164
|
+
const ph = (keyGen.pubkeyhex ?? "").trim();
|
|
165
|
+
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
166
|
+
const keyList = keyGen.keylist ?? [];
|
|
167
|
+
const clientId = continuumNodeSdk.getClientIdFromKeyGenResult(keyGen);
|
|
168
|
+
const first = legs[0];
|
|
169
|
+
const messageHashes = legs.map((l) => l.msgHash);
|
|
170
|
+
const messageRawBatch = legs.map((l) => l.msgRaw);
|
|
171
|
+
const batchMeta = legs.map((l) => ({
|
|
172
|
+
destinationAddress: l.destinationAddress,
|
|
173
|
+
signatureText: l.signatureText,
|
|
174
|
+
...l.audit
|
|
175
|
+
}));
|
|
176
|
+
const proposalTxParams = legs.map((l) => l.proposalTxParams).filter((p) => p != null && typeof p === "object");
|
|
177
|
+
const extraPayload = {
|
|
178
|
+
batchMeta,
|
|
179
|
+
...input.extraJSON ?? {}
|
|
180
|
+
};
|
|
181
|
+
const extraJSON = JSON.stringify(extraPayload);
|
|
182
|
+
const bodyForSign = {
|
|
183
|
+
keyList,
|
|
184
|
+
pubKey: ph,
|
|
185
|
+
msgHash: messageHashes[0],
|
|
186
|
+
msgRaw: first.msgRaw,
|
|
187
|
+
destinationChainID,
|
|
188
|
+
destinationAddress: input.destinationAddress ?? first.destinationAddress,
|
|
189
|
+
extraJSON,
|
|
190
|
+
signatureText: first.signatureText,
|
|
191
|
+
purpose: mergePurposeText(input.purposeText, input.purposeSuffix),
|
|
192
|
+
...first.feeSnapshot
|
|
193
|
+
};
|
|
194
|
+
if (legs.length > 1) {
|
|
195
|
+
bodyForSign.messageHashes = messageHashes;
|
|
196
|
+
bodyForSign.messageRawBatch = messageRawBatch;
|
|
197
|
+
}
|
|
198
|
+
if (proposalTxParams.length > 0) {
|
|
199
|
+
bodyForSign.proposalTxParams = proposalTxParams;
|
|
200
|
+
}
|
|
201
|
+
const valueWei = first.valueWei;
|
|
202
|
+
if (valueWei != null && valueWei > 0n) {
|
|
203
|
+
bodyForSign.value = valueWei.toString();
|
|
204
|
+
}
|
|
205
|
+
if (clientId) bodyForSign.clientId = clientId;
|
|
206
|
+
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
207
|
+
}
|
|
208
|
+
function routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimit) {
|
|
209
|
+
if (chainGasLimit != null && Number.isFinite(chainGasLimit) && chainGasLimit > 0) {
|
|
210
|
+
return continuumNodeSdk.gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit);
|
|
161
211
|
}
|
|
162
|
-
|
|
163
|
-
return cfg > estimatedGas ? cfg : estimatedGas;
|
|
212
|
+
return (estimatedGas * 12n + 9n) / 10n;
|
|
164
213
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
214
|
+
|
|
215
|
+
// src/chains/evm/buildBatch.ts
|
|
216
|
+
async function buildEvmMultisignBatch(args) {
|
|
217
|
+
const { context, steps } = args;
|
|
218
|
+
const {
|
|
219
|
+
chainId,
|
|
220
|
+
rpcUrl,
|
|
221
|
+
executorAddress,
|
|
222
|
+
chainDetail,
|
|
223
|
+
useCustomGas,
|
|
224
|
+
customGasChainDetails,
|
|
225
|
+
keyGen,
|
|
226
|
+
purposeText
|
|
227
|
+
} = context;
|
|
228
|
+
if (steps.length === 0) throw new Error("buildEvmMultisignBatch requires at least one step");
|
|
229
|
+
const ch = viem.defineChain({
|
|
230
|
+
id: chainId,
|
|
231
|
+
name: "Destination",
|
|
173
232
|
nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
|
|
174
|
-
rpcUrls: { default: { http: [
|
|
175
|
-
});
|
|
176
|
-
const publicClient = viem.createPublicClient({
|
|
177
|
-
chain,
|
|
178
|
-
transport: viem.http(url)
|
|
233
|
+
rpcUrls: { default: { http: [rpcUrl] } }
|
|
179
234
|
});
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
235
|
+
const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(rpcUrl) });
|
|
236
|
+
const feeParams = await continuumNodeSdk.fetchChainFeeParams(rpcUrl, chainId);
|
|
237
|
+
const legacy = Boolean(chainDetail?.legacy) || !feeParams.isEip1559;
|
|
238
|
+
const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
239
|
+
const gasLimitConfig = useCustomGas && chainDetail?.gasLimit != null ? Number(chainDetail.gasLimit) : void 0;
|
|
240
|
+
const chainGasLimitRouter = chainDetail?.gasLimit != null && Number.isFinite(Number(chainDetail.gasLimit)) && Number(chainDetail.gasLimit) > 0 ? Number(chainDetail.gasLimit) : void 0;
|
|
241
|
+
const gasFeeMultiplier = useCustomGas && chainDetail?.gasMultiplier != null ? Number(chainDetail.gasMultiplier) : void 0;
|
|
242
|
+
const executor = viem.getAddress(executorAddress);
|
|
243
|
+
const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: "pending" });
|
|
244
|
+
const legs = [];
|
|
245
|
+
for (let i = 0; i < steps.length; i++) {
|
|
246
|
+
const step = steps[i];
|
|
247
|
+
const currentNonce = baseNonce + i;
|
|
248
|
+
let estimatedGas;
|
|
249
|
+
if (args.estimateGasForStep) {
|
|
250
|
+
estimatedGas = await args.estimateGasForStep({ step, index: i, publicClient, executor });
|
|
251
|
+
} else {
|
|
252
|
+
try {
|
|
253
|
+
estimatedGas = await publicClient.estimateGas({
|
|
254
|
+
to: step.to,
|
|
255
|
+
data: step.data,
|
|
256
|
+
value: step.value,
|
|
257
|
+
account: executor
|
|
258
|
+
});
|
|
259
|
+
} catch {
|
|
260
|
+
estimatedGas = step.fallbackGas ?? 100000n;
|
|
261
|
+
}
|
|
190
262
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
263
|
+
let gasLimitI;
|
|
264
|
+
if (args.resolveGasLimit) {
|
|
265
|
+
gasLimitI = await args.resolveGasLimit({ step, index: i, estimatedGas, publicClient });
|
|
266
|
+
} else if (step.routerSwap) {
|
|
267
|
+
gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter);
|
|
268
|
+
} else {
|
|
269
|
+
gasLimitI = useCustomGas ? continuumNodeSdk.gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig) : estimatedGas;
|
|
197
270
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
271
|
+
let proposalTxParams;
|
|
272
|
+
let feeSnapshot;
|
|
273
|
+
let serialized;
|
|
274
|
+
if (legacy) {
|
|
275
|
+
let gasPriceWei = await publicClient.getGasPrice();
|
|
276
|
+
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
277
|
+
gasPriceWei = gasPriceWei * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
278
|
+
}
|
|
279
|
+
if (useCustomGas && chainDetail?.gasPrice != null && chainDetail.gasPrice > 0) {
|
|
280
|
+
const configured = viem.parseGwei(continuumNodeSdk.gweiToDecimalString(Number(chainDetail.gasPrice)));
|
|
281
|
+
if (configured > gasPriceWei) gasPriceWei = configured;
|
|
282
|
+
}
|
|
283
|
+
serialized = viem.serializeTransaction({
|
|
284
|
+
type: "legacy",
|
|
285
|
+
to: step.to,
|
|
286
|
+
data: step.data,
|
|
287
|
+
value: step.value,
|
|
288
|
+
gas: gasLimitI,
|
|
289
|
+
gasPrice: gasPriceWei,
|
|
290
|
+
nonce: currentNonce,
|
|
291
|
+
chainId
|
|
292
|
+
});
|
|
293
|
+
proposalTxParams = {
|
|
294
|
+
nonce: currentNonce,
|
|
295
|
+
gasLimit: gasLimitI.toString(),
|
|
296
|
+
txType: "legacy",
|
|
297
|
+
gasPrice: gasPriceWei.toString()
|
|
298
|
+
};
|
|
299
|
+
feeSnapshot = continuumNodeSdk.proposalTxParamsToFeeSnapshot(proposalTxParams);
|
|
300
|
+
} else {
|
|
301
|
+
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
302
|
+
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
303
|
+
const configuredBase = useCustomGas && chainDetail?.baseFee != null ? Number(chainDetail.baseFee) : 0;
|
|
304
|
+
const configuredPriority = useCustomGas && chainDetail?.priorityFee != null ? Number(chainDetail.priorityFee) : 0;
|
|
305
|
+
const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
|
|
306
|
+
const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
|
|
307
|
+
const baseFeeMultiplierPct = useCustomGas && chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(chainDetail.baseFeeMultiplier)) : 100;
|
|
308
|
+
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
309
|
+
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
310
|
+
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(continuumNodeSdk.gweiToDecimalString(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
311
|
+
let maxFeePerGas = viem.parseGwei(continuumNodeSdk.gweiToDecimalString(maxFeePerGasGwei));
|
|
312
|
+
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
313
|
+
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
314
|
+
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
315
|
+
}
|
|
316
|
+
({ maxFeePerGas, maxPriorityFeePerGas } = continuumNodeSdk.alignEip1559FeesWithLatestBase(
|
|
317
|
+
maxFeePerGas,
|
|
318
|
+
maxPriorityFeePerGas,
|
|
319
|
+
latestBaseFeeWei
|
|
320
|
+
));
|
|
321
|
+
serialized = viem.serializeTransaction({
|
|
322
|
+
type: "eip1559",
|
|
323
|
+
to: step.to,
|
|
324
|
+
data: step.data,
|
|
325
|
+
value: step.value,
|
|
326
|
+
gas: gasLimitI,
|
|
327
|
+
maxFeePerGas,
|
|
328
|
+
maxPriorityFeePerGas,
|
|
329
|
+
nonce: currentNonce,
|
|
330
|
+
chainId
|
|
331
|
+
});
|
|
332
|
+
proposalTxParams = {
|
|
333
|
+
nonce: currentNonce,
|
|
334
|
+
gasLimit: gasLimitI.toString(),
|
|
335
|
+
txType: "eip1559",
|
|
336
|
+
maxFeePerGas: maxFeePerGas.toString(),
|
|
337
|
+
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
338
|
+
};
|
|
339
|
+
feeSnapshot = i === 0 ? continuumNodeSdk.proposalTxParamsToFeeSnapshot(proposalTxParams) : {};
|
|
340
|
+
}
|
|
341
|
+
const h = viem.keccak256(serialized);
|
|
342
|
+
const msgHash = h.startsWith("0x") ? h.slice(2) : h;
|
|
343
|
+
const batchMetaExtra = args.buildBatchMeta({ step, index: i, gasLimit: gasLimitI });
|
|
344
|
+
legs.push({
|
|
345
|
+
msgHash,
|
|
346
|
+
msgRaw: i === 0 && args.firstMsgRawNo0x != null ? args.firstMsgRawNo0x : serialized,
|
|
347
|
+
destinationAddress: step.to,
|
|
348
|
+
signatureText: typeof batchMetaExtra.signatureText === "string" ? batchMetaExtra.signatureText : JSON.stringify(batchMetaExtra.signatureText ?? {}),
|
|
349
|
+
audit: batchMetaExtra,
|
|
350
|
+
feeSnapshot: i === 0 ? feeSnapshot : {},
|
|
351
|
+
proposalTxParams,
|
|
352
|
+
valueWei: i === 0 ? step.value : void 0
|
|
353
|
+
});
|
|
354
|
+
if (i === 0 && args.firstMsgRawNo0x != null) {
|
|
355
|
+
legs[0].msgRaw = args.firstMsgRawNo0x;
|
|
212
356
|
}
|
|
213
357
|
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
358
|
+
const extraJSON = {};
|
|
359
|
+
if (useCustomGas && customGasChainDetails && Object.keys(customGasChainDetails).length > 0) {
|
|
360
|
+
extraJSON.customGasChainDetails = customGasChainDetails;
|
|
361
|
+
}
|
|
362
|
+
const result = finalizeMultisign({
|
|
363
|
+
keyGen,
|
|
364
|
+
purposeText,
|
|
365
|
+
purposeSuffix: args.purposeSuffix,
|
|
366
|
+
destinationChainID: String(chainId),
|
|
367
|
+
destinationAddress: args.destinationAddress ?? steps[0].to,
|
|
368
|
+
legs,
|
|
369
|
+
extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : void 0
|
|
370
|
+
});
|
|
371
|
+
const pv = args.payableValueWei;
|
|
372
|
+
if (pv != null && pv > 0n) {
|
|
373
|
+
result.bodyForSign.value = pv.toString();
|
|
223
374
|
}
|
|
224
|
-
return
|
|
225
|
-
}
|
|
226
|
-
function alignEip1559FeesWithLatestBase(maxFeePerGas, maxPriorityFeePerGas, latestBlockBaseFeeWei) {
|
|
227
|
-
return finalizeEip1559Fees(maxFeePerGas, maxPriorityFeePerGas, null, latestBlockBaseFeeWei);
|
|
375
|
+
return result;
|
|
228
376
|
}
|
|
229
|
-
|
|
230
|
-
// src/protocols/evm/ethena/multisign.ts
|
|
231
377
|
var AAVE_ERC20_APPROVE_FALLBACK = 100000n;
|
|
232
378
|
var ETHENA_SUSDE_DEPOSIT_GET_SIG_GAS_FALLBACK = 1200000n;
|
|
233
379
|
var ETHENA_SUSDE_DEPOSIT_FALLBACK = ETHENA_SUSDE_DEPOSIT_GET_SIG_GAS_FALLBACK;
|
|
234
380
|
var ETHENA_SUSDE_REDEEM_FALLBACK = 1200000n;
|
|
235
|
-
function gweiToDecimalString(n) {
|
|
236
|
-
if (!Number.isFinite(n)) return "0";
|
|
237
|
-
if (n === 0) return "0";
|
|
238
|
-
const s = String(n);
|
|
239
|
-
if (s.indexOf("e") !== -1 || s.indexOf("E") !== -1) return n.toFixed(9).replace(/\.?0+$/, "") || "0";
|
|
240
|
-
return s;
|
|
241
|
-
}
|
|
242
381
|
var erc20AllowanceAbi = viem.parseAbi([
|
|
243
382
|
"function allowance(address owner, address spender) view returns (uint256)",
|
|
244
383
|
"function decimals() view returns (uint8)"
|
|
@@ -295,10 +434,6 @@ async function buildEvmMultisignBodyEthenaUsdeStakeToSusde(args) {
|
|
|
295
434
|
if (args.chainId !== 1) {
|
|
296
435
|
throw new Error("Ethena USDe \u2192 sUSDe stake is only supported on Ethereum mainnet (chain id 1).");
|
|
297
436
|
}
|
|
298
|
-
const ph = (args.keyGen.pubkeyhex ?? "").trim();
|
|
299
|
-
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
300
|
-
const keyList = args.keyGen.keylist ?? [];
|
|
301
|
-
const clientId = firstClientIdFromKeyGen(args.keyGen);
|
|
302
437
|
const usde = viem.getAddress(args.usde);
|
|
303
438
|
const mainnetUsde = viem.getAddress(USDE_ETHEREUM_MAINNET);
|
|
304
439
|
if (usde.toLowerCase() !== mainnetUsde.toLowerCase()) {
|
|
@@ -353,141 +488,58 @@ async function buildEvmMultisignBodyEthenaUsdeStakeToSusde(args) {
|
|
|
353
488
|
args: [amountWei, receiver]
|
|
354
489
|
});
|
|
355
490
|
steps.push({ kind: "deposit", to: susde, data: depositData, value: 0n });
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
const
|
|
363
|
-
const
|
|
364
|
-
const
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
}
|
|
388
|
-
const gasLimitI = useCustomGas ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig) : estimatedGas;
|
|
389
|
-
if (legacy) {
|
|
390
|
-
let gasPriceWei = await publicClient.getGasPrice();
|
|
391
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
392
|
-
gasPriceWei = gasPriceWei * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
393
|
-
}
|
|
394
|
-
if (useCustomGas && args.chainDetail?.gasPrice != null && args.chainDetail.gasPrice > 0) {
|
|
395
|
-
const configured = viem.parseGwei(gweiToDecimalString(Number(args.chainDetail.gasPrice)));
|
|
396
|
-
if (configured > gasPriceWei) gasPriceWei = configured;
|
|
397
|
-
}
|
|
398
|
-
const ser = viem.serializeTransaction({
|
|
399
|
-
type: "legacy",
|
|
400
|
-
to: s.to,
|
|
401
|
-
data: s.data,
|
|
402
|
-
value: s.value,
|
|
403
|
-
gas: gasLimitI,
|
|
404
|
-
gasPrice: gasPriceWei,
|
|
405
|
-
nonce: currentNonce,
|
|
406
|
-
chainId: 1
|
|
407
|
-
});
|
|
408
|
-
const h = viem.keccak256(ser);
|
|
409
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
410
|
-
messageRawBatch.push(ser);
|
|
411
|
-
proposalTxParamsBatch.push({
|
|
412
|
-
nonce: currentNonce,
|
|
413
|
-
gasLimit: gasLimitI.toString(),
|
|
414
|
-
txType: "legacy",
|
|
415
|
-
gasPrice: gasPriceWei.toString()
|
|
416
|
-
});
|
|
417
|
-
if (i === 0) {
|
|
418
|
-
firstTxFeePayload = { txNonce: currentNonce, txGasLimit: gasLimitI.toString(), txGasPrice: gasPriceWei.toString() };
|
|
419
|
-
firstDataNo0x = s.data.startsWith("0x") ? s.data.slice(2) : s.data;
|
|
420
|
-
}
|
|
421
|
-
} else {
|
|
422
|
-
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
423
|
-
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
424
|
-
const configuredBase = useCustomGas && args.chainDetail?.baseFee != null ? Number(args.chainDetail.baseFee) : 0;
|
|
425
|
-
const configuredPriority = useCustomGas && args.chainDetail?.priorityFee != null ? Number(args.chainDetail.priorityFee) : 0;
|
|
426
|
-
const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
|
|
427
|
-
const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
|
|
428
|
-
const baseFeeMultiplierPct = useCustomGas && args.chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(args.chainDetail.baseFeeMultiplier)) : 100;
|
|
429
|
-
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
430
|
-
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
431
|
-
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(gweiToDecimalString(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
432
|
-
let maxFeePerGas = viem.parseGwei(gweiToDecimalString(maxFeePerGasGwei));
|
|
433
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
434
|
-
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
435
|
-
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
491
|
+
const evmSteps = steps.map((s) => ({
|
|
492
|
+
to: s.to,
|
|
493
|
+
data: s.data,
|
|
494
|
+
value: s.value,
|
|
495
|
+
fallbackGas: s.kind === "approve" ? AAVE_ERC20_APPROVE_FALLBACK : ETHENA_SUSDE_DEPOSIT_FALLBACK
|
|
496
|
+
}));
|
|
497
|
+
const n = steps.length;
|
|
498
|
+
const purposeSuffix = n === 1 ? "Ethena: 1-tx \u2014 deposit USDe to sUSDe (allowance already set)." : `Ethena: ${n}-tx batch \u2014 approve USDe to sUSDe vault, then deposit.`;
|
|
499
|
+
const firstDataNo0x = evmSteps[0].data.startsWith("0x") ? evmSteps[0].data.slice(2) : evmSteps[0].data;
|
|
500
|
+
const gasLimitConfig = args.useCustomGas && args.chainDetail?.gasLimit != null ? Number(args.chainDetail.gasLimit) : void 0;
|
|
501
|
+
return buildEvmMultisignBatch({
|
|
502
|
+
context: {
|
|
503
|
+
chainCategory: "evm",
|
|
504
|
+
keyGen: args.keyGen,
|
|
505
|
+
purposeText: args.purposeText,
|
|
506
|
+
chainId: 1,
|
|
507
|
+
rpcUrl: args.rpcUrl.trim(),
|
|
508
|
+
executorAddress: executor,
|
|
509
|
+
chainDetail: args.chainDetail,
|
|
510
|
+
useCustomGas: args.useCustomGas,
|
|
511
|
+
customGasChainDetails: args.customGasChainDetails
|
|
512
|
+
},
|
|
513
|
+
steps: evmSteps,
|
|
514
|
+
purposeSuffix,
|
|
515
|
+
firstMsgRawNo0x: firstDataNo0x,
|
|
516
|
+
destinationAddress: steps[0].to,
|
|
517
|
+
resolveGasLimit: ({ index, estimatedGas }) => {
|
|
518
|
+
const s = steps[index];
|
|
519
|
+
if (s.kind === "deposit" && index > 0) {
|
|
520
|
+
const gas = ETHENA_SUSDE_DEPOSIT_FALLBACK;
|
|
521
|
+
return args.useCustomGas ? continuumNodeSdk.gasLimitFromEstimateAndChainConfig(gas, gasLimitConfig) : gas;
|
|
436
522
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
)
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
455
|
-
messageRawBatch.push(ser);
|
|
456
|
-
proposalTxParamsBatch.push({
|
|
457
|
-
nonce: currentNonce,
|
|
458
|
-
gasLimit: gasLimitI.toString(),
|
|
459
|
-
txType: "eip1559",
|
|
460
|
-
maxFeePerGas: maxFeePerGas.toString(),
|
|
461
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
462
|
-
});
|
|
463
|
-
if (i === 0) {
|
|
464
|
-
firstTxFeePayload = {
|
|
465
|
-
txNonce: currentNonce,
|
|
466
|
-
txGasLimit: gasLimitI.toString(),
|
|
467
|
-
txMaxFeePerGas: maxFeePerGas.toString(),
|
|
468
|
-
txMaxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
523
|
+
return estimatedGas;
|
|
524
|
+
},
|
|
525
|
+
buildBatchMeta: ({ index, gasLimit }) => {
|
|
526
|
+
const s = steps[index];
|
|
527
|
+
if (s.kind === "approve") {
|
|
528
|
+
return {
|
|
529
|
+
signatureText: JSON.stringify({
|
|
530
|
+
kind: "Ethena",
|
|
531
|
+
name: "ERC20.approve",
|
|
532
|
+
to: "sUSDe vault",
|
|
533
|
+
function: "approve(address spender, uint256 amount)",
|
|
534
|
+
spender: susde,
|
|
535
|
+
amountHuman: args.amountHuman,
|
|
536
|
+
note: "Allowance to stake this USDe amount (not unlimited)."
|
|
537
|
+
}),
|
|
538
|
+
evm: { type: "ethena_erc20_approve", version: 1, chainId: "1" },
|
|
539
|
+
ethena: { step: "approve_usde", susde }
|
|
469
540
|
};
|
|
470
|
-
firstDataNo0x = s.data.startsWith("0x") ? s.data.slice(2) : s.data;
|
|
471
541
|
}
|
|
472
|
-
|
|
473
|
-
if (s.kind === "approve") {
|
|
474
|
-
batchMeta.push({
|
|
475
|
-
destinationAddress: usde,
|
|
476
|
-
signatureText: JSON.stringify({
|
|
477
|
-
kind: "Ethena",
|
|
478
|
-
name: "ERC20.approve",
|
|
479
|
-
to: "sUSDe vault",
|
|
480
|
-
function: "approve(address spender, uint256 amount)",
|
|
481
|
-
spender: susde,
|
|
482
|
-
amountHuman: args.amountHuman,
|
|
483
|
-
note: "Allowance to stake this USDe amount (not unlimited)."
|
|
484
|
-
}),
|
|
485
|
-
evm: { type: "ethena_erc20_approve", version: 1, chainId: "1" },
|
|
486
|
-
ethena: { step: "approve_usde", susde }
|
|
487
|
-
});
|
|
488
|
-
} else {
|
|
489
|
-
batchMeta.push({
|
|
490
|
-
destinationAddress: susde,
|
|
542
|
+
return {
|
|
491
543
|
signatureText: JSON.stringify({
|
|
492
544
|
kind: "Ethena",
|
|
493
545
|
name: "StakedUSDe (ERC-4626).deposit",
|
|
@@ -497,40 +549,10 @@ async function buildEvmMultisignBodyEthenaUsdeStakeToSusde(args) {
|
|
|
497
549
|
amountHuman: args.amountHuman
|
|
498
550
|
}),
|
|
499
551
|
evm: { type: "ethena_susde_deposit", version: 1, chainId: "1" },
|
|
500
|
-
ethena: { step: "deposit", vault: susde, gasBuildDeposit: { baseGasUnits:
|
|
501
|
-
}
|
|
552
|
+
ethena: { step: "deposit", vault: susde, gasBuildDeposit: { baseGasUnits: gasLimit.toString() } }
|
|
553
|
+
};
|
|
502
554
|
}
|
|
503
|
-
}
|
|
504
|
-
const extraPayload = { batchMeta };
|
|
505
|
-
if (useCustomGas && args.customGasChainDetails && Object.keys(args.customGasChainDetails).length > 0) {
|
|
506
|
-
extraPayload.customGasChainDetails = args.customGasChainDetails;
|
|
507
|
-
}
|
|
508
|
-
const extraJSON = JSON.stringify(extraPayload);
|
|
509
|
-
const firstSigText = batchMeta[0].signatureText;
|
|
510
|
-
const n = steps.length;
|
|
511
|
-
const purposeSuffix = n === 1 ? "Ethena: 1-tx \u2014 deposit USDe to sUSDe (allowance already set)." : `Ethena: ${n}-tx batch \u2014 approve USDe to sUSDe vault, then deposit.`;
|
|
512
|
-
const bodyForSign = {
|
|
513
|
-
keyList,
|
|
514
|
-
pubKey: ph,
|
|
515
|
-
msgHash: messageHashes[0],
|
|
516
|
-
msgRaw: firstDataNo0x,
|
|
517
|
-
messageHashes,
|
|
518
|
-
messageRawBatch,
|
|
519
|
-
destinationChainID: "1",
|
|
520
|
-
destinationAddress: steps[0].to,
|
|
521
|
-
extraJSON,
|
|
522
|
-
signatureText: firstSigText,
|
|
523
|
-
purpose: (() => {
|
|
524
|
-
const t = args.purposeText.trim();
|
|
525
|
-
return (t ? `${t}
|
|
526
|
-
|
|
527
|
-
` : "") + purposeSuffix;
|
|
528
|
-
})(),
|
|
529
|
-
...firstTxFeePayload,
|
|
530
|
-
proposalTxParams: proposalTxParamsBatch
|
|
531
|
-
};
|
|
532
|
-
if (clientId) bodyForSign.clientId = clientId;
|
|
533
|
-
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
555
|
+
});
|
|
534
556
|
}
|
|
535
557
|
var ETHENA_SUSDE_COOLDOWN_SHARES_FALLBACK = 1200000n;
|
|
536
558
|
var ETHENA_SUSDE_UNSTAKE_CLAIM_FALLBACK = 500000n;
|
|
@@ -538,161 +560,27 @@ async function buildEthenaStakedUsdeOneTxMultisignBody(args) {
|
|
|
538
560
|
if (args.chainId !== 1) {
|
|
539
561
|
throw new Error("Ethena sUSDe exit is only supported on Ethereum mainnet (chain id 1).");
|
|
540
562
|
}
|
|
541
|
-
const
|
|
542
|
-
|
|
543
|
-
const
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
563
|
+
const step = args.step;
|
|
564
|
+
const evmSteps = [{ to: step.to, data: step.data, value: step.value, fallbackGas: args.gasFallback }];
|
|
565
|
+
const firstDataNo0x = step.data.startsWith("0x") ? step.data.slice(2) : step.data;
|
|
566
|
+
return buildEvmMultisignBatch({
|
|
567
|
+
context: {
|
|
568
|
+
chainCategory: "evm",
|
|
569
|
+
keyGen: args.keyGen,
|
|
570
|
+
purposeText: args.purposeText,
|
|
571
|
+
chainId: 1,
|
|
572
|
+
rpcUrl: args.rpcUrl.trim(),
|
|
573
|
+
executorAddress: args.executor,
|
|
574
|
+
chainDetail: args.chainDetail,
|
|
575
|
+
useCustomGas: args.useCustomGas,
|
|
576
|
+
customGasChainDetails: args.customGasChainDetails
|
|
577
|
+
},
|
|
578
|
+
steps: evmSteps,
|
|
579
|
+
purposeSuffix: args.purposeSuffix,
|
|
580
|
+
firstMsgRawNo0x: firstDataNo0x,
|
|
581
|
+
destinationAddress: step.to,
|
|
582
|
+
buildBatchMeta: ({ gasLimit }) => args.makeBatchMeta({ gasLimitI: gasLimit })
|
|
557
583
|
});
|
|
558
|
-
const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(args.rpcUrl.trim()) });
|
|
559
|
-
const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
560
|
-
const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: "pending" });
|
|
561
|
-
const messageHashes = [];
|
|
562
|
-
const messageRawBatch = [];
|
|
563
|
-
const proposalTxParamsBatch = [];
|
|
564
|
-
const batchMeta = [];
|
|
565
|
-
let firstTxFeePayload = {};
|
|
566
|
-
let firstDataNo0x = "";
|
|
567
|
-
for (let i = 0; i < steps.length; i++) {
|
|
568
|
-
const s = steps[i];
|
|
569
|
-
const currentNonce = baseNonce + i;
|
|
570
|
-
let estimatedGas;
|
|
571
|
-
try {
|
|
572
|
-
estimatedGas = await publicClient.estimateGas({
|
|
573
|
-
to: s.to,
|
|
574
|
-
data: s.data,
|
|
575
|
-
value: s.value,
|
|
576
|
-
account: executor
|
|
577
|
-
});
|
|
578
|
-
} catch {
|
|
579
|
-
estimatedGas = args.gasFallback;
|
|
580
|
-
}
|
|
581
|
-
const gasLimitI = useCustomGas ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig) : estimatedGas;
|
|
582
|
-
if (legacy) {
|
|
583
|
-
let gasPriceWei = await publicClient.getGasPrice();
|
|
584
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
585
|
-
gasPriceWei = gasPriceWei * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
586
|
-
}
|
|
587
|
-
if (useCustomGas && args.chainDetail?.gasPrice != null && args.chainDetail.gasPrice > 0) {
|
|
588
|
-
const configured = viem.parseGwei(gweiToDecimalString(Number(args.chainDetail.gasPrice)));
|
|
589
|
-
if (configured > gasPriceWei) gasPriceWei = configured;
|
|
590
|
-
}
|
|
591
|
-
const ser = viem.serializeTransaction({
|
|
592
|
-
type: "legacy",
|
|
593
|
-
to: s.to,
|
|
594
|
-
data: s.data,
|
|
595
|
-
value: s.value,
|
|
596
|
-
gas: gasLimitI,
|
|
597
|
-
gasPrice: gasPriceWei,
|
|
598
|
-
nonce: currentNonce,
|
|
599
|
-
chainId: 1
|
|
600
|
-
});
|
|
601
|
-
const h = viem.keccak256(ser);
|
|
602
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
603
|
-
messageRawBatch.push(ser);
|
|
604
|
-
proposalTxParamsBatch.push({
|
|
605
|
-
nonce: currentNonce,
|
|
606
|
-
gasLimit: gasLimitI.toString(),
|
|
607
|
-
txType: "legacy",
|
|
608
|
-
gasPrice: gasPriceWei.toString()
|
|
609
|
-
});
|
|
610
|
-
if (i === 0) {
|
|
611
|
-
firstTxFeePayload = { txNonce: currentNonce, txGasLimit: gasLimitI.toString(), txGasPrice: gasPriceWei.toString() };
|
|
612
|
-
firstDataNo0x = s.data.startsWith("0x") ? s.data.slice(2) : s.data;
|
|
613
|
-
}
|
|
614
|
-
} else {
|
|
615
|
-
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
616
|
-
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
617
|
-
const configuredBase = useCustomGas && args.chainDetail?.baseFee != null ? Number(args.chainDetail.baseFee) : 0;
|
|
618
|
-
const configuredPriority = useCustomGas && args.chainDetail?.priorityFee != null ? Number(args.chainDetail.priorityFee) : 0;
|
|
619
|
-
const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
|
|
620
|
-
const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
|
|
621
|
-
const baseFeeMultiplierPct = useCustomGas && args.chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(args.chainDetail.baseFeeMultiplier)) : 100;
|
|
622
|
-
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
623
|
-
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
624
|
-
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(gweiToDecimalString(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
625
|
-
let maxFeePerGas = viem.parseGwei(gweiToDecimalString(maxFeePerGasGwei));
|
|
626
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
627
|
-
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
628
|
-
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
629
|
-
}
|
|
630
|
-
({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(
|
|
631
|
-
maxFeePerGas,
|
|
632
|
-
maxPriorityFeePerGas,
|
|
633
|
-
latestBaseFeeWei
|
|
634
|
-
));
|
|
635
|
-
const ser = viem.serializeTransaction({
|
|
636
|
-
type: "eip1559",
|
|
637
|
-
to: s.to,
|
|
638
|
-
data: s.data,
|
|
639
|
-
value: s.value,
|
|
640
|
-
gas: gasLimitI,
|
|
641
|
-
maxFeePerGas,
|
|
642
|
-
maxPriorityFeePerGas,
|
|
643
|
-
nonce: currentNonce,
|
|
644
|
-
chainId: 1
|
|
645
|
-
});
|
|
646
|
-
const h = viem.keccak256(ser);
|
|
647
|
-
messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
|
|
648
|
-
messageRawBatch.push(ser);
|
|
649
|
-
proposalTxParamsBatch.push({
|
|
650
|
-
nonce: currentNonce,
|
|
651
|
-
gasLimit: gasLimitI.toString(),
|
|
652
|
-
txType: "eip1559",
|
|
653
|
-
maxFeePerGas: maxFeePerGas.toString(),
|
|
654
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
655
|
-
});
|
|
656
|
-
if (i === 0) {
|
|
657
|
-
firstTxFeePayload = {
|
|
658
|
-
txNonce: currentNonce,
|
|
659
|
-
txGasLimit: gasLimitI.toString(),
|
|
660
|
-
txMaxFeePerGas: maxFeePerGas.toString(),
|
|
661
|
-
txMaxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
662
|
-
};
|
|
663
|
-
firstDataNo0x = s.data.startsWith("0x") ? s.data.slice(2) : s.data;
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
batchMeta.push(args.makeBatchMeta({ gasLimitI }));
|
|
667
|
-
}
|
|
668
|
-
const extraPayload = { batchMeta };
|
|
669
|
-
if (useCustomGas && args.customGasChainDetails && Object.keys(args.customGasChainDetails).length > 0) {
|
|
670
|
-
extraPayload.customGasChainDetails = args.customGasChainDetails;
|
|
671
|
-
}
|
|
672
|
-
const extraJSON = JSON.stringify(extraPayload);
|
|
673
|
-
const firstSigText = batchMeta[0].signatureText;
|
|
674
|
-
const bodyForSign = {
|
|
675
|
-
keyList,
|
|
676
|
-
pubKey: ph,
|
|
677
|
-
msgHash: messageHashes[0],
|
|
678
|
-
msgRaw: firstDataNo0x,
|
|
679
|
-
messageHashes,
|
|
680
|
-
messageRawBatch,
|
|
681
|
-
destinationChainID: "1",
|
|
682
|
-
destinationAddress: steps[0].to,
|
|
683
|
-
extraJSON,
|
|
684
|
-
signatureText: firstSigText,
|
|
685
|
-
purpose: (() => {
|
|
686
|
-
const t = args.purposeText.trim();
|
|
687
|
-
return (t ? `${t}
|
|
688
|
-
|
|
689
|
-
` : "") + args.purposeSuffix;
|
|
690
|
-
})(),
|
|
691
|
-
...firstTxFeePayload,
|
|
692
|
-
proposalTxParams: proposalTxParamsBatch
|
|
693
|
-
};
|
|
694
|
-
if (clientId) bodyForSign.clientId = clientId;
|
|
695
|
-
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
696
584
|
}
|
|
697
585
|
async function buildEvmMultisignBodyEthenaSusdeRedeemToUsde(args) {
|
|
698
586
|
if (args.chainId !== 1) {
|