fix(@desktop/chat): sign and send appears for both recipient and sender when sharing the address

The reason for this issue is a message where recipient accepted to share his address with sender.
In that message recipient's public key is set as a "from" property of a "Message" object and we
cannot determine which of two users has initiated transaction actually.

This is fixed checking if the "from" address from the "commandParameters" object of the "Message"
is contained as an address in the wallet of logged in user. If yes, means that currently logged in
user has initiated a transaction (he is a sender), otherwise currently logged in user is a
recipient.

We were just sending a transaction, without notifying message about that. Now we call
callPrivateRPC("acceptRequestTransaction".prefix, %* [transactionHash, messageId, signature])
and that notifies message about the change, but only on the sender side. Appropriate message
on the recipient side was not notified about the change. That need to be checked.
This commit is contained in:
Sale Djenic 2021-07-12 21:30:17 +02:00 committed by Iuri Matias
parent 88b990a21a
commit ecb2bac6e5
13 changed files with 115 additions and 73 deletions

View File

@ -36,7 +36,13 @@ proc handleChatEvents(self: ChatController) =
for message in evArgs.messages: for message in evArgs.messages:
if (message.replace != ""): if (message.replace != ""):
# Delete the message that this message replaces # Delete the message that this message replaces
self.view.deleteMessage(message.chatId, message.replace) if (not self.view.deleteMessage(message.chatId, message.replace)):
# In cases where new message need to replace a message which already replaced initial message
# "replace" property contains id of the initial message, but not the id of the message which
# replaced the initial one. That's why we call this proce here in case message with "message.replace"
# was not deleted.
discard self.view.deleteMessageWhichReplacedMessageWithId(message.chatId, message.replace)
self.view.reactions.push(evArgs.emojiReactions) self.view.reactions.push(evArgs.emojiReactions)
if (evArgs.communities.len > 0): if (evArgs.communities.len > 0):
for community in evArgs.communities.mitems: for community in evArgs.communities.mitems:
@ -66,7 +72,7 @@ proc handleChatEvents(self: ChatController) =
self.status.events.on("messageDeleted") do(e: Args): self.status.events.on("messageDeleted") do(e: Args):
var evArgs = MessageArgs(e) var evArgs = MessageArgs(e)
self.view.deleteMessage(evArgs.channel, evArgs.id) discard self.view.deleteMessage(evArgs.channel, evArgs.id)
self.status.events.on("chatHistoryCleared") do(e: Args): self.status.events.on("chatHistoryCleared") do(e: Args):
var args = ChannelArgs(e) var args = ChannelArgs(e)

View File

@ -430,8 +430,11 @@ QtObject:
proc hideLoadingIndicator*(self: ChatsView) {.slot.} = proc hideLoadingIndicator*(self: ChatsView) {.slot.} =
self.messageView.hideLoadingIndicator() self.messageView.hideLoadingIndicator()
proc deleteMessage*(self: ChatsView, channelId: string, messageId: string) = proc deleteMessage*(self: ChatsView, channelId: string, messageId: string): bool =
self.messageView.deleteMessage(channelId, messageId) result = self.messageView.deleteMessage(channelId, messageId)
proc deleteMessageWhichReplacedMessageWithId*(self: ChatsView, channelId: string, messageId: string): bool =
result = self.messageView.deleteMessageWhichReplacedMessageWithId(channelId, messageId)
proc addPinnedMessages*(self: ChatsView, pinnedMessages: seq[Message]) = proc addPinnedMessages*(self: ChatsView, pinnedMessages: seq[Message]) =
self.messageView.addPinnedMessages(pinnedMessages) self.messageView.addPinnedMessages(pinnedMessages)

View File

