@matterlabs/zksync-js 0.0.1 → 0.0.3
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 +1279 -925
- package/dist/adapters/ethers/index.cjs.map +1 -1
- package/dist/adapters/ethers/index.d.ts +1 -0
- package/dist/adapters/ethers/index.js +9 -8
- package/dist/adapters/ethers/resources/contracts/contracts.d.ts +9 -0
- package/dist/adapters/ethers/resources/contracts/index.d.ts +2 -0
- package/dist/adapters/ethers/resources/contracts/types.d.ts +60 -0
- package/dist/adapters/ethers/resources/deposits/context.d.ts +21 -7
- package/dist/adapters/ethers/resources/deposits/index.d.ts +3 -1
- 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 +41 -0
- package/dist/adapters/ethers/resources/tokens/index.d.ts +1 -0
- package/dist/adapters/ethers/resources/tokens/tokens.d.ts +10 -0
- package/dist/adapters/ethers/resources/utils.d.ts +3 -17
- package/dist/adapters/ethers/resources/withdrawals/context.d.ts +15 -7
- package/dist/adapters/ethers/resources/withdrawals/index.d.ts +3 -1
- 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 +1388 -1501
- package/dist/adapters/ethers/sdk.cjs.map +1 -1
- package/dist/adapters/ethers/sdk.d.ts +5 -22
- 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 +1233 -744
- package/dist/adapters/viem/index.cjs.map +1 -1
- package/dist/adapters/viem/index.d.ts +3 -0
- package/dist/adapters/viem/index.js +8 -8
- package/dist/adapters/viem/resources/contracts/contracts.d.ts +9 -0
- package/dist/adapters/viem/resources/contracts/index.d.ts +2 -0
- package/dist/adapters/viem/resources/contracts/types.d.ts +61 -0
- package/dist/adapters/viem/resources/deposits/context.d.ts +21 -7
- package/dist/adapters/viem/resources/deposits/index.d.ts +3 -1
- 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 +37 -0
- package/dist/adapters/viem/resources/tokens/index.d.ts +1 -0
- package/dist/adapters/viem/resources/tokens/tokens.d.ts +3 -0
- package/dist/adapters/viem/resources/utils.d.ts +3 -19
- package/dist/adapters/viem/resources/withdrawals/context.d.ts +14 -9
- package/dist/adapters/viem/resources/withdrawals/index.d.ts +3 -1
- 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 +1225 -699
- package/dist/adapters/viem/sdk.cjs.map +1 -1
- package/dist/adapters/viem/sdk.d.ts +5 -25
- package/dist/adapters/viem/sdk.js +6 -6
- package/dist/{chunk-3LALBFFE.js → chunk-3MRGU4HV.js} +9 -5
- package/dist/{chunk-CGO27P7F.js → chunk-5YWP4CZP.js} +849 -835
- package/dist/{chunk-4HLJJKIY.js → chunk-6K6VJQAL.js} +2 -2
- package/dist/{chunk-6GCT6TLS.js → chunk-F2ENUV3A.js} +13 -1
- package/dist/{chunk-7M4V3FMT.js → chunk-JXUFGIJG.js} +986 -678
- package/dist/chunk-LL3WKCFJ.js +231 -0
- package/dist/{chunk-Y75OMFK6.js → chunk-M5J2MM2U.js} +351 -1
- package/dist/{chunk-263G6636.js → chunk-NCAIVYBR.js} +1 -14
- package/dist/{chunk-DI2CJDPZ.js → chunk-NEC2ZKHI.js} +5 -13
- package/dist/chunk-NTEIA5KA.js +13 -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/codec/ntv.d.ts +48 -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 +4508 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +5 -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/token.d.ts +192 -0
- package/dist/core/types/flows/withdrawals.d.ts +12 -6
- package/dist/core/utils/addr.d.ts +2 -0
- package/dist/index.cjs +4520 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -4
- package/package.json +5 -1
- package/dist/adapters/ethers/resources/token-info.d.ts +0 -31
- package/dist/adapters/ethers/resources/withdrawals/routes/eth-nonbase.d.ts +0 -2
- package/dist/adapters/viem/resources/token-info.d.ts +0 -34
- 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
|
@@ -223,35 +223,17 @@ var OP_DEPOSITS = {
|
|
|
223
223
|
assertErc20Asset: "deposits.erc20-base:assertErc20Asset",
|
|
224
224
|
assertMatchesBase: "deposits.erc20-base:assertMatchesBase",
|
|
225
225
|
baseToken: "deposits.erc20-base:baseToken",
|
|
226
|
-
allowance: "deposits.erc20-base:allowance",
|
|
227
|
-
baseCost: "deposits.erc20-base:l2TransactionBaseCost",
|
|
228
|
-
estGas: "deposits.erc20-base:estimateGas"
|
|
229
|
-
},
|
|
226
|
+
allowance: "deposits.erc20-base:allowance"},
|
|
230
227
|
nonbase: {
|
|
231
|
-
baseToken: "deposits.erc20-nonbase:baseToken",
|
|
232
|
-
assertNotEthAsset: "deposits.erc20-nonbase:assertNotEthAsset",
|
|
233
|
-
allowance: "deposits.erc20-nonbase:allowance",
|
|
234
|
-
allowanceFees: "deposits.erc20-nonbase:allowanceFeesBaseToken",
|
|
235
|
-
baseCost: "deposits.erc20-nonbase:l2TransactionBaseCost",
|
|
236
228
|
encodeCalldata: "deposits.erc20-nonbase:encodeSecondBridgeErc20Args",
|
|
237
|
-
estGas: "deposits.erc20-nonbase:estimateGas",
|
|
238
|
-
assertBaseIsEth: "deposits.erc20-nonbase:assertBaseIsEth",
|
|
239
|
-
assertBaseIsErc20: "deposits.erc20-nonbase:assertBaseIsErc20",
|
|
240
229
|
assertNonBaseToken: "deposits.erc20-nonbase:assertNonBaseToken",
|
|
241
230
|
allowanceToken: "deposits.erc20-nonbase:allowanceToken",
|
|
242
231
|
allowanceBase: "deposits.erc20-nonbase:allowanceBase"
|
|
243
232
|
},
|
|
244
|
-
eth: {
|
|
245
|
-
baseCost: "deposits.eth:l2TransactionBaseCost",
|
|
246
|
-
estGas: "deposits.eth:estimateGas"
|
|
247
|
-
},
|
|
248
233
|
ethNonBase: {
|
|
249
|
-
baseToken: "deposits.eth-nonbase:baseToken",
|
|
250
|
-
baseCost: "deposits.eth-nonbase:l2TransactionBaseCost",
|
|
251
234
|
allowanceBase: "deposits.eth-nonbase:allowanceBaseToken",
|
|
252
235
|
ethBalance: "deposits.eth-nonbase:getEthBalance",
|
|
253
236
|
encodeCalldata: "deposits.eth-nonbase:encodeSecondBridgeEthArgs",
|
|
254
|
-
estGas: "deposits.eth-nonbase:estimateGas",
|
|
255
237
|
assertEthAsset: "deposits.eth-nonbase:assertEthAsset",
|
|
256
238
|
assertNonEthBase: "deposits.eth-nonbase:assertNonEthBase",
|
|
257
239
|
assertEthBalance: "deposits.eth-nonbase:assertEthBalance"
|
|
@@ -603,8 +585,12 @@ var TOPIC_L1_MESSAGE_SENT_NEW = k256hex("L1MessageSent(uint256,bytes32,bytes)");
|
|
|
603
585
|
var TOPIC_L1_MESSAGE_SENT_LEG = k256hex("L1MessageSent(address,bytes32,bytes)");
|
|
604
586
|
var TOPIC_CANONICAL_ASSIGNED = "0x779f441679936c5441b671969f37400b8c3ed0071cb47444431bf985754560df";
|
|
605
587
|
var TOPIC_CANONICAL_SUCCESS = "0xe4def01b981193a97a9e81230d7b9f31812ceaf23f864a828a82c687911cb2df";
|
|
606
|
-
var
|
|
607
|
-
var
|
|
588
|
+
var BUFFER = 20n;
|
|
589
|
+
var TX_OVERHEAD_GAS = 10000n;
|
|
590
|
+
var TX_MEMORY_OVERHEAD_GAS = 10n;
|
|
591
|
+
var DEFAULT_PUBDATA_BYTES = 155n;
|
|
592
|
+
var DEFAULT_ABI_BYTES = 400n;
|
|
593
|
+
var SAFE_L1_BRIDGE_GAS = 600000n;
|
|
608
594
|
|
|
609
595
|
// src/core/internal/abis/IBridgehub.ts
|
|
610
596
|
var IBridgehubABI = [
|
|
@@ -5094,7 +5080,183 @@ var MailboxABI = [
|
|
|
5094
5080
|
];
|
|
5095
5081
|
var Mailbox_default = MailboxABI;
|
|
5096
5082
|
|
|
5083
|
+
// src/core/errors/withdrawal-revert-map.ts
|
|
5084
|
+
var REVERT_TO_READINESS = {
|
|
5085
|
+
// Already done
|
|
5086
|
+
WithdrawalAlreadyFinalized: { kind: "FINALIZED" },
|
|
5087
|
+
// Temporary — try later
|
|
5088
|
+
BatchNotExecuted: { kind: "NOT_READY", reason: "batch-not-executed" },
|
|
5089
|
+
LocalRootIsZero: { kind: "NOT_READY", reason: "root-missing" },
|
|
5090
|
+
// Permanent — won’t become ready for this tx
|
|
5091
|
+
WrongL2Sender: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5092
|
+
InvalidSelector: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5093
|
+
L2WithdrawalMessageWrongLength: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5094
|
+
WrongMsgLength: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5095
|
+
TokenNotLegacy: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5096
|
+
TokenIsLegacy: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5097
|
+
InvalidProof: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5098
|
+
InvalidChainId: { kind: "UNFINALIZABLE", reason: "invalid-chain" },
|
|
5099
|
+
NotSettlementLayer: { kind: "UNFINALIZABLE", reason: "settlement-layer" },
|
|
5100
|
+
// Likely environment mismatch — treat as permanent for this tx
|
|
5101
|
+
OnlyEraSupported: { kind: "UNFINALIZABLE", reason: "unsupported" },
|
|
5102
|
+
LocalRootMustBeZero: { kind: "UNFINALIZABLE", reason: "unsupported" }
|
|
5103
|
+
};
|
|
5104
|
+
|
|
5105
|
+
// src/adapters/ethers/errors/revert.ts
|
|
5106
|
+
var ERROR_IFACES = [];
|
|
5107
|
+
var IFACE_ERROR_STRING = new ethers.Interface(["error Error(string)"]);
|
|
5108
|
+
var IFACE_PANIC = new ethers.Interface(["error Panic(uint256)"]);
|
|
5109
|
+
(function bootstrapDefaultIfaces() {
|
|
5110
|
+
try {
|
|
5111
|
+
ERROR_IFACES.push({
|
|
5112
|
+
name: "IL1Nullifier",
|
|
5113
|
+
iface: new ethers.Interface(IL1Nullifier_default)
|
|
5114
|
+
});
|
|
5115
|
+
} catch {
|
|
5116
|
+
}
|
|
5117
|
+
try {
|
|
5118
|
+
ERROR_IFACES.push({ name: "IERC20", iface: new ethers.Interface(IERC20_default) });
|
|
5119
|
+
} catch {
|
|
5120
|
+
}
|
|
5121
|
+
try {
|
|
5122
|
+
ERROR_IFACES.push({
|
|
5123
|
+
name: "IL1NativeTokenVault",
|
|
5124
|
+
iface: new ethers.Interface(L1NativeTokenVault_default)
|
|
5125
|
+
});
|
|
5126
|
+
} catch {
|
|
5127
|
+
}
|
|
5128
|
+
try {
|
|
5129
|
+
ERROR_IFACES.push({
|
|
5130
|
+
name: "IL2NativeTokenVault",
|
|
5131
|
+
iface: new ethers.Interface(L2NativeTokenVault_default)
|
|
5132
|
+
});
|
|
5133
|
+
} catch {
|
|
5134
|
+
}
|
|
5135
|
+
try {
|
|
5136
|
+
ERROR_IFACES.push({ name: "Mailbox", iface: new ethers.Interface(Mailbox_default) });
|
|
5137
|
+
} catch {
|
|
5138
|
+
}
|
|
5139
|
+
})();
|
|
5140
|
+
function registerErrorAbi(name, abi2) {
|
|
5141
|
+
const existing = ERROR_IFACES.findIndex((x) => x.name === name);
|
|
5142
|
+
const entry = { name, iface: new ethers.Interface(abi2) };
|
|
5143
|
+
if (existing >= 0) ERROR_IFACES[existing] = entry;
|
|
5144
|
+
else ERROR_IFACES.push(entry);
|
|
5145
|
+
}
|
|
5146
|
+
function extractRevertData(e) {
|
|
5147
|
+
const maybe = (
|
|
5148
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
5149
|
+
e?.data?.data ?? e?.error?.data ?? e?.data ?? e?.error?.error?.data ?? e?.info?.error?.data
|
|
5150
|
+
);
|
|
5151
|
+
if (typeof maybe === "string" && maybe.startsWith("0x") && maybe.length >= 10) {
|
|
5152
|
+
return maybe;
|
|
5153
|
+
}
|
|
5154
|
+
return void 0;
|
|
5155
|
+
}
|
|
5156
|
+
function decodeRevert(e) {
|
|
5157
|
+
const data = extractRevertData(e);
|
|
5158
|
+
if (!data) return;
|
|
5159
|
+
const selector = `0x${data.slice(2, 10)}`;
|
|
5160
|
+
try {
|
|
5161
|
+
const parsed = IFACE_ERROR_STRING.parseError(data);
|
|
5162
|
+
if (parsed?.name === "Error") {
|
|
5163
|
+
const args = parsed.args ? Array.from(parsed.args) : void 0;
|
|
5164
|
+
return { selector, name: "Error", args };
|
|
5165
|
+
}
|
|
5166
|
+
} catch {
|
|
5167
|
+
}
|
|
5168
|
+
try {
|
|
5169
|
+
const parsed = IFACE_PANIC.parseError(data);
|
|
5170
|
+
if (parsed?.name === "Panic") {
|
|
5171
|
+
const args = parsed.args ? Array.from(parsed.args) : void 0;
|
|
5172
|
+
return { selector, name: "Panic", args };
|
|
5173
|
+
}
|
|
5174
|
+
} catch {
|
|
5175
|
+
}
|
|
5176
|
+
for (const { name, iface } of ERROR_IFACES) {
|
|
5177
|
+
try {
|
|
5178
|
+
const parsed = iface.parseError(data);
|
|
5179
|
+
if (parsed) {
|
|
5180
|
+
const args = parsed.args ? Array.from(parsed.args) : void 0;
|
|
5181
|
+
return {
|
|
5182
|
+
selector,
|
|
5183
|
+
name: parsed.name,
|
|
5184
|
+
args,
|
|
5185
|
+
contract: name
|
|
5186
|
+
};
|
|
5187
|
+
}
|
|
5188
|
+
} catch {
|
|
5189
|
+
}
|
|
5190
|
+
}
|
|
5191
|
+
return { selector };
|
|
5192
|
+
}
|
|
5193
|
+
function classifyReadinessFromRevert(e) {
|
|
5194
|
+
const r = decodeRevert(e);
|
|
5195
|
+
const name = r?.name;
|
|
5196
|
+
if (name && REVERT_TO_READINESS[name]) return REVERT_TO_READINESS[name];
|
|
5197
|
+
const msg = (() => {
|
|
5198
|
+
if (typeof e !== "object" || e === null) return "";
|
|
5199
|
+
const obj = e;
|
|
5200
|
+
const maybeMsg = obj["shortMessage"] ?? obj["message"];
|
|
5201
|
+
return typeof maybeMsg === "string" ? maybeMsg : "";
|
|
5202
|
+
})();
|
|
5203
|
+
const lower = String(msg).toLowerCase();
|
|
5204
|
+
if (lower.includes("paused")) return { kind: "NOT_READY", reason: "paused" };
|
|
5205
|
+
if (name || r?.selector) {
|
|
5206
|
+
return { kind: "UNFINALIZABLE", reason: "unsupported", detail: name ?? r?.selector };
|
|
5207
|
+
}
|
|
5208
|
+
return { kind: "NOT_READY", reason: "unknown", detail: lower || void 0 };
|
|
5209
|
+
}
|
|
5210
|
+
|
|
5211
|
+
// src/adapters/ethers/errors/error-ops.ts
|
|
5212
|
+
function toZKsyncError(type, base, err) {
|
|
5213
|
+
if (isZKsyncError(err)) return err;
|
|
5214
|
+
const revert = decodeRevert(err);
|
|
5215
|
+
return createError(type, { ...base, ...revert ? { revert } : {}, cause: shapeCause(err) });
|
|
5216
|
+
}
|
|
5217
|
+
function resolveMessage(op, msg) {
|
|
5218
|
+
if (!msg) return `Error during ${op}.`;
|
|
5219
|
+
return typeof msg === "function" ? msg() : msg;
|
|
5220
|
+
}
|
|
5221
|
+
function createErrorHandlers(resource) {
|
|
5222
|
+
async function run(kind, operation, fn, opts) {
|
|
5223
|
+
try {
|
|
5224
|
+
return await fn();
|
|
5225
|
+
} catch (e) {
|
|
5226
|
+
if (isZKsyncError(e)) throw e;
|
|
5227
|
+
const message = resolveMessage(operation, opts?.message);
|
|
5228
|
+
throw toZKsyncError(kind, { resource, operation, context: opts?.ctx ?? {}, message }, e);
|
|
5229
|
+
}
|
|
5230
|
+
}
|
|
5231
|
+
function wrap2(operation, fn, opts) {
|
|
5232
|
+
return run("INTERNAL", operation, fn, opts);
|
|
5233
|
+
}
|
|
5234
|
+
function wrapAs10(kind, operation, fn, opts) {
|
|
5235
|
+
return run(kind, operation, fn, opts);
|
|
5236
|
+
}
|
|
5237
|
+
async function toResult2(operation, fn, opts) {
|
|
5238
|
+
try {
|
|
5239
|
+
const value = await wrap2(operation, fn, opts);
|
|
5240
|
+
return { ok: true, value };
|
|
5241
|
+
} catch (e) {
|
|
5242
|
+
const shaped = isZKsyncError(e) ? e : toZKsyncError(
|
|
5243
|
+
"INTERNAL",
|
|
5244
|
+
{
|
|
5245
|
+
resource,
|
|
5246
|
+
operation,
|
|
5247
|
+
context: opts?.ctx ?? {},
|
|
5248
|
+
message: resolveMessage(operation, opts?.message)
|
|
5249
|
+
},
|
|
5250
|
+
e
|
|
5251
|
+
);
|
|
5252
|
+
return { ok: false, error: shaped };
|
|
5253
|
+
}
|
|
5254
|
+
}
|
|
5255
|
+
return { wrap: wrap2, wrapAs: wrapAs10, toResult: toResult2 };
|
|
5256
|
+
}
|
|
5257
|
+
|
|
5097
5258
|
// src/adapters/ethers/client.ts
|
|
5259
|
+
var { wrapAs } = createErrorHandlers("client");
|
|
5098
5260
|
function createEthersClient(args) {
|
|
5099
5261
|
const { l1, l2, signer } = args;
|
|
5100
5262
|
let boundSigner = signer;
|
|
@@ -5192,7 +5354,10 @@ function createEthersClient(args) {
|
|
|
5192
5354
|
async function baseToken(chainId) {
|
|
5193
5355
|
const { bridgehub } = await ensureAddresses();
|
|
5194
5356
|
const bh = new ethers.Contract(bridgehub, IBridgehub_default, l1);
|
|
5195
|
-
return await bh.baseToken(chainId)
|
|
5357
|
+
return await wrapAs("CONTRACT", OP_DEPOSITS.base.baseToken, () => bh.baseToken(chainId), {
|
|
5358
|
+
ctx: { where: "bridgehub.baseToken", chainIdL2: chainId },
|
|
5359
|
+
message: "Failed to read base token."
|
|
5360
|
+
});
|
|
5196
5361
|
}
|
|
5197
5362
|
const client = {
|
|
5198
5363
|
kind: "ethers",
|
|
@@ -5231,6 +5396,8 @@ function normalizeAddrEq(a, b) {
|
|
|
5231
5396
|
};
|
|
5232
5397
|
return normalize(a) === normalize(b);
|
|
5233
5398
|
}
|
|
5399
|
+
var hexEq = (a, b) => a.toLowerCase() === b.toLowerCase();
|
|
5400
|
+
var normalizeL1Token = (token) => isAddressEq(token, FORMAL_ETH_ADDRESS) ? ETH_ADDRESS : token;
|
|
5234
5401
|
|
|
5235
5402
|
// src/adapters/ethers/resources/deposits/services/verification.ts
|
|
5236
5403
|
var I_BRIDGEHUB = new ethers.Interface([
|
|
@@ -5297,119 +5464,66 @@ async function waitForL2ExecutionFromL1Tx(l1, l2, l1TxHash) {
|
|
|
5297
5464
|
return { l2Receipt, l2TxHash };
|
|
5298
5465
|
}
|
|
5299
5466
|
|
|
5300
|
-
// src/
|
|
5301
|
-
function
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5467
|
+
// src/adapters/ethers/resources/deposits/context.ts
|
|
5468
|
+
async function commonCtx(p, client, tokens, contracts) {
|
|
5469
|
+
const { bridgehub, l1AssetRouter } = await contracts.addresses();
|
|
5470
|
+
const { chainId } = await client.l2.getNetwork();
|
|
5471
|
+
const sender = await client.signer.getAddress();
|
|
5472
|
+
const gasPerPubdata = p.gasPerPubdata ?? 800n;
|
|
5473
|
+
const operatorTip = p.operatorTip ?? 0n;
|
|
5474
|
+
const refundRecipient = p.refundRecipient ?? sender;
|
|
5475
|
+
const resolvedToken = await tokens.resolve(p.token, { chain: "l1" });
|
|
5476
|
+
const baseTokenAssetId = resolvedToken.baseTokenAssetId;
|
|
5477
|
+
const baseTokenL1 = await tokens.l1TokenFromAssetId(baseTokenAssetId);
|
|
5478
|
+
const baseIsEth = resolvedToken.isChainEthBased;
|
|
5479
|
+
const route = (() => {
|
|
5480
|
+
if (resolvedToken.kind === "eth") {
|
|
5481
|
+
return baseIsEth ? "eth-base" : "eth-nonbase";
|
|
5482
|
+
}
|
|
5483
|
+
if (resolvedToken.kind === "base") {
|
|
5484
|
+
return baseIsEth ? "eth-base" : "erc20-base";
|
|
5485
|
+
}
|
|
5486
|
+
return "erc20-nonbase";
|
|
5487
|
+
})();
|
|
5488
|
+
return {
|
|
5489
|
+
client,
|
|
5490
|
+
tokens,
|
|
5491
|
+
contracts,
|
|
5492
|
+
resolvedToken,
|
|
5493
|
+
baseTokenAssetId,
|
|
5494
|
+
baseTokenL1,
|
|
5495
|
+
baseIsEth,
|
|
5496
|
+
l1AssetRouter,
|
|
5497
|
+
route,
|
|
5498
|
+
bridgehub,
|
|
5499
|
+
chainIdL2: BigInt(chainId),
|
|
5500
|
+
sender,
|
|
5501
|
+
gasOverrides: p.l1TxOverrides,
|
|
5502
|
+
l2GasLimit: p.l2GasLimit,
|
|
5503
|
+
gasPerPubdata,
|
|
5504
|
+
operatorTip,
|
|
5505
|
+
refundRecipient
|
|
5506
|
+
};
|
|
5324
5507
|
}
|
|
5325
5508
|
function encodeNativeTokenVaultTransferData(amount, receiver, token) {
|
|
5326
5509
|
return new ethers.AbiCoder().encode(["uint256", "address", "address"], [amount, receiver, token]);
|
|
5327
5510
|
}
|
|
5328
5511
|
function encodeSecondBridgeDataV1(assetId, transferData) {
|
|
5329
|
-
const
|
|
5330
|
-
const data =
|
|
5512
|
+
const abi2 = new ethers.AbiCoder();
|
|
5513
|
+
const data = abi2.encode(["bytes32", "bytes"], [assetId, transferData]);
|
|
5331
5514
|
return ethers.ethers.concat(["0x01", data]);
|
|
5332
5515
|
}
|
|
5333
|
-
function
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
[
|
|
5337
|
-
[chainId, L2_NATIVE_TOKEN_VAULT_ADDRESS, address]
|
|
5516
|
+
function encodeSecondBridgeArgs(token, amount, l2Receiver) {
|
|
5517
|
+
return ethers.AbiCoder.defaultAbiCoder().encode(
|
|
5518
|
+
["address", "uint256", "address"],
|
|
5519
|
+
[token, amount, l2Receiver]
|
|
5338
5520
|
);
|
|
5339
|
-
return ethers.ethers.keccak256(hex);
|
|
5340
5521
|
}
|
|
5341
|
-
function
|
|
5342
|
-
return
|
|
5343
|
-
}
|
|
5344
|
-
function scaleGasLimit(gasLimit) {
|
|
5345
|
-
return gasLimit * BigInt(L1_FEE_ESTIMATION_COEF_NUMERATOR) / BigInt(L1_FEE_ESTIMATION_COEF_DENOMINATOR);
|
|
5346
|
-
}
|
|
5347
|
-
async function checkBaseCost(baseCost, value) {
|
|
5348
|
-
const resolvedValue = await value;
|
|
5349
|
-
if (baseCost > resolvedValue) {
|
|
5350
|
-
throw new Error(
|
|
5351
|
-
`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)}!`
|
|
5352
|
-
);
|
|
5353
|
-
}
|
|
5354
|
-
}
|
|
5355
|
-
async function getFeeOverrides(client, overrides) {
|
|
5356
|
-
assertNoLegacyGas(overrides);
|
|
5357
|
-
const fd = await client.l1.getFeeData();
|
|
5358
|
-
const maxFeeFromProvider = fd.maxFeePerGas ?? void 0;
|
|
5359
|
-
const maxPriorityFromProvider = fd.maxPriorityFeePerGas ?? void 0;
|
|
5360
|
-
const gasPriceFallback = fd.gasPrice ?? void 0;
|
|
5361
|
-
const maxFeePerGas = overrides?.maxFeePerGas ?? maxFeeFromProvider ?? gasPriceFallback;
|
|
5362
|
-
if (maxFeePerGas == null) throw new Error("provider returned no gas price data");
|
|
5363
|
-
const maxPriorityFeePerGas = overrides?.maxPriorityFeePerGas ?? maxPriorityFromProvider ?? maxFeePerGas;
|
|
5364
|
-
assertPriorityFeeBounds({ maxFeePerGas, maxPriorityFeePerGas });
|
|
5365
|
-
const gasPriceForBaseCost = overrides?.maxFeePerGas ?? maxFeeFromProvider ?? gasPriceFallback ?? maxFeePerGas;
|
|
5366
|
-
return {
|
|
5367
|
-
gasLimit: overrides?.gasLimit,
|
|
5368
|
-
maxFeePerGas,
|
|
5369
|
-
maxPriorityFeePerGas,
|
|
5370
|
-
gasPriceForBaseCost
|
|
5371
|
-
};
|
|
5372
|
-
}
|
|
5373
|
-
async function getL2FeeOverrides(client, overrides) {
|
|
5374
|
-
assertNoLegacyGas(overrides);
|
|
5375
|
-
let maxFeeFromProvider;
|
|
5376
|
-
let maxPriorityFromProvider;
|
|
5377
|
-
let gasPriceFallback;
|
|
5378
|
-
try {
|
|
5379
|
-
const fd = await client.l2.getFeeData();
|
|
5380
|
-
if (fd?.maxFeePerGas != null) maxFeeFromProvider = fd.maxFeePerGas;
|
|
5381
|
-
if (fd?.maxPriorityFeePerGas != null) {
|
|
5382
|
-
maxPriorityFromProvider = fd.maxPriorityFeePerGas;
|
|
5383
|
-
}
|
|
5384
|
-
if (fd?.gasPrice != null) gasPriceFallback = fd.gasPrice;
|
|
5385
|
-
} catch {
|
|
5386
|
-
}
|
|
5387
|
-
if (gasPriceFallback == null) {
|
|
5388
|
-
try {
|
|
5389
|
-
if (supportsGetGasPrice(client.l2)) {
|
|
5390
|
-
const gp = await client.l2.getGasPrice();
|
|
5391
|
-
gasPriceFallback = typeof gp === "bigint" ? gp : BigInt(gp.toString());
|
|
5392
|
-
}
|
|
5393
|
-
} catch {
|
|
5394
|
-
}
|
|
5395
|
-
}
|
|
5396
|
-
const maxFeePerGas = overrides?.maxFeePerGas ?? maxFeeFromProvider ?? gasPriceFallback;
|
|
5397
|
-
if (maxFeePerGas == null) {
|
|
5398
|
-
throw new Error("L2 provider returned no gas price data");
|
|
5399
|
-
}
|
|
5400
|
-
const maxPriorityFeePerGas = overrides?.maxPriorityFeePerGas ?? maxPriorityFromProvider ?? maxFeePerGas;
|
|
5401
|
-
assertPriorityFeeBounds({ maxFeePerGas, maxPriorityFeePerGas });
|
|
5402
|
-
return {
|
|
5403
|
-
gasLimit: overrides?.gasLimit,
|
|
5404
|
-
maxFeePerGas,
|
|
5405
|
-
maxPriorityFeePerGas
|
|
5406
|
-
};
|
|
5522
|
+
function encodeSecondBridgeErc20Args(token, amount, l2Receiver) {
|
|
5523
|
+
return encodeSecondBridgeArgs(token, amount, l2Receiver);
|
|
5407
5524
|
}
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
if (fd.gasPrice != null) return fd.gasPrice;
|
|
5411
|
-
if (fd.maxFeePerGas != null) return fd.maxFeePerGas;
|
|
5412
|
-
throw new Error("provider returned no gas price data");
|
|
5525
|
+
function encodeSecondBridgeEthArgs(amount, l2Receiver, ethToken = ETH_ADDRESS) {
|
|
5526
|
+
return encodeSecondBridgeArgs(ethToken, amount, l2Receiver);
|
|
5413
5527
|
}
|
|
5414
5528
|
function buildDirectRequestStruct(args) {
|
|
5415
5529
|
return {
|
|
@@ -5424,389 +5538,465 @@ function buildDirectRequestStruct(args) {
|
|
|
5424
5538
|
refundRecipient: args.refundRecipient
|
|
5425
5539
|
};
|
|
5426
5540
|
}
|
|
5427
|
-
function encodeSecondBridgeArgs(token, amount, l2Receiver) {
|
|
5428
|
-
return ethers.AbiCoder.defaultAbiCoder().encode(
|
|
5429
|
-
["address", "uint256", "address"],
|
|
5430
|
-
[token, amount, l2Receiver]
|
|
5431
|
-
);
|
|
5432
|
-
}
|
|
5433
|
-
function encodeSecondBridgeErc20Args(token, amount, l2Receiver) {
|
|
5434
|
-
return encodeSecondBridgeArgs(token, amount, l2Receiver);
|
|
5435
|
-
}
|
|
5436
|
-
function encodeSecondBridgeEthArgs(amount, l2Receiver, ethToken = ETH_ADDRESS) {
|
|
5437
|
-
return encodeSecondBridgeArgs(ethToken, amount, l2Receiver);
|
|
5438
|
-
}
|
|
5439
|
-
|
|
5440
|
-
// src/core/resources/deposits/route.ts
|
|
5441
|
-
async function pickDepositRoute(client, chainIdL2, token) {
|
|
5442
|
-
if (isETH(token)) {
|
|
5443
|
-
const base2 = await client.baseToken(chainIdL2);
|
|
5444
|
-
return isETH(base2) ? "eth-base" : "eth-nonbase";
|
|
5445
|
-
}
|
|
5446
|
-
const base = await client.baseToken(chainIdL2);
|
|
5447
|
-
return normalizeAddrEq(token, base) ? "erc20-base" : "erc20-nonbase";
|
|
5448
|
-
}
|
|
5449
5541
|
|
|
5450
|
-
// src/
|
|
5451
|
-
|
|
5452
|
-
const
|
|
5453
|
-
const { chainId } = await client.l2.getNetwork();
|
|
5454
|
-
const sender = await client.signer.getAddress();
|
|
5455
|
-
const fee = await getFeeOverrides(client, p.l1TxOverrides);
|
|
5456
|
-
const l2GasLimit = p.l2GasLimit ?? 300000n;
|
|
5457
|
-
const gasPerPubdata = p.gasPerPubdata ?? 800n;
|
|
5458
|
-
const operatorTip = p.operatorTip ?? 0n;
|
|
5459
|
-
const refundRecipient = p.refundRecipient ?? sender;
|
|
5460
|
-
const route = await pickDepositRoute(client, BigInt(chainId), p.token);
|
|
5542
|
+
// src/core/resources/deposits/gas.ts
|
|
5543
|
+
function makeGasQuote(p) {
|
|
5544
|
+
const maxPriorityFeePerGas = p.maxPriorityFeePerGas ?? 0n;
|
|
5461
5545
|
return {
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
sender,
|
|
5468
|
-
fee,
|
|
5469
|
-
l2GasLimit,
|
|
5470
|
-
gasPerPubdata,
|
|
5471
|
-
operatorTip,
|
|
5472
|
-
refundRecipient
|
|
5546
|
+
gasLimit: p.gasLimit,
|
|
5547
|
+
maxFeePerGas: p.maxFeePerGas,
|
|
5548
|
+
maxPriorityFeePerGas,
|
|
5549
|
+
gasPerPubdata: p.gasPerPubdata,
|
|
5550
|
+
maxCost: p.gasLimit * p.maxFeePerGas
|
|
5473
5551
|
};
|
|
5474
5552
|
}
|
|
5475
|
-
|
|
5476
|
-
// src/core/errors/withdrawal-revert-map.ts
|
|
5477
|
-
var REVERT_TO_READINESS = {
|
|
5478
|
-
// Already done
|
|
5479
|
-
WithdrawalAlreadyFinalized: { kind: "FINALIZED" },
|
|
5480
|
-
// Temporary — try later
|
|
5481
|
-
BatchNotExecuted: { kind: "NOT_READY", reason: "batch-not-executed" },
|
|
5482
|
-
LocalRootIsZero: { kind: "NOT_READY", reason: "root-missing" },
|
|
5483
|
-
// Permanent — won’t become ready for this tx
|
|
5484
|
-
WrongL2Sender: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5485
|
-
InvalidSelector: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5486
|
-
L2WithdrawalMessageWrongLength: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5487
|
-
WrongMsgLength: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5488
|
-
TokenNotLegacy: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5489
|
-
TokenIsLegacy: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5490
|
-
InvalidProof: { kind: "UNFINALIZABLE", reason: "message-invalid" },
|
|
5491
|
-
InvalidChainId: { kind: "UNFINALIZABLE", reason: "invalid-chain" },
|
|
5492
|
-
NotSettlementLayer: { kind: "UNFINALIZABLE", reason: "settlement-layer" },
|
|
5493
|
-
// Likely environment mismatch — treat as permanent for this tx
|
|
5494
|
-
OnlyEraSupported: { kind: "UNFINALIZABLE", reason: "unsupported" },
|
|
5495
|
-
LocalRootMustBeZero: { kind: "UNFINALIZABLE", reason: "unsupported" }
|
|
5496
|
-
};
|
|
5497
|
-
|
|
5498
|
-
// src/adapters/ethers/errors/revert.ts
|
|
5499
|
-
var ERROR_IFACES = [];
|
|
5500
|
-
var IFACE_ERROR_STRING = new ethers.Interface(["error Error(string)"]);
|
|
5501
|
-
var IFACE_PANIC = new ethers.Interface(["error Panic(uint256)"]);
|
|
5502
|
-
(function bootstrapDefaultIfaces() {
|
|
5553
|
+
async function fetchFees(estimator) {
|
|
5503
5554
|
try {
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5555
|
+
const fees = await estimator.estimateFeesPerGas();
|
|
5556
|
+
if (fees.maxFeePerGas != null) {
|
|
5557
|
+
return {
|
|
5558
|
+
maxFeePerGas: fees.maxFeePerGas,
|
|
5559
|
+
maxPriorityFeePerGas: fees.maxPriorityFeePerGas ?? 0n
|
|
5560
|
+
};
|
|
5561
|
+
}
|
|
5562
|
+
if (fees.gasPrice != null) {
|
|
5563
|
+
return {
|
|
5564
|
+
maxFeePerGas: fees.gasPrice,
|
|
5565
|
+
maxPriorityFeePerGas: 0n
|
|
5566
|
+
};
|
|
5567
|
+
}
|
|
5508
5568
|
} catch {
|
|
5509
5569
|
}
|
|
5510
5570
|
try {
|
|
5511
|
-
|
|
5571
|
+
const gp = await estimator.getGasPrice();
|
|
5572
|
+
return { maxFeePerGas: gp, maxPriorityFeePerGas: 0n };
|
|
5512
5573
|
} catch {
|
|
5574
|
+
return { maxFeePerGas: 0n, maxPriorityFeePerGas: 0n };
|
|
5575
|
+
}
|
|
5576
|
+
}
|
|
5577
|
+
async function quoteL1Gas(input) {
|
|
5578
|
+
const { estimator, tx, overrides, fallbackGasLimit } = input;
|
|
5579
|
+
let market;
|
|
5580
|
+
const getMarket = async () => {
|
|
5581
|
+
if (market) return market;
|
|
5582
|
+
market = await fetchFees(estimator);
|
|
5583
|
+
return market;
|
|
5584
|
+
};
|
|
5585
|
+
const maxFeePerGas = overrides?.maxFeePerGas ?? (tx.maxFeePerGas != null ? BigInt(tx.maxFeePerGas) : (await getMarket()).maxFeePerGas);
|
|
5586
|
+
const maxPriorityFeePerGas = overrides?.maxPriorityFeePerGas ?? (tx.maxPriorityFeePerGas != null ? BigInt(tx.maxPriorityFeePerGas) : (await getMarket()).maxPriorityFeePerGas);
|
|
5587
|
+
const explicitGasLimit = overrides?.gasLimit ?? (tx.gasLimit != null ? BigInt(tx.gasLimit) : void 0);
|
|
5588
|
+
if (explicitGasLimit != null) {
|
|
5589
|
+
return makeGasQuote({ gasLimit: explicitGasLimit, maxFeePerGas, maxPriorityFeePerGas });
|
|
5513
5590
|
}
|
|
5514
5591
|
try {
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5592
|
+
const est = await estimator.estimateGas(tx);
|
|
5593
|
+
const buffered = BigInt(est) * (100n + BUFFER) / 100n;
|
|
5594
|
+
return makeGasQuote({ gasLimit: buffered, maxFeePerGas, maxPriorityFeePerGas });
|
|
5595
|
+
} catch (err) {
|
|
5596
|
+
if (fallbackGasLimit != null) {
|
|
5597
|
+
return makeGasQuote({ gasLimit: fallbackGasLimit, maxFeePerGas, maxPriorityFeePerGas });
|
|
5598
|
+
}
|
|
5599
|
+
console.warn("L1 gas estimation failed", err);
|
|
5600
|
+
return void 0;
|
|
5601
|
+
}
|
|
5602
|
+
}
|
|
5603
|
+
async function quoteL2Gas(input) {
|
|
5604
|
+
const { estimator, route, tx, gasPerPubdata, l2GasLimit, overrideGasLimit, stateOverrides } = input;
|
|
5605
|
+
const market = await fetchFees(estimator);
|
|
5606
|
+
const maxFeePerGas = market.maxFeePerGas || market.maxPriorityFeePerGas || 0n;
|
|
5607
|
+
const txGasLimit = tx?.gasLimit != null ? BigInt(tx.gasLimit) : void 0;
|
|
5608
|
+
const explicit = overrideGasLimit ?? txGasLimit;
|
|
5609
|
+
if (explicit != null) {
|
|
5610
|
+
return makeGasQuote({
|
|
5611
|
+
gasLimit: explicit,
|
|
5612
|
+
maxFeePerGas,
|
|
5613
|
+
gasPerPubdata
|
|
5518
5614
|
});
|
|
5519
|
-
} catch {
|
|
5520
5615
|
}
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5616
|
+
if (!tx) {
|
|
5617
|
+
return makeGasQuote({
|
|
5618
|
+
gasLimit: l2GasLimit ?? 0n,
|
|
5619
|
+
maxFeePerGas,
|
|
5620
|
+
gasPerPubdata
|
|
5525
5621
|
});
|
|
5526
|
-
} catch {
|
|
5527
5622
|
}
|
|
5528
5623
|
try {
|
|
5529
|
-
|
|
5530
|
-
|
|
5624
|
+
const execEstimate = await estimator.estimateGas(tx, stateOverrides);
|
|
5625
|
+
const memoryBytes = route === "erc20-nonbase" ? 500n : DEFAULT_ABI_BYTES;
|
|
5626
|
+
const pubdataBytes = route === "erc20-nonbase" ? 200n : DEFAULT_PUBDATA_BYTES;
|
|
5627
|
+
const pp = gasPerPubdata ?? 800n;
|
|
5628
|
+
const memoryOverhead = memoryBytes * TX_MEMORY_OVERHEAD_GAS;
|
|
5629
|
+
const pubdataOverhead = pubdataBytes * pp;
|
|
5630
|
+
let total = BigInt(execEstimate) + TX_OVERHEAD_GAS + memoryOverhead + pubdataOverhead;
|
|
5631
|
+
total = total * (100n + BUFFER) / 100n;
|
|
5632
|
+
return makeGasQuote({
|
|
5633
|
+
gasLimit: total,
|
|
5634
|
+
maxFeePerGas,
|
|
5635
|
+
gasPerPubdata: pp
|
|
5636
|
+
});
|
|
5637
|
+
} catch (err) {
|
|
5638
|
+
console.warn("L2 gas estimation failed", err);
|
|
5639
|
+
return makeGasQuote({
|
|
5640
|
+
gasLimit: l2GasLimit ?? 0n,
|
|
5641
|
+
maxFeePerGas,
|
|
5642
|
+
gasPerPubdata
|
|
5643
|
+
});
|
|
5531
5644
|
}
|
|
5532
|
-
})();
|
|
5533
|
-
function registerErrorAbi(name, abi) {
|
|
5534
|
-
const existing = ERROR_IFACES.findIndex((x) => x.name === name);
|
|
5535
|
-
const entry = { name, iface: new ethers.Interface(abi) };
|
|
5536
|
-
if (existing >= 0) ERROR_IFACES[existing] = entry;
|
|
5537
|
-
else ERROR_IFACES.push(entry);
|
|
5538
5645
|
}
|
|
5539
|
-
function
|
|
5540
|
-
const
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
)
|
|
5544
|
-
|
|
5545
|
-
return maybe;
|
|
5646
|
+
async function quoteL2BaseCost(input) {
|
|
5647
|
+
const { estimator, encode: encode2, bridgehub, chainIdL2, l2GasLimit, gasPerPubdata } = input;
|
|
5648
|
+
const market = await fetchFees(estimator);
|
|
5649
|
+
const l1GasPrice = market.maxFeePerGas || market.maxPriorityFeePerGas || 0n;
|
|
5650
|
+
if (l1GasPrice === 0n) {
|
|
5651
|
+
throw new Error("Could not fetch L1 gas price for Bridgehub base cost calculation.");
|
|
5546
5652
|
}
|
|
5547
|
-
|
|
5653
|
+
const data = encode2(IBridgehub_default, "l2TransactionBaseCost", [
|
|
5654
|
+
chainIdL2,
|
|
5655
|
+
l1GasPrice,
|
|
5656
|
+
l2GasLimit,
|
|
5657
|
+
gasPerPubdata
|
|
5658
|
+
]);
|
|
5659
|
+
const raw = await estimator.call({
|
|
5660
|
+
to: bridgehub,
|
|
5661
|
+
data
|
|
5662
|
+
});
|
|
5663
|
+
return BigInt(raw);
|
|
5548
5664
|
}
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
}
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5665
|
+
|
|
5666
|
+
// src/adapters/ethers/estimator.ts
|
|
5667
|
+
function toCoreTx(tx) {
|
|
5668
|
+
return {
|
|
5669
|
+
to: tx.to,
|
|
5670
|
+
from: tx.from,
|
|
5671
|
+
data: tx.data,
|
|
5672
|
+
value: tx.value ? BigInt(tx.value) : void 0,
|
|
5673
|
+
gasLimit: tx.gasLimit ? BigInt(tx.gasLimit) : void 0,
|
|
5674
|
+
maxFeePerGas: tx.maxFeePerGas ? BigInt(tx.maxFeePerGas) : void 0,
|
|
5675
|
+
maxPriorityFeePerGas: tx.maxPriorityFeePerGas ? BigInt(tx.maxPriorityFeePerGas) : void 0
|
|
5676
|
+
};
|
|
5677
|
+
}
|
|
5678
|
+
function ethersToGasEstimator(provider) {
|
|
5679
|
+
return {
|
|
5680
|
+
async estimateGas(tx, stateOverrides) {
|
|
5681
|
+
const ethTx = {
|
|
5682
|
+
to: tx.to,
|
|
5683
|
+
from: tx.from,
|
|
5684
|
+
data: tx.data,
|
|
5685
|
+
value: tx.value,
|
|
5686
|
+
gasLimit: tx.gasLimit,
|
|
5687
|
+
maxFeePerGas: tx.maxFeePerGas,
|
|
5688
|
+
maxPriorityFeePerGas: tx.maxPriorityFeePerGas
|
|
5689
|
+
};
|
|
5690
|
+
if (stateOverrides && "send" in provider) {
|
|
5691
|
+
try {
|
|
5692
|
+
const jsonRpcProvider = provider;
|
|
5693
|
+
const result = await jsonRpcProvider.send("eth_estimateGas", [
|
|
5694
|
+
ethTx,
|
|
5695
|
+
"latest",
|
|
5696
|
+
stateOverrides
|
|
5697
|
+
]);
|
|
5698
|
+
return BigInt(result);
|
|
5699
|
+
} catch (error) {
|
|
5700
|
+
console.warn(
|
|
5701
|
+
"Failed to estimate gas with state overrides, falling back to standard estimation:",
|
|
5702
|
+
error
|
|
5703
|
+
);
|
|
5704
|
+
}
|
|
5705
|
+
} else if (stateOverrides) {
|
|
5706
|
+
console.warn('Provider does not support "send", skipping state overrides estimation.');
|
|
5580
5707
|
}
|
|
5581
|
-
|
|
5708
|
+
return await provider.estimateGas(ethTx);
|
|
5709
|
+
},
|
|
5710
|
+
async estimateFeesPerGas() {
|
|
5711
|
+
const fd = await provider.getFeeData();
|
|
5712
|
+
return {
|
|
5713
|
+
maxFeePerGas: fd.maxFeePerGas != null ? BigInt(fd.maxFeePerGas) : void 0,
|
|
5714
|
+
maxPriorityFeePerGas: fd.maxPriorityFeePerGas != null ? BigInt(fd.maxPriorityFeePerGas) : void 0,
|
|
5715
|
+
gasPrice: fd.gasPrice != null ? BigInt(fd.gasPrice) : void 0
|
|
5716
|
+
};
|
|
5717
|
+
},
|
|
5718
|
+
async getGasPrice() {
|
|
5719
|
+
const fd = await provider.getFeeData();
|
|
5720
|
+
if (fd.gasPrice != null) return BigInt(fd.gasPrice);
|
|
5721
|
+
throw new Error("Could not fetch gas price");
|
|
5722
|
+
},
|
|
5723
|
+
async call(tx) {
|
|
5724
|
+
const ethTx = {
|
|
5725
|
+
to: tx.to,
|
|
5726
|
+
data: tx.data,
|
|
5727
|
+
value: tx.value,
|
|
5728
|
+
from: tx.from
|
|
5729
|
+
};
|
|
5730
|
+
return await provider.call(ethTx);
|
|
5582
5731
|
}
|
|
5583
|
-
}
|
|
5584
|
-
return { selector };
|
|
5732
|
+
};
|
|
5585
5733
|
}
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5734
|
+
|
|
5735
|
+
// src/adapters/ethers/resources/deposits/services/fee.ts
|
|
5736
|
+
var { wrapAs: wrapAs2 } = createErrorHandlers("deposits");
|
|
5737
|
+
var encode = (abi2, fn, args) => {
|
|
5738
|
+
return new ethers.Interface(abi2).encodeFunctionData(fn, args);
|
|
5739
|
+
};
|
|
5740
|
+
async function quoteL2BaseCost2(input) {
|
|
5741
|
+
const { ctx, l2GasLimit } = input;
|
|
5742
|
+
const estimator = ethersToGasEstimator(ctx.client.l1);
|
|
5743
|
+
return wrapAs2(
|
|
5744
|
+
"RPC",
|
|
5745
|
+
"deposits.fees.l2BaseCost",
|
|
5746
|
+
() => quoteL2BaseCost({
|
|
5747
|
+
estimator,
|
|
5748
|
+
encode,
|
|
5749
|
+
bridgehub: ctx.bridgehub,
|
|
5750
|
+
chainIdL2: ctx.chainIdL2,
|
|
5751
|
+
l2GasLimit,
|
|
5752
|
+
gasPerPubdata: ctx.gasPerPubdata
|
|
5753
|
+
}),
|
|
5754
|
+
{ ctx: { chainIdL2: ctx.chainIdL2 } }
|
|
5755
|
+
);
|
|
5602
5756
|
}
|
|
5603
5757
|
|
|
5604
|
-
// src/adapters/ethers/
|
|
5605
|
-
function
|
|
5606
|
-
|
|
5607
|
-
const
|
|
5608
|
-
return
|
|
5758
|
+
// src/adapters/ethers/resources/deposits/services/gas.ts
|
|
5759
|
+
async function quoteL1Gas2(input) {
|
|
5760
|
+
const { ctx, tx, overrides, fallbackGasLimit } = input;
|
|
5761
|
+
const estimator = ethersToGasEstimator(ctx.client.l1);
|
|
5762
|
+
return quoteL1Gas({
|
|
5763
|
+
estimator,
|
|
5764
|
+
tx: toCoreTx(tx),
|
|
5765
|
+
overrides,
|
|
5766
|
+
fallbackGasLimit
|
|
5767
|
+
});
|
|
5609
5768
|
}
|
|
5610
|
-
function
|
|
5611
|
-
|
|
5612
|
-
|
|
5769
|
+
async function quoteL2Gas2(input) {
|
|
5770
|
+
const { ctx, route, l2TxForModeling, overrideGasLimit } = input;
|
|
5771
|
+
const estimator = ethersToGasEstimator(ctx.client.l2);
|
|
5772
|
+
return quoteL2Gas({
|
|
5773
|
+
estimator,
|
|
5774
|
+
route,
|
|
5775
|
+
tx: l2TxForModeling ? toCoreTx(l2TxForModeling) : void 0,
|
|
5776
|
+
gasPerPubdata: ctx.gasPerPubdata,
|
|
5777
|
+
l2GasLimit: ctx.l2GasLimit,
|
|
5778
|
+
overrideGasLimit,
|
|
5779
|
+
stateOverrides: input.stateOverrides
|
|
5780
|
+
});
|
|
5613
5781
|
}
|
|
5614
|
-
function
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
}
|
|
5623
|
-
}
|
|
5624
|
-
function wrap2(operation, fn, opts) {
|
|
5625
|
-
return run("INTERNAL", operation, fn, opts);
|
|
5626
|
-
}
|
|
5627
|
-
function wrapAs9(kind, operation, fn, opts) {
|
|
5628
|
-
return run(kind, operation, fn, opts);
|
|
5782
|
+
async function determineErc20L2Gas(input) {
|
|
5783
|
+
const { ctx, l1Token } = input;
|
|
5784
|
+
const DEFAULT_SAFE_L2_GAS_LIMIT = 3000000n;
|
|
5785
|
+
if (ctx.l2GasLimit != null) {
|
|
5786
|
+
return quoteL2Gas2({
|
|
5787
|
+
ctx,
|
|
5788
|
+
route: "erc20-nonbase",
|
|
5789
|
+
overrideGasLimit: ctx.l2GasLimit
|
|
5790
|
+
});
|
|
5629
5791
|
}
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
return {
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
resource,
|
|
5639
|
-
operation,
|
|
5640
|
-
context: opts?.ctx ?? {},
|
|
5641
|
-
message: resolveMessage(operation, opts?.message)
|
|
5642
|
-
},
|
|
5643
|
-
e
|
|
5644
|
-
);
|
|
5645
|
-
return { ok: false, error: shaped };
|
|
5792
|
+
try {
|
|
5793
|
+
const l2TokenAddress = ctx.tokens ? await ctx.tokens.toL2Address(l1Token) : await (await ctx.contracts.l2NativeTokenVault()).l2TokenAddress(l1Token);
|
|
5794
|
+
if (l2TokenAddress === "0x0000000000000000000000000000000000000000") {
|
|
5795
|
+
return quoteL2Gas2({
|
|
5796
|
+
ctx,
|
|
5797
|
+
route: "erc20-nonbase",
|
|
5798
|
+
overrideGasLimit: DEFAULT_SAFE_L2_GAS_LIMIT
|
|
5799
|
+
});
|
|
5646
5800
|
}
|
|
5801
|
+
const modelTx = {
|
|
5802
|
+
to: input.modelTx?.to ?? ctx.sender,
|
|
5803
|
+
from: input.modelTx?.from ?? ctx.sender,
|
|
5804
|
+
data: input.modelTx?.data ?? "0x",
|
|
5805
|
+
value: input.modelTx?.value ?? 0n
|
|
5806
|
+
};
|
|
5807
|
+
const gas = await quoteL2Gas2({
|
|
5808
|
+
ctx,
|
|
5809
|
+
route: "erc20-nonbase",
|
|
5810
|
+
l2TxForModeling: modelTx
|
|
5811
|
+
});
|
|
5812
|
+
if (!gas) {
|
|
5813
|
+
return quoteL2Gas2({
|
|
5814
|
+
ctx,
|
|
5815
|
+
route: "erc20-nonbase",
|
|
5816
|
+
overrideGasLimit: DEFAULT_SAFE_L2_GAS_LIMIT
|
|
5817
|
+
});
|
|
5818
|
+
}
|
|
5819
|
+
return gas;
|
|
5820
|
+
} catch (err) {
|
|
5821
|
+
console.warn("Failed to determine ERC20 L2 gas; defaulting to safe gas limit.", err);
|
|
5822
|
+
return quoteL2Gas2({
|
|
5823
|
+
ctx,
|
|
5824
|
+
route: "erc20-nonbase",
|
|
5825
|
+
overrideGasLimit: DEFAULT_SAFE_L2_GAS_LIMIT
|
|
5826
|
+
});
|
|
5647
5827
|
}
|
|
5648
|
-
|
|
5828
|
+
}
|
|
5829
|
+
|
|
5830
|
+
// src/core/resources/deposits/fee.ts
|
|
5831
|
+
function buildFeeBreakdown(p) {
|
|
5832
|
+
const l1MaxTotal = p.l1Gas?.maxCost ?? 0n;
|
|
5833
|
+
const l2Total = p.l2BaseCost + p.operatorTip;
|
|
5834
|
+
const l1 = {
|
|
5835
|
+
gasLimit: p.l1Gas?.gasLimit ?? 0n,
|
|
5836
|
+
maxFeePerGas: p.l1Gas?.maxFeePerGas ?? 0n,
|
|
5837
|
+
maxPriorityFeePerGas: p.l1Gas?.maxPriorityFeePerGas,
|
|
5838
|
+
maxTotal: l1MaxTotal
|
|
5839
|
+
};
|
|
5840
|
+
const l2 = {
|
|
5841
|
+
total: l2Total,
|
|
5842
|
+
baseCost: p.l2BaseCost,
|
|
5843
|
+
operatorTip: p.operatorTip,
|
|
5844
|
+
gasLimit: p.l2Gas?.gasLimit ?? 0n,
|
|
5845
|
+
maxFeePerGas: p.l2Gas?.maxFeePerGas ?? 0n,
|
|
5846
|
+
maxPriorityFeePerGas: p.l2Gas?.maxPriorityFeePerGas,
|
|
5847
|
+
gasPerPubdata: p.l2Gas?.gasPerPubdata ?? 0n
|
|
5848
|
+
};
|
|
5849
|
+
return {
|
|
5850
|
+
token: p.feeToken,
|
|
5851
|
+
maxTotal: l1MaxTotal + l2Total,
|
|
5852
|
+
mintValue: p.mintValue,
|
|
5853
|
+
l1,
|
|
5854
|
+
l2
|
|
5855
|
+
};
|
|
5649
5856
|
}
|
|
5650
5857
|
|
|
5651
5858
|
// src/adapters/ethers/resources/deposits/routes/eth.ts
|
|
5652
|
-
var { wrapAs } = createErrorHandlers("deposits");
|
|
5653
5859
|
function routeEthDirect() {
|
|
5654
5860
|
return {
|
|
5655
5861
|
async build(p, ctx) {
|
|
5656
|
-
const bh =
|
|
5657
|
-
const
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5862
|
+
const bh = await ctx.contracts.bridgehub();
|
|
5863
|
+
const l2TxModel = {
|
|
5864
|
+
to: p.to ?? ctx.sender,
|
|
5865
|
+
from: ctx.sender,
|
|
5866
|
+
data: "0x",
|
|
5867
|
+
value: 0n
|
|
5868
|
+
};
|
|
5869
|
+
const l2GasParams = await quoteL2Gas2({
|
|
5870
|
+
ctx,
|
|
5871
|
+
route: "eth-base",
|
|
5872
|
+
l2TxForModeling: l2TxModel,
|
|
5873
|
+
overrideGasLimit: ctx.l2GasLimit,
|
|
5874
|
+
stateOverrides: {
|
|
5875
|
+
[ctx.sender]: {
|
|
5876
|
+
balance: "0xffffffffffffffffffff"
|
|
5877
|
+
}
|
|
5670
5878
|
}
|
|
5671
|
-
);
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
const
|
|
5879
|
+
});
|
|
5880
|
+
if (!l2GasParams) {
|
|
5881
|
+
throw new Error("Failed to estimate L2 gas for deposit.");
|
|
5882
|
+
}
|
|
5883
|
+
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
5884
|
+
const mintValue = baseCost + ctx.operatorTip + p.amount;
|
|
5676
5885
|
const req = buildDirectRequestStruct({
|
|
5677
5886
|
chainId: ctx.chainIdL2,
|
|
5678
5887
|
mintValue,
|
|
5679
|
-
l2GasLimit:
|
|
5888
|
+
l2GasLimit: l2GasParams.gasLimit,
|
|
5680
5889
|
gasPerPubdata: ctx.gasPerPubdata,
|
|
5681
5890
|
refundRecipient: ctx.refundRecipient,
|
|
5682
|
-
l2Contract,
|
|
5683
|
-
l2Value
|
|
5891
|
+
l2Contract: p.to ?? ctx.sender,
|
|
5892
|
+
l2Value: p.amount
|
|
5684
5893
|
});
|
|
5685
5894
|
const data = bh.interface.encodeFunctionData("requestL2TransactionDirect", [req]);
|
|
5686
|
-
|
|
5687
|
-
const tx = {
|
|
5895
|
+
const l1TxCandidate = {
|
|
5688
5896
|
to: ctx.bridgehub,
|
|
5689
5897
|
data,
|
|
5690
5898
|
value: mintValue,
|
|
5691
5899
|
from: ctx.sender,
|
|
5692
|
-
...
|
|
5900
|
+
...ctx.gasOverrides
|
|
5693
5901
|
};
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
{
|
|
5704
|
-
ctx: { where: "l1.estimateGas", to: ctx.bridgehub },
|
|
5705
|
-
message: "Failed to estimate gas for Bridgehub request."
|
|
5706
|
-
}
|
|
5707
|
-
);
|
|
5708
|
-
const buffered = BigInt(est) * 115n / 100n;
|
|
5709
|
-
tx.gasLimit = buffered;
|
|
5710
|
-
resolvedL1GasLimit = buffered;
|
|
5711
|
-
} catch {
|
|
5712
|
-
}
|
|
5902
|
+
const l1GasParams = await quoteL1Gas2({
|
|
5903
|
+
ctx,
|
|
5904
|
+
tx: l1TxCandidate,
|
|
5905
|
+
overrides: ctx.gasOverrides
|
|
5906
|
+
});
|
|
5907
|
+
if (l1GasParams) {
|
|
5908
|
+
l1TxCandidate.gasLimit = l1GasParams.gasLimit;
|
|
5909
|
+
l1TxCandidate.maxFeePerGas = l1GasParams.maxFeePerGas;
|
|
5910
|
+
l1TxCandidate.maxPriorityFeePerGas = l1GasParams.maxPriorityFeePerGas;
|
|
5713
5911
|
}
|
|
5714
5912
|
const steps = [
|
|
5715
5913
|
{
|
|
5716
5914
|
key: "bridgehub:direct",
|
|
5717
5915
|
kind: "bridgehub:direct",
|
|
5718
5916
|
description: "Bridge ETH via Bridgehub.requestL2TransactionDirect",
|
|
5719
|
-
tx
|
|
5917
|
+
tx: l1TxCandidate
|
|
5720
5918
|
}
|
|
5721
5919
|
];
|
|
5920
|
+
const fees = buildFeeBreakdown({
|
|
5921
|
+
feeToken: ETH_ADDRESS,
|
|
5922
|
+
l1Gas: l1GasParams,
|
|
5923
|
+
l2Gas: l2GasParams,
|
|
5924
|
+
l2BaseCost: baseCost,
|
|
5925
|
+
operatorTip: ctx.operatorTip,
|
|
5926
|
+
mintValue
|
|
5927
|
+
});
|
|
5722
5928
|
return {
|
|
5723
5929
|
steps,
|
|
5724
5930
|
approvals: [],
|
|
5725
|
-
|
|
5931
|
+
fees
|
|
5726
5932
|
};
|
|
5727
5933
|
}
|
|
5728
5934
|
};
|
|
5729
5935
|
}
|
|
5730
|
-
var { wrapAs:
|
|
5731
|
-
var MIN_L2_GAS_FOR_ERC20 = 2500000n;
|
|
5936
|
+
var { wrapAs: wrapAs3 } = createErrorHandlers("deposits");
|
|
5732
5937
|
function routeErc20NonBase() {
|
|
5733
5938
|
return {
|
|
5734
|
-
async preflight() {
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
const assetRouter = ctx.l1AssetRouter;
|
|
5739
|
-
const { gasPriceForBaseCost, gasLimit: overrideGasLimit, ...txFeeOverrides } = ctx.fee;
|
|
5740
|
-
const txOverrides = overrideGasLimit != null ? { ...txFeeOverrides, gasLimit: overrideGasLimit } : txFeeOverrides;
|
|
5741
|
-
let resolvedL1GasLimit = overrideGasLimit ?? ctx.l2GasLimit;
|
|
5742
|
-
const baseToken = await wrapAs2(
|
|
5743
|
-
"CONTRACT",
|
|
5744
|
-
OP_DEPOSITS.nonbase.baseToken,
|
|
5745
|
-
() => bh.baseToken(ctx.chainIdL2),
|
|
5746
|
-
{
|
|
5747
|
-
ctx: { where: "bridgehub.baseToken", chainIdL2: ctx.chainIdL2 },
|
|
5748
|
-
message: "Failed to read base token."
|
|
5749
|
-
}
|
|
5750
|
-
);
|
|
5751
|
-
await wrapAs2(
|
|
5939
|
+
async preflight(p, ctx) {
|
|
5940
|
+
const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l1" }) : void 0);
|
|
5941
|
+
const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
|
|
5942
|
+
await wrapAs3(
|
|
5752
5943
|
"VALIDATION",
|
|
5753
5944
|
OP_DEPOSITS.nonbase.assertNonBaseToken,
|
|
5754
5945
|
() => {
|
|
5755
|
-
if (
|
|
5946
|
+
if (resolved?.kind === "base" || resolved?.kind === "eth") {
|
|
5756
5947
|
throw new Error("erc20-nonbase route requires a non-base ERC-20 deposit token.");
|
|
5757
5948
|
}
|
|
5758
5949
|
},
|
|
5759
5950
|
{ ctx: { depositToken: p.token, baseToken } }
|
|
5760
5951
|
);
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5952
|
+
},
|
|
5953
|
+
async build(p, ctx) {
|
|
5954
|
+
const l1Signer = ctx.client.getL1Signer();
|
|
5955
|
+
const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
|
|
5956
|
+
const baseIsEth = ctx.baseIsEth ?? isETH(baseToken);
|
|
5957
|
+
const l2GasParams = await determineErc20L2Gas({
|
|
5958
|
+
ctx,
|
|
5959
|
+
l1Token: p.token,
|
|
5960
|
+
modelTx: {
|
|
5961
|
+
to: p.to ?? ctx.sender,
|
|
5962
|
+
from: ctx.sender,
|
|
5963
|
+
data: "0x",
|
|
5964
|
+
value: 0n
|
|
5774
5965
|
}
|
|
5775
|
-
);
|
|
5776
|
-
|
|
5966
|
+
});
|
|
5967
|
+
if (!l2GasParams) throw new Error("Failed to establish L2 gas parameters.");
|
|
5968
|
+
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
5777
5969
|
const mintValue = baseCost + ctx.operatorTip;
|
|
5778
5970
|
const approvals = [];
|
|
5779
5971
|
const steps = [];
|
|
5780
|
-
const
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
{
|
|
5788
|
-
|
|
5789
|
-
message: "Failed to read deposit-token allowance."
|
|
5790
|
-
}
|
|
5791
|
-
);
|
|
5792
|
-
if (allowanceToken < p.amount) {
|
|
5793
|
-
approvals.push({ token: p.token, spender: assetRouter, amount: p.amount });
|
|
5794
|
-
const data = erc20Deposit.interface.encodeFunctionData("approve", [
|
|
5795
|
-
assetRouter,
|
|
5796
|
-
p.amount
|
|
5797
|
-
]);
|
|
5798
|
-
steps.push({
|
|
5799
|
-
key: `approve:${p.token}:${assetRouter}`,
|
|
5800
|
-
kind: "approve",
|
|
5801
|
-
description: `Approve ${p.amount} for router (deposit token)`,
|
|
5802
|
-
tx: { to: p.token, data, from: ctx.sender, ...txOverrides }
|
|
5803
|
-
});
|
|
5972
|
+
const assetRouter = ctx.l1AssetRouter;
|
|
5973
|
+
const erc20Deposit = new ethers.Contract(p.token, IERC20_default, l1Signer);
|
|
5974
|
+
const allowanceToken = await wrapAs3(
|
|
5975
|
+
"RPC",
|
|
5976
|
+
OP_DEPOSITS.nonbase.allowanceToken,
|
|
5977
|
+
() => erc20Deposit.allowance(ctx.sender, assetRouter),
|
|
5978
|
+
{
|
|
5979
|
+
ctx: { where: "erc20.allowance", token: p.token, spender: assetRouter },
|
|
5980
|
+
message: "Failed to read deposit-token allowance."
|
|
5804
5981
|
}
|
|
5982
|
+
);
|
|
5983
|
+
if (allowanceToken < p.amount) {
|
|
5984
|
+
approvals.push({ token: p.token, spender: assetRouter, amount: p.amount });
|
|
5985
|
+
steps.push({
|
|
5986
|
+
key: `approve:${p.token}:${assetRouter}`,
|
|
5987
|
+
kind: "approve",
|
|
5988
|
+
description: `Approve ${p.amount} for router (deposit token)`,
|
|
5989
|
+
tx: {
|
|
5990
|
+
to: p.token,
|
|
5991
|
+
data: erc20Deposit.interface.encodeFunctionData("approve", [assetRouter, p.amount]),
|
|
5992
|
+
from: ctx.sender,
|
|
5993
|
+
...ctx.gasOverrides
|
|
5994
|
+
}
|
|
5995
|
+
});
|
|
5805
5996
|
}
|
|
5806
|
-
const baseIsEth = isETH(baseToken);
|
|
5807
5997
|
if (!baseIsEth) {
|
|
5808
5998
|
const erc20Base = new ethers.Contract(baseToken, IERC20_default, l1Signer);
|
|
5809
|
-
const allowanceBase = await
|
|
5999
|
+
const allowanceBase = await wrapAs3(
|
|
5810
6000
|
"RPC",
|
|
5811
6001
|
OP_DEPOSITS.nonbase.allowanceBase,
|
|
5812
6002
|
() => erc20Base.allowance(ctx.sender, assetRouter),
|
|
@@ -5817,16 +6007,20 @@ function routeErc20NonBase() {
|
|
|
5817
6007
|
);
|
|
5818
6008
|
if (allowanceBase < mintValue) {
|
|
5819
6009
|
approvals.push({ token: baseToken, spender: assetRouter, amount: mintValue });
|
|
5820
|
-
const data = erc20Base.interface.encodeFunctionData("approve", [assetRouter, mintValue]);
|
|
5821
6010
|
steps.push({
|
|
5822
6011
|
key: `approve:${baseToken}:${assetRouter}`,
|
|
5823
6012
|
kind: "approve",
|
|
5824
6013
|
description: `Approve base token for mintValue`,
|
|
5825
|
-
tx: {
|
|
6014
|
+
tx: {
|
|
6015
|
+
to: baseToken,
|
|
6016
|
+
data: erc20Base.interface.encodeFunctionData("approve", [assetRouter, mintValue]),
|
|
6017
|
+
from: ctx.sender,
|
|
6018
|
+
...ctx.gasOverrides
|
|
6019
|
+
}
|
|
5826
6020
|
});
|
|
5827
6021
|
}
|
|
5828
6022
|
}
|
|
5829
|
-
const secondBridgeCalldata = await
|
|
6023
|
+
const secondBridgeCalldata = await wrapAs3(
|
|
5830
6024
|
"INTERNAL",
|
|
5831
6025
|
OP_DEPOSITS.nonbase.encodeCalldata,
|
|
5832
6026
|
() => Promise.resolve(encodeSecondBridgeErc20Args(p.token, p.amount, p.to ?? ctx.sender)),
|
|
@@ -5835,98 +6029,88 @@ function routeErc20NonBase() {
|
|
|
5835
6029
|
message: "Failed to encode bridging calldata."
|
|
5836
6030
|
}
|
|
5837
6031
|
);
|
|
5838
|
-
const
|
|
6032
|
+
const requestStruct = {
|
|
5839
6033
|
chainId: ctx.chainIdL2,
|
|
5840
6034
|
mintValue,
|
|
5841
|
-
// fees (in ETH if base=ETH, else pulled as base ERC-20)
|
|
5842
6035
|
l2Value: 0n,
|
|
5843
|
-
l2GasLimit:
|
|
6036
|
+
l2GasLimit: l2GasParams.gasLimit,
|
|
5844
6037
|
l2GasPerPubdataByteLimit: ctx.gasPerPubdata,
|
|
5845
6038
|
refundRecipient: ctx.refundRecipient,
|
|
5846
6039
|
secondBridgeAddress: assetRouter,
|
|
5847
6040
|
secondBridgeValue: 0n,
|
|
5848
6041
|
secondBridgeCalldata
|
|
5849
6042
|
};
|
|
5850
|
-
const
|
|
5851
|
-
const
|
|
6043
|
+
const bh = await ctx.contracts.bridgehub();
|
|
6044
|
+
const data = bh.interface.encodeFunctionData("requestL2TransactionTwoBridges", [
|
|
6045
|
+
requestStruct
|
|
6046
|
+
]);
|
|
6047
|
+
const txValue = baseIsEth ? mintValue : 0n;
|
|
6048
|
+
const l1TxCandidate = {
|
|
5852
6049
|
to: ctx.bridgehub,
|
|
5853
|
-
data
|
|
5854
|
-
value:
|
|
6050
|
+
data,
|
|
6051
|
+
value: txValue,
|
|
5855
6052
|
from: ctx.sender,
|
|
5856
|
-
...
|
|
6053
|
+
...ctx.gasOverrides
|
|
5857
6054
|
};
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
ctx: { where: "l1.estimateGas", to: ctx.bridgehub, baseIsEth },
|
|
5869
|
-
message: "Failed to estimate gas for Bridgehub request."
|
|
5870
|
-
}
|
|
5871
|
-
);
|
|
5872
|
-
const buffered = BigInt(est) * 125n / 100n;
|
|
5873
|
-
bridgeTx.gasLimit = buffered;
|
|
5874
|
-
resolvedL1GasLimit = buffered;
|
|
5875
|
-
} catch {
|
|
5876
|
-
}
|
|
6055
|
+
const l1GasParams = await quoteL1Gas2({
|
|
6056
|
+
ctx,
|
|
6057
|
+
tx: l1TxCandidate,
|
|
6058
|
+
overrides: ctx.gasOverrides,
|
|
6059
|
+
fallbackGasLimit: SAFE_L1_BRIDGE_GAS
|
|
6060
|
+
});
|
|
6061
|
+
if (l1GasParams) {
|
|
6062
|
+
l1TxCandidate.gasLimit = l1GasParams.gasLimit;
|
|
6063
|
+
l1TxCandidate.maxFeePerGas = l1GasParams.maxFeePerGas;
|
|
6064
|
+
l1TxCandidate.maxPriorityFeePerGas = l1GasParams.maxPriorityFeePerGas;
|
|
5877
6065
|
}
|
|
5878
6066
|
steps.push({
|
|
5879
|
-
key: "bridgehub:two-bridges
|
|
6067
|
+
key: "bridgehub:two-bridges",
|
|
5880
6068
|
kind: "bridgehub:two-bridges",
|
|
5881
|
-
description: baseIsEth ? "Bridge ERC-20 (
|
|
5882
|
-
tx:
|
|
6069
|
+
description: baseIsEth ? "Bridge ERC-20 (Fees paid in ETH)" : "Bridge ERC-20 (Fees paid in Base Token)",
|
|
6070
|
+
tx: l1TxCandidate
|
|
6071
|
+
});
|
|
6072
|
+
const fees = buildFeeBreakdown({
|
|
6073
|
+
feeToken: baseToken,
|
|
6074
|
+
l1Gas: l1GasParams,
|
|
6075
|
+
l2Gas: l2GasParams,
|
|
6076
|
+
l2BaseCost: baseCost,
|
|
6077
|
+
operatorTip: ctx.operatorTip,
|
|
6078
|
+
mintValue
|
|
5883
6079
|
});
|
|
5884
6080
|
return {
|
|
5885
6081
|
steps,
|
|
5886
6082
|
approvals,
|
|
5887
|
-
|
|
6083
|
+
fees
|
|
5888
6084
|
};
|
|
5889
6085
|
}
|
|
5890
6086
|
};
|
|
5891
6087
|
}
|
|
5892
|
-
var { wrapAs:
|
|
5893
|
-
var BASE_COST_BUFFER_BPS = 100n;
|
|
5894
|
-
var BPS = 10000n;
|
|
5895
|
-
var withBuffer = (x) => x * (BPS + BASE_COST_BUFFER_BPS) / BPS;
|
|
6088
|
+
var { wrapAs: wrapAs4 } = createErrorHandlers("deposits");
|
|
5896
6089
|
function routeEthNonBase() {
|
|
5897
6090
|
return {
|
|
5898
6091
|
async preflight(p, ctx) {
|
|
5899
|
-
await
|
|
6092
|
+
const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l1" }) : void 0);
|
|
6093
|
+
await wrapAs4(
|
|
5900
6094
|
"VALIDATION",
|
|
5901
6095
|
OP_DEPOSITS.ethNonBase.assertEthAsset,
|
|
5902
6096
|
() => {
|
|
5903
|
-
if (!isETH(p.token)) {
|
|
6097
|
+
if (resolved?.kind !== "eth" && !isETH(p.token)) {
|
|
5904
6098
|
throw new Error("eth-nonbase route requires ETH as the deposit asset.");
|
|
5905
6099
|
}
|
|
5906
6100
|
},
|
|
5907
6101
|
{ ctx: { token: p.token } }
|
|
5908
6102
|
);
|
|
5909
|
-
|
|
5910
|
-
const baseToken = await wrapAs3(
|
|
5911
|
-
"CONTRACT",
|
|
5912
|
-
OP_DEPOSITS.ethNonBase.baseToken,
|
|
5913
|
-
() => bh.baseToken(ctx.chainIdL2),
|
|
5914
|
-
{
|
|
5915
|
-
ctx: { where: "bridgehub.baseToken", chainIdL2: ctx.chainIdL2 },
|
|
5916
|
-
message: "Failed to read base token."
|
|
5917
|
-
}
|
|
5918
|
-
);
|
|
5919
|
-
await wrapAs3(
|
|
6103
|
+
await wrapAs4(
|
|
5920
6104
|
"VALIDATION",
|
|
5921
6105
|
OP_DEPOSITS.ethNonBase.assertNonEthBase,
|
|
5922
6106
|
() => {
|
|
5923
|
-
if (
|
|
6107
|
+
if (ctx.baseIsEth) {
|
|
5924
6108
|
throw new Error("eth-nonbase route requires target chain base token \u2260 ETH.");
|
|
5925
6109
|
}
|
|
5926
6110
|
},
|
|
5927
|
-
{ ctx: {
|
|
6111
|
+
{ ctx: { baseIsEth: ctx.baseIsEth, chainIdL2: ctx.chainIdL2 } }
|
|
5928
6112
|
);
|
|
5929
|
-
const ethBal = await
|
|
6113
|
+
const ethBal = await wrapAs4(
|
|
5930
6114
|
"RPC",
|
|
5931
6115
|
OP_DEPOSITS.ethNonBase.ethBalance,
|
|
5932
6116
|
() => ctx.client.l1.getBalance(ctx.sender),
|
|
@@ -5935,7 +6119,7 @@ function routeEthNonBase() {
|
|
|
5935
6119
|
message: "Failed to read L1 ETH balance."
|
|
5936
6120
|
}
|
|
5937
6121
|
);
|
|
5938
|
-
await
|
|
6122
|
+
await wrapAs4(
|
|
5939
6123
|
"VALIDATION",
|
|
5940
6124
|
OP_DEPOSITS.ethNonBase.assertEthBalance,
|
|
5941
6125
|
() => {
|
|
@@ -5948,63 +6132,50 @@ function routeEthNonBase() {
|
|
|
5948
6132
|
return;
|
|
5949
6133
|
},
|
|
5950
6134
|
async build(p, ctx) {
|
|
5951
|
-
const
|
|
5952
|
-
const
|
|
5953
|
-
const
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
6135
|
+
const l1Signer = ctx.client.getL1Signer();
|
|
6136
|
+
const baseToken = ctx.baseTokenL1;
|
|
6137
|
+
const l2TxModel = {
|
|
6138
|
+
to: p.to ?? ctx.sender,
|
|
6139
|
+
from: ctx.sender,
|
|
6140
|
+
data: "0x",
|
|
6141
|
+
value: 0n
|
|
6142
|
+
};
|
|
6143
|
+
const l2GasParams = await quoteL2Gas2({
|
|
6144
|
+
ctx,
|
|
6145
|
+
route: "eth-nonbase",
|
|
6146
|
+
l2TxForModeling: l2TxModel,
|
|
6147
|
+
overrideGasLimit: ctx.l2GasLimit
|
|
6148
|
+
});
|
|
6149
|
+
if (!l2GasParams) throw new Error("Failed to estimate L2 gas parameters.");
|
|
6150
|
+
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
6151
|
+
const mintValue = baseCost + ctx.operatorTip;
|
|
6152
|
+
const approvals = [];
|
|
6153
|
+
const steps = [];
|
|
6154
|
+
const erc20Base = new ethers.Contract(baseToken, IERC20_default, l1Signer);
|
|
6155
|
+
const allowance = await wrapAs4(
|
|
5964
6156
|
"RPC",
|
|
5965
|
-
OP_DEPOSITS.ethNonBase.
|
|
5966
|
-
() =>
|
|
5967
|
-
ctx.chainIdL2,
|
|
5968
|
-
gasPriceForBaseCost,
|
|
5969
|
-
ctx.l2GasLimit,
|
|
5970
|
-
ctx.gasPerPubdata
|
|
5971
|
-
),
|
|
6157
|
+
OP_DEPOSITS.ethNonBase.allowanceBase,
|
|
6158
|
+
() => erc20Base.allowance(ctx.sender, ctx.l1AssetRouter),
|
|
5972
6159
|
{
|
|
5973
|
-
ctx: { where: "
|
|
5974
|
-
message: "
|
|
6160
|
+
ctx: { where: "erc20.allowance", token: baseToken, spender: ctx.l1AssetRouter },
|
|
6161
|
+
message: "Failed to read base-token allowance."
|
|
5975
6162
|
}
|
|
5976
6163
|
);
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
{
|
|
5989
|
-
ctx: { where: "erc20.allowance", token: baseToken, spender: ctx.l1AssetRouter },
|
|
5990
|
-
message: "Failed to read base-token allowance."
|
|
6164
|
+
if (allowance < mintValue) {
|
|
6165
|
+
approvals.push({ token: baseToken, spender: ctx.l1AssetRouter, amount: mintValue });
|
|
6166
|
+
steps.push({
|
|
6167
|
+
key: `approve:${baseToken}`,
|
|
6168
|
+
kind: "approve",
|
|
6169
|
+
description: `Approve base token for fees (mintValue)`,
|
|
6170
|
+
tx: {
|
|
6171
|
+
to: baseToken,
|
|
6172
|
+
data: erc20Base.interface.encodeFunctionData("approve", [ctx.l1AssetRouter, mintValue]),
|
|
6173
|
+
from: ctx.sender,
|
|
6174
|
+
...ctx.gasOverrides
|
|
5991
6175
|
}
|
|
5992
|
-
);
|
|
5993
|
-
if (allowance < mintValue) {
|
|
5994
|
-
approvals.push({ token: baseToken, spender: ctx.l1AssetRouter, amount: mintValue });
|
|
5995
|
-
const data = erc20.interface.encodeFunctionData("approve", [
|
|
5996
|
-
ctx.l1AssetRouter,
|
|
5997
|
-
mintValue
|
|
5998
|
-
]);
|
|
5999
|
-
steps.push({
|
|
6000
|
-
key: `approve:${baseToken}:${ctx.l1AssetRouter}`,
|
|
6001
|
-
kind: "approve",
|
|
6002
|
-
description: `Approve base token for mintValue`,
|
|
6003
|
-
tx: { to: baseToken, data, from: ctx.sender, ...txOverrides }
|
|
6004
|
-
});
|
|
6005
|
-
}
|
|
6176
|
+
});
|
|
6006
6177
|
}
|
|
6007
|
-
const secondBridgeCalldata = await
|
|
6178
|
+
const secondBridgeCalldata = await wrapAs4(
|
|
6008
6179
|
"INTERNAL",
|
|
6009
6180
|
OP_DEPOSITS.ethNonBase.encodeCalldata,
|
|
6010
6181
|
() => Promise.resolve(encodeSecondBridgeEthArgs(p.amount, p.to ?? ctx.sender)),
|
|
@@ -6016,93 +6187,79 @@ function routeEthNonBase() {
|
|
|
6016
6187
|
}
|
|
6017
6188
|
}
|
|
6018
6189
|
);
|
|
6019
|
-
const
|
|
6190
|
+
const requestStruct = {
|
|
6020
6191
|
chainId: ctx.chainIdL2,
|
|
6021
6192
|
mintValue,
|
|
6022
|
-
l2Value:
|
|
6023
|
-
l2GasLimit:
|
|
6193
|
+
l2Value: p.amount,
|
|
6194
|
+
l2GasLimit: l2GasParams.gasLimit,
|
|
6024
6195
|
l2GasPerPubdataByteLimit: ctx.gasPerPubdata,
|
|
6025
6196
|
refundRecipient: ctx.refundRecipient,
|
|
6026
6197
|
secondBridgeAddress: ctx.l1AssetRouter,
|
|
6027
6198
|
secondBridgeValue: p.amount,
|
|
6028
6199
|
secondBridgeCalldata
|
|
6029
6200
|
};
|
|
6030
|
-
const
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
let resolvedL1GasLimit = overrideGasLimit ?? ctx.l2GasLimit;
|
|
6036
|
-
const bridgeTx = {
|
|
6201
|
+
const bridgehub = await ctx.contracts.bridgehub();
|
|
6202
|
+
const data = bridgehub.interface.encodeFunctionData("requestL2TransactionTwoBridges", [
|
|
6203
|
+
requestStruct
|
|
6204
|
+
]);
|
|
6205
|
+
const l1TxCandidate = {
|
|
6037
6206
|
to: ctx.bridgehub,
|
|
6038
|
-
data
|
|
6207
|
+
data,
|
|
6039
6208
|
value: p.amount,
|
|
6040
6209
|
// base ≠ ETH ⇒ msg.value == secondBridgeValue
|
|
6041
6210
|
from: ctx.sender,
|
|
6042
|
-
...
|
|
6211
|
+
...ctx.gasOverrides
|
|
6043
6212
|
};
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
ctx: { where: "l1.estimateGas", to: ctx.bridgehub },
|
|
6055
|
-
message: "Failed to estimate gas for Bridgehub request."
|
|
6056
|
-
}
|
|
6057
|
-
);
|
|
6058
|
-
const buffered = BigInt(est) * 115n / 100n;
|
|
6059
|
-
bridgeTx.gasLimit = buffered;
|
|
6060
|
-
resolvedL1GasLimit = buffered;
|
|
6061
|
-
} catch {
|
|
6062
|
-
}
|
|
6213
|
+
const l1GasParams = await quoteL1Gas2({
|
|
6214
|
+
ctx,
|
|
6215
|
+
tx: l1TxCandidate,
|
|
6216
|
+
overrides: ctx.gasOverrides,
|
|
6217
|
+
fallbackGasLimit: SAFE_L1_BRIDGE_GAS
|
|
6218
|
+
});
|
|
6219
|
+
if (l1GasParams) {
|
|
6220
|
+
l1TxCandidate.gasLimit = l1GasParams.gasLimit;
|
|
6221
|
+
l1TxCandidate.maxFeePerGas = l1GasParams.maxFeePerGas;
|
|
6222
|
+
l1TxCandidate.maxPriorityFeePerGas = l1GasParams.maxPriorityFeePerGas;
|
|
6063
6223
|
}
|
|
6064
6224
|
steps.push({
|
|
6065
6225
|
key: "bridgehub:two-bridges:eth-nonbase",
|
|
6066
6226
|
kind: "bridgehub:two-bridges",
|
|
6067
6227
|
description: "Bridge ETH (fees in base ERC-20) via Bridgehub.requestL2TransactionTwoBridges",
|
|
6068
|
-
tx:
|
|
6228
|
+
tx: l1TxCandidate
|
|
6229
|
+
});
|
|
6230
|
+
const fees = buildFeeBreakdown({
|
|
6231
|
+
feeToken: baseToken,
|
|
6232
|
+
l1Gas: l1GasParams,
|
|
6233
|
+
l2Gas: l2GasParams,
|
|
6234
|
+
l2BaseCost: baseCost,
|
|
6235
|
+
operatorTip: ctx.operatorTip,
|
|
6236
|
+
mintValue
|
|
6069
6237
|
});
|
|
6070
6238
|
return {
|
|
6071
6239
|
steps,
|
|
6072
6240
|
approvals,
|
|
6073
|
-
|
|
6241
|
+
fees
|
|
6074
6242
|
};
|
|
6075
6243
|
}
|
|
6076
6244
|
};
|
|
6077
6245
|
}
|
|
6078
|
-
var { wrapAs:
|
|
6079
|
-
var BASE_COST_BUFFER_BPS2 = 100n;
|
|
6080
|
-
var BPS2 = 10000n;
|
|
6081
|
-
var withBuffer2 = (x) => x * (BPS2 + BASE_COST_BUFFER_BPS2) / BPS2;
|
|
6246
|
+
var { wrapAs: wrapAs5 } = createErrorHandlers("deposits");
|
|
6082
6247
|
function routeErc20Base() {
|
|
6083
6248
|
return {
|
|
6084
6249
|
async preflight(p, ctx) {
|
|
6085
|
-
await
|
|
6250
|
+
const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l1" }) : void 0);
|
|
6251
|
+
await wrapAs5(
|
|
6086
6252
|
"VALIDATION",
|
|
6087
6253
|
OP_DEPOSITS.base.assertErc20Asset,
|
|
6088
6254
|
() => {
|
|
6089
|
-
if (isETH(p.token)) {
|
|
6255
|
+
if (resolved?.kind === "eth" || isETH(p.token)) {
|
|
6090
6256
|
throw new Error("erc20-base route requires an ERC-20 token (not ETH).");
|
|
6091
6257
|
}
|
|
6092
6258
|
},
|
|
6093
6259
|
{ ctx: { token: p.token } }
|
|
6094
6260
|
);
|
|
6095
|
-
const
|
|
6096
|
-
|
|
6097
|
-
"CONTRACT",
|
|
6098
|
-
OP_DEPOSITS.base.baseToken,
|
|
6099
|
-
() => bh.baseToken(ctx.chainIdL2),
|
|
6100
|
-
{
|
|
6101
|
-
ctx: { where: "bridgehub.baseToken", chainIdL2: ctx.chainIdL2 },
|
|
6102
|
-
message: "Failed to read base token."
|
|
6103
|
-
}
|
|
6104
|
-
);
|
|
6105
|
-
await wrapAs4(
|
|
6261
|
+
const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
|
|
6262
|
+
await wrapAs5(
|
|
6106
6263
|
"VALIDATION",
|
|
6107
6264
|
OP_DEPOSITS.base.assertMatchesBase,
|
|
6108
6265
|
() => {
|
|
@@ -6115,42 +6272,28 @@ function routeErc20Base() {
|
|
|
6115
6272
|
return;
|
|
6116
6273
|
},
|
|
6117
6274
|
async build(p, ctx) {
|
|
6118
|
-
const
|
|
6119
|
-
const
|
|
6120
|
-
const
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
"
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
ctx.chainIdL2,
|
|
6136
|
-
gasPriceForBaseCost,
|
|
6137
|
-
ctx.l2GasLimit,
|
|
6138
|
-
ctx.gasPerPubdata
|
|
6139
|
-
),
|
|
6140
|
-
{
|
|
6141
|
-
ctx: { where: "l2TransactionBaseCost", chainIdL2: ctx.chainIdL2 },
|
|
6142
|
-
message: "Could not fetch L2 base cost from Bridgehub."
|
|
6143
|
-
}
|
|
6144
|
-
);
|
|
6145
|
-
const baseCost = BigInt(rawBaseCost);
|
|
6146
|
-
const l2Value = p.amount;
|
|
6147
|
-
const rawMintValue = baseCost + ctx.operatorTip + l2Value;
|
|
6148
|
-
const mintValue = withBuffer2(rawMintValue);
|
|
6275
|
+
const l1Signer = ctx.client.getL1Signer();
|
|
6276
|
+
const baseToken = ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2);
|
|
6277
|
+
const l2TxModel = {
|
|
6278
|
+
to: p.to ?? ctx.sender,
|
|
6279
|
+
from: ctx.sender,
|
|
6280
|
+
data: "0x",
|
|
6281
|
+
value: 0n
|
|
6282
|
+
};
|
|
6283
|
+
const l2GasParams = await quoteL2Gas2({
|
|
6284
|
+
ctx,
|
|
6285
|
+
route: "erc20-base",
|
|
6286
|
+
l2TxForModeling: l2TxModel,
|
|
6287
|
+
overrideGasLimit: ctx.l2GasLimit
|
|
6288
|
+
});
|
|
6289
|
+
if (!l2GasParams) throw new Error("Failed to estimate L2 gas parameters.");
|
|
6290
|
+
const baseCost = await quoteL2BaseCost2({ ctx, l2GasLimit: l2GasParams.gasLimit });
|
|
6291
|
+
const mintValue = baseCost + ctx.operatorTip + p.amount;
|
|
6149
6292
|
const approvals = [];
|
|
6150
6293
|
const steps = [];
|
|
6151
6294
|
{
|
|
6152
|
-
const erc20 = new ethers.Contract(baseToken, IERC20_default,
|
|
6153
|
-
const allowance = await
|
|
6295
|
+
const erc20 = new ethers.Contract(baseToken, IERC20_default, l1Signer);
|
|
6296
|
+
const allowance = await wrapAs5(
|
|
6154
6297
|
"RPC",
|
|
6155
6298
|
OP_DEPOSITS.base.allowance,
|
|
6156
6299
|
() => erc20.allowance(ctx.sender, ctx.l1AssetRouter),
|
|
@@ -6161,75 +6304,350 @@ function routeErc20Base() {
|
|
|
6161
6304
|
);
|
|
6162
6305
|
if (allowance < mintValue) {
|
|
6163
6306
|
approvals.push({ token: baseToken, spender: ctx.l1AssetRouter, amount: mintValue });
|
|
6164
|
-
const data2 = erc20.interface.encodeFunctionData("approve", [
|
|
6165
|
-
ctx.l1AssetRouter,
|
|
6166
|
-
mintValue
|
|
6167
|
-
]);
|
|
6168
6307
|
steps.push({
|
|
6169
6308
|
key: `approve:${baseToken}:${ctx.l1AssetRouter}`,
|
|
6170
6309
|
kind: "approve",
|
|
6171
6310
|
description: "Approve base token for mintValue",
|
|
6172
|
-
tx: {
|
|
6311
|
+
tx: {
|
|
6312
|
+
to: baseToken,
|
|
6313
|
+
data: erc20.interface.encodeFunctionData("approve", [ctx.l1AssetRouter, mintValue]),
|
|
6314
|
+
from: ctx.sender,
|
|
6315
|
+
...ctx.gasOverrides
|
|
6316
|
+
}
|
|
6173
6317
|
});
|
|
6174
6318
|
}
|
|
6175
6319
|
}
|
|
6176
|
-
const
|
|
6320
|
+
const requestStruct = buildDirectRequestStruct({
|
|
6177
6321
|
chainId: ctx.chainIdL2,
|
|
6178
6322
|
mintValue,
|
|
6179
|
-
l2GasLimit:
|
|
6323
|
+
l2GasLimit: l2GasParams.gasLimit,
|
|
6180
6324
|
gasPerPubdata: ctx.gasPerPubdata,
|
|
6181
6325
|
refundRecipient: ctx.refundRecipient,
|
|
6182
6326
|
l2Contract: p.to ?? ctx.sender,
|
|
6183
|
-
l2Value
|
|
6327
|
+
l2Value: p.amount
|
|
6184
6328
|
});
|
|
6185
|
-
const
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
const tx = {
|
|
6329
|
+
const bridgehub = await ctx.contracts.bridgehub();
|
|
6330
|
+
const data = bridgehub.interface.encodeFunctionData("requestL2TransactionDirect", [
|
|
6331
|
+
requestStruct
|
|
6332
|
+
]);
|
|
6333
|
+
const l1TxCandidate = {
|
|
6191
6334
|
to: ctx.bridgehub,
|
|
6192
6335
|
data,
|
|
6193
6336
|
value: 0n,
|
|
6194
6337
|
// base token is ERC-20 ⇒ msg.value MUST be 0
|
|
6195
6338
|
from: ctx.sender,
|
|
6196
|
-
...
|
|
6339
|
+
...ctx.gasOverrides
|
|
6197
6340
|
};
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
ctx: { where: "l1.estimateGas", to: ctx.bridgehub },
|
|
6209
|
-
message: "Failed to estimate gas for Bridgehub request."
|
|
6210
|
-
}
|
|
6211
|
-
);
|
|
6212
|
-
const buffered = BigInt(est) * 115n / 100n;
|
|
6213
|
-
tx.gasLimit = buffered;
|
|
6214
|
-
resolvedL1GasLimit = buffered;
|
|
6215
|
-
} catch {
|
|
6216
|
-
}
|
|
6341
|
+
const l1GasParams = await quoteL1Gas2({
|
|
6342
|
+
ctx,
|
|
6343
|
+
tx: l1TxCandidate,
|
|
6344
|
+
overrides: ctx.gasOverrides,
|
|
6345
|
+
fallbackGasLimit: SAFE_L1_BRIDGE_GAS
|
|
6346
|
+
});
|
|
6347
|
+
if (l1GasParams) {
|
|
6348
|
+
l1TxCandidate.gasLimit = l1GasParams.gasLimit;
|
|
6349
|
+
l1TxCandidate.maxFeePerGas = l1GasParams.maxFeePerGas;
|
|
6350
|
+
l1TxCandidate.maxPriorityFeePerGas = l1GasParams.maxPriorityFeePerGas;
|
|
6217
6351
|
}
|
|
6218
6352
|
steps.push({
|
|
6219
6353
|
key: "bridgehub:direct:erc20-base",
|
|
6220
6354
|
kind: "bridgehub:direct",
|
|
6221
6355
|
description: "Bridge base ERC-20 via Bridgehub.requestL2TransactionDirect",
|
|
6222
|
-
tx
|
|
6356
|
+
tx: l1TxCandidate
|
|
6357
|
+
});
|
|
6358
|
+
const fees = buildFeeBreakdown({
|
|
6359
|
+
feeToken: baseToken,
|
|
6360
|
+
l1Gas: l1GasParams,
|
|
6361
|
+
l2Gas: l2GasParams,
|
|
6362
|
+
l2BaseCost: baseCost,
|
|
6363
|
+
operatorTip: ctx.operatorTip,
|
|
6364
|
+
mintValue
|
|
6223
6365
|
});
|
|
6224
6366
|
return {
|
|
6225
6367
|
steps,
|
|
6226
6368
|
approvals,
|
|
6227
|
-
|
|
6369
|
+
fees
|
|
6228
6370
|
};
|
|
6229
6371
|
}
|
|
6230
6372
|
};
|
|
6231
6373
|
}
|
|
6232
6374
|
|
|
6375
|
+
// src/core/codec/ntv.ts
|
|
6376
|
+
function createNTVCodec(deps) {
|
|
6377
|
+
function encodeAssetId(originChainId, ntvAddress, tokenAddress) {
|
|
6378
|
+
const encoded = deps.encode(
|
|
6379
|
+
["uint256", "address", "address"],
|
|
6380
|
+
[originChainId, ntvAddress, tokenAddress]
|
|
6381
|
+
);
|
|
6382
|
+
return deps.keccak256(encoded);
|
|
6383
|
+
}
|
|
6384
|
+
return {
|
|
6385
|
+
encodeAssetId
|
|
6386
|
+
};
|
|
6387
|
+
}
|
|
6388
|
+
|
|
6389
|
+
// src/adapters/ethers/resources/tokens/tokens.ts
|
|
6390
|
+
var { wrapAs: wrapAs6 } = createErrorHandlers("tokens");
|
|
6391
|
+
var abi = ethers.AbiCoder.defaultAbiCoder();
|
|
6392
|
+
var ntvCodec = createNTVCodec({
|
|
6393
|
+
encode: (types, values) => abi.encode(types, values),
|
|
6394
|
+
keccak256: (data) => ethers.ethers.keccak256(data)
|
|
6395
|
+
});
|
|
6396
|
+
function createTokensResource(client) {
|
|
6397
|
+
let l2NtvL1ChainIdPromise = null;
|
|
6398
|
+
let baseTokenAssetIdPromise = null;
|
|
6399
|
+
let wethL1Promise = null;
|
|
6400
|
+
let wethL2Promise = null;
|
|
6401
|
+
async function getL1ChainId() {
|
|
6402
|
+
if (!l2NtvL1ChainIdPromise) {
|
|
6403
|
+
l2NtvL1ChainIdPromise = wrapAs6("INTERNAL", "getL1ChainId", async () => {
|
|
6404
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6405
|
+
const chainId = await l2NativeTokenVault.L1_CHAIN_ID();
|
|
6406
|
+
return chainId;
|
|
6407
|
+
});
|
|
6408
|
+
}
|
|
6409
|
+
return l2NtvL1ChainIdPromise;
|
|
6410
|
+
}
|
|
6411
|
+
async function getBaseTokenAssetId() {
|
|
6412
|
+
if (!baseTokenAssetIdPromise) {
|
|
6413
|
+
baseTokenAssetIdPromise = wrapAs6("INTERNAL", "baseTokenAssetId", async () => {
|
|
6414
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6415
|
+
const assetId = await l2NativeTokenVault.BASE_TOKEN_ASSET_ID();
|
|
6416
|
+
return assetId;
|
|
6417
|
+
});
|
|
6418
|
+
}
|
|
6419
|
+
return baseTokenAssetIdPromise;
|
|
6420
|
+
}
|
|
6421
|
+
async function getWethL1() {
|
|
6422
|
+
if (!wethL1Promise) {
|
|
6423
|
+
wethL1Promise = wrapAs6("INTERNAL", "wethL1", async () => {
|
|
6424
|
+
const { l1NativeTokenVault } = await client.contracts();
|
|
6425
|
+
const weth = await l1NativeTokenVault.WETH_TOKEN();
|
|
6426
|
+
return weth;
|
|
6427
|
+
});
|
|
6428
|
+
}
|
|
6429
|
+
return wethL1Promise;
|
|
6430
|
+
}
|
|
6431
|
+
async function getWethL2() {
|
|
6432
|
+
if (!wethL2Promise) {
|
|
6433
|
+
wethL2Promise = wrapAs6("INTERNAL", "wethL2", async () => {
|
|
6434
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6435
|
+
const weth = await l2NativeTokenVault.WETH_TOKEN();
|
|
6436
|
+
return weth;
|
|
6437
|
+
});
|
|
6438
|
+
}
|
|
6439
|
+
return wethL2Promise;
|
|
6440
|
+
}
|
|
6441
|
+
async function toL2Address(l1Token) {
|
|
6442
|
+
return wrapAs6("CONTRACT", "tokens.toL2Address", async () => {
|
|
6443
|
+
const normalized = normalizeL1Token(l1Token);
|
|
6444
|
+
const { chainId } = await client.l2.getNetwork();
|
|
6445
|
+
const baseToken = await client.baseToken(BigInt(chainId));
|
|
6446
|
+
if (isAddressEq(normalized, baseToken)) {
|
|
6447
|
+
return L2_BASE_TOKEN_ADDRESS;
|
|
6448
|
+
}
|
|
6449
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6450
|
+
const l2Token = await l2NativeTokenVault.l2TokenAddress(normalized);
|
|
6451
|
+
return l2Token;
|
|
6452
|
+
});
|
|
6453
|
+
}
|
|
6454
|
+
async function toL1Address(l2Token) {
|
|
6455
|
+
return wrapAs6("CONTRACT", "tokens.toL1Address", async () => {
|
|
6456
|
+
if (isAddressEq(l2Token, ETH_ADDRESS)) {
|
|
6457
|
+
return ETH_ADDRESS;
|
|
6458
|
+
}
|
|
6459
|
+
if (isAddressEq(l2Token, L2_BASE_TOKEN_ADDRESS)) {
|
|
6460
|
+
const { chainId } = await client.l2.getNetwork();
|
|
6461
|
+
return await client.baseToken(BigInt(chainId));
|
|
6462
|
+
}
|
|
6463
|
+
const { l2AssetRouter } = await client.contracts();
|
|
6464
|
+
const l1Token = await l2AssetRouter.l1TokenAddress(l2Token);
|
|
6465
|
+
return l1Token;
|
|
6466
|
+
});
|
|
6467
|
+
}
|
|
6468
|
+
async function assetIdOfL1(l1Token) {
|
|
6469
|
+
return wrapAs6("CONTRACT", "tokens.assetIdOfL1", async () => {
|
|
6470
|
+
const normalized = normalizeL1Token(l1Token);
|
|
6471
|
+
const { l1NativeTokenVault } = await client.contracts();
|
|
6472
|
+
const assetId = await l1NativeTokenVault.assetId(normalized);
|
|
6473
|
+
return assetId;
|
|
6474
|
+
});
|
|
6475
|
+
}
|
|
6476
|
+
async function assetIdOfL2(l2Token) {
|
|
6477
|
+
return wrapAs6("CONTRACT", "tokens.assetIdOfL2", async () => {
|
|
6478
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6479
|
+
const assetId = await l2NativeTokenVault.assetId(l2Token);
|
|
6480
|
+
return assetId;
|
|
6481
|
+
});
|
|
6482
|
+
}
|
|
6483
|
+
async function l2TokenFromAssetId(assetId) {
|
|
6484
|
+
return wrapAs6("CONTRACT", "tokens.l2TokenFromAssetId", async () => {
|
|
6485
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6486
|
+
const tokenAddr = await l2NativeTokenVault.tokenAddress(assetId);
|
|
6487
|
+
return tokenAddr;
|
|
6488
|
+
});
|
|
6489
|
+
}
|
|
6490
|
+
async function l1TokenFromAssetId(assetId) {
|
|
6491
|
+
return wrapAs6("CONTRACT", "tokens.l1TokenFromAssetId", async () => {
|
|
6492
|
+
const { l1NativeTokenVault } = await client.contracts();
|
|
6493
|
+
const tokenAddr = await l1NativeTokenVault.tokenAddress(assetId);
|
|
6494
|
+
return tokenAddr;
|
|
6495
|
+
});
|
|
6496
|
+
}
|
|
6497
|
+
async function originChainId(assetId) {
|
|
6498
|
+
return wrapAs6("CONTRACT", "tokens.originChainId", async () => {
|
|
6499
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6500
|
+
const chainId = await l2NativeTokenVault.originChainId(assetId);
|
|
6501
|
+
return chainId;
|
|
6502
|
+
});
|
|
6503
|
+
}
|
|
6504
|
+
async function baseTokenAssetId() {
|
|
6505
|
+
return getBaseTokenAssetId();
|
|
6506
|
+
}
|
|
6507
|
+
async function isChainEthBased() {
|
|
6508
|
+
return wrapAs6("CONTRACT", "tokens.isChainEthBased", async () => {
|
|
6509
|
+
const baseAssetId = await getBaseTokenAssetId();
|
|
6510
|
+
const l1ChainId = await getL1ChainId();
|
|
6511
|
+
const ethAssetId = ntvCodec.encodeAssetId(
|
|
6512
|
+
l1ChainId,
|
|
6513
|
+
L2_NATIVE_TOKEN_VAULT_ADDRESS,
|
|
6514
|
+
ETH_ADDRESS
|
|
6515
|
+
);
|
|
6516
|
+
return hexEq(baseAssetId, ethAssetId);
|
|
6517
|
+
});
|
|
6518
|
+
}
|
|
6519
|
+
async function wethL1() {
|
|
6520
|
+
return getWethL1();
|
|
6521
|
+
}
|
|
6522
|
+
async function wethL2() {
|
|
6523
|
+
return getWethL2();
|
|
6524
|
+
}
|
|
6525
|
+
async function computeL2BridgedAddress(args) {
|
|
6526
|
+
return wrapAs6("CONTRACT", "tokens.computeL2BridgedAddress", async () => {
|
|
6527
|
+
const normalized = normalizeL1Token(args.l1Token);
|
|
6528
|
+
const { l2NativeTokenVault } = await client.contracts();
|
|
6529
|
+
const predicted = await l2NativeTokenVault.calculateCreate2TokenAddress(
|
|
6530
|
+
args.originChainId,
|
|
6531
|
+
normalized
|
|
6532
|
+
);
|
|
6533
|
+
return predicted;
|
|
6534
|
+
});
|
|
6535
|
+
}
|
|
6536
|
+
async function resolve(ref, opts) {
|
|
6537
|
+
return wrapAs6("CONTRACT", "tokens.resolve", async () => {
|
|
6538
|
+
let chain;
|
|
6539
|
+
let address;
|
|
6540
|
+
if (typeof ref === "string") {
|
|
6541
|
+
chain = opts?.chain ?? "l1";
|
|
6542
|
+
address = ref;
|
|
6543
|
+
} else {
|
|
6544
|
+
chain = ref.chain;
|
|
6545
|
+
address = ref.address;
|
|
6546
|
+
}
|
|
6547
|
+
let l1;
|
|
6548
|
+
let l2;
|
|
6549
|
+
if (chain === "l1") {
|
|
6550
|
+
l1 = normalizeL1Token(address);
|
|
6551
|
+
l2 = await toL2Address(address);
|
|
6552
|
+
} else {
|
|
6553
|
+
l2 = address;
|
|
6554
|
+
l1 = await toL1Address(address);
|
|
6555
|
+
}
|
|
6556
|
+
const assetId = await assetIdOfL1(l1);
|
|
6557
|
+
const originChainIdVal = await originChainId(assetId);
|
|
6558
|
+
const [baseAssetId, wethL1Addr, wethL2Addr, ethBased] = await Promise.all([
|
|
6559
|
+
baseTokenAssetId(),
|
|
6560
|
+
wethL1(),
|
|
6561
|
+
wethL2(),
|
|
6562
|
+
isChainEthBased()
|
|
6563
|
+
]);
|
|
6564
|
+
let kind;
|
|
6565
|
+
if (isAddressEq(l1, ETH_ADDRESS)) {
|
|
6566
|
+
kind = "eth";
|
|
6567
|
+
} else if (hexEq(assetId, baseAssetId)) {
|
|
6568
|
+
kind = "base";
|
|
6569
|
+
} else {
|
|
6570
|
+
kind = "erc20";
|
|
6571
|
+
}
|
|
6572
|
+
return {
|
|
6573
|
+
kind,
|
|
6574
|
+
l1,
|
|
6575
|
+
l2,
|
|
6576
|
+
assetId,
|
|
6577
|
+
originChainId: originChainIdVal,
|
|
6578
|
+
isChainEthBased: ethBased,
|
|
6579
|
+
baseTokenAssetId: baseAssetId,
|
|
6580
|
+
wethL1: wethL1Addr,
|
|
6581
|
+
wethL2: wethL2Addr
|
|
6582
|
+
};
|
|
6583
|
+
});
|
|
6584
|
+
}
|
|
6585
|
+
return {
|
|
6586
|
+
resolve,
|
|
6587
|
+
toL2Address,
|
|
6588
|
+
toL1Address,
|
|
6589
|
+
assetIdOfL1,
|
|
6590
|
+
assetIdOfL2,
|
|
6591
|
+
l2TokenFromAssetId,
|
|
6592
|
+
l1TokenFromAssetId,
|
|
6593
|
+
originChainId,
|
|
6594
|
+
baseTokenAssetId,
|
|
6595
|
+
isChainEthBased,
|
|
6596
|
+
wethL1,
|
|
6597
|
+
wethL2,
|
|
6598
|
+
computeL2BridgedAddress
|
|
6599
|
+
};
|
|
6600
|
+
}
|
|
6601
|
+
|
|
6602
|
+
// src/adapters/ethers/resources/contracts/contracts.ts
|
|
6603
|
+
function createContractsResource(client) {
|
|
6604
|
+
async function addresses() {
|
|
6605
|
+
return client.ensureAddresses();
|
|
6606
|
+
}
|
|
6607
|
+
async function instances() {
|
|
6608
|
+
return client.contracts();
|
|
6609
|
+
}
|
|
6610
|
+
async function bridgehub() {
|
|
6611
|
+
const { bridgehub: bridgehub2 } = await instances();
|
|
6612
|
+
return bridgehub2;
|
|
6613
|
+
}
|
|
6614
|
+
async function l1AssetRouter() {
|
|
6615
|
+
const { l1AssetRouter: l1AssetRouter2 } = await instances();
|
|
6616
|
+
return l1AssetRouter2;
|
|
6617
|
+
}
|
|
6618
|
+
async function l1NativeTokenVault() {
|
|
6619
|
+
const { l1NativeTokenVault: l1NativeTokenVault2 } = await instances();
|
|
6620
|
+
return l1NativeTokenVault2;
|
|
6621
|
+
}
|
|
6622
|
+
async function l1Nullifier() {
|
|
6623
|
+
const { l1Nullifier: l1Nullifier2 } = await instances();
|
|
6624
|
+
return l1Nullifier2;
|
|
6625
|
+
}
|
|
6626
|
+
async function l2AssetRouter() {
|
|
6627
|
+
const { l2AssetRouter: l2AssetRouter2 } = await instances();
|
|
6628
|
+
return l2AssetRouter2;
|
|
6629
|
+
}
|
|
6630
|
+
async function l2NativeTokenVault() {
|
|
6631
|
+
const { l2NativeTokenVault: l2NativeTokenVault2 } = await instances();
|
|
6632
|
+
return l2NativeTokenVault2;
|
|
6633
|
+
}
|
|
6634
|
+
async function l2BaseTokenSystem() {
|
|
6635
|
+
const { l2BaseTokenSystem: l2BaseTokenSystem2 } = await instances();
|
|
6636
|
+
return l2BaseTokenSystem2;
|
|
6637
|
+
}
|
|
6638
|
+
return {
|
|
6639
|
+
addresses,
|
|
6640
|
+
instances,
|
|
6641
|
+
bridgehub,
|
|
6642
|
+
l1AssetRouter,
|
|
6643
|
+
l1NativeTokenVault,
|
|
6644
|
+
l1Nullifier,
|
|
6645
|
+
l2AssetRouter,
|
|
6646
|
+
l2NativeTokenVault,
|
|
6647
|
+
l2BaseTokenSystem
|
|
6648
|
+
};
|
|
6649
|
+
}
|
|
6650
|
+
|
|
6233
6651
|
// src/adapters/ethers/resources/deposits/index.ts
|
|
6234
6652
|
var { wrap, toResult } = createErrorHandlers("deposits");
|
|
6235
6653
|
var ROUTES = {
|
|
@@ -6238,42 +6656,26 @@ var ROUTES = {
|
|
|
6238
6656
|
"erc20-nonbase": routeErc20NonBase(),
|
|
6239
6657
|
"erc20-base": routeErc20Base()
|
|
6240
6658
|
};
|
|
6241
|
-
function createDepositsResource(client) {
|
|
6659
|
+
function createDepositsResource(client, tokens, contracts) {
|
|
6660
|
+
const tokensResource = tokens ?? createTokensResource(client);
|
|
6661
|
+
const contractsResource = contracts ?? createContractsResource(client);
|
|
6242
6662
|
async function buildPlan(p) {
|
|
6243
|
-
const ctx = await commonCtx(p, client);
|
|
6663
|
+
const ctx = await commonCtx(p, client, tokensResource, contractsResource);
|
|
6244
6664
|
const route = ctx.route;
|
|
6245
6665
|
await ROUTES[route].preflight?.(p, ctx);
|
|
6246
|
-
const { steps, approvals,
|
|
6247
|
-
const { baseCost, mintValue } = quoteExtras;
|
|
6248
|
-
const fallbackGasLimit = quoteExtras.l1GasLimit;
|
|
6249
|
-
const resolveGasLimit = () => {
|
|
6250
|
-
if (ctx.fee.gasLimit != null) return ctx.fee.gasLimit;
|
|
6251
|
-
for (let i = steps.length - 1; i >= 0; i--) {
|
|
6252
|
-
const candidate = steps[i].tx.gasLimit;
|
|
6253
|
-
if (candidate == null) continue;
|
|
6254
|
-
if (typeof candidate === "bigint") return candidate;
|
|
6255
|
-
try {
|
|
6256
|
-
return BigInt(candidate.toString());
|
|
6257
|
-
} catch {
|
|
6258
|
-
}
|
|
6259
|
-
}
|
|
6260
|
-
if (fallbackGasLimit != null) return fallbackGasLimit;
|
|
6261
|
-
return ctx.l2GasLimit;
|
|
6262
|
-
};
|
|
6263
|
-
const gasLimit = resolveGasLimit();
|
|
6666
|
+
const { steps, approvals, fees } = await ROUTES[route].build(p, ctx);
|
|
6264
6667
|
return {
|
|
6265
6668
|
route: ctx.route,
|
|
6266
6669
|
summary: {
|
|
6267
6670
|
route: ctx.route,
|
|
6268
6671
|
approvalsNeeded: approvals,
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
fees
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
}
|
|
6672
|
+
amounts: {
|
|
6673
|
+
transfer: { token: p.token, amount: p.amount }
|
|
6674
|
+
},
|
|
6675
|
+
fees,
|
|
6676
|
+
// Legacy fields (maintained for backward compatibility)
|
|
6677
|
+
baseCost: fees.l2?.baseCost,
|
|
6678
|
+
mintValue: fees.mintValue
|
|
6277
6679
|
},
|
|
6278
6680
|
steps
|
|
6279
6681
|
};
|
|
@@ -6342,7 +6744,7 @@ function createDepositsResource(client) {
|
|
|
6342
6744
|
step.tx.maxPriorityFeePerGas = overrides.maxPriorityFeePerGas;
|
|
6343
6745
|
}
|
|
6344
6746
|
}
|
|
6345
|
-
if (!
|
|
6747
|
+
if (!p.l1TxOverrides?.gasLimit) {
|
|
6346
6748
|
try {
|
|
6347
6749
|
const est = await client.l1.estimateGas(step.tx);
|
|
6348
6750
|
step.tx.gasLimit = BigInt(est) * 115n / 100n;
|
|
@@ -6533,28 +6935,12 @@ function normalizeTokenForRouting(token) {
|
|
|
6533
6935
|
function pickWithdrawRoute(args) {
|
|
6534
6936
|
const tokenNorm = normalizeTokenForRouting(args.token);
|
|
6535
6937
|
const isL2BaseAlias = tokenNorm.toLowerCase() === L2_BASE_TOKEN_ADDRESS.toLowerCase();
|
|
6536
|
-
if (isL2BaseAlias) return
|
|
6938
|
+
if (isL2BaseAlias) return "base";
|
|
6537
6939
|
return "erc20-nonbase";
|
|
6538
6940
|
}
|
|
6539
|
-
async function ntvBaseAssetId(l2, ntv) {
|
|
6540
|
-
const c = new ethers.Contract(ntv, L2NativeTokenVault_default, l2);
|
|
6541
|
-
return await c.BASE_TOKEN_ASSET_ID();
|
|
6542
|
-
}
|
|
6543
|
-
async function ntvL1ChainId(l2, ntv) {
|
|
6544
|
-
const c = new ethers.Contract(ntv, L2NativeTokenVault_default, l2);
|
|
6545
|
-
return await c.L1_CHAIN_ID();
|
|
6546
|
-
}
|
|
6547
|
-
async function isEthBasedChain(l2, ntv) {
|
|
6548
|
-
const [baseAssetId, l1ChainId] = await Promise.all([
|
|
6549
|
-
ntvBaseAssetId(l2, ntv),
|
|
6550
|
-
ntvL1ChainId(l2, ntv)
|
|
6551
|
-
]);
|
|
6552
|
-
const ethAssetId = encodeNativeTokenVaultAssetId(l1ChainId, ETH_ADDRESS);
|
|
6553
|
-
return baseAssetId.toLowerCase() === ethAssetId.toLowerCase();
|
|
6554
|
-
}
|
|
6555
6941
|
|
|
6556
6942
|
// src/adapters/ethers/resources/withdrawals/context.ts
|
|
6557
|
-
async function commonCtx2(p, client) {
|
|
6943
|
+
async function commonCtx2(p, client, tokens, contracts) {
|
|
6558
6944
|
const sender = await client.signer.getAddress();
|
|
6559
6945
|
const {
|
|
6560
6946
|
bridgehub,
|
|
@@ -6563,16 +6949,21 @@ async function commonCtx2(p, client) {
|
|
|
6563
6949
|
l2AssetRouter,
|
|
6564
6950
|
l2NativeTokenVault,
|
|
6565
6951
|
l2BaseTokenSystem
|
|
6566
|
-
} = await
|
|
6952
|
+
} = await contracts.addresses();
|
|
6567
6953
|
const { chainId } = await client.l2.getNetwork();
|
|
6568
6954
|
const chainIdL2 = BigInt(chainId);
|
|
6569
|
-
const
|
|
6570
|
-
const
|
|
6571
|
-
const
|
|
6572
|
-
const
|
|
6573
|
-
const
|
|
6955
|
+
const resolvedToken = await tokens.resolve(p.token, { chain: "l2" });
|
|
6956
|
+
const baseTokenAssetId = resolvedToken.baseTokenAssetId;
|
|
6957
|
+
const baseTokenL1 = await tokens.l1TokenFromAssetId(baseTokenAssetId);
|
|
6958
|
+
const baseIsEth = resolvedToken.isChainEthBased;
|
|
6959
|
+
const route = pickWithdrawRoute({ token: p.token});
|
|
6574
6960
|
return {
|
|
6575
6961
|
client,
|
|
6962
|
+
tokens,
|
|
6963
|
+
contracts,
|
|
6964
|
+
resolvedToken,
|
|
6965
|
+
baseTokenAssetId,
|
|
6966
|
+
baseTokenL1,
|
|
6576
6967
|
bridgehub,
|
|
6577
6968
|
chainIdL2,
|
|
6578
6969
|
sender,
|
|
@@ -6583,29 +6974,111 @@ async function commonCtx2(p, client) {
|
|
|
6583
6974
|
l2NativeTokenVault,
|
|
6584
6975
|
l2BaseTokenSystem,
|
|
6585
6976
|
baseIsEth,
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
|
|
6977
|
+
gasOverrides: p.l2TxOverrides
|
|
6978
|
+
};
|
|
6979
|
+
}
|
|
6980
|
+
|
|
6981
|
+
// src/core/resources/withdrawals/gas.ts
|
|
6982
|
+
function makeGasQuote2(p) {
|
|
6983
|
+
return {
|
|
6984
|
+
gasLimit: p.gasLimit,
|
|
6985
|
+
maxFeePerGas: p.maxFeePerGas,
|
|
6986
|
+
maxPriorityFeePerGas: p.maxPriorityFeePerGas,
|
|
6987
|
+
maxCost: p.gasLimit * p.maxFeePerGas
|
|
6988
|
+
};
|
|
6989
|
+
}
|
|
6990
|
+
async function fetchFees2(estimator) {
|
|
6991
|
+
try {
|
|
6992
|
+
const fees = await estimator.estimateFeesPerGas();
|
|
6993
|
+
if (fees.maxFeePerGas != null) {
|
|
6994
|
+
return {
|
|
6995
|
+
maxFeePerGas: fees.maxFeePerGas,
|
|
6996
|
+
maxPriorityFeePerGas: fees.maxPriorityFeePerGas ?? 0n
|
|
6997
|
+
};
|
|
6998
|
+
}
|
|
6999
|
+
if (fees.gasPrice != null) {
|
|
7000
|
+
return {
|
|
7001
|
+
maxFeePerGas: fees.gasPrice,
|
|
7002
|
+
maxPriorityFeePerGas: 0n
|
|
7003
|
+
};
|
|
7004
|
+
}
|
|
7005
|
+
} catch {
|
|
7006
|
+
}
|
|
7007
|
+
try {
|
|
7008
|
+
const gp = await estimator.getGasPrice();
|
|
7009
|
+
return { maxFeePerGas: gp, maxPriorityFeePerGas: 0n };
|
|
7010
|
+
} catch {
|
|
7011
|
+
return { maxFeePerGas: 0n, maxPriorityFeePerGas: 0n };
|
|
7012
|
+
}
|
|
7013
|
+
}
|
|
7014
|
+
async function quoteL2Gas3(input) {
|
|
7015
|
+
const { estimator, tx, overrides } = input;
|
|
7016
|
+
const market = await fetchFees2(estimator);
|
|
7017
|
+
const o = overrides;
|
|
7018
|
+
const maxFeePerGas = o?.maxFeePerGas ?? (tx.maxFeePerGas != null ? BigInt(tx.maxFeePerGas) : market.maxFeePerGas);
|
|
7019
|
+
const maxPriorityFeePerGas = o?.maxPriorityFeePerGas ?? (tx.maxPriorityFeePerGas != null ? BigInt(tx.maxPriorityFeePerGas) : market.maxPriorityFeePerGas);
|
|
7020
|
+
const explicitGasLimit = o?.gasLimit ?? (tx.gasLimit != null ? BigInt(tx.gasLimit) : void 0);
|
|
7021
|
+
if (explicitGasLimit != null) {
|
|
7022
|
+
return makeGasQuote2({
|
|
7023
|
+
gasLimit: explicitGasLimit,
|
|
7024
|
+
maxFeePerGas,
|
|
7025
|
+
maxPriorityFeePerGas
|
|
7026
|
+
});
|
|
7027
|
+
}
|
|
7028
|
+
try {
|
|
7029
|
+
const est = await estimator.estimateGas(tx);
|
|
7030
|
+
const buffered = BigInt(est) * (100n + BUFFER) / 100n;
|
|
7031
|
+
return makeGasQuote2({
|
|
7032
|
+
gasLimit: buffered,
|
|
7033
|
+
maxFeePerGas,
|
|
7034
|
+
maxPriorityFeePerGas
|
|
7035
|
+
});
|
|
7036
|
+
} catch (err) {
|
|
7037
|
+
console.warn("Failed to estimate L2 gas for withdrawal.", err);
|
|
7038
|
+
return void 0;
|
|
7039
|
+
}
|
|
7040
|
+
}
|
|
7041
|
+
|
|
7042
|
+
// src/adapters/ethers/resources/withdrawals/services/gas.ts
|
|
7043
|
+
async function quoteL2Gas4(input) {
|
|
7044
|
+
const { ctx, tx } = input;
|
|
7045
|
+
const estimator = ethersToGasEstimator(ctx.client.l2);
|
|
7046
|
+
return quoteL2Gas3({
|
|
7047
|
+
estimator,
|
|
7048
|
+
tx: toCoreTx(tx),
|
|
7049
|
+
overrides: ctx.gasOverrides
|
|
7050
|
+
});
|
|
7051
|
+
}
|
|
7052
|
+
|
|
7053
|
+
// src/adapters/ethers/resources/withdrawals/services/fees.ts
|
|
7054
|
+
function buildFeeBreakdown2(p) {
|
|
7055
|
+
const l2Total = p.l2Gas?.maxCost ?? 0n;
|
|
7056
|
+
const l2 = {
|
|
7057
|
+
total: l2Total,
|
|
7058
|
+
gasLimit: p.l2Gas?.gasLimit ?? 0n,
|
|
7059
|
+
maxFeePerGas: p.l2Gas?.maxFeePerGas ?? 0n,
|
|
7060
|
+
maxPriorityFeePerGas: p.l2Gas?.maxPriorityFeePerGas
|
|
7061
|
+
};
|
|
7062
|
+
return {
|
|
7063
|
+
token: p.feeToken,
|
|
7064
|
+
maxTotal: l2Total,
|
|
7065
|
+
l2
|
|
6589
7066
|
};
|
|
6590
7067
|
}
|
|
6591
|
-
|
|
7068
|
+
|
|
7069
|
+
// src/adapters/ethers/resources/withdrawals/routes/eth.ts
|
|
7070
|
+
var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
|
|
6592
7071
|
function routeEthBase() {
|
|
6593
7072
|
return {
|
|
6594
7073
|
async build(p, ctx) {
|
|
6595
7074
|
const steps = [];
|
|
6596
|
-
const
|
|
6597
|
-
const
|
|
6598
|
-
L2_BASE_TOKEN_ADDRESS,
|
|
6599
|
-
new ethers.Interface(IBaseToken_default),
|
|
6600
|
-
ctx.client.l2
|
|
6601
|
-
);
|
|
6602
|
-
const toL1 = p.to ?? ctx.sender;
|
|
6603
|
-
const data = await wrapAs5(
|
|
7075
|
+
const base = await ctx.contracts.l2BaseTokenSystem();
|
|
7076
|
+
const data = await wrapAs7(
|
|
6604
7077
|
"INTERNAL",
|
|
6605
7078
|
OP_WITHDRAWALS.eth.encodeWithdraw,
|
|
6606
|
-
() => Promise.resolve(base.interface.encodeFunctionData("withdraw", [
|
|
7079
|
+
() => Promise.resolve(base.interface.encodeFunctionData("withdraw", [p.to ?? ctx.sender])),
|
|
6607
7080
|
{
|
|
6608
|
-
ctx: { where: "L2BaseToken.withdraw", to:
|
|
7081
|
+
ctx: { where: "L2BaseToken.withdraw", to: p.to ?? ctx.sender },
|
|
6609
7082
|
message: "Failed to encode ETH withdraw calldata."
|
|
6610
7083
|
}
|
|
6611
7084
|
);
|
|
@@ -6613,38 +7086,29 @@ function routeEthBase() {
|
|
|
6613
7086
|
to: L2_BASE_TOKEN_ADDRESS,
|
|
6614
7087
|
data,
|
|
6615
7088
|
from: ctx.sender,
|
|
6616
|
-
value: p.amount
|
|
6617
|
-
maxFeePerGas,
|
|
6618
|
-
maxPriorityFeePerGas
|
|
7089
|
+
value: p.amount
|
|
6619
7090
|
};
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
message: "Failed to estimate gas for L2 ETH withdraw."
|
|
6631
|
-
}
|
|
6632
|
-
);
|
|
6633
|
-
tx.gasLimit = BigInt(est) * 115n / 100n;
|
|
6634
|
-
} catch {
|
|
6635
|
-
}
|
|
6636
|
-
}
|
|
7091
|
+
const gas = await quoteL2Gas4({ ctx, tx });
|
|
7092
|
+
if (gas) {
|
|
7093
|
+
tx.gasLimit = gas.gasLimit;
|
|
7094
|
+
tx.maxFeePerGas = gas.maxFeePerGas;
|
|
7095
|
+
tx.maxPriorityFeePerGas = gas.maxPriorityFeePerGas;
|
|
7096
|
+
}
|
|
7097
|
+
const fees = buildFeeBreakdown2({
|
|
7098
|
+
feeToken: L2_BASE_TOKEN_ADDRESS,
|
|
7099
|
+
l2Gas: gas
|
|
7100
|
+
});
|
|
6637
7101
|
steps.push({
|
|
6638
7102
|
key: "l2-base-token:withdraw",
|
|
6639
7103
|
kind: "l2-base-token:withdraw",
|
|
6640
7104
|
description: "Withdraw ETH via L2 Base Token System",
|
|
6641
7105
|
tx
|
|
6642
7106
|
});
|
|
6643
|
-
return { steps, approvals: [],
|
|
7107
|
+
return { steps, approvals: [], fees };
|
|
6644
7108
|
}
|
|
6645
7109
|
};
|
|
6646
7110
|
}
|
|
6647
|
-
var { wrapAs:
|
|
7111
|
+
var { wrapAs: wrapAs8 } = createErrorHandlers("withdrawals");
|
|
6648
7112
|
var SIG = {
|
|
6649
7113
|
withdraw: "withdraw(bytes32,bytes)"
|
|
6650
7114
|
};
|
|
@@ -6653,10 +7117,8 @@ function routeErc20NonBase2() {
|
|
|
6653
7117
|
async build(p, ctx) {
|
|
6654
7118
|
const steps = [];
|
|
6655
7119
|
const approvals = [];
|
|
6656
|
-
const { gasLimit: overrideGasLimit, maxFeePerGas, maxPriorityFeePerGas } = ctx.fee;
|
|
6657
|
-
const txOverrides = overrideGasLimit != null ? { maxFeePerGas, maxPriorityFeePerGas, gasLimit: overrideGasLimit } : { maxFeePerGas, maxPriorityFeePerGas };
|
|
6658
7120
|
const erc20 = new ethers.Contract(p.token, IERC20_default, ctx.client.getL2Signer());
|
|
6659
|
-
const current = await
|
|
7121
|
+
const current = await wrapAs8(
|
|
6660
7122
|
"CONTRACT",
|
|
6661
7123
|
OP_WITHDRAWALS.erc20.allowance,
|
|
6662
7124
|
() => erc20.allowance(ctx.sender, ctx.l2NativeTokenVault),
|
|
@@ -6676,39 +7138,51 @@ function routeErc20NonBase2() {
|
|
|
6676
7138
|
ctx.l2NativeTokenVault,
|
|
6677
7139
|
p.amount
|
|
6678
7140
|
]);
|
|
7141
|
+
const approveTx = {
|
|
7142
|
+
to: p.token,
|
|
7143
|
+
data,
|
|
7144
|
+
from: ctx.sender
|
|
7145
|
+
};
|
|
7146
|
+
const approveGas = await quoteL2Gas4({ ctx, tx: approveTx });
|
|
7147
|
+
if (approveGas) {
|
|
7148
|
+
approveTx.gasLimit = approveGas.gasLimit;
|
|
7149
|
+
approveTx.maxFeePerGas = approveGas.maxFeePerGas;
|
|
7150
|
+
approveTx.maxPriorityFeePerGas = approveGas.maxPriorityFeePerGas;
|
|
7151
|
+
}
|
|
6679
7152
|
steps.push({
|
|
6680
7153
|
key: `approve:l2:${p.token}:${ctx.l2NativeTokenVault}`,
|
|
6681
7154
|
kind: "approve:l2",
|
|
6682
7155
|
description: `Approve ${p.amount} to NativeTokenVault`,
|
|
6683
|
-
tx:
|
|
7156
|
+
tx: approveTx
|
|
6684
7157
|
});
|
|
6685
7158
|
}
|
|
6686
|
-
const
|
|
6687
|
-
const assetId = await
|
|
7159
|
+
const resolved = ctx.resolvedToken ?? (ctx.tokens ? await ctx.tokens.resolve(p.token, { chain: "l2" }) : void 0);
|
|
7160
|
+
const assetId = resolved?.assetId ?? await wrapAs8(
|
|
6688
7161
|
"CONTRACT",
|
|
6689
7162
|
OP_WITHDRAWALS.erc20.ensureRegistered,
|
|
6690
|
-
() =>
|
|
7163
|
+
async () => {
|
|
7164
|
+
const ntv = await ctx.contracts.l2NativeTokenVault();
|
|
7165
|
+
const ensured = await ntv.getFunction("ensureTokenIsRegistered").staticCall(p.token);
|
|
7166
|
+
return ensured;
|
|
7167
|
+
},
|
|
6691
7168
|
{
|
|
6692
7169
|
ctx: { where: "L2NativeTokenVault.ensureTokenIsRegistered", token: p.token },
|
|
6693
7170
|
message: "Failed to ensure token is registered in L2NativeTokenVault."
|
|
6694
7171
|
}
|
|
6695
7172
|
);
|
|
6696
|
-
const assetData = await
|
|
7173
|
+
const assetData = await wrapAs8(
|
|
6697
7174
|
"INTERNAL",
|
|
6698
7175
|
OP_WITHDRAWALS.erc20.encodeAssetData,
|
|
6699
7176
|
() => Promise.resolve(
|
|
6700
|
-
|
|
6701
|
-
["uint256", "address", "address"],
|
|
6702
|
-
[p.amount, p.to ?? ctx.sender, p.token]
|
|
6703
|
-
)
|
|
7177
|
+
encodeNativeTokenVaultTransferData(p.amount, p.to ?? ctx.sender, p.token)
|
|
6704
7178
|
),
|
|
6705
7179
|
{
|
|
6706
7180
|
ctx: { where: "AbiCoder.encode", token: p.token, to: p.to ?? ctx.sender },
|
|
6707
7181
|
message: "Failed to encode burn/withdraw asset data."
|
|
6708
7182
|
}
|
|
6709
7183
|
);
|
|
6710
|
-
const l2ar =
|
|
6711
|
-
const dataWithdraw = await
|
|
7184
|
+
const l2ar = await ctx.contracts.l2AssetRouter();
|
|
7185
|
+
const dataWithdraw = await wrapAs8(
|
|
6712
7186
|
"INTERNAL",
|
|
6713
7187
|
OP_WITHDRAWALS.erc20.encodeWithdraw,
|
|
6714
7188
|
() => Promise.resolve(l2ar.interface.encodeFunctionData(SIG.withdraw, [assetId, assetData])),
|
|
@@ -6720,81 +7194,25 @@ function routeErc20NonBase2() {
|
|
|
6720
7194
|
const withdrawTx = {
|
|
6721
7195
|
to: ctx.l2AssetRouter,
|
|
6722
7196
|
data: dataWithdraw,
|
|
6723
|
-
from: ctx.sender
|
|
6724
|
-
...txOverrides
|
|
7197
|
+
from: ctx.sender
|
|
6725
7198
|
};
|
|
7199
|
+
const withdrawGas = await quoteL2Gas4({ ctx, tx: withdrawTx });
|
|
7200
|
+
if (withdrawGas) {
|
|
7201
|
+
withdrawTx.gasLimit = withdrawGas.gasLimit;
|
|
7202
|
+
withdrawTx.maxFeePerGas = withdrawGas.maxFeePerGas;
|
|
7203
|
+
withdrawTx.maxPriorityFeePerGas = withdrawGas.maxPriorityFeePerGas;
|
|
7204
|
+
}
|
|
6726
7205
|
steps.push({
|
|
6727
7206
|
key: "l2-asset-router:withdraw",
|
|
6728
7207
|
kind: "l2-asset-router:withdraw",
|
|
6729
7208
|
description: "Burn on L2 & send L2\u2192L1 message",
|
|
6730
7209
|
tx: withdrawTx
|
|
6731
7210
|
});
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
}
|
|
6736
|
-
var { wrapAs: wrapAs7 } = createErrorHandlers("withdrawals");
|
|
6737
|
-
function routeEthNonBase2() {
|
|
6738
|
-
return {
|
|
6739
|
-
async preflight(p, ctx) {
|
|
6740
|
-
await wrapAs7(
|
|
6741
|
-
"VALIDATION",
|
|
6742
|
-
OP_WITHDRAWALS.ethNonBase.assertNonEthBase,
|
|
6743
|
-
() => {
|
|
6744
|
-
if (p.token.toLowerCase() !== L2_BASE_TOKEN_ADDRESS.toLowerCase()) {
|
|
6745
|
-
throw new Error("eth-nonbase route requires the L2 base-token alias (0x\u2026800A).");
|
|
6746
|
-
}
|
|
6747
|
-
if (ctx.baseIsEth) {
|
|
6748
|
-
throw new Error("eth-nonbase route requires chain base \u2260 ETH.");
|
|
6749
|
-
}
|
|
6750
|
-
},
|
|
6751
|
-
{ ctx: { token: p.token, baseIsEth: ctx.baseIsEth } }
|
|
6752
|
-
);
|
|
6753
|
-
},
|
|
6754
|
-
async build(p, ctx) {
|
|
6755
|
-
const steps = [];
|
|
6756
|
-
const { gasLimit: overrideGasLimit, maxFeePerGas, maxPriorityFeePerGas } = ctx.fee;
|
|
6757
|
-
const toL1 = p.to ?? ctx.sender;
|
|
6758
|
-
const iface = new ethers.Interface(IBaseToken_default);
|
|
6759
|
-
const data = await wrapAs7(
|
|
6760
|
-
"INTERNAL",
|
|
6761
|
-
OP_WITHDRAWALS.eth.encodeWithdraw,
|
|
6762
|
-
// reuse label for base-token system call
|
|
6763
|
-
() => Promise.resolve(iface.encodeFunctionData("withdraw", [toL1])),
|
|
6764
|
-
{ ctx: { where: "L2BaseToken.withdraw", to: toL1 } }
|
|
6765
|
-
);
|
|
6766
|
-
const tx = {
|
|
6767
|
-
to: L2_BASE_TOKEN_ADDRESS,
|
|
6768
|
-
data,
|
|
6769
|
-
from: ctx.sender,
|
|
6770
|
-
value: p.amount,
|
|
6771
|
-
maxFeePerGas,
|
|
6772
|
-
maxPriorityFeePerGas
|
|
6773
|
-
};
|
|
6774
|
-
if (overrideGasLimit != null) {
|
|
6775
|
-
tx.gasLimit = overrideGasLimit;
|
|
6776
|
-
} else {
|
|
6777
|
-
try {
|
|
6778
|
-
const est = await wrapAs7(
|
|
6779
|
-
"RPC",
|
|
6780
|
-
OP_WITHDRAWALS.eth.estGas,
|
|
6781
|
-
() => ctx.client.l2.estimateGas(tx),
|
|
6782
|
-
{
|
|
6783
|
-
ctx: { where: "l2.estimateGas", to: L2_BASE_TOKEN_ADDRESS },
|
|
6784
|
-
message: "Failed to estimate gas for L2 base-token withdraw."
|
|
6785
|
-
}
|
|
6786
|
-
);
|
|
6787
|
-
tx.gasLimit = BigInt(est) * 115n / 100n;
|
|
6788
|
-
} catch {
|
|
6789
|
-
}
|
|
6790
|
-
}
|
|
6791
|
-
steps.push({
|
|
6792
|
-
key: "l2-base-token:withdraw",
|
|
6793
|
-
kind: "l2-base-token:withdraw",
|
|
6794
|
-
description: "Withdraw base token via L2 Base Token System (base \u2260 ETH)",
|
|
6795
|
-
tx
|
|
7211
|
+
const fees = buildFeeBreakdown2({
|
|
7212
|
+
feeToken: ctx.baseTokenL1 ?? await ctx.client.baseToken(ctx.chainIdL2),
|
|
7213
|
+
l2Gas: withdrawGas
|
|
6796
7214
|
});
|
|
6797
|
-
return { steps, approvals
|
|
7215
|
+
return { steps, approvals, fees };
|
|
6798
7216
|
}
|
|
6799
7217
|
};
|
|
6800
7218
|
}
|
|
@@ -6832,7 +7250,7 @@ function messengerLogIndex(raw, opts) {
|
|
|
6832
7250
|
}
|
|
6833
7251
|
|
|
6834
7252
|
// src/adapters/ethers/resources/withdrawals/services/finalization.ts
|
|
6835
|
-
var { wrapAs:
|
|
7253
|
+
var { wrapAs: wrapAs9 } = createErrorHandlers("withdrawals");
|
|
6836
7254
|
var IL1NullifierMini = [
|
|
6837
7255
|
"function isWithdrawalFinalized(uint256,uint256,uint256) view returns (bool)"
|
|
6838
7256
|
];
|
|
@@ -6840,7 +7258,7 @@ function createFinalizationServices(client) {
|
|
|
6840
7258
|
const { l1, l2, signer } = client;
|
|
6841
7259
|
return {
|
|
6842
7260
|
async fetchFinalizeDepositParams(l2TxHash) {
|
|
6843
|
-
const parsed = await
|
|
7261
|
+
const parsed = await wrapAs9(
|
|
6844
7262
|
"RPC",
|
|
6845
7263
|
OP_WITHDRAWALS.finalize.fetchParams.receipt,
|
|
6846
7264
|
() => client.zks.getReceiptWithL2ToL1(l2TxHash),
|
|
@@ -6857,7 +7275,7 @@ function createFinalizationServices(client) {
|
|
|
6857
7275
|
context: { l2TxHash }
|
|
6858
7276
|
});
|
|
6859
7277
|
}
|
|
6860
|
-
const ev = await
|
|
7278
|
+
const ev = await wrapAs9(
|
|
6861
7279
|
"INTERNAL",
|
|
6862
7280
|
OP_WITHDRAWALS.finalize.fetchParams.findMessage,
|
|
6863
7281
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
|
|
@@ -6867,7 +7285,7 @@ function createFinalizationServices(client) {
|
|
|
6867
7285
|
message: "Failed to locate L1MessageSent event in L2 receipt."
|
|
6868
7286
|
}
|
|
6869
7287
|
);
|
|
6870
|
-
const message = await
|
|
7288
|
+
const message = await wrapAs9(
|
|
6871
7289
|
"INTERNAL",
|
|
6872
7290
|
OP_WITHDRAWALS.finalize.fetchParams.decodeMessage,
|
|
6873
7291
|
() => Promise.resolve(ethers.AbiCoder.defaultAbiCoder().decode(["bytes"], ev.data)[0]),
|
|
@@ -6876,7 +7294,7 @@ function createFinalizationServices(client) {
|
|
|
6876
7294
|
message: "Failed to decode withdrawal message."
|
|
6877
7295
|
}
|
|
6878
7296
|
);
|
|
6879
|
-
const raw = await
|
|
7297
|
+
const raw = await wrapAs9(
|
|
6880
7298
|
"RPC",
|
|
6881
7299
|
OP_WITHDRAWALS.finalize.fetchParams.rawReceipt,
|
|
6882
7300
|
() => client.zks.getReceiptWithL2ToL1(l2TxHash),
|
|
@@ -6893,7 +7311,7 @@ function createFinalizationServices(client) {
|
|
|
6893
7311
|
context: { l2TxHash }
|
|
6894
7312
|
});
|
|
6895
7313
|
}
|
|
6896
|
-
const idx = await
|
|
7314
|
+
const idx = await wrapAs9(
|
|
6897
7315
|
"INTERNAL",
|
|
6898
7316
|
OP_WITHDRAWALS.finalize.fetchParams.messengerIndex,
|
|
6899
7317
|
() => Promise.resolve(messengerLogIndex(raw, { index: 0, messenger: L1_MESSENGER_ADDRESS })),
|
|
@@ -6902,7 +7320,7 @@ function createFinalizationServices(client) {
|
|
|
6902
7320
|
message: "Failed to derive messenger log index."
|
|
6903
7321
|
}
|
|
6904
7322
|
);
|
|
6905
|
-
const proof = await
|
|
7323
|
+
const proof = await wrapAs9(
|
|
6906
7324
|
"RPC",
|
|
6907
7325
|
OP_WITHDRAWALS.finalize.fetchParams.proof,
|
|
6908
7326
|
() => client.zks.getL2ToL1LogProof(l2TxHash, idx),
|
|
@@ -6911,7 +7329,7 @@ function createFinalizationServices(client) {
|
|
|
6911
7329
|
message: "Failed to fetch L2\u2192L1 log proof."
|
|
6912
7330
|
}
|
|
6913
7331
|
);
|
|
6914
|
-
const { chainId } = await
|
|
7332
|
+
const { chainId } = await wrapAs9(
|
|
6915
7333
|
"RPC",
|
|
6916
7334
|
OP_WITHDRAWALS.finalize.fetchParams.network,
|
|
6917
7335
|
() => l2.getNetwork(),
|
|
@@ -6930,7 +7348,7 @@ function createFinalizationServices(client) {
|
|
|
6930
7348
|
message,
|
|
6931
7349
|
merkleProof: proof.proof
|
|
6932
7350
|
};
|
|
6933
|
-
const { l1Nullifier } = await
|
|
7351
|
+
const { l1Nullifier } = await wrapAs9(
|
|
6934
7352
|
"INTERNAL",
|
|
6935
7353
|
OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
|
|
6936
7354
|
() => client.ensureAddresses(),
|
|
@@ -6942,7 +7360,7 @@ function createFinalizationServices(client) {
|
|
|
6942
7360
|
return { params, nullifier: l1Nullifier };
|
|
6943
7361
|
},
|
|
6944
7362
|
async simulateFinalizeReadiness(params) {
|
|
6945
|
-
const { l1Nullifier } = await
|
|
7363
|
+
const { l1Nullifier } = await wrapAs9(
|
|
6946
7364
|
"INTERNAL",
|
|
6947
7365
|
OP_WITHDRAWALS.finalize.readiness.ensureAddresses,
|
|
6948
7366
|
() => client.ensureAddresses(),
|
|
@@ -6954,7 +7372,7 @@ function createFinalizationServices(client) {
|
|
|
6954
7372
|
const done = await (async () => {
|
|
6955
7373
|
try {
|
|
6956
7374
|
const cMini = new ethers.Contract(l1Nullifier, IL1NullifierMini, l1);
|
|
6957
|
-
const isFinalized = await
|
|
7375
|
+
const isFinalized = await wrapAs9(
|
|
6958
7376
|
"RPC",
|
|
6959
7377
|
OP_WITHDRAWALS.finalize.readiness.isFinalized,
|
|
6960
7378
|
() => cMini.isWithdrawalFinalized(
|
|
@@ -6982,7 +7400,7 @@ function createFinalizationServices(client) {
|
|
|
6982
7400
|
}
|
|
6983
7401
|
},
|
|
6984
7402
|
async isWithdrawalFinalized(key) {
|
|
6985
|
-
const { l1Nullifier } = await
|
|
7403
|
+
const { l1Nullifier } = await wrapAs9(
|
|
6986
7404
|
"INTERNAL",
|
|
6987
7405
|
OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
|
|
6988
7406
|
() => client.ensureAddresses(),
|
|
@@ -6992,7 +7410,7 @@ function createFinalizationServices(client) {
|
|
|
6992
7410
|
}
|
|
6993
7411
|
);
|
|
6994
7412
|
const c = new ethers.Contract(l1Nullifier, IL1NullifierMini, l1);
|
|
6995
|
-
return await
|
|
7413
|
+
return await wrapAs9(
|
|
6996
7414
|
"RPC",
|
|
6997
7415
|
OP_WITHDRAWALS.finalize.isFinalized,
|
|
6998
7416
|
() => c.isWithdrawalFinalized(key.chainIdL2, key.l2BatchNumber, key.l2MessageIndex),
|
|
@@ -7003,7 +7421,7 @@ function createFinalizationServices(client) {
|
|
|
7003
7421
|
);
|
|
7004
7422
|
},
|
|
7005
7423
|
async estimateFinalization(params) {
|
|
7006
|
-
const { l1Nullifier } = await
|
|
7424
|
+
const { l1Nullifier } = await wrapAs9(
|
|
7007
7425
|
"INTERNAL",
|
|
7008
7426
|
OP_WITHDRAWALS.finalize.estimate,
|
|
7009
7427
|
() => client.ensureAddresses(),
|
|
@@ -7014,7 +7432,7 @@ function createFinalizationServices(client) {
|
|
|
7014
7432
|
);
|
|
7015
7433
|
const signer2 = client.getL1Signer();
|
|
7016
7434
|
const c = new ethers.Contract(l1Nullifier, IL1Nullifier_default, signer2);
|
|
7017
|
-
const gasLimit = await
|
|
7435
|
+
const gasLimit = await wrapAs9(
|
|
7018
7436
|
"RPC",
|
|
7019
7437
|
OP_WITHDRAWALS.finalize.estimate,
|
|
7020
7438
|
() => c.finalizeDeposit.estimateGas(params),
|
|
@@ -7029,7 +7447,7 @@ function createFinalizationServices(client) {
|
|
|
7029
7447
|
message: "Failed to estimate gas for finalizeDeposit."
|
|
7030
7448
|
}
|
|
7031
7449
|
);
|
|
7032
|
-
const feeData = await
|
|
7450
|
+
const feeData = await wrapAs9("RPC", OP_WITHDRAWALS.finalize.estimate, () => l1.getFeeData(), {
|
|
7033
7451
|
ctx: { where: "l1.getFeeData" },
|
|
7034
7452
|
message: "Failed to estimate fee data for finalizeDeposit."
|
|
7035
7453
|
});
|
|
@@ -7050,7 +7468,7 @@ function createFinalizationServices(client) {
|
|
|
7050
7468
|
};
|
|
7051
7469
|
},
|
|
7052
7470
|
async finalizeDeposit(params) {
|
|
7053
|
-
const { l1Nullifier } = await
|
|
7471
|
+
const { l1Nullifier } = await wrapAs9(
|
|
7054
7472
|
"INTERNAL",
|
|
7055
7473
|
OP_WITHDRAWALS.finalize.fetchParams.ensureAddresses,
|
|
7056
7474
|
() => client.ensureAddresses(),
|
|
@@ -7106,45 +7524,32 @@ function createFinalizationServices(client) {
|
|
|
7106
7524
|
|
|
7107
7525
|
// src/adapters/ethers/resources/withdrawals/index.ts
|
|
7108
7526
|
var ROUTES2 = {
|
|
7109
|
-
|
|
7527
|
+
base: routeEthBase(),
|
|
7110
7528
|
// BaseTokenSystem.withdraw, chain base = ETH
|
|
7111
|
-
"eth-nonbase": routeEthNonBase2(),
|
|
7112
|
-
// BaseTokenSystem.withdraw, chain base ≠ ETH
|
|
7113
7529
|
"erc20-nonbase": routeErc20NonBase2()
|
|
7114
7530
|
// AssetRouter.withdraw for non-base ERC-20s
|
|
7115
7531
|
};
|
|
7116
|
-
function createWithdrawalsResource(client) {
|
|
7532
|
+
function createWithdrawalsResource(client, tokens, contracts) {
|
|
7117
7533
|
const svc = createFinalizationServices(client);
|
|
7118
7534
|
const { wrap: wrap2, toResult: toResult2 } = createErrorHandlers("withdrawals");
|
|
7535
|
+
const tokensResource = tokens ?? createTokensResource(client);
|
|
7536
|
+
const contractsResource = contracts ?? createContractsResource(client);
|
|
7119
7537
|
async function buildPlan(p) {
|
|
7120
|
-
const ctx = await commonCtx2(p, client);
|
|
7538
|
+
const ctx = await commonCtx2(p, client, tokensResource, contractsResource);
|
|
7121
7539
|
await ROUTES2[ctx.route].preflight?.(p, ctx);
|
|
7122
|
-
const { steps, approvals } = await ROUTES2[ctx.route].build(p, ctx);
|
|
7123
|
-
|
|
7124
|
-
if (ctx.fee.gasLimit != null) return ctx.fee.gasLimit;
|
|
7125
|
-
for (let i = steps.length - 1; i >= 0; i--) {
|
|
7126
|
-
const candidate = steps[i].tx.gasLimit;
|
|
7127
|
-
if (candidate == null) continue;
|
|
7128
|
-
if (typeof candidate === "bigint") return candidate;
|
|
7129
|
-
try {
|
|
7130
|
-
return BigInt(candidate.toString());
|
|
7131
|
-
} catch {
|
|
7132
|
-
}
|
|
7133
|
-
}
|
|
7134
|
-
return void 0;
|
|
7135
|
-
};
|
|
7136
|
-
const gasLimit = resolveGasLimit();
|
|
7137
|
-
const summary = {
|
|
7540
|
+
const { steps, approvals, fees } = await ROUTES2[ctx.route].build(p, ctx);
|
|
7541
|
+
return {
|
|
7138
7542
|
route: ctx.route,
|
|
7139
|
-
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7543
|
+
summary: {
|
|
7544
|
+
route: ctx.route,
|
|
7545
|
+
approvalsNeeded: approvals,
|
|
7546
|
+
amounts: {
|
|
7547
|
+
transfer: { token: p.token, amount: p.amount }
|
|
7548
|
+
},
|
|
7549
|
+
fees
|
|
7550
|
+
},
|
|
7551
|
+
steps
|
|
7146
7552
|
};
|
|
7147
|
-
return { route: ctx.route, summary, steps };
|
|
7148
7553
|
}
|
|
7149
7554
|
const finalizeCache = /* @__PURE__ */ new Map();
|
|
7150
7555
|
const quote = (p) => wrap2(
|
|
@@ -7454,62 +7859,17 @@ function createWithdrawalsResource(client) {
|
|
|
7454
7859
|
|
|
7455
7860
|
// src/adapters/ethers/sdk.ts
|
|
7456
7861
|
function createEthersSdk(client) {
|
|
7862
|
+
const tokens = createTokensResource(client);
|
|
7863
|
+
const contracts = createContractsResource(client);
|
|
7457
7864
|
return {
|
|
7458
|
-
deposits: createDepositsResource(client),
|
|
7459
|
-
withdrawals: createWithdrawalsResource(client),
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
addresses: () => client.ensureAddresses(),
|
|
7463
|
-
contracts: () => client.contracts(),
|
|
7464
|
-
async l1AssetRouter() {
|
|
7465
|
-
const { l1AssetRouter } = await client.contracts();
|
|
7466
|
-
return l1AssetRouter;
|
|
7467
|
-
},
|
|
7468
|
-
async l1NativeTokenVault() {
|
|
7469
|
-
const { l1NativeTokenVault } = await client.contracts();
|
|
7470
|
-
return l1NativeTokenVault;
|
|
7471
|
-
},
|
|
7472
|
-
async l1Nullifier() {
|
|
7473
|
-
const { l1Nullifier } = await client.contracts();
|
|
7474
|
-
return l1Nullifier;
|
|
7475
|
-
},
|
|
7476
|
-
async baseToken(chainId) {
|
|
7477
|
-
const id = chainId ?? BigInt((await client.l2.getNetwork()).chainId);
|
|
7478
|
-
return client.baseToken(id);
|
|
7479
|
-
},
|
|
7480
|
-
async l2TokenAddress(l1Token) {
|
|
7481
|
-
if (isAddressEq(l1Token, FORMAL_ETH_ADDRESS)) {
|
|
7482
|
-
return ETH_ADDRESS;
|
|
7483
|
-
}
|
|
7484
|
-
const { chainId } = await client.l2.getNetwork();
|
|
7485
|
-
const base = await client.baseToken(BigInt(chainId));
|
|
7486
|
-
if (isAddressEq(l1Token, base)) {
|
|
7487
|
-
return L2_BASE_TOKEN_ADDRESS;
|
|
7488
|
-
}
|
|
7489
|
-
const { l2NativeTokenVault } = await client.contracts();
|
|
7490
|
-
const addr = await l2NativeTokenVault.l2TokenAddress(l1Token);
|
|
7491
|
-
return addr;
|
|
7492
|
-
},
|
|
7493
|
-
async l1TokenAddress(l2Token) {
|
|
7494
|
-
if (isAddressEq(l2Token, ETH_ADDRESS)) {
|
|
7495
|
-
return ETH_ADDRESS;
|
|
7496
|
-
}
|
|
7497
|
-
const { l2AssetRouter } = await client.contracts();
|
|
7498
|
-
const addr = await l2AssetRouter.l1TokenAddress(l2Token);
|
|
7499
|
-
return addr;
|
|
7500
|
-
},
|
|
7501
|
-
async assetId(l1Token) {
|
|
7502
|
-
const norm = isAddressEq(l1Token, FORMAL_ETH_ADDRESS) ? ETH_ADDRESS : l1Token;
|
|
7503
|
-
const { l1NativeTokenVault } = await client.contracts();
|
|
7504
|
-
const id = await l1NativeTokenVault.assetId(norm);
|
|
7505
|
-
return id;
|
|
7506
|
-
}
|
|
7507
|
-
}
|
|
7865
|
+
deposits: createDepositsResource(client, tokens, contracts),
|
|
7866
|
+
withdrawals: createWithdrawalsResource(client, tokens, contracts),
|
|
7867
|
+
tokens,
|
|
7868
|
+
contracts
|
|
7508
7869
|
};
|
|
7509
7870
|
}
|
|
7510
7871
|
|
|
7511
7872
|
exports.buildDirectRequestStruct = buildDirectRequestStruct;
|
|
7512
|
-
exports.checkBaseCost = checkBaseCost;
|
|
7513
7873
|
exports.classifyReadinessFromRevert = classifyReadinessFromRevert;
|
|
7514
7874
|
exports.createClient = createEthersClient;
|
|
7515
7875
|
exports.createDepositsResource = createDepositsResource;
|
|
@@ -7517,21 +7877,15 @@ exports.createErrorHandlers = createErrorHandlers;
|
|
|
7517
7877
|
exports.createEthersClient = createEthersClient;
|
|
7518
7878
|
exports.createEthersSdk = createEthersSdk;
|
|
7519
7879
|
exports.createFinalizationServices = createFinalizationServices;
|
|
7880
|
+
exports.createTokensResource = createTokensResource;
|
|
7520
7881
|
exports.createWithdrawalsResource = createWithdrawalsResource;
|
|
7521
7882
|
exports.decodeRevert = decodeRevert;
|
|
7522
|
-
exports.encodeNTVAssetId = encodeNTVAssetId;
|
|
7523
|
-
exports.encodeNTVTransferData = encodeNTVTransferData;
|
|
7524
|
-
exports.encodeNativeTokenVaultAssetId = encodeNativeTokenVaultAssetId;
|
|
7525
7883
|
exports.encodeNativeTokenVaultTransferData = encodeNativeTokenVaultTransferData;
|
|
7526
7884
|
exports.encodeSecondBridgeArgs = encodeSecondBridgeArgs;
|
|
7527
7885
|
exports.encodeSecondBridgeDataV1 = encodeSecondBridgeDataV1;
|
|
7528
7886
|
exports.encodeSecondBridgeErc20Args = encodeSecondBridgeErc20Args;
|
|
7529
7887
|
exports.encodeSecondBridgeEthArgs = encodeSecondBridgeEthArgs;
|
|
7530
|
-
exports.getFeeOverrides = getFeeOverrides;
|
|
7531
|
-
exports.getGasPriceWei = getGasPriceWei;
|
|
7532
|
-
exports.getL2FeeOverrides = getL2FeeOverrides;
|
|
7533
7888
|
exports.registerErrorAbi = registerErrorAbi;
|
|
7534
|
-
exports.scaleGasLimit = scaleGasLimit;
|
|
7535
7889
|
exports.toZKsyncError = toZKsyncError;
|
|
7536
7890
|
//# sourceMappingURL=index.cjs.map
|
|
7537
7891
|
//# sourceMappingURL=index.cjs.map
|