refactor: add back eip1559
This commit is contained in:
parent
c0024ec6b1
commit
bfda545646
|
@ -136,7 +136,7 @@ proc newModule*[T](
|
|||
result.walletSectionModule = wallet_section_module.newModule[Module[T]](
|
||||
result, events, tokenService,
|
||||
transactionService, collectible_service, walletAccountService,
|
||||
settingsService, savedAddressService
|
||||
settingsService, savedAddressService, networkService,
|
||||
)
|
||||
result.browserSectionModule = browser_section_module.newModule(result, bookmarkService, settingsService,
|
||||
dappPermissionsService, providerService)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import ./controller_interface
|
||||
import ../../../../app_service/service/settings/service_interface as settings_service
|
||||
import ../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
import ../../../../app_service/service/network/service as network_service
|
||||
|
||||
export controller_interface
|
||||
|
||||
|
@ -9,16 +10,19 @@ type
|
|||
delegate: T
|
||||
settingsService: settings_service.ServiceInterface
|
||||
walletAccountService: wallet_account_service.ServiceInterface
|
||||
|
||||
networkService: network_service.ServiceInterface
|
||||
|
||||
proc newController*[T](
|
||||
delegate: T,
|
||||
settingsService: settings_service.ServiceInterface,
|
||||
walletAccountService: wallet_account_service.ServiceInterface,
|
||||
networkService: network_service.ServiceInterface,
|
||||
): Controller[T] =
|
||||
result = Controller[T]()
|
||||
result.delegate = delegate
|
||||
result.settingsService = settingsService
|
||||
result.walletAccountService = walletAccountService
|
||||
result.networkService = networkService
|
||||
|
||||
method delete*[T](self: Controller[T]) =
|
||||
discard
|
||||
|
@ -40,3 +44,6 @@ method getCurrencyBalance*[T](self: Controller[T]): float64 =
|
|||
|
||||
method updateCurrency*[T](self: Controller[T], currency: string) =
|
||||
self.walletAccountService.updateCurrency(currency)
|
||||
|
||||
method isEIP1559Enabled*[T](self: Controller[T]): bool =
|
||||
return self.networkService.isEIP1559Enabled()
|
|
@ -23,6 +23,8 @@ method getCurrencyBalance*(self: AccessInterface): float64 {.base.} =
|
|||
method updateCurrency*(self: AccessInterface, currency: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isEIP1559Enabled*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
|
|
|
@ -48,6 +48,9 @@ method transactionsModuleDidLoad*(self: AccessInterface) {.base.} =
|
|||
method savedAddressesModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isEIP1559Enabled*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
|
|
|
@ -19,6 +19,7 @@ import ../../../../app_service/service/collectible/service as collectible_servic
|
|||
import ../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
import ../../../../app_service/service/settings/service_interface as settings_service
|
||||
import ../../../../app_service/service/saved_address/service_interface as saved_address_service
|
||||
import ../../../../app_service/service/network/service_interface as network_service
|
||||
|
||||
import io_interface
|
||||
export io_interface
|
||||
|
@ -48,12 +49,13 @@ proc newModule*[T](
|
|||
walletAccountService: wallet_account_service.ServiceInterface,
|
||||
settingsService: settings_service.ServiceInterface,
|
||||
savedAddressService: saved_address_service.ServiceInterface,
|
||||
networkService: network_service.ServiceInterface,
|
||||
): Module[T] =
|
||||
result = Module[T]()
|
||||
result.delegate = delegate
|
||||
result.events = events
|
||||
result.moduleLoaded = false
|
||||
result.controller = newController(result, settingsService, walletAccountService)
|
||||
result.controller = newController(result, settingsService, walletAccountService, networkService)
|
||||
result.view = newView(result)
|
||||
|
||||
result.accountTokensModule = account_tokens_module.newModule(result, events, walletAccountService)
|
||||
|
@ -87,6 +89,9 @@ method switchAccount*[T](self: Module[T], accountIndex: int) =
|
|||
method setTotalCurrencyBalance*[T](self: Module[T]) =
|
||||
self.view.setTotalCurrencyBalance(self.controller.getCurrencyBalance())
|
||||
|
||||
method isEIP1559Enabled*[T](self: Module[T]): bool =
|
||||
return self.controller.isEIP1559Enabled()
|
||||
|
||||
method load*[T](self: Module[T]) =
|
||||
singletonInstance.engine.setRootContextProperty("walletSection", newQVariant(self.view))
|
||||
|
||||
|
@ -168,4 +173,4 @@ method transactionsModuleDidLoad*[T](self: Module[T]) =
|
|||
self.checkIfModuleDidLoad()
|
||||
|
||||
method savedAddressesModuleDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
self.checkIfModuleDidLoad()
|
|
@ -93,6 +93,14 @@ method transferEth*(self: Controller, from_addr: string, to_addr: string, value:
|
|||
|
||||
method transferTokens*(self: Controller, from_addr: string, to_addr: string, contractAddress: string,
|
||||
value: string, gas: string, gasPrice: string, maxPriorityFeePerGas: string,maxFeePerGas: string,
|
||||
password: string, uuid: string): bool =
|
||||
password: string, uuid: string
|
||||
): bool =
|
||||
result = self.transactionService.transferTokens(from_addr, to_addr, contractAddress, value, gas,
|
||||
gasPrice, maxPriorityFeePerGas, maxFeePerGas, password, uuid)
|
||||
|
||||
method baseFeePerGas*(self: Controller): string =
|
||||
return self.transactionService.baseFeePerGas()
|
||||
|
||||
method suggestedFees*(self: Controller): string =
|
||||
let suggestedFees = self.transactionService.suggestedFees()
|
||||
return suggestedFees.toJson()
|
|
@ -43,7 +43,14 @@ method transferEth*(self: AccessInterface, from_addr: string, to_addr: string, v
|
|||
method transferTokens*(self: AccessInterface, from_addr: string, to_addr: string,
|
||||
contractAddress: string, value: string, gas: string, gasPrice: string,
|
||||
maxPriorityFeePerGas: string, maxFeePerGas: string, password: string,
|
||||
uuid: string): bool {.base.} =
|
||||
uuid: string
|
||||
): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method baseFeePerGas*(self: AccessInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method suggestedFees*(self: AccessInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
type
|
||||
|
|
|
@ -57,6 +57,12 @@ method transferTokens*(self: AccessInterface, from_addr: string, to_addr: string
|
|||
method transactionWasSent*(self: AccessInterface, result: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method baseFeePerGas*(self: AccessInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method suggestedFees*(self: AccessInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
# View Delegate Interface
|
||||
# Delegate for the view must be declared here due to use of QtObject and multi
|
||||
# inheritance, which is not well supported in Nim.
|
||||
|
|
|
@ -103,3 +103,8 @@ method transferTokens*(self: Module, from_addr: string, to_addr: string, contrac
|
|||
method transactionWasSent*(self: Module, result: string) =
|
||||
self.view.transactionWasSent(result)
|
||||
|
||||
method baseFeePerGas*(self: Module): string =
|
||||
return self.controller.baseFeePerGas()
|
||||
|
||||
method suggestedFees*(self: Module): string =
|
||||
return self.controller.suggestedFees()
|
||||
|
|
|
@ -4,6 +4,7 @@ import ./item
|
|||
import ./model
|
||||
import ./io_interface
|
||||
|
||||
import ../../../../../app_service/common/conversion as common_conversion
|
||||
import ../../../../../app_service/service/wallet_account/dto
|
||||
|
||||
QtObject:
|
||||
|
@ -123,3 +124,10 @@ QtObject:
|
|||
maxFeePerGas: string, password: string, uuid: string): bool {.slot.} =
|
||||
result = self.delegate.transferTokens(from_addr, to_addr, contractAddress, value, gas, gasPrice,
|
||||
maxPriorityFeePerGas, maxFeePerGas, password, uuid)
|
||||
|
||||
proc latestBaseFeePerGas*(self: View): string {.slot.} =
|
||||
let baseFeeWei = self.delegate.baseFeePerGas()
|
||||
return common_conversion.wei2Gwei(baseFeeWei)
|
||||
|
||||
proc suggestedFees*(self: View): string {.slot.} =
|
||||
return self.delegate.suggestedFees()
|
|
@ -72,3 +72,6 @@ QtObject:
|
|||
self.signingPhrase = signingPhrase
|
||||
self.isMnemonicBackedUp = mnemonicBackedUp
|
||||
self.currentCurrencyChanged()
|
||||
|
||||
proc isEIP1559Enabled*(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.delegate.isEIP1559Enabled())
|
|
@ -296,7 +296,7 @@ QtObject:
|
|||
try:
|
||||
let
|
||||
chainId = self.settingsService.getCurrentNetworkId()
|
||||
eip1559Enabled = self.settingsService.isEIP1559Enabled()
|
||||
eip1559Enabled = self.networkService.isEIP1559Enabled()
|
||||
txData = ens_utils.buildTransaction(parseAddress(address), 0.u256, gas, gasPrice,
|
||||
eip1559Enabled, maxPriorityFeePerGas, maxFeePerGas)
|
||||
|
||||
|
@ -385,7 +385,7 @@ QtObject:
|
|||
networkType = self.settingsService.getCurrentNetwork().toNetworkType()
|
||||
network = self.networkService.getNetwork(networkType)
|
||||
chainId = network.chainId
|
||||
eip1559Enabled = self.settingsService.isEIP1559Enabled()
|
||||
eip1559Enabled = self.networkService.isEIP1559Enabled()
|
||||
txData = ens_utils.buildTransaction(parseAddress(address), 0.u256, gas, gasPrice,
|
||||
eip1559Enabled, maxPriorityFeePerGas, maxFeePerGas)
|
||||
|
||||
|
|
|
@ -146,6 +146,7 @@ proc validateTransactionInput*(from_addr, to_addr, assetAddress, value, gas, gas
|
|||
if not isAddress(to_addr): raise newException(ValueError, "to_addr is not a valid ETH address")
|
||||
if parseFloat(value) < 0: raise newException(ValueError, "value should be a number >= 0")
|
||||
if parseInt(gas) <= 0: raise newException(ValueError, "gas should be a number > 0")
|
||||
|
||||
if isEIP1599Enabled:
|
||||
if gasPrice != "" and (maxPriorityFeePerGas != "" or maxFeePerGas != ""):
|
||||
raise newException(ValueError, "gasPrice can't be used with maxPriorityFeePerGas and maxFeePerGas")
|
||||
|
|
|
@ -84,4 +84,15 @@ method toggleNetwork*(self: Service, chainId: int) =
|
|||
let network = self.getNetwork(chainId)
|
||||
|
||||
network.enabled = not network.enabled
|
||||
self.upsertNetwork(network)
|
||||
self.upsertNetwork(network)
|
||||
|
||||
method isEIP1559Enabled*(self: Service): bool =
|
||||
# TODO: Assume multi network is not enabled
|
||||
# TODO: add block number chain for other chains
|
||||
let network = self.getEnabledNetworks()[0]
|
||||
case network.chainId:
|
||||
of 3: return true
|
||||
of 4: return true
|
||||
of 5: return true
|
||||
of 1: return true
|
||||
else: return false
|
|
@ -31,4 +31,7 @@ method getNetwork*(self: ServiceInterface, chainId: int): NetworkDto {.base.} =
|
|||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method toggleNetwork*(self: ServiceInterface, chainId: int) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isEIP1559Enabled*(self: ServiceInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -393,23 +393,6 @@ method saveWalletVisibleTokens*(self: Service, visibleTokens: Table[int, seq[str
|
|||
|
||||
return false
|
||||
|
||||
method isEIP1559Enabled*(self: Service, blockNumber: int): bool =
|
||||
let networkId = self.getCurrentNetworkDetails().config.NetworkId
|
||||
let activationBlock = case networkId:
|
||||
of 3: 10499401 # Ropsten
|
||||
of 4: 8897988 # Rinkeby
|
||||
of 5: 5062605 # Goerli
|
||||
of 1: 12965000 # Mainnet
|
||||
else: -1
|
||||
if activationBlock > -1 and blockNumber >= activationBlock:
|
||||
result = true
|
||||
else:
|
||||
result = false
|
||||
self.eip1559Enabled = result
|
||||
|
||||
method isEIP1559Enabled*(self: Service): bool =
|
||||
result = self.eip1559Enabled
|
||||
|
||||
method getRecentStickers*(self: Service): seq[string] =
|
||||
result = self.settings.recentStickerHashes
|
||||
|
||||
|
|
|
@ -227,12 +227,6 @@ method getWalletVisibleTokens*(self: ServiceInterface): Table[int, seq[string]]
|
|||
method saveWalletVisibleTokens*(self: ServiceInterface, tokens: Table[int, seq[string]]): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isEIP1559Enabled*(self: ServiceInterface, blockNumber: int): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isEIP1559Enabled*(self: ServiceInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getRecentStickers*(self: ServiceInterface): seq[string] {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ QtObject:
|
|||
)
|
||||
|
||||
proc buy*(self: Service, packId: int, address: string, price: string, gas: string, gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string): tuple[response: string, success: bool] =
|
||||
let eip1559Enabled = self.settingsService.isEIP1559Enabled()
|
||||
let eip1559Enabled = self.networkService.isEIP1559Enabled()
|
||||
|
||||
try:
|
||||
status_utils.validateTransactionInput(address, address, "", price, gas, gasPrice, "", eip1559Enabled, maxPriorityFeePerGas, maxFeePerGas, "ok")
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import NimQml, chronicles, sequtils, sugar, stint, strutils, json, strformat
|
||||
import NimQml, chronicles, sequtils, sugar, stint, strutils, json, strformat, algorithm, math
|
||||
import ../../../backend/transactions as transactions
|
||||
import ../../../backend/wallet as status_wallet
|
||||
import ../../../backend/eth
|
||||
|
||||
import ../ens/utils as ens_utils
|
||||
from ../../common/account_constants import ZERO_ADDRESS
|
||||
import ../../common/conversion as common_conversion
|
||||
|
||||
import ../../../app/core/[main]
|
||||
import ../../../app/core/signals/types
|
||||
|
@ -48,6 +49,19 @@ type
|
|||
TransactionSentArgs* = ref object of Args
|
||||
result*: string
|
||||
|
||||
type SuggestedFees = object
|
||||
gasPrice: string
|
||||
baseFee: float
|
||||
maxPriorityFeePerGas: float
|
||||
maxFeePerGasL: float
|
||||
maxFeePerGasM: float
|
||||
maxFeePerGasH: float
|
||||
|
||||
proc cmpUint256(x, y: Uint256): int =
|
||||
if x > y: 1
|
||||
elif x == y: 0
|
||||
else: -1
|
||||
|
||||
QtObject:
|
||||
type Service* = ref object of QObject
|
||||
events: EventEmitter
|
||||
|
@ -57,6 +71,8 @@ QtObject:
|
|||
networkService: network_service.ServiceInterface
|
||||
settingsService: settings_service.ServiceInterface
|
||||
|
||||
baseFeePerGas: string
|
||||
|
||||
# Forward declaration
|
||||
proc checkPendingTransactions*(self: Service)
|
||||
proc checkPendingTransactions*(self: Service, address: string)
|
||||
|
@ -71,7 +87,7 @@ QtObject:
|
|||
ethService: eth_service.ServiceInterface,
|
||||
networkService: network_service.ServiceInterface,
|
||||
settingsService: settings_service.ServiceInterface
|
||||
): Service =
|
||||
): Service =
|
||||
new(result, delete)
|
||||
result.QObject.setup
|
||||
result.events = events
|
||||
|
@ -81,20 +97,25 @@ QtObject:
|
|||
result.networkService = networkService
|
||||
result.settingsService = settingsService
|
||||
|
||||
proc baseFeePerGas*(self: Service): string =
|
||||
return self.baseFeePerGas
|
||||
|
||||
proc setLatestBaseFeePerGas*(self: Service) =
|
||||
let response = eth.getBlockByNumber("latest")
|
||||
self.baseFeePerGas = $fromHex(Stuint[256], response.result{"baseFeePerGas"}.getStr)
|
||||
|
||||
proc doConnect*(self: Service) =
|
||||
self.events.on(SignalType.Wallet.event) do(e:Args):
|
||||
var data = WalletSignal(e)
|
||||
if(data.eventType == "newblock"):
|
||||
self.setLatestBaseFeePerGas()
|
||||
|
||||
for acc in data.accounts:
|
||||
self.checkPendingTransactions(acc)
|
||||
# TODO check if these need to be added back
|
||||
# self.status.wallet.updateAccount(acc)
|
||||
# discard self.status.wallet.isEIP1559Enabled(data.blockNumber)
|
||||
# self.status.wallet.setLatestBaseFee(data.baseFeePerGas)
|
||||
# self.view.updateView()
|
||||
|
||||
proc init*(self: Service) =
|
||||
self.doConnect()
|
||||
self.setLatestBaseFeePerGas()
|
||||
|
||||
proc checkRecentHistory*(self: Service) =
|
||||
try:
|
||||
|
@ -266,7 +287,7 @@ QtObject:
|
|||
uuid: string
|
||||
): bool {.slot.} =
|
||||
try:
|
||||
let eip1559Enabled = self.settingsService.isEIP1559Enabled()
|
||||
let eip1559Enabled = self.networkService.isEIP1559Enabled()
|
||||
eth_utils.validateTransactionInput(from_addr, to_addr, assetAddress = "", value, gas,
|
||||
gasPrice, data = "", eip1559Enabled, maxPriorityFeePerGas, maxFeePerGas, uuid)
|
||||
|
||||
|
@ -277,6 +298,7 @@ QtObject:
|
|||
|
||||
let json: JsonNode = %tx
|
||||
let response = eth.sendTransaction($json, password)
|
||||
|
||||
# only till it is moved to another thred
|
||||
# if response.error != nil:
|
||||
# raise newException(Exception, response.error.message)
|
||||
|
@ -305,7 +327,7 @@ QtObject:
|
|||
uuid: string
|
||||
): bool =
|
||||
try:
|
||||
let eip1559Enabled = self.settingsService.isEIP1559Enabled()
|
||||
let eip1559Enabled = self.networkService.isEIP1559Enabled()
|
||||
eth_utils.validateTransactionInput(from_addr, to_addr, assetAddress, value, gas,
|
||||
gasPrice, data = "", eip1559Enabled, maxPriorityFeePerGas, maxFeePerGas, uuid)
|
||||
|
||||
|
@ -332,3 +354,56 @@ QtObject:
|
|||
error "Error sending token transfer transaction", msg = e.msg
|
||||
return false
|
||||
return true
|
||||
|
||||
proc maxPriorityFeePerGas(self: Service): Uint256 =
|
||||
let response = eth.maxPriorityFeePerGas()
|
||||
return fromHex(Stuint[256], response.result.getStr)
|
||||
|
||||
proc getGasPrice(self: Service): Uint256 =
|
||||
let response = eth.getGasPrice()
|
||||
return fromHex(Stuint[256], response.result.getStr)
|
||||
|
||||
proc feeHistory(self: Service, n:int): seq[Uint256] =
|
||||
let response = eth.feeHistory(101)
|
||||
for it in response.result["baseFeePerGas"]:
|
||||
result.add(fromHex(Stuint[256], it.getStr))
|
||||
|
||||
result.sort(cmpUint256)
|
||||
|
||||
proc suggestedFees*(self: Service): SuggestedFees =
|
||||
#[
|
||||
0. priority tip always same, the value returned by eth_maxPriorityFeePerGas
|
||||
1. slow fee 10th percentile base fee (last 100 blocks) + eth_maxPriorityFeePerGas
|
||||
2. normal fee.
|
||||
if 20th_percentile <= current_base_fee <= 80th_percentile then fee = current_base_fee + eth_maxPriorityFeePerGas.
|
||||
if current_base_fee < 20th_percentile then fee = 20th_percentile + eth_maxPriorityFeePerGas
|
||||
if current_base_fee > 80th_percentile then fee = 80th_percentile + eth_maxPriorityFeePerGas
|
||||
The idea is to avoid setting too low base fee when price is in a dip and also to avoid overpaying on peak.
|
||||
Specific percentiles can be revisit later, it doesn't need to be symmetric because we are mostly interested in not getting stuck and overpaying might not be a huge issue here.
|
||||
3. fast fee: current_base_fee + eth_maxPriorityFeePerGas
|
||||
]#
|
||||
|
||||
let maxPriorityFeePerGas = self.maxPriorityFeePerGas()
|
||||
let feeHistory = self.feeHistory(101)
|
||||
let baseFee = self.baseFeePerGas.u256
|
||||
let gasPrice = self.getGasPrice()
|
||||
|
||||
let perc10 = feeHistory[ceil(10/100 * feeHistory.len.float).int - 1]
|
||||
let perc20 = feeHistory[ceil(20/100 * feeHistory.len.float).int - 1]
|
||||
let perc80 = feeHistory[ceil(80/100 * feeHistory.len.float).int - 1]
|
||||
|
||||
let maxFeePerGasM = if baseFee >= perc20 and baseFee <= perc80:
|
||||
baseFee + maxPriorityFeePerGas
|
||||
elif baseFee < perc20:
|
||||
perc20 + maxPriorityFeePerGas
|
||||
else:
|
||||
perc80 + maxPriorityFeePerGas
|
||||
|
||||
return SuggestedFees(
|
||||
gasPrice: $gasPrice,
|
||||
baseFee: parseFloat(common_conversion.wei2gwei($baseFee)),
|
||||
maxPriorityFeePerGas: parseFloat(common_conversion.wei2gwei($maxPriorityFeePerGas)),
|
||||
maxFeePerGasL: parseFloat(common_conversion.wei2gwei($(perc10 + maxPriorityFeePerGas))),
|
||||
maxFeePerGasM: parseFloat(common_conversion.wei2gwei($(maxFeePerGasM))),
|
||||
maxFeePerGasH: parseFloat(common_conversion.wei2gwei($(baseFee + maxPriorityFeePerGas)))
|
||||
)
|
||||
|
|
|
@ -29,3 +29,11 @@ proc getEthAccounts*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
|||
|
||||
proc getGasPrice*(payload = %* []): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
return core.callPrivateRPC("eth_gasPrice", payload)
|
||||
|
||||
proc maxPriorityFeePerGas*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* []
|
||||
return core.callPrivateRPC("eth_maxPriorityFeePerGas", payload)
|
||||
|
||||
proc feeHistory*(n: int): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [n, "latest", nil]
|
||||
return core.callPrivateRPC("eth_feeHistory", payload)
|
|
@ -22,4 +22,8 @@ QtObject {
|
|||
// walletModel.gasView.getGasPrice()
|
||||
}
|
||||
|
||||
function isEIP1559Enabled() {
|
||||
return walletSection.isEIP1559Enabled()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ QtObject {
|
|||
// TODO: use bignumber instead of floats
|
||||
trx.value = RootStore.getEth2Hex(parseFloat(value))
|
||||
trx.gas = "0x" + parseInt(selectedGasLimit, 10).toString(16)
|
||||
if (walletModel.transactionsView.isEIP1559Enabled) {
|
||||
if (WalletStore.isEIP1559Enabled()) {
|
||||
trx.maxPriorityFeePerGas = RootStore.getGwei2Hex(parseFloat(selectedTipLimit))
|
||||
trx.maxFeePerGas = RootStore.getGwei2Hex(parseFloat(selectedOverallLimit))
|
||||
} else {
|
||||
|
|
|
@ -91,4 +91,16 @@ QtObject {
|
|||
return walletSectionTransactions.transferTokens(from, to, address, amount, gasLimit,
|
||||
gasPrice, tipLimit, overallLimit, password, uuid);
|
||||
}
|
||||
|
||||
function isEIP1559Enabled() {
|
||||
return walletSection.isEIP1559Enabled()
|
||||
}
|
||||
|
||||
function latestBaseFeePerGas() {
|
||||
return walletSectionTransactions.latestBaseFeePerGas()
|
||||
}
|
||||
|
||||
function suggestedFees() {
|
||||
return JSON.parse(walletSectionTransactions.suggestedFees())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,14 +17,16 @@ Item {
|
|||
property double gasPrice: 0
|
||||
|
||||
|
||||
// Not Refactored Yet
|
||||
property bool eip1599Enabled: false //walletModel.transactionsView.isEIP1559Enabled
|
||||
property var suggestedFees: "" //JSON.parse(walletModel.gasView.suggestedFees)
|
||||
property var latestBaseFee: "" //JSON.parse(walletModel.transactionsView.latestBaseFee)
|
||||
property bool isEIP1559Enabled: true
|
||||
property var latestBaseFeePerGas: ""
|
||||
|
||||
property double latestBaseFeeGwei: {
|
||||
if (!eip1599Enabled) return 0;
|
||||
return parseFloat(latestBaseFee.gwei)
|
||||
// Not Refactored Yet
|
||||
property var suggestedFees: ""
|
||||
|
||||
property double latestBaseFeePerGasGwei: {
|
||||
if (!isEIP1559Enabled) return 0;
|
||||
|
||||
return parseFloat(latestBaseFeePerGas)
|
||||
}
|
||||
|
||||
property var getGasGweiValue: function () {}
|
||||
|
@ -83,7 +85,7 @@ Item {
|
|||
|
||||
|
||||
function checkLimits(){
|
||||
if(!eip1599Enabled) return;
|
||||
if(!isEIP1559Enabled) return;
|
||||
|
||||
let inputTipLimit = parseFloat(inputPerGasTipLimit.text || "0.00")
|
||||
let inputOverallLimit = parseFloat(inputGasPrice.text || "0.00")
|
||||
|
@ -110,15 +112,15 @@ Item {
|
|||
}
|
||||
|
||||
// Per-gas overall limit rules
|
||||
if(inputOverallLimit < latestBaseFeeGwei){
|
||||
errorMsg = appendError(errorMsg, qsTr("The limit is below the current base fee of %1 %2").arg(latestBaseFeeGwei).arg("Gwei"))
|
||||
if(inputOverallLimit < latestBaseFeePerGasGwei){
|
||||
errorMsg = appendError(errorMsg, qsTr("The limit is below the current base fee of %1 %2").arg(latestBaseFeePerGasGwei).arg("Gwei"))
|
||||
showPriceLimitWarning = true
|
||||
}
|
||||
|
||||
/* TODO: change these values false once EIP1559 suggestions are revised
|
||||
else if((inputOverallLimit - inputTipLimit) < latestBaseFeeGwei){
|
||||
else if((inputOverallLimit - inputTipLimit) < latestBaseFeePerGasGwei){
|
||||
errorMsg = appendError(errorMsg, qsTr("The limit should be at least %1 Gwei above the base fee").arg(perGasTipLimitFloor))
|
||||
} else if((inputOverallLimit - perGasTipLimitAverage) < latestBaseFeeGwei) {
|
||||
} else if((inputOverallLimit - perGasTipLimitAverage) < latestBaseFeePerGasGwei) {
|
||||
errorMsg = appendError(errorMsg, qsTr("The maximum miner tip after the current base fee will be %1 Gwei, the minimum miner tip is currently %2 Gwei").arg(inputOverallLimit).arg(perGasTipLimitFloor), true)
|
||||
showTipLimitWarning = true
|
||||
}*/
|
||||
|
@ -201,11 +203,11 @@ Item {
|
|||
|
||||
StyledText {
|
||||
id: baseFeeText
|
||||
visible: eip1599Enabled && advancedMode
|
||||
visible: isEIP1559Enabled && advancedMode
|
||||
anchors.top: parent.top
|
||||
anchors.left: prioritytext.right
|
||||
anchors.leftMargin: Style.current.smallPadding
|
||||
text: qsTr("Current base fee: %1 %2").arg(latestBaseFeeGwei).arg("Gwei")
|
||||
text: qsTr("Current base fee: %1 %2").arg(latestBaseFeePerGasGwei).arg("Gwei")
|
||||
font.weight: Font.Medium
|
||||
font.pixelSize: 13
|
||||
color: Style.current.secondaryText
|
||||
|
@ -241,7 +243,7 @@ Item {
|
|||
buttonGroup: gasGroup
|
||||
text: qsTr("Low")
|
||||
price: {
|
||||
if (!eip1599Enabled) return gasPrice;
|
||||
if (!isEIP1559Enabled) return gasPrice;
|
||||
return formatDec(suggestedFees.maxFeePerGasL, 6)
|
||||
}
|
||||
gasLimit: inputGasLimit ? inputGasLimit.text : ""
|
||||
|
@ -249,7 +251,7 @@ Item {
|
|||
getFiatValue: root.getFiatValue
|
||||
defaultCurrency: root.defaultCurrency
|
||||
onChecked: {
|
||||
if (eip1599Enabled){
|
||||
if (isEIP1559Enabled){
|
||||
inputPerGasTipLimit.text = formatDec(suggestedFees.maxPriorityFeePerGas, 2);
|
||||
inputGasPrice.text = formatDec(suggestedFees.maxFeePerGasL, 2);
|
||||
} else {
|
||||
|
@ -266,7 +268,7 @@ Item {
|
|||
//% "Optimal"
|
||||
text: qsTrId("optimal")
|
||||
price: {
|
||||
if (!eip1599Enabled) {
|
||||
if (!isEIP1559Enabled) {
|
||||
// Setting the gas price field here because the binding didn't work
|
||||
inputGasPrice.text = root.gasPrice
|
||||
return root.gasPrice
|
||||
|
@ -279,7 +281,7 @@ Item {
|
|||
getFiatValue: root.getFiatValue
|
||||
defaultCurrency: root.defaultCurrency
|
||||
onChecked: {
|
||||
if (eip1599Enabled){
|
||||
if (isEIP1559Enabled){
|
||||
inputPerGasTipLimit.text = formatDec(suggestedFees.maxPriorityFeePerGas, 2);
|
||||
inputGasPrice.text = formatDec(suggestedFees.maxFeePerGasM, 2);
|
||||
} else {
|
||||
|
@ -294,7 +296,7 @@ Item {
|
|||
buttonGroup: gasGroup
|
||||
text: qsTr("High")
|
||||
price: {
|
||||
if (!eip1599Enabled) return gasPrice;
|
||||
if (!isEIP1559Enabled) return gasPrice;
|
||||
return formatDec(suggestedFees.maxFeePerGasH,6);
|
||||
}
|
||||
gasLimit: inputGasLimit ? inputGasLimit.text : ""
|
||||
|
@ -302,7 +304,7 @@ Item {
|
|||
getFiatValue: root.getFiatValue
|
||||
defaultCurrency: root.defaultCurrency
|
||||
onChecked: {
|
||||
if (eip1599Enabled){
|
||||
if (isEIP1559Enabled){
|
||||
inputPerGasTipLimit.text = formatDec(suggestedFees.maxPriorityFeePerGas, 2);
|
||||
inputGasPrice.text = formatDec(suggestedFees.maxFeePerGasH, 2);
|
||||
} else {
|
||||
|
@ -331,7 +333,7 @@ Item {
|
|||
customHeight: 56
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: eip1599Enabled ? inputPerGasTipLimit.left : inputGasPrice.left
|
||||
anchors.right: isEIP1559Enabled ? inputPerGasTipLimit.left : inputGasPrice.left
|
||||
anchors.rightMargin: Style.current.padding
|
||||
placeholderText: "21000"
|
||||
validator: IntValidator{
|
||||
|
@ -355,7 +357,7 @@ Item {
|
|||
anchors.right: inputGasPrice.left
|
||||
anchors.rightMargin: Style.current.padding
|
||||
anchors.left: undefined
|
||||
visible: eip1599Enabled
|
||||
visible: isEIP1559Enabled
|
||||
width: 125
|
||||
customHeight: 56
|
||||
text: formatDec(suggestedFees.maxPriorityFeePerGas, 2);
|
||||
|
@ -372,7 +374,7 @@ Item {
|
|||
color: Style.current.secondaryText
|
||||
//% "Gwei"
|
||||
text: qsTrId("gwei")
|
||||
visible: eip1599Enabled
|
||||
visible: isEIP1559Enabled
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 42
|
||||
anchors.right: inputPerGasTipLimit.right
|
||||
|
|
|
@ -45,7 +45,7 @@ ModalPopup {
|
|||
selectRecipient.selectedRecipient.address,
|
||||
txtAmount.selectedAmount,
|
||||
gasSelector.selectedGasLimit,
|
||||
gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.isEIP1559Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.selectedTipLimit,
|
||||
gasSelector.selectedOverallLimit,
|
||||
transactionSigner.enteredPassword,
|
||||
|
@ -57,7 +57,7 @@ ModalPopup {
|
|||
txtAmount.selectedAsset.address,
|
||||
txtAmount.selectedAmount,
|
||||
gasSelector.selectedGasLimit,
|
||||
gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.isEIP1559Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.selectedTipLimit,
|
||||
gasSelector.selectedOverallLimit,
|
||||
transactionSigner.enteredPassword,
|
||||
|
@ -147,6 +147,9 @@ ModalPopup {
|
|||
getGasEthValue: root.store.getGasEthValue
|
||||
getFiatValue: root.store.getFiatValue
|
||||
defaultCurrency: root.store.currentCurrency
|
||||
isEIP1559Enabled: root.store.isEIP1559Enabled()
|
||||
latestBaseFeePerGas: root.store.latestBaseFeePerGas()
|
||||
suggestedFees: root.store.suggestedFees()
|
||||
|
||||
width: stack.width
|
||||
property var estimateGas: Backpressure.debounce(gasSelector, 600, function() {
|
||||
|
@ -265,16 +268,16 @@ ModalPopup {
|
|||
return root.sendTransaction()
|
||||
}
|
||||
|
||||
if(gasSelector.eip1599Enabled && stack.currentGroup === group2 && gasSelector.advancedMode){
|
||||
if(gasSelector.isEIP1559Enabled && stack.currentGroup === group2 && gasSelector.advancedMode){
|
||||
if(gasSelector.showPriceLimitWarning || gasSelector.showTipLimitWarning){
|
||||
Global.openPopup(transactionSettingsConfirmationPopupComponent, {
|
||||
currentBaseFee: gasSelector.latestBaseFeeGwei,
|
||||
currentBaseFee: gasSelector.latestBaseFeePerGasGwei,
|
||||
currentMinimumTip: gasSelector.perGasTipLimitFloor,
|
||||
currentAverageTip: gasSelector.perGasTipLimitAverage,
|
||||
tipLimit: gasSelector.selectedTipLimit,
|
||||
suggestedTipLimit: gasSelector.perGasTipLimitFloor,
|
||||
priceLimit: gasSelector.selectedOverallLimit,
|
||||
suggestedPriceLimit: gasSelector.latestBaseFeeGwei + gasSelector.perGasTipLimitFloor,
|
||||
suggestedPriceLimit: gasSelector.latestBaseFeePerGasGwei + gasSelector.perGasTipLimitFloor,
|
||||
showPriceLimitWarning: gasSelector.showPriceLimitWarning,
|
||||
showTipLimitWarning: gasSelector.showTipLimitWarning,
|
||||
onConfirm: function(){
|
||||
|
|
|
@ -45,7 +45,7 @@ StatusModal {
|
|||
selectRecipient.selectedRecipient.address,
|
||||
root.selectedAmount,
|
||||
gasSelector.selectedGasLimit,
|
||||
gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.isEIP1559Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.selectedTipLimit,
|
||||
gasSelector.selectedOverallLimit,
|
||||
transactionSigner.enteredPassword,
|
||||
|
@ -57,7 +57,7 @@ StatusModal {
|
|||
root.selectedAsset.address,
|
||||
root.selectedAmount,
|
||||
gasSelector.selectedGasLimit,
|
||||
gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.isEIP1559Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.selectedTipLimit,
|
||||
gasSelector.selectedOverallLimit,
|
||||
transactionSigner.enteredPassword,
|
||||
|
@ -156,6 +156,9 @@ StatusModal {
|
|||
getGasEthValue: root.store.getGasEthValue
|
||||
getFiatValue: root.store.getFiatValue
|
||||
defaultCurrency: root.store.currentCurrency
|
||||
isEIP1559Enabled: root.store.isEIP1559Enabled()
|
||||
latestBaseFeePerGas: root.store.latestBaseFeePerGas()
|
||||
suggestedFees: root.store.suggestedFees()
|
||||
width: stack.width
|
||||
|
||||
property var estimateGas: Backpressure.debounce(gasSelector, 600, function() {
|
||||
|
@ -295,22 +298,22 @@ StatusModal {
|
|||
if (validity.isValid && !validity.isPending) {
|
||||
if (stack.isLastGroup) {
|
||||
return root.sendTransaction(gasSelector.selectedGasLimit,
|
||||
gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.isEIP1559Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.selectedTipLimit,
|
||||
gasSelector.selectedOverallLimit,
|
||||
transactionSigner.enteredPassword)
|
||||
}
|
||||
|
||||
if(gasSelector.eip1599Enabled && stack.currentGroup === groupSelectGas && gasSelector.advancedMode){
|
||||
if(gasSelector.isEIP1559Enabled && stack.currentGroup === groupSelectGas && gasSelector.advancedMode){
|
||||
if(gasSelector.showPriceLimitWarning || gasSelector.showTipLimitWarning){
|
||||
Global.openPopup(transactionSettingsConfirmationPopupComponent, {
|
||||
currentBaseFee: gasSelector.latestBaseFeeGwei,
|
||||
currentBaseFee: gasSelector.latestBaseFeePerGasGwei,
|
||||
currentMinimumTip: gasSelector.perGasTipLimitFloor,
|
||||
currentAverageTip: gasSelector.perGasTipLimitAverage,
|
||||
tipLimit: gasSelector.selectedTipLimit,
|
||||
suggestedTipLimit: gasSelector.perGasTipLimitFloor, // TODO:
|
||||
priceLimit: gasSelector.selectedOverallLimit,
|
||||
suggestedPriceLimit: gasSelector.latestBaseFeeGwei + gasSelector.perGasTipLimitFloor,
|
||||
suggestedPriceLimit: gasSelector.latestBaseFeePerGasGwei + gasSelector.perGasTipLimitFloor,
|
||||
showPriceLimitWarning: gasSelector.showPriceLimitWarning,
|
||||
showTipLimitWarning: gasSelector.showTipLimitWarning,
|
||||
onConfirm: function(){
|
||||
|
|
|
@ -35,7 +35,7 @@ ModalPopup {
|
|||
let responseStr = root.ensUsernamesStore.setPubKey(root.ensUsername,
|
||||
selectFromAccount.selectedAccount.address,
|
||||
gasSelector.selectedGasLimit,
|
||||
gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.isEIP1559Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.selectedTipLimit,
|
||||
gasSelector.selectedOverallLimit,
|
||||
transactionSigner.enteredPassword)
|
||||
|
@ -120,7 +120,10 @@ ModalPopup {
|
|||
getGasEthValue: root.ensUsernamesStore.getGasEthValue
|
||||
getFiatValue: root.ensUsernamesStore.getFiatValue
|
||||
defaultCurrency: root.ensUsernamesStore.getCurrentCurrency()
|
||||
|
||||
isEIP1559Enabled: root.store.isEIP1559Enabled()
|
||||
latestBaseFeePerGas: root.store.latestBaseFeePerGas()
|
||||
suggestedFees: root.store.suggestedFees()
|
||||
|
||||
property var estimateGas: Backpressure.debounce(gasSelector, 600, function() {
|
||||
let estimatedGas = root.estimateGasFunction(selectFromAccount.selectedAccount);
|
||||
gasSelector.selectedGasLimit = estimatedGas
|
||||
|
@ -215,16 +218,16 @@ ModalPopup {
|
|||
return root.sendTransaction()
|
||||
}
|
||||
|
||||
if(gasSelector.eip1599Enabled && stack.currentGroup === group2 && gasSelector.advancedMode){
|
||||
if(gasSelector.isEIP1559Enabled && stack.currentGroup === group2 && gasSelector.advancedMode){
|
||||
if(gasSelector.showPriceLimitWarning || gasSelector.showTipLimitWarning){
|
||||
Global.openPopup(transactionSettingsConfirmationPopupComponent, {
|
||||
currentBaseFee: gasSelector.latestBaseFeeGwei,
|
||||
currentBaseFee: gasSelector.latestBaseFeePerGasGwei,
|
||||
currentMinimumTip: gasSelector.perGasTipLimitFloor,
|
||||
currentAverageTip: gasSelector.perGasTipLimitAverage,
|
||||
tipLimit: gasSelector.selectedTipLimit,
|
||||
suggestedTipLimit: gasSelector.perGasTipLimitFloor,
|
||||
priceLimit: gasSelector.selectedOverallLimit,
|
||||
suggestedPriceLimit: gasSelector.latestBaseFeeGwei + gasSelector.perGasTipLimitFloor,
|
||||
suggestedPriceLimit: gasSelector.latestBaseFeePerGasGwei + gasSelector.perGasTipLimitFloor,
|
||||
showPriceLimitWarning: gasSelector.showPriceLimitWarning,
|
||||
showTipLimitWarning: gasSelector.showTipLimitWarning,
|
||||
onConfirm: function(){
|
||||
|
|
|
@ -52,7 +52,7 @@ ModalPopup {
|
|||
function sendTransaction() {
|
||||
let responseStr = onSendTransaction(selectFromAccount.selectedAccount.address,
|
||||
gasSelector.selectedGasLimit,
|
||||
gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.isEIP1559Enabled ? "" : gasSelector.selectedGasPrice,
|
||||
gasSelector.selectedTipLimit,
|
||||
gasSelector.selectedOverallLimit,
|
||||
transactionSigner.enteredPassword);
|
||||
|
@ -127,6 +127,9 @@ ModalPopup {
|
|||
getGasEthValue: root.store.getGasEthValue
|
||||
getFiatValue: root.store.getFiatValue
|
||||
defaultCurrency: root.store.getCurrentCurrency()
|
||||
isEIP1559Enabled: root.store.isEIP1559Enabled()
|
||||
latestBaseFeePerGas: root.store.latestBaseFeePerGas()
|
||||
suggestedFees: root.store.suggestedFees()
|
||||
width: stack.width
|
||||
|
||||
property var estimateGas: Backpressure.debounce(gasSelector, 600, function() {
|
||||
|
@ -228,16 +231,16 @@ ModalPopup {
|
|||
return root.sendTransaction()
|
||||
}
|
||||
|
||||
if(gasSelector.eip1599Enabled && stack.currentGroup === group2 && gasSelector.advancedMode){
|
||||
if(gasSelector.isEIP1559Enabled && stack.currentGroup === group2 && gasSelector.advancedMode){
|
||||
if(gasSelector.showPriceLimitWarning || gasSelector.showTipLimitWarning){
|
||||
Global.openPopup(transactionSettingsConfirmationPopupComponent, {
|
||||
currentBaseFee: gasSelector.latestBaseFeeGwei,
|
||||
currentBaseFee: gasSelector.latestBaseFeePerGasGwei,
|
||||
currentMinimumTip: gasSelector.perGasTipLimitFloor,
|
||||
currentAverageTip: gasSelector.perGasTipLimitAverage,
|
||||
tipLimit: gasSelector.selectedTipLimit,
|
||||
suggestedTipLimit: gasSelector.perGasTipLimitFloor, // TODO:
|
||||
priceLimit: gasSelector.selectedOverallLimit,
|
||||
suggestedPriceLimit: gasSelector.latestBaseFeeGwei + gasSelector.perGasTipLimitFloor,
|
||||
suggestedPriceLimit: gasSelector.latestBaseFeePerGasGwei + gasSelector.perGasTipLimitFloor,
|
||||
showPriceLimitWarning: gasSelector.showPriceLimitWarning,
|
||||
showTipLimitWarning: gasSelector.showTipLimitWarning,
|
||||
onConfirm: function(){
|
||||
|
|
Loading…
Reference in New Issue