feat(dapps) check max fees against balance
Also differentiate between l1 and l2 fees and check them against the specific chain balance Also - Included tests for the new functionality - Fixed some inconsistencies in handling types Updates: #15552
This commit is contained in:
parent
8db0ac94f0
commit
36e3a7cbb5
|
@ -26,6 +26,7 @@ import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
import AppLayouts.Wallet.panels 1.0
|
import AppLayouts.Wallet.panels 1.0
|
||||||
import AppLayouts.Profile.stores 1.0
|
import AppLayouts.Profile.stores 1.0
|
||||||
|
import AppLayouts.Wallet.stores 1.0 as WalletStore
|
||||||
|
|
||||||
import mainui 1.0
|
import mainui 1.0
|
||||||
import shared.stores 1.0
|
import shared.stores 1.0
|
||||||
|
@ -378,6 +379,19 @@ Item {
|
||||||
return Constants.TransactionEstimatedTime.LessThanThreeMins
|
return Constants.TransactionEstimatedTime.LessThanThreeMins
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSuggestedFees() {
|
||||||
|
return {
|
||||||
|
gasPrice: 2.0,
|
||||||
|
baseFee: 5.0,
|
||||||
|
maxPriorityFeePerGas: 2.0,
|
||||||
|
maxFeePerGasL: 1.0,
|
||||||
|
maxFeePerGasM: 1.1,
|
||||||
|
maxFeePerGasH: 1.2,
|
||||||
|
l1GasFee: 4.0,
|
||||||
|
eip1559Enabled: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function hexToDec(hex) {
|
function hexToDec(hex) {
|
||||||
if (hex.length > "0xfffffffffffff".length) {
|
if (hex.length > "0xfffffffffffff".length) {
|
||||||
console.warn(`Beware of possible loss of precision converting ${hex}`)
|
console.warn(`Beware of possible loss of precision converting ${hex}`)
|
||||||
|
@ -398,6 +412,12 @@ Item {
|
||||||
return "eth:oeth:arb"
|
return "eth:oeth:arb"
|
||||||
}
|
}
|
||||||
readonly property CurrenciesStore currencyStore: CurrenciesStore {}
|
readonly property CurrenciesStore currencyStore: CurrenciesStore {}
|
||||||
|
readonly property WalletStore.WalletAssetsStore walletAssetsStore: WalletStore.WalletAssetsStore {
|
||||||
|
// Silence warnings
|
||||||
|
assetsWithFilteredBalances: ListModel {}
|
||||||
|
// Name mismatch between storybook and production
|
||||||
|
readonly property var groupedAccountAssetsModel: groupedAccountsAssetsModel
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onDisplayToastMessage: (message, isErr) => {
|
onDisplayToastMessage: (message, isErr) => {
|
||||||
|
|
|
@ -155,7 +155,7 @@ function formatApproveSessionResponse(networksArray, accountsArray, custom) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatSessionRequest(chainId, method, params, topic) {
|
function formatSessionRequest(chainId, method, params, topic) {
|
||||||
let paramsStr = params.map(param => `"${param}"`).join(',')
|
let paramsStr = params.map(param => `${param}`).join(',')
|
||||||
return `{
|
return `{
|
||||||
"id": 1717149885151715,
|
"id": 1717149885151715,
|
||||||
"params": {
|
"params": {
|
||||||
|
|
|
@ -14,6 +14,7 @@ import AppLayouts.Wallet.services.dapps 1.0
|
||||||
import AppLayouts.Wallet.services.dapps.types 1.0
|
import AppLayouts.Wallet.services.dapps.types 1.0
|
||||||
import AppLayouts.Profile.stores 1.0
|
import AppLayouts.Profile.stores 1.0
|
||||||
import AppLayouts.Wallet.panels 1.0
|
import AppLayouts.Wallet.panels 1.0
|
||||||
|
import AppLayouts.Wallet.stores 1.0 as WalletStore
|
||||||
|
|
||||||
import shared.stores 1.0
|
import shared.stores 1.0
|
||||||
|
|
||||||
|
@ -82,7 +83,6 @@ Item {
|
||||||
Component {
|
Component {
|
||||||
id: dappsStoreComponent
|
id: dappsStoreComponent
|
||||||
|
|
||||||
|
|
||||||
DAppsStore {
|
DAppsStore {
|
||||||
property string dappsListReceivedJsonStr: '[]'
|
property string dappsListReceivedJsonStr: '[]'
|
||||||
|
|
||||||
|
@ -119,6 +119,24 @@ Item {
|
||||||
function updateWalletConnectSessions(activeTopicsJson) {
|
function updateWalletConnectSessions(activeTopicsJson) {
|
||||||
updateWalletConnectSessionsCalls.push({activeTopicsJson})
|
updateWalletConnectSessionsCalls.push({activeTopicsJson})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getEstimatedTime(chainId, maxFeePerGas) {
|
||||||
|
return Constants.TransactionEstimatedTime.LessThanThreeMins
|
||||||
|
}
|
||||||
|
|
||||||
|
property var mockedSuggestedFees: ({
|
||||||
|
gasPrice: 2.0,
|
||||||
|
baseFee: 5.0,
|
||||||
|
maxPriorityFeePerGas: 2.0,
|
||||||
|
maxFeePerGasL: 1.0,
|
||||||
|
maxFeePerGasM: 1.1,
|
||||||
|
maxFeePerGasH: 1.2,
|
||||||
|
l1GasFee: 0.0,
|
||||||
|
eip1559Enabled: true
|
||||||
|
})
|
||||||
|
function getSuggestedFees() {
|
||||||
|
return mockedSuggestedFees
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,11 +145,25 @@ Item {
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
readonly property ListModel filteredFlatModel: ListModel {
|
readonly property ListModel filteredFlatModel: ListModel {
|
||||||
ListElement { chainId: 1 }
|
ListElement {
|
||||||
|
chainId: 1
|
||||||
|
layer: 1
|
||||||
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
chainId: 2
|
chainId: 2
|
||||||
chainName: "Test Chain"
|
chainName: "Test Chain"
|
||||||
iconUrl: "network/Network=Ethereum"
|
iconUrl: "network/Network=Ethereum"
|
||||||
|
layer: 2
|
||||||
|
}
|
||||||
|
// Used by tst_balanceCheck
|
||||||
|
ListElement {
|
||||||
|
chainId: 11155111
|
||||||
|
layer: 1
|
||||||
|
}
|
||||||
|
// Used by tst_balanceCheck
|
||||||
|
ListElement {
|
||||||
|
chainId: 421613
|
||||||
|
layer: 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,24 +176,45 @@ Item {
|
||||||
color: "#2A4AF5"
|
color: "#2A4AF5"
|
||||||
}
|
}
|
||||||
ListElement { address: "0x3a" }
|
ListElement { address: "0x3a" }
|
||||||
|
// Account from GroupedAccountsAssetsModel
|
||||||
|
ListElement { address: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240" }
|
||||||
}
|
}
|
||||||
function getNetworkShortNames(chainIds) {
|
function getNetworkShortNames(chainIds) {
|
||||||
return "eth:oeth:arb"
|
return "eth:oeth:arb"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly property var currencyStore: CurrenciesStore {}
|
||||||
|
readonly property var walletAssetsStore: assetsStoreMock
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WalletStore.WalletAssetsStore {
|
||||||
|
id: assetsStoreMock
|
||||||
|
// Silence warnings
|
||||||
|
assetsWithFilteredBalances: ListModel {}
|
||||||
|
|
||||||
|
readonly property var groupedAccountAssetsModel: groupedAccountsAssetsModel
|
||||||
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: dappsRequestHandlerComponent
|
id: dappsRequestHandlerComponent
|
||||||
|
|
||||||
DAppsRequestHandler {
|
DAppsRequestHandler {
|
||||||
currenciesStore: CurrenciesStore {}
|
currenciesStore: CurrenciesStore {}
|
||||||
|
assetsStore: assetsStoreMock
|
||||||
|
|
||||||
|
property var maxFeesUpdatedCalls: []
|
||||||
|
onMaxFeesUpdated: function(fiatMaxFees, ethMaxFees, haveEnoughFunds, haveEnoughForFees, symbol, feesInfo) {
|
||||||
|
maxFeesUpdatedCalls.push({fiatMaxFees, ethMaxFees, haveEnoughFunds, haveEnoughForFees, symbol, feesInfo})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TestCase {
|
TestCase {
|
||||||
id: requestHandlerTest
|
id: requestHandlerTest
|
||||||
name: "DAppsRequestHandler"
|
name: "DAppsRequestHandler"
|
||||||
|
// Ensure mocked GroupedAccountsAssetsModel is properly initialized
|
||||||
|
when: windowShown
|
||||||
|
|
||||||
property DAppsRequestHandler handler: null
|
property DAppsRequestHandler handler: null
|
||||||
|
|
||||||
|
@ -209,7 +262,7 @@ Item {
|
||||||
let chainId = 2
|
let chainId = 2
|
||||||
let method = "personal_sign"
|
let method = "personal_sign"
|
||||||
let message = "hello world"
|
let message = "hello world"
|
||||||
let params = [Helpers.strToHex(message), testAddressUpper]
|
let params = [`"${Helpers.strToHex(message)}"`, `"${testAddressUpper}"`]
|
||||||
let topic = "b536a"
|
let topic = "b536a"
|
||||||
let session = JSON.parse(Testing.formatSessionRequest(chainId, method, params, topic))
|
let session = JSON.parse(Testing.formatSessionRequest(chainId, method, params, topic))
|
||||||
// Expect to have calls to getActiveSessions from service initialization
|
// Expect to have calls to getActiveSessions from service initialization
|
||||||
|
@ -218,6 +271,89 @@ Item {
|
||||||
|
|
||||||
compare(sdk.getActiveSessionsCallbacks.length, 1, "expected DAppsRequestHandler call sdk.getActiveSessions")
|
compare(sdk.getActiveSessionsCallbacks.length, 1, "expected DAppsRequestHandler call sdk.getActiveSessions")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_balanceCheck_data() {
|
||||||
|
return [{
|
||||||
|
tag: "have_enough_funds",
|
||||||
|
chainId: 11155111,
|
||||||
|
|
||||||
|
expect: {
|
||||||
|
haveEnoughForFees: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "doest_have_enough_funds",
|
||||||
|
chainId: 11155111,
|
||||||
|
// Override the suggestedFees to a higher value
|
||||||
|
maxFeePerGasM: 1000000.0, /*GWEI*/
|
||||||
|
|
||||||
|
expect: {
|
||||||
|
haveEnoughForFees: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "check_l2_doesnt_have_enough_funds_on_l1",
|
||||||
|
chainId: 421613,
|
||||||
|
// Override the l1 additional fees
|
||||||
|
l1GasFee: 1000000000.0,
|
||||||
|
|
||||||
|
expect: {
|
||||||
|
haveEnoughForFees: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "check_l2_doesnt_have_enough_funds_on_l2",
|
||||||
|
chainId: 421613,
|
||||||
|
// Override the l2 to a higher value
|
||||||
|
maxFeePerGasM: 1000000.0, /*GWEI*/
|
||||||
|
// Override the l1 additional fees
|
||||||
|
l1GasFee: 10.0,
|
||||||
|
|
||||||
|
expect: {
|
||||||
|
haveEnoughForFees: false,
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_balanceCheck(data) {
|
||||||
|
let sdk = handler.sdk
|
||||||
|
|
||||||
|
// Override the suggestedFees
|
||||||
|
if (!!data.maxFeePerGasM) {
|
||||||
|
handler.store.mockedSuggestedFees.maxFeePerGasM = data.maxFeePerGasM
|
||||||
|
}
|
||||||
|
if (!!data.l1GasFee) {
|
||||||
|
handler.store.mockedSuggestedFees.l1GasFee = data.l1GasFee
|
||||||
|
}
|
||||||
|
|
||||||
|
let testAddress = "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240"
|
||||||
|
let chainId = data.chainId
|
||||||
|
let method = "eth_sendTransaction"
|
||||||
|
let message = "hello world"
|
||||||
|
let params = [`{
|
||||||
|
"data": "0x",
|
||||||
|
"from": "${testAddress}",
|
||||||
|
"to": "0x2",
|
||||||
|
"value": "0x12345"
|
||||||
|
}`]
|
||||||
|
let topic = "b536a"
|
||||||
|
let session = JSON.parse(Testing.formatSessionRequest(chainId, method, params, topic))
|
||||||
|
sdk.sessionRequestEvent(session)
|
||||||
|
|
||||||
|
compare(sdk.getActiveSessionsCallbacks.length, 1, "expected DAppsRequestHandler call sdk.getActiveSessions")
|
||||||
|
let callback = sdk.getActiveSessionsCallbacks[0].callback
|
||||||
|
callback({"b536a": JSON.parse(Testing.formatApproveSessionResponse([chainId, 7], [testAddress]))})
|
||||||
|
compare(handler.maxFeesUpdatedCalls.length, 1, "expected a call to handler.onMaxFeesUpdated")
|
||||||
|
|
||||||
|
let args = handler.maxFeesUpdatedCalls[0]
|
||||||
|
verify(args.ethMaxFees > 0, "expected ethMaxFees to be set")
|
||||||
|
// storybook's CurrenciesStore mock up getFiatValue returns the balance
|
||||||
|
compare(args.fiatMaxFees.toString(), args.ethMaxFees.toString(), "expected fiatMaxFees to be set")
|
||||||
|
verify(args.haveEnoughFunds, "expected haveEnoughFunds to be set")
|
||||||
|
compare(args.haveEnoughForFees, data.expect.haveEnoughForFees, "expected haveEnoughForFees to be set")
|
||||||
|
compare(args.symbol, "$", "expected symbol to be set")
|
||||||
|
verify(!!args.feesInfo, "expected feesInfo to be set")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TestCase {
|
TestCase {
|
||||||
|
@ -238,8 +374,7 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SignalSpy {
|
readonly property SignalSpy sessionRequestSpy: SignalSpy {
|
||||||
id: sessionRequestSpy
|
|
||||||
target: walletConnectServiceTest.service
|
target: walletConnectServiceTest.service
|
||||||
signalName: "sessionRequest"
|
signalName: "sessionRequest"
|
||||||
|
|
||||||
|
@ -337,7 +472,7 @@ Item {
|
||||||
let chainId = 2
|
let chainId = 2
|
||||||
let method = "personal_sign"
|
let method = "personal_sign"
|
||||||
let message = "hello world"
|
let message = "hello world"
|
||||||
let params = [Helpers.strToHex(message), testAddress]
|
let params = [`"${Helpers.strToHex(message)}"`, `"${testAddress}"`]
|
||||||
let topic = "b536a"
|
let topic = "b536a"
|
||||||
let session = JSON.parse(Testing.formatSessionRequest(chainId, method, params, topic))
|
let session = JSON.parse(Testing.formatSessionRequest(chainId, method, params, topic))
|
||||||
// Expect to have calls to getActiveSessions from service initialization
|
// Expect to have calls to getActiveSessions from service initialization
|
||||||
|
@ -674,7 +809,7 @@ Item {
|
||||||
let network = networksMdodel.get(1)
|
let network = networksMdodel.get(1)
|
||||||
let method = "personal_sign"
|
let method = "personal_sign"
|
||||||
let message = "hello world"
|
let message = "hello world"
|
||||||
let params = [Helpers.strToHex(message), account.address]
|
let params = [`"${Helpers.strToHex(message)}"`, `"${account.address}"`]
|
||||||
let topic = "b536a"
|
let topic = "b536a"
|
||||||
let requestEvent = JSON.parse(Testing.formatSessionRequest(network.chainId, method, params, topic))
|
let requestEvent = JSON.parse(Testing.formatSessionRequest(network.chainId, method, params, topic))
|
||||||
let request = tc.createTemporaryObject(sessionRequestComponent, root, {
|
let request = tc.createTemporaryObject(sessionRequestComponent, root, {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import QtQuick 2.15
|
||||||
|
|
||||||
import AppLayouts.Wallet.services.dapps 1.0
|
import AppLayouts.Wallet.services.dapps 1.0
|
||||||
import AppLayouts.Wallet.services.dapps.types 1.0
|
import AppLayouts.Wallet.services.dapps.types 1.0
|
||||||
|
import AppLayouts.Wallet.stores 1.0 as WalletStore
|
||||||
|
|
||||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ SQUtils.QObject {
|
||||||
required property var accountsModel
|
required property var accountsModel
|
||||||
required property var networksModel
|
required property var networksModel
|
||||||
required property CurrenciesStore currenciesStore
|
required property CurrenciesStore currenciesStore
|
||||||
|
required property WalletStore.WalletAssetsStore assetsStore
|
||||||
|
|
||||||
property alias requestsModel: requests
|
property alias requestsModel: requests
|
||||||
|
|
||||||
|
@ -124,6 +126,7 @@ SQUtils.QObject {
|
||||||
console.error("Error finding network for event", JSON.stringify(event))
|
console.error("Error finding network for event", JSON.stringify(event))
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = extractMethodData(event, method)
|
let data = extractMethodData(event, method)
|
||||||
if(!data) {
|
if(!data) {
|
||||||
console.error("Error in event data lookup", JSON.stringify(event))
|
console.error("Error in event data lookup", JSON.stringify(event))
|
||||||
|
@ -168,9 +171,19 @@ SQUtils.QObject {
|
||||||
let estimatedTimeEnum = getEstimatedTimeInterval(data, method, obj.network.chainId)
|
let estimatedTimeEnum = getEstimatedTimeInterval(data, method, obj.network.chainId)
|
||||||
root.estimatedTimeUpdated(estimatedTimeEnum)
|
root.estimatedTimeUpdated(estimatedTimeEnum)
|
||||||
|
|
||||||
let st = getEstimatedFeesStatus(data, method, obj.network.chainId)
|
const mainNet = lookupMainnetNetwork()
|
||||||
|
let mainChainId = obj.network.chainId
|
||||||
|
if (!!mainNet) {
|
||||||
|
mainChainId = mainNet.chainId
|
||||||
|
} else {
|
||||||
|
console.error("Error finding mainnet network")
|
||||||
|
}
|
||||||
|
let st = getEstimatedFeesStatus(data, method, obj.network.chainId, mainChainId)
|
||||||
|
|
||||||
root.maxFeesUpdated(st.fiatMaxFees, st.maxFeesEth, st.haveEnoughFunds, st.haveEnoughFees, st.symbol, st.feesInfo)
|
let fundsStatus = checkFundsStatus(st.feesInfo.maxFees, st.feesInfo.l1GasFee, account.address, obj.network.chainId, mainNet.chainId)
|
||||||
|
|
||||||
|
root.maxFeesUpdated(st.fiatMaxFees.toNumber(), st.maxFeesEth, fundsStatus.haveEnoughFunds,
|
||||||
|
fundsStatus.haveEnoughForFees, st.symbol, st.feesInfo)
|
||||||
})
|
})
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
@ -216,6 +229,11 @@ SQUtils.QObject {
|
||||||
return SQUtils.ModelUtils.getByKey(root.networksModel, "chainId", chainId)
|
return SQUtils.ModelUtils.getByKey(root.networksModel, "chainId", chainId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns null if the network is not found
|
||||||
|
function lookupMainnetNetwork() {
|
||||||
|
return SQUtils.ModelUtils.getByKey(root.networksModel, "layer", 1)
|
||||||
|
}
|
||||||
|
|
||||||
function extractMethodData(event, method) {
|
function extractMethodData(event, method) {
|
||||||
if (method === SessionRequest.methods.personalSign.name ||
|
if (method === SessionRequest.methods.personalSign.name ||
|
||||||
method === SessionRequest.methods.sign.name)
|
method === SessionRequest.methods.sign.name)
|
||||||
|
@ -362,7 +380,7 @@ SQUtils.QObject {
|
||||||
// maxPriorityFeePerGas
|
// maxPriorityFeePerGas
|
||||||
// gasPrice
|
// gasPrice
|
||||||
// }
|
// }
|
||||||
function getEstimatedMaxFees(data, method, chainId) {
|
function getEstimatedMaxFees(data, method, chainId, mainNetChainId) {
|
||||||
let tx = {}
|
let tx = {}
|
||||||
if (d.isTransactionMethod(method)) {
|
if (d.isTransactionMethod(method)) {
|
||||||
tx = d.getTxObject(method, data)
|
tx = d.getTxObject(method, data)
|
||||||
|
@ -371,6 +389,8 @@ SQUtils.QObject {
|
||||||
let Math = SQUtils.AmountsArithmetic
|
let Math = SQUtils.AmountsArithmetic
|
||||||
let gasLimit = Math.fromString("21000")
|
let gasLimit = Math.fromString("21000")
|
||||||
let gasPrice, maxFeePerGas, maxPriorityFeePerGas
|
let gasPrice, maxFeePerGas, maxPriorityFeePerGas
|
||||||
|
let l1GasFee = Math.fromNumber(0)
|
||||||
|
|
||||||
// Beware, the tx values are standard blockchain hex big number values; the fees values are nim's float64 values, hence the complex conversions
|
// Beware, the tx values are standard blockchain hex big number values; the fees values are nim's float64 values, hence the complex conversions
|
||||||
if (!!tx.maxFeePerGas && !!tx.maxPriorityFeePerGas) {
|
if (!!tx.maxFeePerGas && !!tx.maxPriorityFeePerGas) {
|
||||||
let maxFeePerGasDec = root.store.hexToDec(tx.maxFeePerGas)
|
let maxFeePerGasDec = root.store.hexToDec(tx.maxFeePerGas)
|
||||||
|
@ -384,7 +404,7 @@ SQUtils.QObject {
|
||||||
maxPriorityFeePerGas = fees.maxPriorityFeePerGas
|
maxPriorityFeePerGas = fees.maxPriorityFeePerGas
|
||||||
if (fees.eip1559Enabled) {
|
if (fees.eip1559Enabled) {
|
||||||
if (!!fees.maxFeePerGasM) {
|
if (!!fees.maxFeePerGasM) {
|
||||||
gasPrice = Math.fromString(fees.maxFeePerGasM)
|
gasPrice = Math.fromNumber(fees.maxFeePerGasM)
|
||||||
maxFeePerGas = fees.maxFeePerGasM
|
maxFeePerGas = fees.maxFeePerGasM
|
||||||
} else if(!!tx.maxFeePerGas) {
|
} else if(!!tx.maxFeePerGas) {
|
||||||
let maxFeePerGasDec = root.store.hexToDec(tx.maxFeePerGas)
|
let maxFeePerGasDec = root.store.hexToDec(tx.maxFeePerGas)
|
||||||
|
@ -396,38 +416,75 @@ SQUtils.QObject {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!!fees.gasPrice) {
|
if (!!fees.gasPrice) {
|
||||||
gasPrice = Math.fromString(fees.gasPrice)
|
gasPrice = Math.fromNumber(fees.gasPrice)
|
||||||
} else {
|
} else {
|
||||||
console.error("Error fetching suggested fees")
|
console.error("Error fetching suggested fees")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gasPrice = Math.sum(gasPrice, Math.fromString(fees.l1GasFee))
|
l1GasFee = Math.fromNumber(fees.l1GasFee)
|
||||||
}
|
}
|
||||||
|
|
||||||
let maxFees = Math.times(gasLimit, gasPrice)
|
let maxFees = Math.times(gasLimit, gasPrice)
|
||||||
return {maxFees, maxFeePerGas, maxPriorityFeePerGas, gasPrice}
|
return {maxFees, maxFeePerGas, maxPriorityFeePerGas, gasPrice, l1GasFee}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEstimatedFeesStatus(data, method, chainId) {
|
// Returned values are Big numbers
|
||||||
|
function getEstimatedFeesStatus(data, method, chainId, mainNetChainId) {
|
||||||
let Math = SQUtils.AmountsArithmetic
|
let Math = SQUtils.AmountsArithmetic
|
||||||
|
|
||||||
let feesInfo = getEstimatedMaxFees(data, method, chainId)
|
let feesInfo = getEstimatedMaxFees(data, method, chainId, mainNetChainId)
|
||||||
|
|
||||||
let maxFeesEth = Math.div(feesInfo.maxFees, Math.fromString("1000000000"))
|
let totalMaxFees = Math.sum(feesInfo.maxFees, feesInfo.l1GasFee)
|
||||||
|
let maxFeesEth = Math.div(totalMaxFees, Math.fromString("1000000000"))
|
||||||
// TODO #15192: extract account.balance
|
|
||||||
//let accountFundsEth = account.balance
|
|
||||||
//let haveEnoughFees = Math.cmp(accountFundsEth, maxFeesEth) >= 0
|
|
||||||
let haveEnoughFees = true
|
|
||||||
|
|
||||||
let maxFeesEthStr = maxFeesEth.toString()
|
let maxFeesEthStr = maxFeesEth.toString()
|
||||||
let fiatMaxFees = root.currenciesStore.getFiatValue(maxFeesEthStr, Constants.ethToken)
|
let fiatMaxFeesStr = root.currenciesStore.getFiatValue(maxFeesEthStr, Constants.ethToken)
|
||||||
let symbol = root.currenciesStore.currentCurrency
|
let fiatMaxFees = Math.fromString(fiatMaxFeesStr)
|
||||||
|
let symbol = root.currenciesStore.currentCurrencySymbol
|
||||||
|
|
||||||
// We don't process the transaction so we don't have this information yet
|
return {fiatMaxFees, maxFeesEth, symbol, feesInfo}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkBalanceForChain(balances, address, chainId, fees) {
|
||||||
|
let Math = SQUtils.AmountsArithmetic
|
||||||
|
let accEth = SQUtils.ModelUtils.getFirstModelEntryIf(balances, (balance) => {
|
||||||
|
return balance.account.toLowerCase() === address.toLowerCase() && balance.chainId === chainId
|
||||||
|
})
|
||||||
|
if (!accEth) {
|
||||||
|
console.error("Error balance lookup for account ", address, " on chain ", chainId)
|
||||||
|
return {haveEnoughForFees, haveEnoughFunds}
|
||||||
|
}
|
||||||
|
let accountFundsWei = Math.fromString(accEth.balance)
|
||||||
|
let accountFundsEth = Math.div(accountFundsWei, Math.fromString("1000000000000000000"))
|
||||||
|
|
||||||
|
let feesEth = Math.div(fees, Math.fromString("1000000000"))
|
||||||
|
return Math.cmp(accountFundsEth, feesEth) >= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkFundsStatus(maxFees, l1GasFee, address, chainId, mainNetChainId) {
|
||||||
|
let Math = SQUtils.AmountsArithmetic
|
||||||
|
|
||||||
|
let haveEnoughForFees = false
|
||||||
|
// TODO #15192: extract funds from transaction and check against it
|
||||||
let haveEnoughFunds = true
|
let haveEnoughFunds = true
|
||||||
return {fiatMaxFees, maxFeesEth, haveEnoughFunds, haveEnoughFees, symbol, feesInfo}
|
|
||||||
|
let token = SQUtils.ModelUtils.getByKey(root.assetsStore.groupedAccountAssetsModel, "tokensKey", Constants.ethToken)
|
||||||
|
if (!token || !token.balances) {
|
||||||
|
console.error("Error token balances lookup for ETH")
|
||||||
|
return {haveEnoughForFees, haveEnoughFunds}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chainId == mainNetChainId) {
|
||||||
|
const finalFees = Math.sum(maxFees, l1GasFee)
|
||||||
|
haveEnoughForFees = checkBalanceForChain(token.balances, address, chainId, finalFees)
|
||||||
|
} else {
|
||||||
|
const haveEnoughOnChain = checkBalanceForChain(token.balances, address, chainId, maxFees)
|
||||||
|
const haveEnoughOnMain = checkBalanceForChain(token.balances, address, mainNetChainId, l1GasFee)
|
||||||
|
haveEnoughForFees = haveEnoughOnChain && haveEnoughOnMain
|
||||||
|
}
|
||||||
|
|
||||||
|
return {haveEnoughForFees, haveEnoughFunds}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isTransactionMethod(method) {
|
function isTransactionMethod(method) {
|
||||||
|
|
|
@ -239,6 +239,7 @@ QObject {
|
||||||
accountsModel: root.validAccounts
|
accountsModel: root.validAccounts
|
||||||
networksModel: root.flatNetworks
|
networksModel: root.flatNetworks
|
||||||
currenciesStore: root.walletRootStore.currencyStore
|
currenciesStore: root.walletRootStore.currencyStore
|
||||||
|
assetsStore: root.walletRootStore.walletAssetsStore
|
||||||
|
|
||||||
onSessionRequest: (request) => {
|
onSessionRequest: (request) => {
|
||||||
timeoutTimer.stop()
|
timeoutTimer.stop()
|
||||||
|
|
Loading…
Reference in New Issue