@matterlabs/zksync-js 0.0.1 → 0.0.2
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 +12 -12
- package/dist/adapters/ethers/client.cjs +642 -1
- package/dist/adapters/ethers/client.cjs.map +1 -1
- package/dist/adapters/ethers/client.js +6 -5
- package/dist/adapters/ethers/estimator.d.ts +4 -0
- package/dist/adapters/ethers/index.cjs +934 -801
- package/dist/adapters/ethers/index.cjs.map +1 -1
- package/dist/adapters/ethers/index.js +9 -8
- package/dist/adapters/ethers/resources/deposits/context.d.ts +5 -5
- package/dist/adapters/ethers/resources/deposits/routes/types.d.ts +2 -6
- package/dist/adapters/ethers/resources/deposits/services/fee.d.ts +6 -0
- package/dist/adapters/ethers/resources/deposits/services/gas.d.ts +40 -0
- package/dist/adapters/ethers/resources/utils.d.ts +4 -15
- package/dist/adapters/ethers/resources/withdrawals/context.d.ts +4 -4
- package/dist/adapters/ethers/resources/withdrawals/routes/types.d.ts +2 -2
- package/dist/adapters/ethers/resources/withdrawals/services/fees.d.ts +14 -0
- package/dist/adapters/ethers/resources/withdrawals/services/gas.d.ts +12 -0
- package/dist/adapters/ethers/sdk.cjs +947 -1292
- package/dist/adapters/ethers/sdk.cjs.map +1 -1
- package/dist/adapters/ethers/sdk.js +7 -6
- package/dist/adapters/viem/client.cjs.map +1 -1
- package/dist/adapters/viem/client.d.ts +1 -1
- package/dist/adapters/viem/client.js +4 -5
- package/dist/adapters/viem/estimator.d.ts +4 -0
- package/dist/adapters/viem/index.cjs +944 -662
- package/dist/adapters/viem/index.cjs.map +1 -1
- package/dist/adapters/viem/index.js +8 -8
- package/dist/adapters/viem/resources/deposits/context.d.ts +5 -5
- package/dist/adapters/viem/resources/deposits/routes/types.d.ts +2 -6
- package/dist/adapters/viem/resources/deposits/services/fee.d.ts +6 -0
- package/dist/adapters/viem/resources/deposits/services/gas.d.ts +36 -0
- package/dist/adapters/viem/resources/utils.d.ts +3 -16
- package/dist/adapters/viem/resources/withdrawals/context.d.ts +3 -6
- package/dist/adapters/viem/resources/withdrawals/routes/types.d.ts +12 -2
- package/dist/adapters/viem/resources/withdrawals/services/fee.d.ts +17 -0
- package/dist/adapters/viem/resources/withdrawals/services/gas.d.ts +12 -0
- package/dist/adapters/viem/sdk.cjs +877 -563
- package/dist/adapters/viem/sdk.cjs.map +1 -1
- package/dist/adapters/viem/sdk.d.ts +1 -1
- package/dist/adapters/viem/sdk.js +6 -6
- package/dist/{chunk-3LALBFFE.js → chunk-3MRGU4HV.js} +9 -5
- package/dist/{chunk-4HLJJKIY.js → chunk-6K6VJQAL.js} +2 -2
- package/dist/{chunk-CGO27P7F.js → chunk-BCCKWWOX.js} +540 -741
- package/dist/{chunk-6GCT6TLS.js → chunk-F2ENUV3A.js} +13 -1
- package/dist/{chunk-DI2CJDPZ.js → chunk-HLUANWGN.js} +2 -2
- package/dist/{chunk-Y75OMFK6.js → chunk-M5J2MM2U.js} +351 -1
- package/dist/{chunk-263G6636.js → chunk-NCAIVYBR.js} +1 -14
- package/dist/{chunk-7M4V3FMT.js → chunk-OC6ZVLSP.js} +669 -559
- package/dist/chunk-QJS6ETEE.js +217 -0
- package/dist/chunk-XRE7H466.js +157 -0
- package/dist/{chunk-BD2LUO5T.js → chunk-YUK547UF.js} +3 -3
- package/dist/core/abi.d.ts +9 -0
- package/dist/core/adapters/interfaces.d.ts +25 -0
- package/dist/core/constants.cjs +12 -0
- package/dist/core/constants.cjs.map +1 -1
- package/dist/core/constants.d.ts +6 -0
- package/dist/core/constants.js +1 -1
- package/dist/core/index.cjs +4504 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +4 -4
- package/dist/core/resources/deposits/fee.d.ts +15 -0
- package/dist/core/resources/deposits/gas.d.ts +38 -0
- package/dist/core/resources/withdrawals/gas.d.ts +14 -0
- package/dist/core/types/errors.d.ts +1 -1
- package/dist/core/types/fees.d.ts +40 -0
- package/dist/core/types/flows/base.d.ts +0 -10
- package/dist/core/types/flows/deposits.d.ts +20 -6
- package/dist/core/types/flows/route.d.ts +2 -3
- package/dist/core/types/flows/withdrawals.d.ts +12 -6
- package/dist/index.cjs +4516 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -4
- package/package.json +5 -1
- package/dist/adapters/ethers/resources/withdrawals/routes/eth-nonbase.d.ts +0 -2
- package/dist/adapters/viem/resources/withdrawals/routes/eth-nonbase.d.ts +0 -2
- package/dist/chunk-B77GWPO5.js +0 -339
- package/dist/core/internal/abi-registry.d.ts +0 -9
- package/dist/core/utils/gas.d.ts +0 -13
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { ETH_ADDRESS, L2_NATIVE_TOKEN_VAULT_ADDRESS,
|
|
1
|
+
import { createErrorHandlers, toZKsyncError, classifyReadinessFromRevert } from './chunk-XRE7H466.js';
|
|
2
|
+
import { buildFeeBreakdown, quoteL2Gas, quoteL2BaseCost, quoteL1Gas, quoteL2Gas2 } from './chunk-QJS6ETEE.js';
|
|
3
|
+
import { findL1MessageSentLog, messengerLogIndex, isAddressEq, isHash66, pickDepositRoute, isETH, normalizeAddrEq, pickWithdrawRoute } from './chunk-HLUANWGN.js';
|
|
4
|
+
import { OP_WITHDRAWALS, IL1Nullifier_default, createError, OP_DEPOSITS, IERC20_default, isZKsyncError, isReceiptNotFound, IBridgehub_default, L2NativeTokenVault_default } from './chunk-M5J2MM2U.js';
|
|
5
|
+
import { ETH_ADDRESS, L2_NATIVE_TOKEN_VAULT_ADDRESS, L1_MESSENGER_ADDRESS, L2_ASSET_ROUTER_ADDRESS, FORMAL_ETH_ADDRESS, L2_BASE_TOKEN_ADDRESS, TOPIC_CANONICAL_ASSIGNED, TOPIC_CANONICAL_SUCCESS, SAFE_L1_BRIDGE_GAS } from './chunk-F2ENUV3A.js';
|
|
6
6
|
import { Interface, AbiCoder, ethers, Contract, NonceManager } from 'ethers';
|
|
7
7
|
|
|
8
8
|
var I_BRIDGEHUB = new Interface([
|
|
@@ -68,8 +68,29 @@ async function waitForL2ExecutionFromL1Tx(l1, l2, l1TxHash) {
|
|
|
68
68
|
}
|
|
69
69
|
return { l2Receipt, l2TxHash };
|
|
70
70
|
}
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
|
|
72
|
+
// src/adapters/ethers/resources/deposits/context.ts
|
|
73
|
+
async function commonCtx(p, client) {
|
|
74
|
+
const { bridgehub, l1AssetRouter } = await client.ensureAddresses();
|
|
75
|
+
const { chainId } = await client.l2.getNetwork();
|
|
76
|
+
const sender = await client.signer.getAddress();
|
|
77
|
+
const gasPerPubdata = p.gasPerPubdata ?? 800n;
|
|
78
|
+
const operatorTip = p.operatorTip ?? 0n;
|
|
79
|
+
const refundRecipient = p.refundRecipient ?? sender;
|
|
80
|
+
const route = await pickDepositRoute(client, BigInt(chainId), p.token);
|
|
81
|
+
return {
|
|
82
|
+
client,
|
|
83
|
+
l1AssetRouter,
|
|
84
|
+
route,
|
|
85
|
+
bridgehub,
|
|
86
|
+
chainIdL2: BigInt(chainId),
|
|
87
|
+
sender,
|
|
88
|
+
gasOverrides: p.l1TxOverrides,
|
|
89
|
+
l2GasLimit: p.l2GasLimit,
|
|
90
|
+
gasPerPubdata,
|
|
91
|
+
operatorTip,
|
|
92
|
+
refundRecipient
|
|
93
|
+
};
|
|
73
94
|
}
|
|
74
95
|
function encodeNativeTokenVaultAssetId(chainId, address) {
|
|
75
96
|
const abi = new AbiCoder();
|
|
@@ -95,78 +116,18 @@ function encodeNTVAssetId(chainId, address) {
|
|
|
95
116
|
);
|
|
96
117
|
return ethers.keccak256(hex);
|
|
97
118
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
async function checkBaseCost(baseCost, value) {
|
|
105
|
-
const resolvedValue = await value;
|
|
106
|
-
if (baseCost > resolvedValue) {
|
|
107
|
-
throw new Error(
|
|
108
|
-
`The base cost of performing the priority operation is higher than the provided value parameter for the transaction: baseCost: ${String(baseCost)}, provided value: ${String(resolvedValue)}!`
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
async function getFeeOverrides(client, overrides) {
|
|
113
|
-
assertNoLegacyGas(overrides);
|
|
114
|
-
const fd = await client.l1.getFeeData();
|
|
115
|
-
const maxFeeFromProvider = fd.maxFeePerGas ?? void 0;
|
|
116
|
-
const maxPriorityFromProvider = fd.maxPriorityFeePerGas ?? void 0;
|
|
117
|
-
const gasPriceFallback = fd.gasPrice ?? void 0;
|
|
118
|
-
const maxFeePerGas = overrides?.maxFeePerGas ?? maxFeeFromProvider ?? gasPriceFallback;
|
|
119
|
-
if (maxFeePerGas == null) throw new Error("provider returned no gas price data");
|
|
120
|
-
const maxPriorityFeePerGas = overrides?.maxPriorityFeePerGas ?? maxPriorityFromProvider ?? maxFeePerGas;
|
|
121
|
-
assertPriorityFeeBounds({ maxFeePerGas, maxPriorityFeePerGas });
|
|
122
|
-
const gasPriceForBaseCost = overrides?.maxFeePerGas ?? maxFeeFromProvider ?? gasPriceFallback ?? maxFeePerGas;
|
|
123
|
-
return {
|
|
124
|
-
gasLimit: overrides?.gasLimit,
|
|
125
|
-
maxFeePerGas,
|
|
126
|
-
maxPriorityFeePerGas,
|
|
127
|
-
gasPriceForBaseCost
|
|
128
|
-
};
|
|
119
|
+
var encodeNTVTransferData = encodeNativeTokenVaultTransferData;
|
|
120
|
+
function encodeSecondBridgeArgs(token, amount, l2Receiver) {
|
|
121
|
+
return AbiCoder.defaultAbiCoder().encode(
|
|
122
|
+
["address", "uint256", "address"],
|
|
123
|
+
[token, amount, l2Receiver]
|
|
124
|
+
);
|
|
129
125
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
let maxFeeFromProvider;
|
|
133
|
-
let maxPriorityFromProvider;
|
|
134
|
-
let gasPriceFallback;
|
|
135
|
-
try {
|
|
136
|
-
const fd = await client.l2.getFeeData();
|
|
137
|
-
if (fd?.maxFeePerGas != null) maxFeeFromProvider = fd.maxFeePerGas;
|
|
138
|
-
if (fd?.maxPriorityFeePerGas != null) {
|
|
139
|
-
maxPriorityFromProvider = fd.maxPriorityFeePerGas;
|
|
140
|
-
}
|
|
141
|
-
if (fd?.gasPrice != null) gasPriceFallback = fd.gasPrice;
|
|
142
|
-
} catch {
|
|
143
|
-
}
|
|
144
|
-
if (gasPriceFallback == null) {
|
|
145
|
-
try {
|
|
146
|
-
if (supportsGetGasPrice(client.l2)) {
|
|
147
|
-
const gp = await client.l2.getGasPrice();
|
|
148
|
-
gasPriceFallback = typeof gp === "bigint" ? gp : BigInt(gp.toString());
|
|
149
|
-
}
|
|
150
|
-
} catch {
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
const maxFeePerGas = overrides?.maxFeePerGas ?? maxFeeFromProvider ?? gasPriceFallback;
|
|
154
|
-
if (maxFeePerGas == null) {
|
|
155
|
-
throw new Error("L2 provider returned no gas price data");
|
|
156
|
-
}
|
|
157
|
-
const maxPriorityFeePerGas = overrides?.maxPriorityFeePerGas ?? maxPriorityFromProvider ?? maxFeePerGas;
|
|
158
|
-
assertPriorityFeeBounds({ maxFeePerGas, maxPriorityFeePerGas });
|
|
159
|
-
return {
|
|
160
|
-
gasLimit: overrides?.gasLimit,
|
|
161
|
-
maxFeePerGas,
|
|
162
|
-
maxPriorityFeePerGas
|
|
163
|
-
};
|
|
126
|
+
function encodeSecondBridgeErc20Args(token, amount, l2Receiver) {
|
|
127
|
+
return encodeSecondBridgeArgs(token, amount, l2Receiver);
|
|
164
128
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (fd.gasPrice != null) return fd.gasPrice;
|
|
168
|
-
if (fd.maxFeePerGas != null) return fd.maxFeePerGas;
|
|
169
|
-
throw new Error("provider returned no gas price data");
|
|
129
|
+
function encodeSecondBridgeEthArgs(amount, l2Receiver, ethToken = ETH_ADDRESS) {
|
|
130
|
+
return encodeSecondBridgeArgs(ethToken, amount, l2Receiver);
|
|
170
131
|
}
|
|
171
132
|
function buildDirectRequestStruct(args) {
|
|
172
133
|
return {
|
|
@@ -181,296 +142,256 @@ function buildDirectRequestStruct(args) {
|
|
|
181
142
|
refundRecipient: args.refundRecipient
|
|
182
143
|
};
|
|
183
144
|
}
|
|
184
|
-
function encodeSecondBridgeArgs(token, amount, l2Receiver) {
|
|
185
|
-
return AbiCoder.defaultAbiCoder().encode(
|
|
186
|
-
["address", "uint256", "address"],
|
|
187
|
-
[token, amount, l2Receiver]
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
function encodeSecondBridgeErc20Args(token, amount, l2Receiver) {
|
|
191
|
-
return encodeSecondBridgeArgs(token, amount, l2Receiver);
|
|
192
|
-
}
|
|
193
|
-
function encodeSecondBridgeEthArgs(amount, l2Receiver, ethToken = ETH_ADDRESS) {
|
|
194
|
-
return encodeSecondBridgeArgs(ethToken, amount, l2Receiver);
|
|
195
|
-
}
|
|
196
145
|
|
|
197
|
-
// src/adapters/ethers/
|
|
198
|
-
|
|
199
|
-
const { bridgehub, l1AssetRouter } = await client.ensureAddresses();
|
|
200
|
-
const { chainId } = await client.l2.getNetwork();
|
|
201
|
-
const sender = await client.signer.getAddress();
|
|
202
|
-
const fee = await getFeeOverrides(client, p.l1TxOverrides);
|
|
203
|
-
const l2GasLimit = p.l2GasLimit ?? 300000n;
|
|
204
|
-
const gasPerPubdata = p.gasPerPubdata ?? 800n;
|
|
205
|
-
const operatorTip = p.operatorTip ?? 0n;
|
|
206
|
-
const refundRecipient = p.refundRecipient ?? sender;
|
|
207
|
-
const route = await pickDepositRoute(client, BigInt(chainId), p.token);
|
|
146
|
+
// src/adapters/ethers/estimator.ts
|
|
147
|
+
function toCoreTx(tx) {
|
|
208
148
|
return {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
l2GasLimit,
|
|
217
|
-
gasPerPubdata,
|
|
218
|
-
operatorTip,
|
|
219
|
-
refundRecipient
|
|
149
|
+
to: tx.to,
|
|
150
|
+
from: tx.from,
|
|
151
|
+
data: tx.data,
|
|
152
|
+
value: tx.value ? BigInt(tx.value) : void 0,
|
|
153
|
+
gasLimit: tx.gasLimit ? BigInt(tx.gasLimit) : void 0,
|
|
154
|
+
maxFeePerGas: tx.maxFeePerGas ? BigInt(tx.maxFeePerGas) : void 0,
|
|
155
|
+
maxPriorityFeePerGas: tx.maxPriorityFeePerGas ? BigInt(tx.maxPriorityFeePerGas) : void 0
|
|
220
156
|
};
|
|
221
157
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
try {
|
|
252
|
-
ERROR_IFACES.push({ name: "Mailbox", iface: new Interface(Mailbox_default) });
|
|
253
|
-
} catch {
|
|
254
|
-
}
|
|
255
|
-
})();
|
|
256
|
-
function registerErrorAbi(name, abi) {
|
|
257
|
-
const existing = ERROR_IFACES.findIndex((x) => x.name === name);
|
|
258
|
-
const entry = { name, iface: new Interface(abi) };
|
|
259
|
-
if (existing >= 0) ERROR_IFACES[existing] = entry;
|
|
260
|
-
else ERROR_IFACES.push(entry);
|
|
261
|
-
}
|
|
262
|
-
function extractRevertData(e) {
|
|
263
|
-
const maybe = (
|
|
264
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
265
|
-
e?.data?.data ?? e?.error?.data ?? e?.data ?? e?.error?.error?.data ?? e?.info?.error?.data
|
|
266
|
-
);
|
|
267
|
-
if (typeof maybe === "string" && maybe.startsWith("0x") && maybe.length >= 10) {
|
|
268
|
-
return maybe;
|
|
269
|
-
}
|
|
270
|
-
return void 0;
|
|
271
|
-
}
|
|
272
|
-
function decodeRevert(e) {
|
|
273
|
-
const data = extractRevertData(e);
|
|
274
|
-
if (!data) return;
|
|
275
|
-
const selector = `0x${data.slice(2, 10)}`;
|
|
276
|
-
try {
|
|
277
|
-
const parsed = IFACE_ERROR_STRING.parseError(data);
|
|
278
|
-
if (parsed?.name === "Error") {
|
|
279
|
-
const args = parsed.args ? Array.from(parsed.args) : void 0;
|
|
280
|
-
return { selector, name: "Error", args };
|
|
281
|
-
}
|
|
282
|
-
} catch {
|
|
283
|
-
}
|
|
284
|
-
try {
|
|
285
|
-
const parsed = IFACE_PANIC.parseError(data);
|
|
286
|
-
if (parsed?.name === "Panic") {
|
|
287
|
-
const args = parsed.args ? Array.from(parsed.args) : void 0;
|
|
288
|
-
return { selector, name: "Panic", args };
|
|
289
|
-
}
|
|
290
|
-
} catch {
|
|
291
|
-
}
|
|
292
|
-
for (const { name, iface } of ERROR_IFACES) {
|
|
293
|
-
try {
|
|
294
|
-
const parsed = iface.parseError(data);
|
|
295
|
-
if (parsed) {
|
|
296
|
-
const args = parsed.args ? Array.from(parsed.args) : void 0;
|
|
297
|
-
return {
|
|
298
|
-
selector,
|
|
299
|
-
name: parsed.name,
|
|
300
|
-
args,
|
|
301
|
-
contract: name
|
|
302
|
-
};
|
|
158
|
+
function ethersToGasEstimator(provider) {
|
|
159
|
+
return {
|
|
160
|
+
async estimateGas(tx, stateOverrides) {
|
|
161
|
+
const ethTx = {
|
|
162
|
+
to: tx.to,
|
|
163
|
+
from: tx.from,
|
|
164
|
+
data: tx.data,
|
|
165
|
+
value: tx.value,
|
|
166
|
+
gasLimit: tx.gasLimit,
|
|
167
|
+
maxFeePerGas: tx.maxFeePerGas,
|
|
168
|
+
maxPriorityFeePerGas: tx.maxPriorityFeePerGas
|
|
169
|
+
};
|
|
170
|
+
if (stateOverrides && "send" in provider) {
|
|
171
|
+
try {
|
|
172
|
+
const jsonRpcProvider = provider;
|
|
173
|
+
const result = await jsonRpcProvider.send("eth_estimateGas", [
|
|
174
|
+
ethTx,
|
|
175
|
+
"latest",
|
|
176
|
+
stateOverrides
|
|
177
|
+
]);
|
|
178
|
+
return BigInt(result);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
console.warn(
|
|
181
|
+
"Failed to estimate gas with state overrides, falling back to standard estimation:",
|
|
182
|
+
error
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
} else if (stateOverrides) {
|
|
186
|
+
console.warn('Provider does not support "send", skipping state overrides estimation.');
|
|
303
187
|
}
|
|
304
|
-
|
|
188
|
+
return await provider.estimateGas(ethTx);
|
|
189
|
+
},
|
|
190
|
+
async estimateFeesPerGas() {
|
|
191
|
+
const fd = await provider.getFeeData();
|
|
192
|
+
return {
|
|
193
|
+
maxFeePerGas: fd.maxFeePerGas != null ? BigInt(fd.maxFeePerGas) : void 0,
|
|
194
|
+
maxPriorityFeePerGas: fd.maxPriorityFeePerGas != null ? BigInt(fd.maxPriorityFeePerGas) : void 0,
|
|
195
|
+
gasPrice: fd.gasPrice != null ? BigInt(fd.gasPrice) : void 0
|
|
196
|
+
};
|
|
197
|
+
},
|
|
198
|
+
async getGasPrice() {
|
|
199
|
+
const fd = await provider.getFeeData();
|
|
200
|
+
if (fd.gasPrice != null) return BigInt(fd.gasPrice);
|
|
201
|
+
throw new Error("Could not fetch gas price");
|
|
202
|
+
},
|
|
203
|
+
async call(tx) {
|
|
204
|
+
const ethTx = {
|
|
205
|
+
to: tx.to,
|
|
206
|
+
data: tx.data,
|
|
207
|
+
value: tx.value,
|
|
208
|
+
from: tx.from
|
|
209
|
+
};
|
|
210
|
+
return await provider.call(ethTx);
|
|
305
211
|
}
|
|
306
|
-
}
|
|
307
|
-
return { selector };
|
|
212
|
+
};
|
|
308
213
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
214
|
+
|
|
215
|
+
// src/adapters/ethers/resources/deposits/services/fee.ts
|
|
216
|
+
var { wrapAs } = createErrorHandlers("deposits");
|
|
217
|
+
var encode = (abi, fn, args) => {
|
|
218
|
+
return new Interface(abi).encodeFunctionData(fn, args);
|
|
219
|
+
};
|
|
220
|
+
async function quoteL2BaseCost2(input) {
|
|
221
|
+
const { ctx, l2GasLimit } = input;
|
|
222
|
+
const estimator = ethersToGasEstimator(ctx.client.l1);
|
|
223
|
+
return wrapAs(
|
|
224
|
+
"RPC",
|
|
225
|
+
"deposits.fees.l2BaseCost",
|
|
226
|
+
() => quoteL2BaseCost({
|
|
227
|
+
estimator,
|
|
228
|
+
encode,
|
|
229
|
+
bridgehub: ctx.bridgehub,
|
|
230
|
+
chainIdL2: ctx.chainIdL2,
|
|
231
|
+
l2GasLimit,
|
|
232
|
+
gasPerPubdata: ctx.gasPerPubdata
|
|
233
|
+
}),
|
|
234
|
+
{ ctx: { chainIdL2: ctx.chainIdL2 } }
|
|
235
|
+
);
|
|
325
236
|
}
|
|
326
237
|
|
|
327
|
-
// src/adapters/ethers/
|
|
328
|
-
function
|
|
329
|
-
|
|
330
|
-
const
|
|
331
|
-
return
|
|
238
|
+
// src/adapters/ethers/resources/deposits/services/gas.ts
|
|
239
|
+
async function quoteL1Gas2(input) {
|
|
240
|
+
const { ctx, tx, overrides, fallbackGasLimit } = input;
|
|
241
|
+
const estimator = ethersToGasEstimator(ctx.client.l1);
|
|
242
|
+
return quoteL1Gas({
|
|
243
|
+
estimator,
|
|
244
|
+
tx: toCoreTx(tx),
|
|
245
|
+
overrides,
|
|
246
|
+
fallbackGasLimit
|
|
247
|
+
});
|
|
332
248
|
}
|
|
333
|
-
function
|
|
334
|
-
|
|
335
|
-
|
|
249
|
+
async function quoteL2Gas3(input) {
|
|
250
|
+
const { ctx, route, l2TxForModeling, overrideGasLimit } = input;
|
|
251
|
+
const estimator = ethersToGasEstimator(ctx.client.l2);
|
|
252
|
+
return quoteL2Gas({
|
|
253
|
+
estimator,
|
|
254
|
+
route,
|
|
255
|
+
tx: l2TxForModeling ? toCoreTx(l2TxForModeling) : void 0,
|
|
256
|
+
gasPerPubdata: ctx.gasPerPubdata,
|
|
257
|
+
l2GasLimit: ctx.l2GasLimit,
|
|
258
|
+
overrideGasLimit,
|
|
259
|
+
stateOverrides: input.stateOverrides
|
|
260
|
+
});
|
|
336
261
|
}
|
|
337
|
-
function
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
function wrap2(operation, fn, opts) {
|
|
348
|
-
return run("INTERNAL", operation, fn, opts);
|
|
349
|
-
}
|
|
350
|
-
function wrapAs9(kind, operation, fn, opts) {
|
|
351
|
-
return run(kind, operation, fn, opts);
|
|
262
|
+
async function determineErc20L2Gas(input) {
|
|
263
|
+
const { ctx, l1Token } = input;
|
|
264
|
+
const DEFAULT_SAFE_L2_GAS_LIMIT = 3000000n;
|
|
265
|
+
if (ctx.l2GasLimit != null) {
|
|
266
|
+
return quoteL2Gas3({
|
|
267
|
+
ctx,
|
|
268
|
+
route: "erc20-nonbase",
|
|
269
|
+
overrideGasLimit: ctx.l2GasLimit
|
|
270
|
+
});
|
|
352
271
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
"
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
272
|
+
try {
|
|
273
|
+
const { l2NativeTokenVault } = await ctx.client.contracts();
|
|
274
|
+
const l2TokenAddress = await l2NativeTokenVault.l2TokenAddress(l1Token);
|
|
275
|
+
if (l2TokenAddress === "0x0000000000000000000000000000000000000000") {
|
|
276
|
+
return quoteL2Gas3({
|
|
277
|
+
ctx,
|
|
278
|
+
route: "erc20-nonbase",
|
|
279
|
+
overrideGasLimit: DEFAULT_SAFE_L2_GAS_LIMIT
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
const modelTx = {
|
|
283
|
+
to: input.modelTx?.to ?? ctx.sender,
|
|
284
|
+
from: input.modelTx?.from ?? ctx.sender,
|
|
285
|
+
data: input.modelTx?.data ?? "0x",
|
|
286
|
+
value: input.modelTx?.value ?? 0n
|
|
287
|
+
};
|
|
288
|
+
const gas = await quoteL2Gas3({
|
|
289
|
+
ctx,
|
|
290
|
+
route: "erc20-nonbase",
|
|
291
|
+
l2TxForModeling: modelTx
|
|
292
|
+
});
|
|
293
|
+
if (!gas) {
|
|
294
|
+
return quoteL2Gas3({
|
|
295
|
+
ctx,
|
|
296
|
+
route: "erc20-nonbase",
|
|
297
|
+
overrideGasLimit: DEFAULT_SAFE_L2_GAS_LIMIT
|
|
298
|
+
});
|
|
369
299
|
}
|
|
300
|
+
return gas;
|
|
301
|
+
} catch (err) {
|
|
302
|
+
console.warn("Failed to determine ERC20 L2 gas; defaulting to safe gas limit.", err);
|
|
303
|
+
return quoteL2Gas3({
|
|
304
|
+
ctx,
|
|
305
|
+
route: "erc20-nonbase",
|
|
306
|
+
overrideGasLimit: DEFAULT_SAFE_L2_GAS_LIMIT
|
|
307
|
+
});
|
|
370
308
|
}
|
|
371
|
-
return { wrap: wrap2, wrapAs: wrapAs9, toResult: toResult2 };
|
|
372
309
|
}
|
|
373
310
|
|
|
374
311
|
// src/adapters/ethers/resources/deposits/routes/eth.ts
|
|
375
|
-
var { wrapAs } = createErrorHandlers("deposits");
|
|
376
312
|
function routeEthDirect() {
|
|
377
313
|
return {
|
|
378
314
|
async build(p, ctx) {
|
|
379
315
|
const bh = new Contract(ctx.bridgehub, IBridgehub_default, ctx.client.l1);
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
316
|
+
const l2TxModel = {
|
|
317
|
+
to: p.to ?? ctx.sender,
|
|
318
|
+
from: ctx.sender,
|
|
319
|
+
data: "0x",
|
|
320
|
+
value: 0n
|
|
321
|
+
};
|
|
322
|
+
const l2GasParams = await quoteL2Gas3({
|
|
323
|
+
ctx,
|
|
324
|
+
route: "eth-base",
|
|
325
|
+
l2TxForModeling: l2TxModel,
|
|
326
|
+
overrideGasLimit: ctx.l2GasLimit,
|
|
327
|
+
stateOverrides: {
|
|
328
|
+
[ctx.sender]: {
|
|
329
|
+
balance: "0xffffffffffffffffffff"
|
|
330
|
+
}
|
|
393
331
|
}
|
|
394
|
-
);
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
const
|
|
332
|
+
});
|
|
333
|
+
if (!l2GasParams) {
|
|
334
|
+
throw new Error("Failed to estimate L2 gas for deposit.");
|
|
335
|
+
}
|
|
336
|
+
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
337
|
+
const mintValue = baseCost + ctx.operatorTip + p.amount;
|
|
399
338
|
const req = buildDirectRequestStruct({
|
|
400
339
|
chainId: ctx.chainIdL2,
|
|
401
340
|
mintValue,
|
|
402
|
-
l2GasLimit:
|
|
341
|
+
l2GasLimit: l2GasParams.gasLimit,
|
|
403
342
|
gasPerPubdata: ctx.gasPerPubdata,
|
|
404
343
|
refundRecipient: ctx.refundRecipient,
|
|
405
|
-
l2Contract,
|
|
406
|
-
l2Value
|
|
344
|
+
l2Contract: p.to ?? ctx.sender,
|
|
345
|
+
l2Value: p.amount
|
|
407
346
|
});
|
|
408
347
|
const data = bh.interface.encodeFunctionData("requestL2TransactionDirect", [req]);
|
|
409
|
-
|
|
410
|
-
const tx = {
|
|
348
|
+
const l1TxCandidate = {
|
|
411
349
|
to: ctx.bridgehub,
|
|
412
350
|
data,
|
|
413
351
|
value: mintValue,
|
|
414
352
|
from: ctx.sender,
|
|
415
|
-
...
|
|
353
|
+
...ctx.gasOverrides
|
|
416
354
|
};
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
{
|
|
427
|
-
ctx: { where: "l1.estimateGas", to: ctx.bridgehub },
|
|
428
|
-
message: "Failed to estimate gas for Bridgehub request."
|
|
429
|
-
}
|
|
430
|
-
);
|
|
431
|
-
const buffered = BigInt(est) * 115n / 100n;
|
|
432
|
-
tx.gasLimit = buffered;
|
|
433
|
-
resolvedL1GasLimit = buffered;
|
|
434
|
-
} catch {
|
|
435
|
-
}
|
|
355
|
+
const l1GasParams = await quoteL1Gas2({
|
|
356
|
+
ctx,
|
|
357
|
+
tx: l1TxCandidate,
|
|
358
|
+
overrides: ctx.gasOverrides
|
|
359
|
+
});
|
|
360
|
+
if (l1GasParams) {
|
|
361
|
+
l1TxCandidate.gasLimit = l1GasParams.gasLimit;
|
|
362
|
+
l1TxCandidate.maxFeePerGas = l1GasParams.maxFeePerGas;
|
|
363
|
+
l1TxCandidate.maxPriorityFeePerGas = l1GasParams.maxPriorityFeePerGas;
|
|
436
364
|
}
|
|
437
365
|
const steps = [
|
|
438
366
|
{
|
|
439
367
|
key: "bridgehub:direct",
|
|
440
368
|
kind: "bridgehub:direct",
|
|
441
369
|
description: "Bridge ETH via Bridgehub.requestL2TransactionDirect",
|
|
442
|
-
tx
|
|
370
|
+
tx: l1TxCandidate
|
|
443
371
|
}
|
|
444
372
|
];
|
|
373
|
+
const fees = buildFeeBreakdown({
|
|
374
|
+
feeToken: ETH_ADDRESS,
|
|
375
|
+
l1Gas: l1GasParams,
|
|
376
|
+
l2Gas: l2GasParams,
|
|
377
|
+
l2BaseCost: baseCost,
|
|
378
|
+
operatorTip: ctx.operatorTip,
|
|
379
|
+
mintValue
|
|
380
|
+
});
|
|
445
381
|
return {
|
|
446
382
|
steps,
|
|
447
383
|
approvals: [],
|
|
448
|
-
|
|
384
|
+
fees
|
|
449
385
|
};
|
|
450
386
|
}
|
|
451
387
|
};
|
|
452
388
|
}
|
|
453
389
|
var { wrapAs: wrapAs2 } = createErrorHandlers("deposits");
|
|
454
|
-
var MIN_L2_GAS_FOR_ERC20 = 2500000n;
|
|
455
390
|
function routeErc20NonBase() {
|
|
456
391
|
return {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
const bh = new Contract(ctx.bridgehub, IBridgehub_default, ctx.client.l1);
|
|
461
|
-
const assetRouter = ctx.l1AssetRouter;
|
|
462
|
-
const { gasPriceForBaseCost, gasLimit: overrideGasLimit, ...txFeeOverrides } = ctx.fee;
|
|
463
|
-
const txOverrides = overrideGasLimit != null ? { ...txFeeOverrides, gasLimit: overrideGasLimit } : txFeeOverrides;
|
|
464
|
-
let resolvedL1GasLimit = overrideGasLimit ?? ctx.l2GasLimit;
|
|
465
|
-
const baseToken = await wrapAs2(
|
|
466
|
-
"CONTRACT",
|
|
467
|
-
OP_DEPOSITS.nonbase.baseToken ?? "deposits.erc20-nonbase:baseToken",
|
|
468
|
-
() => bh.baseToken(ctx.chainIdL2),
|
|
469
|
-
{
|
|
470
|
-
ctx: { where: "bridgehub.baseToken", chainIdL2: ctx.chainIdL2 },
|
|
471
|
-
message: "Failed to read base token."
|
|
472
|
-
}
|
|
473
|
-
);
|
|
392
|
+
// TODO: do we even need these validations?
|
|
393
|
+
async preflight(p, ctx) {
|
|
394
|
+
const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
|
|
474
395
|
await wrapAs2(
|
|
475
396
|
"VALIDATION",
|
|
476
397
|
OP_DEPOSITS.nonbase.assertNonBaseToken,
|
|
@@ -481,52 +402,51 @@ function routeErc20NonBase() {
|
|
|
481
402
|
},
|
|
482
403
|
{ ctx: { depositToken: p.token, baseToken } }
|
|
483
404
|
);
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
405
|
+
},
|
|
406
|
+
async build(p, ctx) {
|
|
407
|
+
const l1Signer = ctx.client.getL1Signer();
|
|
408
|
+
const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
|
|
409
|
+
const baseIsEth = isETH(baseToken);
|
|
410
|
+
const l2GasParams = await determineErc20L2Gas({
|
|
411
|
+
ctx,
|
|
412
|
+
l1Token: p.token,
|
|
413
|
+
modelTx: {
|
|
414
|
+
to: p.to ?? ctx.sender,
|
|
415
|
+
from: ctx.sender,
|
|
416
|
+
data: "0x",
|
|
417
|
+
value: 0n
|
|
497
418
|
}
|
|
498
|
-
);
|
|
499
|
-
|
|
419
|
+
});
|
|
420
|
+
if (!l2GasParams) throw new Error("Failed to establish L2 gas parameters.");
|
|
421
|
+
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
500
422
|
const mintValue = baseCost + ctx.operatorTip;
|
|
501
423
|
const approvals = [];
|
|
502
424
|
const steps = [];
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
{
|
|
511
|
-
|
|
512
|
-
message: "Failed to read deposit-token allowance."
|
|
513
|
-
}
|
|
514
|
-
);
|
|
515
|
-
if (allowanceToken < p.amount) {
|
|
516
|
-
approvals.push({ token: p.token, spender: assetRouter, amount: p.amount });
|
|
517
|
-
const data = erc20Deposit.interface.encodeFunctionData("approve", [
|
|
518
|
-
assetRouter,
|
|
519
|
-
p.amount
|
|
520
|
-
]);
|
|
521
|
-
steps.push({
|
|
522
|
-
key: `approve:${p.token}:${assetRouter}`,
|
|
523
|
-
kind: "approve",
|
|
524
|
-
description: `Approve ${p.amount} for router (deposit token)`,
|
|
525
|
-
tx: { to: p.token, data, from: ctx.sender, ...txOverrides }
|
|
526
|
-
});
|
|
425
|
+
const assetRouter = ctx.l1AssetRouter;
|
|
426
|
+
const erc20Deposit = new Contract(p.token, IERC20_default, l1Signer);
|
|
427
|
+
const allowanceToken = await wrapAs2(
|
|
428
|
+
"RPC",
|
|
429
|
+
OP_DEPOSITS.nonbase.allowanceToken,
|
|
430
|
+
() => erc20Deposit.allowance(ctx.sender, assetRouter),
|
|
431
|
+
{
|
|
432
|
+
ctx: { where: "erc20.allowance", token: p.token, spender: assetRouter },
|
|
433
|
+
message: "Failed to read deposit-token allowance."
|
|
527
434
|
}
|
|
435
|
+
);
|
|
436
|
+
if (allowanceToken < p.amount) {
|
|
437
|
+
approvals.push({ token: p.token, spender: assetRouter, amount: p.amount });
|
|
438
|
+
steps.push({
|
|
439
|
+
key: `approve:${p.token}:${assetRouter}`,
|
|
440
|
+
kind: "approve",
|
|
441
|
+
description: `Approve ${p.amount} for router (deposit token)`,
|
|
442
|
+
tx: {
|
|
443
|
+
to: p.token,
|
|
444
|
+
data: erc20Deposit.interface.encodeFunctionData("approve", [assetRouter, p.amount]),
|
|
445
|
+
from: ctx.sender,
|
|
446
|
+
...ctx.gasOverrides
|
|
447
|
+
}
|
|
448
|
+
});
|
|
528
449
|
}
|
|
529
|
-
const baseIsEth = isETH(baseToken);
|
|
530
450
|
if (!baseIsEth) {
|
|
531
451
|
const erc20Base = new Contract(baseToken, IERC20_default, l1Signer);
|
|
532
452
|
const allowanceBase = await wrapAs2(
|
|
@@ -540,12 +460,16 @@ function routeErc20NonBase() {
|
|
|
540
460
|
);
|
|
541
461
|
if (allowanceBase < mintValue) {
|
|
542
462
|
approvals.push({ token: baseToken, spender: assetRouter, amount: mintValue });
|
|
543
|
-
const data = erc20Base.interface.encodeFunctionData("approve", [assetRouter, mintValue]);
|
|
544
463
|
steps.push({
|
|
545
464
|
key: `approve:${baseToken}:${assetRouter}`,
|
|
546
465
|
kind: "approve",
|
|
547
466
|
description: `Approve base token for mintValue`,
|
|
548
|
-
tx: {
|
|
467
|
+
tx: {
|
|
468
|
+
to: baseToken,
|
|
469
|
+
data: erc20Base.interface.encodeFunctionData("approve", [assetRouter, mintValue]),
|
|
470
|
+
from: ctx.sender,
|
|
471
|
+
...ctx.gasOverrides
|
|
472
|
+
}
|
|
549
473
|
});
|
|
550
474
|
}
|
|
551
475
|
}
|
|
@@ -558,64 +482,63 @@ function routeErc20NonBase() {
|
|
|
558
482
|
message: "Failed to encode bridging calldata."
|
|
559
483
|
}
|
|
560
484
|
);
|
|
561
|
-
const
|
|
485
|
+
const requestStruct = {
|
|
562
486
|
chainId: ctx.chainIdL2,
|
|
563
487
|
mintValue,
|
|
564
|
-
// fees (in ETH if base=ETH, else pulled as base ERC-20)
|
|
565
488
|
l2Value: 0n,
|
|
566
|
-
l2GasLimit:
|
|
489
|
+
l2GasLimit: l2GasParams.gasLimit,
|
|
567
490
|
l2GasPerPubdataByteLimit: ctx.gasPerPubdata,
|
|
568
491
|
refundRecipient: ctx.refundRecipient,
|
|
569
492
|
secondBridgeAddress: assetRouter,
|
|
570
493
|
secondBridgeValue: 0n,
|
|
571
494
|
secondBridgeCalldata
|
|
572
495
|
};
|
|
573
|
-
const
|
|
574
|
-
const
|
|
496
|
+
const bh = (await ctx.client.contracts()).bridgehub;
|
|
497
|
+
const data = bh.interface.encodeFunctionData("requestL2TransactionTwoBridges", [
|
|
498
|
+
requestStruct
|
|
499
|
+
]);
|
|
500
|
+
const txValue = baseIsEth ? mintValue : 0n;
|
|
501
|
+
const l1TxCandidate = {
|
|
575
502
|
to: ctx.bridgehub,
|
|
576
|
-
data
|
|
577
|
-
value:
|
|
503
|
+
data,
|
|
504
|
+
value: txValue,
|
|
578
505
|
from: ctx.sender,
|
|
579
|
-
...
|
|
506
|
+
...ctx.gasOverrides
|
|
580
507
|
};
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
ctx: { where: "l1.estimateGas", to: ctx.bridgehub, baseIsEth },
|
|
592
|
-
message: "Failed to estimate gas for Bridgehub request."
|
|
593
|
-
}
|
|
594
|
-
);
|
|
595
|
-
const buffered = BigInt(est) * 125n / 100n;
|
|
596
|
-
bridgeTx.gasLimit = buffered;
|
|
597
|
-
resolvedL1GasLimit = buffered;
|
|
598
|
-
} catch {
|
|
599
|
-
}
|
|
508
|
+
const l1GasParams = await quoteL1Gas2({
|
|
509
|
+
ctx,
|
|
510
|
+
tx: l1TxCandidate,
|
|
511
|
+
overrides: ctx.gasOverrides,
|
|
512
|
+
fallbackGasLimit: SAFE_L1_BRIDGE_GAS
|
|
513
|
+
});
|
|
514
|
+
if (l1GasParams) {
|
|
515
|
+
l1TxCandidate.gasLimit = l1GasParams.gasLimit;
|
|
516
|
+
l1TxCandidate.maxFeePerGas = l1GasParams.maxFeePerGas;
|
|
517
|
+
l1TxCandidate.maxPriorityFeePerGas = l1GasParams.maxPriorityFeePerGas;
|
|
600
518
|
}
|
|
601
519
|
steps.push({
|
|
602
|
-
key: "bridgehub:two-bridges
|
|
520
|
+
key: "bridgehub:two-bridges",
|
|
603
521
|
kind: "bridgehub:two-bridges",
|
|
604
|
-
description: baseIsEth ? "Bridge ERC-20 (
|
|
605
|
-
tx:
|
|
522
|
+
description: baseIsEth ? "Bridge ERC-20 (Fees paid in ETH)" : "Bridge ERC-20 (Fees paid in Base Token)",
|
|
523
|
+
tx: l1TxCandidate
|
|
524
|
+
});
|
|
525
|
+
const fees = buildFeeBreakdown({
|
|
526
|
+
feeToken: baseToken,
|
|
527
|
+
l1Gas: l1GasParams,
|
|
528
|
+
l2Gas: l2GasParams,
|
|
529
|
+
l2BaseCost: baseCost,
|
|
530
|
+
operatorTip: ctx.operatorTip,
|
|
531
|
+
mintValue
|
|
606
532
|
});
|
|
607
533
|
return {
|
|
608
534
|
steps,
|
|
609
535
|
approvals,
|
|
610
|
-
|
|
536
|
+
fees
|
|
611
537
|
};
|
|
612
538
|
}
|
|
613
539
|
};
|
|
614
540
|
}
|
|
615
541
|
var { wrapAs: wrapAs3 } = createErrorHandlers("deposits");
|
|
616
|
-
var BASE_COST_BUFFER_BPS = 100n;
|
|
617
|
-
var BPS = 10000n;
|
|
618
|
-
var withBuffer = (x) => x * (BPS + BASE_COST_BUFFER_BPS) / BPS;
|
|
619
542
|
function routeEthNonBase() {
|
|
620
543
|
return {
|
|
621
544
|
async preflight(p, ctx) {
|
|
@@ -629,16 +552,7 @@ function routeEthNonBase() {
|
|
|
629
552
|
},
|
|
630
553
|
{ ctx: { token: p.token } }
|
|
631
554
|
);
|
|
632
|
-
const
|
|
633
|
-
const baseToken = await wrapAs3(
|
|
634
|
-
"CONTRACT",
|
|
635
|
-
OP_DEPOSITS.ethNonBase.baseToken,
|
|
636
|
-
() => bh.baseToken(ctx.chainIdL2),
|
|
637
|
-
{
|
|
638
|
-
ctx: { where: "bridgehub.baseToken", chainIdL2: ctx.chainIdL2 },
|
|
639
|
-
message: "Failed to read base token."
|
|
640
|
-
}
|
|
641
|
-
);
|
|
555
|
+
const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
|
|
642
556
|
await wrapAs3(
|
|
643
557
|
"VALIDATION",
|
|
644
558
|
OP_DEPOSITS.ethNonBase.assertNonEthBase,
|
|
@@ -671,61 +585,48 @@ function routeEthNonBase() {
|
|
|
671
585
|
return;
|
|
672
586
|
},
|
|
673
587
|
async build(p, ctx) {
|
|
674
|
-
const
|
|
675
|
-
const
|
|
676
|
-
const
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
588
|
+
const l1Signer = ctx.client.getL1Signer();
|
|
589
|
+
const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
|
|
590
|
+
const l2TxModel = {
|
|
591
|
+
to: p.to ?? ctx.sender,
|
|
592
|
+
from: ctx.sender,
|
|
593
|
+
data: "0x",
|
|
594
|
+
value: 0n
|
|
595
|
+
};
|
|
596
|
+
const l2GasParams = await quoteL2Gas3({
|
|
597
|
+
ctx,
|
|
598
|
+
route: "eth-nonbase",
|
|
599
|
+
l2TxForModeling: l2TxModel,
|
|
600
|
+
overrideGasLimit: ctx.l2GasLimit
|
|
601
|
+
});
|
|
602
|
+
if (!l2GasParams) throw new Error("Failed to estimate L2 gas parameters.");
|
|
603
|
+
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
604
|
+
const mintValue = baseCost + ctx.operatorTip;
|
|
605
|
+
const approvals = [];
|
|
606
|
+
const steps = [];
|
|
607
|
+
const erc20Base = new Contract(baseToken, IERC20_default, l1Signer);
|
|
608
|
+
const allowance = await wrapAs3(
|
|
687
609
|
"RPC",
|
|
688
|
-
OP_DEPOSITS.ethNonBase.
|
|
689
|
-
() =>
|
|
690
|
-
ctx.chainIdL2,
|
|
691
|
-
gasPriceForBaseCost,
|
|
692
|
-
ctx.l2GasLimit,
|
|
693
|
-
ctx.gasPerPubdata
|
|
694
|
-
),
|
|
610
|
+
OP_DEPOSITS.ethNonBase.allowanceBase,
|
|
611
|
+
() => erc20Base.allowance(ctx.sender, ctx.l1AssetRouter),
|
|
695
612
|
{
|
|
696
|
-
ctx: { where: "
|
|
697
|
-
message: "
|
|
613
|
+
ctx: { where: "erc20.allowance", token: baseToken, spender: ctx.l1AssetRouter },
|
|
614
|
+
message: "Failed to read base-token allowance."
|
|
698
615
|
}
|
|
699
616
|
);
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
{
|
|
712
|
-
ctx: { where: "erc20.allowance", token: baseToken, spender: ctx.l1AssetRouter },
|
|
713
|
-
message: "Failed to read base-token allowance."
|
|
617
|
+
if (allowance < mintValue) {
|
|
618
|
+
approvals.push({ token: baseToken, spender: ctx.l1AssetRouter, amount: mintValue });
|
|
619
|
+
steps.push({
|
|
620
|
+
key: `approve:${baseToken}`,
|
|
621
|
+
kind: "approve",
|
|
622
|
+
description: `Approve base token for fees (mintValue)`,
|
|
623
|
+
tx: {
|
|
624
|
+
to: baseToken,
|
|
625
|
+
data: erc20Base.interface.encodeFunctionData("approve", [ctx.l1AssetRouter, mintValue]),
|
|
626
|
+
from: ctx.sender,
|
|
627
|
+
...ctx.gasOverrides
|
|
714
628
|
}
|
|
715
|
-
);
|
|
716
|
-
if (allowance < mintValue) {
|
|
717
|
-
approvals.push({ token: baseToken, spender: ctx.l1AssetRouter, amount: mintValue });
|
|
718
|
-
const data = erc20.interface.encodeFunctionData("approve", [
|
|
719
|
-
ctx.l1AssetRouter,
|
|
720
|
-
mintValue
|
|
721
|
-
]);
|
|
722
|
-
steps.push({
|
|
723
|
-
key: `approve:${baseToken}:${ctx.l1AssetRouter}`,
|
|
724
|
-
kind: "approve",
|
|
725
|
-
description: `Approve base token for mintValue`,
|
|
726
|
-
tx: { to: baseToken, data, from: ctx.sender, ...txOverrides }
|
|
727
|
-
});
|
|
728
|
-
}
|
|
629
|
+
});
|
|
729
630
|
}
|
|
730
631
|
const secondBridgeCalldata = await wrapAs3(
|
|
731
632
|
"INTERNAL",
|
|
@@ -739,69 +640,64 @@ function routeEthNonBase() {
|
|
|
739
640
|
}
|
|
740
641
|
}
|
|
741
642
|
);
|
|
742
|
-
const
|
|
643
|
+
const requestStruct = {
|
|
743
644
|
chainId: ctx.chainIdL2,
|
|
744
645
|
mintValue,
|
|
745
|
-
l2Value:
|
|
746
|
-
l2GasLimit:
|
|
646
|
+
l2Value: p.amount,
|
|
647
|
+
l2GasLimit: l2GasParams.gasLimit,
|
|
747
648
|
l2GasPerPubdataByteLimit: ctx.gasPerPubdata,
|
|
748
649
|
refundRecipient: ctx.refundRecipient,
|
|
749
650
|
secondBridgeAddress: ctx.l1AssetRouter,
|
|
750
651
|
secondBridgeValue: p.amount,
|
|
751
652
|
secondBridgeCalldata
|
|
752
653
|
};
|
|
753
|
-
const
|
|
654
|
+
const data = new Contract(
|
|
754
655
|
ctx.bridgehub,
|
|
755
656
|
IBridgehub_default,
|
|
756
657
|
ctx.client.l1
|
|
757
|
-
).interface.encodeFunctionData("requestL2TransactionTwoBridges", [
|
|
758
|
-
|
|
759
|
-
const bridgeTx = {
|
|
658
|
+
).interface.encodeFunctionData("requestL2TransactionTwoBridges", [requestStruct]);
|
|
659
|
+
const l1TxCandidate = {
|
|
760
660
|
to: ctx.bridgehub,
|
|
761
|
-
data
|
|
661
|
+
data,
|
|
762
662
|
value: p.amount,
|
|
763
663
|
// base ≠ ETH ⇒ msg.value == secondBridgeValue
|
|
764
664
|
from: ctx.sender,
|
|
765
|
-
...
|
|
665
|
+
...ctx.gasOverrides
|
|
766
666
|
};
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
ctx: { where: "l1.estimateGas", to: ctx.bridgehub },
|
|
778
|
-
message: "Failed to estimate gas for Bridgehub request."
|
|
779
|
-
}
|
|
780
|
-
);
|
|
781
|
-
const buffered = BigInt(est) * 115n / 100n;
|
|
782
|
-
bridgeTx.gasLimit = buffered;
|
|
783
|
-
resolvedL1GasLimit = buffered;
|
|
784
|
-
} catch {
|
|
785
|
-
}
|
|
667
|
+
const l1GasParams = await quoteL1Gas2({
|
|
668
|
+
ctx,
|
|
669
|
+
tx: l1TxCandidate,
|
|
670
|
+
overrides: ctx.gasOverrides,
|
|
671
|
+
fallbackGasLimit: SAFE_L1_BRIDGE_GAS
|
|
672
|
+
});
|
|
673
|
+
if (l1GasParams) {
|
|
674
|
+
l1TxCandidate.gasLimit = l1GasParams.gasLimit;
|
|
675
|
+
l1TxCandidate.maxFeePerGas = l1GasParams.maxFeePerGas;
|
|
676
|
+
l1TxCandidate.maxPriorityFeePerGas = l1GasParams.maxPriorityFeePerGas;
|
|
786
677
|
}
|
|
787
678
|
steps.push({
|
|
788
679
|
key: "bridgehub:two-bridges:eth-nonbase",
|
|
789
680
|
kind: "bridgehub:two-bridges",
|
|
790
681
|
description: "Bridge ETH (fees in base ERC-20) via Bridgehub.requestL2TransactionTwoBridges",
|
|
791
|
-
tx:
|
|
682
|
+
tx: l1TxCandidate
|
|
683
|
+
});
|
|
684
|
+
const fees = buildFeeBreakdown({
|
|
685
|
+
feeToken: baseToken,
|
|
686
|
+
l1Gas: l1GasParams,
|
|
687
|
+
l2Gas: l2GasParams,
|
|
688
|
+
l2BaseCost: baseCost,
|
|
689
|
+
operatorTip: ctx.operatorTip,
|
|
690
|
+
mintValue
|
|
792
691
|
});
|
|
793
692
|
return {
|
|
794
693
|
steps,
|
|
795
694
|
approvals,
|
|
796
|
-
|
|
695
|
+
fees
|
|
797
696
|
};
|
|
798
697
|
}
|
|
799
698
|
};
|
|
800
699
|
}
|
|
801
700
|
var { wrapAs: wrapAs4 } = createErrorHandlers("deposits");
|
|
802
|
-
var BASE_COST_BUFFER_BPS2 = 100n;
|
|
803
|
-
var BPS2 = 10000n;
|
|
804
|
-
var withBuffer2 = (x) => x * (BPS2 + BASE_COST_BUFFER_BPS2) / BPS2;
|
|
805
701
|
function routeErc20Base() {
|
|
806
702
|
return {
|
|
807
703
|
async preflight(p, ctx) {
|
|
@@ -815,16 +711,7 @@ function routeErc20Base() {
|
|
|
815
711
|
},
|
|
816
712
|
{ ctx: { token: p.token } }
|
|
817
713
|
);
|
|
818
|
-
const
|
|
819
|
-
const baseToken = await wrapAs4(
|
|
820
|
-
"CONTRACT",
|
|
821
|
-
OP_DEPOSITS.base.baseToken,
|
|
822
|
-
() => bh.baseToken(ctx.chainIdL2),
|
|
823
|
-
{
|
|
824
|
-
ctx: { where: "bridgehub.baseToken", chainIdL2: ctx.chainIdL2 },
|
|
825
|
-
message: "Failed to read base token."
|
|
826
|
-
}
|
|
827
|
-
);
|
|
714
|
+
const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
|
|
828
715
|
await wrapAs4(
|
|
829
716
|
"VALIDATION",
|
|
830
717
|
OP_DEPOSITS.base.assertMatchesBase,
|
|
@@ -838,41 +725,27 @@ function routeErc20Base() {
|
|
|
838
725
|
return;
|
|
839
726
|
},
|
|
840
727
|
async build(p, ctx) {
|
|
841
|
-
const
|
|
842
|
-
const
|
|
843
|
-
const
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
"
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
ctx.chainIdL2,
|
|
859
|
-
gasPriceForBaseCost,
|
|
860
|
-
ctx.l2GasLimit,
|
|
861
|
-
ctx.gasPerPubdata
|
|
862
|
-
),
|
|
863
|
-
{
|
|
864
|
-
ctx: { where: "l2TransactionBaseCost", chainIdL2: ctx.chainIdL2 },
|
|
865
|
-
message: "Could not fetch L2 base cost from Bridgehub."
|
|
866
|
-
}
|
|
867
|
-
);
|
|
868
|
-
const baseCost = BigInt(rawBaseCost);
|
|
869
|
-
const l2Value = p.amount;
|
|
870
|
-
const rawMintValue = baseCost + ctx.operatorTip + l2Value;
|
|
871
|
-
const mintValue = withBuffer2(rawMintValue);
|
|
728
|
+
const l1Signer = ctx.client.getL1Signer();
|
|
729
|
+
const baseToken = await ctx.client.baseToken(ctx.chainIdL2);
|
|
730
|
+
const l2TxModel = {
|
|
731
|
+
to: p.to ?? ctx.sender,
|
|
732
|
+
from: ctx.sender,
|
|
733
|
+
data: "0x",
|
|
734
|
+
value: 0n
|
|
735
|
+
};
|
|
736
|
+
const l2GasParams = await quoteL2Gas3({
|
|
737
|
+
ctx,
|
|
738
|
+
route: "erc20-base",
|
|
739
|
+
l2TxForModeling: l2TxModel,
|
|
740
|
+
overrideGasLimit: ctx.l2GasLimit
|
|
741
|
+
});
|
|
742
|
+
if (!l2GasParams) throw new Error("Failed to estimate L2 gas parameters.");
|
|
743
|
+
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
744
|
+
const mintValue = baseCost + ctx.operatorTip + p.amount;
|
|
872
745
|
const approvals = [];
|
|
873
746
|
const steps = [];
|
|
874
747
|
{
|
|
875
|
-
const erc20 = new Contract(baseToken, IERC20_default,
|
|
748
|
+
const erc20 = new Contract(baseToken, IERC20_default, l1Signer);
|
|
876
749
|
const allowance = await wrapAs4(
|
|
877
750
|
"RPC",
|
|
878
751
|
OP_DEPOSITS.base.allowance,
|
|
@@ -884,70 +757,70 @@ function routeErc20Base() {
|
|
|
884
757
|
);
|
|
885
758
|
if (allowance < mintValue) {
|
|
886
759
|
approvals.push({ token: baseToken, spender: ctx.l1AssetRouter, amount: mintValue });
|
|
887
|
-
const data2 = erc20.interface.encodeFunctionData("approve", [
|
|
888
|
-
ctx.l1AssetRouter,
|
|
889
|
-
mintValue
|
|
890
|
-
]);
|
|
891
760
|
steps.push({
|
|
892
761
|
key: `approve:${baseToken}:${ctx.l1AssetRouter}`,
|
|
893
762
|
kind: "approve",
|
|
894
763
|
description: "Approve base token for mintValue",
|
|
895
|
-
tx: {
|
|
764
|
+
tx: {
|
|
765
|
+
to: baseToken,
|
|
766
|
+
data: erc20.interface.encodeFunctionData("approve", [ctx.l1AssetRouter, mintValue]),
|
|
767
|
+
from: ctx.sender,
|
|
768
|
+
...ctx.gasOverrides
|
|
769
|
+
}
|
|
896
770
|
});
|
|
897
771
|
}
|
|
898
772
|
}
|
|
899
|
-
const
|
|
773
|
+
const requestStruct = buildDirectRequestStruct({
|
|
900
774
|
chainId: ctx.chainIdL2,
|
|
901
775
|
mintValue,
|
|
902
|
-
l2GasLimit:
|
|
776
|
+
l2GasLimit: l2GasParams.gasLimit,
|
|
903
777
|
gasPerPubdata: ctx.gasPerPubdata,
|
|
904
778
|
refundRecipient: ctx.refundRecipient,
|
|
905
779
|
l2Contract: p.to ?? ctx.sender,
|
|
906
|
-
l2Value
|
|
780
|
+
l2Value: p.amount
|
|
907
781
|
});
|
|
908
782
|
const data = new Contract(
|
|
909
783
|
ctx.bridgehub,
|
|
910
784
|
IBridgehub_default,
|
|
911
785
|
ctx.client.l1
|
|
912
|
-
).interface.encodeFunctionData("requestL2TransactionDirect", [
|
|
913
|
-
const
|
|
786
|
+
).interface.encodeFunctionData("requestL2TransactionDirect", [requestStruct]);
|
|
787
|
+
const l1TxCandidate = {
|
|
914
788
|
to: ctx.bridgehub,
|
|
915
789
|
data,
|
|
916
790
|
value: 0n,
|
|
917
791
|
// base token is ERC-20 ⇒ msg.value MUST be 0
|
|
918
792
|
from: ctx.sender,
|
|
919
|
-
...
|
|
793
|
+
...ctx.gasOverrides
|
|
920
794
|
};
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
ctx: { where: "l1.estimateGas", to: ctx.bridgehub },
|
|
932
|
-
message: "Failed to estimate gas for Bridgehub request."
|
|
933
|
-
}
|
|
934
|
-
);
|
|
935
|
-
const buffered = BigInt(est) * 115n / 100n;
|
|
936
|
-
tx.gasLimit = buffered;
|
|
937
|
-
resolvedL1GasLimit = buffered;
|
|
938
|
-
} catch {
|
|
939
|
-
}
|
|
795
|
+
const l1GasParams = await quoteL1Gas2({
|
|
796
|
+
ctx,
|
|
797
|
+
tx: l1TxCandidate,
|
|
798
|
+
overrides: ctx.gasOverrides,
|
|
799
|
+
fallbackGasLimit: SAFE_L1_BRIDGE_GAS
|
|
800
|
+
});
|
|
801
|
+
if (l1GasParams) {
|
|
802
|
+
l1TxCandidate.gasLimit = l1GasParams.gasLimit;
|
|
803
|
+
l1TxCandidate.maxFeePerGas = l1GasParams.maxFeePerGas;
|
|
804
|
+
l1TxCandidate.maxPriorityFeePerGas = l1GasParams.maxPriorityFeePerGas;
|
|
940
805
|
}
|
|
941
806
|
steps.push({
|
|
942
807
|
key: "bridgehub:direct:erc20-base",
|
|
943
808
|
kind: "bridgehub:direct",
|
|
944
809
|
description: "Bridge base ERC-20 via Bridgehub.requestL2TransactionDirect",
|
|
945
|
-
tx
|
|
810
|
+
tx: l1TxCandidate
|
|
811
|
+
});
|
|
812
|
+
const fees = buildFeeBreakdown({
|
|
813
|
+
feeToken: baseToken,
|
|
814
|
+
l1Gas: l1GasParams,
|
|
815
|
+
l2Gas: l2GasParams,
|
|
816
|
+
l2BaseCost: baseCost,
|
|
817
|
+
operatorTip: ctx.operatorTip,
|
|
818
|
+
mintValue
|
|
946
819
|
});
|
|
947
820
|
return {
|
|
948
821
|
steps,
|
|
949
822
|
approvals,
|
|
950
|
-
|
|
823
|
+
fees
|
|
951
824
|
};
|
|
952
825
|
}
|
|
953
826
|
};
|
|
@@ -966,37 +839,19 @@ function createDepositsResource(client) {
|
|
|
966
839
|
const ctx = await commonCtx(p, client);
|
|
967
840
|
const route = ctx.route;
|
|
968
841
|
await ROUTES[route].preflight?.(p, ctx);
|
|
969
|
-
const { steps, approvals,
|
|
970
|
-
const { baseCost, mintValue } = quoteExtras;
|
|
971
|
-
const fallbackGasLimit = quoteExtras.l1GasLimit;
|
|
972
|
-
const resolveGasLimit = () => {
|
|
973
|
-
if (ctx.fee.gasLimit != null) return ctx.fee.gasLimit;
|
|
974
|
-
for (let i = steps.length - 1; i >= 0; i--) {
|
|
975
|
-
const candidate = steps[i].tx.gasLimit;
|
|
976
|
-
if (candidate == null) continue;
|
|
977
|
-
if (typeof candidate === "bigint") return candidate;
|
|
978
|
-
try {
|
|
979
|
-
return BigInt(candidate.toString());
|
|
980
|
-
} catch {
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
if (fallbackGasLimit != null) return fallbackGasLimit;
|
|
984
|
-
return ctx.l2GasLimit;
|
|
985
|
-
};
|
|
986
|
-
const gasLimit = resolveGasLimit();
|
|
842
|
+
const { steps, approvals, fees } = await ROUTES[route].build(p, ctx);
|
|
987
843
|
return {
|
|
988
844
|
route: ctx.route,
|
|
989
845
|
summary: {
|
|
990
846
|
route: ctx.route,
|
|
991
847
|
approvalsNeeded: approvals,
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
fees
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
}
|
|
848
|
+
amounts: {
|
|
849
|
+
transfer: { token: p.token, amount: p.amount }
|
|
850
|
+
},
|
|
851
|
+
fees,
|
|
852
|
+
// Legacy fields (maintained for backward compatibility)
|
|
853
|
+
baseCost: fees.l2?.baseCost,
|
|
854
|
+
mintValue: fees.mintValue
|
|
1000
855
|
},
|
|
1001
856
|
steps
|
|
1002
857
|
};
|
|
@@ -1065,7 +920,7 @@ function createDepositsResource(client) {
|
|
|
1065
920
|
step.tx.maxPriorityFeePerGas = overrides.maxPriorityFeePerGas;
|
|
1066
921
|
}
|
|
1067
922
|
}
|
|
1068
|
-
if (!
|
|
923
|
+
if (!p.l1TxOverrides?.gasLimit) {
|
|
1069
924
|
try {
|
|
1070
925
|
const est = await client.l1.estimateGas(step.tx);
|
|
1071
926
|
step.tx.gasLimit = BigInt(est) * 115n / 100n;
|
|
@@ -1277,10 +1132,7 @@ async function commonCtx2(p, client) {
|
|
|
1277
1132
|
const { chainId } = await client.l2.getNetwork();
|
|
1278
1133
|
const chainIdL2 = BigInt(chainId);
|
|
1279
1134
|
const baseIsEth = await isEthBasedChain(client.l2, l2NativeTokenVault);
|
|
1280
|
-
const fee = await getL2FeeOverrides(client, p.l2TxOverrides);
|
|
1281
1135
|
const route = pickWithdrawRoute({ token: p.token, baseIsEth });
|
|
1282
|
-
const l2GasLimit = p.l2GasLimit ?? 300000n;
|
|
1283
|
-
const gasBufferPct = 15;
|
|
1284
1136
|
return {
|
|
1285
1137
|
client,
|
|
1286
1138
|
bridgehub,
|
|
@@ -1293,29 +1145,50 @@ async function commonCtx2(p, client) {
|
|
|
1293
1145
|
l2NativeTokenVault,
|
|
1294
1146
|
l2BaseTokenSystem,
|
|
1295
1147
|
baseIsEth,
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1148
|
+
gasOverrides: p.l2TxOverrides
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
// src/adapters/ethers/resources/withdrawals/services/gas.ts
|
|
1153
|
+
async function quoteL2Gas4(input) {
|
|
1154
|
+
const { ctx, tx } = input;
|
|
1155
|
+
const estimator = ethersToGasEstimator(ctx.client.l2);
|
|
1156
|
+
return quoteL2Gas2({
|
|
1157
|
+
estimator,
|
|
1158
|
+
tx: toCoreTx(tx),
|
|
1159
|
+
overrides: ctx.gasOverrides
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
// src/adapters/ethers/resources/withdrawals/services/fees.ts
|
|
1164
|
+
function buildFeeBreakdown2(p) {
|
|
1165
|
+
const l2Total = p.l2Gas?.maxCost ?? 0n;
|
|
1166
|
+
const l2 = {
|
|
1167
|
+
total: l2Total,
|
|
1168
|
+
gasLimit: p.l2Gas?.gasLimit ?? 0n,
|
|
1169
|
+
maxFeePerGas: p.l2Gas?.maxFeePerGas ?? 0n,
|
|
1170
|
+
maxPriorityFeePerGas: p.l2Gas?.maxPriorityFeePerGas
|
|
1171
|
+
};
|
|
1172
|
+
return {
|
|
1173
|
+
token: p.feeToken,
|
|
1174
|
+
maxTotal: l2Total,
|
|
1175
|
+
l2
|
|
1299
1176
|
};
|
|
1300
1177
|
}
|
|
1178
|
+
|
|
1179
|
+
// src/adapters/ethers/resources/withdrawals/routes/eth.ts
|
|
1301
1180
|
var { wrapAs: wrapAs5 } = createErrorHandlers("withdrawals");
|
|
1302
1181
|
function routeEthBase() {
|
|
1303
1182
|
return {
|
|
1304
1183
|
async build(p, ctx) {
|
|
1305
1184
|
const steps = [];
|
|
1306
|
-
const
|
|
1307
|
-
const base = new Contract(
|
|
1308
|
-
L2_BASE_TOKEN_ADDRESS,
|
|
1309
|
-
new Interface(IBaseToken_default),
|
|
1310
|
-
ctx.client.l2
|
|
1311
|
-
);
|
|
1312
|
-
const toL1 = p.to ?? ctx.sender;
|
|
1185
|
+
const base = (await ctx.client.contracts()).l2BaseTokenSystem;
|
|
1313
1186
|
const data = await wrapAs5(
|
|
1314
1187
|
"INTERNAL",
|
|
1315
1188
|
OP_WITHDRAWALS.eth.encodeWithdraw,
|
|
1316
|
-
() => Promise.resolve(base.interface.encodeFunctionData("withdraw", [
|
|
1189
|
+
() => Promise.resolve(base.interface.encodeFunctionData("withdraw", [p.to ?? ctx.sender])),
|
|
1317
1190
|
{
|
|
1318
|
-
ctx: { where: "L2BaseToken.withdraw", to:
|
|
1191
|
+
ctx: { where: "L2BaseToken.withdraw", to: p.to ?? ctx.sender },
|
|
1319
1192
|
message: "Failed to encode ETH withdraw calldata."
|
|
1320
1193
|
}
|
|
1321
1194
|
);
|
|
@@ -1323,34 +1196,25 @@ function routeEthBase() {
|
|
|
1323
1196
|
to: L2_BASE_TOKEN_ADDRESS,
|
|
1324
1197
|
data,
|
|
1325
1198
|
from: ctx.sender,
|
|
1326
|
-
value: p.amount
|
|
1327
|
-
maxFeePerGas,
|
|
1328
|
-
maxPriorityFeePerGas
|
|
1199
|
+
value: p.amount
|
|
1329
1200
|
};
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
"RPC",
|
|
1336
|
-
OP_WITHDRAWALS.eth.estGas,
|
|
1337
|
-
() => ctx.client.l2.estimateGas(tx),
|
|
1338
|
-
{
|
|
1339
|
-
ctx: { where: "l2.estimateGas", to: L2_BASE_TOKEN_ADDRESS },
|
|
1340
|
-
message: "Failed to estimate gas for L2 ETH withdraw."
|
|
1341
|
-
}
|
|
1342
|
-
);
|
|
1343
|
-
tx.gasLimit = BigInt(est) * 115n / 100n;
|
|
1344
|
-
} catch {
|
|
1345
|
-
}
|
|
1201
|
+
const gas = await quoteL2Gas4({ ctx, tx });
|
|
1202
|
+
if (gas) {
|
|
1203
|
+
tx.gasLimit = gas.gasLimit;
|
|
1204
|
+
tx.maxFeePerGas = gas.maxFeePerGas;
|
|
1205
|
+
tx.maxPriorityFeePerGas = gas.maxPriorityFeePerGas;
|
|
1346
1206
|
}
|
|
1207
|
+
const fees = buildFeeBreakdown2({
|
|
1208
|
+
feeToken: L2_BASE_TOKEN_ADDRESS,
|
|
1209
|
+
l2Gas: gas
|
|
1210
|
+
});
|
|
1347
1211
|
steps.push({
|
|
1348
1212
|
key: "l2-base-token:withdraw",
|
|
1349
1213
|
kind: "l2-base-token:withdraw",
|
|
1350
1214
|
description: "Withdraw ETH via L2 Base Token System",
|
|
1351
1215
|
tx
|
|
1352
1216
|
});
|
|
1353
|
-
return { steps, approvals: [],
|
|
1217
|
+
return { steps, approvals: [], fees };
|
|
1354
1218
|
}
|
|
1355
1219
|
};
|
|
1356
1220
|
}
|
|
@@ -1363,8 +1227,6 @@ function routeErc20NonBase2() {
|
|
|
1363
1227
|
async build(p, ctx) {
|
|
1364
1228
|
const steps = [];
|
|
1365
1229
|
const approvals = [];
|
|
1366
|
-
const { gasLimit: overrideGasLimit, maxFeePerGas, maxPriorityFeePerGas } = ctx.fee;
|
|
1367
|
-
const txOverrides = overrideGasLimit != null ? { maxFeePerGas, maxPriorityFeePerGas, gasLimit: overrideGasLimit } : { maxFeePerGas, maxPriorityFeePerGas };
|
|
1368
1230
|
const erc20 = new Contract(p.token, IERC20_default, ctx.client.getL2Signer());
|
|
1369
1231
|
const current = await wrapAs6(
|
|
1370
1232
|
"CONTRACT",
|
|
@@ -1386,14 +1248,25 @@ function routeErc20NonBase2() {
|
|
|
1386
1248
|
ctx.l2NativeTokenVault,
|
|
1387
1249
|
p.amount
|
|
1388
1250
|
]);
|
|
1251
|
+
const approveTx = {
|
|
1252
|
+
to: p.token,
|
|
1253
|
+
data,
|
|
1254
|
+
from: ctx.sender
|
|
1255
|
+
};
|
|
1256
|
+
const approveGas = await quoteL2Gas4({ ctx, tx: approveTx });
|
|
1257
|
+
if (approveGas) {
|
|
1258
|
+
approveTx.gasLimit = approveGas.gasLimit;
|
|
1259
|
+
approveTx.maxFeePerGas = approveGas.maxFeePerGas;
|
|
1260
|
+
approveTx.maxPriorityFeePerGas = approveGas.maxPriorityFeePerGas;
|
|
1261
|
+
}
|
|
1389
1262
|
steps.push({
|
|
1390
1263
|
key: `approve:l2:${p.token}:${ctx.l2NativeTokenVault}`,
|
|
1391
1264
|
kind: "approve:l2",
|
|
1392
1265
|
description: `Approve ${p.amount} to NativeTokenVault`,
|
|
1393
|
-
tx:
|
|
1266
|
+
tx: approveTx
|
|
1394
1267
|
});
|
|
1395
1268
|
}
|
|
1396
|
-
const ntv =
|
|
1269
|
+
const ntv = (await ctx.client.contracts()).l2NativeTokenVault;
|
|
1397
1270
|
const assetId = await wrapAs6(
|
|
1398
1271
|
"CONTRACT",
|
|
1399
1272
|
OP_WITHDRAWALS.erc20.ensureRegistered,
|
|
@@ -1407,17 +1280,14 @@ function routeErc20NonBase2() {
|
|
|
1407
1280
|
"INTERNAL",
|
|
1408
1281
|
OP_WITHDRAWALS.erc20.encodeAssetData,
|
|
1409
1282
|
() => Promise.resolve(
|
|
1410
|
-
|
|
1411
|
-
["uint256", "address", "address"],
|
|
1412
|
-
[p.amount, p.to ?? ctx.sender, p.token]
|
|
1413
|
-
)
|
|
1283
|
+
encodeNativeTokenVaultTransferData(p.amount, p.to ?? ctx.sender, p.token)
|
|
1414
1284
|
),
|
|
1415
1285
|
{
|
|
1416
1286
|
ctx: { where: "AbiCoder.encode", token: p.token, to: p.to ?? ctx.sender },
|
|
1417
1287
|
message: "Failed to encode burn/withdraw asset data."
|
|
1418
1288
|
}
|
|
1419
1289
|
);
|
|
1420
|
-
const l2ar =
|
|
1290
|
+
const l2ar = (await ctx.client.contracts()).l2AssetRouter;
|
|
1421
1291
|
const dataWithdraw = await wrapAs6(
|
|
1422
1292
|
"INTERNAL",
|
|
1423
1293
|
OP_WITHDRAWALS.erc20.encodeWithdraw,
|
|
@@ -1430,85 +1300,29 @@ function routeErc20NonBase2() {
|
|
|
1430
1300
|
const withdrawTx = {
|
|
1431
1301
|
to: ctx.l2AssetRouter,
|
|
1432
1302
|
data: dataWithdraw,
|
|
1433
|
-
from: ctx.sender
|
|
1434
|
-
...txOverrides
|
|
1303
|
+
from: ctx.sender
|
|
1435
1304
|
};
|
|
1305
|
+
const withdrawGas = await quoteL2Gas4({ ctx, tx: withdrawTx });
|
|
1306
|
+
if (withdrawGas) {
|
|
1307
|
+
withdrawTx.gasLimit = withdrawGas.gasLimit;
|
|
1308
|
+
withdrawTx.maxFeePerGas = withdrawGas.maxFeePerGas;
|
|
1309
|
+
withdrawTx.maxPriorityFeePerGas = withdrawGas.maxPriorityFeePerGas;
|
|
1310
|
+
}
|
|
1436
1311
|
steps.push({
|
|
1437
1312
|
key: "l2-asset-router:withdraw",
|
|
1438
1313
|
kind: "l2-asset-router:withdraw",
|
|
1439
1314
|
description: "Burn on L2 & send L2\u2192L1 message",
|
|
1440
1315
|
tx: withdrawTx
|
|
1441
1316
|
});
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
}
|
|
1446
|
-
var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
|
|
1447
|
-
function routeEthNonBase2() {
|
|
1448
|
-
return {
|
|
1449
|
-
async preflight(p, ctx) {
|
|
1450
|
-
await wrapAs7(
|
|
1451
|
-
"VALIDATION",
|
|
1452
|
-
OP_WITHDRAWALS.ethNonBase.assertNonEthBase,
|
|
1453
|
-
() => {
|
|
1454
|
-
if (p.token.toLowerCase() !== L2_BASE_TOKEN_ADDRESS.toLowerCase()) {
|
|
1455
|
-
throw new Error("eth-nonbase route requires the L2 base-token alias (0x\u2026800A).");
|
|
1456
|
-
}
|
|
1457
|
-
if (ctx.baseIsEth) {
|
|
1458
|
-
throw new Error("eth-nonbase route requires chain base \u2260 ETH.");
|
|
1459
|
-
}
|
|
1460
|
-
},
|
|
1461
|
-
{ ctx: { token: p.token, baseIsEth: ctx.baseIsEth } }
|
|
1462
|
-
);
|
|
1463
|
-
},
|
|
1464
|
-
async build(p, ctx) {
|
|
1465
|
-
const steps = [];
|
|
1466
|
-
const { gasLimit: overrideGasLimit, maxFeePerGas, maxPriorityFeePerGas } = ctx.fee;
|
|
1467
|
-
const toL1 = p.to ?? ctx.sender;
|
|
1468
|
-
const iface = new Interface(IBaseToken_default);
|
|
1469
|
-
const data = await wrapAs7(
|
|
1470
|
-
"INTERNAL",
|
|
1471
|
-
OP_WITHDRAWALS.eth.encodeWithdraw,
|
|
1472
|
-
// reuse label for base-token system call
|
|
1473
|
-
() => Promise.resolve(iface.encodeFunctionData("withdraw", [toL1])),
|
|
1474
|
-
{ ctx: { where: "L2BaseToken.withdraw", to: toL1 } }
|
|
1475
|
-
);
|
|
1476
|
-
const tx = {
|
|
1477
|
-
to: L2_BASE_TOKEN_ADDRESS,
|
|
1478
|
-
data,
|
|
1479
|
-
from: ctx.sender,
|
|
1480
|
-
value: p.amount,
|
|
1481
|
-
maxFeePerGas,
|
|
1482
|
-
maxPriorityFeePerGas
|
|
1483
|
-
};
|
|
1484
|
-
if (overrideGasLimit != null) {
|
|
1485
|
-
tx.gasLimit = overrideGasLimit;
|
|
1486
|
-
} else {
|
|
1487
|
-
try {
|
|
1488
|
-
const est = await wrapAs7(
|
|
1489
|
-
"RPC",
|
|
1490
|
-
OP_WITHDRAWALS.eth.estGas,
|
|
1491
|
-
() => ctx.client.l2.estimateGas(tx),
|
|
1492
|
-
{
|
|
1493
|
-
ctx: { where: "l2.estimateGas", to: L2_BASE_TOKEN_ADDRESS },
|
|
1494
|
-
message: "Failed to estimate gas for L2 base-token withdraw."
|
|
1495
|
-
}
|
|
1496
|
-
);
|
|
1497
|
-
tx.gasLimit = BigInt(est) * 115n / 100n;
|
|
1498
|
-
} catch {
|
|
1499
|
-
}
|
|
1500
|
-
}
|
|
1501
|
-
steps.push({
|
|
1502
|
-
key: "l2-base-token:withdraw",
|
|
1503
|
-
kind: "l2-base-token:withdraw",
|
|
1504
|
-
description: "Withdraw base token via L2 Base Token System (base \u2260 ETH)",
|
|
1505
|
-
tx
|
|
1317
|
+
const fees = buildFeeBreakdown2({
|
|
1318
|
+
feeToken: await ctx.client.baseToken(ctx.chainIdL2),
|
|
1319
|
+
l2Gas: withdrawGas
|
|
1506
1320
|
});
|
|
1507
|
-
return { steps, approvals
|
|
1321
|
+
return { steps, approvals, fees };
|
|
1508
1322
|
}
|
|
1509
1323
|
};
|
|
1510
1324
|
}
|
|
1511
|
-
var { wrapAs:
|
|
1325
|
+
var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
|
|
1512
1326
|
var IL1NullifierMini = [
|
|
1513
1327
|
"function isWithdrawalFinalized(uint256,uint256,uint256) view returns (bool)"
|
|
1514
1328
|
];
|
|
@@ -1516,7 +1330,7 @@ function createFinalizationServices(client) {
|
|
|
1516
1330
|
const { l1, l2, signer } = client;
|
|
1517
1331
|
return {
|
|
1518
1332
|
async fetchFinalizeDepositParams(l2TxHash) {
|
|
1519
|
-
const parsed = await
|
|
1333
|
+
const parsed = await wrapAs7(
|
|
1520
1334
|
"RPC",
|
|
1521
1335
|
OP_WITHDRAWALS.finalize.fetchParams.receipt,
|
|
1522
1336
|
() => client.zks.getReceiptWithL2ToL1(l2TxHash),
|
|
@@ -1533,7 +1347,7 @@ function createFinalizationServices(client) {
|
|
|
1533
1347
|
context: { l2TxHash }
|
|
1534
1348
|
});
|
|
1535
1349
|
}
|
|
1536
|
-
const ev = await
|
|
1350
|
+
const ev = await wrapAs7(
|
|
1537
1351
|
"INTERNAL",
|
|
1538
1352
|
OP_WITHDRAWALS.finalize.fetchParams.findMessage,
|
|
1539
1353
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
|
|
@@ -1543,7 +1357,7 @@ function createFinalizationServices(client) {
|
|
|
1543
1357
|
message: "Failed to locate L1MessageSent event in L2 receipt."
|
|
1544
1358
|
}
|
|
1545
1359
|
);
|
|
1546
|
-
const message = await
|
|
1360
|
+
const message = await wrapAs7(
|
|
1547
1361
|
"INTERNAL",
|
|
1548
1362
|
OP_WITHDRAWALS.finalize.fetchParams.decodeMessage,
|
|
1549
1363
|
() => Promise.resolve(AbiCoder.defaultAbiCoder().decode(["bytes"], ev.data)[0]),
|
|
@@ -1552,7 +1366,7 @@ function createFinalizationServices(client) {
|
|
|
1552
1366
|
message: "Failed to decode withdrawal message."
|
|
1553
1367
|
}
|
|
1554
1368
|
);
|
|
1555
|
-
const raw = await
|
|
1369
|
+
const raw = await wrapAs7(
|
|
1556
1370
|
"RPC",
|
|
1557
1371
|
OP_WITHDRAWALS.finalize.fetchParams.rawReceipt,
|
|
1558
1372
|
() => client.zks.getReceiptWithL2ToL1(l2TxHash),
|
|
@@ -1569,7 +1383,7 @@ function createFinalizationServices(client) {
|
|
|
1569
1383
|
context: { l2TxHash }
|
|
1570
1384
|
});
|
|
1571
1385
|
}
|
|
1572
|
-
const idx = await
|
|
1386
|
+
const idx = await wrapAs7(
|
|
1573
1387
|
"INTERNAL",
|
|
1574
1388
|
OP_WITHDRAWALS.finalize.fetchParams.messengerIndex,
|
|
1575
1389
|
() => Promise.resolve(messengerLogIndex(raw, { index: 0, messenger: L1_MESSENGER_ADDRESS })),
|
|
@@ -1578,7 +1392,7 @@ function createFinalizationServices(client) {
|
|
|
1578
1392
|
message: "Failed to derive messenger log index."
|
|
1579
1393
|
}
|
|
1580
1394
|
);
|
|
1581
|
-
const proof = await
|
|
1395
|
+
const proof = await wrapAs7(
|
|
1582
1396
|
"RPC",
|
|
1583
1397
|
OP_WITHDRAWALS.finalize.fetchParams.proof,
|
|
1584
1398
|
() => client.zks.getL2ToL1LogProof(l2TxHash, idx),
|
|
@@ -1587,7 +1401,7 @@ function createFinalizationServices(client) {
|
|
|
1587
1401
|
message: "Failed to fetch L2\u2192L1 log proof."
|
|
1588
1402
|
}
|
|
1589
1403
|
);
|
|
1590
|
-
const { chainId } = await
|
|
1404
|
+
const { chainId } = await wrapAs7(
|
|
1591
1405
|
"RPC",
|
|
1592
1406
|
OP_WITHDRAWALS.finalize.fetchParams.network,
|
|
1593
1407
|
() => l2.getNetwork(),
|
|
@@ -1606,7 +1420,7 @@ function createFinalizationServices(client) {
|
|
|
1606
1420
|
message,
|
|
1607
1421
|
merkleProof: proof.proof
|
|
1608
1422
|
};
|
|
1609
|
-
const { l1Nullifier } = await
|
|
1423
|
+
const { l1Nullifier } = await wrapAs7(
|
|
1610
1424
|
"INTERNAL",
|
|
1611
1425
|
OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
|
|
1612
1426
|
() => client.ensureAddresses(),
|
|
@@ -1618,7 +1432,7 @@ function createFinalizationServices(client) {
|
|
|
1618
1432
|
return { params, nullifier: l1Nullifier };
|
|
1619
1433
|
},
|
|
1620
1434
|
async simulateFinalizeReadiness(params) {
|
|
1621
|
-
const { l1Nullifier } = await
|
|
1435
|
+
const { l1Nullifier } = await wrapAs7(
|
|
1622
1436
|
"INTERNAL",
|
|
1623
1437
|
OP_WITHDRAWALS.finalize.readiness.ensureAddresses,
|
|
1624
1438
|
() => client.ensureAddresses(),
|
|
@@ -1630,7 +1444,7 @@ function createFinalizationServices(client) {
|
|
|
1630
1444
|
const done = await (async () => {
|
|
1631
1445
|
try {
|
|
1632
1446
|
const cMini = new Contract(l1Nullifier, IL1NullifierMini, l1);
|
|
1633
|
-
const isFinalized = await
|
|
1447
|
+
const isFinalized = await wrapAs7(
|
|
1634
1448
|
"RPC",
|
|
1635
1449
|
OP_WITHDRAWALS.finalize.readiness.isFinalized,
|
|
1636
1450
|
() => cMini.isWithdrawalFinalized(
|
|
@@ -1658,7 +1472,7 @@ function createFinalizationServices(client) {
|
|
|
1658
1472
|
}
|
|
1659
1473
|
},
|
|
1660
1474
|
async isWithdrawalFinalized(key) {
|
|
1661
|
-
const { l1Nullifier } = await
|
|
1475
|
+
const { l1Nullifier } = await wrapAs7(
|
|
1662
1476
|
"INTERNAL",
|
|
1663
1477
|
OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
|
|
1664
1478
|
() => client.ensureAddresses(),
|
|
@@ -1668,7 +1482,7 @@ function createFinalizationServices(client) {
|
|
|
1668
1482
|
}
|
|
1669
1483
|
);
|
|
1670
1484
|
const c = new Contract(l1Nullifier, IL1NullifierMini, l1);
|
|
1671
|
-
return await
|
|
1485
|
+
return await wrapAs7(
|
|
1672
1486
|
"RPC",
|
|
1673
1487
|
OP_WITHDRAWALS.finalize.isFinalized,
|
|
1674
1488
|
() => c.isWithdrawalFinalized(key.chainIdL2, key.l2BatchNumber, key.l2MessageIndex),
|
|
@@ -1679,7 +1493,7 @@ function createFinalizationServices(client) {
|
|
|
1679
1493
|
);
|
|
1680
1494
|
},
|
|
1681
1495
|
async estimateFinalization(params) {
|
|
1682
|
-
const { l1Nullifier } = await
|
|
1496
|
+
const { l1Nullifier } = await wrapAs7(
|
|
1683
1497
|
"INTERNAL",
|
|
1684
1498
|
OP_WITHDRAWALS.finalize.estimate,
|
|
1685
1499
|
() => client.ensureAddresses(),
|
|
@@ -1690,7 +1504,7 @@ function createFinalizationServices(client) {
|
|
|
1690
1504
|
);
|
|
1691
1505
|
const signer2 = client.getL1Signer();
|
|
1692
1506
|
const c = new Contract(l1Nullifier, IL1Nullifier_default, signer2);
|
|
1693
|
-
const gasLimit = await
|
|
1507
|
+
const gasLimit = await wrapAs7(
|
|
1694
1508
|
"RPC",
|
|
1695
1509
|
OP_WITHDRAWALS.finalize.estimate,
|
|
1696
1510
|
() => c.finalizeDeposit.estimateGas(params),
|
|
@@ -1705,7 +1519,7 @@ function createFinalizationServices(client) {
|
|
|
1705
1519
|
message: "Failed to estimate gas for finalizeDeposit."
|
|
1706
1520
|
}
|
|
1707
1521
|
);
|
|
1708
|
-
const feeData = await
|
|
1522
|
+
const feeData = await wrapAs7("RPC", OP_WITHDRAWALS.finalize.estimate, () => l1.getFeeData(), {
|
|
1709
1523
|
ctx: { where: "l1.getFeeData" },
|
|
1710
1524
|
message: "Failed to estimate fee data for finalizeDeposit."
|
|
1711
1525
|
});
|
|
@@ -1726,7 +1540,7 @@ function createFinalizationServices(client) {
|
|
|
1726
1540
|
};
|
|
1727
1541
|
},
|
|
1728
1542
|
async finalizeDeposit(params) {
|
|
1729
|
-
const { l1Nullifier } = await
|
|
1543
|
+
const { l1Nullifier } = await wrapAs7(
|
|
1730
1544
|
"INTERNAL",
|
|
1731
1545
|
OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
|
|
1732
1546
|
() => client.ensureAddresses(),
|
|
@@ -1782,10 +1596,8 @@ function createFinalizationServices(client) {
|
|
|
1782
1596
|
|
|
1783
1597
|
// src/adapters/ethers/resources/withdrawals/index.ts
|
|
1784
1598
|
var ROUTES2 = {
|
|
1785
|
-
|
|
1599
|
+
base: routeEthBase(),
|
|
1786
1600
|
// BaseTokenSystem.withdraw, chain base = ETH
|
|
1787
|
-
"eth-nonbase": routeEthNonBase2(),
|
|
1788
|
-
// BaseTokenSystem.withdraw, chain base ≠ ETH
|
|
1789
1601
|
"erc20-nonbase": routeErc20NonBase2()
|
|
1790
1602
|
// AssetRouter.withdraw for non-base ERC-20s
|
|
1791
1603
|
};
|
|
@@ -1795,32 +1607,19 @@ function createWithdrawalsResource(client) {
|
|
|
1795
1607
|
async function buildPlan(p) {
|
|
1796
1608
|
const ctx = await commonCtx2(p, client);
|
|
1797
1609
|
await ROUTES2[ctx.route].preflight?.(p, ctx);
|
|
1798
|
-
const { steps, approvals } = await ROUTES2[ctx.route].build(p, ctx);
|
|
1799
|
-
|
|
1800
|
-
if (ctx.fee.gasLimit != null) return ctx.fee.gasLimit;
|
|
1801
|
-
for (let i = steps.length - 1; i >= 0; i--) {
|
|
1802
|
-
const candidate = steps[i].tx.gasLimit;
|
|
1803
|
-
if (candidate == null) continue;
|
|
1804
|
-
if (typeof candidate === "bigint") return candidate;
|
|
1805
|
-
try {
|
|
1806
|
-
return BigInt(candidate.toString());
|
|
1807
|
-
} catch {
|
|
1808
|
-
}
|
|
1809
|
-
}
|
|
1810
|
-
return void 0;
|
|
1811
|
-
};
|
|
1812
|
-
const gasLimit = resolveGasLimit();
|
|
1813
|
-
const summary = {
|
|
1610
|
+
const { steps, approvals, fees } = await ROUTES2[ctx.route].build(p, ctx);
|
|
1611
|
+
return {
|
|
1814
1612
|
route: ctx.route,
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1613
|
+
summary: {
|
|
1614
|
+
route: ctx.route,
|
|
1615
|
+
approvalsNeeded: approvals,
|
|
1616
|
+
amounts: {
|
|
1617
|
+
transfer: { token: p.token, amount: p.amount }
|
|
1618
|
+
},
|
|
1619
|
+
fees
|
|
1620
|
+
},
|
|
1621
|
+
steps
|
|
1822
1622
|
};
|
|
1823
|
-
return { route: ctx.route, summary, steps };
|
|
1824
1623
|
}
|
|
1825
1624
|
const finalizeCache = /* @__PURE__ */ new Map();
|
|
1826
1625
|
const quote = (p) => wrap2(
|
|
@@ -2184,4 +1983,4 @@ function createEthersSdk(client) {
|
|
|
2184
1983
|
};
|
|
2185
1984
|
}
|
|
2186
1985
|
|
|
2187
|
-
export { buildDirectRequestStruct,
|
|
1986
|
+
export { buildDirectRequestStruct, createDepositsResource, createEthersSdk, createFinalizationServices, createWithdrawalsResource, encodeNTVAssetId, encodeNTVTransferData, encodeNativeTokenVaultAssetId, encodeNativeTokenVaultTransferData, encodeSecondBridgeArgs, encodeSecondBridgeDataV1, encodeSecondBridgeErc20Args, encodeSecondBridgeEthArgs };
|