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