Make the getENSName calls async (#16099)
* wip: make the getENSName calls async * fix: login to the app takes forever Resolving ens name sometimes, most likely due to network congestion can be really slow, that results in slow app loading, especially if user has more accounts, cause the app checks ens name existence for each account. This PR does that check in an async way. Fixes #16086 * chore: async check for ens name existence when adding new accounts --------- Co-authored-by: Sale Djenic <aleksandardjenic@status.im>
This commit is contained in:
parent
c63c114e5c
commit
6cd9fa91e8
|
@ -257,3 +257,28 @@ proc getTokenBalanceHistoryDataTask*(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
"error": e.msg,
|
"error": e.msg,
|
||||||
}
|
}
|
||||||
arg.finish(output)
|
arg.finish(output)
|
||||||
|
|
||||||
|
#################################################
|
||||||
|
# Async get ENS names for account
|
||||||
|
#################################################
|
||||||
|
|
||||||
|
type
|
||||||
|
FetchENSNamesForAddressesTaskArg = ref object of QObjectTaskArg
|
||||||
|
chainId: int
|
||||||
|
addresses: seq[string]
|
||||||
|
|
||||||
|
proc fetchENSNamesForAddressesTask*(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
|
let arg = decode[FetchENSNamesForAddressesTaskArg](argEncoded)
|
||||||
|
var response = %* {
|
||||||
|
"result": [],
|
||||||
|
"error": "",
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
var result = newJobject()
|
||||||
|
for address in arg.addresses:
|
||||||
|
let name = getEnsName(address, arg.chainId)
|
||||||
|
result[address] = %name
|
||||||
|
response["result"] = result
|
||||||
|
except Exception as e:
|
||||||
|
response["error"] = %* e.msg
|
||||||
|
arg.finish(response)
|
||||||
|
|
|
@ -56,6 +56,8 @@ QtObject:
|
||||||
proc handleKeypair(self: Service, keypair: KeypairDto)
|
proc handleKeypair(self: Service, keypair: KeypairDto)
|
||||||
proc updateAccountsPositions(self: Service)
|
proc updateAccountsPositions(self: Service)
|
||||||
proc importPartiallyOperableAccounts(self: Service, keyUid: string, password: string)
|
proc importPartiallyOperableAccounts(self: Service, keyUid: string, password: string)
|
||||||
|
proc parseCurrencyValueByTokensKey*(self: Service, tokensKey: string, amountInt: UInt256): float64
|
||||||
|
proc fetchENSNamesForAddressesAsync(self: Service, addresses: seq[string], chainId: int)
|
||||||
# All slots defined in included files have to be forward declared
|
# All slots defined in included files have to be forward declared
|
||||||
proc onAllTokensBuilt*(self: Service, response: string) {.slot.}
|
proc onAllTokensBuilt*(self: Service, response: string) {.slot.}
|
||||||
proc onDerivedAddressesFetched*(self: Service, jsonString: string) {.slot.}
|
proc onDerivedAddressesFetched*(self: Service, jsonString: string) {.slot.}
|
||||||
|
@ -66,7 +68,7 @@ QtObject:
|
||||||
proc onFetchChainIdForUrl*(self: Service, jsonString: string) {.slot.}
|
proc onFetchChainIdForUrl*(self: Service, jsonString: string) {.slot.}
|
||||||
proc onNonProfileKeycardKeypairMigratedToApp*(self: Service, response: string) {.slot.}
|
proc onNonProfileKeycardKeypairMigratedToApp*(self: Service, response: string) {.slot.}
|
||||||
proc tokenBalanceHistoryDataResolved*(self: Service, response: string) {.slot.}
|
proc tokenBalanceHistoryDataResolved*(self: Service, response: string) {.slot.}
|
||||||
proc parseCurrencyValueByTokensKey*(self: Service, tokensKey: string, amountInt: UInt256): float64
|
proc onENSNamesFetched*(self: Service, response: string) {.slot.}
|
||||||
|
|
||||||
proc delete*(self: Service) =
|
proc delete*(self: Service) =
|
||||||
self.closingApp = true
|
self.closingApp = true
|
||||||
|
|
|
@ -136,17 +136,20 @@ proc startWallet(self: Service) =
|
||||||
|
|
||||||
proc init*(self: Service) =
|
proc init*(self: Service) =
|
||||||
try:
|
try:
|
||||||
|
var addressesToGetENSName: seq[string] = @[]
|
||||||
let chainId = self.networkService.getAppNetwork().chainId
|
let chainId = self.networkService.getAppNetwork().chainId
|
||||||
let woAccounts = getWatchOnlyAccountsFromDb()
|
let woAccounts = getWatchOnlyAccountsFromDb()
|
||||||
for acc in woAccounts:
|
for acc in woAccounts:
|
||||||
acc.ens = getEnsName(acc.address, chainId)
|
addressesToGetENSName.add(acc.address)
|
||||||
self.storeWatchOnlyAccount(acc)
|
self.storeWatchOnlyAccount(acc)
|
||||||
let keypairs = getKeypairsFromDb()
|
let keypairs = getKeypairsFromDb()
|
||||||
for kp in keypairs:
|
for kp in keypairs:
|
||||||
for acc in kp.accounts:
|
for acc in kp.accounts:
|
||||||
acc.ens = getEnsName(acc.address, chainId)
|
addressesToGetENSName.add(acc.address)
|
||||||
self.storeKeypair(kp)
|
self.storeKeypair(kp)
|
||||||
|
|
||||||
|
self.fetchENSNamesForAddressesAsync(addressesToGetENSName, chainId)
|
||||||
|
|
||||||
let addresses = self.getWalletAddresses()
|
let addresses = self.getWalletAddresses()
|
||||||
self.checkRecentHistory(addresses)
|
self.checkRecentHistory(addresses)
|
||||||
self.startWallet()
|
self.startWallet()
|
||||||
|
@ -195,8 +198,8 @@ proc addNewKeypairsAccountsToLocalStoreAndNotify(self: Service, notify: bool = t
|
||||||
break
|
break
|
||||||
if found:
|
if found:
|
||||||
continue
|
continue
|
||||||
woAccDb.ens = getEnsName(woAccDb.address, chainId)
|
|
||||||
self.storeWatchOnlyAccount(woAccDb)
|
self.storeWatchOnlyAccount(woAccDb)
|
||||||
|
self.fetchENSNamesForAddressesAsync(@[woAccDb.address], chainId)
|
||||||
self.buildAllTokens(@[woAccDb.address], store = true)
|
self.buildAllTokens(@[woAccDb.address], store = true)
|
||||||
if notify:
|
if notify:
|
||||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_SAVED, AccountArgs(account: woAccDb))
|
self.events.emit(SIGNAL_WALLET_ACCOUNT_SAVED, AccountArgs(account: woAccDb))
|
||||||
|
@ -207,9 +210,9 @@ proc addNewKeypairsAccountsToLocalStoreAndNotify(self: Service, notify: bool = t
|
||||||
if localKp.isNil:
|
if localKp.isNil:
|
||||||
self.storeKeypair(kpDb)
|
self.storeKeypair(kpDb)
|
||||||
let addresses = kpDb.accounts.map(a => a.address)
|
let addresses = kpDb.accounts.map(a => a.address)
|
||||||
|
self.fetchENSNamesForAddressesAsync(addresses, chainId)
|
||||||
self.buildAllTokens(addresses, store = true)
|
self.buildAllTokens(addresses, store = true)
|
||||||
for acc in kpDb.accounts:
|
for acc in kpDb.accounts:
|
||||||
acc.ens = getEnsName(acc.address, chainId)
|
|
||||||
if acc.isChat:
|
if acc.isChat:
|
||||||
continue
|
continue
|
||||||
if notify:
|
if notify:
|
||||||
|
@ -223,8 +226,8 @@ proc addNewKeypairsAccountsToLocalStoreAndNotify(self: Service, notify: bool = t
|
||||||
break
|
break
|
||||||
if found:
|
if found:
|
||||||
continue
|
continue
|
||||||
accDb.ens = getEnsName(accDb.address, chainId)
|
|
||||||
self.storeAccountToKeypair(accDb)
|
self.storeAccountToKeypair(accDb)
|
||||||
|
self.fetchENSNamesForAddressesAsync(@[accDb.address], chainId)
|
||||||
if accDb.isChat:
|
if accDb.isChat:
|
||||||
continue
|
continue
|
||||||
self.buildAllTokens(@[accDb.address], store = true)
|
self.buildAllTokens(@[accDb.address], store = true)
|
||||||
|
@ -279,19 +282,21 @@ proc updateAccountsPositions(self: Service) =
|
||||||
continue
|
continue
|
||||||
localAcc.position = dbAcc.position
|
localAcc.position = dbAcc.position
|
||||||
|
|
||||||
proc updateAccountInLocalStoreAndNotify(self: Service, address, name, colorId, emoji: string, operable: string = "",
|
proc updateAccountInLocalStoreAndNotify(self: Service, address, name, colorId, emoji: string, ensName: string = "",
|
||||||
positionUpdated: Option[bool] = none(bool), notify: bool = true) =
|
operable: string = "", positionUpdated: Option[bool] = none(bool), notify: bool = true) =
|
||||||
if address.len > 0:
|
if address.len > 0:
|
||||||
var account = self.getAccountByAddress(address)
|
var account = self.getAccountByAddress(address)
|
||||||
if account.isNil:
|
if account.isNil:
|
||||||
return
|
return
|
||||||
if name.len > 0 or colorId.len > 0 or emoji.len > 0 or operable.len > 0:
|
if name.len > 0 or colorId.len > 0 or emoji.len > 0 or operable.len > 0 or ensName.len > 0:
|
||||||
if name.len > 0 and name != account.name:
|
if name.len > 0 and name != account.name:
|
||||||
account.name = name
|
account.name = name
|
||||||
if colorId.len > 0 and colorId != account.colorId:
|
if colorId.len > 0 and colorId != account.colorId:
|
||||||
account.colorId = colorId
|
account.colorId = colorId
|
||||||
if emoji.len > 0 and emoji != account.emoji:
|
if emoji.len > 0 and emoji != account.emoji:
|
||||||
account.emoji = emoji
|
account.emoji = emoji
|
||||||
|
if ensName.len > 0 and ensName != account.ens:
|
||||||
|
account.ens = ensName
|
||||||
if operable.len > 0 and operable != account.operable and
|
if operable.len > 0 and operable != account.operable and
|
||||||
(operable == AccountNonOperable or operable == AccountPartiallyOperable or operable == AccountFullyOperable):
|
(operable == AccountNonOperable or operable == AccountPartiallyOperable or operable == AccountFullyOperable):
|
||||||
account.operable = operable
|
account.operable = operable
|
||||||
|
@ -445,7 +450,7 @@ proc makePartiallyOperableAccoutsFullyOperable(self: Service, password: string,
|
||||||
return
|
return
|
||||||
let affectedAccounts = map(response.result.getElems(), x => x.getStr())
|
let affectedAccounts = map(response.result.getElems(), x => x.getStr())
|
||||||
for acc in affectedAccounts:
|
for acc in affectedAccounts:
|
||||||
self.updateAccountInLocalStoreAndNotify(acc, name = "", colorId = "", emoji = "", operable = AccountFullyOperable)
|
self.updateAccountInLocalStoreAndNotify(acc, name = "", colorId = "", emoji = "", ensName = "", operable = AccountFullyOperable)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error: ", procName="makeSeedPhraseKeypairFullyOperable", errName=e.name, errDesription=e.msg
|
error "error: ", procName="makeSeedPhraseKeypairFullyOperable", errName=e.name, errDesription=e.msg
|
||||||
|
|
||||||
|
@ -464,7 +469,7 @@ proc onNonProfileKeycardKeypairMigratedToApp*(self: Service, response: string) {
|
||||||
else:
|
else:
|
||||||
kp.keycards = @[]
|
kp.keycards = @[]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error handilng migrated keycard response", errDesription=e.msg
|
error "error handling migrated keycard response", errDesription=e.msg
|
||||||
self.events.emit(SIGNAL_ALL_KEYCARDS_DELETED, data)
|
self.events.emit(SIGNAL_ALL_KEYCARDS_DELETED, data)
|
||||||
|
|
||||||
proc migrateNonProfileKeycardKeypairToAppAsync*(self: Service, keyUid, seedPhrase, password: string, doPasswordHashing: bool) =
|
proc migrateNonProfileKeycardKeypairToAppAsync*(self: Service, keyUid, seedPhrase, password: string, doPasswordHashing: bool) =
|
||||||
|
@ -481,6 +486,29 @@ proc migrateNonProfileKeycardKeypairToAppAsync*(self: Service, keyUid, seedPhras
|
||||||
)
|
)
|
||||||
self.threadpool.start(arg)
|
self.threadpool.start(arg)
|
||||||
|
|
||||||
|
proc onENSNamesFetched*(self: Service, response: string) {.slot.} =
|
||||||
|
try:
|
||||||
|
let responseObj = response.parseJson
|
||||||
|
if responseObj{"error"}.kind != JNull and responseObj{"error"}.getStr != "":
|
||||||
|
raise newException(CatchableError, responseObj["error"].getStr)
|
||||||
|
for address, name in responseObj["result"].pairs:
|
||||||
|
let ensName = name.getStr
|
||||||
|
if ensName.len == 0:
|
||||||
|
continue
|
||||||
|
self.updateAccountInLocalStoreAndNotify(address, name = "", colorId = "", emoji = "", ensName)
|
||||||
|
except Exception as e:
|
||||||
|
error "error getting ENS names for accounts", errDesription=e.msg
|
||||||
|
|
||||||
|
proc fetchENSNamesForAddressesAsync(self: Service, addresses: seq[string], chainId: int) =
|
||||||
|
let arg = FetchENSNamesForAddressesTaskArg(
|
||||||
|
tptr: fetchENSNamesForAddressesTask,
|
||||||
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
|
slot: "onENSNamesFetched",
|
||||||
|
addresses: addresses,
|
||||||
|
chainId: chainId
|
||||||
|
)
|
||||||
|
self.threadpool.start(arg)
|
||||||
|
|
||||||
proc getRandomMnemonic*(self: Service): string =
|
proc getRandomMnemonic*(self: Service): string =
|
||||||
try:
|
try:
|
||||||
let response = status_go_accounts.getRandomMnemonic()
|
let response = status_go_accounts.getRandomMnemonic()
|
||||||
|
@ -621,7 +649,7 @@ proc moveAccountFinally*(self: Service, fromPosition: int, toPosition: int) =
|
||||||
updated = true
|
updated = true
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error: ", procName="moveAccountFinally", errName=e.name, errDesription=e.msg
|
error "error: ", procName="moveAccountFinally", errName=e.name, errDesription=e.msg
|
||||||
self.updateAccountInLocalStoreAndNotify(address = "", name = "", colorId = "", emoji = "", operable = "", some(updated))
|
self.updateAccountInLocalStoreAndNotify(address = "", name = "", colorId = "", emoji = "", ensName = "", operable = "", some(updated))
|
||||||
|
|
||||||
proc updateKeypairName*(self: Service, keyUid: string, name: string) =
|
proc updateKeypairName*(self: Service, keyUid: string, name: string) =
|
||||||
try:
|
try:
|
||||||
|
@ -719,7 +747,7 @@ proc handleWalletAccount(self: Service, account: WalletAccountDto, notify: bool
|
||||||
var localAcc = self.getAccountByAddress(account.address)
|
var localAcc = self.getAccountByAddress(account.address)
|
||||||
if not localAcc.isNil:
|
if not localAcc.isNil:
|
||||||
self.updateAccountInLocalStoreAndNotify(account.address, account.name, account.colorId, account.emoji,
|
self.updateAccountInLocalStoreAndNotify(account.address, account.name, account.colorId, account.emoji,
|
||||||
account.operable, none(bool), notify)
|
account.ens, account.operable, none(bool), notify)
|
||||||
else:
|
else:
|
||||||
self.addNewKeypairsAccountsToLocalStoreAndNotify(notify)
|
self.addNewKeypairsAccountsToLocalStoreAndNotify(notify)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue