Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ QtObject:
proc removeLinkPreviewData*(self: View, index: int) {.slot.} =
self.linkPreviewModel.removePreviewData(index)

proc addPaymentRequest*(self: View, receiver: string, amount: string, tokenKey: string, symbol: string) {.slot.} =
self.paymentRequestModel.addPaymentRequest(receiver, amount, tokenKey, symbol)
proc addPaymentRequest*(self: View, receiver: string, amount: string, tokenKey: string, symbol: string, logoUri: string) {.slot.} =
self.paymentRequestModel.addPaymentRequest(receiver, amount, tokenKey, symbol, logoUri)

proc removePaymentRequestPreviewData*(self: View, index: int) {.slot.} =
self.paymentRequestModel.removeItemWithIndex(index)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ proc getAllTokenLists*(self: Controller): var seq[TokenListItem] =
proc buildGroupsForChain*(self: Controller, chainId: int): bool =
return self.tokenService.buildGroupsForChain(chainId)

proc getTokenByKeyOrGroupKeyFromAllTokens*(self: Controller, key: string): TokenItem =
return self.tokenService.getTokenByKeyOrGroupKeyFromAllTokens(key)

proc getGroupsForChain*(self: Controller): var seq[TokenGroupItem] =
return self.tokenService.getGroupsForChain()

Expand Down Expand Up @@ -145,4 +148,7 @@ proc toggleAutoRefreshTokensLists*(self: Controller): bool =
return self.settingsService.toggleAutoRefreshTokens()

proc tokenAvailableForBridgingViaHop*(self: Controller, tokenChainId: int, tokenAddress: string): bool =
return self.tokenService.tokenAvailableForBridgingViaHop(tokenChainId, tokenAddress)
return self.tokenService.tokenAvailableForBridgingViaHop(tokenChainId, tokenAddress)

proc getMandatoryTokenGroupKeys*(self: Controller): seq[string] =
return self.tokenService.getMandatoryTokenGroupKeys()
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ method viewDidLoad*(self: AccessInterface) {.base.} =
method buildGroupsForChain*(self: AccessInterface, chainId: int): bool {.base.} =
raise newException(ValueError, "No implementation available")

method getTokenByKeyOrGroupKeyFromAllTokens*(self: AccessInterface, key: string): TokenItem {.base.} =
raise newException(ValueError, "No implementation available")

method filterChanged*(self: AccessInterface, addresses: seq[string]) {.base.} =
raise newException(ValueError, "No implementation available")

Expand Down Expand Up @@ -127,4 +130,7 @@ method showCommunityAssetWhenSendingTokensChanged*(self: AccessInterface) {.base
raise newException(ValueError, "No implementation available")

method tokenAvailableForBridgingViaHop*(self: AccessInterface, tokenChainId: int, tokenAddress: string): bool {.base.} =
raise newException(ValueError, "No implementation available")

method getMandatoryTokenGroupKeys*(self: AccessInterface): seq[string] {.base.} =
raise newException(ValueError, "No implementation available")
8 changes: 7 additions & 1 deletion src/app/modules/main/wallet_section/all_tokens/module.nim
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ method getTokenMarketValuesDataSource*(self: Module): TokenMarketValuesDataSourc
method buildGroupsForChain*(self: Module, chainId: int): bool =
return self.controller.buildGroupsForChain(chainId)

method getTokenByKeyOrGroupKeyFromAllTokens*(self: Module, key: string): TokenItem =
return self.controller.getTokenByKeyOrGroupKeyFromAllTokens(key)

method filterChanged*(self: Module, addresses: seq[string]) =
if addresses == self.addresses:
return
Expand Down Expand Up @@ -183,4 +186,7 @@ method showCommunityAssetWhenSendingTokensChanged*(self: Module) =
self.view.showCommunityAssetWhenSendingTokensChanged()

method tokenAvailableForBridgingViaHop*(self: Module, tokenChainId: int, tokenAddress: string): bool =
return self.controller.tokenAvailableForBridgingViaHop(tokenChainId, tokenAddress)
return self.controller.tokenAvailableForBridgingViaHop(tokenChainId, tokenAddress)

method getMandatoryTokenGroupKeys*(self: Module): seq[string] =
return self.controller.getMandatoryTokenGroupKeys()
19 changes: 15 additions & 4 deletions src/app/modules/main/wallet_section/all_tokens/view.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import nimqml, sequtils, strutils, chronicles
import nimqml, sequtils, strutils, json, chronicles

import io_interface, token_lists_model, token_groups_model

Expand Down Expand Up @@ -107,13 +107,24 @@ QtObject:
read = getTokenGroupsModel
notify = tokenGroupsModelChanged

proc buildGroupsForChain*(self: View, chainId: int, mandatoryKeysString: string) {.slot.} =
let mandatoryKeys = mandatoryKeysString.split("$$")
proc buildGroupsForChain*(self: View, chainId: int, mandatoryGroupKeysString: string) {.slot.} =
if not self.delegate.buildGroupsForChain(chainId):
return
self.tokenGroupsForChainModel.modelsUpdated(resetModelSize = true, mandatoryKeys)
var mandatoryGroupKeys: seq[string] = @[]
if mandatoryGroupKeysString.len > 0:
mandatoryGroupKeys = mandatoryGroupKeysString.split("$$")
else:
mandatoryGroupKeys = self.delegate.getMandatoryTokenGroupKeys()

self.tokenGroupsForChainModel.modelsUpdated(resetModelSize = true, mandatoryGroupKeys)
self.tokenGroupsForChainModelChanged()

proc getTokenByKeyOrGroupKeyFromAllTokens*(self: View, key: string): string {.slot.} =
let token = self.delegate.getTokenByKeyOrGroupKeyFromAllTokens(key)
if token.isNil:
return ""
return $(%* token)

proc modelsUpdated*(self: View) =
self.tokenListsModel.modelsUpdated()
self.tokenGroupsModel.modelsUpdated()
Expand Down
8 changes: 6 additions & 2 deletions src/app/modules/shared_models/payment_request_model.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type
Symbol
Amount
ReceiverAddress
LogoUri

QtObject:
type
Expand Down Expand Up @@ -42,6 +43,7 @@ QtObject:
ModelRole.Symbol.int: "symbol",
ModelRole.Amount.int: "amount",
ModelRole.ReceiverAddress.int: "receiver",
ModelRole.LogoUri.int:"logoUri",
}.toTable

