diff --git a/src/app/modules/main/wallet_section/activity/controller.nim b/src/app/modules/main/wallet_section/activity/controller.nim index 6d38b533bb..2bee90f83b 100644 --- a/src/app/modules/main/wallet_section/activity/controller.nim +++ b/src/app/modules/main/wallet_section/activity/controller.nim @@ -9,6 +9,7 @@ import collectibles_model import collectibles_item import events_handler import status +import utils import web3/conversions @@ -36,9 +37,6 @@ const FETCH_BATCH_COUNT_DEFAULT = 10 const FETCH_RECIPIENTS_BATCH_COUNT_DEFAULT = 2000 const FETCH_COLLECTIBLES_BATCH_COUNT_DEFAULT = 2000 -type - CollectiblesToTokenConverter* = proc (id: string): backend_activity.Token - QtObject: type Controller* = ref object of QObject @@ -65,8 +63,6 @@ QtObject: requestId: int32 - collectiblesToTokenConverter: CollectiblesToTokenConverter - proc setup(self: Controller) = self.QObject.setup @@ -311,8 +307,7 @@ QtObject: currencyService: currency_service.Service, tokenService: token_service.Service, savedAddressService: saved_address_service.Service, - events: EventEmitter, - collectiblesConverter: CollectiblesToTokenConverter): Controller = + events: EventEmitter): Controller = new(result, delete) result.requestId = requestId @@ -334,8 +329,6 @@ QtObject: result.allAddressesSelected = false result.chainIds = @[] - result.collectiblesToTokenConverter = collectiblesConverter - result.setup() result.setupEventHandlers(events) @@ -373,8 +366,12 @@ QtObject: var collectibles = newSeq[backend_activity.Token]() for i in 0 ..< collectiblesJson.len: let uid = collectiblesJson[i].getStr() - let token = self.collectiblesToTokenConverter(uid) - collectibles.add(token) + # TODO: We need the token type here, which is not part of the uid. + # We currently don't support filtering ERC1155 tokens anyway, so it's not an issue. + # When we have a split model for all collectibles metadata, get the entry from there + # to get the token type. Perhaps also add an "UnknownCollectible" TokenType that includes + # both ERC721 and ERC1155? + collectibles.add(collectibleUidToActivityToken(uid, TokenType.ERC721)) self.currentActivityFilter.collectibles = collectibles diff --git a/src/app/modules/main/wallet_section/activity/utils.nim b/src/app/modules/main/wallet_section/activity/utils.nim new file mode 100644 index 0000000000..e92492f1ba --- /dev/null +++ b/src/app/modules/main/wallet_section/activity/utils.nim @@ -0,0 +1,20 @@ +import stint, chronicles + +import backend/collectibles_types as backend_collectibles +import backend/activity as backend_activity +import app_service/common/types +import web3/ethtypes as eth + +proc collectibleUidToActivityToken*(uid: string, tokenType: TokenType): backend_activity.Token = + try: + let id = uid.toCollectibleUniqueID() + result.tokenType = tokenType + result.chainId = backend_activity.ChainId(id.contractID.chainID) + let contractAddress = id.contractID.address + if len(contractAddress) > 0: + var address: eth.Address + address = eth.fromHex(eth.Address, contractAddress) + result.address = some(address) + result.tokenId = some(backend_activity.TokenId("0x" & stint.toHex(id.tokenId))) + except: + error "Invalid collectible uid: ", uid diff --git a/src/app/modules/main/wallet_section/module.nim b/src/app/modules/main/wallet_section/module.nim index 95a00ff6b0..456670ec1c 100644 --- a/src/app/modules/main/wallet_section/module.nim +++ b/src/app/modules/main/wallet_section/module.nim @@ -129,7 +129,7 @@ proc newModule*( result.assetsModule = assets_module.newModule(result, events, walletAccountService, networkService, tokenService, currencyService) result.sendModule = send_module.newModule(result, events, walletAccountService, networkService, currencyService, - transactionService, keycardService) + transactionService, keycardService) result.savedAddressesModule = saved_addresses_module.newModule(result, events, savedAddressService) result.buySellCryptoModule = buy_sell_crypto_module.newModule(result, events, transactionService) result.overviewModule = overview_module.newModule(result, events, walletAccountService, currencyService) @@ -137,12 +137,10 @@ proc newModule*( result.networksService = networkService result.transactionService = transactionService - let collectiblesToTokenConverter = proc(id: string): backend_activity.Token = - return allCollectiblesModule.getAllCollectiblesModel().getActivityToken(id) result.activityController = activityc.newController(int32(ActivityID.History), currencyService, tokenService, - savedAddressService, events, collectiblesToTokenConverter) + savedAddressService, events) result.tmpActivityController = activityc.newController(int32(ActivityID.Temporary), currencyService, tokenService, - savedAddressService, events, collectiblesToTokenConverter) + savedAddressService, events) result.collectibleDetailsController = collectible_detailsc.newController(int32(backend_collectibles.CollectiblesRequestID.WalletAccount), networkService, events) result.filter = initFilter(result.controller) diff --git a/src/app/modules/shared_models/collectibles_entry.nim b/src/app/modules/shared_models/collectibles_entry.nim index a6cfc1e292..c1cd8829e8 100644 --- a/src/app/modules/shared_models/collectibles_entry.nim +++ b/src/app/modules/shared_models/collectibles_entry.nim @@ -59,9 +59,6 @@ QtObject: generatedCollectionId:{self.generatedCollectionId} )""" - proc getCollectibleUniqueID*(self: CollectiblesEntry): backend.CollectibleUniqueID = - return self.id - proc hasCollectibleData(self: CollectiblesEntry): bool = return self.data != nil and isSome(self.data.collectibleData) @@ -108,18 +105,18 @@ QtObject: read = getTokenIDAsString # Unique ID to identify collectible, generated by us - proc getID*(self: CollectiblesEntry): string = + proc getID*(self: CollectiblesEntry): backend.CollectibleUniqueID = + return self.id + + proc getIDAsString*(self: CollectiblesEntry): string = return self.generatedId - - proc generateId*(self: CollectiblesEntry): string = - return fmt"{self.getChainId}+{self.getContractAddress}+{self.getTokenID}" # Unique ID to identify collection, generated by us - proc getCollectionID*(self: CollectiblesEntry): string = - return self.generatedCollectionId + proc getCollectionID*(self: CollectiblesEntry): backend.ContractID = + return self.id.contractID - proc generateCollectionId*(self: CollectiblesEntry): string = - return fmt"{self.getChainId}+{self.getContractAddress}" + proc getCollectionIDAsString*(self: CollectiblesEntry): string = + return self.generatedCollectionId proc nameChanged*(self: CollectiblesEntry) {.signal.} proc getName*(self: CollectiblesEntry): string {.slot.} = @@ -341,8 +338,8 @@ QtObject: result.id = data.id result.setData(data) result.extradata = extradata - result.generatedId = result.generateId() - result.generatedCollectionId = result.generateCollectionId() + result.generatedId = result.id.toString() + result.generatedCollectionId = result.id.contractID.toString() result.setup() proc newCollectibleDetailsBasicEntry*(id: backend.CollectibleUniqueID, extradata: ExtraData): CollectiblesEntry = @@ -351,8 +348,8 @@ QtObject: result.extradata = extradata result.traits = newTraitModel() result.ownership = newOwnershipModel() - result.generatedId = result.generateId() - result.generatedCollectionId = result.generateCollectionId() + result.generatedId = result.id.toString() + result.generatedCollectionId = result.id.contractID.toString() result.setup() proc newCollectibleDetailsEmptyEntry*(): CollectiblesEntry = diff --git a/src/app/modules/shared_models/collectibles_model.nim b/src/app/modules/shared_models/collectibles_model.nim index fb49e993fc..92a55b3b5c 100644 --- a/src/app/modules/shared_models/collectibles_model.nim +++ b/src/app/modules/shared_models/collectibles_model.nim @@ -2,9 +2,7 @@ import NimQml, Tables, strutils, strformat, sequtils, stint, json import logging import ./collectibles_entry -import web3/ethtypes as eth import backend/collectibles as backend_collectibles -import backend/activity as backend_activity import app_service/common/utils as common_utils import app_service/common/types @@ -164,7 +162,7 @@ QtObject: let item = self.items[index.row] case enumRole: of CollectibleRole.Uid: - result = newQVariant(item.getID()) + result = newQVariant(item.getIDAsString()) of CollectibleRole.ChainId: result = newQVariant(item.getChainID()) of CollectibleRole.ContractAddress: @@ -182,7 +180,7 @@ QtObject: of CollectibleRole.BackgroundColor: result = newQVariant(item.getBackgroundColor()) of CollectibleRole.CollectionUid: - result = newQVariant(item.getCollectionID()) + result = newQVariant(item.getCollectionIDAsString()) of CollectibleRole.CollectionName: result = newQVariant(item.getCollectionName()) of CollectibleRole.CollectionSlug: @@ -205,7 +203,7 @@ QtObject: return let item = self.items[index] case column: - of "uid": result = item.getID() + of "uid": result = item.getIDAsString() of "chainId": result = $item.getChainID() of "contractAddress": result = item.getContractAddress() of "tokenId": result = item.getTokenIDAsString() @@ -214,7 +212,7 @@ QtObject: of "mediaType": result = item.getMediaType() of "imageUrl": result = item.getImageURL() of "backgroundColor": result = item.getBackgroundColor() - of "collectionUid": result = item.getCollectionID() + of "collectionUid": result = item.getCollectionIDAsString() of "collectionName": result = item.getCollectionName() of "collectionSlug": result = item.getCollectionSlug() of "isLoading": result = $false @@ -271,12 +269,12 @@ QtObject: var newTable = initTable[string, int](len(newItems)) for i in 0 ..< len(newItems): - newTable.add(newItems[i].getID(), i) + newTable.add(newItems[i].getIDAsString(), i) # Needs to be built in sequential index order var oldIndicesToRemove: seq[int] = @[] for idx in 0 ..< len(self.items): - let uid = self.items[idx].getID() + let uid = self.items[idx].getIDAsString() if not newTable.hasKey(uid): # Item in old list but not in new -> Must remove oldIndicesToRemove.add(idx) @@ -303,7 +301,7 @@ QtObject: proc getItemById*(self: Model, id: string): CollectiblesEntry = for item in self.items: - if(cmpIgnoreCase(item.getID(), id) == 0): + if(cmpIgnoreCase(item.getIDAsString(), id) == 0): return item return nil @@ -343,45 +341,20 @@ QtObject: proc getImageUrl*(self: Model, id: string): string {.slot.} = for item in self.items: - if(cmpIgnoreCase(item.getId(), id) == 0): + if(cmpIgnoreCase(item.getIDAsString(), id) == 0): return item.getImageUrl() return "" proc getName*(self: Model, id: string): string {.slot.} = for item in self.items: - if(cmpIgnoreCase(item.getId(), id) == 0): + if(cmpIgnoreCase(item.getIDAsString(), id) == 0): return item.getName() return "" - proc getActivityToken*(self: Model, id: string): backend_activity.Token = - for item in self.items: - if(cmpIgnoreCase(item.getID(), id) == 0): - result.tokenType = TokenType.ERC721 - result.chainId = backend_activity.ChainId(item.getChainID()) - var contract = item.getContractAddress() - if len(contract) > 0: - var address: eth.Address - address = eth.fromHex(eth.Address, contract) - result.address = some(address) - var tokenId = item.getTokenID() - if tokenId > 0: - result.tokenId = some(backend_activity.TokenId("0x" & stint.toHex(tokenId))) - return result - - # Fallback, use data from id - var parts = id.split("+") - if len(parts) == 3: - result.chainId = backend_activity.ChainId(parseInt(parts[0])) - result.address = some(eth.fromHex(eth.Address, parts[1])) - var tokenIdInt = u256(parseInt(parts[2])) - result.tokenId = some(backend_activity.TokenId("0x" & stint.toHex(tokenIdInt))) - - return result - proc getUidForData*(self: Model, tokenId: string, tokenAddress: string, chainId: int): string {.slot.} = for item in self.items: - if(cmpIgnoreCase(item.getTokenIDAsString(), tokenId) == 0 and cmpIgnoreCase(item.getContractAddress(), tokenAddress) == 0): - return item.getID() + if(cmpIgnoreCase(item.getTokenIDAsString(), tokenId) == 0 and cmpIgnoreCase(item.getContractAddress(), tokenAddress) == 0) and item.getChainID() == chainId: + return item.getIDAsString() # Fallback, create uid from data, because it still might not be fetched if chainId > 0 and len(tokenAddress) > 0 and len(tokenId) > 0: return $chainId & "+" & tokenAddress & "+" & tokenId diff --git a/src/app/modules/shared_models/collectibles_nested_model.nim b/src/app/modules/shared_models/collectibles_nested_model.nim index 23519b9e68..e055dfc2b8 100644 --- a/src/app/modules/shared_models/collectibles_nested_model.nim +++ b/src/app/modules/shared_models/collectibles_nested_model.nim @@ -125,7 +125,7 @@ QtObject: var collectiblesPerCollection = initTable[string, seq[flat_item.CollectiblesEntry]]() for item in items: - let collectionId = item.getCollectionID() + let collectionId = item.getCollectionIDAsString() if not collectiblesPerCollection.hasKey(collectionId): collectiblesPerCollection[collectionId] = @[] collectiblesPerCollection[collectionId].add(item) diff --git a/src/app/modules/shared_models/collectibles_nested_utils.nim b/src/app/modules/shared_models/collectibles_nested_utils.nim index e8200fa459..d2a6359e0a 100644 --- a/src/app/modules/shared_models/collectibles_nested_utils.nim +++ b/src/app/modules/shared_models/collectibles_nested_utils.nim @@ -3,22 +3,22 @@ import ./collectibles_nested_item as nested_item proc collectibleToCollectibleNestedItem*(flatItem: flat_item.CollectiblesEntry): nested_item.Item = return nested_item.initItem( - flatItem.getID(), + flatItem.getIDAsString(), flatItem.getChainID(), flatItem.getName(), flatItem.getImageURL(), - flatItem.getCollectionID(), + flatItem.getCollectionIDAsString(), flatItem.getCollectionName(), false ) proc collectibleToCollectionNestedItem*(flatItem: flat_item.CollectiblesEntry): nested_item.Item = return nested_item.initItem( - flatItem.getCollectionID(), + flatItem.getCollectionIDAsString(), flatItem.getChainID(), flatItem.getCollectionName(), flatItem.getCollectionImageURL(), - flatItem.getCollectionID(), + flatItem.getCollectionIDAsString(), flatItem.getCollectionName(), true ) diff --git a/src/app/modules/shared_modules/collectibles/controller.nim b/src/app/modules/shared_modules/collectibles/controller.nim index fb2bdb88b4..2728d456cb 100644 --- a/src/app/modules/shared_modules/collectibles/controller.nim +++ b/src/app/modules/shared_modules/collectibles/controller.nim @@ -9,7 +9,6 @@ import events_handler import app/core/eventemitter import backend/collectibles as backend_collectibles -import backend/activity as backend_activity import app_service/service/network/service as network_service const FETCH_BATCH_COUNT_DEFAULT = 50 @@ -302,9 +301,6 @@ QtObject: self.resetModel() - proc getActivityToken*(self: Controller, id: string): backend_activity.Token = - return self.model.getActivityToken(id) - proc getItemForData*(self: Controller, tokenId: string, tokenAddress: string, chainId: int): CollectiblesEntry = let uid = self.model.getUidForData(tokenId, tokenAddress, chainId) return self.model.getItemById(uid) diff --git a/src/backend/collectibles_types.nim b/src/backend/collectibles_types.nim index 53d4855e36..326a2d3bce 100644 --- a/src/backend/collectibles_types.nim +++ b/src/backend/collectibles_types.nim @@ -1,5 +1,5 @@ import json, strformat, json_serialization -import stint, Tables, options +import stint, Tables, options, strutils import community_tokens_types include app_service/common/json_utils @@ -126,6 +126,13 @@ proc fromJson*(t: JsonNode, T: typedesc[ref ContractID]): ref ContractID {.inlin result = new(ContractID) result[] = fromJson(t, ContractID) +proc toString*(t: ContractID): string = + return fmt"{t.chainID}+{t.address}" + +proc toContractID*(t: string): ContractID = + var parts = t.split("+") + return ContractID(chainID: parts[0].parseInt(), address: parts[1]) + # CollectibleUniqueID proc `$`*(self: CollectibleUniqueID): string = return fmt"""CollectibleUniqueID( @@ -154,6 +161,19 @@ proc fromJson*(t: JsonNode, T: typedesc[ref CollectibleUniqueID]): ref Collectib result = new(CollectibleUniqueID) result[] = fromJson(t, CollectibleUniqueID) +proc toString*(t: CollectibleUniqueID): string = + return fmt"{t.contractID.chainID}+{t.contractID.address}+{t.tokenID.toString()}" + +proc toCollectibleUniqueID*(t: string): CollectibleUniqueID = + var parts = t.split("+") + return CollectibleUniqueID( + contractID: ContractID( + chainID: parts[0].parseInt(), + address: parts[1] + ), + tokenID: stint.parse(parts[2], UInt256) + ) + # CollectibleTrait proc `$`*(self: CollectibleTrait): string = return fmt"""CollectibleTrait( diff --git a/test/nim/collectibles_types_conversions_test.nim b/test/nim/collectibles_types_conversions_test.nim index 5fe8eb0663..ab5cb963c7 100644 --- a/test/nim/collectibles_types_conversions_test.nim +++ b/test/nim/collectibles_types_conversions_test.nim @@ -41,3 +41,25 @@ suite "collectibles types": check(oldCommOwners[0].name == newCommOwners[0].name) check(oldCommOwners[0].imageSource == newCommOwners[0].imageSource) check(oldCommOwners[0].collectibleOwner.address == newCommOwners[0].collectibleOwner.address) + + test "ContractID string conversion": + + let oldContractID = ContractID(chainID: 321, address: "0x123") + let contractIDString = oldContractID.toString() + + let newContractID = contractIDString.toContractID() + + check(oldContractID == newContractID) + + test "CollectibleUniqueID string conversion": + + let oldUniqueID = CollectibleUniqueID( + contractID: ContractID(chainID: 321, address: "0x123"), + tokenId: stint.u256(23) + ) + let uniqueIDString = oldUniqueID.toString() + + let newUniqueID = uniqueIDString.toCollectibleUniqueID() + + check(oldUniqueID == newUniqueID) + diff --git a/vendor/status-go b/vendor/status-go index 972a4f9df9..54ea0981a5 160000 --- a/vendor/status-go +++ b/vendor/status-go @@ -1 +1 @@ -Subproject commit 972a4f9df9fdd0464d02e014fc65a9de70753b3c +Subproject commit 54ea0981a5e1496c1358ea9dcc8c99ffc2098c73