From 100389aa8d1d0eb3facabd9643dec216b36d721d Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Wed, 2 Oct 2024 12:57:58 +0200 Subject: [PATCH] chore: align buying/releasing/setting ens usernames with the new sending flow Based on changes done in this PR https://github.com/status-im/status-go/pull/5807 we can simplify our client logic a lot. This results in the removal of many lines of code that are no longer needed Closes 2nd part of #16336 --- .../ens_usernames/controller.nim | 81 +---- .../ens_usernames/io_interface.nim | 33 +- .../profile_section/ens_usernames/module.nim | 257 +++------------ .../profile_section/ens_usernames/view.nim | 30 +- .../modules/main/profile_section/module.nim | 2 +- .../service/ens/dto/ens_username_dto.nim | 11 +- src/app_service/service/ens/service.nim | 309 ++++++------------ src/app_service/service/stickers/service.nim | 1 - src/backend/ens.nim | 36 +- .../Profile/stores/EnsUsernamesStore.qml | 29 -- .../Profile/views/EnsDetailsView.qml | 25 +- .../Profile/views/EnsSearchView.qml | 24 +- .../views/EnsTermsAndConditionsView.qml | 27 +- 13 files changed, 161 insertions(+), 704 deletions(-) diff --git a/src/app/modules/main/profile_section/ens_usernames/controller.nim b/src/app/modules/main/profile_section/ens_usernames/controller.nim index 7d4fabeebb..711ae32ba2 100644 --- a/src/app/modules/main/profile_section/ens_usernames/controller.nim +++ b/src/app/modules/main/profile_section/ens_usernames/controller.nim @@ -1,4 +1,4 @@ -import uuids, chronicles, json +import uuids, chronicles import io_interface import app/global/global_singleton @@ -8,16 +8,11 @@ import app_service/service/ens/service as ens_service import app_service/service/network/service as network_service import app_service/service/wallet_account/service as wallet_account_service import app_service/service/token/service as token_service -import app_service/service/keycard/service as keycard_service -from app_service/service/transaction/dto import PendingTransactionTypeDto -import app/modules/shared_modules/keycard_popup/io_interface as keycard_shared_module import app_service/service/network/network_item logScope: topics = "profile-section-ens-usernames-module-controller" -const UNIQUE_ENS_SECTION_TRANSACTION_MODULE_IDENTIFIER* = "EnsSection-TransactionModule" - type Controller* = ref object of RootObj delegate: io_interface.AccessInterface @@ -27,7 +22,6 @@ type networkService: network_service.Service walletAccountService: wallet_account_service.Service tokenService: token_service.Service - keycardService: keycard_service.Service connectionKeycardResponse: UUID proc newController*( @@ -35,7 +29,6 @@ proc newController*( settingsService: settings_service.Service, ensService: ens_service.Service, walletAccountService: wallet_account_service.Service, networkService: network_service.Service, tokenService: token_service.Service, - keycardService: keycard_service.Service ): Controller = result = Controller() result.delegate = delegate @@ -45,7 +38,6 @@ proc newController*( result.walletAccountService = walletAccountService result.networkService = networkService result.tokenService = tokenService - result.keycardService = keycardService proc delete*(self: Controller) = discard @@ -59,19 +51,17 @@ proc init*(self: Controller) = let args = EnsUsernameDetailsArgs(e) self.delegate.onDetailsForEnsUsername(args.chainId, args.ensUsername, args.address, args.pubkey, args.isStatus, args.expirationTime) + self.events.on(SIGNAL_ENS_TRANSACTION_SENT) do(e:Args): + let args = EnsTxResultArgs(e) + self.delegate.ensTransactionSent(args.transactionType, args.chainId, args.ensUsername, args.txHash, args.error) + self.events.on(SIGNAL_ENS_TRANSACTION_CONFIRMED) do(e:Args): let args = EnsTransactionArgs(e) - self.delegate.ensTransactionConfirmed(args.transactionType, args.ensUsername, args.transactionHash) + self.delegate.ensTransactionConfirmed(args.transactionType, args.ensUsername, args.txHash) self.events.on(SIGNAL_ENS_TRANSACTION_REVERTED) do(e:Args): let args = EnsTransactionArgs(e) - self.delegate.ensTransactionReverted(args.transactionType, args.ensUsername, args.transactionHash) - - self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args): - let args = SharedKeycarModuleArgs(e) - if args.uniqueIdentifier != UNIQUE_ENS_SECTION_TRANSACTION_MODULE_IDENTIFIER: - return - self.delegate.onKeypairAuthenticated(args.password, args.pin) + self.delegate.ensTransactionReverted(args.transactionType, args.ensUsername, args.txHash) proc getAppNetwork*(self: Controller): NetworkItem = return self.networkService.getAppNetwork() @@ -88,13 +78,6 @@ proc getAllMyEnsUsernames*(self: Controller, includePendingEnsUsernames: bool): proc fetchDetailsForEnsUsername*(self: Controller, chainId: int, ensUsername: string) = self.ensService.fetchDetailsForEnsUsername(chainId, ensUsername) -proc setPubKeyGasEstimate*(self: Controller, chainId: int, ensUsername: string, address: string): int = - return self.ensService.setPubKeyGasEstimate(chainId, ensUsername, address) - - -proc getSigningPhrase*(self: Controller): string = - return self.settingsService.getSigningPhrase() - proc addEnsUsername*(self: Controller, chainId: int, ensUsername: string): bool = return self.ensService.add(chainId, ensUsername) @@ -104,10 +87,6 @@ proc removeEnsUsername*(self: Controller, chainId: int, ensUsername: string): bo proc getPreferredEnsUsername*(self: Controller): string = return self.settingsService.getPreferredName() -proc releaseEnsEstimate*(self: Controller, chainId: int, ensUsername: string, address: string): int = - return self.ensService.releaseEnsEstimate(chainId, ensUsername, address) - - proc setPreferredName*(self: Controller, preferredName: string) = if(self.settingsService.savePreferredName(preferredName)): singletonInstance.userProfile.setPreferredName(preferredName) @@ -130,15 +109,9 @@ proc fixPreferredName*(self: Controller, ignoreCurrentValue: bool = false) = proc getEnsRegisteredAddress*(self: Controller): string = return self.ensService.getEnsRegisteredAddress() -proc registerEnsGasEstimate*(self: Controller, chainId: int, ensUsername: string, address: string): int = - return self.ensService.registerEnsGasEstimate(chainId, ensUsername, address) - proc getWalletDefaultAddress*(self: Controller): string = return self.walletAccountService.getWalletAccount(0).address -proc getKeypairByAccountAddress*(self: Controller, address: string): KeypairDto = - return self.walletAccountService.getKeypairByAccountAddress(address) - proc getCurrentCurrency*(self: Controller): string = return self.settingsService.getCurrency() @@ -146,42 +119,4 @@ proc getPriceBySymbol*(self: Controller, crypto: string): float64 = return self.tokenService.getPriceBySymbol(crypto) proc getStatusTokenKey*(self: Controller): string = - return self.tokenService.getStatusTokenKey() - -proc authenticate*(self: Controller, keyUid = "") = - let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_ENS_SECTION_TRANSACTION_MODULE_IDENTIFIER, - keyUid: keyUid) - self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data) - -proc prepareEnsTx*(self: Controller, txType: PendingTransactionTypeDto, chainId: int, ensUsername: string, address: string, - gas: string, gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, eip1559Enabled: bool): JsonNode = - return self.ensService.prepareEnsTx(txType, chainId, ensUsername, address, gas, gasPrice, maxPriorityFeePerGas, - maxFeePerGas, eip1559Enabled) - -proc signEnsTxLocally*(self: Controller, data, account, hashedPasssword: string): string = - return self.ensService.signEnsTxLocally(data, account, hashedPasssword) - -proc sendEnsTxWithSignatureAndWatch*(self: Controller, txType: PendingTransactionTypeDto, chainId: int, - txData: JsonNode, ensUsername: string, signature: string): EnsTxResultArgs = - return self.ensService.sendEnsTxWithSignatureAndWatch(txType, chainId, txData, ensUsername, signature) - -proc disconnectKeycardReponseSignal(self: Controller) = - self.events.disconnect(self.connectionKeycardResponse) - -proc connectKeycardReponseSignal(self: Controller) = - self.connectionKeycardResponse = self.events.onWithUUID(SIGNAL_KEYCARD_RESPONSE) do(e: Args): - let args = KeycardLibArgs(e) - self.disconnectKeycardReponseSignal() - let currentFlow = self.keycardService.getCurrentFlow() - if currentFlow != KCSFlowType.Sign: - self.delegate.onTransactionSigned("", KeycardEvent()) - return - self.delegate.onTransactionSigned(args.flowType, args.flowEvent) - -proc cancelCurrentFlow*(self: Controller) = - self.keycardService.cancelCurrentFlow() - -proc runSignFlow*(self: Controller, pin, bip44Path, txHash: string) = - self.cancelCurrentFlow() - self.connectKeycardReponseSignal() - self.keycardService.startSignFlow(bip44Path, txHash, pin) + return self.tokenService.getStatusTokenKey() \ No newline at end of file diff --git a/src/app/modules/main/profile_section/ens_usernames/io_interface.nim b/src/app/modules/main/profile_section/ens_usernames/io_interface.nim index 2c14b576af..ea5f59cc22 100644 --- a/src/app/modules/main/profile_section/ens_usernames/io_interface.nim +++ b/src/app/modules/main/profile_section/ens_usernames/io_interface.nim @@ -1,5 +1,4 @@ import NimQml -from app_service/service/keycard/service import KeycardEvent type AccessInterface* {.pure inheritable.} = ref object of RootObj @@ -23,6 +22,9 @@ method onDetailsForEnsUsername*(self: AccessInterface, chainId: int, ensUsername isStatus: bool, expirationTime: int) {.base.} = raise newException(ValueError, "No implementation available") +method ensTransactionSent*(self: AccessInterface, trxType: string, chainId: int, ensUsername: string, txHash: string, err: string) {.base.} = + raise newException(ValueError, "No implementation available") + method ensTransactionConfirmed*(self: AccessInterface, trxType: string, ensUsername: string, transactionHash: string) {.base.} = raise newException(ValueError, "No implementation available") @@ -42,36 +44,15 @@ method numOfPendingEnsUsernames*(self: AccessInterface): int {.base.} = method fetchDetailsForEnsUsername*(self: AccessInterface, chainId: int, ensUsername: string) {.base.} = raise newException(ValueError, "No implementation available") -method setPubKeyGasEstimate*(self: AccessInterface, chainId: int, ensUsername: string, address: string): int {.base.} = - raise newException(ValueError, "No implementation available") - -method authenticateAndSetPubKey*(self: AccessInterface, chainId: int, ensUsername: string, address: string, gas: string, gasPrice: string, - maxPriorityFeePerGas: string, maxFeePerGas: string, eip1559Enabled: bool) {.base.} = - raise newException(ValueError, "No implementation available") - method removeEnsUsername*(self: AccessInterface, chainId: int, ensUsername: string): bool {.base.} = raise newException(ValueError, "No implementation available") -method releaseEnsEstimate*(self: AccessInterface, chainId: int, ensUsername: string, address: string): int {.base.} = - raise newException(ValueError, "No implementation available") - -method authenticateAndReleaseEns*(self: AccessInterface, chainId: int, ensUsername: string, address: string, gas: string, gasPrice: string, - maxPriorityFeePerGas: string, maxFeePerGas: string, eip1559Enabled: bool) {.base.} = - raise newException(ValueError, "No implementation available") - method connectOwnedUsername*(self: AccessInterface, ensUsername: string, isStatus: bool) {.base.} = raise newException(ValueError, "No implementation available") method getEnsRegisteredAddress*(self: AccessInterface): string {.base.} = raise newException(ValueError, "No implementation available") -method registerEnsGasEstimate*(self: AccessInterface, chainId: int, ensUsername: string, address: string): int {.base.} = - raise newException(ValueError, "No implementation available") - -method authenticateAndRegisterEns*(self: AccessInterface, chainId: int, ensUsername: string, address: string, gas: string, gasPrice: string, - maxPriorityFeePerGas: string, maxFeePerGas: string, eip1559Enabled: bool) {.base.} = - raise newException(ValueError, "No implementation available") - method getWalletDefaultAddress*(self: AccessInterface): string {.base.} = raise newException(ValueError, "No implementation available") @@ -93,10 +74,4 @@ method getStatusTokenKey*(self: AccessInterface): string {.base.} = raise newException(ValueError, "No implementation available") method setPrefferedEnsUsername*(self: AccessInterface, ensUsername: string) {.base.} = - raise newException(ValueError, "No implementation available") - -method onKeypairAuthenticated*(self: AccessInterface, password: string, pin: string) {.base.} = - raise newException(ValueError, "No implementation available") - -method onTransactionSigned*(self: AccessInterface, keycardFlowType: string, keycardEvent: KeycardEvent) {.base.} = - raise newException(ValueError, "No implementation available") + raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/src/app/modules/main/profile_section/ens_usernames/module.nim b/src/app/modules/main/profile_section/ens_usernames/module.nim index d93ee46fbf..89bbd5e766 100644 --- a/src/app/modules/main/profile_section/ens_usernames/module.nim +++ b/src/app/modules/main/profile_section/ens_usernames/module.nim @@ -1,4 +1,4 @@ -import NimQml, json, stint, sequtils, strutils, sugar, stew/shims/strformat, parseutils, chronicles +import NimQml, json, stint, strutils, stew/shims/strformat, parseutils, chronicles import io_interface import ../io_interface as delegate_interface @@ -6,16 +6,12 @@ import view, controller, model import app/core/eventemitter import app_service/common/conversion as service_conversion -import app_service/common/utils as common_utils -import app_service/common/wallet_constants as common_wallet_constants import app_service/service/settings/service as settings_service import app_service/service/ens/service as ens_service import app_service/service/network/service as network_service import app_service/service/ens/utils as ens_utils import app_service/service/wallet_account/service as wallet_account_service import app_service/service/token/service as token_service -import app_service/service/keycard/service as keycard_service -import app_service/service/keycard/constants as keycard_constants from app_service/service/transaction/dto import PendingTransactionTypeDto export io_interface @@ -27,20 +23,6 @@ include app_service/common/json_utils const cancelledRequest* = "cancelled" -# Shouldn't be public ever, use only within this module. -type TmpSendEnsTransactionDetails = object - chainId: int - ensUsername: string - address: string - addressPath: string - gas: string - gasPrice: string - maxPriorityFeePerGas: string - maxFeePerGas: string - eip1559Enabled: bool - txType: PendingTransactionTypeDto - txData: JsonNode - type Module* = ref object of io_interface.AccessInterface delegate: delegate_interface.AccessInterface @@ -48,7 +30,6 @@ type viewVariant: QVariant controller: Controller moduleLoaded: bool - tmpSendEnsTransactionDetails: TmpSendEnsTransactionDetails events: EventEmitter proc newModule*( @@ -57,14 +38,13 @@ proc newModule*( walletAccountService: wallet_account_service.Service, networkService: network_service.Service, tokenService: token_service.Service, - keycardService: keycard_service.Service ): Module = result = Module() result.delegate = delegate result.view = view.newView(result) result.viewVariant = newQVariant(result.view) result.controller = controller.newController(result, events, settingsService, ensService, walletAccountService, - networkService, tokenService, keycardService) + networkService, tokenService) result.moduleLoaded = false result.events = events @@ -73,19 +53,11 @@ method delete*(self: Module) = self.viewVariant.delete self.controller.delete -proc clear(self: Module) = - self.tmpSendEnsTransactionDetails = TmpSendEnsTransactionDetails() - -proc finish(self: Module, chainId: int, txHash: string, error: string) = - self.clear() - self.view.emitTransactionWasSentSignal(chainId, txHash, error) - method load*(self: Module) = self.controller.init() - let signingPhrase = self.controller.getSigningPhrase() let link = self.controller.getAppNetwork().blockExplorerUrl & "/tx/" - self.view.load(link, signingPhrase) + self.view.load(link) self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e: Args): self.controller.fixPreferredName(true) @@ -131,59 +103,6 @@ method onDetailsForEnsUsername*(self: Module, chainId: int, ensUsername: string, expirationTime: int) = self.view.processObtainedEnsUsermesDetails(chainId, ensUsername, address, pubkey, isStatus, expirationTime) -method setPubKeyGasEstimate*(self: Module, chainId: int, ensUsername: string, address: string): int = - return self.controller.setPubKeyGasEstimate(chainId, ensUsername, address) - -# At this moment we're somehow assume that we're sending from the default wallet address. Need to change that! -# This function provides a possibility to authenticate sending from any address, not only from the wallet default one. -proc authenticateKeypairThatContainsObservedAddress*(self: Module) = - if self.tmpSendEnsTransactionDetails.address.len == 0: - error "tehre is no set address" - return - let kp = self.controller.getKeypairByAccountAddress(self.tmpSendEnsTransactionDetails.address) - if kp.migratedToKeycard(): - let accounts = kp.accounts.filter(acc => cmpIgnoreCase(acc.address, self.tmpSendEnsTransactionDetails.address) == 0) - if accounts.len != 1: - error "cannot resolve selected account to send from among known keypair accounts" - return - self.tmpSendEnsTransactionDetails.addressPath = accounts[0].path - self.controller.authenticate(kp.keyUid) - else: - self.controller.authenticate() - -method authenticateAndSetPubKey*(self: Module, chainId: int, ensUsername: string, address: string, gas: string, gasPrice: string, - maxPriorityFeePerGas: string, maxFeePerGas: string, eip1559Enabled: bool) = - - self.tmpSendEnsTransactionDetails.chainId = chainId - self.tmpSendEnsTransactionDetails.ensUsername = ensUsername - self.tmpSendEnsTransactionDetails.address = address - self.tmpSendEnsTransactionDetails.gas = gas - self.tmpSendEnsTransactionDetails.gasPrice = gasPrice - self.tmpSendEnsTransactionDetails.maxPriorityFeePerGas = maxPriorityFeePerGas - self.tmpSendEnsTransactionDetails.maxFeePerGas = maxFeePerGas - self.tmpSendEnsTransactionDetails.eip1559Enabled = eip1559Enabled - self.tmpSendEnsTransactionDetails.txType = PendingTransactionTypeDto.SetPubKey - - self.authenticateKeypairThatContainsObservedAddress() - -method releaseEnsEstimate*(self: Module, chainId: int, ensUsername: string, address: string): int = - return self.controller.releaseEnsEstimate(chainId, ensUsername, address) - -method authenticateAndReleaseEns*(self: Module, chainId: int, ensUsername: string, address: string, gas: string, gasPrice: string, - maxPriorityFeePerGas: string, maxFeePerGas: string, eip1559Enabled: bool) = - - self.tmpSendEnsTransactionDetails.chainId = chainId - self.tmpSendEnsTransactionDetails.ensUsername = ensUsername - self.tmpSendEnsTransactionDetails.address = address - self.tmpSendEnsTransactionDetails.gas = gas - self.tmpSendEnsTransactionDetails.gasPrice = gasPrice - self.tmpSendEnsTransactionDetails.maxPriorityFeePerGas = maxPriorityFeePerGas - self.tmpSendEnsTransactionDetails.maxFeePerGas = maxFeePerGas - self.tmpSendEnsTransactionDetails.eip1559Enabled = eip1559Enabled - self.tmpSendEnsTransactionDetails.txType = PendingTransactionTypeDto.ReleaseENS - - self.authenticateKeypairThatContainsObservedAddress() - proc onEnsUsernameRemoved(self: Module, chainId: int, ensUsername: string) = if (self.controller.getPreferredEnsUsername() == ensUsername): self.controller.fixPreferredName(true) @@ -196,56 +115,56 @@ method removeEnsUsername*(self: Module, chainId: int, ensUsername: string): bool self.onEnsUsernameRemoved(chainId, ensUsername) return true -proc formatUsername(self: Module, ensUsername: string, isStatus: bool): string = - result = ensUsername - if isStatus: - result = ensUsername & ens_utils.STATUS_DOMAIN - method connectOwnedUsername*(self: Module, ensUsername: string, isStatus: bool) = let chainId = self.controller.getAppNetwork().chainId - var ensUsername = self.formatUsername(ensUsername, isStatus) - if(not self.controller.addEnsUsername(chainId, ensUsername)): + let finalEnsUsername = ens_utils.addDomain(ensUsername) + if(not self.controller.addEnsUsername(chainId, finalEnsUsername)): info "an error occurred saving ens username", methodName="connectOwnedUsername" return - self.controller.fixPreferredName() - self.view.model().addItem(Item(chainId: chainId, ensUsername: ensUsername, isPending: false)) + self.view.model().addItem(Item(chainId: chainId, ensUsername: finalEnsUsername, isPending: false)) + +method ensTransactionSent*(self: Module, trxType: string, chainId: int, ensUsername: string, txHash: string, err: string) = + var finalError = err + defer: + self.view.emitTransactionWasSentSignal(chainId, txHash, finalError) + if (err.len != 0): + error "sending ens tx failed", errMsg=err, methodName="ensTransactionSent" + return + let finalEnsUsername = ens_utils.addDomain(ensUsername) + case trxType: + of $SetPubKey: + let item = Item(chainId: chainId, ensUsername: finalEnsUsername, isPending: true) + self.view.model().addItem(item) + of $ReleaseENS: + self.onEnsUsernameRemoved(chainId, finalEnsUsername) + of $RegisterENS: + let item = Item(chainId: chainId, ensUsername: finalEnsUsername, isPending: true) + self.controller.fixPreferredName() + self.view.model().addItem(item) + else: + finalError = "unknown ens action" + error "sending ens tx failed", errMsg=err, methodName="ensTransactionSent" method ensTransactionConfirmed*(self: Module, trxType: string, ensUsername: string, transactionHash: string) = let chainId = self.controller.getAppNetwork().chainId self.controller.fixPreferredName() - if(self.view.model().containsEnsUsername(chainId, ensUsername)): - self.view.model().updatePendingStatus(chainId, ensUsername, false) + let finalEnsUsername = ens_utils.addDomain(ensUsername) + if(self.view.model().containsEnsUsername(chainId, finalEnsUsername)): + self.view.model().updatePendingStatus(chainId, finalEnsUsername, false) else: - self.view.model().addItem(Item(chainId: chainId, ensUsername: ensUsername, isPending: false)) - self.view.emitTransactionCompletedSignal(true, transactionHash, ensUsername, trxType) + self.view.model().addItem(Item(chainId: chainId, ensUsername: finalEnsUsername, isPending: false)) + self.view.emitTransactionCompletedSignal(true, transactionHash, finalEnsUsername, trxType) method ensTransactionReverted*(self: Module, trxType: string, ensUsername: string, transactionHash: string) = let chainId = self.controller.getAppNetwork().chainId - self.view.model().removeItemByEnsUsername(chainId, ensUsername) - self.view.emitTransactionCompletedSignal(false, transactionHash, ensUsername, trxType) + let finalEnsUsername = ens_utils.addDomain(ensUsername) + self.view.model().removeItemByEnsUsername(chainId, finalEnsUsername) + self.view.emitTransactionCompletedSignal(false, transactionHash, finalEnsUsername, trxType) method getEnsRegisteredAddress*(self: Module): string = return self.controller.getEnsRegisteredAddress() -method registerEnsGasEstimate*(self: Module, chainId: int, ensUsername: string, address: string): int = - return self.controller.registerEnsGasEstimate(chainId, ensUsername, address) - -method authenticateAndRegisterEns*(self: Module, chainId: int, ensUsername: string, address: string, gas: string, gasPrice: string, - maxPriorityFeePerGas: string, maxFeePerGas: string, eip1559Enabled: bool) = - - self.tmpSendEnsTransactionDetails.chainId = chainId - self.tmpSendEnsTransactionDetails.ensUsername = ensUsername - self.tmpSendEnsTransactionDetails.address = address - self.tmpSendEnsTransactionDetails.gas = gas - self.tmpSendEnsTransactionDetails.gasPrice = gasPrice - self.tmpSendEnsTransactionDetails.maxPriorityFeePerGas = maxPriorityFeePerGas - self.tmpSendEnsTransactionDetails.maxFeePerGas = maxFeePerGas - self.tmpSendEnsTransactionDetails.eip1559Enabled = eip1559Enabled - self.tmpSendEnsTransactionDetails.txType = PendingTransactionTypeDto.RegisterENS - - self.authenticateKeypairThatContainsObservedAddress() - method getWalletDefaultAddress*(self: Module): string = return self.controller.getWalletDefaultAddress() @@ -305,106 +224,4 @@ method getStatusTokenKey*(self: Module): string = return self.controller.getStatusTokenKey() method setPrefferedEnsUsername*(self: Module, ensUsername: string) = - self.controller.setPreferredName(ensUsername) - -proc sendEnsTxWithSignatureAndWatch(self: Module, signature: string) = - let response = self.controller.sendEnsTxWithSignatureAndWatch( - self.tmpSendEnsTransactionDetails.txType, - self.tmpSendEnsTransactionDetails.chainId, - self.tmpSendEnsTransactionDetails.txData, - self.tmpSendEnsTransactionDetails.ensUsername, - signature - ) - - if not response.error.isEmptyOrWhitespace(): - error "sending ens tx failed", errMsg=response.error, methodName="sendEnsTxWithSignatureAndWatch" - self.finish(chainId = 0, txHash = "", error = response.error) - return - - if self.tmpSendEnsTransactionDetails.txType == PendingTransactionTypeDto.SetPubKey: - let item = Item(chainId: self.tmpSendEnsTransactionDetails.chainId, - ensUsername: self.tmpSendEnsTransactionDetails.ensUsername, - isPending: true) - self.view.model().addItem(item) - elif self.tmpSendEnsTransactionDetails.txType == PendingTransactionTypeDto.ReleaseENS: - self.onEnsUsernameRemoved(self.tmpSendEnsTransactionDetails.chainId, self.tmpSendEnsTransactionDetails.ensUsername) - elif self.tmpSendEnsTransactionDetails.txType == PendingTransactionTypeDto.RegisterENS: - let ensUsername = self.formatUsername(self.tmpSendEnsTransactionDetails.ensUsername, true) - let item = Item(chainId: self.tmpSendEnsTransactionDetails.chainId, ensUsername: ensUsername, isPending: true) - self.controller.fixPreferredName() - self.view.model().addItem(item) - else: - error "unknown ens action", methodName="sendEnsTxWithSignatureAndWatch" - self.finish(chainId = 0, txHash = "", error = "unknown ens action") - return - - self.finish(response.chainId, response.txHash, response.error) - -method onKeypairAuthenticated*(self: Module, password: string, pin: string) = - if password.len == 0: - self.finish(chainId = 0, txHash = "", error = cancelledRequest) - return - - let txDataJson = self.controller.prepareEnsTx( - self.tmpSendEnsTransactionDetails.txType, - self.tmpSendEnsTransactionDetails.chainId, - self.tmpSendEnsTransactionDetails.ensUsername, - self.tmpSendEnsTransactionDetails.address, - self.tmpSendEnsTransactionDetails.gas, - self.tmpSendEnsTransactionDetails.gasPrice, - self.tmpSendEnsTransactionDetails.maxPriorityFeePerGas, - self.tmpSendEnsTransactionDetails.maxFeePerGas, - self.tmpSendEnsTransactionDetails.eip1559Enabled, - ) - - if txDataJson.isNil or - txDataJson.kind != JsonNodeKind.JObject or - not txDataJson.hasKey("txArgs") or - not txDataJson.hasKey("messageToSign"): - let errMsg = "unexpected response format preparing tx ens username" - error "error", msg=errMsg, methodName="onKeypairAuthenticated" - self.finish(chainId = 0, txHash = "", error = errMsg) - return - - var txToBeSigned = txDataJson["messageToSign"].getStr - if txToBeSigned.len != common_wallet_constants.TX_HASH_LEN_WITH_PREFIX: - let errMsg = "unexpected tx hash length" - error "error", msg=errMsg, methodName="onKeypairAuthenticated" - self.finish(chainId = 0, txHash = "", error = errMsg) - return - - self.tmpSendEnsTransactionDetails.txData = txDataJson["txArgs"] - - if txDataJson.hasKey("signOnKeycard") and txDataJson["signOnKeycard"].getBool: - if pin.len != PINLengthForStatusApp: - let errMsg = "cannot proceed with keycard signing, unexpected pin" - error "error", msg=errMsg, methodName="onKeypairAuthenticated" - self.finish(chainId = 0, txHash = "", error = errMsg) - return - var txForKcFlow = txToBeSigned - if txForKcFlow.startsWith("0x"): - txForKcFlow = txForKcFlow[2..^1] - self.controller.runSignFlow(pin, self.tmpSendEnsTransactionDetails.addressPath, txForKcFlow) - return - - var finalPassword = password - if pin.len == 0: - finalPassword = common_utils.hashPassword(password) - - let signature = self.controller.signEnsTxLocally(txToBeSigned, self.tmpSendEnsTransactionDetails.address, finalPassword) - if signature.len == 0: - let errMsg = "couldn't sign tx locally" - error "error", msg=errMsg, methodName="onKeypairAuthenticated" - self.finish(chainId = 0, txHash = "", error = errMsg) - return - - self.sendEnsTxWithSignatureAndWatch(signature) - -method onTransactionSigned*(self: Module, keycardFlowType: string, keycardEvent: KeycardEvent) = - if keycardFlowType != keycard_constants.ResponseTypeValueKeycardFlowResult: - let errMsg = "unexpected error while keycard signing transaction" - error "error", msg=errMsg, methodName="onTransactionSigned" - self.finish(chainId = 0, txHash = "", error = errMsg) - return - let signature = "0x" & keycardEvent.txSignature.r & keycardEvent.txSignature.s & keycardEvent.txSignature.v - self.sendEnsTxWithSignatureAndWatch(signature) + self.controller.setPreferredName(ensUsername) \ No newline at end of file diff --git a/src/app/modules/main/profile_section/ens_usernames/view.nim b/src/app/modules/main/profile_section/ens_usernames/view.nim index 2ffffae72d..61389934a4 100644 --- a/src/app/modules/main/profile_section/ens_usernames/view.nim +++ b/src/app/modules/main/profile_section/ens_usernames/view.nim @@ -1,7 +1,7 @@ import NimQml import io_interface import model -from ../../../../../app_service/service/ens/utils import ENS_REGISTRY +from app_service/service/ens/utils import ENS_REGISTRY QtObject: type @@ -10,7 +10,6 @@ QtObject: model: Model modelVariant: QVariant etherscanLink: string - signingPhrase: string proc delete*(self: View) = self.model.delete @@ -24,9 +23,8 @@ QtObject: result.modelVariant = newQVariant(result.model) result.delegate = delegate - proc load*(self: View, link: string, signingPhrase: string) = + proc load*(self: View, link: string) = self.etherscanLink = link - self.signingPhrase = signingPhrase self.delegate.viewDidLoad() proc model*(self: View): Model = @@ -68,19 +66,9 @@ QtObject: proc emitTransactionWasSentSignal*(self: View, chainId: int, txHash: string, error: string) = self.transactionWasSent(chainId, txHash, error) - proc setPubKeyGasEstimate*(self: View, chainId: int, ensUsername: string, address: string): int {.slot.} = - return self.delegate.setPubKeyGasEstimate(chainId, ensUsername, address) - - proc authenticateAndSetPubKey*(self: View, chainId: int, ensUsername: string, address: string, gas: string, gasPrice: string, - maxPriorityFeePerGas: string, maxFeePerGas: string, eip1559Enabled: bool) {.slot.} = - self.delegate.authenticateAndSetPubKey(chainId, ensUsername, address, gas, gasPrice, maxPriorityFeePerGas, maxFeePerGas, eip1559Enabled) - proc getEtherscanLink*(self: View): string {.slot.} = return self.etherscanLink - proc getSigningPhrase*(self: View): string {.slot.} = - return self.signingPhrase - proc usernameConfirmed(self: View, username: string) {.signal.} proc emitUsernameConfirmedSignal*(self: View, ensUsername: string) = self.usernameConfirmed(ensUsername) @@ -92,26 +80,12 @@ QtObject: proc removeEnsUsername*(self: View, chainId: int, ensUsername: string): bool {.slot.} = return self.delegate.removeEnsUsername(chainId, ensUsername) - proc releaseEnsEstimate*(self: View, chainId: int, ensUsername: string, address: string): int {.slot.} = - return self.delegate.releaseEnsEstimate(chainId, ensUsername, address) - - proc authenticateAndReleaseEns*(self: View, chainId: int, ensUsername: string, address: string, gas: string, gasPrice: string, - maxPriorityFeePerGas: string, maxFeePerGas: string, eip1559Enabled: bool) {.slot.} = - self.delegate.authenticateAndReleaseEns(chainId, ensUsername, address, gas, gasPrice, maxPriorityFeePerGas, maxFeePerGas, eip1559Enabled) - proc connectOwnedUsername*(self: View, ensUsername: string, isStatus: bool) {.slot.} = self.delegate.connectOwnedUsername(ensUsername, isStatus) proc getEnsRegisteredAddress*(self: View): string {.slot.} = return self.delegate.getEnsRegisteredAddress() - proc registerEnsGasEstimate*(self: View, chainId: int, ensUsername: string, address: string): int {.slot.} = - return self.delegate.registerEnsGasEstimate(chainId, ensUsername, address) - - proc authenticateAndRegisterEns*(self: View, chainId: int, ensUsername: string, address: string, gas: string, gasPrice: string, - maxPriorityFeePerGas: string, maxFeePerGas: string, eip1559Enabled: bool) {.slot.} = - self.delegate.authenticateAndRegisterEns(chainId, ensUsername, address, gas, gasPrice, maxPriorityFeePerGas, maxFeePerGas, eip1559Enabled) - proc getWalletDefaultAddress*(self: View): string {.slot.} = return self.delegate.getWalletDefaultAddress() diff --git a/src/app/modules/main/profile_section/module.nim b/src/app/modules/main/profile_section/module.nim index 93a5862594..700607c404 100644 --- a/src/app/modules/main/profile_section/module.nim +++ b/src/app/modules/main/profile_section/module.nim @@ -107,7 +107,7 @@ proc newModule*(delegate: delegate_interface.AccessInterface, result.wakuModule = waku_module.newModule(result, events, settingsService, nodeConfigurationService) result.notificationsModule = notifications_module.newModule(result, events, settingsService, chatService, contactsService, communityService) result.ensUsernamesModule = ens_usernames_module.newModule( - result, events, settingsService, ensService, walletAccountService, networkService, tokenService, keycardService + result, events, settingsService, ensService, walletAccountService, networkService, tokenService ) result.communitiesModule = communities_module.newModule(result, communityService) result.keycardModule = keycard_module.newModule(result, events, keycardService, settingsService, networkService, diff --git a/src/app_service/service/ens/dto/ens_username_dto.nim b/src/app_service/service/ens/dto/ens_username_dto.nim index 58b7c43156..8f4b3ceaf6 100644 --- a/src/app_service/service/ens/dto/ens_username_dto.nim +++ b/src/app_service/service/ens/dto/ens_username_dto.nim @@ -1,11 +1,15 @@ {.used.} import json, stew/shims/strformat, hashes -include ../../../common/json_utils +import app_service/service/transaction/dto +include app_service/common/json_utils type EnsUsernameDto* = ref object chainId*: int username*: string + txType*: PendingTransactionTypeDto + txHash*: string + txStatus*: string proc `==`*(l, r: EnsUsernameDto): bool = return l.chainId == r.chainid and l.username == r.username @@ -13,7 +17,10 @@ proc `==`*(l, r: EnsUsernameDto): bool = proc `$`*(self: EnsUsernameDto): string = result = fmt"""ContactDto( chainId: {self.chainId}, - username: {self.username} + username: {self.username}, + txType: {self.txType}, + txHash: {self.txHash}, + txStatus: {self.txStatus} )""" proc hash*(dto: EnsUsernameDto): Hash = diff --git a/src/app_service/service/ens/service.nim b/src/app_service/service/ens/service.nim index 5071e9af66..6312505ae4 100644 --- a/src/app_service/service/ens/service.nim +++ b/src/app_service/service/ens/service.nim @@ -1,5 +1,5 @@ -import NimQml, Tables, sets, json, sequtils, strutils, stint, chronicles -import web3/ethtypes, web3/conversions, stew/byteutils, nimcrypto, json_serialization +import NimQml, Tables, json, sequtils, strutils, stint, chronicles +import web3/ethtypes, stew/byteutils, nimcrypto, json_serialization import app/core/eventemitter import app/core/tasks/[qt, threadpool] @@ -7,9 +7,6 @@ import app/core/tasks/[qt, threadpool] import app/global/global_singleton import backend/ens as status_ens import backend/backend as status_go_backend -import backend/wallet as status_wallet - -import app_service/common/conversion as common_conversion import utils as ens_utils import app_service/service/settings/service as settings_service @@ -17,10 +14,7 @@ import app_service/service/wallet_account/service as wallet_account_service import app_service/service/transaction/service as transaction_service import app_service/service/network/service as network_service import app_service/service/token/service as token_service -import app_service/service/eth/utils as status_utils import app_service/service/eth/dto/coder -import app_service/service/eth/dto/transaction -import app_service/common/wallet_constants import dto/ens_username_dto export ens_username_dto @@ -55,18 +49,21 @@ type gasPrice*: string EnsTransactionArgs* = ref object of Args - transactionHash*: string + txHash*: string ensUsername*: string transactionType*: string EnsTxResultArgs* = ref object of Args + transactionType*: string chainId*: int + ensUsername*: string txHash*: string error*: string # Signals which may be emitted by this service: const SIGNAL_ENS_USERNAME_AVAILABILITY_CHECKED* = "ensUsernameAvailabilityChecked" const SIGNAL_ENS_USERNAME_DETAILS_FETCHED* = "ensUsernameDetailsFetched" +const SIGNAL_ENS_TRANSACTION_SENT* = "ensTransactionSent" const SIGNAL_ENS_TRANSACTION_CONFIRMED* = "ensTransactionConfirmed" const SIGNAL_ENS_TRANSACTION_REVERTED* = "ensTransactionReverted" @@ -75,13 +72,17 @@ QtObject: Service* = ref object of QObject events: EventEmitter threadpool: ThreadPool - pendingEnsUsernames*: HashSet[EnsUsernameDto] + pendingEnsUsernames*: Table[string, EnsUsernameDto] settingsService: settings_service.Service walletAccountService: wallet_account_service.Service transactionService: transaction_service.Service networkService: network_service.Service tokenService: token_service.Service + ## Forward declarations + proc add*(self: Service, chainId: int, username: string): bool + proc remove*(self: Service, chainId: int, username: string): bool + proc delete*(self: Service) = self.QObject.delete @@ -98,6 +99,7 @@ QtObject: result.QObject.setup result.events = events result.threadpool = threadpool + result.pendingEnsUsernames = initTable[string, EnsUsernameDto]() result.settingsService = settingsService result.walletAccountService = walletAccountService result.transactionService = transactionService @@ -107,43 +109,99 @@ QtObject: proc getChainId(self: Service): int = return self.networkService.getAppNetwork().chainId - proc confirmTransaction(self: Service, trxType: string, ensUsername: string, transactionHash: string) = - let dto = EnsUsernameDto(chainId: self.getChainId(), username: ensUsername) - let data = EnsTransactionArgs(transactionHash: transactionHash, ensUsername: ensUsername, transactionType: $trxType) - self.pendingEnsUsernames.excl(dto) - self.events.emit(SIGNAL_ENS_TRANSACTION_CONFIRMED, data) + proc makeKey(username: string, chainId: int): string = + return $username & "-" & $chainId - proc revertTransaction(self: Service, trxType: string, ensUsername: string, transactionHash: string) = - let dto = EnsUsernameDto(chainId: self.getChainId(), username: ensUsername) - let data = EnsTransactionArgs(transactionHash: transactionHash, ensUsername: ensUsername, transactionType: $trxType) - self.pendingEnsUsernames.excl(dto) - self.events.emit(SIGNAL_ENS_TRANSACTION_REVERTED, data) + proc formatUsername(self: Service, username: string, isStatus: bool): string = + result = username + if isStatus: + result = result & ens_utils.STATUS_DOMAIN + + proc updateEnsUsernames(self: Service, chainId: int, transactionHash: string, status: string) = + if status == TxStatusPending: + return + + # find ens username by transactionHash + var ensDto = EnsUsernameDto() + for _, value in self.pendingEnsUsernames.pairs: + if value.txHash == transactionHash: + ensDto = value + break + + if ensDto.username.len == 0: + error "Error updating ens username status", message = "no ens username found for transactionHash: " & transactionHash + return + + let key = makeKey(ensDto.username, chainId) + if status == TxStatusSuccess: + self.pendingEnsUsernames[key].txStatus = TxStatusSuccess + let data = EnsTransactionArgs(txHash: transactionHash, ensUsername: ensDto.username, transactionType: $ensDto.txType) + self.events.emit(SIGNAL_ENS_TRANSACTION_CONFIRMED, data) + return + if status == TxStatusFailed: + self.pendingEnsUsernames[key].txStatus = TxStatusFailed + let data = EnsTransactionArgs(txHash: transactionHash, ensUsername: ensDto.username, transactionType: $ensDto.txType) + self.events.emit(SIGNAL_ENS_TRANSACTION_REVERTED, data) + return + error "Error updating ens username status", message = "unknown status: " & status proc doConnect(self: Service) = - self.events.on(PendingTransactionTypeDto.RegisterENS.event) do(e: Args): - var receivedData = TransactionMinedArgs(e) - if receivedData.success: - self.confirmTransaction($PendingTransactionTypeDto.RegisterENS, receivedData.data, receivedData.transactionHash) - else: - self.revertTransaction($PendingTransactionTypeDto.RegisterENS, receivedData.data, receivedData.transactionHash) + self.events.on(SIGNAL_TRANSACTION_SENT) do(e:Args): + let args = TransactionSentArgs(e) + if args.txType != SendType.ENSRegister and args.txType != SendType.ENSSetPubKey and args.txType != SendType.ENSRelease: + return - self.events.on(PendingTransactionTypeDto.SetPubKey.event) do(e: Args): - var receivedData = TransactionMinedArgs(e) - if receivedData.success: - self.confirmTransaction($PendingTransactionTypeDto.SetPubKey, receivedData.data, receivedData.transactionHash) - else: - self.revertTransaction($PendingTransactionTypeDto.SetPubKey, receivedData.data, receivedData.transactionHash) + var err = args.error + var dto = EnsUsernameDto( + chainId: args.chainId, + username: args.username, + txHash: args.txHash, + txStatus: TxStatusPending + ) + + if args.txType == SendType.ENSRegister: + dto.txType = RegisterENS + if err.len == 0: + let ensUsernameFinal = self.formatUsername(args.username, true) + if not self.add(args.chainId, ensUsernameFinal): + err = "failed to add ens username" + error "error", err + elif args.txType == SendType.ENSSetPubKey: + dto.txType = SetPubKey + if err.len == 0: + let usernameWithDomain = args.username.addDomain() + if not self.add(args.chainId, usernameWithDomain): + err = "failed to set ens username" + error "error", err + elif args.txType == SendType.ENSRelease: + dto.txType = ReleaseENS + if err.len == 0: + let ensUsernameFinal = self.formatUsername(args.username, true) + if not self.remove(args.chainId, ensUsernameFinal): + err = "failed to remove ens username" + error "error", err + + self.pendingEnsUsernames[makeKey(dto.username, args.chainId)] = dto + + let data = EnsTxResultArgs(transactionType: $dto.txType, chainId: args.chainId, ensUsername: args.username, txHash: args.txHash, error: err) + self.events.emit(SIGNAL_ENS_TRANSACTION_SENT, data) + + self.events.on(SIGNAL_TRANSACTION_STATUS_CHANGED) do(e:Args): + let args = TransactionStatusArgs(e) + self.updateEnsUsernames(args.data.chainId, args.data.hash, args.data.status) proc init*(self: Service) = self.doConnect() for trx in self.transactionService.getPendingTransactions(): - if trx.typeValue == $PendingTransactionTypeDto.RegisterENS or trx.typeValue == $PendingTransactionTypeDto.SetPubKey: - let dto = EnsUsernameDto(chainId: trx.chainId, username: trx.additionalData) - self.pendingEnsUsernames.incl(dto) + if trx.typeValue == $PendingTransactionTypeDto.RegisterENS or + trx.typeValue == $PendingTransactionTypeDto.SetPubKey or + trx.typeValue == $PendingTransactionTypeDto.ReleaseENS: + let dto = EnsUsernameDto(chainId: trx.chainId, username: trx.additionalData) + self.pendingEnsUsernames[makeKey(dto.username, dto.chainId)] = dto proc getMyPendingEnsUsernames*(self: Service): seq[EnsUsernameDto] = - for i in self.pendingEnsUsernames.items: + for i in self.pendingEnsUsernames.values: result.add(i) proc getAllMyEnsUsernames*(self: Service, includePending: bool): seq[EnsUsernameDto] = @@ -212,11 +270,6 @@ QtObject: # notify view, this is important self.events.emit(SIGNAL_ENS_USERNAME_AVAILABILITY_CHECKED, EnsUsernameAvailabilityArgs()) - proc formatUsername(self: Service, username: string, isStatus: bool): string = - result = username - if isStatus: - result = result & ens_utils.STATUS_DOMAIN - proc checkEnsUsernameAvailability*(self: Service, ensUsername: string, isStatus: bool) = let registeredEnsUsernames = self.getAllMyEnsUsernames(true) let dto = EnsUsernameDto(chainId: self.getChainId(), @@ -280,185 +333,13 @@ QtObject: proc extractCoordinates(self: Service, pubkey: string):tuple[x: string, y:string] = result = ("0x" & pubkey[4..67], "0x" & pubkey[68..131]) - proc setPubKeyGasEstimate*(self: Service, chainId: int, ensUsername: string, address: string): int = - try: - let txData = ens_utils.buildTransaction(parseAddress(address), 0.u256) - let resp = status_ens.setPubKeyEstimate(chainId, %txData, ensUsername, - singletonInstance.userProfile.getPubKey()) - result = resp.result.getInt - except Exception as e: - result = 80000 - error "error occurred", procName="setPubKeyGasEstimate", msg = e.msg - - proc releaseEnsEstimate*(self: Service, chainId: int, ensUsername: string, address: string): int = - try: - let txData = ens_utils.buildTransaction(parseAddress(address), 0.u256) - var userNameNoDomain = ensUsername - if ensUsername.endsWith(ens_utils.STATUS_DOMAIN): - userNameNoDomain = ensUsername.replace(ens_utils.STATUS_DOMAIN, "") - - let resp = status_ens.releaseEstimate(chainId, %txData, userNameNoDomain) - result = resp.result.getInt - except Exception as e: - error "error occurred", procName="releaseEnsEstimate", msg = e.msg - result = 100000 - proc getEnsRegisteredAddress*(self: Service): string = return status_ens.getRegistrarAddress(self.getChainId()).result.getStr - proc registerENSGasEstimate*(self: Service, chainId: int, ensUsername: string, address: string): int = - try: - let txData = ens_utils.buildTransaction(parseAddress(address), 0.u256) - let resp = status_ens.registerEstimate(chainId, %txData, ensUsername, - singletonInstance.userProfile.getPubKey()) - result = resp.result.getInt - except Exception as e: - result = 380000 - error "error occurred", procName="registerENSGasEstimate", msg = e.msg - proc resourceUrl*(self: Service, username: string): (string, string, string) = try: let response = status_ens.resourceURL(self.getChainId(), username) return (response.result{"Scheme"}.getStr, response.result{"Host"}.getStr, response.result{"Path"}.getStr) except Exception as e: error "Error getting ENS resourceUrl", username=username, exception=e.msg - raise - - proc prepareEnsTx*(self: Service, txType: PendingTransactionTypeDto, chainId: int, ensUsername: string, address: string, - gas: string, gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, eip1559Enabled: bool): JsonNode = - try: - var prepareTxResponse: RpcResponse[JsonNode] - let txData = ens_utils.buildTransaction(parseAddress(address), 0.u256, gas, gasPrice, eip1559Enabled, - maxPriorityFeePerGas, maxFeePerGas) - if txType == PendingTransactionTypeDto.SetPubKey: - prepareTxResponse = status_ens.prepareTxForSetPubKey(chainId, %txData, ensUsername.addDomain(), - singletonInstance.userProfile.getPubKey()) - elif txType == PendingTransactionTypeDto.RegisterENS: - prepareTxResponse = status_ens.prepareTxForRegisterEnsUsername(chainId, %txData, ensUsername, - singletonInstance.userProfile.getPubKey()) - elif txType == PendingTransactionTypeDto.ReleaseENS: - var userNameNoDomain = ensUsername - if ensUsername.endsWith(ens_utils.STATUS_DOMAIN): - userNameNoDomain = ensUsername.replace(ens_utils.STATUS_DOMAIN, "") - prepareTxResponse = status_ens.prepareTxForReleaseEnsUsername(chainId, %txData, userNameNoDomain) - else: - error "Unknown action", procName="prepareEnsTx" - - if not prepareTxResponse.error.isNil: - error "error occurred", procName="prepareEnsTx", msg = prepareTxResponse.error.message - return - - prepareTxResponse.result["gas"] = %* (if gas.isEmptyOrWhitespace: Quantity.none else: Quantity(cast[uint64](parseFloat(gas).toUInt64)).some) - if eip1559Enabled: - let maxPriorityFeePerGasFinal = if maxPriorityFeePerGas.isEmptyOrWhitespace: Uint256.none else: gwei2Wei(parseFloat(maxPriorityFeePerGas)).some - let maxFeePerGasFinal = if maxFeePerGas.isEmptyOrWhitespace: Uint256.none else: gwei2Wei(parseFloat(maxFeePerGas)).some - prepareTxResponse.result["maxPriorityFeePerGas"] = %* ("0x" & maxPriorityFeePerGasFinal.unsafeGet.toHex) - prepareTxResponse.result["maxFeePerGas"] = %* ("0x" & maxFeePerGasFinal.unsafeGet.toHex) - else: - let gasPriceFinal = if gasPrice.isEmptyOrWhitespace: int.none else: gwei2Wei(parseFloat(gasPrice)).truncate(int).some - prepareTxResponse.result["gasPrice"] = %* ("0x" & gasPriceFinal.unsafeGet.toHex.stripLeadingZeros) - - var buildTxResponse: JsonNode - let err = status_wallet.buildTransaction(buildTxResponse, chainId, $prepareTxResponse.result) - if err.len > 0: - error "error occurred", procName="prepareEnsTx", msg = err - return - - return buildTxResponse - except Exception as e: - error "error occurred", procName="prepareEnsTx", msg = e.msg - - proc signEnsTxLocally*(self: Service, data, account, hashedPasssword: string): string = - try: - var response: JsonNode - let err = status_wallet.signMessage(response, data, account, hashedPasssword) - if err.len > 0 or response.isNil: - error "error occurred", procName="signEnsTxLocally", msg = err - return - return response.getStr() - except Exception as e: - error "error occurred", procName="signEnsTxLocally", msg = e.msg - - proc sendEnsTxWithSignatureAndWatch*(self: Service, txType: PendingTransactionTypeDto, chainId: int, - txData: JsonNode, ensUsername: string, signature: string): EnsTxResultArgs = - result = EnsTxResultArgs(chainId: chainId) - try: - if txData.isNil: - result.error = "txData is nil" - error "error occurred", procName="sendEnsTxWithSignatureAndWatch", msg = result.error - return - if not txData.hasKey("from") or txData["from"].getStr().len == 0: - result.error = "from address is empty" - error "error occurred", procName="sendEnsTxWithSignatureAndWatch", msg = result.error - return - if not txData.hasKey("to") or txData["to"].getStr().len == 0: - result.error = "to address is empty" - error "error occurred", procName="sendEnsTxWithSignatureAndWatch", msg = result.error - return - if txType != PendingTransactionTypeDto.SetPubKey and - txType != PendingTransactionTypeDto.RegisterENS and - txType != PendingTransactionTypeDto.ReleaseENS: - result.error = "invalid tx type" - error "error occurred", procName="sendEnsTxWithSignatureAndWatch", msg = result.error - return - - var finalSignature = signature - if finalSignature.startsWith("0x"): - finalSignature = finalSignature[2..^1] - - var txResponse: JsonNode - let err = status_wallet.sendTransactionWithSignature(txResponse, chainId, $txType, $txData, finalSignature) - if err.len > 0 or txResponse.isNil: - result.error = err - error "error occurred", procName="sendEnsTxWithSignatureAndWatch", msg = result.error - return - - let - transactionHash = txResponse.getStr() - fromAddress = txData["from"].getStr() - toAddress = txData["to"].getStr() - - if txType == PendingTransactionTypeDto.SetPubKey: - let usernameWithDomain = ensUsername.addDomain() - if not self.add(chainId, usernameWithDomain): - result.error = "failed to add ens username" - error "error occurred", procName="sendEnsTxWithSignatureAndWatch", msg = result.error - return - let resolverAddress = status_ens.resolver(chainId, usernameWithDomain).result.getStr - self.transactionService.watchTransaction(transactionHash, fromAddress, resolverAddress, $txType, - ensUsername, chainId) - let dto = EnsUsernameDto(chainId: chainId, username: ensUsername) - self.pendingEnsUsernames.incl(dto) - elif txType == PendingTransactionTypeDto.RegisterENS: - var sntContract: string = "" - if self.settingsService.areTestNetworksEnabled(): - if self.settingsService.isGoerliEnabled(): - sntContract = STT_CONTRACT_ADDRESS_GOERLI - else: - sntContract = STT_CONTRACT_ADDRESS_SEPOLIA - else: - sntContract = SNT_CONTRACT_ADDRESS - let ensUsernameFinal = self.formatUsername(ensUsername, true) - if not self.add(chainId, ensUsernameFinal): - result.error = "failed to add ens username" - error "error occurred", procName="sendEnsTxWithSignatureAndWatch", msg = result.error - return - self.transactionService.watchTransaction(transactionHash, fromAddress, sntContract, $txType, - ensUsernameFinal, chainId) - let dto = EnsUsernameDto(chainId: chainId, username: ensUsernameFinal) - self.pendingEnsUsernames.incl(dto) - elif txType == PendingTransactionTypeDto.ReleaseENS: - let ensUsernameFinal = self.formatUsername(ensUsername, true) - if not self.remove(chainId, ensUsernameFinal): - result.error = "failed to add ens username" - error "error occurred", procName="sendEnsTxWithSignatureAndWatch", msg = result.error - return - let ensUsernamesAddress = self.getEnsRegisteredAddress() - self.transactionService.watchTransaction(transactionHash, fromAddress, ensUsernamesAddress, $txType, ensUsername, chainId) - let dto = EnsUsernameDto(chainId: chainId, username: ensUsername) - self.pendingEnsUsernames.excl(dto) - - result.txHash = transactionHash - except Exception as e: - result.error = e.msg - error "error occurred", procName="sendEnsTxWithSignatureAndWatch", msg = result.error + raise \ No newline at end of file diff --git a/src/app_service/service/stickers/service.nim b/src/app_service/service/stickers/service.nim index 86d483c4b8..472cb871f7 100644 --- a/src/app_service/service/stickers/service.nim +++ b/src/app_service/service/stickers/service.nim @@ -137,7 +137,6 @@ QtObject: break if packId.len == 0: - error "Error updating sticker pack status", message = "no packId found for transactionHash: " & transactionHash return if status == TxStatusSuccess: diff --git a/src/backend/ens.nim b/src/backend/ens.nim index 2af1599907..464cd6c9e8 100644 --- a/src/backend/ens.nim +++ b/src/backend/ens.nim @@ -19,21 +19,11 @@ proc getRegistrarAddress*(chainId: int): RpcResponse[JsonNode] = return core.callPrivateRPC("ens_getRegistrarAddress", payload) -proc resolver*(chainId: int, username: string): RpcResponse[JsonNode] = - let payload = %* [chainId, username] - - return core.callPrivateRPC("ens_resolver", payload) - proc ownerOf*(chainId: int, username: string): RpcResponse[JsonNode] = let payload = %* [chainId, username] return core.callPrivateRPC("ens_ownerOf", payload) -proc contentHash*(chainId: int, username: string): RpcResponse[JsonNode] = - let payload = %* [chainId, username] - - return core.callPrivateRPC("ens_contentHash", payload) - proc publicKeyOf*(chainId: int, username: string): RpcResponse[JsonNode] = let payload = %* [chainId, username] @@ -55,28 +45,4 @@ proc price*(chainId: int): RpcResponse[JsonNode] = proc resourceURL*(chainId: int, username: string): RpcResponse[JsonNode] = let payload = %* [chainId, username] - return core.callPrivateRPC("ens_resourceURL", payload) - -proc prepareTxForRegisterEnsUsername*(chainId: int, txData: JsonNode, username: string, pubkey: string): RpcResponse[JsonNode] = - let payload = %* [chainId, txData, username, pubkey] - return core.callPrivateRPC("ens_registerPrepareTx", payload) - -proc registerEstimate*(chainId: int, txData: JsonNode, username: string, pubkey: string): RpcResponse[JsonNode] = - let payload = %* [chainId, txData, username, pubkey] - return core.callPrivateRPC("ens_registerEstimate", payload) - -proc prepareTxForReleaseEnsUsername*(chainId: int, txData: JsonNode, username: string): RpcResponse[JsonNode] = - let payload = %* [chainId, txData, username] - return core.callPrivateRPC("ens_releasePrepareTx", payload) - -proc releaseEstimate*(chainId: int, txData: JsonNode, username: string): RpcResponse[JsonNode] = - let payload = %* [chainId, txData, username] - return core.callPrivateRPC("ens_releaseEstimate", payload) - -proc prepareTxForSetPubKey*(chainId: int, txData: JsonNode, username: string, pubkey: string): RpcResponse[JsonNode] = - let payload = %* [chainId, txData, username, pubkey] - return core.callPrivateRPC("ens_setPubKeyPrepareTx", payload) - -proc setPubKeyEstimate*(chainId: int, txData: JsonNode, username: string, pubkey: string): RpcResponse[JsonNode] = - let payload = %* [chainId, txData, username, pubkey] - return core.callPrivateRPC("ens_setPubKeyEstimate", payload) \ No newline at end of file + return core.callPrivateRPC("ens_resourceURL", payload) \ No newline at end of file diff --git a/ui/app/AppLayouts/Profile/stores/EnsUsernamesStore.qml b/ui/app/AppLayouts/Profile/stores/EnsUsernamesStore.qml index c055a8d014..8620d3eb53 100644 --- a/ui/app/AppLayouts/Profile/stores/EnsUsernamesStore.qml +++ b/ui/app/AppLayouts/Profile/stores/EnsUsernamesStore.qml @@ -48,17 +48,6 @@ QtObject { ensUsernamesModule.fetchDetailsForEnsUsername(chainId, ensUsername) } - function setPubKeyGasEstimate(chainId, ensUsername, address) { - if(!root.ensUsernamesModule) - return 0 - return ensUsernamesModule.setPubKeyGasEstimate(chainId, ensUsername, address) - } - - function authenticateAndSetPubKey(chainId, ensUsername, address, gas, gasPrice, maxPriorityFeePerGas, maxFeePerGas, eip1559Enabled) { - if(!root.ensUsernamesModule) - return "" - return ensUsernamesModule.authenticateAndSetPubKey(chainId, ensUsername, address, gas, gasPrice, maxPriorityFeePerGas, maxFeePerGas, eip1559Enabled) - } function getEtherscanLink() { if(!root.ensUsernamesModule) @@ -66,18 +55,6 @@ QtObject { return ensUsernamesModule.getEtherscanLink() } - function getSigningPhrase() { - if(!root.ensUsernamesModule) - return "" - return ensUsernamesModule.getSigningPhrase() - } - - function authenticateAndReleaseEns(chainId, ensUsername, address, gas, gasPrice, maxPriorityFeePerGas, maxFeePerGas, eip1559Enabled) { - if(!root.ensUsernamesModule) - return "" - return ensUsernamesModule.authenticateAndReleaseEns(chainId, ensUsername, address, gas, gasPrice, maxPriorityFeePerGas, maxFeePerGas, eip1559Enabled) - } - function ensConnectOwnedUsername(name, isStatus) { if(!root.ensUsernamesModule) return @@ -90,12 +67,6 @@ QtObject { return ensUsernamesModule.getEnsRegisteredAddress() } - function authenticateAndRegisterEns(chainId, ensUsername, address, gasLimit, gasPrice, tipLimit, overallLimit, eip1559Enabled) { - if(!root.ensUsernamesModule) - return - ensUsernamesModule.authenticateAndRegisterEns(chainId, ensUsername, address, gasLimit, gasPrice, tipLimit, overallLimit, eip1559Enabled) - } - function getEnsRegistry() { if(!root.ensUsernamesModule) return "" diff --git a/ui/app/AppLayouts/Profile/views/EnsDetailsView.qml b/ui/app/AppLayouts/Profile/views/EnsDetailsView.qml index f6f294acd8..a1d04cc4de 100644 --- a/ui/app/AppLayouts/Profile/views/EnsDetailsView.qml +++ b/ui/app/AppLayouts/Profile/views/EnsDetailsView.qml @@ -131,23 +131,7 @@ Item { preSelectedHoldingType: Constants.TokenType.ERC20 publicKey: root.contactsStore.myPublicKey ensName: root.username - sendTransaction: function() { - if(bestRoutes.count === 1) { - let path = bestRoutes.firstItem() - let eip1559Enabled = path.gasFees.eip1559Enabled - let maxFeePerGas = path.gasFees.maxFeePerGasM - root.ensUsernamesStore.authenticateAndReleaseEns( - root.chainId, - root.username, - store.selectedSenderAccountAddress, - path.gasAmount, - eip1559Enabled ? "" : path.gasFees.gasPrice, - eip1559Enabled ? path.gasFees.maxPriorityFeePerGas : "", - eip1559Enabled ? maxFeePerGas: path.gasFees.gasPrice, - eip1559Enabled, - ) - } - } + Connections { target: root.ensUsernamesStore.ensUsernamesModule function onTransactionWasSent(chainId: int, txHash: string, error: string) { @@ -159,13 +143,6 @@ Item { return releaseEnsModal.sendingError.open() } usernameReleased() - let url = "%1/%2".arg(releaseEnsModal.store.getEtherscanLink(chainId)).arg(txHash) - Global.displayToastMessage(qsTr("Transaction pending..."), - qsTr("View on etherscan"), - "", - true, - Constants.ephemeralNotificationType.normal, - url) releaseEnsModal.close() } } diff --git a/ui/app/AppLayouts/Profile/views/EnsSearchView.qml b/ui/app/AppLayouts/Profile/views/EnsSearchView.qml index 9d02f354eb..ed6150cfa5 100644 --- a/ui/app/AppLayouts/Profile/views/EnsSearchView.qml +++ b/ui/app/AppLayouts/Profile/views/EnsSearchView.qml @@ -76,22 +76,7 @@ Item { preSelectedHoldingType: Constants.TokenType.ERC20 publicKey: root.contactsStore.myPublicKey ensName: ensUsername.text - sendTransaction: function() { - if(bestRoutes.count === 1) { - let path = bestRoutes.firstItem() - let eip1559Enabled = path.gasFees.eip1559Enabled - root.ensUsernamesStore.authenticateAndSetPubKey( - root.ensUsernamesStore.chainId, - ensUsername.text + (isStatus ? ".stateofus.eth" : "" ), - store.selectedSenderAccountAddress, - path.gasAmount, - eip1559Enabled ? "" : path.gasFees.gasPrice, - "", - "", - eip1559Enabled, - ) - } - } + Connections { target: root.ensUsernamesStore.ensUsernamesModule function onTransactionWasSent(chainId: int, txHash: string, error: string) { @@ -103,13 +88,6 @@ Item { return connectEnsModal.sendingError.open() } usernameUpdated(ensUsername.text); - let url = "%1/%2".arg(connectEnsModal.store.getEtherscanLink(chainId)).arg(txHash) - Global.displayToastMessage(qsTr("Transaction pending..."), - qsTr("View on etherscan"), - "", - true, - Constants.ephemeralNotificationType.normal, - url) connectEnsModal.close() } } diff --git a/ui/app/AppLayouts/Profile/views/EnsTermsAndConditionsView.qml b/ui/app/AppLayouts/Profile/views/EnsTermsAndConditionsView.qml index f6057893e7..1548cd4e6d 100644 --- a/ui/app/AppLayouts/Profile/views/EnsTermsAndConditionsView.qml +++ b/ui/app/AppLayouts/Profile/views/EnsTermsAndConditionsView.qml @@ -79,23 +79,7 @@ Item { preSelectedHoldingType: Constants.TokenType.ERC20 publicKey: root.contactsStore.myPublicKey ensName: root.username - sendTransaction: function() { - if(bestRoutes.count === 1) { - let path = bestRoutes.firstItem() - let eip1559Enabled = path.gasFees.eip1559Enabled - let maxFeePerGas = path.gasFees.maxFeePerGasM - root.ensUsernamesStore.authenticateAndRegisterEns( - root.ensUsernamesStore.chainId, - username, - store.selectedSenderAccountAddress, - path.gasAmount, - eip1559Enabled ? "" : path.gasFees.gasPrice, - eip1559Enabled ? path.gasFees.maxPriorityFeePerGas : "", - eip1559Enabled ? maxFeePerGas: path.gasFees.gasPrice, - eip1559Enabled, - ) - } - } + Connections { target: root.ensUsernamesStore.ensUsernamesModule function onTransactionWasSent(chainId: int, txHash: string, error: string) { @@ -106,14 +90,7 @@ Item { buyEnsModal.sendingError.text = error return buyEnsModal.sendingError.open() } - usernameRegistered(username) - let url = "%1/%2".arg(buyEnsModal.store.getEtherscanLink(chainId)).arg(txHash) - Global.displayToastMessage(qsTr("Transaction pending..."), - qsTr("View on etherscan"), - "", - true, - Constants.ephemeralNotificationType.normal, - url) + usernameRegistered(username) } } }