method data(self: Model, index: QModelIndex, role: int): QVariant =
Expand All @@ -63,6 +65,8 @@ QtObject:
result = newQVariant(item.amount)
of ModelRole.ReceiverAddress:
result = newQVariant(item.receiver)
of ModelRole.LogoUri:
result = newQVariant(item.logoUri)
else:
result = newQVariant()

Expand All @@ -85,8 +89,8 @@ QtObject:
self.items.add(paymentRequest)
self.endInsertRows()

proc addPaymentRequest*(self: Model, receiver: string, amount: string, tokenKey: string, symbol: string) {.slot.}=
let paymentRequest = newPaymentRequest(receiver, amount, tokenKey, symbol)
proc addPaymentRequest*(self: Model, receiver: string, amount: string, tokenKey: string, symbol: string, logoUri: string) {.slot.}=
let paymentRequest = newPaymentRequest(receiver, amount, tokenKey, symbol, logoUri)
self.insertItem(paymentRequest)

proc clearItems*(self: Model) =
Expand Down
2 changes: 1 addition & 1 deletion src/app_service/service/activity_center/service.nim
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ QtObject:
if response.result.kind != JNull:
if response.result.contains("chats"):
for jsonChat in response.result["chats"]:
let chat = toChatDto(jsonChat)
var chat = toChatDto(jsonChat)
self.chatService.updateOrAddChat(chat)
self.events.emit(SIGNAL_CHAT_UPDATE, ChatUpdateArgs(chats: @[chat]))

Expand Down
16 changes: 12 additions & 4 deletions src/app_service/service/message/dto/payment_request.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,37 @@ type PaymentRequest* = object
amount*: string
tokenKey*: string
symbol*: string
logoUri*: string
chainId*: int # kept for backward compatibility with the old payment requests

proc newPaymentRequest*(receiver: string, amount: string, tokenKey: string, symbol: string): PaymentRequest =
result = PaymentRequest(receiver: receiver, amount: amount, tokenKey: tokenKey, symbol: symbol)

proc newPaymentRequest*(receiver: string, amount: string, tokenKey: string, symbol: string, logoUri: string): PaymentRequest =
result = PaymentRequest(receiver: receiver, amount: amount, tokenKey: tokenKey, symbol: symbol, logoUri: logoUri)

proc toPaymentRequest*(jsonObj: JsonNode): PaymentRequest =
result = PaymentRequest()
discard jsonObj.getProp("receiver", result.receiver)
discard jsonObj.getProp("amount", result.amount)
discard jsonObj.getProp("tokenKey", result.tokenKey)
discard jsonObj.getProp("symbol", result.symbol)
discard jsonObj.getProp("logoUri", result.logoUri)
discard jsonObj.getProp("chainId", result.chainId)

