From 7b6cf87a0134e35e50ac8a651de77287fca6ceca Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Sat, 6 Jul 2024 10:37:21 +0700 Subject: [PATCH 1/6] [Issue-239] Fix enforcing the minimum miner tip --- .../src/koni/api/tokens/evm/transfer.ts | 9 +++++--- .../src/koni/background/handlers/Extension.ts | 19 +++++++++------ .../src/services/fee-service/service.ts | 4 ++-- .../src/services/fee-service/utils/index.ts | 23 +++++++++++++++---- .../src/services/transaction-service/index.ts | 3 ++- .../src/types/fee/subscription.ts | 2 +- 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/packages/extension-base/src/koni/api/tokens/evm/transfer.ts b/packages/extension-base/src/koni/api/tokens/evm/transfer.ts index 40693f1501c..484709152ea 100644 --- a/packages/extension-base/src/koni/api/tokens/evm/transfer.ts +++ b/packages/extension-base/src/koni/api/tokens/evm/transfer.ts @@ -56,6 +56,7 @@ interface TransferEvmProps extends TransactionFee { transferAll: boolean; value: string; evmApi: _EvmApi; + isTestnet: boolean } export async function getEVMTransactionObject ({ chain, @@ -64,13 +65,13 @@ export async function getEVMTransactionObject ({ chain, feeOption, from, getChainFee, + isTestnet, to, transferAll, value }: TransferEvmProps): Promise<[TransactionConfig, string]> { const id = getId(); const feeCustom = _feeCustom as EvmEIP1995FeeOption; - const feeInfo = await getChainFee(id, chain, 'evm') as EvmFeeInfo; - + const feeInfo = await getChainFee(id, chain, 'evm', isTestnet) as EvmFeeInfo; const feeCombine = combineEthFee(feeInfo, feeOption, feeCustom); const transactionObject = { @@ -114,6 +115,7 @@ interface TransferERC20Props extends TransactionFee { to: string; transferAll: boolean; value: string; + isTestnet: boolean } export async function getERC20TransactionObject ({ assetAddress, @@ -123,6 +125,7 @@ export async function getERC20TransactionObject ({ assetAddress, feeOption, from, getChainFee, + isTestnet, to, transferAll, value }: TransferERC20Props): Promise<[TransactionConfig, string]> { @@ -151,7 +154,7 @@ export async function getERC20TransactionObject ({ assetAddress, const [gasLimit, _feeInfo] = await Promise.all([ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access erc20Contract.methods.transfer(to, transferValue).estimateGas({ from }) as number, - getChainFee(id, chain, 'evm') + getChainFee(id, chain, 'evm', isTestnet) ]); const feeInfo = _feeInfo as EvmFeeInfo; diff --git a/packages/extension-base/src/koni/background/handlers/Extension.ts b/packages/extension-base/src/koni/background/handlers/Extension.ts index 49cd1f61054..2e232030887 100644 --- a/packages/extension-base/src/koni/background/handlers/Extension.ts +++ b/packages/extension-base/src/koni/background/handlers/Extension.ts @@ -1868,6 +1868,7 @@ export default class KoniExtension { const evmApiMap = this.#koniState.getEvmApiMap(); const chainInfo = this.#koniState.getChainInfo(chain); + const isTestnet = chainInfo.isTestnet; const nativeTokenInfo = this.#koniState.getNativeTokenInfo(chain); const nativeTokenSlug: string = nativeTokenInfo.slug; const isTransferNativeToken = nativeTokenSlug === tokenSlug; @@ -1881,8 +1882,8 @@ export default class KoniExtension { // Get native token amount const freeBalance = await this.getAddressFreeBalance({ address: from, networkKey: chain, token: tokenSlug }); - const getChainFee: GetFeeFunction = (id, chain, type) => { - return this.#koniState.feeService.subscribeChainFee(id, chain, type); + const getChainFee: GetFeeFunction = (id, chain, type, isTestnet) => { + return this.#koniState.feeService.subscribeChainFee(id, chain, type, isTestnet); }; const txVal: string = transferAll ? freeBalance.value : (value || '0'); @@ -1907,7 +1908,8 @@ export default class KoniExtension { getChainFee, to, transferAll, - value: txVal + value: txVal, + isTestnet }); } else { [ @@ -1922,7 +1924,8 @@ export default class KoniExtension { getChainFee, to, transferAll, - value: txVal + value: txVal, + isTestnet }); } } else if (_isMantaZkAsset(tokenInfo)) { // TODO @@ -2045,6 +2048,7 @@ export default class KoniExtension { const warnings: TransactionWarning[] = []; const chainInfo = this.#koniState.getChainInfo(chain); + const isTesnet = chainInfo.isTestnet; const nativeTokenInfo = this.#koniState.getNativeTokenInfo(chain); const nativeTokenSlug: string = nativeTokenInfo.slug; const isTransferNativeToken = nativeTokenSlug === tokenSlug; @@ -2059,7 +2063,7 @@ export default class KoniExtension { const freeBalance = await this.getAddressFreeBalance({ address: from, networkKey: chain, token: tokenSlug }); const getChainFee: GetFeeFunction = (id, chain, type) => { - return this.#koniState.feeService.subscribeChainFee(id, chain, type); + return this.#koniState.feeService.subscribeChainFee(id, chain, type, isTesnet); }; const txVal: string = transferAll ? freeBalance.value : (value || '0'); @@ -2122,11 +2126,12 @@ export default class KoniExtension { const { chain, feeCustom, feeOption, from, to, transferAll, value } = inputData; const chainInfo = this.#koniState.getChainInfo(chain); + const isTestnet = chainInfo.isTestnet; const bitcoinApi = this.#koniState.getBitcoinApi(chain); // Get Bitcoin API map const network = chainInfo.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin; const getChainFee: GetFeeFunction = (id, chain, type) => { - return this.#koniState.feeService.subscribeChainFee(id, chain, type); + return this.#koniState.feeService.subscribeChainFee(id, chain, type, isTestnet); }; const [ @@ -2783,7 +2788,7 @@ export default class KoniExtension { freeBalanceSubject.next(data); // Must be called after subscription }); - const fee = await this.#koniState.feeService.subscribeChainFee(id, chain, feeChainType, (data) => { + const fee = await this.#koniState.feeService.subscribeChainFee(id, chain, feeChainType, undefined, (data) => { feeSubject.next(data); // Must be called after subscription }); diff --git a/packages/extension-base/src/services/fee-service/service.ts b/packages/extension-base/src/services/fee-service/service.ts index 7db6298d320..ecd91fd0cda 100644 --- a/packages/extension-base/src/services/fee-service/service.ts +++ b/packages/extension-base/src/services/fee-service/service.ts @@ -87,7 +87,7 @@ export default class FeeService { }; } - public subscribeChainFee (id: string, chain: string, type: FeeChainType, callback?: (data: FeeInfo) => void) { + public subscribeChainFee (id: string, chain: string, type: FeeChainType, isTestnet = true, callback?: (data: FeeInfo) => void) { return new Promise((resolve) => { const _callback = (value: FeeInfo | undefined) => { console.log(id, this.chainFeeSubscriptionMap); @@ -134,7 +134,7 @@ export default class FeeService { if (type === 'evm') { const api = this.state.getEvmApi(chain); - calculateGasFeeParams(api, chain) + calculateGasFeeParams(api, chain, false, false, isTestnet) .then((info) => { observer.next(info); }) diff --git a/packages/extension-base/src/services/fee-service/utils/index.ts b/packages/extension-base/src/services/fee-service/utils/index.ts index 103574a0a63..a520be574f0 100644 --- a/packages/extension-base/src/services/fee-service/utils/index.ts +++ b/packages/extension-base/src/services/fee-service/utils/index.ts @@ -10,6 +10,7 @@ import BigN from 'bignumber.js'; const INFURA_API_KEY = process.env.INFURA_API_KEY || ''; const INFURA_API_KEY_SECRET = process.env.INFURA_API_KEY_SECRET || ''; const INFURA_AUTH = 'Basic ' + Buffer.from(INFURA_API_KEY + ':' + INFURA_API_KEY_SECRET).toString('base64'); +const EIP1559_MIN_PRIORITY_FEE = '1'; export const parseInfuraFee = (info: InfuraFeeInfo, threshold: InfuraThresholdInfo): EvmFeeInfo => { const base = new BigN(info.estimatedBaseFee).multipliedBy(BN_WEI); @@ -122,7 +123,7 @@ export const getEIP1559GasFee = ( return { maxFeePerGas: maxFee.toFixed(0), maxPriorityFeePerGas: maxPriorityFee.toFixed(0), time }; }; -export const calculateGasFeeParams = async (web3: _EvmApi, networkKey: string, useOnline = false, useInfura = false): Promise => { +export const calculateGasFeeParams = async (web3: _EvmApi, networkKey: string, useOnline = false, useInfura = false, isTestnet?: boolean): Promise => { if (useOnline) { try { const chainId = await web3.api.eth.getChainId(); @@ -167,15 +168,19 @@ export const calculateGasFeeParams = async (web3: _EvmApi, networkKey: string, u const averagePriorityFee = history.reward.reduce((previous, rewards) => previous.plus(rewards[1]), BN_ZERO).dividedBy(numBlock).decimalPlaces(0); const fastPriorityFee = history.reward.reduce((previous, rewards) => previous.plus(rewards[2]), BN_ZERO).dividedBy(numBlock).decimalPlaces(0); + const slowFee = enforceMinOneTip(getEIP1559GasFee(baseGasFee, slowPriorityFee, 30000), isTestnet); + const averageFee = enforceMinOneTip(getEIP1559GasFee(baseGasFee, averagePriorityFee, 45000), isTestnet); + const fastFee = enforceMinOneTip(getEIP1559GasFee(baseGasFee, fastPriorityFee, 60000), isTestnet); + return { type: 'evm', gasPrice: undefined, baseGasFee: baseGasFee.toString(), busyNetwork, options: { - slow: getEIP1559GasFee(baseGasFee, slowPriorityFee, 30000), - average: getEIP1559GasFee(baseGasFee, averagePriorityFee, 45000), - fast: getEIP1559GasFee(baseGasFee, fastPriorityFee, 60000), + slow: slowFee, + average: averageFee, + fast: fastFee, default: busyNetwork ? 'average' : 'slow' } }; @@ -192,3 +197,13 @@ export const calculateGasFeeParams = async (web3: _EvmApi, networkKey: string, u }; } }; + +const enforceMinOneTip = (feeOptionDetail: EvmEIP1995FeeOptionDetail, isTestnet?: boolean): EvmEIP1995FeeOptionDetail => { + if (isTestnet && feeOptionDetail.maxPriorityFeePerGas === '0') { + feeOptionDetail.maxPriorityFeePerGas = EIP1559_MIN_PRIORITY_FEE; + + return feeOptionDetail; + } + + return feeOptionDetail; +}; diff --git a/packages/extension-base/src/services/transaction-service/index.ts b/packages/extension-base/src/services/transaction-service/index.ts index e64a8764f14..efd0a208846 100644 --- a/packages/extension-base/src/services/transaction-service/index.ts +++ b/packages/extension-base/src/services/transaction-service/index.ts @@ -175,9 +175,10 @@ export default class TransactionService { if (!web3) { validationResponse.errors.push(new TransactionError(BasicTxErrorType.CHAIN_DISCONNECTED, undefined)); } else { + const isTestnet = chainInfo.isTestnet; const gasLimit = await web3.api.eth.estimateGas(transaction); - const feeInfo = await this.state.feeService.subscribeChainFee(id, chain, 'evm') as EvmFeeInfo; + const feeInfo = await this.state.feeService.subscribeChainFee(id, chain, 'evm', isTestnet) as EvmFeeInfo; const feeCombine = combineEthFee(feeInfo, feeOption, feeCustom as EvmEIP1995FeeOption); if (feeCombine.maxFeePerGas) { diff --git a/packages/extension-base/src/types/fee/subscription.ts b/packages/extension-base/src/types/fee/subscription.ts index 4aef7c8548c..b3748154f21 100644 --- a/packages/extension-base/src/types/fee/subscription.ts +++ b/packages/extension-base/src/types/fee/subscription.ts @@ -18,4 +18,4 @@ export interface FeeSubscription { unsubscribe: VoidFunction; } -export type GetFeeFunction = (id: string, chain: string, type: FeeChainType) => Promise; +export type GetFeeFunction = (id: string, chain: string, type: FeeChainType, isTestnet?: boolean) => Promise; From 86ca6548ffdf5bc9827856707f35ed5743670dfe Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Sat, 6 Jul 2024 10:49:09 +0700 Subject: [PATCH 2/6] fix eslint --- .../src/services/transaction-service/balance.spec.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/extension-base/src/services/transaction-service/balance.spec.ts b/packages/extension-base/src/services/transaction-service/balance.spec.ts index bbff592ea5b..90b596d2c42 100644 --- a/packages/extension-base/src/services/transaction-service/balance.spec.ts +++ b/packages/extension-base/src/services/transaction-service/balance.spec.ts @@ -87,6 +87,7 @@ describe('test token transfer', () => { for (let i = start; i < start + count && i < chainList.length; i++) { const chain = chainList[i]; + const isTestnet = chain.isTestnet; const networkKey = chain.slug; console.log('current', i); @@ -117,7 +118,8 @@ describe('test token transfer', () => { getChainFee, to: '0x5e10e440FEce4dB0b16a6159A4536efb74d32E9b', transferAll: false, - value: '0' + value: '0', + isTestnet }); } else { [transaction] = await getEVMTransactionObject({ @@ -127,7 +129,8 @@ describe('test token transfer', () => { getChainFee, to: '0x5e10e440FEce4dB0b16a6159A4536efb74d32E9b', transferAll: false, - value: '0' + value: '0', + isTestnet }); } From 912ab594c6d7e06b1bf408f6f9d9d17723d43906 Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Sat, 6 Jul 2024 11:25:40 +0700 Subject: [PATCH 3/6] Revert "fix eslint" This reverts commit 86ca6548ffdf5bc9827856707f35ed5743670dfe. --- .../src/services/transaction-service/balance.spec.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/extension-base/src/services/transaction-service/balance.spec.ts b/packages/extension-base/src/services/transaction-service/balance.spec.ts index 90b596d2c42..bbff592ea5b 100644 --- a/packages/extension-base/src/services/transaction-service/balance.spec.ts +++ b/packages/extension-base/src/services/transaction-service/balance.spec.ts @@ -87,7 +87,6 @@ describe('test token transfer', () => { for (let i = start; i < start + count && i < chainList.length; i++) { const chain = chainList[i]; - const isTestnet = chain.isTestnet; const networkKey = chain.slug; console.log('current', i); @@ -118,8 +117,7 @@ describe('test token transfer', () => { getChainFee, to: '0x5e10e440FEce4dB0b16a6159A4536efb74d32E9b', transferAll: false, - value: '0', - isTestnet + value: '0' }); } else { [transaction] = await getEVMTransactionObject({ @@ -129,8 +127,7 @@ describe('test token transfer', () => { getChainFee, to: '0x5e10e440FEce4dB0b16a6159A4536efb74d32E9b', transferAll: false, - value: '0', - isTestnet + value: '0' }); } From fdbd06bd4ad028fcd469c3f3d16c4660129bf0e2 Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Sat, 6 Jul 2024 11:25:47 +0700 Subject: [PATCH 4/6] Revert "[Issue-239] Fix enforcing the minimum miner tip" This reverts commit 7b6cf87a0134e35e50ac8a651de77287fca6ceca. --- .../src/koni/api/tokens/evm/transfer.ts | 9 +++----- .../src/koni/background/handlers/Extension.ts | 19 ++++++--------- .../src/services/fee-service/service.ts | 4 ++-- .../src/services/fee-service/utils/index.ts | 23 ++++--------------- .../src/services/transaction-service/index.ts | 3 +-- .../src/types/fee/subscription.ts | 2 +- 6 files changed, 18 insertions(+), 42 deletions(-) diff --git a/packages/extension-base/src/koni/api/tokens/evm/transfer.ts b/packages/extension-base/src/koni/api/tokens/evm/transfer.ts index 484709152ea..40693f1501c 100644 --- a/packages/extension-base/src/koni/api/tokens/evm/transfer.ts +++ b/packages/extension-base/src/koni/api/tokens/evm/transfer.ts @@ -56,7 +56,6 @@ interface TransferEvmProps extends TransactionFee { transferAll: boolean; value: string; evmApi: _EvmApi; - isTestnet: boolean } export async function getEVMTransactionObject ({ chain, @@ -65,13 +64,13 @@ export async function getEVMTransactionObject ({ chain, feeOption, from, getChainFee, - isTestnet, to, transferAll, value }: TransferEvmProps): Promise<[TransactionConfig, string]> { const id = getId(); const feeCustom = _feeCustom as EvmEIP1995FeeOption; - const feeInfo = await getChainFee(id, chain, 'evm', isTestnet) as EvmFeeInfo; + const feeInfo = await getChainFee(id, chain, 'evm') as EvmFeeInfo; + const feeCombine = combineEthFee(feeInfo, feeOption, feeCustom); const transactionObject = { @@ -115,7 +114,6 @@ interface TransferERC20Props extends TransactionFee { to: string; transferAll: boolean; value: string; - isTestnet: boolean } export async function getERC20TransactionObject ({ assetAddress, @@ -125,7 +123,6 @@ export async function getERC20TransactionObject ({ assetAddress, feeOption, from, getChainFee, - isTestnet, to, transferAll, value }: TransferERC20Props): Promise<[TransactionConfig, string]> { @@ -154,7 +151,7 @@ export async function getERC20TransactionObject ({ assetAddress, const [gasLimit, _feeInfo] = await Promise.all([ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access erc20Contract.methods.transfer(to, transferValue).estimateGas({ from }) as number, - getChainFee(id, chain, 'evm', isTestnet) + getChainFee(id, chain, 'evm') ]); const feeInfo = _feeInfo as EvmFeeInfo; diff --git a/packages/extension-base/src/koni/background/handlers/Extension.ts b/packages/extension-base/src/koni/background/handlers/Extension.ts index 2e232030887..49cd1f61054 100644 --- a/packages/extension-base/src/koni/background/handlers/Extension.ts +++ b/packages/extension-base/src/koni/background/handlers/Extension.ts @@ -1868,7 +1868,6 @@ export default class KoniExtension { const evmApiMap = this.#koniState.getEvmApiMap(); const chainInfo = this.#koniState.getChainInfo(chain); - const isTestnet = chainInfo.isTestnet; const nativeTokenInfo = this.#koniState.getNativeTokenInfo(chain); const nativeTokenSlug: string = nativeTokenInfo.slug; const isTransferNativeToken = nativeTokenSlug === tokenSlug; @@ -1882,8 +1881,8 @@ export default class KoniExtension { // Get native token amount const freeBalance = await this.getAddressFreeBalance({ address: from, networkKey: chain, token: tokenSlug }); - const getChainFee: GetFeeFunction = (id, chain, type, isTestnet) => { - return this.#koniState.feeService.subscribeChainFee(id, chain, type, isTestnet); + const getChainFee: GetFeeFunction = (id, chain, type) => { + return this.#koniState.feeService.subscribeChainFee(id, chain, type); }; const txVal: string = transferAll ? freeBalance.value : (value || '0'); @@ -1908,8 +1907,7 @@ export default class KoniExtension { getChainFee, to, transferAll, - value: txVal, - isTestnet + value: txVal }); } else { [ @@ -1924,8 +1922,7 @@ export default class KoniExtension { getChainFee, to, transferAll, - value: txVal, - isTestnet + value: txVal }); } } else if (_isMantaZkAsset(tokenInfo)) { // TODO @@ -2048,7 +2045,6 @@ export default class KoniExtension { const warnings: TransactionWarning[] = []; const chainInfo = this.#koniState.getChainInfo(chain); - const isTesnet = chainInfo.isTestnet; const nativeTokenInfo = this.#koniState.getNativeTokenInfo(chain); const nativeTokenSlug: string = nativeTokenInfo.slug; const isTransferNativeToken = nativeTokenSlug === tokenSlug; @@ -2063,7 +2059,7 @@ export default class KoniExtension { const freeBalance = await this.getAddressFreeBalance({ address: from, networkKey: chain, token: tokenSlug }); const getChainFee: GetFeeFunction = (id, chain, type) => { - return this.#koniState.feeService.subscribeChainFee(id, chain, type, isTesnet); + return this.#koniState.feeService.subscribeChainFee(id, chain, type); }; const txVal: string = transferAll ? freeBalance.value : (value || '0'); @@ -2126,12 +2122,11 @@ export default class KoniExtension { const { chain, feeCustom, feeOption, from, to, transferAll, value } = inputData; const chainInfo = this.#koniState.getChainInfo(chain); - const isTestnet = chainInfo.isTestnet; const bitcoinApi = this.#koniState.getBitcoinApi(chain); // Get Bitcoin API map const network = chainInfo.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin; const getChainFee: GetFeeFunction = (id, chain, type) => { - return this.#koniState.feeService.subscribeChainFee(id, chain, type, isTestnet); + return this.#koniState.feeService.subscribeChainFee(id, chain, type); }; const [ @@ -2788,7 +2783,7 @@ export default class KoniExtension { freeBalanceSubject.next(data); // Must be called after subscription }); - const fee = await this.#koniState.feeService.subscribeChainFee(id, chain, feeChainType, undefined, (data) => { + const fee = await this.#koniState.feeService.subscribeChainFee(id, chain, feeChainType, (data) => { feeSubject.next(data); // Must be called after subscription }); diff --git a/packages/extension-base/src/services/fee-service/service.ts b/packages/extension-base/src/services/fee-service/service.ts index ecd91fd0cda..7db6298d320 100644 --- a/packages/extension-base/src/services/fee-service/service.ts +++ b/packages/extension-base/src/services/fee-service/service.ts @@ -87,7 +87,7 @@ export default class FeeService { }; } - public subscribeChainFee (id: string, chain: string, type: FeeChainType, isTestnet = true, callback?: (data: FeeInfo) => void) { + public subscribeChainFee (id: string, chain: string, type: FeeChainType, callback?: (data: FeeInfo) => void) { return new Promise((resolve) => { const _callback = (value: FeeInfo | undefined) => { console.log(id, this.chainFeeSubscriptionMap); @@ -134,7 +134,7 @@ export default class FeeService { if (type === 'evm') { const api = this.state.getEvmApi(chain); - calculateGasFeeParams(api, chain, false, false, isTestnet) + calculateGasFeeParams(api, chain) .then((info) => { observer.next(info); }) diff --git a/packages/extension-base/src/services/fee-service/utils/index.ts b/packages/extension-base/src/services/fee-service/utils/index.ts index a520be574f0..103574a0a63 100644 --- a/packages/extension-base/src/services/fee-service/utils/index.ts +++ b/packages/extension-base/src/services/fee-service/utils/index.ts @@ -10,7 +10,6 @@ import BigN from 'bignumber.js'; const INFURA_API_KEY = process.env.INFURA_API_KEY || ''; const INFURA_API_KEY_SECRET = process.env.INFURA_API_KEY_SECRET || ''; const INFURA_AUTH = 'Basic ' + Buffer.from(INFURA_API_KEY + ':' + INFURA_API_KEY_SECRET).toString('base64'); -const EIP1559_MIN_PRIORITY_FEE = '1'; export const parseInfuraFee = (info: InfuraFeeInfo, threshold: InfuraThresholdInfo): EvmFeeInfo => { const base = new BigN(info.estimatedBaseFee).multipliedBy(BN_WEI); @@ -123,7 +122,7 @@ export const getEIP1559GasFee = ( return { maxFeePerGas: maxFee.toFixed(0), maxPriorityFeePerGas: maxPriorityFee.toFixed(0), time }; }; -export const calculateGasFeeParams = async (web3: _EvmApi, networkKey: string, useOnline = false, useInfura = false, isTestnet?: boolean): Promise => { +export const calculateGasFeeParams = async (web3: _EvmApi, networkKey: string, useOnline = false, useInfura = false): Promise => { if (useOnline) { try { const chainId = await web3.api.eth.getChainId(); @@ -168,19 +167,15 @@ export const calculateGasFeeParams = async (web3: _EvmApi, networkKey: string, u const averagePriorityFee = history.reward.reduce((previous, rewards) => previous.plus(rewards[1]), BN_ZERO).dividedBy(numBlock).decimalPlaces(0); const fastPriorityFee = history.reward.reduce((previous, rewards) => previous.plus(rewards[2]), BN_ZERO).dividedBy(numBlock).decimalPlaces(0); - const slowFee = enforceMinOneTip(getEIP1559GasFee(baseGasFee, slowPriorityFee, 30000), isTestnet); - const averageFee = enforceMinOneTip(getEIP1559GasFee(baseGasFee, averagePriorityFee, 45000), isTestnet); - const fastFee = enforceMinOneTip(getEIP1559GasFee(baseGasFee, fastPriorityFee, 60000), isTestnet); - return { type: 'evm', gasPrice: undefined, baseGasFee: baseGasFee.toString(), busyNetwork, options: { - slow: slowFee, - average: averageFee, - fast: fastFee, + slow: getEIP1559GasFee(baseGasFee, slowPriorityFee, 30000), + average: getEIP1559GasFee(baseGasFee, averagePriorityFee, 45000), + fast: getEIP1559GasFee(baseGasFee, fastPriorityFee, 60000), default: busyNetwork ? 'average' : 'slow' } }; @@ -197,13 +192,3 @@ export const calculateGasFeeParams = async (web3: _EvmApi, networkKey: string, u }; } }; - -const enforceMinOneTip = (feeOptionDetail: EvmEIP1995FeeOptionDetail, isTestnet?: boolean): EvmEIP1995FeeOptionDetail => { - if (isTestnet && feeOptionDetail.maxPriorityFeePerGas === '0') { - feeOptionDetail.maxPriorityFeePerGas = EIP1559_MIN_PRIORITY_FEE; - - return feeOptionDetail; - } - - return feeOptionDetail; -}; diff --git a/packages/extension-base/src/services/transaction-service/index.ts b/packages/extension-base/src/services/transaction-service/index.ts index efd0a208846..e64a8764f14 100644 --- a/packages/extension-base/src/services/transaction-service/index.ts +++ b/packages/extension-base/src/services/transaction-service/index.ts @@ -175,10 +175,9 @@ export default class TransactionService { if (!web3) { validationResponse.errors.push(new TransactionError(BasicTxErrorType.CHAIN_DISCONNECTED, undefined)); } else { - const isTestnet = chainInfo.isTestnet; const gasLimit = await web3.api.eth.estimateGas(transaction); - const feeInfo = await this.state.feeService.subscribeChainFee(id, chain, 'evm', isTestnet) as EvmFeeInfo; + const feeInfo = await this.state.feeService.subscribeChainFee(id, chain, 'evm') as EvmFeeInfo; const feeCombine = combineEthFee(feeInfo, feeOption, feeCustom as EvmEIP1995FeeOption); if (feeCombine.maxFeePerGas) { diff --git a/packages/extension-base/src/types/fee/subscription.ts b/packages/extension-base/src/types/fee/subscription.ts index b3748154f21..4aef7c8548c 100644 --- a/packages/extension-base/src/types/fee/subscription.ts +++ b/packages/extension-base/src/types/fee/subscription.ts @@ -18,4 +18,4 @@ export interface FeeSubscription { unsubscribe: VoidFunction; } -export type GetFeeFunction = (id: string, chain: string, type: FeeChainType, isTestnet?: boolean) => Promise; +export type GetFeeFunction = (id: string, chain: string, type: FeeChainType) => Promise; From 0e55c341686c285ba9226111fcd8e1d72c0f1d44 Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Sat, 6 Jul 2024 11:44:50 +0700 Subject: [PATCH 5/6] [Issue-239] Fix enforcing the minimum miner tip --- .../services/chain-service/handler/EvmApi.ts | 4 +++- .../chain-service/handler/EvmChainHandler.ts | 4 ++-- .../services/chain-service/handler/types.ts | 1 + .../src/services/chain-service/index.ts | 3 ++- .../src/services/chain-service/types.ts | 1 + .../src/services/fee-service/utils/index.ts | 23 ++++++++++++++++--- 6 files changed, 29 insertions(+), 7 deletions(-) diff --git a/packages/extension-base/src/services/chain-service/handler/EvmApi.ts b/packages/extension-base/src/services/chain-service/handler/EvmApi.ts index b5d21b2f734..c46bca09331 100644 --- a/packages/extension-base/src/services/chain-service/handler/EvmApi.ts +++ b/packages/extension-base/src/services/chain-service/handler/EvmApi.ts @@ -16,6 +16,7 @@ export class EvmApi implements _EvmApi { api: Web3; apiUrl: string; provider: HttpProvider | WebsocketProvider; + isTestnet?: boolean; apiError?: string; apiRetry = 0; public readonly isApiConnectedSubject = new BehaviorSubject(false); @@ -77,11 +78,12 @@ export class EvmApi implements _EvmApi { } } - constructor (chainSlug: string, apiUrl: string, { providerName }: _ApiOptions = {}) { + constructor (chainSlug: string, apiUrl: string, { isTestnet, providerName }: _ApiOptions = {}) { this.chainSlug = chainSlug; this.apiUrl = apiUrl; this.providerName = providerName || 'unknown'; this.provider = this.createProvider(apiUrl); + this.isTestnet = isTestnet; this.api = new Web3(this.provider); this.isReadyHandler = createPromiseHandler<_EvmApi>(); diff --git a/packages/extension-base/src/services/chain-service/handler/EvmChainHandler.ts b/packages/extension-base/src/services/chain-service/handler/EvmChainHandler.ts index f271be807f3..9fd0ab43d00 100644 --- a/packages/extension-base/src/services/chain-service/handler/EvmChainHandler.ts +++ b/packages/extension-base/src/services/chain-service/handler/EvmChainHandler.ts @@ -40,7 +40,7 @@ export class EvmChainHandler extends AbstractChainHandler { this.evmApiMap[chainSlug] = evmApi; } - public async initApi (chainSlug: string, apiUrl: string, { onUpdateStatus, providerName }: Omit<_ApiOptions, 'metadata'> = {}) { + public async initApi (chainSlug: string, apiUrl: string, { isTestnet, onUpdateStatus, providerName }: Omit<_ApiOptions, 'metadata'> = {}) { const existed = this.getEvmApiByChain(chainSlug); if (existed) { @@ -53,7 +53,7 @@ export class EvmChainHandler extends AbstractChainHandler { return existed; } - const apiObject = new EvmApi(chainSlug, apiUrl, { providerName }); + const apiObject = new EvmApi(chainSlug, apiUrl, { isTestnet, providerName }); apiObject.connectionStatusSubject.subscribe(this.handleConnection.bind(this, chainSlug)); apiObject.connectionStatusSubject.subscribe(onUpdateStatus); diff --git a/packages/extension-base/src/services/chain-service/handler/types.ts b/packages/extension-base/src/services/chain-service/handler/types.ts index 8f95d2b6224..b7749b95038 100644 --- a/packages/extension-base/src/services/chain-service/handler/types.ts +++ b/packages/extension-base/src/services/chain-service/handler/types.ts @@ -26,6 +26,7 @@ export interface _SubstrateChainSpec { export interface _ApiOptions { providerName?: string, + isTestnet?: boolean, metadata?: MetadataItem, onUpdateStatus?: (status: _ChainConnectionStatus) => void, externalApiPromise?: ApiPromise diff --git a/packages/extension-base/src/services/chain-service/index.ts b/packages/extension-base/src/services/chain-service/index.ts index cee87568173..84c4befe806 100644 --- a/packages/extension-base/src/services/chain-service/index.ts +++ b/packages/extension-base/src/services/chain-service/index.ts @@ -969,7 +969,8 @@ export class ChainService { } if (chainInfo.evmInfo !== null && chainInfo.evmInfo !== undefined) { - const chainApi = await this.evmChainHandler.initApi(chainInfo.slug, endpoint, { providerName, onUpdateStatus }); + const isTestnet = chainInfo.isTestnet; + const chainApi = await this.evmChainHandler.initApi(chainInfo.slug, endpoint, { isTestnet, providerName, onUpdateStatus }); this.evmChainHandler.setEvmApi(chainInfo.slug, chainApi); } diff --git a/packages/extension-base/src/services/chain-service/types.ts b/packages/extension-base/src/services/chain-service/types.ts index ab9e6e8ac81..347a4b5ef73 100644 --- a/packages/extension-base/src/services/chain-service/types.ts +++ b/packages/extension-base/src/services/chain-service/types.ts @@ -50,6 +50,7 @@ export interface _ChainBaseApi { chainSlug: string; apiUrl: string; providerName?: string; + isTestnet?: boolean; apiError?: string; apiRetry?: number; diff --git a/packages/extension-base/src/services/fee-service/utils/index.ts b/packages/extension-base/src/services/fee-service/utils/index.ts index 103574a0a63..4ce5e8ef314 100644 --- a/packages/extension-base/src/services/fee-service/utils/index.ts +++ b/packages/extension-base/src/services/fee-service/utils/index.ts @@ -10,6 +10,7 @@ import BigN from 'bignumber.js'; const INFURA_API_KEY = process.env.INFURA_API_KEY || ''; const INFURA_API_KEY_SECRET = process.env.INFURA_API_KEY_SECRET || ''; const INFURA_AUTH = 'Basic ' + Buffer.from(INFURA_API_KEY + ':' + INFURA_API_KEY_SECRET).toString('base64'); +const EIP1559_MIN_PRIORITY_FEE = '1'; export const parseInfuraFee = (info: InfuraFeeInfo, threshold: InfuraThresholdInfo): EvmFeeInfo => { const base = new BigN(info.estimatedBaseFee).multipliedBy(BN_WEI); @@ -167,15 +168,21 @@ export const calculateGasFeeParams = async (web3: _EvmApi, networkKey: string, u const averagePriorityFee = history.reward.reduce((previous, rewards) => previous.plus(rewards[1]), BN_ZERO).dividedBy(numBlock).decimalPlaces(0); const fastPriorityFee = history.reward.reduce((previous, rewards) => previous.plus(rewards[2]), BN_ZERO).dividedBy(numBlock).decimalPlaces(0); + const slowFee = enforceMinOneTip(getEIP1559GasFee(baseGasFee, slowPriorityFee, 30000), web3.isTestnet); + const averageFee = enforceMinOneTip(getEIP1559GasFee(baseGasFee, averagePriorityFee, 45000), web3.isTestnet); + const fastFee = enforceMinOneTip(getEIP1559GasFee(baseGasFee, fastPriorityFee, 60000), web3.isTestnet); + + console.log('slowFee', web3.isTestnet, slowFee, averageFee, fastFee); + return { type: 'evm', gasPrice: undefined, baseGasFee: baseGasFee.toString(), busyNetwork, options: { - slow: getEIP1559GasFee(baseGasFee, slowPriorityFee, 30000), - average: getEIP1559GasFee(baseGasFee, averagePriorityFee, 45000), - fast: getEIP1559GasFee(baseGasFee, fastPriorityFee, 60000), + slow: slowFee, + average: averageFee, + fast: fastFee, default: busyNetwork ? 'average' : 'slow' } }; @@ -192,3 +199,13 @@ export const calculateGasFeeParams = async (web3: _EvmApi, networkKey: string, u }; } }; + +const enforceMinOneTip = (feeOptionDetail: EvmEIP1995FeeOptionDetail, isTestnet?: boolean): EvmEIP1995FeeOptionDetail => { + if (isTestnet && feeOptionDetail.maxPriorityFeePerGas === '0') { + feeOptionDetail.maxPriorityFeePerGas = EIP1559_MIN_PRIORITY_FEE; + + return feeOptionDetail; + } + + return feeOptionDetail; +}; From 0e2f2c565dc23644ba763d66417bc72398ce0ffd Mon Sep 17 00:00:00 2001 From: bluezdot <72647326+bluezdot@users.noreply.github.com> Date: Sat, 6 Jul 2024 11:49:19 +0700 Subject: [PATCH 6/6] remove log --- packages/extension-base/src/services/fee-service/utils/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/extension-base/src/services/fee-service/utils/index.ts b/packages/extension-base/src/services/fee-service/utils/index.ts index 4ce5e8ef314..fbf1a921781 100644 --- a/packages/extension-base/src/services/fee-service/utils/index.ts +++ b/packages/extension-base/src/services/fee-service/utils/index.ts @@ -172,8 +172,6 @@ export const calculateGasFeeParams = async (web3: _EvmApi, networkKey: string, u const averageFee = enforceMinOneTip(getEIP1559GasFee(baseGasFee, averagePriorityFee, 45000), web3.isTestnet); const fastFee = enforceMinOneTip(getEIP1559GasFee(baseGasFee, fastPriorityFee, 60000), web3.isTestnet); - console.log('slowFee', web3.isTestnet, slowFee, averageFee, fastFee); - return { type: 'evm', gasPrice: undefined,