fix(@desktop/communities): Compute deployment fees in async way.
Improve showing errors when estimating fees. Fix #10035
This commit is contained in:
parent
8dafdfceb8
commit
4ceeb905dc
|
@ -216,7 +216,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
||||||
result.settingsService, result.walletAccountService, result.transactionService,
|
result.settingsService, result.walletAccountService, result.transactionService,
|
||||||
result.networkService, result.tokenService)
|
result.networkService, result.tokenService)
|
||||||
result.tokensService = tokens_service.newService(statusFoundation.events, statusFoundation.threadpool,
|
result.tokensService = tokens_service.newService(statusFoundation.events, statusFoundation.threadpool,
|
||||||
result.transactionService, result.tokenService, result.settingsService)
|
result.transactionService, result.tokenService, result.settingsService, result.walletAccountService)
|
||||||
result.providerService = provider_service.newService(statusFoundation.events, statusFoundation.threadpool, result.ensService)
|
result.providerService = provider_service.newService(statusFoundation.events, statusFoundation.threadpool, result.ensService)
|
||||||
result.networkConnectionService = network_connection_service.newService(statusFoundation.events, result.walletAccountService, result.networkService, result.nodeService)
|
result.networkConnectionService = network_connection_service.newService(statusFoundation.events, result.walletAccountService, result.networkService, result.nodeService)
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,9 @@ proc init*(self: Controller) =
|
||||||
if args.uniqueIdentifier != UNIQUE_DEPLOY_COLLECTIBLES_COMMUNITY_TOKENS_MODULE_IDENTIFIER:
|
if args.uniqueIdentifier != UNIQUE_DEPLOY_COLLECTIBLES_COMMUNITY_TOKENS_MODULE_IDENTIFIER:
|
||||||
return
|
return
|
||||||
self.communityTokensModule.onUserAuthenticated(args.password)
|
self.communityTokensModule.onUserAuthenticated(args.password)
|
||||||
|
self.events.on(SIGNAL_COMPUTE_DEPLOY_FEE) do(e:Args):
|
||||||
|
let args = ComputeDeployFeeArgs(e)
|
||||||
|
self.communityTokensModule.onDeployFeeComputed(args.ethCurrency, args.fiatCurrency, args.errorCode)
|
||||||
|
|
||||||
proc deployCollectibles*(self: Controller, communityId: string, addressFrom: string, password: string, deploymentParams: DeploymentParameters, tokenMetadata: CommunityTokensMetadataDto, chainId: int) =
|
proc deployCollectibles*(self: Controller, communityId: string, addressFrom: string, password: string, deploymentParams: DeploymentParameters, tokenMetadata: CommunityTokensMetadataDto, chainId: int) =
|
||||||
self.communityTokensService.deployCollectibles(communityId, addressFrom, password, deploymentParams, tokenMetadata, chainId)
|
self.communityTokensService.deployCollectibles(communityId, addressFrom, password, deploymentParams, tokenMetadata, chainId)
|
||||||
|
@ -52,11 +55,8 @@ proc authenticateUser*(self: Controller, keyUid = "") =
|
||||||
proc getCommunityTokens*(self: Controller, communityId: string): seq[CommunityTokenDto] =
|
proc getCommunityTokens*(self: Controller, communityId: string): seq[CommunityTokenDto] =
|
||||||
return self.communityTokensService.getCommunityTokens(communityId)
|
return self.communityTokensService.getCommunityTokens(communityId)
|
||||||
|
|
||||||
proc getSuggestedFees*(self: Controller, chainId: int): SuggestedFeesDto =
|
proc computeDeployFee*(self: Controller, chainId: int, accountAddress: string) =
|
||||||
return self.transactionService.suggestedFees(chainId)
|
self.communityTokensService.computeDeployFee(chainId, accountAddress)
|
||||||
|
|
||||||
proc getFiatValue*(self: Controller, cryptoBalance: string, cryptoSymbol: string): string =
|
|
||||||
return self.communityTokensService.getFiatValue(cryptoBalance, cryptoSymbol)
|
|
||||||
|
|
||||||
proc getCommunityTokenBySymbol*(self: Controller, communityId: string, symbol: string): CommunityTokenDto =
|
proc getCommunityTokenBySymbol*(self: Controller, communityId: string, symbol: string): CommunityTokenDto =
|
||||||
return self.communityTokensService.getCommunityTokenBySymbol(communityId, symbol)
|
return self.communityTokensService.getCommunityTokenBySymbol(communityId, symbol)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import ../../../../../app_service/service/community_tokens/dto/community_token
|
import ../../../../../app_service/service/community_tokens/service
|
||||||
|
import ../../../shared_models/currency_amount
|
||||||
|
|
||||||
type
|
type
|
||||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
|
@ -22,5 +23,8 @@ method onUserAuthenticated*(self: AccessInterface, password: string) {.base.} =
|
||||||
method resetTempValues*(self: AccessInterface) {.base.} =
|
method resetTempValues*(self: AccessInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method computeDeployFee*(self: AccessInterface, chainId: int): string {.base.} =
|
method computeDeployFee*(self: AccessInterface, chainId: int, accountAddress: string) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method onDeployFeeComputed*(self: AccessInterface, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
|
@ -1,12 +1,12 @@
|
||||||
import NimQml, json, stint, strformat, strutils, chronicles
|
import NimQml, json, stint, strutils, chronicles
|
||||||
|
|
||||||
import ../../../../../app_service/service/community_tokens/service as community_tokens_service
|
import ../../../../../app_service/service/community_tokens/service as community_tokens_service
|
||||||
import ../../../../../app_service/service/transaction/service as transaction_service
|
import ../../../../../app_service/service/transaction/service as transaction_service
|
||||||
import ../../../../../app_service/service/community/dto/community
|
import ../../../../../app_service/service/community/dto/community
|
||||||
import ../../../../../app_service/common/conversion
|
|
||||||
import ../../../../../app_service/service/accounts/utils as utl
|
import ../../../../../app_service/service/accounts/utils as utl
|
||||||
import ../../../../core/eventemitter
|
import ../../../../core/eventemitter
|
||||||
import ../../../../global/global_singleton
|
import ../../../../global/global_singleton
|
||||||
|
import ../../../shared_models/currency_amount
|
||||||
import ../io_interface as parent_interface
|
import ../io_interface as parent_interface
|
||||||
import ./io_interface, ./view , ./controller
|
import ./io_interface, ./view , ./controller
|
||||||
|
|
||||||
|
@ -118,19 +118,8 @@ method onUserAuthenticated*(self: Module, password: string) =
|
||||||
elif self.tempContractAction == ContractAction.Airdrop:
|
elif self.tempContractAction == ContractAction.Airdrop:
|
||||||
self.controller.airdropCollectibles(self.tempCommunityId, password, self.tempTokenAndAmountList, self.tempWalletAddresses)
|
self.controller.airdropCollectibles(self.tempCommunityId, password, self.tempTokenAndAmountList, self.tempWalletAddresses)
|
||||||
|
|
||||||
method computeDeployFee*(self: Module, chainId: int): string =
|
method onDeployFeeComputed*(self: Module, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode) =
|
||||||
let suggestedFees = self.controller.getSuggestedFees(chainId)
|
self.view.updateDeployFee(ethCurrency, fiatCurrency, errorCode.int)
|
||||||
if suggestedFees == nil:
|
|
||||||
return "-"
|
|
||||||
|
|
||||||
let contractGasUnits = 3702411 # this should go from status-go
|
method computeDeployFee*(self: Module, chainId: int, accountAddress: string) =
|
||||||
let maxFees = suggestedFees.maxFeePerGasM
|
self.controller.computeDeployFee(chainId, accountAddress)
|
||||||
let gasPrice = if suggestedFees.eip1559Enabled: maxFees else: suggestedFees.gasPrice
|
|
||||||
|
|
||||||
let weiValue = gwei2Wei(gasPrice) * contractGasUnits.u256
|
|
||||||
let ethValueStr = wei2Eth(weiValue)
|
|
||||||
let ethValue = parseFloat(ethValueStr)
|
|
||||||
|
|
||||||
let fiatValue = self.controller.getFiatValue(ethValueStr, "ETH")
|
|
||||||
|
|
||||||
return fmt"{ethValue:.4f}ETH (${fiatValue})"
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import NimQml, json, strutils, sequtils
|
import NimQml, json, strutils, sequtils
|
||||||
|
|
||||||
import ./io_interface as community_tokens_module_interface
|
import ./io_interface as community_tokens_module_interface
|
||||||
|
import ../../../shared_models/currency_amount
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type
|
type
|
||||||
View* = ref object of QObject
|
View* = ref object of QObject
|
||||||
communityTokensModule: community_tokens_module_interface.AccessInterface
|
communityTokensModule: community_tokens_module_interface.AccessInterface
|
||||||
deployFee: string
|
|
||||||
|
|
||||||
proc load*(self: View) =
|
proc load*(self: View) =
|
||||||
discard
|
discard
|
||||||
|
@ -25,16 +25,12 @@ QtObject:
|
||||||
proc airdropCollectibles*(self: View, communityId: string, collectiblesJsonString: string, walletsJsonString: string) {.slot.} =
|
proc airdropCollectibles*(self: View, communityId: string, collectiblesJsonString: string, walletsJsonString: string) {.slot.} =
|
||||||
self.communityTokensModule.airdropCollectibles(communityId, collectiblesJsonString, walletsJsonString)
|
self.communityTokensModule.airdropCollectibles(communityId, collectiblesJsonString, walletsJsonString)
|
||||||
|
|
||||||
proc deployFeeUpdated*(self: View) {.signal.}
|
proc deployFeeUpdated*(self: View, ethCurrency: QVariant, fiatCurrency: QVariant, errorCode: int) {.signal.}
|
||||||
|
|
||||||
proc computeDeployFee*(self: View, chainId: int) {.slot.} =
|
proc computeDeployFee*(self: View, chainId: int, accountAddress: string) {.slot.} =
|
||||||
self.deployFee = self.communityTokensModule.computeDeployFee(chainId)
|
self.communityTokensModule.computeDeployFee(chainId, accountAddress)
|
||||||
self.deployFeeUpdated()
|
|
||||||
|
|
||||||
proc getDeployFee(self: View): QVariant {.slot.} =
|
proc updateDeployFee*(self: View, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: int) =
|
||||||
return newQVariant(self.deployFee)
|
self.deployFeeUpdated(newQVariant(ethCurrency), newQVariant(fiatCurrency), errorCode)
|
||||||
|
|
||||||
QtProperty[QVariant] deployFee:
|
|
||||||
read = getDeployFee
|
|
||||||
notify = deployFeeUpdated
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
include ../../common/json_utils
|
||||||
|
import ../../../backend/eth
|
||||||
|
import ../../../app/core/tasks/common
|
||||||
|
import ../../../app/core/tasks/qt
|
||||||
|
import ../transaction/dto
|
||||||
|
|
||||||
|
type
|
||||||
|
AsyncGetSuggestedFees = ref object of QObjectTaskArg
|
||||||
|
chainId: int
|
||||||
|
|
||||||
|
const asyncGetSuggestedFeesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
|
let arg = decode[AsyncGetSuggestedFees](argEncoded)
|
||||||
|
try:
|
||||||
|
let response = eth.suggestedFees(arg.chainId).result
|
||||||
|
arg.finish(%* {
|
||||||
|
"fees": response.toSuggestedFeesDto(),
|
||||||
|
"error": "",
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
arg.finish(%* {
|
||||||
|
"error": e.msg,
|
||||||
|
})
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import NimQml, Tables, chronicles, json, stint, strutils, strformat
|
import NimQml, Tables, chronicles, json, stint, strutils, strformat
|
||||||
import ../../../app/core/eventemitter
|
import ../../../app/core/eventemitter
|
||||||
import ../../../app/core/tasks/[qt, threadpool]
|
import ../../../app/core/tasks/[qt, threadpool]
|
||||||
|
import ../../../app/modules/shared_models/currency_amount
|
||||||
|
|
||||||
import ../../../backend/community_tokens as tokens_backend
|
import ../../../backend/community_tokens as tokens_backend
|
||||||
import ../transaction/service as transaction_service
|
import ../transaction/service as transaction_service
|
||||||
import ../token/service as token_service
|
import ../token/service as token_service
|
||||||
import ../settings/service as settings_service
|
import ../settings/service as settings_service
|
||||||
|
import ../wallet_account/service as wallet_account_service
|
||||||
import ../ens/utils as ens_utils
|
import ../ens/utils as ens_utils
|
||||||
import ../eth/dto/transaction
|
import ../eth/dto/transaction
|
||||||
|
|
||||||
|
@ -16,6 +18,7 @@ import ../community/dto/community
|
||||||
|
|
||||||
import ./dto/deployment_parameters
|
import ./dto/deployment_parameters
|
||||||
import ./dto/community_token
|
import ./dto/community_token
|
||||||
|
include async_tasks
|
||||||
|
|
||||||
export community_token
|
export community_token
|
||||||
export deployment_parameters
|
export deployment_parameters
|
||||||
|
@ -38,9 +41,23 @@ type
|
||||||
CommunityTokenDeployedArgs* = ref object of Args
|
CommunityTokenDeployedArgs* = ref object of Args
|
||||||
communityToken*: CommunityTokenDto
|
communityToken*: CommunityTokenDto
|
||||||
|
|
||||||
|
type
|
||||||
|
ComputeFeeErrorCode* {.pure.} = enum
|
||||||
|
Success,
|
||||||
|
Infura,
|
||||||
|
Balance,
|
||||||
|
Other
|
||||||
|
|
||||||
|
type
|
||||||
|
ComputeDeployFeeArgs* = ref object of Args
|
||||||
|
ethCurrency*: CurrencyAmount
|
||||||
|
fiatCurrency*: CurrencyAmount
|
||||||
|
errorCode*: ComputeFeeErrorCode
|
||||||
|
|
||||||
# Signals which may be emitted by this service:
|
# Signals which may be emitted by this service:
|
||||||
const SIGNAL_COMMUNITY_TOKEN_DEPLOY_STATUS* = "communityTokenDeployStatus"
|
const SIGNAL_COMMUNITY_TOKEN_DEPLOY_STATUS* = "communityTokenDeployStatus"
|
||||||
const SIGNAL_COMMUNITY_TOKEN_DEPLOYED* = "communityTokenDeployed"
|
const SIGNAL_COMMUNITY_TOKEN_DEPLOYED* = "communityTokenDeployed"
|
||||||
|
const SIGNAL_COMPUTE_DEPLOY_FEE* = "computeDeployFee"
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type
|
type
|
||||||
|
@ -50,6 +67,9 @@ QtObject:
|
||||||
transactionService: transaction_service.Service
|
transactionService: transaction_service.Service
|
||||||
tokenService: token_service.Service
|
tokenService: token_service.Service
|
||||||
settingsService: settings_service.Service
|
settingsService: settings_service.Service
|
||||||
|
walletAccountService: wallet_account_service.Service
|
||||||
|
tempAccountAddress: string
|
||||||
|
tempChainId: int
|
||||||
|
|
||||||
proc delete*(self: Service) =
|
proc delete*(self: Service) =
|
||||||
self.QObject.delete
|
self.QObject.delete
|
||||||
|
@ -59,7 +79,8 @@ QtObject:
|
||||||
threadpool: ThreadPool,
|
threadpool: ThreadPool,
|
||||||
transactionService: transaction_service.Service,
|
transactionService: transaction_service.Service,
|
||||||
tokenService: token_service.Service,
|
tokenService: token_service.Service,
|
||||||
settingsService: settings_service.Service
|
settingsService: settings_service.Service,
|
||||||
|
walletAccountService: wallet_account_service.Service
|
||||||
): Service =
|
): Service =
|
||||||
result = Service()
|
result = Service()
|
||||||
result.QObject.setup
|
result.QObject.setup
|
||||||
|
@ -68,6 +89,7 @@ QtObject:
|
||||||
result.transactionService = transactionService
|
result.transactionService = transactionService
|
||||||
result.tokenService = tokenService
|
result.tokenService = tokenService
|
||||||
result.settingsService = settingsService
|
result.settingsService = settingsService
|
||||||
|
result.walletAccountService = walletAccountService
|
||||||
|
|
||||||
proc init*(self: Service) =
|
proc init*(self: Service) =
|
||||||
self.events.on(PendingTransactionTypeDto.CollectibleDeployment.event) do(e: Args):
|
self.events.on(PendingTransactionTypeDto.CollectibleDeployment.event) do(e: Args):
|
||||||
|
@ -83,17 +105,23 @@ QtObject:
|
||||||
let data = CommunityTokenDeployedStatusArgs(communityId: tokenDto.communityId, contractAddress: tokenDto.address, deployState: deployState)
|
let data = CommunityTokenDeployedStatusArgs(communityId: tokenDto.communityId, contractAddress: tokenDto.address, deployState: deployState)
|
||||||
self.events.emit(SIGNAL_COMMUNITY_TOKEN_DEPLOY_STATUS, data)
|
self.events.emit(SIGNAL_COMMUNITY_TOKEN_DEPLOY_STATUS, data)
|
||||||
|
|
||||||
|
proc deployCollectiblesEstimate*(self: Service): int =
|
||||||
|
try:
|
||||||
|
let response = tokens_backend.deployCollectiblesEstimate()
|
||||||
|
return response.result.getInt()
|
||||||
|
except RpcException:
|
||||||
|
error "Error getting deploy estimate", message = getCurrentExceptionMsg()
|
||||||
|
|
||||||
proc deployCollectibles*(self: Service, communityId: string, addressFrom: string, password: string, deploymentParams: DeploymentParameters, tokenMetadata: CommunityTokensMetadataDto, chainId: int) =
|
proc deployCollectibles*(self: Service, communityId: string, addressFrom: string, password: string, deploymentParams: DeploymentParameters, tokenMetadata: CommunityTokensMetadataDto, chainId: int) =
|
||||||
try:
|
try:
|
||||||
# TODO this will come from SendModal
|
# TODO this will come from SendModal
|
||||||
let suggestedFees = self.transactionService.suggestedFees(chainId)
|
let suggestedFees = self.transactionService.suggestedFees(chainId)
|
||||||
let contractGasUnits = "3702411"
|
let contractGasUnits = self.deployCollectiblesEstimate()
|
||||||
|
|
||||||
if suggestedFees == nil:
|
if suggestedFees == nil:
|
||||||
error "Error deploying collectibles", message = "Can't get suggested fees"
|
error "Error deploying collectibles", message = "Can't get suggested fees"
|
||||||
return
|
return
|
||||||
|
|
||||||
let txData = ens_utils.buildTransaction(parseAddress(addressFrom), 0.u256, contractGasUnits,
|
let txData = ens_utils.buildTransaction(parseAddress(addressFrom), 0.u256, $contractGasUnits,
|
||||||
if suggestedFees.eip1559Enabled: "" else: $suggestedFees.gasPrice, suggestedFees.eip1559Enabled,
|
if suggestedFees.eip1559Enabled: "" else: $suggestedFees.gasPrice, suggestedFees.eip1559Enabled,
|
||||||
if suggestedFees.eip1559Enabled: $suggestedFees.maxPriorityFeePerGas else: "",
|
if suggestedFees.eip1559Enabled: $suggestedFees.maxPriorityFeePerGas else: "",
|
||||||
if suggestedFees.eip1559Enabled: $suggestedFees.maxFeePerGasM else: "")
|
if suggestedFees.eip1559Enabled: $suggestedFees.maxFeePerGasM else: "")
|
||||||
|
@ -152,16 +180,6 @@ QtObject:
|
||||||
if token.symbol == symbol:
|
if token.symbol == symbol:
|
||||||
return token
|
return token
|
||||||
|
|
||||||
proc getFiatValue*(self: Service, cryptoBalance: string, cryptoSymbol: string): string =
|
|
||||||
if (cryptoBalance == "" or cryptoSymbol == ""):
|
|
||||||
return "0.00"
|
|
||||||
|
|
||||||
let currentCurrency = self.settingsService.getCurrency()
|
|
||||||
|
|
||||||
let price = self.tokenService.getTokenPrice(cryptoSymbol, currentCurrency)
|
|
||||||
let value = parseFloat(cryptoBalance) * price
|
|
||||||
return fmt"{value:.2f}"
|
|
||||||
|
|
||||||
proc contractOwner*(self: Service, chainId: int, contractAddress: string): string =
|
proc contractOwner*(self: Service, chainId: int, contractAddress: string): string =
|
||||||
try:
|
try:
|
||||||
let response = tokens_backend.contractOwner(chainId, contractAddress)
|
let response = tokens_backend.contractOwner(chainId, contractAddress)
|
||||||
|
@ -178,3 +196,60 @@ QtObject:
|
||||||
echo "!!! Transaction hash ", response.result.getStr()
|
echo "!!! Transaction hash ", response.result.getStr()
|
||||||
except RpcException:
|
except RpcException:
|
||||||
error "Error minting collectibles", message = getCurrentExceptionMsg()
|
error "Error minting collectibles", message = getCurrentExceptionMsg()
|
||||||
|
|
||||||
|
proc getFiatValue*(self: Service, cryptoBalance: float, cryptoSymbol: string): float =
|
||||||
|
if (cryptoSymbol == ""):
|
||||||
|
return 0.0
|
||||||
|
let currentCurrency = self.settingsService.getCurrency()
|
||||||
|
let price = self.tokenService.getTokenPrice(cryptoSymbol, currentCurrency)
|
||||||
|
return cryptoBalance * price
|
||||||
|
|
||||||
|
proc computeDeployFee*(self: Service, chainId: int, accountAddress: string) =
|
||||||
|
try:
|
||||||
|
self.tempAccountAddress = accountAddress
|
||||||
|
self.tempChainId = chainId
|
||||||
|
let arg = AsyncGetSuggestedFees(
|
||||||
|
tptr: cast[ByteAddress](asyncGetSuggestedFeesTask),
|
||||||
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
|
slot: "onSuggestedFees",
|
||||||
|
chainId: chainId,
|
||||||
|
)
|
||||||
|
self.threadpool.start(arg)
|
||||||
|
except Exception as e:
|
||||||
|
error "Error loading fees", msg = e.msg
|
||||||
|
|
||||||
|
proc onSuggestedFees*(self:Service, response: string) {.slot.} =
|
||||||
|
let responseJson = response.parseJson()
|
||||||
|
|
||||||
|
if responseJson{"error"}.kind != JNull and responseJson{"error"}.getStr != "":
|
||||||
|
let errorMessage = responseJson["error"].getStr
|
||||||
|
var errorCode = ComputeFeeErrorCode.Other
|
||||||
|
if errorMessage.contains("403 Forbidden") or errorMessage.contains("exceed"):
|
||||||
|
errorCode = ComputeFeeErrorCode.Infura
|
||||||
|
let ethCurrency = newCurrencyAmount(0.0, "ETH", 1, false)
|
||||||
|
let fiatCurrency = newCurrencyAmount(0.0, self.settingsService.getCurrency(), 1, false)
|
||||||
|
let data = ComputeDeployFeeArgs(ethCurrency: ethCurrency, fiatCurrency: fiatCurrency, errorCode: errorCode)
|
||||||
|
self.events.emit(SIGNAL_COMPUTE_DEPLOY_FEE, data)
|
||||||
|
return
|
||||||
|
|
||||||
|
let suggestedFees = decodeSuggestedFeesDto(responseJson["fees"])
|
||||||
|
let contractGasUnits = self.deployCollectiblesEstimate()
|
||||||
|
let maxFees = suggestedFees.maxFeePerGasM
|
||||||
|
let gasPrice = if suggestedFees.eip1559Enabled: maxFees else: suggestedFees.gasPrice
|
||||||
|
|
||||||
|
const ethSymbol = "ETH"
|
||||||
|
|
||||||
|
let weiValue = gwei2Wei(gasPrice) * contractGasUnits.u256
|
||||||
|
let ethValueStr = wei2Eth(weiValue)
|
||||||
|
let ethValue = parseFloat(ethValueStr)
|
||||||
|
let fiatValue = self.getFiatValue(ethValue, ethSymbol)
|
||||||
|
|
||||||
|
let wallet = self.walletAccountService.getAccountByAddress(self.tempAccountAddress)
|
||||||
|
let balance = wallet.getCurrencyBalance(@[self.tempChainId], ethSymbol)
|
||||||
|
|
||||||
|
let ethCurrency = newCurrencyAmount(ethValue, "ETH", 4, false)
|
||||||
|
let fiatCurrency = newCurrencyAmount(fiatValue, self.settingsService.getCurrency(), 2, false)
|
||||||
|
|
||||||
|
let data = ComputeDeployFeeArgs(ethCurrency: ethCurrency, fiatCurrency: fiatCurrency,
|
||||||
|
errorCode: (if ethValue > balance: ComputeFeeErrorCode.Balance else: ComputeFeeErrorCode.Success))
|
||||||
|
self.events.emit(SIGNAL_COMPUTE_DEPLOY_FEE, data)
|
||||||
|
|
|
@ -27,3 +27,7 @@ proc mintTo*(chainId: int, contractAddress: string, txData: JsonNode, password:
|
||||||
proc contractOwner*(chainId: int, contractAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
proc contractOwner*(chainId: int, contractAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
let payload = %* [chainId, contractAddress]
|
let payload = %* [chainId, contractAddress]
|
||||||
return core.callPrivateRPC("collectibles_contractOwner", payload)
|
return core.callPrivateRPC("collectibles_contractOwner", payload)
|
||||||
|
|
||||||
|
proc deployCollectiblesEstimate*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
let payload = %*[]
|
||||||
|
return core.callPrivateRPC("collectibles_deployCollectiblesEstimate", payload)
|
|
@ -22,6 +22,7 @@ SettingsPageLayout {
|
||||||
property var tokensModel
|
property var tokensModel
|
||||||
property var holdersModel
|
property var holdersModel
|
||||||
property string feeText
|
property string feeText
|
||||||
|
property string errorText
|
||||||
property bool isFeeLoading: true
|
property bool isFeeLoading: true
|
||||||
|
|
||||||
// Network related properties:
|
// Network related properties:
|
||||||
|
@ -48,7 +49,13 @@ SettingsPageLayout {
|
||||||
string accountName,
|
string accountName,
|
||||||
string accountAddress)
|
string accountAddress)
|
||||||
|
|
||||||
signal signMintTransactionOpened(int chainId)
|
signal signMintTransactionOpened(int chainId, string accountAddress)
|
||||||
|
|
||||||
|
function setFeeLoading() {
|
||||||
|
root.isFeeLoading = true
|
||||||
|
root.feeText = ""
|
||||||
|
root.errorText = ""
|
||||||
|
}
|
||||||
|
|
||||||
function navigateBack() {
|
function navigateBack() {
|
||||||
stackManager.pop(StackView.Immediate)
|
stackManager.pop(StackView.Immediate)
|
||||||
|
@ -191,8 +198,7 @@ SettingsPageLayout {
|
||||||
id: preview
|
id: preview
|
||||||
|
|
||||||
function signMintTransaction() {
|
function signMintTransaction() {
|
||||||
root.isFeeLoading = true
|
root.setFeeLoading()
|
||||||
root.feeText = ""
|
|
||||||
root.mintCollectible(artworkSource,
|
root.mintCollectible(artworkSource,
|
||||||
name,
|
name,
|
||||||
symbol,
|
symbol,
|
||||||
|
@ -227,9 +233,13 @@ SettingsPageLayout {
|
||||||
accountName: parent.accountName
|
accountName: parent.accountName
|
||||||
networkName: parent.chainName
|
networkName: parent.chainName
|
||||||
feeText: root.feeText
|
feeText: root.feeText
|
||||||
|
errorText: root.errorText
|
||||||
isFeeLoading: root.isFeeLoading
|
isFeeLoading: root.isFeeLoading
|
||||||
|
|
||||||
onOpened: root.signMintTransactionOpened(parent.chainId)
|
onOpened: {
|
||||||
|
root.setFeeLoading()
|
||||||
|
root.signMintTransactionOpened(parent.chainId, d.accountAddress)
|
||||||
|
}
|
||||||
onCancelClicked: close()
|
onCancelClicked: close()
|
||||||
onSignTransactionClicked: parent.signMintTransaction()
|
onSignTransactionClicked: parent.signMintTransaction()
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ StatusDialog {
|
||||||
|
|
||||||
property alias accountName: accountText.text
|
property alias accountName: accountText.text
|
||||||
property alias feeText: feeText.text
|
property alias feeText: feeText.text
|
||||||
|
property alias errorText: errorTxt.text
|
||||||
property alias isFeeLoading: feeLoading.visible
|
property alias isFeeLoading: feeLoading.visible
|
||||||
|
|
||||||
property string collectibleName
|
property string collectibleName
|
||||||
|
@ -99,6 +100,17 @@ StatusDialog {
|
||||||
font.pixelSize: Style.current.primaryTextFontSize
|
font.pixelSize: Style.current.primaryTextFontSize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusBaseText {
|
||||||
|
id: errorTxt
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.pixelSize: Style.current.primaryTextFontSize
|
||||||
|
color: Theme.palette.dangerColor1
|
||||||
|
visible: root.errorText !== ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
footer: StatusDialogFooter {
|
footer: StatusDialogFooter {
|
||||||
|
@ -113,7 +125,7 @@ StatusDialog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatusButton {
|
StatusButton {
|
||||||
enabled: !root.isFeeLoading
|
enabled: root.errorText === "" && !root.isFeeLoading
|
||||||
icon.name: "password"
|
icon.name: "password"
|
||||||
text: qsTr("Sign transaction")
|
text: qsTr("Sign transaction")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
|
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property var rootStore
|
||||||
property var communityTokensModuleInst: communityTokensModule ?? null
|
property var communityTokensModuleInst: communityTokensModule ?? null
|
||||||
property string deployFee: communityTokensModuleInst.deployFee
|
|
||||||
|
|
||||||
// Network selection properties:
|
// Network selection properties:
|
||||||
property var layer1Networks: networksModule.layer1
|
property var layer1Networks: networksModule.layer1
|
||||||
|
@ -49,8 +48,6 @@ QtObject {
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
signal deployFeeUpdated(string value) // TO BE REMOVED
|
|
||||||
|
|
||||||
// Minting tokens:
|
// Minting tokens:
|
||||||
function deployCollectible(communityId, accountAddress, name, symbol, description, supply,
|
function deployCollectible(communityId, accountAddress, name, symbol, description, supply,
|
||||||
infiniteSupply, transferable, selfDestruct, chainId, artworkSource, accountName)
|
infiniteSupply, transferable, selfDestruct, chainId, artworkSource, accountName)
|
||||||
|
@ -60,10 +57,17 @@ QtObject {
|
||||||
infiniteSupply, transferable, selfDestruct, chainId, artworkSource)
|
infiniteSupply, transferable, selfDestruct, chainId, artworkSource)
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeDeployFee(chainId) {
|
signal deployFeeUpdated(var ethCurrency, var fiatCurrency, int error)
|
||||||
// TODO this call will be async
|
|
||||||
communityTokensModuleInst.computeDeployFee(chainId)
|
readonly property Connections connections: Connections {
|
||||||
root.deployFeeUpdated(root.deployFee)
|
target: communityTokensModuleInst
|
||||||
|
function onDeployFeeUpdated(ethCurrency, fiatCurrency, errorCode) {
|
||||||
|
root.deployFeeUpdated(ethCurrency, fiatCurrency, errorCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeDeployFee(chainId, accountAddress) {
|
||||||
|
communityTokensModuleInst.computeDeployFee(chainId, accountAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Airdrop tokens:
|
// Airdrop tokens:
|
||||||
|
|
|
@ -15,7 +15,7 @@ QtObject {
|
||||||
chatCommunitySectionModuleInst: chatCommunitySectionModule
|
chatCommunitySectionModuleInst: chatCommunitySectionModule
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property CommunityTokensStore communityTokensStore: CommunityTokensStore {}
|
readonly property CommunityTokensStore communityTokensStore: CommunityTokensStore { rootStore: root }
|
||||||
|
|
||||||
property bool openCreateChat: false
|
property bool openCreateChat: false
|
||||||
property string createChatInitMessage: ""
|
property string createChatInitMessage: ""
|
||||||
|
|
|
@ -300,7 +300,7 @@ StatusSectionLayout {
|
||||||
accounts: root.rootStore.accounts
|
accounts: root.rootStore.accounts
|
||||||
|
|
||||||
onPreviousPageNameChanged: root.backButtonName = previousPageName
|
onPreviousPageNameChanged: root.backButtonName = previousPageName
|
||||||
onSignMintTransactionOpened: communityTokensStore.computeDeployFee(chainId)
|
onSignMintTransactionOpened: communityTokensStore.computeDeployFee(chainId, accountAddress)
|
||||||
onMintCollectible: {
|
onMintCollectible: {
|
||||||
communityTokensStore.deployCollectible(root.community.id,
|
communityTokensStore.deployCollectible(root.community.id,
|
||||||
accountAddress,
|
accountAddress,
|
||||||
|
@ -322,17 +322,25 @@ StatusSectionLayout {
|
||||||
value: communityMintTokensSettingsPanel.StackView.index
|
value: communityMintTokensSettingsPanel.StackView.index
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Review once backend is done
|
|
||||||
Connections {
|
Connections {
|
||||||
target: rootStore.communityTokensStore
|
target: rootStore.communityTokensStore
|
||||||
function onDeployFeeUpdated(value) {
|
function onDeployFeeUpdated(ethCurrency, fiatCurrency, errorCode) {
|
||||||
// TODO better error handling
|
if (errorCode === Constants.ComputeFeeErrorCode.Success || errorCode === Constants.ComputeFeeErrorCode.Balance) {
|
||||||
if (value === "-") {
|
let valueStr = LocaleUtils.currencyAmountToLocaleString(ethCurrency) + "(" + LocaleUtils.currencyAmountToLocaleString(fiatCurrency) + ")"
|
||||||
mintPanel.isFeeLoading = true
|
mintPanel.feeText = valueStr
|
||||||
} else {
|
if (errorCode === Constants.ComputeFeeErrorCode.Balance) {
|
||||||
mintPanel.isFeeLoading = false
|
mintPanel.errorText = qsTr("Not enough funds to make transaction")
|
||||||
mintPanel.feeText = value
|
|
||||||
}
|
}
|
||||||
|
mintPanel.isFeeLoading = false
|
||||||
|
return
|
||||||
|
} else if (errorCode === Constants.ComputeFeeErrorCode.Infura) {
|
||||||
|
mintPanel.errorText = qsTr("Infura error")
|
||||||
|
mintPanel.isFeeLoading = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mintPanel.errorText = qsTr("Unknown error")
|
||||||
|
mintPanel.isFeeLoading = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -864,6 +864,12 @@ QtObject {
|
||||||
Keycard
|
Keycard
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ComputeFeeErrorCode {
|
||||||
|
Success,
|
||||||
|
Infura,
|
||||||
|
Balance,
|
||||||
|
Other
|
||||||
|
}
|
||||||
|
|
||||||
readonly property QtObject walletSection: QtObject {
|
readonly property QtObject walletSection: QtObject {
|
||||||
readonly property string cancelledMessage: "cancelled"
|
readonly property string cancelledMessage: "cancelled"
|
||||||
|
|
Loading…
Reference in New Issue