zksync-web3
Advanced tools
Comparing version 0.14.4-beta.5 to 0.14.4
import { BigNumber, BigNumberish, BytesLike, ethers } from 'ethers'; | ||
import { Provider } from './provider'; | ||
import { Address, BalancesMap, BlockTag, Eip712Meta, FullDepositFee, PriorityOpResponse, TransactionResponse } from './types'; | ||
declare type Constructor<T = {}> = new (...args: any[]) => T; | ||
import { Address, BalancesMap, BlockTag, Eip712Meta, PriorityOpResponse, TransactionResponse } from './types'; | ||
type Constructor<T = {}> = new (...args: any[]) => T; | ||
interface TxSender { | ||
@@ -19,3 +19,2 @@ sendTransaction(tx: ethers.providers.TransactionRequest): Promise<ethers.providers.TransactionResponse>; | ||
getBalanceL1(token?: Address, blockTag?: ethers.providers.BlockTag): Promise<BigNumber>; | ||
getAllowanceL1(token: Address, bridgeAddress?: Address, blockTag?: ethers.providers.BlockTag): Promise<BigNumber>; | ||
l2TokenAddress(token: Address): Promise<string>; | ||
@@ -62,9 +61,2 @@ approveERC20(token: Address, amount: BigNumberish, overrides?: ethers.Overrides & { | ||
}): Promise<any>; | ||
getFullRequiredDepositFee(transaction: { | ||
token: Address; | ||
to?: Address; | ||
bridgeAddress?: Address; | ||
gasPerPubdataByte?: BigNumberish; | ||
overrides?: ethers.PayableOverrides; | ||
}): Promise<FullDepositFee>; | ||
_getWithdrawalLog(withdrawalHash: BytesLike, index?: number): Promise<{ | ||
@@ -71,0 +63,0 @@ log: import("./types").Log; |
@@ -38,7 +38,2 @@ "use strict"; | ||
} | ||
async getAllowanceL1(token, bridgeAddress, blockTag) { | ||
const erc20contract = typechain_1.IERC20MetadataFactory.connect(token, this._providerL1()); | ||
bridgeAddress !== null && bridgeAddress !== void 0 ? bridgeAddress : (bridgeAddress = (await this.getL1BridgeContracts()).erc20.address); | ||
return await erc20contract.allowance(await this.getAddress(), bridgeAddress, { blockTag }); | ||
} | ||
async l2TokenAddress(token) { | ||
@@ -65,3 +60,2 @@ if (token == utils_1.ETH_ADDRESS) { | ||
} | ||
overrides !== null && overrides !== void 0 ? overrides : (overrides = {}); | ||
return await erc20contract.approve(bridgeAddress, amount, overrides); | ||
@@ -78,10 +72,5 @@ } | ||
async deposit(transaction) { | ||
var _a, _b, _c, _d; | ||
var _e; | ||
var _a; | ||
const depositTx = await this.getDepositTx(transaction); | ||
if (transaction.token == utils_1.ETH_ADDRESS) { | ||
const baseGasLimit = await this.estimateGasRequestExecute(depositTx); | ||
const gasLimit = (0, utils_1.scaleGasLimit)(baseGasLimit); | ||
(_a = depositTx.overrides) !== null && _a !== void 0 ? _a : (depositTx.overrides = {}); | ||
(_b = (_e = depositTx.overrides).gasLimit) !== null && _b !== void 0 ? _b : (_e.gasLimit = gasLimit); | ||
return this.requestExecute(depositTx); | ||
@@ -92,15 +81,8 @@ } | ||
if (transaction.approveERC20) { | ||
// We only request the allowance if the current one is not enough. | ||
const allowance = await this.getAllowanceL1(transaction.token); | ||
if (allowance.lt(transaction.amount)) { | ||
const approveTx = await this.approveERC20(transaction.token, transaction.amount, { | ||
bridgeAddress: (_c = transaction.bridgeAddress) !== null && _c !== void 0 ? _c : bridgeContracts.erc20.address, | ||
...transaction.approveOverrides | ||
}); | ||
await approveTx.wait(); | ||
} | ||
const approveTx = await this.approveERC20(transaction.token, transaction.amount, { | ||
bridgeAddress: (_a = transaction.bridgeAddress) !== null && _a !== void 0 ? _a : bridgeContracts.erc20.address, | ||
...transaction.approveOverrides | ||
}); | ||
await approveTx.wait(); | ||
} | ||
const baseGasLimit = await this._providerL1().estimateGas(depositTx); | ||
const gasLimit = (0, utils_1.scaleGasLimit)(baseGasLimit); | ||
(_d = depositTx.gasLimit) !== null && _d !== void 0 ? _d : (depositTx.gasLimit = gasLimit); | ||
return await this._providerL2().getPriorityOpResponse(await this._signerL1().sendTransaction(depositTx)); | ||
@@ -111,10 +93,8 @@ } | ||
const depositTx = await this.getDepositTx(transaction); | ||
let baseGasLimit; | ||
if (transaction.token == utils_1.ETH_ADDRESS) { | ||
baseGasLimit = await this.estimateGasRequestExecute(depositTx); | ||
return await this.estimateGasRequestExecute(depositTx); | ||
} | ||
else { | ||
baseGasLimit = await this._providerL1().estimateGas(depositTx); | ||
return await this._providerL1().estimateGas(depositTx); | ||
} | ||
return (0, utils_1.scaleGasLimit)(baseGasLimit); | ||
} | ||
@@ -160,70 +140,8 @@ async getDepositTx(transaction) { | ||
await (0, utils_1.checkBaseCost)(baseCost, overrides.value); | ||
// TODO: compatibility layer: using the old API which uses msg.sender as the | ||
// refund recipient, to make the SDK compatible with the old contracts. | ||
// const contract = bridgeContracts.erc20 as ethers.Contract; | ||
return await bridgeContracts.erc20.populateTransaction.deposit(...args, overrides); | ||
} | ||
} | ||
// Retrieves the full needed ETH fee for the deposit. | ||
// Returns the L1 fee and the L2 fee. | ||
async getFullRequiredDepositFee(transaction) { | ||
var _a, _b, _c; | ||
// It is assumed that the L2 fee for the transaction does not depend on its value. | ||
const dummyAmount = '1'; | ||
const { ...tx } = transaction; | ||
const zksyncContract = await this.getMainContract(); | ||
(_a = tx.overrides) !== null && _a !== void 0 ? _a : (tx.overrides = {}); | ||
await insertGasPrice(this._providerL1(), tx.overrides); | ||
const gasPriceForMessages = (await tx.overrides.maxFeePerGas) || (await tx.overrides.gasPrice); | ||
(_b = tx.to) !== null && _b !== void 0 ? _b : (tx.to = await this.getAddress()); | ||
(_c = tx.gasPerPubdataByte) !== null && _c !== void 0 ? _c : (tx.gasPerPubdataByte = utils_1.REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT); | ||
const l2GasLimit = await (0, utils_1.estimateDefaultBridgeDepositL2Gas)(this._providerL1(), this._providerL2(), tx.token, dummyAmount, tx.to, await this.getAddress(), tx.gasPerPubdataByte); | ||
const baseCost = await zksyncContract.l2TransactionBaseCost(gasPriceForMessages, l2GasLimit, tx.gasPerPubdataByte); | ||
const selfBalanceETH = await this.getBalanceL1(); | ||
// We could 0 in, because the final fee will anyway be bigger than | ||
if (baseCost.gte(selfBalanceETH.add(dummyAmount))) { | ||
const recommendedETHBalance = ethers_1.BigNumber.from(tx.token == utils_1.ETH_ADDRESS | ||
? utils_1.L1_RECOMMENDED_MIN_ETH_DEPOSIT_GAS_LIMIT | ||
: utils_1.L1_RECOMMENDED_MIN_ERC20_DEPOSIT_GAS_LIMIT) | ||
.mul(gasPriceForMessages) | ||
.add(baseCost); | ||
const formattedRecommendedBalance = ethers_1.ethers.utils.formatEther(recommendedETHBalance); | ||
throw new Error(`Not enough balance for deposit. Under the provided gas price, the recommended balance to perform a deposit is ${formattedRecommendedBalance} ETH`); | ||
} | ||
// For ETH token the value that the user passes to the estimation is the one which has the | ||
// value for the L2 comission substracted. | ||
let amountForEstimate; | ||
if ((0, utils_1.isETH)(tx.token)) { | ||
amountForEstimate = ethers_1.BigNumber.from(dummyAmount); | ||
} | ||
else { | ||
amountForEstimate = ethers_1.BigNumber.from(dummyAmount); | ||
if ((await this.getAllowanceL1(tx.token)) < amountForEstimate) { | ||
throw new Error('Not enough allowance to cover the deposit'); | ||
} | ||
} | ||
// Deleting the explicit gas limits in the fee estimation | ||
// in order to prevent the situation where the transaction | ||
// fails because the user does not have enough balance | ||
const estimationOverrides = { ...tx.overrides }; | ||
delete estimationOverrides.gasPrice; | ||
delete estimationOverrides.maxFeePerGas; | ||
delete estimationOverrides.maxPriorityFeePerGas; | ||
const l1GasLimit = await this.estimateGasDeposit({ | ||
...tx, | ||
amount: amountForEstimate, | ||
overrides: estimationOverrides, | ||
l2GasLimit | ||
}); | ||
const fullCost = { | ||
baseCost, | ||
l1GasLimit, | ||
l2GasLimit | ||
}; | ||
if (tx.overrides.gasPrice) { | ||
fullCost.gasPrice = ethers_1.BigNumber.from(await tx.overrides.gasPrice); | ||
} | ||
else { | ||
fullCost.maxFeePerGas = ethers_1.BigNumber.from(await tx.overrides.maxFeePerGas); | ||
fullCost.maxPriorityFeePerGas = ethers_1.BigNumber.from(await tx.overrides.maxPriorityFeePerGas); | ||
} | ||
return fullCost; | ||
} | ||
async _getWithdrawalLog(withdrawalHash, index = 0) { | ||
@@ -315,5 +233,2 @@ const hash = ethers_1.ethers.utils.hexlify(withdrawalHash); | ||
const requestExecuteTx = await this.getRequestExecuteTx(transaction); | ||
delete requestExecuteTx.gasPrice; | ||
delete requestExecuteTx.maxFeePerGas; | ||
delete requestExecuteTx.maxPriorityFeePerGas; | ||
return this._providerL1().estimateGas(requestExecuteTx); | ||
@@ -320,0 +235,0 @@ } |
export * as utils from './utils'; | ||
export * as types from './types'; | ||
export { EIP712Signer, Signer, L1Signer, L1VoidSigner, L2VoidSigner } from './signer'; | ||
export { EIP712Signer, Signer, L1Signer } from './signer'; | ||
export { Wallet } from './wallet'; | ||
export { Web3Provider, Provider } from './provider'; | ||
export { ContractFactory, Contract } from './contract'; |
@@ -26,3 +26,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Contract = exports.ContractFactory = exports.Provider = exports.Web3Provider = exports.Wallet = exports.L2VoidSigner = exports.L1VoidSigner = exports.L1Signer = exports.Signer = exports.EIP712Signer = exports.types = exports.utils = void 0; | ||
exports.Contract = exports.ContractFactory = exports.Provider = exports.Web3Provider = exports.Wallet = exports.L1Signer = exports.Signer = exports.EIP712Signer = exports.types = exports.utils = void 0; | ||
exports.utils = __importStar(require("./utils")); | ||
@@ -34,4 +34,2 @@ exports.types = __importStar(require("./types")); | ||
Object.defineProperty(exports, "L1Signer", { enumerable: true, get: function () { return signer_1.L1Signer; } }); | ||
Object.defineProperty(exports, "L1VoidSigner", { enumerable: true, get: function () { return signer_1.L1VoidSigner; } }); | ||
Object.defineProperty(exports, "L2VoidSigner", { enumerable: true, get: function () { return signer_1.L2VoidSigner; } }); | ||
var wallet_1 = require("./wallet"); | ||
@@ -38,0 +36,0 @@ Object.defineProperty(exports, "Wallet", { enumerable: true, get: function () { return wallet_1.Wallet; } }); |
@@ -5,3 +5,3 @@ import { ethers, BigNumber, BigNumberish, utils, providers, BytesLike } from 'ethers'; | ||
import { ConnectionInfo } from '@ethersproject/web'; | ||
import { Address, EventFilter, BlockTag, TransactionResponse, TransactionRequest, TransactionStatus, Token, PriorityOpResponse, BalancesMap, MessageProof, TransactionReceipt, Block, BlockWithTransactions, Log, TransactionDetails, BlockDetails, ContractAccountInfo } from './types'; | ||
import { Address, EventFilter, BlockTag, TransactionResponse, TransactionRequest, TransactionStatus, Token, PriorityOpResponse, BalancesMap, MessageProof, TransactionReceipt, Block, BlockWithTransactions, Log, TransactionDetails, BatchDetails, BlockDetails, ContractAccountInfo } from './types'; | ||
import { Signer } from './signer'; | ||
@@ -42,2 +42,3 @@ export declare class Provider extends ethers.providers.JsonRpcProvider { | ||
getL1BatchNumber(): Promise<number>; | ||
getL1BatchDetails(number: number): Promise<BatchDetails>; | ||
getBlockDetails(number: number): Promise<BlockDetails>; | ||
@@ -44,0 +45,0 @@ getTransactionDetails(txHash: BytesLike): Promise<TransactionDetails>; |
@@ -13,15 +13,2 @@ "use strict"; | ||
class Provider extends ethers_1.ethers.providers.JsonRpcProvider { | ||
constructor(url, network) { | ||
super(url, network); | ||
this.pollingInterval = 500; | ||
const blockTag = this.formatter.blockTag.bind(this.formatter); | ||
this.formatter.blockTag = (tag) => { | ||
if (tag == 'committed' || tag == 'finalized') { | ||
return tag; | ||
} | ||
return blockTag(tag); | ||
}; | ||
this.contractAddresses = {}; | ||
this.formatter.transaction = utils_1.parseTransaction; | ||
} | ||
async getTransactionReceipt(transactionHash) { | ||
@@ -227,2 +214,15 @@ await this.getNetwork(); | ||
} | ||
constructor(url, network) { | ||
super(url, network); | ||
this.pollingInterval = 500; | ||
const blockTag = this.formatter.blockTag.bind(this.formatter); | ||
this.formatter.blockTag = (tag) => { | ||
if (tag == 'committed' || tag == 'finalized') { | ||
return tag; | ||
} | ||
return blockTag(tag); | ||
}; | ||
this.contractAddresses = {}; | ||
this.formatter.transaction = utils_1.parseTransaction; | ||
} | ||
async getMessageProof(blockNumber, sender, messageHash, logIndex) { | ||
@@ -290,2 +290,5 @@ return await this.send('zks_getL2ToL1MsgProof', [ | ||
} | ||
async getL1BatchDetails(number) { | ||
return await this.send('zks_getL1BatchDetails', [number]); | ||
} | ||
async getBlockDetails(number) { | ||
@@ -292,0 +295,0 @@ return await this.send('zks_getBlockDetails', [number]); |
@@ -81,3 +81,2 @@ import { ethers } from 'ethers'; | ||
getBalanceL1(token?: string, blockTag?: ethers.providers.BlockTag): Promise<ethers.BigNumber>; | ||
getAllowanceL1(token: string, bridgeAddress?: string, blockTag?: ethers.providers.BlockTag): Promise<ethers.BigNumber>; | ||
l2TokenAddress(token: string): Promise<string>; | ||
@@ -124,9 +123,2 @@ approveERC20(token: string, amount: ethers.BigNumberish, overrides?: ethers.Overrides & { | ||
}): Promise<any>; | ||
getFullRequiredDepositFee(transaction: { | ||
token: string; | ||
to?: string; | ||
bridgeAddress?: string; | ||
gasPerPubdataByte?: ethers.BigNumberish; | ||
overrides?: ethers.PayableOverrides; | ||
}): Promise<import("./types").FullDepositFee>; | ||
_getWithdrawalLog(withdrawalHash: ethers.utils.BytesLike, index?: number): Promise<{ | ||
@@ -196,163 +188,2 @@ log: import("./types").Log; | ||
} | ||
declare const L2VoidSigner_base: { | ||
new (...args: any[]): { | ||
_providerL2(): Provider; | ||
_signerL2(): ethers.Signer; | ||
getBalance(token?: string, blockTag?: BlockTag): Promise<ethers.BigNumber>; | ||
getAllBalances(): Promise<import("./types").BalancesMap>; | ||
getL2BridgeContracts(): Promise<{ | ||
erc20: import("../typechain").IL2Bridge; | ||
}>; | ||
_fillCustomData(data: import("./types").Eip712Meta): import("./types").Eip712Meta; | ||
withdraw(transaction: { | ||
token: string; | ||
amount: ethers.BigNumberish; | ||
to?: string; | ||
bridgeAddress?: string; | ||
overrides?: ethers.Overrides; | ||
}): Promise<TransactionResponse>; | ||
transfer(transaction: { | ||
to: string; | ||
amount: ethers.BigNumberish; | ||
token?: string; | ||
overrides?: ethers.Overrides; | ||
}): Promise<TransactionResponse>; | ||
sendTransaction(tx: ethers.providers.TransactionRequest): Promise<ethers.providers.TransactionResponse>; | ||
getAddress(): Promise<string>; | ||
}; | ||
} & typeof ethers.VoidSigner; | ||
export declare class L2VoidSigner extends L2VoidSigner_base { | ||
provider: Provider; | ||
eip712: EIP712Signer; | ||
_signerL2(): this; | ||
_providerL2(): Provider; | ||
static from(signer: ethers.VoidSigner & { | ||
provider: Provider; | ||
}): L2VoidSigner; | ||
getNonce(blockTag?: BlockTag): Promise<number>; | ||
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse>; | ||
} | ||
declare const L1VoidSigner_base: { | ||
new (...args: any[]): { | ||
_providerL2(): Provider; | ||
_providerL1(): ethers.providers.Provider; | ||
_signerL1(): ethers.Signer; | ||
getMainContract(): Promise<import("../typechain").IZkSync>; | ||
getL1BridgeContracts(): Promise<{ | ||
erc20: import("../typechain").IL1Bridge; | ||
}>; | ||
getBalanceL1(token?: string, blockTag?: ethers.providers.BlockTag): Promise<ethers.BigNumber>; | ||
getAllowanceL1(token: string, bridgeAddress?: string, blockTag?: ethers.providers.BlockTag): Promise<ethers.BigNumber>; | ||
l2TokenAddress(token: string): Promise<string>; | ||
approveERC20(token: string, amount: ethers.BigNumberish, overrides?: ethers.Overrides & { | ||
bridgeAddress?: string; | ||
}): Promise<ethers.providers.TransactionResponse>; | ||
getBaseCost(params: { | ||
gasLimit: ethers.BigNumberish; | ||
gasPerPubdataByte?: ethers.BigNumberish; | ||
gasPrice?: ethers.BigNumberish; | ||
}): Promise<ethers.BigNumber>; | ||
deposit(transaction: { | ||
token: string; | ||
amount: ethers.BigNumberish; | ||
to?: string; | ||
operatorTip?: ethers.BigNumberish; | ||
bridgeAddress?: string; | ||
approveERC20?: boolean; | ||
l2GasLimit?: ethers.BigNumberish; | ||
gasPerPubdataByte?: ethers.BigNumberish; | ||
overrides?: ethers.PayableOverrides; | ||
approveOverrides?: ethers.Overrides; | ||
}): Promise<import("./types").PriorityOpResponse>; | ||
estimateGasDeposit(transaction: { | ||
token: string; | ||
amount: ethers.BigNumberish; | ||
to?: string; | ||
operatorTip?: ethers.BigNumberish; | ||
bridgeAddress?: string; | ||
l2GasLimit?: ethers.BigNumberish; | ||
gasPerPubdataByte?: ethers.BigNumberish; | ||
overrides?: ethers.PayableOverrides; | ||
}): Promise<ethers.BigNumber>; | ||
getDepositTx(transaction: { | ||
token: string; | ||
amount: ethers.BigNumberish; | ||
to?: string; | ||
operatorTip?: ethers.BigNumberish; | ||
bridgeAddress?: string; | ||
l2GasLimit?: ethers.BigNumberish; | ||
gasPerPubdataByte?: ethers.BigNumberish; | ||
overrides?: ethers.PayableOverrides; | ||
}): Promise<any>; | ||
getFullRequiredDepositFee(transaction: { | ||
token: string; | ||
to?: string; | ||
bridgeAddress?: string; | ||
gasPerPubdataByte?: ethers.BigNumberish; | ||
overrides?: ethers.PayableOverrides; | ||
}): Promise<import("./types").FullDepositFee>; | ||
_getWithdrawalLog(withdrawalHash: ethers.utils.BytesLike, index?: number): Promise<{ | ||
log: import("./types").Log; | ||
l1BatchTxId: number; | ||
}>; | ||
_getWithdrawalL2ToL1Log(withdrawalHash: ethers.utils.BytesLike, index?: number): Promise<{ | ||
l2ToL1LogIndex: number; | ||
l2ToL1Log: import("./types").L2ToL1Log; | ||
}>; | ||
finalizeWithdrawalParams(withdrawalHash: ethers.utils.BytesLike, index?: number): Promise<{ | ||
l1BatchNumber: number; | ||
l2MessageIndex: number; | ||
l2TxNumberInBlock: number; | ||
message: any; | ||
sender: string; | ||
proof: string[]; | ||
}>; | ||
finalizeWithdrawal(withdrawalHash: ethers.utils.BytesLike, index?: number, overrides?: ethers.Overrides): Promise<ethers.ContractTransaction>; | ||
isWithdrawalFinalized(withdrawalHash: ethers.utils.BytesLike, index?: number): Promise<boolean>; | ||
claimFailedDeposit(depositHash: ethers.utils.BytesLike, overrides?: ethers.Overrides): Promise<ethers.ContractTransaction>; | ||
requestExecute(transaction: { | ||
contractAddress: string; | ||
calldata: ethers.utils.BytesLike; | ||
l2GasLimit?: ethers.BigNumberish; | ||
l2Value?: ethers.BigNumberish; | ||
factoryDeps?: ethers.utils.BytesLike[]; | ||
operatorTip?: ethers.BigNumberish; | ||
gasPerPubdataByte?: ethers.BigNumberish; | ||
refundRecipient?: string; | ||
overrides?: ethers.PayableOverrides; | ||
}): Promise<import("./types").PriorityOpResponse>; | ||
estimateGasRequestExecute(transaction: { | ||
contractAddress: string; | ||
calldata: ethers.utils.BytesLike; | ||
l2GasLimit?: ethers.BigNumberish; | ||
l2Value?: ethers.BigNumberish; | ||
factoryDeps?: ethers.utils.BytesLike[]; | ||
operatorTip?: ethers.BigNumberish; | ||
gasPerPubdataByte?: ethers.BigNumberish; | ||
refundRecipient?: string; | ||
overrides?: ethers.PayableOverrides; | ||
}): Promise<ethers.BigNumber>; | ||
getRequestExecuteTx(transaction: { | ||
contractAddress: string; | ||
calldata: ethers.utils.BytesLike; | ||
l2GasLimit?: ethers.BigNumberish; | ||
l2Value?: ethers.BigNumberish; | ||
factoryDeps?: ethers.utils.BytesLike[]; | ||
operatorTip?: ethers.BigNumberish; | ||
gasPerPubdataByte?: ethers.BigNumberish; | ||
refundRecipient?: string; | ||
overrides?: ethers.PayableOverrides; | ||
}): Promise<ethers.PopulatedTransaction>; | ||
sendTransaction(tx: ethers.providers.TransactionRequest): Promise<ethers.providers.TransactionResponse>; | ||
getAddress(): Promise<string>; | ||
}; | ||
} & typeof ethers.VoidSigner; | ||
export declare class L1VoidSigner extends L1VoidSigner_base { | ||
providerL2: Provider; | ||
_providerL2(): Provider; | ||
_providerL1(): ethers.providers.Provider; | ||
_signerL1(): this; | ||
static from(signer: ethers.VoidSigner, zksyncProvider: Provider): L1VoidSigner; | ||
connectToL2(provider: Provider): this; | ||
} | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.L1VoidSigner = exports.L2VoidSigner = exports.L1Signer = exports.Signer = exports.EIP712Signer = exports.eip712Types = void 0; | ||
exports.L1Signer = exports.Signer = exports.EIP712Signer = exports.eip712Types = void 0; | ||
const ethers_1 = require("ethers"); | ||
@@ -153,76 +153,1 @@ const utils_1 = require("./utils"); | ||
exports.L1Signer = L1Signer; | ||
class L2VoidSigner extends (0, adapters_1.AdapterL2)(ethers_1.ethers.VoidSigner) { | ||
_signerL2() { | ||
return this; | ||
} | ||
_providerL2() { | ||
return this.provider; | ||
} | ||
static from(signer) { | ||
const newSigner = Object.setPrototypeOf(signer, L2VoidSigner.prototype); | ||
// @ts-ignore | ||
newSigner.eip712 = new EIP712Signer(newSigner, newSigner.getChainId()); | ||
return newSigner; | ||
} | ||
// an alias with a better name | ||
async getNonce(blockTag) { | ||
return await this.getTransactionCount(blockTag); | ||
} | ||
async sendTransaction(transaction) { | ||
var _a, _b, _c, _d, _e, _f, _g; | ||
if (transaction.customData == null && transaction.type == null) { | ||
// use legacy txs by default | ||
transaction.type = 0; | ||
} | ||
if (transaction.customData == null && transaction.type != utils_1.EIP712_TX_TYPE) { | ||
return (await super.sendTransaction(transaction)); | ||
} | ||
else { | ||
const address = await this.getAddress(); | ||
(_a = transaction.from) !== null && _a !== void 0 ? _a : (transaction.from = address); | ||
if (transaction.from.toLowerCase() != address.toLowerCase()) { | ||
throw new Error('Transaction `from` address mismatch'); | ||
} | ||
transaction.type = utils_1.EIP712_TX_TYPE; | ||
(_b = transaction.value) !== null && _b !== void 0 ? _b : (transaction.value = 0); | ||
(_c = transaction.data) !== null && _c !== void 0 ? _c : (transaction.data = '0x'); | ||
(_d = transaction.nonce) !== null && _d !== void 0 ? _d : (transaction.nonce = await this.getNonce()); | ||
transaction.customData = this._fillCustomData(transaction.customData); | ||
(_e = transaction.gasPrice) !== null && _e !== void 0 ? _e : (transaction.gasPrice = await this.provider.getGasPrice()); | ||
(_f = transaction.gasLimit) !== null && _f !== void 0 ? _f : (transaction.gasLimit = await this.provider.estimateGas(transaction)); | ||
(_g = transaction.chainId) !== null && _g !== void 0 ? _g : (transaction.chainId = (await this.provider.getNetwork()).chainId); | ||
transaction.customData.customSignature = await this.eip712.sign(transaction); | ||
const txBytes = (0, utils_1.serialize)(transaction); | ||
return await this.provider.sendTransaction(txBytes); | ||
} | ||
} | ||
} | ||
exports.L2VoidSigner = L2VoidSigner; | ||
// This class is to be used on the frontend with metamask injection. | ||
// It only contains L1 operations. For L2 operations, see Signer. | ||
// Sample usage: | ||
// const provider = new ethers.Web3Provider(window.ethereum); | ||
// const zksyncProvider = new zkweb3.Provider('<rpc_url>'); | ||
// const signer = zkweb3.L1Signer.from(provider.getSigner(), zksyncProvider); | ||
// const tx = await signer.deposit({ ... }); | ||
class L1VoidSigner extends (0, adapters_1.AdapterL1)(ethers_1.ethers.VoidSigner) { | ||
_providerL2() { | ||
return this.providerL2; | ||
} | ||
_providerL1() { | ||
return this.provider; | ||
} | ||
_signerL1() { | ||
return this; | ||
} | ||
static from(signer, zksyncProvider) { | ||
const newSigner = Object.setPrototypeOf(signer, L1VoidSigner.prototype); | ||
newSigner.providerL2 = zksyncProvider; | ||
return newSigner; | ||
} | ||
connectToL2(provider) { | ||
this.providerL2 = provider; | ||
return this; | ||
} | ||
} | ||
exports.L1VoidSigner = L1VoidSigner; |
import { BytesLike, BigNumberish, providers, BigNumber } from 'ethers'; | ||
import { BlockWithTransactions as EthersBlockWithTransactions } from '@ethersproject/abstract-provider'; | ||
export declare type Address = string; | ||
export declare type Signature = string; | ||
export type Address = string; | ||
export type Signature = string; | ||
export declare enum Network { | ||
@@ -27,7 +27,7 @@ Mainnet = 1, | ||
} | ||
export declare type PaymasterParams = { | ||
export type PaymasterParams = { | ||
paymaster: Address; | ||
paymasterInput: BytesLike; | ||
}; | ||
export declare type Eip712Meta = { | ||
export type Eip712Meta = { | ||
gasPerPubdata?: BigNumberish; | ||
@@ -38,4 +38,4 @@ factoryDeps?: BytesLike[]; | ||
}; | ||
export declare type BlockTag = number | string | 'committed' | 'finalized' | 'latest' | 'earliest' | 'pending'; | ||
export declare type DeploymentType = 'create' | 'createAccount'; | ||
export type BlockTag = number | string | 'committed' | 'finalized' | 'latest' | 'earliest' | 'pending'; | ||
export type DeploymentType = 'create' | 'createAccount'; | ||
export interface Token { | ||
@@ -98,3 +98,3 @@ l1Address: Address; | ||
} | ||
export declare type TransactionRequest = providers.TransactionRequest & { | ||
export type TransactionRequest = providers.TransactionRequest & { | ||
customData?: Eip712Meta; | ||
@@ -105,3 +105,3 @@ }; | ||
} | ||
export declare type BalancesMap = { | ||
export type BalancesMap = { | ||
[key: string]: BigNumber; | ||
@@ -129,3 +129,3 @@ }; | ||
} | ||
export declare type PaymasterInput = ApprovalBasedPaymasterInput | GeneralPaymasterInput; | ||
export type PaymasterInput = ApprovalBasedPaymasterInput | GeneralPaymasterInput; | ||
export declare enum AccountAbstractionVersion { | ||
@@ -143,5 +143,22 @@ None = 0, | ||
} | ||
export interface BatchDetails { | ||
number: number; | ||
timestamp: number; | ||
l1TxCount: number; | ||
l2TxCount: number; | ||
rootHash?: string; | ||
status: string; | ||
commitTxHash?: string; | ||
committedAt?: Date; | ||
proveTxHash?: string; | ||
provenAt?: Date; | ||
executeTxHash?: string; | ||
executedAt?: Date; | ||
l1GasPrice: number; | ||
l2FairGasPrice: number; | ||
} | ||
export interface BlockDetails { | ||
number: number; | ||
timestamp: number; | ||
l1BatchNumber: number; | ||
l1TxCount: number; | ||
@@ -168,9 +185,1 @@ l2TxCount: number; | ||
} | ||
export interface FullDepositFee { | ||
maxFeePerGas?: BigNumber; | ||
maxPriorityFeePerGas?: BigNumber; | ||
gasPrice?: BigNumber; | ||
baseCost: BigNumber; | ||
l1GasLimit: BigNumber; | ||
l2GasLimit: BigNumber; | ||
} |
@@ -24,6 +24,2 @@ import { utils, ethers, BigNumber, BigNumberish, BytesLike } from 'ethers'; | ||
export declare const MAX_BYTECODE_LEN_BYTES: number; | ||
export declare const L1_FEE_ESTIMATION_COEF_NUMERATOR: ethers.BigNumber; | ||
export declare const L1_FEE_ESTIMATION_COEF_DENOMINATOR: ethers.BigNumber; | ||
export declare const L1_RECOMMENDED_MIN_ERC20_DEPOSIT_GAS_LIMIT = 400000; | ||
export declare const L1_RECOMMENDED_MIN_ETH_DEPOSIT_GAS_LIMIT = 200000; | ||
export declare const DEFAULT_GAS_PER_PUBDATA_LIMIT = 50000; | ||
@@ -52,2 +48,1 @@ export declare const REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT = 800; | ||
export declare function estimateDefaultBridgeDepositL2Gas(providerL1: ethers.providers.Provider, providerL2: Provider, token: Address, amount: BigNumberish, to: Address, from?: Address, gasPerPubdataByte?: BigNumberish): Promise<BigNumber>; | ||
export declare function scaleGasLimit(gasLimit: BigNumber): BigNumber; |
@@ -17,3 +17,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.scaleGasLimit = exports.estimateDefaultBridgeDepositL2Gas = exports.isTypedDataSignatureCorrect = exports.isMessageSignatureCorrect = exports.getERC20BridgeCalldata = exports.undoL1ToL2Alias = exports.applyL1ToL2Alias = exports.getL2HashFromPriorityOp = exports.parseTransaction = exports.hashBytecode = exports.serialize = exports.checkBaseCost = exports.createAddress = exports.create2Address = exports.getDeployedContracts = exports.getHashedL2ToL1Msg = exports.layer1TxDefaults = exports.sleep = exports.isETH = exports.REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT = exports.DEFAULT_GAS_PER_PUBDATA_LIMIT = exports.L1_RECOMMENDED_MIN_ETH_DEPOSIT_GAS_LIMIT = exports.L1_RECOMMENDED_MIN_ERC20_DEPOSIT_GAS_LIMIT = exports.L1_FEE_ESTIMATION_COEF_DENOMINATOR = exports.L1_FEE_ESTIMATION_COEF_NUMERATOR = exports.MAX_BYTECODE_LEN_BYTES = exports.PRIORITY_OPERATION_L2_TX_TYPE = exports.EIP712_TX_TYPE = exports.EIP1271_MAGIC_VALUE = exports.L1_TO_L2_ALIAS_OFFSET = exports.L2_ETH_TOKEN_ADDRESS = exports.L1_MESSENGER_ADDRESS = exports.CONTRACT_DEPLOYER_ADDRESS = exports.BOOTLOADER_FORMAL_ADDRESS = exports.L2_BRIDGE_ABI = exports.L1_BRIDGE_ABI = exports.IERC1271 = exports.IERC20 = exports.L1_MESSENGER = exports.CONTRACT_DEPLOYER = exports.ZKSYNC_MAIN_ABI = exports.ETH_ADDRESS = void 0; | ||
exports.estimateDefaultBridgeDepositL2Gas = exports.isTypedDataSignatureCorrect = exports.isMessageSignatureCorrect = exports.getERC20BridgeCalldata = exports.undoL1ToL2Alias = exports.applyL1ToL2Alias = exports.getL2HashFromPriorityOp = exports.parseTransaction = exports.hashBytecode = exports.serialize = exports.checkBaseCost = exports.createAddress = exports.create2Address = exports.getDeployedContracts = exports.getHashedL2ToL1Msg = exports.layer1TxDefaults = exports.sleep = exports.isETH = exports.REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT = exports.DEFAULT_GAS_PER_PUBDATA_LIMIT = exports.MAX_BYTECODE_LEN_BYTES = exports.PRIORITY_OPERATION_L2_TX_TYPE = exports.EIP712_TX_TYPE = exports.EIP1271_MAGIC_VALUE = exports.L1_TO_L2_ALIAS_OFFSET = exports.L2_ETH_TOKEN_ADDRESS = exports.L1_MESSENGER_ADDRESS = exports.CONTRACT_DEPLOYER_ADDRESS = exports.BOOTLOADER_FORMAL_ADDRESS = exports.L2_BRIDGE_ABI = exports.L1_BRIDGE_ABI = exports.IERC1271 = exports.IERC20 = exports.L1_MESSENGER = exports.CONTRACT_DEPLOYER = exports.ZKSYNC_MAIN_ABI = exports.ETH_ADDRESS = void 0; | ||
const ethers_1 = require("ethers"); | ||
@@ -42,9 +42,2 @@ const types_1 = require("./types"); | ||
exports.MAX_BYTECODE_LEN_BYTES = ((1 << 16) - 1) * 32; | ||
// Currently, for some reason the SDK may return slightly smaller value than required for the L1->L2 | ||
// transaction. We will use a coefficient to ensure that the transaction will be accepted. | ||
exports.L1_FEE_ESTIMATION_COEF_NUMERATOR = ethers_1.BigNumber.from(12); | ||
exports.L1_FEE_ESTIMATION_COEF_DENOMINATOR = ethers_1.BigNumber.from(10); | ||
// This gas limit will be used for displaying the error messages when the users do not have enough fee. | ||
exports.L1_RECOMMENDED_MIN_ERC20_DEPOSIT_GAS_LIMIT = 400000; | ||
exports.L1_RECOMMENDED_MIN_ETH_DEPOSIT_GAS_LIMIT = 200000; | ||
// The large L2 gas per pubdata to sign. This gas is enough to ensure that | ||
@@ -442,5 +435,1 @@ // any reasonable limit will be accepted. Note, that the operator is NOT required to | ||
exports.estimateDefaultBridgeDepositL2Gas = estimateDefaultBridgeDepositL2Gas; | ||
function scaleGasLimit(gasLimit) { | ||
return gasLimit.mul(exports.L1_FEE_ESTIMATION_COEF_NUMERATOR).div(exports.L1_FEE_ESTIMATION_COEF_DENOMINATOR); | ||
} | ||
exports.scaleGasLimit = scaleGasLimit; |
@@ -42,3 +42,2 @@ import { EIP712Signer } from './signer'; | ||
getBalanceL1(token?: string, blockTag?: ethers.providers.BlockTag): Promise<ethers.BigNumber>; | ||
getAllowanceL1(token: string, bridgeAddress?: string, blockTag?: ethers.providers.BlockTag): Promise<ethers.BigNumber>; | ||
l2TokenAddress(token: string): Promise<string>; | ||
@@ -85,9 +84,2 @@ approveERC20(token: string, amount: ethers.BigNumberish, overrides?: ethers.Overrides & { | ||
}): Promise<any>; | ||
getFullRequiredDepositFee(transaction: { | ||
token: string; | ||
to?: string; | ||
bridgeAddress?: string; | ||
gasPerPubdataByte?: ethers.BigNumberish; | ||
overrides?: ethers.PayableOverrides; | ||
}): Promise<import("./types").FullDepositFee>; | ||
_getWithdrawalLog(withdrawalHash: ethers.utils.BytesLike, index?: number): Promise<{ | ||
@@ -94,0 +86,0 @@ log: import("./types").Log; |
@@ -9,11 +9,2 @@ "use strict"; | ||
class Wallet extends (0, adapters_1.AdapterL2)((0, adapters_1.AdapterL1)(ethers_1.ethers.Wallet)) { | ||
constructor(privateKey, providerL2, providerL1) { | ||
super(privateKey, providerL2); | ||
if (this.provider != null) { | ||
const chainId = this.getChainId(); | ||
// @ts-ignore | ||
this.eip712 = new signer_1.EIP712Signer(this, chainId); | ||
} | ||
this.providerL1 = providerL1; | ||
} | ||
_providerL1() { | ||
@@ -63,2 +54,11 @@ if (this.providerL1 == null) { | ||
} | ||
constructor(privateKey, providerL2, providerL1) { | ||
super(privateKey, providerL2); | ||
if (this.provider != null) { | ||
const chainId = this.getChainId(); | ||
// @ts-ignore | ||
this.eip712 = new signer_1.EIP712Signer(this, chainId); | ||
} | ||
this.providerL1 = providerL1; | ||
} | ||
async populateTransaction(transaction) { | ||
@@ -65,0 +65,0 @@ var _a, _b; |
# Changelog | ||
## [0.14.4](https://github.com/matter-labs/zksync-2-dev/compare/zksync-web3-v0.14.1...zksync-web3-v0.14.4) (2023-04-13) | ||
### Features | ||
* add getL1BatchDetails method to js SDK ([#1666](https://github.com/matter-labs/zksync-2-dev/issues/1666)) ([babb8a9](https://github.com/matter-labs/zksync-2-dev/commit/babb8a94466a8f8c81a19391d61aa9ea66f9cfa8)) | ||
* **sdk:** extend BlockDetails type to include l1BatchNumber ([#1677](https://github.com/matter-labs/zksync-2-dev/issues/1677)) ([67acf90](https://github.com/matter-labs/zksync-2-dev/commit/67acf90301e401004d41361b43f2d3336a48676e)) | ||
## [0.14.0](https://github.com/matter-labs/zksync-2-dev/compare/zksync-web3-v0.13.3...zksync-web3-v0.14.0) (2023-03-21) | ||
@@ -4,0 +12,0 @@ |
{ | ||
"name": "zksync-web3", | ||
"version": "0.14.4-beta.5", | ||
"version": "0.14.4", | ||
"main": "build/src/index.js", | ||
@@ -13,3 +13,2 @@ "types": "build/src/index.d.ts", | ||
"license": "MIT", | ||
"dependencies": {}, | ||
"devDependencies": { | ||
@@ -16,0 +15,0 @@ "@types/chai": "^4.2.19", |
import { BigNumber, BigNumberish, BytesLike, ethers } from 'ethers'; | ||
import { IERC20MetadataFactory, IL1BridgeFactory, IL2BridgeFactory, IZkSyncFactory } from '../typechain'; | ||
import { Provider } from './provider'; | ||
import { Address, BalancesMap, BlockTag, Eip712Meta, PriorityOpResponse, TransactionResponse } from './types'; | ||
import { | ||
Address, | ||
BalancesMap, | ||
BlockTag, | ||
Eip712Meta, | ||
FullDepositFee, | ||
PriorityOpResponse, | ||
TransactionResponse | ||
} from './types'; | ||
import { | ||
BOOTLOADER_FORMAL_ADDRESS, | ||
@@ -23,6 +15,3 @@ checkBaseCost, | ||
undoL1ToL2Alias, | ||
estimateDefaultBridgeDepositL2Gas, | ||
scaleGasLimit, | ||
L1_RECOMMENDED_MIN_ETH_DEPOSIT_GAS_LIMIT, | ||
L1_RECOMMENDED_MIN_ERC20_DEPOSIT_GAS_LIMIT | ||
estimateDefaultBridgeDepositL2Gas | ||
} from './utils'; | ||
@@ -71,12 +60,2 @@ | ||
async getAllowanceL1( | ||
token: Address, | ||
bridgeAddress?: Address, | ||
blockTag?: ethers.providers.BlockTag | ||
): Promise<BigNumber> { | ||
const erc20contract = IERC20MetadataFactory.connect(token, this._providerL1()); | ||
bridgeAddress ??= (await this.getL1BridgeContracts()).erc20.address; | ||
return await erc20contract.allowance(await this.getAddress(), bridgeAddress, { blockTag }); | ||
} | ||
async l2TokenAddress(token: Address) { | ||
@@ -109,4 +88,2 @@ if (token == ETH_ADDRESS) { | ||
overrides ??= {}; | ||
return await erc20contract.approve(bridgeAddress, amount, overrides); | ||
@@ -147,10 +124,3 @@ } | ||
const depositTx = await this.getDepositTx(transaction); | ||
if (transaction.token == ETH_ADDRESS) { | ||
const baseGasLimit = await this.estimateGasRequestExecute(depositTx); | ||
const gasLimit = scaleGasLimit(baseGasLimit); | ||
depositTx.overrides ??= {}; | ||
depositTx.overrides.gasLimit ??= gasLimit; | ||
return this.requestExecute(depositTx); | ||
@@ -160,18 +130,8 @@ } else { | ||
if (transaction.approveERC20) { | ||
// We only request the allowance if the current one is not enough. | ||
const allowance = await this.getAllowanceL1(transaction.token); | ||
if (allowance.lt(transaction.amount)) { | ||
const approveTx = await this.approveERC20(transaction.token, transaction.amount, { | ||
bridgeAddress: transaction.bridgeAddress ?? bridgeContracts.erc20.address, | ||
...transaction.approveOverrides | ||
}); | ||
await approveTx.wait(); | ||
} | ||
const approveTx = await this.approveERC20(transaction.token, transaction.amount, { | ||
bridgeAddress: transaction.bridgeAddress ?? bridgeContracts.erc20.address, | ||
...transaction.approveOverrides | ||
}); | ||
await approveTx.wait(); | ||
} | ||
const baseGasLimit = await this._providerL1().estimateGas(depositTx); | ||
const gasLimit = scaleGasLimit(baseGasLimit); | ||
depositTx.gasLimit ??= gasLimit; | ||
return await this._providerL2().getPriorityOpResponse( | ||
@@ -194,11 +154,7 @@ await this._signerL1().sendTransaction(depositTx) | ||
const depositTx = await this.getDepositTx(transaction); | ||
let baseGasLimit: BigNumber; | ||
if (transaction.token == ETH_ADDRESS) { | ||
baseGasLimit = await this.estimateGasRequestExecute(depositTx); | ||
return await this.estimateGasRequestExecute(depositTx); | ||
} else { | ||
baseGasLimit = await this._providerL1().estimateGas(depositTx); | ||
return await this._providerL1().estimateGas(depositTx); | ||
} | ||
return scaleGasLimit(baseGasLimit); | ||
} | ||
@@ -273,2 +229,5 @@ | ||
// TODO: compatibility layer: using the old API which uses msg.sender as the | ||
// refund recipient, to make the SDK compatible with the old contracts. | ||
// const contract = bridgeContracts.erc20 as ethers.Contract; | ||
return await bridgeContracts.erc20.populateTransaction.deposit(...args, overrides); | ||
@@ -278,101 +237,2 @@ } | ||
// Retrieves the full needed ETH fee for the deposit. | ||
// Returns the L1 fee and the L2 fee. | ||
async getFullRequiredDepositFee(transaction: { | ||
token: Address; | ||
to?: Address; | ||
bridgeAddress?: Address; | ||
gasPerPubdataByte?: BigNumberish; | ||
overrides?: ethers.PayableOverrides; | ||
}): Promise<FullDepositFee> { | ||
// It is assumed that the L2 fee for the transaction does not depend on its value. | ||
const dummyAmount = '1'; | ||
const { ...tx } = transaction; | ||
const zksyncContract = await this.getMainContract(); | ||
tx.overrides ??= {}; | ||
await insertGasPrice(this._providerL1(), tx.overrides); | ||
const gasPriceForMessages = (await tx.overrides.maxFeePerGas) || (await tx.overrides.gasPrice); | ||
tx.to ??= await this.getAddress(); | ||
tx.gasPerPubdataByte ??= REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT; | ||
const l2GasLimit = await estimateDefaultBridgeDepositL2Gas( | ||
this._providerL1(), | ||
this._providerL2(), | ||
tx.token, | ||
dummyAmount, | ||
tx.to, | ||
await this.getAddress(), | ||
tx.gasPerPubdataByte | ||
); | ||
const baseCost = await zksyncContract.l2TransactionBaseCost( | ||
gasPriceForMessages, | ||
l2GasLimit, | ||
tx.gasPerPubdataByte | ||
); | ||
const selfBalanceETH = await this.getBalanceL1(); | ||
// We could 0 in, because the final fee will anyway be bigger than | ||
if (baseCost.gte(selfBalanceETH.add(dummyAmount))) { | ||
const recommendedETHBalance = BigNumber.from( | ||
tx.token == ETH_ADDRESS | ||
? L1_RECOMMENDED_MIN_ETH_DEPOSIT_GAS_LIMIT | ||
: L1_RECOMMENDED_MIN_ERC20_DEPOSIT_GAS_LIMIT | ||
) | ||
.mul(gasPriceForMessages) | ||
.add(baseCost); | ||
const formattedRecommendedBalance = ethers.utils.formatEther(recommendedETHBalance); | ||
throw new Error( | ||
`Not enough balance for deposit. Under the provided gas price, the recommended balance to perform a deposit is ${formattedRecommendedBalance} ETH` | ||
); | ||
} | ||
// For ETH token the value that the user passes to the estimation is the one which has the | ||
// value for the L2 comission substracted. | ||
let amountForEstimate: BigNumber; | ||
if (isETH(tx.token)) { | ||
amountForEstimate = BigNumber.from(dummyAmount); | ||
} else { | ||
amountForEstimate = BigNumber.from(dummyAmount); | ||
if ((await this.getAllowanceL1(tx.token)) < amountForEstimate) { | ||
throw new Error('Not enough allowance to cover the deposit'); | ||
} | ||
} | ||
// Deleting the explicit gas limits in the fee estimation | ||
// in order to prevent the situation where the transaction | ||
// fails because the user does not have enough balance | ||
const estimationOverrides = { ...tx.overrides }; | ||
delete estimationOverrides.gasPrice; | ||
delete estimationOverrides.maxFeePerGas; | ||
delete estimationOverrides.maxPriorityFeePerGas; | ||
const l1GasLimit = await this.estimateGasDeposit({ | ||
...tx, | ||
amount: amountForEstimate, | ||
overrides: estimationOverrides, | ||
l2GasLimit | ||
}); | ||
const fullCost: FullDepositFee = { | ||
baseCost, | ||
l1GasLimit, | ||
l2GasLimit | ||
}; | ||
if (tx.overrides.gasPrice) { | ||
fullCost.gasPrice = BigNumber.from(await tx.overrides.gasPrice); | ||
} else { | ||
fullCost.maxFeePerGas = BigNumber.from(await tx.overrides.maxFeePerGas); | ||
fullCost.maxPriorityFeePerGas = BigNumber.from(await tx.overrides.maxPriorityFeePerGas); | ||
} | ||
return fullCost; | ||
} | ||
async _getWithdrawalLog(withdrawalHash: BytesLike, index: number = 0) { | ||
@@ -536,7 +396,2 @@ const hash = ethers.utils.hexlify(withdrawalHash); | ||
const requestExecuteTx = await this.getRequestExecuteTx(transaction); | ||
delete requestExecuteTx.gasPrice; | ||
delete requestExecuteTx.maxFeePerGas; | ||
delete requestExecuteTx.maxPriorityFeePerGas; | ||
return this._providerL1().estimateGas(requestExecuteTx); | ||
@@ -543,0 +398,0 @@ } |
export * as utils from './utils'; | ||
export * as types from './types'; | ||
export { EIP712Signer, Signer, L1Signer, L1VoidSigner, L2VoidSigner } from './signer'; | ||
export { EIP712Signer, Signer, L1Signer } from './signer'; | ||
export { Wallet } from './wallet'; | ||
export { Web3Provider, Provider } from './provider'; | ||
export { ContractFactory, Contract } from './contract'; |
@@ -22,2 +22,3 @@ import { ethers, BigNumber, BigNumberish, utils, providers, BytesLike, Contract } from 'ethers'; | ||
TransactionDetails, | ||
BatchDetails, | ||
BlockDetails, | ||
@@ -367,2 +368,6 @@ ContractAccountInfo | ||
async getL1BatchDetails(number: number): Promise<BatchDetails> { | ||
return await this.send('zks_getL1BatchDetails', [number]); | ||
} | ||
async getBlockDetails(number: number): Promise<BlockDetails> { | ||
@@ -369,0 +374,0 @@ return await this.send('zks_getBlockDetails', [number]); |
@@ -171,88 +171,1 @@ import { ethers } from 'ethers'; | ||
} | ||
export class L2VoidSigner extends AdapterL2(ethers.VoidSigner) { | ||
public override provider: Provider; | ||
public eip712: EIP712Signer; | ||
override _signerL2() { | ||
return this; | ||
} | ||
override _providerL2() { | ||
return this.provider; | ||
} | ||
static from(signer: ethers.VoidSigner & { provider: Provider }): L2VoidSigner { | ||
const newSigner: L2VoidSigner = Object.setPrototypeOf(signer, L2VoidSigner.prototype); | ||
// @ts-ignore | ||
newSigner.eip712 = new EIP712Signer(newSigner, newSigner.getChainId()); | ||
return newSigner; | ||
} | ||
// an alias with a better name | ||
async getNonce(blockTag?: BlockTag) { | ||
return await this.getTransactionCount(blockTag); | ||
} | ||
override async sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse> { | ||
if (transaction.customData == null && transaction.type == null) { | ||
// use legacy txs by default | ||
transaction.type = 0; | ||
} | ||
if (transaction.customData == null && transaction.type != EIP712_TX_TYPE) { | ||
return (await super.sendTransaction(transaction)) as TransactionResponse; | ||
} else { | ||
const address = await this.getAddress(); | ||
transaction.from ??= address; | ||
if (transaction.from.toLowerCase() != address.toLowerCase()) { | ||
throw new Error('Transaction `from` address mismatch'); | ||
} | ||
transaction.type = EIP712_TX_TYPE; | ||
transaction.value ??= 0; | ||
transaction.data ??= '0x'; | ||
transaction.nonce ??= await this.getNonce(); | ||
transaction.customData = this._fillCustomData(transaction.customData); | ||
transaction.gasPrice ??= await this.provider.getGasPrice(); | ||
transaction.gasLimit ??= await this.provider.estimateGas(transaction); | ||
transaction.chainId ??= (await this.provider.getNetwork()).chainId; | ||
transaction.customData.customSignature = await this.eip712.sign(transaction); | ||
const txBytes = serialize(transaction); | ||
return await this.provider.sendTransaction(txBytes); | ||
} | ||
} | ||
} | ||
// This class is to be used on the frontend with metamask injection. | ||
// It only contains L1 operations. For L2 operations, see Signer. | ||
// Sample usage: | ||
// const provider = new ethers.Web3Provider(window.ethereum); | ||
// const zksyncProvider = new zkweb3.Provider('<rpc_url>'); | ||
// const signer = zkweb3.L1Signer.from(provider.getSigner(), zksyncProvider); | ||
// const tx = await signer.deposit({ ... }); | ||
export class L1VoidSigner extends AdapterL1(ethers.VoidSigner) { | ||
public providerL2: Provider; | ||
override _providerL2() { | ||
return this.providerL2; | ||
} | ||
override _providerL1() { | ||
return this.provider; | ||
} | ||
override _signerL1() { | ||
return this; | ||
} | ||
static from(signer: ethers.VoidSigner, zksyncProvider: Provider): L1VoidSigner { | ||
const newSigner: L1VoidSigner = Object.setPrototypeOf(signer, L1VoidSigner.prototype); | ||
newSigner.providerL2 = zksyncProvider; | ||
return newSigner; | ||
} | ||
connectToL2(provider: Provider): this { | ||
this.providerL2 = provider; | ||
return this; | ||
} | ||
} | ||
@@ -178,5 +178,23 @@ import { BytesLike, BigNumberish, providers, BigNumber } from 'ethers'; | ||
export interface BatchDetails { | ||
number: number; | ||
timestamp: number; | ||
l1TxCount: number; | ||
l2TxCount: number; | ||
rootHash?: string; | ||
status: string; | ||
commitTxHash?: string; | ||
committedAt?: Date; | ||
proveTxHash?: string; | ||
provenAt?: Date; | ||
executeTxHash?: string; | ||
executedAt?: Date; | ||
l1GasPrice: number; | ||
l2FairGasPrice: number; | ||
} | ||
export interface BlockDetails { | ||
number: number; | ||
timestamp: number; | ||
l1BatchNumber: number; | ||
l1TxCount: number; | ||
@@ -204,10 +222,1 @@ l2TxCount: number; | ||
} | ||
export interface FullDepositFee { | ||
maxFeePerGas?: BigNumber; | ||
maxPriorityFeePerGas?: BigNumber; | ||
gasPrice?: BigNumber; | ||
baseCost: BigNumber; | ||
l1GasLimit: BigNumber; | ||
l2GasLimit: BigNumber; | ||
} |
@@ -44,11 +44,2 @@ import { utils, ethers, BigNumber, BigNumberish, BytesLike } from 'ethers'; | ||
// Currently, for some reason the SDK may return slightly smaller value than required for the L1->L2 | ||
// transaction. We will use a coefficient to ensure that the transaction will be accepted. | ||
export const L1_FEE_ESTIMATION_COEF_NUMERATOR = BigNumber.from(12); | ||
export const L1_FEE_ESTIMATION_COEF_DENOMINATOR = BigNumber.from(10); | ||
// This gas limit will be used for displaying the error messages when the users do not have enough fee. | ||
export const L1_RECOMMENDED_MIN_ERC20_DEPOSIT_GAS_LIMIT = 400000; | ||
export const L1_RECOMMENDED_MIN_ETH_DEPOSIT_GAS_LIMIT = 200000; | ||
// The large L2 gas per pubdata to sign. This gas is enough to ensure that | ||
@@ -547,5 +538,1 @@ // any reasonable limit will be accepted. Note, that the operator is NOT required to | ||
} | ||
export function scaleGasLimit(gasLimit: BigNumber): BigNumber { | ||
return gasLimit.mul(L1_FEE_ESTIMATION_COEF_NUMERATOR).div(L1_FEE_ESTIMATION_COEF_DENOMINATOR); | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
858921
75
27404