import type { EthereumTransactionData, Network } from 'bnc-sdk' import { BigNumber } from 'ethers' import { configuration } from './configuration.js' import { state } from './store/index.js' import type { WalletState } from './types.js' import { gweiToWeiHex, networkToChainId, toHexString } from './utils.js' const ACTIONABLE_EVENT_CODES: string[] = ['txPool'] const VALID_GAS_NETWORKS: Network[] = ['main', 'matic-main'] const WALLETS_SUPPORT_REPLACEMENT: WalletState['label'][] = [ 'Ledger', 'Trezor', 'Keystone', 'KeepKey', `D'CENT` ] export const actionableEventCode = (eventCode: string): boolean => ACTIONABLE_EVENT_CODES.includes(eventCode) export const validGasNetwork = (network: Network): boolean => VALID_GAS_NETWORKS.includes(network) export const walletSupportsReplacement = (wallet: WalletState): boolean => wallet && WALLETS_SUPPORT_REPLACEMENT.includes(wallet.label) export async function replaceTransaction({ type, wallet, transaction }: { type: 'speedup' | 'cancel' wallet: WalletState transaction: EthereumTransactionData }): Promise { const { from, input, value, to, nonce, gas: gasLimit, network } = transaction const chainId = networkToChainId[network] const { gasPriceProbability } = state.get().notify.replacement const { gas, apiKey } = configuration // get gas price const [gasResult] = await gas.get({ chains: [networkToChainId[network]], endpoint: 'blockPrices', apiKey }) const { maxFeePerGas, maxPriorityFeePerGas } = gasResult.blockPrices[0].estimatedPrices.find( ({ confidence }) => confidence === (type === 'speedup' ? gasPriceProbability.speedup : gasPriceProbability.cancel) ) const maxFeePerGasWeiHex = gweiToWeiHex(maxFeePerGas) const maxPriorityFeePerGasWeiHex = gweiToWeiHex(maxPriorityFeePerGas) // Some wallets do not like empty '0x' val const dataObj = input === '0x' ? {} : { data: input } return wallet.provider.request({ method: 'eth_sendTransaction', params: [ { type: '0x2', from, to: type === 'cancel' ? from : to, chainId: parseInt(chainId), value: `${BigNumber.from(value).toHexString()}`, nonce: toHexString(nonce), gasLimit: toHexString(gasLimit), maxFeePerGas: maxFeePerGasWeiHex, maxPriorityFeePerGas: maxPriorityFeePerGasWeiHex, ...dataObj } ] }) }