Add function to get all gas params - gas price, gas limit and L1 fee, if exists, in one object & bump lib version to 1.3.0
This commit is contained in:
parent
de369f405c
commit
a0476b0e34
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@tornado/tornado-oracles",
|
"name": "@tornado/tornado-oracles",
|
||||||
"version": "1.2.2",
|
"version": "1.3.0",
|
||||||
"description": "Gas oracle for Tornado-specific transactions",
|
"description": "Gas oracle for Tornado-specific transactions",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
import { GasPriceOracle } from '@tornado/gas-price-oracle';
|
import { GasPriceOracle } from '@tornado/gas-price-oracle';
|
||||||
import { BigNumber, BigNumberish, ethers } from 'ethers';
|
import { BigNumber, BigNumberish, ethers } from 'ethers';
|
||||||
import { parseUnits } from 'ethers/lib/utils';
|
import { parseUnits } from 'ethers/lib/utils';
|
||||||
import { TransactionData, TxType, ITornadoFeeOracle, LegacyGasPriceKey, GasPriceParams } from './types';
|
import {
|
||||||
|
TransactionData,
|
||||||
|
TxType,
|
||||||
|
ITornadoFeeOracle,
|
||||||
|
LegacyGasPriceKey,
|
||||||
|
GasPriceParams,
|
||||||
|
GetGasParamsRes,
|
||||||
|
HexadecimalStringifiedNumber,
|
||||||
|
} from './types';
|
||||||
import { JsonRpcProvider } from '@ethersproject/providers';
|
import { JsonRpcProvider } from '@ethersproject/providers';
|
||||||
import { ChainId, defaultGasPrices, defaultInstanceTokensGasLimit, InstanceTokenSymbol } from './config';
|
import { ChainId, defaultGasPrices, defaultInstanceTokensGasLimit, InstanceTokenSymbol } from './config';
|
||||||
import { bump, calculateGasPriceInWei, convertETHToToken, fromGweiToWeiHex, serializeTx } from './utils';
|
import { bump, calculateGasPriceInWei, convertETHToToken, fromGweiToWeiHex, serializeTx } from './utils';
|
||||||
@ -23,9 +31,9 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
* Because Optimism transaction published on Mainnet, for each OP transaction we need to calculate L1 security fee:
|
* Because Optimism transaction published on Mainnet, for each OP transaction we need to calculate L1 security fee:
|
||||||
* https://community.optimism.io/docs/developers/build/transaction-fees/#priority-fee
|
* https://community.optimism.io/docs/developers/build/transaction-fees/#priority-fee
|
||||||
* @param {TransactionData} tx Transaction data to estimate L1 additional fee
|
* @param {TransactionData} tx Transaction data to estimate L1 additional fee
|
||||||
* @returns {Promise<string>} Fee in WEI (MATIC)
|
* @returns {Promise<HexadecimalStringifiedNumber>} Fee in WEI (MATIC), '0' if chain is not Optimism
|
||||||
*/
|
*/
|
||||||
async fetchL1OptimismFee(tx?: TransactionData): Promise<string> {
|
async fetchL1OptimismFee(tx?: TransactionData): Promise<HexadecimalStringifiedNumber> {
|
||||||
if (this.chainId != ChainId.OPTIMISM) return BigNumber.from(0).toHexString();
|
if (this.chainId != ChainId.OPTIMISM) return BigNumber.from(0).toHexString();
|
||||||
|
|
||||||
const optimismL1FeeOracle = getOptimismL1FeeOracle(this.provider);
|
const optimismL1FeeOracle = getOptimismL1FeeOracle(this.provider);
|
||||||
@ -35,17 +43,40 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Estimates next block gas for signed, unsigned or incomplete Tornado transaction
|
* Estimate gas price, gas limit and l1Fee for sidechain (if exists)
|
||||||
* @param {TransactionData} tx Transaction data in web3 / ethers format
|
* @param {TransactionData} [tx] Transaction data in web3 / ethers format
|
||||||
* @param {TxType} txType Tornado transaction type: withdrawal by user, withdrawal by relayer or 'other'
|
* @param {TxType} [txType=other] Tornado transaction type: withdrawal by user, withdrawal by relayer or 'other'
|
||||||
* @param {LegacyGasPriceKey} speed Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
* @param {LegacyGasPriceKey} [speed=fast] Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
||||||
* @returns {Promise<string>} Gas value in WEI (hex-format)
|
* @returns {Promise<GetGasParamsRes>} Object with fields 'gasPrice', 'gasLimit' and 'l1Fee'
|
||||||
*/
|
*/
|
||||||
async getGas(tx?: TransactionData, txType: TxType = 'other', speed: LegacyGasPriceKey = 'fast'): Promise<string> {
|
async getGasParams(
|
||||||
const [gasPrice, gasLimit] = await Promise.all([this.getGasPrice(txType, speed), this.getGasLimit(tx, txType)]);
|
tx?: TransactionData,
|
||||||
let gas = BigNumber.from(gasPrice).mul(gasLimit);
|
txType: TxType = 'other',
|
||||||
if (tx) tx = Object.assign(tx, { gasPrice, gasLimit });
|
speed: LegacyGasPriceKey = 'fast',
|
||||||
if (this.chainId === ChainId.OPTIMISM) gas = gas.add(await this.fetchL1OptimismFee(tx));
|
): Promise<GetGasParamsRes> {
|
||||||
|
const [gasPrice, gasLimit, l1Fee] = await Promise.all([
|
||||||
|
this.getGasPrice(txType, speed),
|
||||||
|
this.getGasLimit(tx, txType),
|
||||||
|
this.fetchL1OptimismFee(tx),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return { gasLimit, gasPrice, l1Fee };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Estimates next block gas for signed, unsigned or incomplete Tornado transaction
|
||||||
|
* @param {TransactionData} [tx] Transaction data in web3 / ethers format
|
||||||
|
* @param {TxType} [txType=other] Tornado transaction type: withdrawal by user, withdrawal by relayer or 'other'
|
||||||
|
* @param {LegacyGasPriceKey} [speed=fast] Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
||||||
|
* @returns {Promise<HexadecimalStringifiedNumber>} Gas value in WEI (hex-format)
|
||||||
|
*/
|
||||||
|
async getGas(
|
||||||
|
tx?: TransactionData,
|
||||||
|
txType: TxType = 'other',
|
||||||
|
speed: LegacyGasPriceKey = 'fast',
|
||||||
|
): Promise<HexadecimalStringifiedNumber> {
|
||||||
|
const { gasPrice, gasLimit, l1Fee } = await this.getGasParams(tx, txType, speed);
|
||||||
|
const gas = BigNumber.from(gasPrice).mul(gasLimit).add(l1Fee);
|
||||||
|
|
||||||
return gas.toHexString();
|
return gas.toHexString();
|
||||||
}
|
}
|
||||||
@ -75,13 +106,13 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
* @param {TxType} type Tornado transaction type (to select correct default bump percent)
|
* @param {TxType} type Tornado transaction type (to select correct default bump percent)
|
||||||
* @param {LegacyGasPriceKey} speed Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
* @param {LegacyGasPriceKey} speed Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
||||||
* @param {number} bumpPercent Gas bump percent to prioritize transaction
|
* @param {number} bumpPercent Gas bump percent to prioritize transaction
|
||||||
* @returns {Promise<string>} Gas price in WEI (hex string)
|
* @returns {Promise<HexadecimalStringifiedNumber>} Gas price in WEI (hex string)
|
||||||
*/
|
*/
|
||||||
async getGasPrice(
|
async getGasPrice(
|
||||||
type: TxType = 'other',
|
type: TxType = 'other',
|
||||||
speed: LegacyGasPriceKey = 'fast',
|
speed: LegacyGasPriceKey = 'fast',
|
||||||
bumpPercent: number = 0,
|
bumpPercent: number = 0,
|
||||||
): Promise<string> {
|
): Promise<HexadecimalStringifiedNumber> {
|
||||||
const gasPriceParams = await this.getGasPriceParams(type, speed, bumpPercent);
|
const gasPriceParams = await this.getGasPriceParams(type, speed, bumpPercent);
|
||||||
return calculateGasPriceInWei(gasPriceParams).toHexString();
|
return calculateGasPriceInWei(gasPriceParams).toHexString();
|
||||||
}
|
}
|
||||||
@ -101,9 +132,9 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
*
|
*
|
||||||
* Refund needed that recipient can use tokens after withdrawal (covers gas fee for send/swap)
|
* Refund needed that recipient can use tokens after withdrawal (covers gas fee for send/swap)
|
||||||
* @param {InstanceTokenSymbol} tokenSymbol Withdrawal token (currency) symbol - for example, 'dai'
|
* @param {InstanceTokenSymbol} tokenSymbol Withdrawal token (currency) symbol - for example, 'dai'
|
||||||
* @returns {Promise<string>} Refund amount in WEI (hexed number)
|
* @returns {Promise<HexadecimalStringifiedNumber>} Refund amount in WEI (in hex format)
|
||||||
*/
|
*/
|
||||||
async calculateRefundInETH(tokenSymbol: InstanceTokenSymbol): Promise<string> {
|
async calculateRefundInETH(tokenSymbol: InstanceTokenSymbol): Promise<HexadecimalStringifiedNumber> {
|
||||||
// In Tornado we need to calculate refund only on user side, relayer get refund value in proof
|
// In Tornado we need to calculate refund only on user side, relayer get refund value in proof
|
||||||
const gasPrice = await this.getGasPrice();
|
const gasPrice = await this.getGasPrice();
|
||||||
const gasLimit = defaultInstanceTokensGasLimit[tokenSymbol];
|
const gasLimit = defaultInstanceTokensGasLimit[tokenSymbol];
|
||||||
@ -113,15 +144,15 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
/**
|
/**
|
||||||
* Get refund amount on ETH or Goerli in non-native token
|
* Get refund amount on ETH or Goerli in non-native token
|
||||||
* @param {BigNumberish} tokenPriceInEth Token price in WEI in native currency
|
* @param {BigNumberish} tokenPriceInEth Token price in WEI in native currency
|
||||||
* @param {string | number} tokenDecimals Token (currency) decimals
|
* @param {HexadecimalStringifiedNumber | number} tokenDecimals Token (currency) decimals
|
||||||
* @param {InstanceTokenSymbol} tokenSymbol Withdrawal token (currency) symbol - for example, 'dai'
|
* @param {InstanceTokenSymbol} tokenSymbol Withdrawal token (currency) symbol - for example, 'dai'
|
||||||
* @returns {Promise<string>} Refund amount in WEI in selected token (hexed number)
|
* @returns {Promise<HexadecimalStringifiedNumber>} Refund amount in WEI in selected token (hexed number)
|
||||||
*/
|
*/
|
||||||
async calculateRefundInToken(
|
async calculateRefundInToken(
|
||||||
tokenPriceInEth: BigNumberish,
|
tokenPriceInEth: BigNumberish,
|
||||||
tokenDecimals: string | number,
|
tokenDecimals: HexadecimalStringifiedNumber | number,
|
||||||
tokenSymbol: InstanceTokenSymbol,
|
tokenSymbol: InstanceTokenSymbol,
|
||||||
): Promise<string> {
|
): Promise<HexadecimalStringifiedNumber> {
|
||||||
const refundInEth = await this.calculateRefundInETH(tokenSymbol);
|
const refundInEth = await this.calculateRefundInETH(tokenSymbol);
|
||||||
return convertETHToToken(refundInEth, tokenDecimals, tokenPriceInEth).toHexString();
|
return convertETHToToken(refundInEth, tokenDecimals, tokenPriceInEth).toHexString();
|
||||||
}
|
}
|
||||||
@ -134,22 +165,22 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
* @param {TransactionData} tx Transaction data (object in web3 / ethers format)
|
* @param {TransactionData} tx Transaction data (object in web3 / ethers format)
|
||||||
* @param {number} relayerFeePercent Relayer fee percent from the transaction amount (for example, 0.15 for BNB or 0.4 for ETH Mainnet)
|
* @param {number} relayerFeePercent Relayer fee percent from the transaction amount (for example, 0.15 for BNB or 0.4 for ETH Mainnet)
|
||||||
* @param {AvailableTokenSymbols | Uppercase<AvailableTokenSymbols>} currency Currency symbol
|
* @param {AvailableTokenSymbols | Uppercase<AvailableTokenSymbols>} currency Currency symbol
|
||||||
* @param {number | string } amount Withdrawal amount in selected currency
|
* @param {number | HexadecimalStringifiedNumber } amount Withdrawal amount in selected currency
|
||||||
* @param {number | string } decimals Token (currency) decimals
|
* @param {number | HexadecimalStringifiedNumber } decimals Token (currency) decimals
|
||||||
* @param {BigNumberish} [refundInEth=0] Refund in ETH, if withdrawed other tokens on Mainnet (not ETH)
|
* @param {BigNumberish} [refundInEth=0] Refund in ETH, if withdrawed other tokens on Mainnet (not ETH)
|
||||||
* @param {BigNumberish} [tokenPriceInEth] If withdrawing other token on Mainnet or Goerli, need to provide token price in ETH (in WEI)
|
* @param {BigNumberish} [tokenPriceInEth] If withdrawing other token on Mainnet or Goerli, need to provide token price in ETH (in WEI)
|
||||||
* @returns {Promise<string>} Fee in WEI (hexed string)
|
* @returns {Promise<HexadecimalStringifiedNumber>} Fee in WEI (hexed string)
|
||||||
*/
|
*/
|
||||||
async calculateWithdrawalFeeViaRelayer(
|
async calculateWithdrawalFeeViaRelayer(
|
||||||
type: TxType,
|
type: TxType,
|
||||||
tx: TransactionData,
|
tx: TransactionData,
|
||||||
relayerFeePercent: number,
|
relayerFeePercent: number,
|
||||||
currency: AvailableTokenSymbols | Uppercase<AvailableTokenSymbols>,
|
currency: AvailableTokenSymbols | Uppercase<AvailableTokenSymbols>,
|
||||||
amount: string | number,
|
amount: HexadecimalStringifiedNumber | number,
|
||||||
decimals: string | number,
|
decimals: HexadecimalStringifiedNumber | number,
|
||||||
refundInEth: BigNumberish = 0,
|
refundInEth: BigNumberish = 0,
|
||||||
tokenPriceInEth?: BigNumberish,
|
tokenPriceInEth?: BigNumberish,
|
||||||
): Promise<string> {
|
): Promise<HexadecimalStringifiedNumber> {
|
||||||
const gasCosts = BigNumber.from(await this.getGas(tx, type));
|
const gasCosts = BigNumber.from(await this.getGas(tx, type));
|
||||||
|
|
||||||
const relayerFee = parseUnits(amount.toString(), decimals)
|
const relayerFee = parseUnits(amount.toString(), decimals)
|
||||||
|
31
src/types.ts
31
src/types.ts
@ -3,6 +3,9 @@ import { GasPriceKey, GetTxGasParamsRes } from '@tornado/gas-price-oracle/lib/se
|
|||||||
import { AvailableTokenSymbols } from '@tornado/tornado-config';
|
import { AvailableTokenSymbols } from '@tornado/tornado-config';
|
||||||
import { InstanceTokenSymbol } from './config';
|
import { InstanceTokenSymbol } from './config';
|
||||||
|
|
||||||
|
// Type for big hexadecimal numbers, like 0x1eff87f47e37a0
|
||||||
|
export type HexadecimalStringifiedNumber = string;
|
||||||
|
|
||||||
export type LegacyGasPriceKey = GasPriceKey;
|
export type LegacyGasPriceKey = GasPriceKey;
|
||||||
export type GasPriceParams = GetTxGasParamsRes;
|
export type GasPriceParams = GetTxGasParamsRes;
|
||||||
export type LegacyGasPrices = {
|
export type LegacyGasPrices = {
|
||||||
@ -32,27 +35,32 @@ export interface TransactionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ITornadoFeeOracle {
|
export interface ITornadoFeeOracle {
|
||||||
getGas: (tx?: TransactionData, type?: TxType) => Promise<string>;
|
getGasParams: (tx?: TransactionData, txType?: TxType, speed?: LegacyGasPriceKey) => Promise<GetGasParamsRes>;
|
||||||
|
getGas: (tx?: TransactionData, type?: TxType) => Promise<HexadecimalStringifiedNumber>;
|
||||||
getGasPriceParams: (type?: TxType, speed?: LegacyGasPriceKey, bumpPercent?: number) => Promise<GasPriceParams>;
|
getGasPriceParams: (type?: TxType, speed?: LegacyGasPriceKey, bumpPercent?: number) => Promise<GasPriceParams>;
|
||||||
getGasPrice: (type?: TxType, speed?: LegacyGasPriceKey, bumpPercent?: number) => Promise<string>;
|
getGasPrice: (
|
||||||
|
type?: TxType,
|
||||||
|
speed?: LegacyGasPriceKey,
|
||||||
|
bumpPercent?: number,
|
||||||
|
) => Promise<HexadecimalStringifiedNumber>;
|
||||||
getGasLimit: (tx?: TransactionData, type?: TxType, bumpPercent?: number) => Promise<number>;
|
getGasLimit: (tx?: TransactionData, type?: TxType, bumpPercent?: number) => Promise<number>;
|
||||||
fetchL1OptimismFee: (tx?: TransactionData) => Promise<string>;
|
fetchL1OptimismFee: (tx?: TransactionData) => Promise<HexadecimalStringifiedNumber>;
|
||||||
calculateRefundInETH: (tokenSymbol: InstanceTokenSymbol) => Promise<string>;
|
calculateRefundInETH: (tokenSymbol: InstanceTokenSymbol) => Promise<HexadecimalStringifiedNumber>;
|
||||||
calculateRefundInToken: (
|
calculateRefundInToken: (
|
||||||
tokenPriceInEth: BigNumberish,
|
tokenPriceInEth: BigNumberish,
|
||||||
tokenDecimals: string | number,
|
tokenDecimals: HexadecimalStringifiedNumber | number,
|
||||||
tokenSymbol: InstanceTokenSymbol,
|
tokenSymbol: InstanceTokenSymbol,
|
||||||
) => Promise<string>;
|
) => Promise<HexadecimalStringifiedNumber>;
|
||||||
calculateWithdrawalFeeViaRelayer: (
|
calculateWithdrawalFeeViaRelayer: (
|
||||||
type: TxType,
|
type: TxType,
|
||||||
tx: TransactionData,
|
tx: TransactionData,
|
||||||
relayerFeePercent: number,
|
relayerFeePercent: number,
|
||||||
currency: AvailableTokenSymbols,
|
currency: AvailableTokenSymbols,
|
||||||
amount: string,
|
amount: HexadecimalStringifiedNumber | number,
|
||||||
decimals: number,
|
decimals: number,
|
||||||
refundInEth: BigNumberish,
|
refundInEth: BigNumberish,
|
||||||
tokenPriceInEth?: BigNumberish,
|
tokenPriceInEth?: BigNumberish,
|
||||||
) => Promise<string>;
|
) => Promise<HexadecimalStringifiedNumber>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITornadoPriceOracle {
|
export interface ITornadoPriceOracle {
|
||||||
@ -79,3 +87,10 @@ export type Token = {
|
|||||||
decimals: number;
|
decimals: number;
|
||||||
};
|
};
|
||||||
export type TokenPrices = { [tokenSymbol in TokenSymbol]?: BigNumberish };
|
export type TokenPrices = { [tokenSymbol in TokenSymbol]?: BigNumberish };
|
||||||
|
|
||||||
|
// Reponse type for getGasParams function of fee oracle
|
||||||
|
export type GetGasParamsRes = {
|
||||||
|
gasLimit: number;
|
||||||
|
gasPrice: HexadecimalStringifiedNumber;
|
||||||
|
l1Fee: HexadecimalStringifiedNumber;
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user