@ -103,8 +103,10 @@ QtObject:
proc getMessage*(self: ChatMessageList, messageId: string): Message = proc getMessage*(self: ChatMessageList, messageId: string): Message =
return self.messages[self.messageIndex[messageId]] return self.messages[self.messageIndex[messageId]]
proc deleteMessage*(self: ChatMessageList, messageId: string) = proc deleteMessage*(self: ChatMessageList, messageId: string): bool =
if not self.messageIndex.hasKey(messageId): return if not self.messageIndex.hasKey(messageId):
return false
let messageIndex = self.messageIndex[messageId] let messageIndex = self.messageIndex[messageId]
self.beginRemoveRows(newQModelIndex(), messageIndex, messageIndex) self.beginRemoveRows(newQModelIndex(), messageIndex, messageIndex)
self.messages.delete(messageIndex) self.messages.delete(messageIndex)
@ -115,10 +117,12 @@ QtObject:
self.messageIndex[self.messages[i].id] = i self.messageIndex[self.messages[i].id] = i
self.endRemoveRows() self.endRemoveRows()
return true
proc deleteMessagesByChatId*(self: ChatMessageList, chatId: string) = proc deleteMessagesByChatId*(self: ChatMessageList, chatId: string) =
let messages = self.messages.filter(m => m.chatId == chatId) let messages = self.messages.filter(m => m.chatId == chatId)
for message in messages: for message in messages:
self.deleteMessage(message.id) discard self.deleteMessage(message.id)
proc replaceMessage*(self: ChatMessageList, message: Message) = proc replaceMessage*(self: ChatMessageList, message: Message) =
let msgIdx = self.messageIndex[message.id] let msgIdx = self.messageIndex[message.id]
@ -382,7 +386,7 @@ QtObject:
if m.fromAuthor == publicKey: # Can't delete on a loop if m.fromAuthor == publicKey: # Can't delete on a loop
msgIdxToDelete.add(m.id) msgIdxToDelete.add(m.id)
for m in msgIdxToDelete: for m in msgIdxToDelete:
self.deleteMessage(m) discard self.deleteMessage(m)
proc getID*(self: ChatMessageList):string {.slot.} = proc getID*(self: ChatMessageList):string {.slot.} =
self.id self.id

View File

@ -415,9 +415,24 @@ QtObject:
self.unreadDirectMessagesAndMentionsCount = currentUnreadDirectMessagesAndMentionsCount self.unreadDirectMessagesAndMentionsCount = currentUnreadDirectMessagesAndMentionsCount
self.unreadDirectMessagesAndMentionsCountChanged() self.unreadDirectMessagesAndMentionsCountChanged()
proc deleteMessage*(self: MessageView, channelId: string, messageId: string) = proc deleteMessage*(self: MessageView, channelId: string, messageId: string): bool =
self.messageList[channelId].deleteMessage(messageId) result = self.messageList[channelId].deleteMessage(messageId)
self.hideMessage(messageId) if (result):
self.hideMessage(messageId)
proc deleteMessageWhichReplacedMessageWithId*(self: MessageView, channelId: string, messageId: string): bool =
var msgIdToBeDeleted: string
for message in self.messageList[channelId].messages:
if (message.replace == messageId):
msgIdToBeDeleted = message.id
break
if (msgIdToBeDeleted.len == 0):
return false
result = self.messageList[channelId].deleteMessage(msgIdToBeDeleted)
if (result):
self.hideMessage(msgIdToBeDeleted)
proc removeMessagesByUserId(self: MessageView, publicKey: string) {.slot.} = proc removeMessagesByUserId(self: MessageView, publicKey: string) {.slot.} =
for k in self.messageList.keys: for k in self.messageList.keys:

View File

@ -34,3 +34,6 @@ QtObject:
proc declineRequest*(self: TransactionsView, messageId: string) {.slot.} = proc declineRequest*(self: TransactionsView, messageId: string) {.slot.} =
self.status.chat.declineRequestTransaction(messageId) self.status.chat.declineRequestTransaction(messageId)
proc acceptRequestTransaction*(self: TransactionsView, transactionHash: string, messageId: string, signature: string) {.slot.} =
self.status.chat.acceptRequestTransaction(transactionHash, messageId, signature)

View File

