fix(@desktop/wallet): SendModal: Move logic to nim Part 2, parsing recipient address string to separate the chain prefixes

fixes #12149
This commit is contained in:
Khushboo Mehta 2023-09-19 17:06:57 +02:00 committed by Khushboo-dev-cpp
parent 3e985e62e1
commit c8c9c706d9
8 changed files with 118 additions and 91 deletions

View File

@ -65,3 +65,6 @@ method getCollectiblesModel*(self: AccessInterface): collectibles.Model =
method getNestedCollectiblesModel*(self: AccessInterface): nested_collectibles.Model = method getNestedCollectiblesModel*(self: AccessInterface): nested_collectibles.Model =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method splitAndFormatAddressPrefix*(self: AccessInterface, text : string, updateInStore: bool): string {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -334,3 +334,26 @@ method getCollectiblesModel*(self: Module): collectibles.Model =
method getNestedCollectiblesModel*(self: Module): nested_collectibles.Model = method getNestedCollectiblesModel*(self: Module): nested_collectibles.Model =
return self.nestedCollectiblesModel return self.nestedCollectiblesModel
method splitAndFormatAddressPrefix*(self: Module, text : string, updateInStore: bool): string {.slot.} =
var tempPreferredChains: seq[int]
var chainFound = false
var editedText = ""
for word in plainText(text).split(':'):
if word.startsWith("0x"):
editedText = editedText & word
else:
let chainColor = self.view.getNetworkColor(word)
if not chainColor.isEmptyOrWhitespace():
chainFound = true
tempPreferredChains.add(self.view.getNetworkChainId(word))
editedText = editedText & "<span style='color: " & chainColor & "'>" & word & "</span>" & ":"
if updateInStore:
if not chainFound:
self.view.updateRoutePreferredChains(self.view.getLayer1NetworkChainId())
else:
self.view.updateRoutePreferredChains(tempPreferredChains.join(":"))
editedText = "<a><p>" & editedText & "</a></p>"
return editedText

View File

@ -166,25 +166,30 @@ QtObject:
proc updateFromNetworks*(self: NetworkModel, path: SuggestedRouteItem, hasGas: bool) = proc updateFromNetworks*(self: NetworkModel, path: SuggestedRouteItem, hasGas: bool) =
for i in 0 ..< self.items.len: for i in 0 ..< self.items.len:
let index = self.createIndex(i, 0, nil)
defer: index.delete
self.items[i].amountIn = ""
self.items[i].resetToNetworks
self.items[i].hasGas = true
self.items[i].locked = false
if path.getfromNetwork() == self.items[i].getChainId(): if path.getfromNetwork() == self.items[i].getChainId():
let index = self.createIndex(i, 0, nil)
defer: index.delete
self.items[i].amountIn = path.getAmountIn() self.items[i].amountIn = path.getAmountIn()
self.items[i].toNetworks = path.getToNetwork() self.items[i].toNetworks = path.getToNetwork()
self.items[i].hasGas = hasGas self.items[i].hasGas = hasGas
self.items[i].locked = path.getAmountInLocked() self.items[i].locked = path.getAmountInLocked()
self.dataChanged(index, index, @[ModelRole.AmountIn.int, ModelRole.ToNetworks.int, ModelRole.HasGas.int, ModelRole.Locked.int]) self.dataChanged(index, index, @[ModelRole.AmountIn.int, ModelRole.ToNetworks.int, ModelRole.HasGas.int, ModelRole.Locked.int])
proc updateToNetworks*(self: NetworkModel, path: SuggestedRouteItem) = proc updateToNetworks*(self: NetworkModel, path: SuggestedRouteItem) =
for i in 0 ..< self.items.len: for i in 0 ..< self.items.len:
let index = self.createIndex(i, 0, nil)
defer: index.delete
self.items[i].amountOut = ""
if path.getToNetwork() == self.items[i].getChainId(): if path.getToNetwork() == self.items[i].getChainId():
let index = self.createIndex(i, 0, nil)
defer: index.delete
if self.items[i].getAmountOut().len != 0: if self.items[i].getAmountOut().len != 0:
self.items[i].amountOut = $(parseInt(self.items[i].getAmountOut()) + parseInt(path.getAmountOut())) self.items[i].amountOut = $(parseInt(self.items[i].getAmountOut()) + parseInt(path.getAmountOut()))
else: else:
self.items[i].amountOut = path.getAmountOut() self.items[i].amountOut = path.getAmountOut()
self.dataChanged(index, index, @[ModelRole.AmountOut.int]) self.dataChanged(index, index, @[ModelRole.AmountOut.int])
proc getRouteDisabledNetworkChainIds*(self: NetworkModel): seq[int] = proc getRouteDisabledNetworkChainIds*(self: NetworkModel): seq[int] =
var disbaledChains: seq[int] = @[] var disbaledChains: seq[int] = @[]
@ -303,3 +308,8 @@ QtObject:
self.items[i].lockedAmount = amount self.items[i].lockedAmount = amount
self.dataChanged(index, index, @[ModelRole.LockedAmount.int]) self.dataChanged(index, index, @[ModelRole.LockedAmount.int])
proc getLayer1Network*(self: NetworkModel): int =
for item in self.items:
if item.getLayer() == 1:
return item.getChainId()
return 0

View File

@ -228,8 +228,6 @@ QtObject:
return self.selectedSenderAccount.address() return self.selectedSenderAccount.address()
proc updatedNetworksWithRoutes*(self: View, paths: seq[SuggestedRouteItem], totalFeesInEth: float) = proc updatedNetworksWithRoutes*(self: View, paths: seq[SuggestedRouteItem], totalFeesInEth: float) =
self.fromNetworksModel.reset()
self.toNetworksModel.reset()
for path in paths: for path in paths:
let fromChainId = path.getfromNetwork() let fromChainId = path.getfromNetwork()
let hasGas = self.selectedSenderAccount.getAssets().hasGas(fromChainId, self.fromNetworksModel.getNetworkNativeGasSymbol(fromChainId), totalFeesInEth) let hasGas = self.selectedSenderAccount.getAssets().hasGas(fromChainId, self.fromNetworksModel.getNetworkNativeGasSymbol(fromChainId), totalFeesInEth)
@ -242,3 +240,30 @@ QtObject:
self.transactionRoutes = newTransactionRoutes() self.transactionRoutes = newTransactionRoutes()
self.selectedAssetSymbol = "" self.selectedAssetSymbol = ""
self.showUnPreferredChains = false self.showUnPreferredChains = false
proc getLayer1NetworkChainId*(self: View): string =
return $self.fromNetworksModel.getLayer1Network()
proc getNetworkColor*(self: View, shortName : string): string =
return self.fromNetworksModel.getNetworkColor(shortName)
proc getNetworkChainId*(self: View, shortName : string): int =
return self.fromNetworksModel.getNetworkChainId(shortName)
proc splitAndFormatAddressPrefix(self: View, text : string, updateInStore: bool): string {.slot.} =
return self.delegate.splitAndFormatAddressPrefix(text, updateInStore)
proc getAddressFromFormattedString(self: View, text : string): string {.slot.} =
var splitWords = plainText(text).split(':')
for i in countdown(splitWords.len-1, 0):
if splitWords[i].startsWith("0x"):
return splitWords[i]
return ""
proc getShortChainIds(self: View, chainShortNames : string): string {.slot.} =
if chainShortNames.isEmptyOrWhitespace():
return ""
var preferredChains: seq[int]
for shortName in chainShortNames.split(':'):
preferredChains.add(self.fromNetworksModel.getNetworkChainId(shortName))
return preferredChains.join(":")

View File

@ -450,7 +450,7 @@ StatusDialog {
store: popup.store store: popup.store
interactive: popup.interactive interactive: popup.interactive
selectedAccount: popup.selectedAccount selectedAccount: popup.selectedAccount
ensAddressOrEmpty: recipientLoader.isENSValid ? recipientLoader.resolvedENSAddress : "" ensAddressOrEmpty: recipientLoader.resolvedENSAddress
amountToSend: amountToSendInput.cryptoValueToSendFloat amountToSend: amountToSendInput.cryptoValueToSendFloat
minSendCryptoDecimals: amountToSendInput.minSendCryptoDecimals minSendCryptoDecimals: amountToSendInput.minSendCryptoDecimals
minReceiveCryptoDecimals: amountToSendInput.minReceiveCryptoDecimals minReceiveCryptoDecimals: amountToSendInput.minReceiveCryptoDecimals

View File

@ -23,9 +23,8 @@ Loader {
property var selectedRecipient: null property var selectedRecipient: null
property int selectedRecipientType property int selectedRecipientType
readonly property bool ready: (d.isAddressValid || root.isENSValid) && !d.isPending readonly property bool ready: (d.isAddressValid || !!resolvedENSAddress) && !d.isPending
property string addressText property string addressText
property bool isENSValid: false
property string resolvedENSAddress property string resolvedENSAddress
signal recalculateRoutesAndFees() signal recalculateRoutesAndFees()
@ -35,84 +34,74 @@ Loader {
onSelectedRecipientChanged: { onSelectedRecipientChanged: {
root.isLoading() root.isLoading()
d.waitTimer.restart()
if(!isERC721Transfer) {
if(!root.isBridgeTx)
root.store.updateRoutePreferredChains(root.selectedRecipient.preferredSharingChainIds)
else
root.store.setAllNetworksAsRoutePreferredChains()
}
if(!!root.selectedRecipient && root.selectedRecipientType !== TabAddressSelectorView.Type.None) { if(!!root.selectedRecipient && root.selectedRecipientType !== TabAddressSelectorView.Type.None) {
let preferredChainIds = []
switch(root.selectedRecipientType) { switch(root.selectedRecipientType) {
case TabAddressSelectorView.Type.Account: {
root.addressText = root.selectedRecipient.address
preferredChainIds = root.selectedRecipient.preferredSharingChainIds
break
}
case TabAddressSelectorView.Type.SavedAddress: { case TabAddressSelectorView.Type.SavedAddress: {
if (root.selectedRecipient.ens.length > 0) { root.addressText = root.selectedRecipient.address
d.isPending = true if (!!root.selectedRecipient.ens && root.selectedRecipient.ens.length > 0) {
return store.resolveENS(root.selectedRecipient.ens) root.resolvedENSAddress = root.selectedRecipient.ens
} }
preferredChainIds = store.getShortChainIds(root.selectedRecipient.chainShortNames)
break break
} }
case TabAddressSelectorView.Type.RecentsAddress: { case TabAddressSelectorView.Type.RecentsAddress: {
let isIncoming = root.selectedRecipient.txType === Constants.TransactionType.Receive let isIncoming = root.selectedRecipient.txType === Constants.TransactionType.Receive
root.addressText = isIncoming ? root.selectedRecipient.sender : root.selectedRecipient.recipient root.addressText = isIncoming ? root.selectedRecipient.sender : root.selectedRecipient.recipient
root.item.input.text = root.addressText root.item.input.text = root.addressText
return break
} }
case TabAddressSelectorView.Type.Address: { case TabAddressSelectorView.Type.Address: {
root.addressText = root.selectedRecipient.address
root.item.input.text = root.selectedRecipient.address root.item.input.text = root.selectedRecipient.address
break break
} }
} }
root.addressText = root.selectedRecipient.address
// set preferred chains
if(!isERC721Transfer) {
if(root.isBridgeTx)
root.store.setAllNetworksAsRoutePreferredChains()
else
root.store.updateRoutePreferredChains(preferredChainIds)
}
recalculateRoutesAndFees()
} }
} }
QtObject { QtObject {
id: d id: d
property bool isAddressValid: Utils.isValidAddress(root.addressText) property bool isAddressValid: Utils.isValidAddress(root.addressText)
readonly property var resolveENS: Backpressure.debounce(root, 500, function (ensName) { readonly property var resolveENS: Backpressure.debounce(root, 1500, function (ensName) {
store.resolveENS(ensName) store.resolveENS(ensName)
}) })
property bool isPending: false property bool isPending: false
function clearValues() { function clearValues() {
root.addressText = "" root.addressText = ""
root.isENSValid = false
root.resolvedENSAddress = "" root.resolvedENSAddress = ""
root.selectedRecipientType = TabAddressSelectorView.Type.None root.selectedRecipientType = TabAddressSelectorView.Type.None
root.selectedRecipient = null root.selectedRecipient = null
} }
property Timer waitTimer: Timer { property Timer waitTimer: Timer {
interval: 1500 interval: 1500
onTriggered: { onTriggered: d.evaluateAndSetPreferredChains()
if(!!root.item) {
if (d.isPending) {
return
}
if (root.isENSValid) {
if(!!root.item.input)
root.item.input.text = root.resolvedENSAddress
root.addressText = root.resolvedENSAddress
store.splitAndFormatAddressPrefix(root.address, !root.isBridgeTx && !isERC721Transfer)
} else {
let address = d.getAddress()
let result = store.splitAndFormatAddressPrefix(address, !root.isBridgeTx && !isERC721Transfer)
if(!!result.address) {
root.addressText = result.address
if(!!root.item.input)
root.item.input.text = result.formattedText
}
}
root.recalculateRoutesAndFees()
}
}
} }
function getAddress() { function evaluateAndSetPreferredChains() {
if(root.selectedRecipientType === TabAddressSelectorView.Type.SavedAddress || root.selectedRecipientType === TabAddressSelectorView.Type.Account){ let address = !!root.item.input && !!root.store.plainText(root.item.input.text) ? root.store.plainText(root.item.input.text): ""
return root.item.chainShortNames + root.selectedRecipient.address let result = store.splitAndFormatAddressPrefix(address, !root.isBridgeTx && !isERC721Transfer)
} if(!!result.address) {
else { root.addressText = result.address
return !!root.item.input && !!root.store.plainText(root.item.input.text) ? root.store.plainText(root.item.input.text): "" if(!!root.item.input)
root.item.input.text = result.formattedText
} }
root.recalculateRoutesAndFees()
} }
} }
@ -196,7 +185,7 @@ Loader {
Layout.preferredHeight: 16 Layout.preferredHeight: 16
icon: "tiny/checkmark" icon: "tiny/checkmark"
color: Theme.palette.primaryColor1 color: Theme.palette.primaryColor1
visible: !!store.plainText(recipientInput.text) visible: root.ready
} }
ClearButton { ClearButton {
Layout.preferredWidth: 24 Layout.preferredWidth: 24
@ -215,11 +204,13 @@ Loader {
} }
else { else {
root.isLoading() root.isLoading()
d.waitTimer.restart() if(Utils.isValidEns(plainText)) {
if(!Utils.isValidAddress(plainText)) {
d.isPending = true d.isPending = true
d.resolveENS(plainText) d.resolveENS(plainText)
} }
else {
d.waitTimer.restart()
}
} }
} }
} }
@ -231,9 +222,11 @@ Loader {
d.isPending = false d.isPending = false
if(Utils.isValidAddress(resolvedAddress)) { if(Utils.isValidAddress(resolvedAddress)) {
root.resolvedENSAddress = resolvedAddress root.resolvedENSAddress = resolvedAddress
root.isENSValid = true root.addressText = root.resolvedENSAddress
if(!!root.item.input)
root.item.input.text = root.resolvedENSAddress
d.evaluateAndSetPreferredChains()
} }
d.waitTimer.restart()
} }
} }
} }

