From 52e96e904b264decb954e4ff8bb9ba648cd3a80e Mon Sep 17 00:00:00 2001 From: Khushboo Mehta Date: Wed, 9 Feb 2022 01:04:49 +0100 Subject: [PATCH] fix(@desktop/chat): enable transactions over chat fixes #4610 --- src/app/boot/app_controller.nim | 4 +- .../modules/main/activity_center/module.nim | 2 + .../chat_section/chat_content/controller.nim | 8 +- .../chat_content/controller_interface.nim | 7 + .../chat_content/messages/controller.nim | 7 + .../messages/controller_interface.nim | 7 + .../chat_content/messages/module.nim | 55 ++- .../main/chat_section/chat_content/module.nim | 27 +- .../main/wallet_section/accounts/model.nim | 18 + .../main/wallet_section/accounts/view.nim | 13 + .../transactions/controller.nim | 3 + .../transactions/io_interface.nim | 3 + .../wallet_section/transactions/module.nim | 4 + .../main/wallet_section/transactions/view.nim | 5 + .../modules/shared_models/message_item.nim | 13 +- .../modules/shared_models/message_model.nim | 15 +- .../message_transaction_parameters_item.nim | 109 +++++ .../service/message/dto/message.nim | 26 ++ src/app_service/service/message/service.nim | 29 +- .../service/transaction/service.nim | 11 + .../Chat/popups/ChatCommandModal.qml | 8 +- .../Chat/popups/PinnedMessagesPopup.qml | 1 + .../Chat/popups/SignTransactionModal.qml | 388 ------------------ ui/app/AppLayouts/Chat/stores/RootStore.qml | 67 ++- .../AppLayouts/Chat/views/ChatColumnView.qml | 4 +- .../Chat/views/ChatMessagesView.qml | 1 + ui/app/AppLayouts/stores/RootStore.qml | 2 + .../shared/controls/ContactSelector.qml | 8 +- .../shared/popups/SignTransactionModal.qml | 147 ++++--- .../shared/views/TransactionPreview.qml | 3 +- .../views/chat/AcceptTransactionView.qml | 52 +-- .../shared/views/chat/CompactMessageView.qml | 5 +- ui/imports/shared/views/chat/MessageView.qml | 3 + .../views/chat/TransactionBubbleView.qml | 94 +++-- 34 files changed, 577 insertions(+), 572 deletions(-) create mode 100644 src/app/modules/shared_models/message_transaction_parameters_item.nim delete mode 100644 ui/app/AppLayouts/Chat/popups/SignTransactionModal.qml diff --git a/src/app/boot/app_controller.nim b/src/app/boot/app_controller.nim index 0a27aea1dc..66239e82c9 100644 --- a/src/app/boot/app_controller.nim +++ b/src/app/boot/app_controller.nim @@ -135,8 +135,6 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController = result.chatService = chat_service.newService(statusFoundation.events, result.contactsService) result.communityService = community_service.newService(statusFoundation.events, statusFoundation.threadpool, result.chatService) - result.messageService = message_service.newService(statusFoundation.events, statusFoundation.threadpool, - result.contactsService) result.activityCenterService = activity_center_service.newService(statusFoundation.events, statusFoundation.threadpool, result.chatService) result.tokenService = token_service.newService( @@ -147,6 +145,8 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController = statusFoundation.events, result.settingsService, result.accountsService, result.tokenService, result.networkService, ) + result.messageService = message_service.newService(statusFoundation.events, statusFoundation.threadpool, + result.contactsService, result.ethService, result.tokenService, result.walletAccountService) result.transactionService = transaction_service.newService(statusFoundation.events, statusFoundation.threadpool, result.walletAccountService, result.ethService, result.networkService, result.settingsService) result.bookmarkService = bookmark_service.newService() diff --git a/src/app/modules/main/activity_center/module.nim b/src/app/modules/main/activity_center/module.nim index dbb3ed643e..62d1213df0 100644 --- a/src/app/modules/main/activity_center/module.nim +++ b/src/app/modules/main/activity_center/module.nim @@ -4,6 +4,7 @@ import ./io_interface, ./view, ./controller import ./item as notification_item import ../../shared_models/message_item as message_item import ../../shared_models/message_item_qobject as message_item_qobject +import ../../shared_models/message_transaction_parameters_item import ../../../global/global_singleton import ../../../core/eventemitter import ../../../../app_service/service/activity_center/service as activity_center_service @@ -91,6 +92,7 @@ method convertToItems*[T]( self.controller.decodeContentHash(n.message.sticker.hash), n.message.sticker.pack, n.message.links, + initTransactionParametersItem("","","","","","",-1,""), )) return notification_item.initItem( diff --git a/src/app/modules/main/chat_section/chat_content/controller.nim b/src/app/modules/main/chat_section/chat_content/controller.nim index 0b0fd34ff9..2798b44afa 100644 --- a/src/app/modules/main/chat_section/chat_content/controller.nim +++ b/src/app/modules/main/chat_section/chat_content/controller.nim @@ -9,6 +9,7 @@ import ../../../../../app_service/service/chat/service as chat_service import ../../../../../app_service/service/community/service as community_service import ../../../../../app_service/service/message/service as message_service import ../../../../../app_service/service/eth/utils as eth_utils +import ../../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../core/signals/types import ../../../../core/eventemitter @@ -180,6 +181,11 @@ method getCurrentFleet*(self: Controller): string = method getRenderedText*(self: Controller, parsedTextArray: seq[ParsedText]): string = return self.messageService.getRenderedText(parsedTextArray) - method decodeContentHash*(self: Controller, hash: string): string = return eth_utils.decodeContentHash(hash) + +method getTransactionDetails*(self: Controller, message: MessageDto): (string,string) = + return self.messageService.getTransactionDetails(message) + +method getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] = + return self.messageService.getWalletAccounts() diff --git a/src/app/modules/main/chat_section/chat_content/controller_interface.nim b/src/app/modules/main/chat_section/chat_content/controller_interface.nim index 5fd0bbfdd0..949afca04f 100644 --- a/src/app/modules/main/chat_section/chat_content/controller_interface.nim +++ b/src/app/modules/main/chat_section/chat_content/controller_interface.nim @@ -3,6 +3,7 @@ import ../../../../../app_service/service/message/dto/[message, reaction] import ../../../../../app_service/service/community/dto/[community] import ../../../../../app_service/service/chat/dto/[chat] import ../../../../../app_service/service/contacts/service +import ../../../../../app_service/service/wallet_account/[dto] type AccessInterface* {.pure inheritable.} = ref object of RootObj @@ -72,3 +73,9 @@ method getRenderedText*(self: AccessInterface, parsedTextArray: seq[ParsedText]) method decodeContentHash*(self: AccessInterface, hash: string): string {.base.} = raise newException(ValueError, "No implementation available") + +method getTransactionDetails*(self: AccessInterface, message: MessageDto): (string,string) {.base.} = + raise newException(ValueError, "No implementation available") + +method getWalletAccounts*(self: AccessInterface): seq[WalletAccountDto] = + raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/chat_section/chat_content/messages/controller.nim b/src/app/modules/main/chat_section/chat_content/messages/controller.nim index e6ac456a4a..38755ab9c3 100644 --- a/src/app/modules/main/chat_section/chat_content/messages/controller.nim +++ b/src/app/modules/main/chat_section/chat_content/messages/controller.nim @@ -7,6 +7,7 @@ import ../../../../../../app_service/service/community/service as community_serv import ../../../../../../app_service/service/chat/service as chat_service import ../../../../../../app_service/service/message/service as message_service import ../../../../../../app_service/service/mailservers/service as mailservers_service +import ../../../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../../../app_service/service/eth/utils as eth_utils import ../../../../../core/signals/types import ../../../../../core/eventemitter @@ -234,3 +235,9 @@ method requestMoreMessages*(self: Controller) = method fillGaps*(self: Controller, messageId: string) = self.mailserversService.fillGaps(self.chatId, messageId) + +method getTransactionDetails*(self: Controller, message: MessageDto): (string,string) = + return self.messageService.getTransactionDetails(message) + +method getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] = + return self.messageService.getWalletAccounts() diff --git a/src/app/modules/main/chat_section/chat_content/messages/controller_interface.nim b/src/app/modules/main/chat_section/chat_content/messages/controller_interface.nim index 3aa841cdf9..07ec7f01a8 100644 --- a/src/app/modules/main/chat_section/chat_content/messages/controller_interface.nim +++ b/src/app/modules/main/chat_section/chat_content/messages/controller_interface.nim @@ -2,6 +2,7 @@ import ../../../../../../app_service/service/contacts/dto/[contacts, contact_det import ../../../../../../app_service/service/community/dto/[community] import ../../../../../../app_service/service/chat/dto/[chat] import ../../../../../../app_service/service/message/dto/[message, reaction] +import ../../../../../../app_service/service/wallet_account/[dto] type AccessInterface* {.pure inheritable.} = ref object of RootObj @@ -95,3 +96,9 @@ method requestMoreMessages*(self: AccessInterface) {.base.} = method fillGaps*(self: AccessInterface, messageId: string) {.base.} = raise newException(ValueError, "No implementation available") + +method getTransactionDetails*(self: AccessInterface, message: MessageDto): (string,string) {.base.} = + raise newException(ValueError, "No implementation available") + +method getWalletAccounts*(self: AccessInterface): seq[WalletAccountDto] = + raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/chat_section/chat_content/messages/module.nim b/src/app/modules/main/chat_section/chat_content/messages/module.nim index 9c23d0a863..cf46b9c329 100644 --- a/src/app/modules/main/chat_section/chat_content/messages/module.nim +++ b/src/app/modules/main/chat_section/chat_content/messages/module.nim @@ -5,6 +5,7 @@ import view, controller import ../../../../shared_models/message_model import ../../../../shared_models/message_item import ../../../../shared_models/message_reaction_item +import ../../../../shared_models/message_transaction_parameters_item import ../../../../../global/global_singleton import ../../../../../core/eventemitter import ../../../../../../app_service/service/contacts/service as contact_service @@ -90,6 +91,7 @@ proc createFetchMoreMessagesItem(self: Module): Item = sticker = "", stickerPack = -1, @[], + initTransactionParametersItem("","","","","","",-1,""), ) proc createChatIdentifierItem(self: Module): Item = @@ -120,6 +122,7 @@ proc createChatIdentifierItem(self: Module): Item = sticker = "", stickerPack = -1, @[], + initTransactionParametersItem("","","","","","",-1,""), ) proc checkIfMessageLoadedAndScrollToItIfItIs(self: Module): bool = @@ -135,6 +138,15 @@ proc checkIfMessageLoadedAndScrollToItIfItIs(self: Module): bool = return true return false +method currentUserWalletContainsAddress(self: Module, address: string): bool = + if (address.len == 0): + return false + let accounts = self.controller.getWalletAccounts() + for acc in accounts: + if (acc.address == address): + return true + return false + method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: seq[ReactionDto], pinnedMessages: seq[PinnedMessageDto]) = var viewItems: seq[Item] @@ -144,6 +156,13 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se let sender = self.controller.getContactDetails(m.`from`) let renderedMessageText = self.controller.getRenderedText(m.parsedText) + var transactionContract = m.transactionParameters.contract + var transactionValue = m.transactionParameters.value + var isCurrentUser = sender.isCurrentUser + if(m.contentType.ContentType == ContentType.Transaction): + (transactionContract, transactionValue) = self.controller.getTransactionDetails(m) + if m.transactionParameters.fromAddress != "": + isCurrentUser = self.currentUserWalletContainsAddress(m.transactionParameters.fromAddress) var item = initItem( m.id, m.responseTo, @@ -152,7 +171,7 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se sender.details.localNickname, sender.icon, sender.isIdenticon, - sender.isCurrentUser, + isCurrentUser, m.outgoingStatus, renderedMessageText, m.image, @@ -164,7 +183,15 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se sticker = self.controller.decodeContentHash(m.sticker.hash), m.sticker.pack, m.links, - ) + initTransactionParametersItem(m.transactionParameters.id, + m.transactionParameters.fromAddress, + m.transactionParameters.address, + transactionContract, + transactionValue, + m.transactionParameters.transactionHash, + m.transactionParameters.commandState, + m.transactionParameters.signature), + ) for r in reactions: if(r.messageId == m.id): @@ -207,6 +234,18 @@ method messageAdded*(self: Module, message: MessageDto) = let sender = self.controller.getContactDetails(message.`from`) let renderedMessageText = self.controller.getRenderedText(message.parsedText) + + var transactionContract = message.transactionParameters.contract + var transactionValue = message.transactionParameters.value + var isCurrentUser = sender.isCurrentUser + if message.contentType.ContentType == ContentType.Transaction: + (transactionContract, transactionValue) = self.controller.getTransactionDetails(message) + if message.transactionParameters.fromAddress != "": + isCurrentUser = self.currentUserWalletContainsAddress(message.transactionParameters.fromAddress) + # remove a message which has replace parameters filled + let index = self.view.model().findIndexForMessageId(message.replace) + if(index != -1): + self.view.model().removeItem(message.replace) var item = initItem( message.id, message.responseTo, @@ -215,7 +254,7 @@ method messageAdded*(self: Module, message: MessageDto) = sender.details.localNickname, sender.icon, sender.isIdenticon, - sender.isCurrentUser, + isCurrentUser, message.outgoingStatus, renderedMessageText, message.image, @@ -226,7 +265,15 @@ method messageAdded*(self: Module, message: MessageDto) = message.messageType, sticker = self.controller.decodeContentHash(message.sticker.hash), message.sticker.pack, - message.links + message.links, + initTransactionParametersItem(message.transactionParameters.id, + message.transactionParameters.fromAddress, + message.transactionParameters.address, + transactionContract, + transactionValue, + message.transactionParameters.transactionHash, + message.transactionParameters.commandState, + message.transactionParameters.signature), ) self.view.model().insertItemBasedOnTimestamp(item) diff --git a/src/app/modules/main/chat_section/chat_content/module.nim b/src/app/modules/main/chat_section/chat_content/module.nim index 0c08559a8e..b47e1eca4e 100644 --- a/src/app/modules/main/chat_section/chat_content/module.nim +++ b/src/app/modules/main/chat_section/chat_content/module.nim @@ -4,6 +4,7 @@ import ../io_interface as delegate_interface import view, controller import ../../../shared_models/message_model as pinned_msg_model import ../../../shared_models/message_item as pinned_msg_item +import ../../../shared_models/message_transaction_parameters_item import ../../../shared_models/message_reaction_item as pinned_msg_reaction_item import ../../../../global/global_singleton import ../../../../core/eventemitter @@ -130,6 +131,15 @@ method getMessagesModule*(self: Module): QVariant = method getUsersModule*(self: Module): QVariant = return self.usersModule.getModuleAsVariant() +method currentUserWalletContainsAddress(self: Module, address: string): bool = + if (address.len == 0): + return false + let accounts = self.controller.getWalletAccounts() + for acc in accounts: + if (acc.address == address): + return true + return false + proc buildPinnedMessageItem(self: Module, messageId: string, actionInitiatedBy: string, item: var pinned_msg_item.Item): bool = let (m, reactions, err) = self.controller.getMessageDetails(messageId) @@ -138,6 +148,13 @@ proc buildPinnedMessageItem(self: Module, messageId: string, actionInitiatedBy: let contactDetails = self.controller.getContactDetails(m.`from`) + var transactionContract = m.transactionParameters.contract + var transactionValue = m.transactionParameters.value + var isCurrentUser = contactDetails.isCurrentUser + if(m.contentType.ContentType == ContentType.Transaction): + (transactionContract, transactionValue) = self.controller.getTransactionDetails(m) + if m.transactionParameters.fromAddress != "": + isCurrentUser = self.currentUserWalletContainsAddress(m.transactionParameters.fromAddress) item = pinned_msg_item.initItem( m.id, m.responseTo, @@ -146,7 +163,7 @@ proc buildPinnedMessageItem(self: Module, messageId: string, actionInitiatedBy: contactDetails.details.localNickname, contactDetails.icon, contactDetails.isIdenticon, - contactDetails.isCurrentUser, + isCurrentUser, m.outgoingStatus, self.controller.getRenderedText(m.parsedText), m.image, @@ -158,6 +175,14 @@ proc buildPinnedMessageItem(self: Module, messageId: string, actionInitiatedBy: self.controller.decodeContentHash(m.sticker.hash), m.sticker.pack, m.links, + initTransactionParametersItem(m.transactionParameters.id, + m.transactionParameters.fromAddress, + m.transactionParameters.address, + transactionContract, + transactionValue, + m.transactionParameters.transactionHash, + m.transactionParameters.commandState, + m.transactionParameters.signature) ) item.pinned = true item.pinnedBy = actionInitiatedBy diff --git a/src/app/modules/main/wallet_section/accounts/model.nim b/src/app/modules/main/wallet_section/accounts/model.nim index 3cde99de13..134568e7ff 100644 --- a/src/app/modules/main/wallet_section/accounts/model.nim +++ b/src/app/modules/main/wallet_section/accounts/model.nim @@ -98,3 +98,21 @@ QtObject: self.items = items self.endResetModel() self.countChanged() + + proc getAccountNameByAddress*(self: Model, address: string): string = + for account in self.items: + if(account.getAddress() == address): + return account.getName() + return "" + + proc getAccountIconColorByAddress*(self: Model, address: string): string = + for account in self.items: + if(account.getAddress() == address): + return account.getColor() + return "" + + proc getAccountAssetsByAddress*(self: Model, address: string): QVariant = + for account in self.items: + if(account.getAddress() == address): + return newQVariant(account.getAssets()) + return nil diff --git a/src/app/modules/main/wallet_section/accounts/view.nim b/src/app/modules/main/wallet_section/accounts/view.nim index d4cfc58a24..bcef91ad45 100644 --- a/src/app/modules/main/wallet_section/accounts/view.nim +++ b/src/app/modules/main/wallet_section/accounts/view.nim @@ -10,6 +10,7 @@ QtObject: delegate: io_interface.AccessInterface model: Model modelVariant: QVariant + tmpAddress: string proc delete*(self: View) = self.model.delete @@ -52,3 +53,15 @@ QtObject: proc deleteAccount*(self: View, address: string) {.slot.} = self.delegate.deleteAccount(address) + + proc getAccountNameByAddress*(self: View, address: string): string {.slot.} = + return self.model.getAccountNameByAddress(address) + + proc getAccountIconColorByAddress*(self: View, address: string): string {.slot.} = + return self.model.getAccountIconColorByAddress(address) + + proc setAddressForAssets*(self: View, address: string) {.slot.} = + self.tmpAddress = address + + proc getAccountAssetsByAddress*(self: View): QVariant {.slot.} = + return self.model.getAccountAssetsByAddress(self.tmpAddress) diff --git a/src/app/modules/main/wallet_section/transactions/controller.nim b/src/app/modules/main/wallet_section/transactions/controller.nim index 4319de2115..d2164a440c 100644 --- a/src/app/modules/main/wallet_section/transactions/controller.nim +++ b/src/app/modules/main/wallet_section/transactions/controller.nim @@ -61,6 +61,9 @@ method init*(self: Controller) = let args = TransactionsLoadedArgs(e) self.delegate.setTrxHistoryResult(args.transactions, args.address, args.wasFetchMore) + self.events.on(SIGNAL_TRANSACTION_SENT) do(e:Args): + self.delegate.transactionWasSent(TransactionSentArgs(e).result) + method checkPendingTransactions*(self: Controller) = self.transactionService.checkPendingTransactions() diff --git a/src/app/modules/main/wallet_section/transactions/io_interface.nim b/src/app/modules/main/wallet_section/transactions/io_interface.nim index eec187b495..86f6ec581e 100644 --- a/src/app/modules/main/wallet_section/transactions/io_interface.nim +++ b/src/app/modules/main/wallet_section/transactions/io_interface.nim @@ -54,6 +54,9 @@ method transferTokens*(self: AccessInterface, from_addr: string, to_addr: string uuid: string): bool {.base.} = raise newException(ValueError, "No implementation available") +method transactionWasSent*(self: AccessInterface, result: string) {.base.} = + raise newException(ValueError, "No implementation available") + # View Delegate Interface # Delegate for the view must be declared here due to use of QtObject and multi # inheritance, which is not well supported in Nim. diff --git a/src/app/modules/main/wallet_section/transactions/module.nim b/src/app/modules/main/wallet_section/transactions/module.nim index 6f8a40fe34..9d36ae4bb2 100644 --- a/src/app/modules/main/wallet_section/transactions/module.nim +++ b/src/app/modules/main/wallet_section/transactions/module.nim @@ -99,3 +99,7 @@ method transferTokens*(self: Module, from_addr: string, to_addr: string, contrac maxFeePerGas: string, password: string, uuid: string): bool = result = self.controller.transferTokens(from_addr, to_addr, contractAddress, value, gas, gasPrice, maxPriorityFeePerGas, maxFeePerGas, password, uuid) + +method transactionWasSent*(self: Module, result: string) = + self.view.transactionWasSent(result) + diff --git a/src/app/modules/main/wallet_section/transactions/view.nim b/src/app/modules/main/wallet_section/transactions/view.nim index d646c7b216..8bbbaf6449 100644 --- a/src/app/modules/main/wallet_section/transactions/view.nim +++ b/src/app/modules/main/wallet_section/transactions/view.nim @@ -107,6 +107,11 @@ QtObject: result = self.delegate.estimateGas(from_addr, to, assetAddress, value, data) result = self.delegate.estimateGas(from_addr, to, assetAddress, value, data) + proc transactionSent*(self: View, txResult: string) {.signal.} + + proc transactionWasSent*(self: View,txResult: string) {.slot} = + self.transactionSent(txResult) + proc transferEth*(self: View, from_addr: string, to_addr: string, value: string, gas: string, gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string, uuid: string): bool {.slot.} = diff --git a/src/app/modules/shared_models/message_item.nim b/src/app/modules/shared_models/message_item.nim index 0ec36b5672..f384c1af1f 100644 --- a/src/app/modules/shared_models/message_item.nim +++ b/src/app/modules/shared_models/message_item.nim @@ -2,7 +2,7 @@ import json, strformat import ../../../app_service/common/types export types.ContentType -import message_reaction_model, message_reaction_item +import message_reaction_model, message_reaction_item, message_transaction_parameters_item type Item* = ref object @@ -32,6 +32,7 @@ type editMode: bool isEdited: bool links: seq[string] + transactionParameters: TransactionParametersItem proc initItem*( id, @@ -53,6 +54,7 @@ proc initItem*( sticker: string, stickerPack: int, links: seq[string], + transactionParameters: TransactionParametersItem, ): Item = result = Item() result.id = id @@ -78,6 +80,7 @@ proc initItem*( result.editMode = false result.isEdited = false result.links = links + result.transactionParameters = transactionParameters proc `$`*(self: Item): string = result = fmt"""Item( @@ -99,8 +102,9 @@ proc `$`*(self: Item): string = pinnedBy:{$self.pinnedBy}, messageReactions: [{$self.reactionsModel}], editMode:{$self.editMode}, - isEdited:{$self.isEdited} - links:{$self.links} + isEdited:{$self.isEdited}, + links:{$self.links}, + transactionParameters:{$self.transactionParameters}, )""" proc id*(self: Item): string {.inline.} = @@ -206,6 +210,9 @@ proc removeReaction*(self: Item, emojiId: EmojiId, reactionId: string, didIRemov proc links*(self: Item): seq[string] {.inline.} = self.links +proc transactionParameters*(self: Item): TransactionParametersItem {.inline.} = + self.transactionParameters + proc toJsonNode*(self: Item): JsonNode = result = %* { "id": self.id, diff --git a/src/app/modules/shared_models/message_model.nim b/src/app/modules/shared_models/message_model.nim index a2dd52741a..d77d7b0bf9 100644 --- a/src/app/modules/shared_models/message_model.nim +++ b/src/app/modules/shared_models/message_model.nim @@ -1,6 +1,6 @@ import NimQml, Tables, json, strutils, strformat -import message_item, message_reaction_item +import message_item, message_reaction_item, message_transaction_parameters_item type ModelRole {.pure.} = enum @@ -31,6 +31,7 @@ type EditMode IsEdited Links + TransactionParameters QtObject: type @@ -93,6 +94,7 @@ QtObject: ModelRole.EditMode.int: "editMode", ModelRole.IsEdited.int: "isEdited", ModelRole.Links.int: "links", + ModelRole.TransactionParameters.int: "transactionParameters", }.toTable method data(self: Model, index: QModelIndex, role: int): QVariant = @@ -158,6 +160,17 @@ QtObject: result = newQVariant(item.isEdited) of ModelRole.Links: result = newQVariant(item.links.join(" ")) + of ModelRole.TransactionParameters: + result = newQVariant($(%*{ + "id": item.transactionParameters.id, + "fromAddress": item.transactionParameters.fromAddress, + "address": item.transactionParameters.address, + "contract": item.transactionParameters.contract, + "value": item.transactionParameters.value, + "transactionHash": item.transactionParameters.transactionHash, + "commandState": item.transactionParameters.commandState, + "signature": item.transactionParameters.signature + })) proc findIndexForMessageId*(self: Model, messageId: string): int = for i in 0 ..< self.items.len: diff --git a/src/app/modules/shared_models/message_transaction_parameters_item.nim b/src/app/modules/shared_models/message_transaction_parameters_item.nim new file mode 100644 index 0000000000..79ef810a42 --- /dev/null +++ b/src/app/modules/shared_models/message_transaction_parameters_item.nim @@ -0,0 +1,109 @@ +import Nimqml, json, strformat + +QtObject: + type + TransactionParametersItem* = ref object of QObject + id: string + fromAddress: string + address: string + contract: string + value: string + transactionHash: string + commandState: int + signature: string + + proc initTransactionParametersItem*( + id: string, + fromAddress: string, + address: string, + contract: string, + value: string, + transactionHash: string, + commandState: int, + signature: string, + ): TransactionParametersItem = + result = TransactionParametersItem() + result.id = id + result.fromAddress = fromAddress + result.address = address + result.contract = contract + result.value = value + result.transactionHash = transactionHash + result.commandState = commandState + result.signature = signature + + proc `$`*(self: TransactionParametersItem): string = + result = fmt"""TransactionParametersItem( + id: {$self.id}, + fromAddress: {$self.fromAddress}, + address: {$self.address}, + contract: {$self.contract}, + value: {$self.value}, + transactionHash: {$self.transactionHash}, + commandState: {$self.commandState}, + signature: {$self.signature}, + )""" + + proc idChanged*(self: TransactionParametersItem) {.signal.} + QtProperty[string] id: + read = id + notify = idChanged + + proc id*(self: TransactionParametersItem): string {.inline.} = + self.id + + proc fromAddressChanged*(self: TransactionParametersItem) {.signal.} + QtProperty[string] fromAddress: + read = fromAddress + notify = fromAddressChanged + + proc fromAddress*(self: TransactionParametersItem): string {.inline.} = + self.fromAddress + + proc addressChanged*(self: TransactionParametersItem) {.signal.} + QtProperty[string] address: + read = address + notify = addressChanged + + proc address*(self: TransactionParametersItem): string {.inline.} = + self.address + + proc contractChanged*(self: TransactionParametersItem) {.signal.} + QtProperty[string] contract: + read = contract + notify = contractChanged + + proc contract*(self: TransactionParametersItem): string {.inline.} = + self.contract + + proc valueChanged*(self: TransactionParametersItem) {.signal.} + QtProperty[string] value: + read = value + notify = valueChanged + + proc value*(self: TransactionParametersItem): string {.inline.} = + self.value + + proc transactionHashChanged*(self: TransactionParametersItem) {.signal.} + QtProperty[string] transactionHash: + read = transactionHash + notify = transactionHashChanged + + proc transactionHash*(self: TransactionParametersItem): string {.inline.} = + self.transactionHash + + proc commandStateChanged*(self: TransactionParametersItem) {.signal.} + QtProperty[int] commandState: + read = commandState + notify = commandStateChanged + + proc commandState*(self: TransactionParametersItem): int {.inline.} = + self.commandState + + proc signatureChanged*(self: TransactionParametersItem) {.signal.} + QtProperty[string] signature: + read = signature + notify = signatureChanged + + proc signature*(self: TransactionParametersItem): string {.inline.} = + self.signature diff --git a/src/app_service/service/message/dto/message.nim b/src/app_service/service/message/dto/message.nim index cd8ea6d54d..c2b1c43b0c 100644 --- a/src/app_service/service/message/dto/message.nim +++ b/src/app_service/service/message/dto/message.nim @@ -36,6 +36,16 @@ type GapParameters* = object `from`*: int64 to*: int64 +type TransactionParameters* = object + id*: string + fromAddress*: string + address*: string + contract*: string + value*: string + transactionHash*: string + commandState*: int + signature*: string + type MessageDto* = object id*: string whisperTimestamp*: int64 @@ -63,6 +73,7 @@ type MessageDto* = object messageType*: int links*: seq[string] editedAt*: int + transactionParameters*: TransactionParameters proc toParsedText*(jsonObj: JsonNode): ParsedText = result = ParsedText() @@ -95,6 +106,17 @@ proc toGapParameters*(jsonObj: JsonNode): GapParameters = discard jsonObj.getProp("from", result.from) discard jsonObj.getProp("to", result.to) +proc toTransactionParameters*(jsonObj: JsonNode): TransactionParameters = + result = TransactionParameters() + discard jsonObj.getProp("id", result.id) + discard jsonObj.getProp("from", result.fromAddress) + discard jsonObj.getProp("address", result.address) + discard jsonObj.getProp("contract", result.contract) + discard jsonObj.getProp("value", result.value) + discard jsonObj.getProp("transactionHash", result.transactionHash) + discard jsonObj.getProp("commandState", result.commandState) + discard jsonObj.getProp("signature", result.signature) + proc toMessageDto*(jsonObj: JsonNode): MessageDto = result = MessageDto() discard jsonObj.getProp("id", result.id) @@ -141,6 +163,10 @@ proc toMessageDto*(jsonObj: JsonNode): MessageDto = for pTextObj in parsedTextArr: result.parsedText.add(toParsedText(pTextObj)) + var transactionParametersObj: JsonNode + if(jsonObj.getProp("commandParameters", transactionParametersObj)): + result.transactionParameters = toTransactionParameters(transactionParametersObj) + proc containsContactMentions*(self: MessageDto): bool = for pText in self.parsedText: for child in pText.children: diff --git a/src/app_service/service/message/service.nim b/src/app_service/service/message/service.nim index 4c163a4a2b..b146ccffdf 100644 --- a/src/app_service/service/message/service.nim +++ b/src/app_service/service/message/service.nim @@ -6,6 +6,9 @@ import ../../../app/core/eventemitter import ../../../app/global/global_singleton import ../../../backend/messages as status_go import ../contacts/service as contact_service +import ../eth/service as eth_service +import ../token/service as token_service +import ../wallet_account/service as wallet_account_service import ./dto/message as message_dto import ./dto/pinned_message as pinned_msg_dto import ./dto/reaction as reaction_dto @@ -14,6 +17,11 @@ import ./dto/pinned_message_update as pinned_msg_update_dto import ./dto/removed_message as removed_msg_dto import ../../common/message as message_common +import ../../common/conversion as service_conversion + +from ../../common/account_constants import ZERO_ADDRESS + +import web3/conversions export message_dto export pinned_msg_dto @@ -96,6 +104,9 @@ QtObject: events: EventEmitter threadpool: ThreadPool contactService: contact_service.Service + ethService: eth_service.ServiceInterface + tokenService: token_service.Service + walletAccountService: wallet_account_service.ServiceInterface msgCursor: Table[string, string] lastUsedMsgCursor: Table[string, string] pinnedMsgCursor: Table[string, string] @@ -105,12 +116,15 @@ QtObject: proc delete*(self: Service) = self.QObject.delete - proc newService*(events: EventEmitter, threadpool: ThreadPool, contactService: contact_service.Service): Service = + proc newService*(events: EventEmitter, threadpool: ThreadPool, contactService: contact_service.Service, ethService: eth_service.ServiceInterface, tokenService: token_service.Service, walletAccountService: wallet_account_service.ServiceInterface): Service = new(result, delete) result.QObject.setup result.events = events result.threadpool = threadpool result.contactService = contactService + result.ethService = ethService + result.tokenService = tokenService + result.walletAccountService = walletAccountService result.msgCursor = initTable[string, string]() result.lastUsedMsgCursor = initTable[string, string]() result.pinnedMsgCursor = initTable[string, string]() @@ -230,6 +244,16 @@ QtObject: return self.pinnedMsgCursor[chatId] + + proc getTransactionDetails*(self: Service, message: MessageDto): (string, string) = + let allContracts = self.ethService.allErc20Contracts() + let ethereum = newErc20Contract("Ethereum", Mainnet, parseAddress(ZERO_ADDRESS), "ETH", 18, true) + let tokenContract = if message.transactionParameters.contract == "" : ethereum else: self.ethService.findByAddress(allContracts, parseAddress(message.transactionParameters.contract)) + let tokenContractStr = if tokenContract == nil: "{}" else: $(Json.encode(tokenContract)) + var weiStr = if tokenContract == nil: "0" else: service_conversion.wei2Eth(message.transactionParameters.value, tokenContract.decimals) + weiStr.trimZeros() + return (tokenContractStr, weiStr) + proc onAsyncLoadMoreMessagesForChat*(self: Service, response: string) {.slot.} = let responseObj = response.parseJson if (responseObj.kind != JObject): @@ -688,3 +712,6 @@ proc switchTo*(self: Service, sectionId: string, chatId: string, messageId: stri ## section and/or chat and/or message let data = ActiveSectionChatArgs(sectionId: sectionId, chatId: chatId, messageId: messageId) self.events.emit(SIGNAL_MAKE_SECTION_CHAT_ACTIVE, data) + +proc getWalletAccounts*(self: Service): seq[wallet_account_service.WalletAccountDto] = + return self.walletAccountService.getWalletAccounts() diff --git a/src/app_service/service/transaction/service.nim b/src/app_service/service/transaction/service.nim index e357a72abe..2d67a913ee 100644 --- a/src/app_service/service/transaction/service.nim +++ b/src/app_service/service/transaction/service.nim @@ -29,6 +29,7 @@ include ../../common/json_utils # Signals which may be emitted by this service: const SIGNAL_TRANSACTIONS_LOADED* = "transactionsLoaded" +const SIGNAL_TRANSACTION_SENT* = "transactionSent" type TransactionMinedArgs* = ref object of Args @@ -43,6 +44,10 @@ type address*: string wasFetchMore*: bool +type + TransactionSentArgs* = ref object of Args + result*: string + QtObject: type Service* = ref object of QObject events: EventEmitter @@ -275,6 +280,9 @@ QtObject: if response.error != nil: raise newException(Exception, response.error.message) + let output = %* { "result": %response.result.getStr, "success": %(response.error == nil), "uuid": %uuid } + self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionSentArgs(result: $output)) + self.trackPendingTransaction(response.result.getStr, from_addr, to_addr, $PendingTransactionTypeDto.WalletTransfer, data = "") except Exception as e: @@ -314,6 +322,9 @@ QtObject: let transferMethod = contract.getMethod("transfer") let response = transferMethod.send(tx, transfer, password, success) + let output = %* { "result": %response, "success": %success, "uuid": %uuid } + self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionSentArgs(result: $output)) + self.trackPendingTransaction(response, from_addr, to_addr, $PendingTransactionTypeDto.WalletTransfer, data = "") except Exception as e: diff --git a/ui/app/AppLayouts/Chat/popups/ChatCommandModal.qml b/ui/app/AppLayouts/Chat/popups/ChatCommandModal.qml index 67593ae6f0..5e2ad0c38d 100644 --- a/ui/app/AppLayouts/Chat/popups/ChatCommandModal.qml +++ b/ui/app/AppLayouts/Chat/popups/ChatCommandModal.qml @@ -116,8 +116,8 @@ StatusModal { id: txtAmount selectedAccount: selectFromAccount.selectedAccount currentCurrency: root.store.currentCurrency + getFiatValue: root.store.getFiatValue // Not Refactored Yet -// getFiatValue: root.store.walletModelInst.balanceView.getFiatValue // getCryptoValue: root.store.walletModelInst.balanceView.getCryptoValue validateBalance: !root.isRequested width: stack.width @@ -188,9 +188,3 @@ StatusModal { ] } -/*##^## -Designer { - D{i:0;autoSize:true;height:480;width:640} -} -##^##*/ - diff --git a/ui/app/AppLayouts/Chat/popups/PinnedMessagesPopup.qml b/ui/app/AppLayouts/Chat/popups/PinnedMessagesPopup.qml index fda4110d52..88e47ec20e 100644 --- a/ui/app/AppLayouts/Chat/popups/PinnedMessagesPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/PinnedMessagesPopup.qml @@ -132,6 +132,7 @@ ModalPopup { reactionsModel: model.reactions linkUrls: model.links isInPinnedPopup: true + transactionParams: model.transactionParameters // This is possible since we have all data loaded before we load qml. // When we fetch messages to fulfill a gap we have to set them at once. diff --git a/ui/app/AppLayouts/Chat/popups/SignTransactionModal.qml b/ui/app/AppLayouts/Chat/popups/SignTransactionModal.qml deleted file mode 100644 index a58f97be38..0000000000 --- a/ui/app/AppLayouts/Chat/popups/SignTransactionModal.qml +++ /dev/null @@ -1,388 +0,0 @@ -import QtQuick 2.13 -import QtQuick.Controls 2.13 -import QtQuick.Layouts 1.13 -import QtQuick.Dialogs 1.3 - -import utils 1.0 -import shared.controls 1.0 - -import StatusQ.Popups 0.1 -import StatusQ.Controls 0.1 - -import shared.views 1.0 -import shared.panels 1.0 -import shared.popups 1.0 -import "../../Wallet/" - -//TODO remove dynamic scoping -StatusModal { - id: root - //% "Send" - header.title: qsTrId("command-button-send") - height: 540 - - property var store - property var contactsStore - - property var selectedAccount - property var selectedRecipient - property var selectedAsset - property var selectedAmount - property var selectedFiatAmount - property bool outgoing: true - - property string trxData: "" - - property alias transactionSigner: transactionSigner - - property var sendTransaction: function(selectedGasLimit, selectedGasPrice, selectedTipLimit, selectedOveralLimit, enteredPassword) { - let success = false - // Not Refactored Yet -// if(root.selectedAsset.address == Constants.zeroAddress){ -// success = root.store.walletModelInst.transactionsView.transferEth( -// selectFromAccount.selectedAccount.address, -// selectRecipient.selectedRecipient.address, -// root.selectedAmount, -// selectedGasLimit, -// gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice, -// gasSelector.selectedTipLimit, -// gasSelector.selectedOverallLimit, -// enteredPassword, -// stack.uuid) -// } else { -// success = root.store.walletModelInst.transactionsView.transferTokens( -// selectFromAccount.selectedAccount.address, -// selectRecipient.selectedRecipient.address, -// root.selectedAsset.address, -// root.selectedAmount, -// selectedGasLimit, -// gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice, -// gasSelector.selectedTipLimit, -// gasSelector.selectedOverallLimit, -// enteredPassword, -// stack.uuid) -// } - -// if(!success){ -// //% "Invalid transaction parameters" -// sendingError.text = qsTrId("invalid-transaction-parameters") -// sendingError.open() -// } - } - - property MessageDialog sendingError: MessageDialog { - id: sendingError - //% "Error sending the transaction" - title: qsTrId("error-sending-the-transaction") - icon: StandardIcon.Critical - standardButtons: StandardButton.Ok - } - - onClosed: { - stack.pop(groupPreview, StackView.Immediate) - } - - contentItem: Item { - width: root.width - height: childrenRect.height - TransactionStackView { - id: stack - anchors.leftMargin: Style.current.padding - anchors.rightMargin: Style.current.padding - initialItem: groupPreview - isLastGroup: stack.currentGroup === groupSignTx - onGroupActivated: { - header.title = group.headerText - btnNext.text = group.footerText - } - TransactionFormGroup { - id: groupSelectAcct - headerText: { - // Not Refactored Yet -// if(trxData.startsWith("0x095ea7b3")){ -// const approveData = JSON.parse(root.store.walletModelInst.tokensView.decodeTokenApproval(selectedRecipient.address, trxData)) -// if(approveData.symbol) -// //% "Authorize %1 %2" -// return qsTrId("authorize--1--2").arg(approveData.amount).arg(approveData.symbol) -// } - return qsTrId("command-button-send"); - } - //% "Continue" - footerText: qsTrId("continue") - showNextBtn: false - onBackClicked: function() { - if(validate()) { - stack.pop() - } - } - StatusAccountSelector { - id: selectFromAccount - // Not Refactored Yet -// accounts: root.store.walletModelInst.accountsView.accounts -// currency: root.store.walletModelInst.balanceView.defaultCurrency - width: stack.width - selectedAccount: root.selectedAccount - //% "Choose account" - label: qsTrId("choose-account") - showBalanceForAssetSymbol: root.selectedAsset.symbol - minRequiredAssetBalance: parseFloat(root.selectedAmount) - onSelectedAccountChanged: if (isValid) { gasSelector.estimateGas() } - } - RecipientSelector { - id: selectRecipient - visible: false - // Not Refactored Yet -// accounts: root.store.walletModelInst.accountsView.accounts - contactsStore: root.contactsStore - selectedRecipient: root.selectedRecipient - readOnly: true - } - } - TransactionFormGroup { - id: groupSelectGas - //% "Network fee" - headerText: qsTrId("network-fee") - footerText: qsTr("Continue") - showNextBtn: false - onBackClicked: function() { - stack.pop() - } - GasSelector { - id: gasSelector - anchors.topMargin: Style.current.padding - // Not Refactored Yet -// gasPrice: parseFloat(root.store.walletModelInst.gasView.gasPrice) -// getGasEthValue: root.store.walletModelInst.gasView.getGasEthValue -// getFiatValue: root.store.walletModelInst.balanceView.getFiatValue -// defaultCurrency: root.store.walletModelInst.balanceView.defaultCurrency - width: stack.width - - property var estimateGas: Backpressure.debounce(gasSelector, 600, function() { - // Not Refactored Yet -// if (!(selectFromAccount.selectedAccount && selectFromAccount.selectedAccount.address && -// selectRecipient.selectedRecipient && selectRecipient.selectedRecipient.address && -// root.selectedAsset && root.selectedAsset.address && -// root.selectedAmount)) { -// selectedGasLimit = 250000 -// defaultGasLimit = selectedGasLimit -// return -// } - -// let gasEstimate = JSON.parse(root.store.walletModelInst.gasView.estimateGas( -// selectFromAccount.selectedAccount.address, -// selectRecipient.selectedRecipient.address, -// root.selectedAsset.address, -// root.selectedAmount, -// trxData)) - -// if (!gasEstimate.success) { -// //% "Error estimating gas: %1" -// let message = qsTrId("error-estimating-gas---1").arg(gasEstimate.error.message) - -// //% ". The transaction will probably fail." -// gasEstimateErrorPopup.confirmationText = message + qsTrId("--the-transaction-will-probably-fail-") -// gasEstimateErrorPopup.open() -// return -// } -// selectedGasLimit = gasEstimate.result -// defaultGasLimit = selectedGasLimit - }) - } - GasValidator { - id: gasValidator - anchors.top: gasSelector.bottom - selectedAccount: selectFromAccount.selectedAccount - selectedAmount: parseFloat(root.selectedAmount) - selectedAsset: root.selectedAsset - selectedGasEthValue: gasSelector.selectedGasEthValue - } - } - - TransactionFormGroup { - id: groupPreview - //% "Transaction preview" - headerText: qsTrId("transaction-preview") - //% "Sign with password" - footerText: qsTrId("sign-with-password") - showBackBtn: false - onNextClicked: function() { - stack.push(groupSignTx, StackView.Immediate) - } - isValid: groupSelectAcct.isValid && groupSelectGas.isValid && pvwTransaction.isValid - - TransactionPreview { - id: pvwTransaction - width: stack.width - fromAccount: selectFromAccount.selectedAccount - gas: { - "value": gasSelector.selectedGasEthValue, - "symbol": "ETH", - "fiatValue": gasSelector.selectedGasFiatValue - } - toAccount: selectRecipient.selectedRecipient - asset: root.selectedAsset - amount: { "value": root.selectedAmount, "fiatValue": root.selectedFiatAmount } - // Not Refactored Yet -// currency: root.store.walletModelInst.balanceView.defaultCurrency - isFromEditable: false - trxData: root.trxData - isGasEditable: true - fromValid: balanceValidator.isValid - gasValid: gasValidator.isValid - onFromClicked: { stack.push(groupSelectAcct, StackView.Immediate) } - onGasClicked: { stack.push(groupSelectGas, StackView.Immediate) } - } - BalanceValidator { - id: balanceValidator - anchors.top: pvwTransaction.bottom - anchors.horizontalCenter: parent.horizontalCenter - account: selectFromAccount.selectedAccount - amount: !!root.selectedAmount ? parseFloat(root.selectedAmount) : 0.0 - asset: root.selectedAsset - } - GasValidator { - id: gasValidator2 - anchors.top: balanceValidator.visible ? balanceValidator.bottom : pvwTransaction.bottom - anchors.topMargin: balanceValidator.visible ? 5 : 0 - anchors.horizontalCenter: parent.horizontalCenter - selectedAccount: selectFromAccount.selectedAccount - selectedAmount: parseFloat(root.selectedAmount) - selectedAsset: root.selectedAsset - selectedGasEthValue: gasSelector.selectedGasEthValue - } - } - TransactionFormGroup { - id: groupSignTx - //% "Sign with password" - headerText: qsTrId("sign-with-password") - //% "Send %1 %2" - footerText: qsTrId("send--1--2").arg(root.selectedAmount).arg(!!root.selectedAsset ? root.selectedAsset.symbol : "") - onBackClicked: function() { - stack.pop() - } - - TransactionSigner { - id: transactionSigner - width: stack.width - // Not Refactored Yet -// signingPhrase: root.store.walletModelInst.utilsView.signingPhrase - } - } - } - } - - leftButtons: [ - StatusRoundButton { - id: btnBack - icon.name: "arrow-right" - icon.width: 20 - icon.height: 16 - icon.rotation: 180 - visible: stack.currentGroup.showBackBtn - enabled: stack.currentGroup.isValid || stack.isLastGroup - onClicked: { - if (typeof stack.currentGroup.onBackClicked === "function") { - return stack.currentGroup.onBackClicked() - } - stack.back() - } - } - ] - - rightButtons: [ - StatusButton { - id: btnNext - //% "Next" - text: qsTrId("next") - enabled: stack.currentGroup.isValid && !stack.currentGroup.isPending - visible: stack.currentGroup.showNextBtn - onClicked: { - const validity = stack.currentGroup.validate() - if (validity.isValid && !validity.isPending) { - if (stack.isLastGroup) { - return root.sendTransaction(gasSelector.selectedGasLimit, - gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice, - gasSelector.selectedTipLimit, - gasSelector.selectedOverallLimit, - transactionSigner.enteredPassword) - } - - if(gasSelector.eip1599Enabled && stack.currentGroup === groupSelectGas && gasSelector.advancedMode){ - if(gasSelector.showPriceLimitWarning || gasSelector.showTipLimitWarning){ - Global.openPopup(transactionSettingsConfirmationPopupComponent, { - currentBaseFee: gasSelector.latestBaseFeeGwei, - currentMinimumTip: gasSelector.perGasTipLimitFloor, - currentAverageTip: gasSelector.perGasTipLimitAverage, - tipLimit: gasSelector.selectedTipLimit, - suggestedTipLimit: gasSelector.perGasTipLimitFloor, // TODO: - priceLimit: gasSelector.selectedOverallLimit, - suggestedPriceLimit: gasSelector.latestBaseFeeGwei + gasSelector.perGasTipLimitFloor, - showPriceLimitWarning: gasSelector.showPriceLimitWarning, - showTipLimitWarning: gasSelector.showTipLimitWarning, - onConfirm: function(){ - stack.next(); - } - }) - return - } - } - - - if (typeof stack.currentGroup.onNextClicked === "function") { - return stack.currentGroup.onNextClicked() - } - stack.next() - } - } - } - ] - - Component { - id: transactionSettingsConfirmationPopupComponent - TransactionSettingsConfirmationPopup { - - } - } - - // Not Refactored Yet -// Connections { -// target: root.store.walletModelInst.transactionsView -// onTransactionWasSent: { -// try { -// let response = JSON.parse(txResult) -// if (response.uuid !== stack.uuid) -// return - -// let transactionId = response.result - -// if (!response.success) { -// if (Utils.isInvalidPasswordMessage(transactionId)){ -// //% "Wrong password" -// transactionSigner.validationError = qsTrId("wrong-password") -// return -// } -// sendingError.text = transactionId -// return sendingError.open() -// } - -// // Not Refactored Yet -//// chatsModel.transactions.acceptRequestTransaction(transactionId, -//// messageId, -//// userProfile.pubKey + transactionId.substr(2)) - -// //% "Transaction pending..." -// toastMessage.title = qsTrId("ens-transaction-pending") -// toastMessage.source = Style.svg("loading") -// toastMessage.iconColor = Style.current.primary -// toastMessage.iconRotates = true -// toastMessage.link = `${root.store.walletModelInst.utilsView.etherscanLink}/${transactionId}` -// toastMessage.open() - -// root.close() -// } catch (e) { -// console.error('Error parsing the response', e) -// } -// } -// } -} - diff --git a/ui/app/AppLayouts/Chat/stores/RootStore.qml b/ui/app/AppLayouts/Chat/stores/RootStore.qml index e88f8e86dd..7d6b1b8895 100644 --- a/ui/app/AppLayouts/Chat/stores/RootStore.qml +++ b/ui/app/AppLayouts/Chat/stores/RootStore.qml @@ -71,10 +71,16 @@ QtObject { property var accounts: walletSectionAccounts.model property var currentAccount: walletSectionCurrent - property var currentCurrency: walletSection.currentCurrency + + property string currentCurrency: walletSection.currentCurrency + property string signingPhrase: walletSection.signingPhrase + + property string gasPrice: profileSectionModule.ensUsernamesModule.gasPrice property ListModel addToGroupContacts: ListModel {} + property var walletSectionTransactionsInst: walletSectionTransactions + function reCalculateAddToGroupContacts(channel) { const contacts = getContactListObject() @@ -355,4 +361,63 @@ QtObject { callback: result.callback } } + + function getPubkey() { + return userProfile.getPubKey() + } + + function getFiatValue(balance, cryptoSymbo, fiatSymbol) { + return profileSectionModule.ensUsernamesModule.getFiatValue(balance, cryptoSymbo, fiatSymbol) + } + + function acceptRequestTransaction(transactionHash, messageId, signature) { + return currentChatContentModule().inputAreaModule.acceptRequestTransaction(transactionHash, messageId, signature) + } + + function acceptAddressRequest(messageId, address) { + currentChatContentModule().inputAreaModule.acceptAddressRequest(messageId, address) + } + + function declineAddressRequest(messageId) { + currentChatContentModule().inputAreaModule.declineAddressRequest(messageId) + } + + function declineRequest(messageId) { + currentChatContentModule().inputAreaModule.declineRequest(messageId) + } + + function getGasEthValue(gweiValue, gasLimit) { + return profileSectionModule.ensUsernamesModule.getGasEthValue(gweiValue, gasLimit) + } + + function estimateGas(from_addr, to, assetAddress, value, data) { + return walletSectionTransactions.estimateGas(from_addr, to, assetAddress, value, data) + } + + function transferEth(from, to, amount, gasLimit, gasPrice, tipLimit, overallLimit, password, uuid) { + return walletSectionTransactions.transferEth(from, to, amount, gasLimit, gasPrice, tipLimit, + overallLimit, password, uuid); + } + + function transferTokens(from, to, address, amount, gasLimit, gasPrice, tipLimit, overallLimit, password, uuid) { + return walletSectionTransactions.transferTokens(from, to, address, amount, gasLimit, + gasPrice, tipLimit, overallLimit, password, uuid); + } + + function getAccountNameByAddress(address) { + return walletSectionAccounts.getAccountNameByAddress(address) + } + + function getAccountIconColorByAddress(address) { + return walletSectionAccounts.getAccountIconColorByAddress(address) + } + + function getAccountAssetsByAddress(address) { + walletSectionAccounts.setAddressForAssets(address) + return walletSectionAccounts.getAccountAssetsByAddress() + } + + function fetchGasPrice() { + profileSectionModule.ensUsernamesModule.fetchGasPrice() + } } diff --git a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml index a92cbf6c20..5cf8c81ff0 100644 --- a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml @@ -92,7 +92,6 @@ Item { chatContentModule.inputAreaModule.requestAddress(address, amount, tokenAddress) - txModalLoader.close() } function requestTransaction(address, amount, tokenAddress, tokenDecimals = 18) { amount = globalUtils.eth2Wei(amount.toString(), tokenDecimals) @@ -254,7 +253,8 @@ Item { alias: chatContentModule.chatDetails.name, // Do we need the alias for real or name works? identicon: chatContentModule.chatDetails.icon, name: chatContentModule.chatDetails.name, - type: RecipientSelector.Type.Contact + type: RecipientSelector.Type.Contact, + ensVerified: true } } selectRecipient.selectedType: RecipientSelector.Type.Contact diff --git a/ui/app/AppLayouts/Chat/views/ChatMessagesView.qml b/ui/app/AppLayouts/Chat/views/ChatMessagesView.qml index d75bb06d03..f280c3b82c 100644 --- a/ui/app/AppLayouts/Chat/views/ChatMessagesView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatMessagesView.qml @@ -324,6 +324,7 @@ Item { editModeOn: model.editMode isEdited: model.isEdited linkUrls: model.links + transactionParams: model.transactionParameters // This is possible since we have all data loaded before we load qml. // When we fetch messages to fulfill a gap we have to set them at once. diff --git a/ui/app/AppLayouts/stores/RootStore.qml b/ui/app/AppLayouts/stores/RootStore.qml index b60583e397..046b409a1e 100644 --- a/ui/app/AppLayouts/stores/RootStore.qml +++ b/ui/app/AppLayouts/stores/RootStore.qml @@ -50,6 +50,8 @@ QtObject { property real volume: !!localAccountSensitiveSettings ? localAccountSensitiveSettings.volume : 0.0 property bool notificationSoundsEnabled: !!localAccountSensitiveSettings ? localAccountSensitiveSettings.notificationSoundsEnabled : false + property var walletSectionTransactionsInst: walletSectionTransactions + function createCommunity(communityName, communityDescription, checkedMembership, ensOnlySwitchChecked, communityColor, communityImage, imageCropperModalaX, imageCropperModalaY, imageCropperModalbX, imageCropperModalbY) { communitiesModuleInst.createCommunity(communityName, communityDescription, checkedMembership, ensOnlySwitchChecked, communityColor, communityImage, imageCropperModalaX, imageCropperModalaY, imageCropperModalbX, imageCropperModalbY); } diff --git a/ui/imports/shared/controls/ContactSelector.qml b/ui/imports/shared/controls/ContactSelector.qml index e1df982acb..817a631645 100644 --- a/ui/imports/shared/controls/ContactSelector.qml +++ b/ui/imports/shared/controls/ContactSelector.qml @@ -54,7 +54,7 @@ Item { if (!selectedContact) { return root.isValid } - let isValidAddress = Utils.isValidAddress(selectedContact.publicKey) + let isValidAddress = Utils.isValidAddress(selectedContact.address) let isDefaultValue = selectedContact.alias === selectAContact let isValid = (selectedContact.ensVerified && isValidAddress) || isPending || isValidAddress select.validationError = "" @@ -147,12 +147,12 @@ Item { onResolved: { root.isResolvedAddress = true var selectedContact = root.selectedContact - selectedContact.publicKey = resolvedAddress + selectedContact.address = resolvedAddress root.selectedContact = selectedContact } onIsPendingChanged: { if (isPending) { - root.selectedContact.publicKey = "" + root.selectedContact.address = "" } } } @@ -197,7 +197,7 @@ Item { height: 16 } StatusBaseText { - text: currentContact.publicKey + text: currentContact.address width: 85 elide: Text.ElideMiddle color: Theme.palette.baseColor1 diff --git a/ui/imports/shared/popups/SignTransactionModal.qml b/ui/imports/shared/popups/SignTransactionModal.qml index d392710310..e7954a7a83 100644 --- a/ui/imports/shared/popups/SignTransactionModal.qml +++ b/ui/imports/shared/popups/SignTransactionModal.qml @@ -28,45 +28,58 @@ StatusModal { property var selectedAsset property var selectedAmount property var selectedFiatAmount + property var selectedType: RecipientSelector.Type.Address property bool outgoing: true property string msgId: "" property string trxData: "" property alias transactionSigner: transactionSigner - property var sendTransaction: function(selectedGasLimit, selectedGasPrice, selectedTipLimit, selectedOveralLimit, enteredPassword) { - // Not Refactored Yet -// let success = false -// if(root.selectedAsset.address == Constants.zeroAddress){ -// success = root.store.walletModelInst.transactionsView.transferEth( -// selectFromAccount.selectedAccount.address, -// selectRecipient.selectedRecipient.address, -// root.selectedAmount, -// selectedGasLimit, -// gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice, -// gasSelector.selectedTipLimit, -// gasSelector.selectedOverallLimit, -// enteredPassword, -// stack.uuid) -// } else { -// success = root.store.walletModelInst.transactionsView.transferTokens( -// selectFromAccount.selectedAccount.address, -// selectRecipient.selectedRecipient.address, -// root.selectedAsset.address, -// root.selectedAmount, -// selectedGasLimit, -// gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice, -// gasSelector.selectedTipLimit, -// gasSelector.selectedOverallLimit, -// enteredPassword, -// stack.uuid) -// } + property var sendTransaction: function() { + stack.currentGroup.isPending = true + let success = false + if(root.selectedAsset.address === "" || root.selectedAsset.address === Constants.zeroAddress){ + success = root.store.transferEth( + selectFromAccount.selectedAccount.address, + selectRecipient.selectedRecipient.address, + root.selectedAmount, + gasSelector.selectedGasLimit, + gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice, + gasSelector.selectedTipLimit, + gasSelector.selectedOverallLimit, + transactionSigner.enteredPassword, + stack.uuid) + } else { + success = root.store.transferTokens( + selectFromAccount.selectedAccount.address, + selectRecipient.selectedRecipient.address, + root.selectedAsset.address, + root.selectedAmount, + gasSelector.selectedGasLimit, + gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice, + gasSelector.selectedTipLimit, + gasSelector.selectedOverallLimit, + transactionSigner.enteredPassword, + stack.uuid) + } -// if(!success){ -// //% "Invalid transaction parameters" -// sendingError.text = qsTrId("invalid-transaction-parameters") -// sendingError.open() -// } + if(!success){ + //% "Invalid transaction parameters" + sendingError.text = qsTrId("invalid-transaction-parameters") + sendingError.open() + } else { + // TODO remove this else once the thread and connection are back + stack.currentGroup.isPending = false + //% "Transaction pending..." + Global.toastMessage.title = qsTrId("ens-transaction-pending") + Global.toastMessage.source = Style.svg("loading") + Global.toastMessage.iconColor = Style.current.primary + Global.toastMessage.iconRotates = true + // Refactor this + // Global.toastMessage.link = `${walletModel.utilsView.etherscanLink}/${response.result}` + Global.toastMessage.open() + root.close() + } } property MessageDialog sendingError: MessageDialog { @@ -92,7 +105,7 @@ StatusModal { initialItem: groupPreview isLastGroup: stack.currentGroup === groupSignTx onGroupActivated: { - root.title = group.headerText + root.header.title = group.headerText btnNext.text = group.footerText } TransactionFormGroup { @@ -117,8 +130,7 @@ StatusModal { } StatusAccountSelector { id: selectFromAccount - // Not Refactored Yet -// accounts: root.store.walletModelInst.accountsView.accounts + accounts: root.store.accounts currency: root.store.currentCurrency width: stack.width selectedAccount: root.selectedAccount @@ -131,10 +143,10 @@ StatusModal { RecipientSelector { id: selectRecipient visible: false - // Not Refactored Yet -// accounts: root.store.walletModelInst.accountsView.accounts + accounts: root.store.accounts contactsStore: root.contactsStore selectedRecipient: root.selectedRecipient + selectedType: root.selectedType readOnly: true } } @@ -334,44 +346,31 @@ StatusModal { TransactionSettingsConfirmationPopup { } } - // Not Refactored Yet -// Connections { -// target: root.store.walletModelInst.transactionsView -// onTransactionWasSent: { -// try { -// let response = JSON.parse(txResult) -// if (response.uuid !== stack.uuid) -// return + Connections { + target: root.store.walletSectionTransactionsInst + onTransactionSent: { + try { + let response = JSON.parse(txResult) + if (response.uuid !== stack.uuid) + return -// let transactionId = response.result + let transactionId = response.result -// if (!response.success) { -// if (Utils.isInvalidPasswordMessage(transactionId)){ -// //% "Wrong password" -// transactionSigner.validationError = qsTrId("wrong-password") -// return -// } -// sendingError.text = transactionId -// return sendingError.open() -// } - -// // Not Refactored Yet -// root.store.chatsModelInst.transactions.acceptRequestTransaction(transactionId, msgId, -// root.store.profileModelInst.profile.pubKey + transactionId.substr(2)) - -// //% "Transaction pending..." -// Global.toastMessage.title = qsTrId("ens-transaction-pending") -// Global.toastMessage.source = Style.svg("loading") -// Global.toastMessage.iconColor = Style.current.primary -// Global.toastMessage.iconRotates = true -// Global.toastMessage.link = `${root.store.walletModelInst.utilsView.etherscanLink}/${transactionId}` -// Global.toastMessage.open() - -// root.close() -// } catch (e) { -// console.error('Error parsing the response', e) -// } -// } -// } + if (!response.success) { + if (Utils.isInvalidPasswordMessage(transactionId)){ + //% "Wrong password" + transactionSigner.validationError = qsTrId("wrong-password") + return + } + sendingError.text = transactionId + return sendingError.open() + } + root.store.acceptRequestTransaction(transactionId, msgId, root.store.getPubkey() + transactionId.substr(2)) + root.close() + } catch (e) { + console.error('Error parsing the response', e) + } + } + } } diff --git a/ui/imports/shared/views/TransactionPreview.qml b/ui/imports/shared/views/TransactionPreview.qml index 92acb1b38b..e588175876 100644 --- a/ui/imports/shared/views/TransactionPreview.qml +++ b/ui/imports/shared/views/TransactionPreview.qml @@ -161,7 +161,7 @@ Item { } PropertyChanges { target: idtToContact - source: root.toAccount.identicon + image.source: root.toAccount.identicon visible: true } PropertyChanges { @@ -263,6 +263,7 @@ Item { anchors.verticalCenter: parent.verticalCenter image.width: 32 image.height: 32 + image.isIdenticon: true } SVGImage { id: toInvalid diff --git a/ui/imports/shared/views/chat/AcceptTransactionView.qml b/ui/imports/shared/views/chat/AcceptTransactionView.qml index 0cd3d18767..c7b48f1ceb 100644 --- a/ui/imports/shared/views/chat/AcceptTransactionView.qml +++ b/ui/imports/shared/views/chat/AcceptTransactionView.qml @@ -16,10 +16,10 @@ Item { property var store property var contactsStore - property var commandParametersObject property var token property string tokenAmount property string fiatValue + property var selectedRecipient property int state: Constants.addressRequested Separator { @@ -80,13 +80,11 @@ Item { anchors.fill: parent cursorShape: Qt.PointingHandCursor onClicked: { - // Not Refactored Yet -// if (root.state === Constants.addressRequested) { -// root.store.chatsModelInst.transactions.declineAddressRequest(messageId) -// } else if (root.state === Constants.transactionRequested) { -// root.store.chatsModelInst.transactions.declineRequest(messageId) -// } - + if (root.state === Constants.addressRequested) { + root.store.declineAddressRequest(messageId) + } else if (root.state === Constants.transactionRequested) { + root.store.declineRequest(messageId) + } } } } @@ -102,32 +100,19 @@ Item { Component { id: signTxComponent SignTransactionModal { + anchors.centerIn: parent store: root.store contactsStore: root.contactsStore msgId: messageId - onOpened: { - // Not Refactored Yet -// root.store.walletModelInst.gasView.getGasPrice() - } - onClosed: { - destroy(); - } + onOpened: root.store.fetchGasPrice() + onClosed: destroy() onOpenGasEstimateErrorPopup: { gasEstimateErrorPopup.confirmationText = message + qsTrId("--the-transaction-will-probably-fail-"); gasEstimateErrorPopup.open(); return; } - selectedAccount: {} - selectedRecipient: { - return { - address: commandParametersObject.address, - // Not Refactored Yet -// identicon: root.store.chatsModelInst.channelView.activeChannel.identicon, -// name: root.store.chatsModelInst.channelView.activeChannel.name, - type: RecipientSelector.Type.Contact - } - } + selectedRecipient: root.selectedRecipient selectedAsset: token selectedAmount: tokenAmount selectedFiatAmount: fiatValue @@ -136,19 +121,12 @@ Item { SelectAccountModal { id: selectAccountModal - // Not Refactored Yet -// accounts: root.store.walletModelInst.accountsView.accounts -// currency: root.store.walletModelInst.balanceView.defaultCurrency + anchors.centerIn: parent + accounts: root.store.accounts + currency: root.store.currentCurrency onSelectAndShareAddressButtonClicked: { - // Not Refactored Yet -// root.store.chatsModelInst.transactions.acceptAddressRequest(messageId, accountSelector.selectedAccount.address) -// selectAccountModal.close() + root.store.acceptAddressRequest(messageId, accountSelector.selectedAccount.address) + selectAccountModal.close() } } } - -/*##^## -Designer { - D{i:0;formeditorColor:"#ffffff";formeditorZoom:1.25} -} -##^##*/ diff --git a/ui/imports/shared/views/chat/CompactMessageView.qml b/ui/imports/shared/views/chat/CompactMessageView.qml index 1e84451d0b..0012e72655 100644 --- a/ui/imports/shared/views/chat/CompactMessageView.qml +++ b/ui/imports/shared/views/chat/CompactMessageView.qml @@ -57,6 +57,8 @@ Item { property bool editModeOn: false property string linkUrls: "" + property var transactionParams + signal openStickerPackPopup(string stickerPackId) signal addEmoji(bool isProfileClick, bool isSticker, bool isImage , var image, bool emojiOnly, bool hideEmojiPicker) signal clickMessage(bool isProfileClick, bool isSticker, bool isImage, var image, bool emojiOnly, bool hideEmojiPicker, bool isReply, bool isRightClickOnImage, string imageSource) @@ -621,7 +623,8 @@ Item { anchors.topMargin: active ? (chatName.visible ? 4 : 6) : 0 sourceComponent: Component { TransactionBubbleView { - //store: rootStore + transactionParams: root.transactionParams + store: root.store contactsStore: root.contactsStore } } diff --git a/ui/imports/shared/views/chat/MessageView.qml b/ui/imports/shared/views/chat/MessageView.qml index e1c7f0b23b..0a4d999a43 100644 --- a/ui/imports/shared/views/chat/MessageView.qml +++ b/ui/imports/shared/views/chat/MessageView.qml @@ -41,6 +41,7 @@ Column { property var reactionsModel: [] property string linkUrls: "" property bool isInPinnedPopup: false // The pinned popup limits the number of buttons shown + property var transactionParams property int prevMessageIndex: -1 property var prevMessageAsJsonObj @@ -360,6 +361,8 @@ Column { linkUrls: root.linkUrls isInPinnedPopup: root.isInPinnedPopup + transactionParams: root.transactionParams + onAddEmoji: { root.clickMessage(isProfileClick, isSticker, isImage , image, emojiOnly, hideEmojiPicker) } diff --git a/ui/imports/shared/views/chat/TransactionBubbleView.qml b/ui/imports/shared/views/chat/TransactionBubbleView.qml index cebdab439e..7bda167e6d 100644 --- a/ui/imports/shared/views/chat/TransactionBubbleView.qml +++ b/ui/imports/shared/views/chat/TransactionBubbleView.qml @@ -5,6 +5,7 @@ import shared.panels 1.0 import shared.popups 1.0 import shared.views.chat 1.0 import shared.controls.chat 1.0 +import shared.controls 1.0 Item { id: root @@ -14,12 +15,14 @@ Item { property var store property var contactsStore - property var commandParametersObject: { + property var transactionParams + + property var transactionParamsObject: { try { - return JSON.parse(commandParameters) + return JSON.parse(transactionParams) } catch (e) { console.error('Error parsing command parameters') - console.error('JSON:', commandParameters) + console.error('JSON:', transactionParams) console.error('Error:', e) return { id: "", @@ -34,28 +37,46 @@ Item { } } - property var token: JSON.parse(commandParametersObject.contract) // TODO: handle {} - property string tokenAmount: commandParametersObject.value + property var token:{ + try { + return JSON.parse(transactionParamsObject.contract) + } catch (e) { + console.error('Error parsing command parameters') + console.error('JSON:', transactionParamsObject.contract) + console.error('Error:', e) + return "" + } + } + + property var selectedRecipient: { + return { + address: transactionParamsObject.address, + identicon: senderIcon, + name: senderDisplayName, + type: RecipientSelector.Type.Contact, + alias: senderDisplayName + } + } + + property string tokenAmount: transactionParamsObject.value property string tokenSymbol: token.symbol || "" property string fiatValue: { if (!tokenAmount || !token.symbol) { return "0" } - // Not Refactored Yet -// var defaultFiatSymbol = root.store.walletModelInst.balanceView.defaultCurrency -// return root.store.walletModelInst.balanceView.getFiatValue(tokenAmount, token.symbol, defaultFiatSymbol) + " " + defaultFiatSymbol.toUpperCase() - return "0" + var defaultFiatSymbol = root.store.currentCurrency + return root.store.getFiatValue(tokenAmount, token.symbol, defaultFiatSymbol) + " " + defaultFiatSymbol.toUpperCase() } - property int state: commandParametersObject.commandState + property int state: transactionParamsObject.commandState // Any transaction where isCurrentUser is true is actually outgoing transaction. property bool outgoing: isCurrentUser property int innerMargin: 12 - property bool isError: commandParametersObject.contract === "{}" + property bool isError: transactionParamsObject.contract === "{}" onTokenSymbolChanged: { if (!!tokenSymbol) { - tokenImage.source = `../../../../img/tokens/${root.tokenSymbol}.png` + tokenImage.source = Style.png("tokens/"+root.tokenSymbol) } } @@ -189,7 +210,7 @@ Item { token: root.token fiatValue: root.fiatValue tokenAmount: root.tokenAmount - commandParametersObject: root.commandParametersObject + selectedRecipient: root.selectedRecipient } } @@ -197,31 +218,18 @@ Item { id: signAndSendComponent SendTransactionButton { - // outgoing: root.outgoing - // Not Refactored Yet -// acc: root.store.walletModelInst.accountsView.focusedAccount selectedAsset: token selectedAmount: tokenAmount selectedFiatAmount: fiatValue - fromAddress: commandParametersObject.fromAddress - selectedRecipient: { - return { - address: commandParametersObject.address, - // Not Refactored Yet -// identicon: root.store.chatsModelInst.channelView.activeChannel.identicon, -// name: root.store.chatsModelInst.channelView.activeChannel.name, - type: RecipientSelector.Type.Contact - } - } + fromAddress: transactionParamsObject.fromAddress + selectedRecipient: root.selectedRecipient onSendTransaction: { - // Not Refactored Yet -// root.store.walletModelInst.accountsView.setFocusedAccountByAddress(fromAddress); -// Global.openPopup(signTxComponent, {selectedAccount: { -// name: acc.name, -// address: fromAddress, -// iconColor: acc.iconColor, -// assets: acc.assets -// }}) + Global.openPopup(signTxComponent, {selectedAccount: { + name: root.store.getAccountNameByAddress(fromAddress), + address: fromAddress, + color: root.store.getAccountIconColorByAddress(fromAddress), + assets: root.store.getAccountAssetsByAddress(fromAddress) + }}) } } } @@ -229,19 +237,17 @@ Item { Component { id: signTxComponent SignTransactionModal { + anchors.centerIn: parent store: root.store contactsStore: root.contactsStore - selectedAsset: root.selectedAsset - selectedAmount: root.selectedAmount + selectedAsset: root.token + selectedAmount: root.tokenAmount selectedRecipient: root.selectedRecipient - selectedFiatAmount: root.selectedFiatAmount - onOpened: { - // Not Refactored Yet -// root.store.walletModelInst.gasView.getGasPrice(); - } - onClosed: { - destroy(); - } + selectedFiatAmount: root.fiatValue + selectedType: RecipientSelector.Type.Contact + onOpened: root.store.fetchGasPrice() + onClosed: destroy() + msgId: messageId } }