proc `%`*(self: PaymentRequest): JsonNode =
return %*{
"receiver": self.receiver,
"amount": self.amount,
"tokenKey": self.tokenKey,
"symbol": self.symbol
"symbol": self.symbol,
"logoUri": self.logoUri
}

proc `$`*(self: PaymentRequest): string =
result = fmt"""PaymentRequest(
receiver: {self.receiver},
amount: {self.amount},
tokenKey: {self.tokenKey},
symbol: {self.symbol}
symbol: {self.symbol},
logoUri: {self.logoUri},
chainId: {self.chainId}
)"""
38 changes: 32 additions & 6 deletions src/app_service/service/message/service.nim
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ import ./dto/urls_unfurling_plan
import ./dto/link_preview
import ./message_cursor

import ../../common/activity_center
import ../../common/message as message_common
import ../../common/conversion as service_conversion

from ../../common/account_constants import ZERO_ADDRESS
import app_service/common/activity_center
import app_service/common/message as message_common
import app_service/common/conversion as service_conversion
from app_service/common/account_constants import ZERO_ADDRESS

import web3/conversions

Expand Down Expand Up @@ -225,6 +224,27 @@ QtObject:

return self.pinnedMsgCursor[chatId]

proc checkPaymentRequestsInMessage*(self: Service, message: var MessageDto) =
for paymentRequest in message.paymentRequests.mitems:
if paymentRequest.tokenKey.len == 0 or paymentRequest.logoUri.len == 0:
if paymentRequest.symbol.len > 0:
# due to backward compatibility, in case the tokenKey is empty, we should try to find it by symbol on the received chain.
let token = self.tokenService.getTokenBySymbolOnChain(paymentRequest.symbol, paymentRequest.chainId)
if token.isNil:
error "token is nil", tokenKey=paymentRequest.tokenKey, procName="checkPaymentRequestsInMessage"
continue
paymentRequest.tokenKey = token.key
paymentRequest.symbol = token.symbol
paymentRequest.logoUri = token.logoUri

proc checkPaymentRequestsInMessages*(self: Service, messages: var seq[MessageDto]) =
for message in messages.mitems:
self.checkPaymentRequestsInMessage(message)

proc checkPaymentRequestsInPinnedMessages*(self: Service, pinnedMessages: var seq[PinnedMessageDto]) =
for pinnedMessage in pinnedMessages.mitems:
self.checkPaymentRequestsInMessage(pinnedMessage.message)

proc asyncLoadMoreMessagesForChat*(self: Service, chatId: string, limit = MESSAGES_PER_PAGE): bool =
if (chatId.len == 0):
error "empty chat id", procName="asyncLoadMoreMessagesForChat"
Expand Down Expand Up @@ -357,6 +377,7 @@ QtObject:
return

self.bulkReplacePubKeysWithDisplayNames(messages)
self.checkPaymentRequestsInMessages(messages)

for i in 0 ..< chats.len:
let chatId = chats[i].id
Expand Down Expand Up @@ -405,7 +426,7 @@ QtObject:
return self.numOfPinnedMessagesPerChat[chatId]
return 0

proc handlePinnedMessagesUpdate(self: Service, pinnedMessages: seq[PinnedMessageUpdateDto]) =
proc handlePinnedMessagesUpdate(self: Service, pinnedMessages: var seq[PinnedMessageUpdateDto]) =
for pm in pinnedMessages:
var chatId: string = ""
if (self.numOfPinnedMessagesPerChat.contains(pm.localChatId)):
Expand Down Expand Up @@ -480,6 +501,7 @@ QtObject:
messages = map(args.messages.getElems(), proc(x: JsonNode): MessageDto = x.toMessageDto())

self.bulkReplacePubKeysWithDisplayNames(messages)
self.checkPaymentRequestsInMessages(messages)