View File

@ -33,7 +33,6 @@ Item {
enum Type { enum Type {
Address, Address,
Contact,
Account, Account,
SavedAddress, SavedAddress,
RecentsAddress, RecentsAddress,

View File

@ -226,40 +226,14 @@ QtObject {
nestedCollectiblesModel.currentCollectionUid = "" nestedCollectiblesModel.currentCollectionUid = ""
} }
// TODO: move to nim
function splitAndFormatAddressPrefix(text, updateInStore) { function splitAndFormatAddressPrefix(text, updateInStore) {
let address = ""
let tempPreferredChains = []
let chainFound = false
let splitWords = plainText(text).split(':')
let editedText = ""
for(var i=0; i<splitWords.length; i++) {
const word = splitWords[i]
if(word.startsWith("0x")) {
address = word
editedText += word
} else {
let chainColor = fromNetworksModel.getNetworkColor(word)
if(!!chainColor) {
chainFound = true
tempPreferredChains.push(fromNetworksModel.getNetworkChainId(word))
editedText += `<span style='color: %1'>%2</span>`.arg(chainColor).arg(word)+':'
}
}
}
if(updateInStore) {
if(!chainFound)
updateRoutePreferredChains(networksModule.getMainnetChainId())
else
updateRoutePreferredChains(tempPreferredChains.join(":"))
}
editedText +="</a></p>"
return { return {
formattedText: editedText, formattedText: walletSectionSendInst.splitAndFormatAddressPrefix(text, updateInStore),
address: address address: walletSectionSendInst.getAddressFromFormattedString(text)
} }
} }
function getShortChainIds(chainShortNames) {
return walletSectionSendInst.getShortChainIds(chainShortNames)
}
} }