@ -416,6 +416,10 @@ proc requestAddressForTransaction*(self: ChatModel, chatId: string, fromAddress:
let response = status_chat_commands.requestAddressForTransaction(chatId, fromAddress, amount, address) let response = status_chat_commands.requestAddressForTransaction(chatId, fromAddress, amount, address)
discard self.processMessageUpdateAfterSend(response) discard self.processMessageUpdateAfterSend(response)
proc acceptRequestTransaction*(self: ChatModel, transactionHash: string, messageId: string, signature: string) =
let response = status_chat_commands.acceptRequestTransaction(transactionHash, messageId, signature)
discard self.processMessageUpdateAfterSend(response)
proc requestTransaction*(self: ChatModel, chatId: string, fromAddress: string, amount: string, tokenAddress: string) = proc requestTransaction*(self: ChatModel, chatId: string, fromAddress: string, amount: string, tokenAddress: string) =
let address = if (tokenAddress == ZERO_ADDRESS): "" else: tokenAddress let address = if (tokenAddress == ZERO_ADDRESS): "" else: tokenAddress
let response = status_chat_commands.requestTransaction(chatId, fromAddress, amount, address) let response = status_chat_commands.requestTransaction(chatId, fromAddress, amount, address)

View File

@ -32,6 +32,9 @@ type CommandParameters* = object
commandState*: int commandState*: int
signature*: string signature*: string
proc `$`*(self: CommandParameters): string =
result = fmt"CommandParameters(id:{self.id}, fromAddr:{self.fromAddress}, addr:{self.address}, contract:{self.contract}, value:{self.value}, transactionHash:{self.transactionHash}, commandState:{self.commandState}, signature:{self.signature})"
type Message* = object type Message* = object
alias*: string alias*: string
userName*: string userName*: string

View File

@ -1,24 +1,20 @@
import ../libstatus/settings as status_settings
proc formatChatUpdate(response: JsonNode): (seq[Chat], seq[Message]) = proc formatChatUpdate(response: JsonNode): (seq[Chat], seq[Message]) =
var chats: seq[Chat] = @[] var chats: seq[Chat] = @[]
var messages: seq[Message] = @[] var messages: seq[Message] = @[]
let pk = status_settings.getSetting[string](Setting.PublicKey, "0x0")
if response["result"]{"messages"} != nil: if response["result"]{"messages"} != nil:
for jsonMsg in response["result"]["messages"]: for jsonMsg in response["result"]["messages"]:
messages.add(jsonMsg.toMessage(pk)) messages.add(jsonMsg.toMessage())
if response["result"]{"chats"} != nil: if response["result"]{"chats"} != nil:
for jsonChat in response["result"]["chats"]: for jsonChat in response["result"]["chats"]:
chats.add(jsonChat.toChat) chats.add(jsonChat.toChat)
result = (chats, messages) result = (chats, messages)
proc processChatUpdate(self: ChatModel, response: JsonNode): (seq[Chat], seq[Message]) = proc processChatUpdate(self: ChatModel, response: JsonNode): (seq[Chat], seq[Message]) =
let pk = status_settings.getSetting[string](Setting.PublicKey, "0x0")
var chats: seq[Chat] = @[] var chats: seq[Chat] = @[]
var messages: seq[Message] = @[] var messages: seq[Message] = @[]
if response{"result"}{"messages"} != nil: if response{"result"}{"messages"} != nil:
for jsonMsg in response["result"]["messages"]: for jsonMsg in response["result"]["messages"]:
messages.add(jsonMsg.toMessage(pk)) messages.add(jsonMsg.toMessage())
if response{"result"}{"chats"} != nil: if response{"result"}{"chats"} != nil:
for jsonChat in response["result"]["chats"]: for jsonChat in response["result"]["chats"]:
let chat = jsonChat.toChat let chat = jsonChat.toChat

View File

@ -77,18 +77,16 @@ proc parseChatMessagesResponse*(rpcResult: JsonNode): (string, seq[Message]) =
var messages: seq[Message] = @[] var messages: seq[Message] = @[]
let messagesObj = rpcResult{"messages"} let messagesObj = rpcResult{"messages"}
if(messagesObj != nil and messagesObj.kind != JNull): if(messagesObj != nil and messagesObj.kind != JNull):
let pk = status_settings.getSetting[string](Setting.PublicKey, "0x0")
for jsonMsg in messagesObj: for jsonMsg in messagesObj:
messages.add(jsonMsg.toMessage(pk)) messages.add(jsonMsg.toMessage())
return (rpcResult{"cursor"}.getStr, messages) return (rpcResult{"cursor"}.getStr, messages)
proc parseActivityCenterNotifications*(rpcResult: JsonNode): (string, seq[ActivityCenterNotification]) = proc parseActivityCenterNotifications*(rpcResult: JsonNode): (string, seq[ActivityCenterNotification]) =
let pk = status_settings.getSetting[string](Setting.PublicKey, "0x0")
var notifs: seq[ActivityCenterNotification] = @[] var notifs: seq[ActivityCenterNotification] = @[]
var msg: Message var msg: Message
if rpcResult{"notifications"}.kind != JNull: if rpcResult{"notifications"}.kind != JNull:
for jsonMsg in rpcResult["notifications"]: for jsonMsg in rpcResult["notifications"]:
notifs.add(jsonMsg.toActivityCenterNotification(pk)) notifs.add(jsonMsg.toActivityCenterNotification())
return (rpcResult{"cursor"}.getStr, notifs) return (rpcResult{"cursor"}.getStr, notifs)
proc rpcChatMessages*(chatId: string, cursorVal: JsonNode, limit: int, success: var bool): string = proc rpcChatMessages*(chatId: string, cursorVal: JsonNode, limit: int, success: var bool): string =
@ -542,10 +540,9 @@ proc parseChatPinnedMessagesResponse*(rpcResult: JsonNode): (string, seq[Message
var messages: seq[Message] = @[] var messages: seq[Message] = @[]
let messagesObj = rpcResult{"pinnedMessages"} let messagesObj = rpcResult{"pinnedMessages"}
if(messagesObj != nil and messagesObj.kind != JNull): if(messagesObj != nil and messagesObj.kind != JNull):
let pk = status_settings.getSetting[string](Setting.PublicKey, "0x0")
var msg: Message var msg: Message
for jsonMsg in messagesObj: for jsonMsg in messagesObj:
msg = jsonMsg["message"].toMessage(pk) msg = jsonMsg["message"].toMessage()
msg.pinnedBy = $jsonMsg{"pinnedBy"}.getStr msg.pinnedBy = $jsonMsg{"pinnedBy"}.getStr
messages.add(msg) messages.add(msg)
return (rpcResult{"cursor"}.getStr, messages) return (rpcResult{"cursor"}.getStr, messages)

View File

@ -15,3 +15,6 @@ proc requestAddressForTransaction*(chatId: string, fromAddress: string, amount:
proc requestTransaction*(chatId: string, fromAddress: string, amount: string, tokenAddress: string): string = proc requestTransaction*(chatId: string, fromAddress: string, amount: string, tokenAddress: string): string =
result = callPrivateRPC("requestTransaction".prefix, %* [chatId, amount, tokenAddress, fromAddress]) result = callPrivateRPC("requestTransaction".prefix, %* [chatId, amount, tokenAddress, fromAddress])
proc acceptRequestTransaction*(transactionHash: string, messageId: string, signature: string): string =
result = callPrivateRPC("acceptRequestTransaction".prefix, %* [transactionHash, messageId, signature])

View File

@ -1,6 +1,8 @@
import json, random, strutils, sequtils, sugar, chronicles, tables import json, random, strutils, sequtils, sugar, chronicles, tables
import json_serialization import json_serialization
import ../utils import ../utils
import ../wallet/account
import ../libstatus/wallet as status_wallet
import ../libstatus/accounts as status_accounts import ../libstatus/accounts as status_accounts
import ../libstatus/accounts/constants as constants import ../libstatus/accounts/constants as constants
import ../libstatus/settings as status_settings import ../libstatus/settings as status_settings
@ -13,7 +15,7 @@ import types
import web3/conversions import web3/conversions
from ../utils import parseAddress, wei2Eth from ../utils import parseAddress, wei2Eth
proc toMessage*(jsonMsg: JsonNode, pk: string): Message proc toMessage*(jsonMsg: JsonNode): Message
proc toChat*(jsonChat: JsonNode): Chat proc toChat*(jsonChat: JsonNode): Chat
@ -23,15 +25,13 @@ proc toCommunity*(jsonCommunity: JsonNode): Community
proc toCommunityMembershipRequest*(jsonCommunityMembershipRequest: JsonNode): CommunityMembershipRequest proc toCommunityMembershipRequest*(jsonCommunityMembershipRequest: JsonNode): CommunityMembershipRequest
proc toActivityCenterNotification*(jsonNotification: JsonNode, pk: string): ActivityCenterNotification proc toActivityCenterNotification*(jsonNotification: JsonNode): ActivityCenterNotification
proc fromEvent*(event: JsonNode): Signal = proc fromEvent*(event: JsonNode): Signal =
var signal:MessageSignal = MessageSignal() var signal:MessageSignal = MessageSignal()
signal.messages = @[] signal.messages = @[]
signal.contacts = @[] signal.contacts = @[]
let pk = status_settings.getSetting[string](Setting.PublicKey, "0x0")
if event["event"]{"contacts"} != nil: if event["event"]{"contacts"} != nil:
for jsonContact in event["event"]["contacts"]: for jsonContact in event["event"]["contacts"]:
signal.contacts.add(jsonContact.toProfileModel()) signal.contacts.add(jsonContact.toProfileModel())
@ -40,7 +40,7 @@ proc fromEvent*(event: JsonNode): Signal =
if event["event"]{"messages"} != nil: if event["event"]{"messages"} != nil:
for jsonMsg in event["event"]["messages"]: for jsonMsg in event["event"]["messages"]:
var message = jsonMsg.toMessage(pk) var message = jsonMsg.toMessage()
if message.hasMention: if message.hasMention:
chatsWithMentions.add(message.chatId) chatsWithMentions.add(message.chatId)
signal.messages.add(message) signal.messages.add(message)
@ -70,7 +70,7 @@ proc fromEvent*(event: JsonNode): Signal =
if event["event"]{"activityCenterNotifications"} != nil: if event["event"]{"activityCenterNotifications"} != nil:
for jsonNotification in event["event"]["activityCenterNotifications"]: for jsonNotification in event["event"]["activityCenterNotifications"]:
signal.activityCenterNotification.add(jsonNotification.toActivityCenterNotification(pk)) signal.activityCenterNotification.add(jsonNotification.toActivityCenterNotification())
if event["event"]{"pinMessages"} != nil: if event["event"]{"pinMessages"} != nil:
for jsonPinnedMessage in event["event"]["pinMessages"]: for jsonPinnedMessage in event["event"]["pinMessages"]:
@ -150,8 +150,6 @@ proc toChat*(jsonChat: JsonNode): Chat =
let chatTypeInt = jsonChat{"chatType"}.getInt let chatTypeInt = jsonChat{"chatType"}.getInt
let chatType: ChatType = if chatTypeInt >= ord(low(ChatType)) or chatTypeInt <= ord(high(ChatType)): ChatType(chatTypeInt) else: ChatType.Unknown let chatType: ChatType = if chatTypeInt >= ord(low(ChatType)) or chatTypeInt <= ord(high(ChatType)): ChatType(chatTypeInt) else: ChatType.Unknown
let pk = status_settings.getSetting[string](Setting.PublicKey, "0x0")
result = Chat( result = Chat(
id: jsonChat{"id"}.getStr, id: jsonChat{"id"}.getStr,
communityId: jsonChat{"communityId"}.getStr, communityId: jsonChat{"communityId"}.getStr,
@ -176,7 +174,7 @@ proc toChat*(jsonChat: JsonNode): Chat =
result.muted = jsonChat["muted"].getBool result.muted = jsonChat["muted"].getBool
if jsonChat["lastMessage"].kind != JNull: if jsonChat["lastMessage"].kind != JNull:
result.lastMessage = jsonChat{"lastMessage"}.toMessage(pk) result.lastMessage = jsonChat{"lastMessage"}.toMessage()
if jsonChat.hasKey("joined") and jsonChat["joined"].kind != JNull: if jsonChat.hasKey("joined") and jsonChat["joined"].kind != JNull:
result.joined = jsonChat{"joined"}.getInt result.joined = jsonChat{"joined"}.getInt
@ -279,8 +277,20 @@ proc toTextItem*(jsonText: JsonNode): TextItem =
for child in jsonText["children"]: for child in jsonText["children"]:
result.children.add(child.toTextItem) result.children.add(child.toTextItem)
proc currentUserWalletContainsAddress(address: string): bool =
if (address.len == 0):
return false
let accounts = status_wallet.getWalletAccounts()
for acc in accounts:
if (acc.address == address):
return true
return false
proc toMessage*(jsonMsg: JsonNode): Message =
let publicChatKey = status_settings.getSetting[string](Setting.PublicKey, "0x0")
proc toMessage*(jsonMsg: JsonNode, pk: string): Message =
var contentType: ContentType var contentType: ContentType
try: try:
contentType = ContentType(jsonMsg{"contentType"}.getInt) contentType = ContentType(jsonMsg{"contentType"}.getInt)
@ -311,7 +321,7 @@ proc toMessage*(jsonMsg: JsonNode, pk: string): Message =
timestamp: $jsonMsg{"timestamp"}.getInt, timestamp: $jsonMsg{"timestamp"}.getInt,
whisperTimestamp: $jsonMsg{"whisperTimestamp"}.getInt, whisperTimestamp: $jsonMsg{"whisperTimestamp"}.getInt,
outgoingStatus: $jsonMsg{"outgoingStatus"}.getStr, outgoingStatus: $jsonMsg{"outgoingStatus"}.getStr,
isCurrentUser: pk == jsonMsg{"from"}.getStr, isCurrentUser: publicChatKey == jsonMsg{"from"}.getStr,
stickerHash: "", stickerHash: "",
stickerPackId: -1, stickerPackId: -1,
parsedText: @[], parsedText: @[],
@ -362,7 +372,20 @@ proc toMessage*(jsonMsg: JsonNode, pk: string): Message =
signature: jsonMsg["commandParameters"]["signature"].getStr signature: jsonMsg["commandParameters"]["signature"].getStr
) )
message.hasMention = concat(message.parsedText.map(t => t.children.filter(c => c.textType == "mention" and c.literal == pk))).len > 0 # This is kind of a workaround in case we're processing a transaction message. The reason for
# that is a message where a recipient accepted to share his address with sender. In that message
# a recipient's public key is set as a "from" property of a "Message" object and we cannot
# determine which of two users has initiated transaction actually.
#
# To overcome this we're checking if the "from" address from the "commandParameters" object of
# the "Message" is contained as an address in the wallet of logged in user. If yes, means that
# currently logged in user has initiated a transaction (he is a sender), otherwise currently
# logged in user is a recipient.
message.isCurrentUser = currentUserWalletContainsAddress(message.commandParameters.fromAddress)
message.hasMention = concat(message.parsedText.map(
t => t.children.filter(
c => c.textType == "mention" and c.literal == publicChatKey))).len > 0
result = message result = message
@ -376,7 +399,7 @@ proc toReaction*(jsonReaction: JsonNode): Reaction =
retracted: jsonReaction{"retracted"}.getBool retracted: jsonReaction{"retracted"}.getBool
) )
proc toActivityCenterNotification*(jsonNotification: JsonNode, pk: string): ActivityCenterNotification = proc toActivityCenterNotification*(jsonNotification: JsonNode): ActivityCenterNotification =
var activityCenterNotificationType: ActivityCenterNotificationType var activityCenterNotificationType: ActivityCenterNotificationType
try: try:
activityCenterNotificationType = ActivityCenterNotificationType(jsonNotification{"type"}.getInt) activityCenterNotificationType = ActivityCenterNotificationType(jsonNotification{"type"}.getInt)
@ -396,4 +419,4 @@ proc toActivityCenterNotification*(jsonNotification: JsonNode, pk: string): Acti
) )
if jsonNotification.contains("message") and jsonNotification{"message"}.kind != JNull: if jsonNotification.contains("message") and jsonNotification{"message"}.kind != JNull:
result.message = jsonNotification{"message"}.toMessage(pk) result.message = jsonNotification{"message"}.toMessage()

View File

@ -45,9 +45,6 @@ ModalPopup {
sendingError.text = qsTr("Invalid transaction parameters") sendingError.text = qsTr("Invalid transaction parameters")
sendingError.open() sendingError.open()
} }
root.close()
} }
id: root id: root
@ -62,6 +59,7 @@ ModalPopup {
title: qsTrId("error-sending-the-transaction") title: qsTrId("error-sending-the-transaction")
icon: StandardIcon.Critical icon: StandardIcon.Critical
standardButtons: StandardButton.Ok standardButtons: StandardButton.Ok
onAccepted: root.close()
} }
onClosed: { onClosed: {
@ -158,7 +156,7 @@ ModalPopup {
if (!gasEstimate.success) { if (!gasEstimate.success) {
//% "Error estimating gas: %1" //% "Error estimating gas: %1"
let message = qsTrId("error-estimating-gas---1").arg(gasEstimate.error.message) let message = qsTrId("error-estimating-gas---1").arg(gasEstimate.error.message)
console.warn(message)
//% ". The transaction will probably fail." //% ". The transaction will probably fail."
gasEstimateErrorPopup.confirmationText = message + qsTrId("--the-transaction-will-probably-fail-") gasEstimateErrorPopup.confirmationText = message + qsTrId("--the-transaction-will-probably-fail-")
gasEstimateErrorPopup.open() gasEstimateErrorPopup.open()
@ -296,28 +294,33 @@ ModalPopup {
onTransactionWasSent: { onTransactionWasSent: {
try { try {
let response = JSON.parse(txResult) let response = JSON.parse(txResult)
if (response.uuid !== stack.uuid)
return
if (response.uuid !== stack.uuid) return let transactionId = response.result
stack.currentGroup.isPending = false
if (!response.success) { if (!response.success) {
if (Utils.isInvalidPasswordMessage(response.result)){ if (Utils.isInvalidPasswordMessage(transactionId)){
//% "Wrong password" //% "Wrong password"
transactionSigner.validationError = qsTrId("wrong-password") transactionSigner.validationError = qsTrId("wrong-password")
return return
} }
sendingError.text = response.result sendingError.text = transactionId
return sendingError.open() return sendingError.open()
} }
chatsModel.transactions.acceptRequestTransaction(transactionId,
messageId,
profileModel.profile.pubKey + transactionId.substr(2))
//% "Transaction pending..." //% "Transaction pending..."
toastMessage.title = qsTrId("ens-transaction-pending") toastMessage.title = qsTrId("ens-transaction-pending")
toastMessage.source = "../../../../img/loading.svg" toastMessage.source = "../../../../img/loading.svg"
toastMessage.iconColor = Style.current.primary toastMessage.iconColor = Style.current.primary
toastMessage.iconRotates = true toastMessage.iconRotates = true
toastMessage.link = `${walletModel.utilsView.etherscanLink}/${response.result}` toastMessage.link = `${walletModel.utilsView.etherscanLink}/${transactionId}`
toastMessage.open() toastMessage.open()
root.close() root.close()
} catch (e) { } catch (e) {
console.error('Error parsing the response', e) console.error('Error parsing the response', e)
@ -327,9 +330,3 @@ ModalPopup {
} }
} }
/*##^##
Designer {
D{i:0;autoSize:true;height:480;width:640}
}
##^##*/

View File

@ -24,6 +24,7 @@ Item {
} }
} }
} }
property var token: JSON.parse(commandParametersObject.contract) // TODO: handle {} property var token: JSON.parse(commandParametersObject.contract) // TODO: handle {}
property string tokenAmount: commandParametersObject.value property string tokenAmount: commandParametersObject.value
property string tokenSymbol: token.symbol || "" property string tokenSymbol: token.symbol || ""
@ -35,18 +36,10 @@ Item {
return walletModel.balanceView.getFiatValue(tokenAmount, token.symbol, defaultFiatSymbol) + " " + defaultFiatSymbol.toUpperCase() return walletModel.balanceView.getFiatValue(tokenAmount, token.symbol, defaultFiatSymbol) + " " + defaultFiatSymbol.toUpperCase()
} }
property int state: commandParametersObject.commandState property int state: commandParametersObject.commandState
property bool outgoing: {
switch (root.state) { // Any transaction where isCurrentUser is true is actually outgoing transaction.
case Constants.pending: property bool outgoing: isCurrentUser
case Constants.confirmed:
case Constants.transactionRequested:
case Constants.addressRequested: return isCurrentUser
case Constants.declined:
case Constants.transactionDeclined:
case Constants.addressReceived: return !isCurrentUser
default: return false
}
}
property int innerMargin: 12 property int innerMargin: 12
property bool isError: commandParametersObject.contract === "{}" property bool isError: commandParametersObject.contract === "{}"
onTokenSymbolChanged: { onTokenSymbolChanged: {
@ -74,11 +67,12 @@ Item {
color: Style.current.secondaryText color: Style.current.secondaryText
text: { text: {
if (root.state === Constants.transactionRequested) { if (root.state === Constants.transactionRequested) {
let prefix = root.outgoing ? "↓ ": "↑ " let prefix = outgoing? "↑ " : "↓ "
//% "Transaction request" //% "Transaction request"
return prefix + qsTrId("transaction-request") return prefix + qsTrId("transaction-request")
} }
return root.outgoing ?
return outgoing ?
//% " Outgoing transaction" //% " Outgoing transaction"
qsTrId("--outgoing-transaction") : qsTrId("--outgoing-transaction") :
//% " Incoming transaction" //% " Incoming transaction"
@ -208,9 +202,3 @@ Item {
} }
} }
} }
/*##^##
Designer {
D{i:0;formeditorColor:"#4c4e50";formeditorZoom:1.25}
}
##^##*/