self.events.emit(SIGNAL_MESSAGES_LOADED, MessagesLoadedArgs(
chatId: args.chatId,
Expand Down Expand Up @@ -581,6 +603,8 @@ QtObject:
result = x.toReactionDto()
)

self.checkPaymentRequestsInPinnedMessages(pinnedMessages)

let data = PinnedMessagesLoadedArgs(chatId: chatId, pinnedMessages: pinnedMessages, reactions: reactions)

self.events.emit(SIGNAL_PINNED_MESSAGES_LOADED, data)
Expand Down Expand Up @@ -619,6 +643,7 @@ QtObject:
messages = map(messagesArr.getElems(), proc(x: JsonNode): MessageDto = x.toMessageDto())

self.bulkReplacePubKeysWithDisplayNames(messages)
self.checkPaymentRequestsInMessages(messages)

# handling reactions
var reactionsArr: JsonNode
Expand Down Expand Up @@ -660,6 +685,7 @@ QtObject:
var messages = map(rpcResponseObj{"messages"}.getElems(), proc(x: JsonNode): MessageDto = x.toMessageDto())
if messages.len > 0:
self.bulkReplacePubKeysWithDisplayNames(messages)
self.checkPaymentRequestsInMessages(messages)

let data = CommunityMemberMessagesArgs(communityId: communityId, messages: messages)
self.events.emit(SIGNAL_COMMUNITY_MEMBER_ALL_MESSAGES, data)
Expand Down
20 changes: 18 additions & 2 deletions src/app_service/service/token/items/token.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import strutils, tables
import strutils, tables, json

import app_service/common/wallet_constants as common_wallet_constants
import app_service/common/utils as common_utils
Expand Down Expand Up @@ -113,4 +113,20 @@ proc createStatusTokenItem*(chainId: int): TokenItem =
tokenDto.symbol = common_wallet_constants.STATUS_SYMBOL_TESTNET
tokenDto.decimals = common_wallet_constants.STATUS_DECIMALS_TESTNET

return createTokenItem(tokenDto, common_types.TokenType.ERC20)
return createTokenItem(tokenDto, common_types.TokenType.ERC20)

proc `%`*(self: TokenItem): JsonNode =
return %*{
"key": self.key,
"groupKey": self.groupKey,
"crossChainId": self.crossChainId,
"address": self.address,
"name": self.name,
"symbol": self.symbol,
"decimals": self.decimals,
"chainId": self.chainId,
"logoUri": self.logoUri,
"customToken": self.customToken,
"communityId": self.communityData.id,
"type": self.`type`
}
2 changes: 1 addition & 1 deletion src/app_service/service/token/service.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import nimqml, tables, json, sequtils, chronicles, strutils, sugar, algorithm
import nimqml, tables, json, std/sequtils, chronicles, strutils, sugar, algorithm

import web3/eth_api_types
import backend/backend as backend
Expand Down
36 changes: 36 additions & 0 deletions src/app_service/service/token/service_main.nim
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ proc init*(self: Service) =

self.refreshTokens()

proc getMandatoryTokenGroupKeys*(self: Service): seq[string] =
let tokenKeys = getMandatoryTokenKeys()
let tokens = getTokensByKeys(tokenKeys)
var groupKeysMap: Table[string, bool] = initTable[string, bool]()
for token in tokens:
groupKeysMap[token.groupKey] = true
return toSeq(groupKeysMap.keys)

proc getCurrency*(self: Service): string =
return self.settingsService.getCurrency()

Expand Down Expand Up @@ -105,6 +113,20 @@ proc getGroupsForChain*(self: Service): var seq[TokenGroupItem] =
proc getAllTokenLists*(self: Service): var seq[TokenListItem] =
return self.allTokenLists

################################################################################
## This is a very special function that should not be used anywhere else,
## it covers the backward compatibility with the old payment requests.
##
## Itterates over all tokens for the given chain and returns the first token
## that matches the symbol or name (cause some tokens have different symbols for EVM/BSC chains), case insensitive.
proc getTokenBySymbolOnChain*(self: Service, symbol: string, chainId: int): TokenItem =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just delete it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunatelly we cannot (unless we don't care about backward compatibillity). If we delete it we will break backward compatibility for an already received payment requests in the past.

let tokens = getTokensByChain(chainId)
for token in tokens:
if cmpIgnoreCase(token.symbol, symbol) == 0 or cmpIgnoreCase(token.name, symbol) == 0:
return token
return nil
################################################################################

proc getAllCommunityTokens*(self: Service): var seq[TokenItem] =
const communityTokenListId = "community"
for tl in self.allTokenLists:
Expand Down Expand Up @@ -148,6 +170,20 @@ proc getTokensByGroupKey*(self: Service, groupKey: string): seq[TokenItem] =
return @[token]
return self.groupsOfInterestByKey[groupKey].tokens

## Note: use this function in a very rare case, when you're sure the token is not present in the models.
## Returns a token that matches the key, or the first token in the group that matches the key.
proc getTokenByKeyOrGroupKeyFromAllTokens*(self: Service, key: string): TokenItem =
if common_utils.isTokenKey(key):
return self.getTokenByKey(key)
var tokens = self.getTokensByGroupKey(key)
if tokens.len > 0:
return tokens[0]
tokens = getAllTokens()
let matchedTokens = tokens.filter(t => t.groupKey == key)
if matchedTokens.len > 0:
return matchedTokens[0]
return nil

proc getTokenByGroupKeyAndChainId*(self: Service, groupKey: string, chainId: int): TokenItem =
let tokens = self.getTokensByGroupKey(groupKey)
if tokens.len > 0:
Expand Down
Loading