Skip to content

Commit

Permalink
feat(@desktop/wallet): Integrates the new sign model into the simple …
Browse files Browse the repository at this point in the history
…send

fixes #17060
  • Loading branch information
Khushboo-dev-cpp authored and Khushboo mehta committed Jan 23, 2025
1 parent 30009b2 commit 595807e
Show file tree
Hide file tree
Showing 15 changed files with 403 additions and 103 deletions.
11 changes: 8 additions & 3 deletions storybook/pages/SendSignModalPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ SplitView {
formatBigNumber: (number, symbol, noSymbolOption) => parseFloat(number).toLocaleString(Qt.locale(), 'f', 2)
+ (noSymbolOption ? "" : " " + (symbol || Qt.locale().currencySymbol(Locale.CurrencyIsoCode)))

fromTokenSymbol: ctrlFromSymbol.text
fromTokenAmount: ctrlFromAmount.text
fromTokenContractAddress: "0x6B175474E89094C44Da98b954EedeAC495271d0F"
tokenSymbol: ctrlFromSymbol.text
tokenAmount: ctrlFromAmount.text
tokenContractAddress: "0x6B175474E89094C44Da98b954EedeAC495271d0F"

accountName: priv.selectedAccount.name
accountAddress: priv.selectedAccount.address
Expand All @@ -98,6 +98,7 @@ SplitView {
cryptoFees: formatBigNumber(0.06, "ETH")
estimatedTime: qsTr("> 5 minutes")

isCollectibleLoading: isCollectibleLoadingCheckbox.checked
isCollectible: isCollectibleCheckbox.checked
collectibleContractAddress: !!collectibleComboBox.currentCollectible ?
collectibleComboBox.currentCollectible.contractAddress: ""
Expand Down Expand Up @@ -152,6 +153,10 @@ SplitView {
id: isCollectibleCheckbox
text:"is collectible"
}
CheckBox {
id: isCollectibleLoadingCheckbox
text:"is collectible loading"
}
ComboBox {
id: collectibleComboBox
property var currentCollectible
Expand Down
44 changes: 22 additions & 22 deletions storybook/qmlTests/tests/tst_SendSignModal.qml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ Item {

formatBigNumber: (number, symbol, noSymbolOption) => parseFloat(number).toLocaleString(Qt.locale(), 'f', 2) + (noSymbolOption ? "" : " " + symbol)

fromTokenSymbol: "DAI"
fromTokenAmount: "100.07"
fromTokenContractAddress: "0x6B175474E89094C44Da98b954EedeAC495271d0F"
tokenSymbol: "DAI"
tokenAmount: "100.07"
tokenContractAddress: "0x6B175474E89094C44Da98b954EedeAC495271d0F"

accountName: "Hot wallet (generated)"
accountAddress: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8881"
Expand Down Expand Up @@ -101,15 +101,15 @@ Item {

function test_fromToProps() {
verify(!!controlUnderTest)
controlUnderTest.fromTokenSymbol = "DAI"
controlUnderTest.fromTokenAmount = "1000.123456789"
controlUnderTest.fromTokenContractAddress = "Oxdeadbeef"
controlUnderTest.tokenSymbol = "DAI"
controlUnderTest.tokenAmount = "1000.123456789"
controlUnderTest.tokenContractAddress = "Oxdeadbeef"

// title
compare(controlUnderTest.title, qsTr("Sign Send"))

// subtitle
compare(controlUnderTest.subtitle, qsTr("%1 to %2").arg(controlUnderTest.formatBigNumber(controlUnderTest.fromTokenAmount, controlUnderTest.fromTokenSymbol))
compare(controlUnderTest.subtitle, qsTr("%1 %2 to %3").arg(controlUnderTest.tokenAmount).arg(controlUnderTest.tokenSymbol)
.arg(SQUtils.Utils.elideAndFormatWalletAddress(controlUnderTest.recipientAddress)))

compare(controlUnderTest.gradientColor, controlUnderTest.accountColor)
Expand All @@ -120,8 +120,8 @@ Item {
// info box
const headerText = findChild(controlUnderTest.contentItem, "headerText")
verify(!!headerText)
compare(headerText.text, qsTr("Send %1 to %2 on %3").
arg(controlUnderTest.formatBigNumber(controlUnderTest.fromTokenAmount, controlUnderTest.fromTokenSymbol)).
compare(headerText.text, qsTr("Send %1 %2 to %3 on %4").
arg(controlUnderTest.tokenAmount).arg(controlUnderTest.tokenSymbol).
arg(SQUtils.Utils.elideAndFormatWalletAddress(controlUnderTest.recipientAddress)).arg(controlUnderTest.networkName))
const fromImage = findChild(controlUnderTest.contentItem, "fromImageIdenticon")
verify(!!fromImage)
Expand All @@ -132,14 +132,14 @@ Item {

const toImage = findChild(controlUnderTest.contentItem, "toImageIdenticon")
verify(!!toImage)
compare(toImage.asset.name, Constants.tokenIcon(controlUnderTest.fromTokenSymbol))
compare(toImage.asset.name, Constants.tokenIcon(controlUnderTest.tokenSymbol))

// send box
const sendBox = findChild(controlUnderTest.contentItem, "sendAssetBox")
verify(!!sendBox)
compare(sendBox.caption, qsTr("Send"))
compare(sendBox.primaryText, "1,000.12 DAI")
compare(sendBox.secondaryText, SQUtils.Utils.elideAndFormatWalletAddress(controlUnderTest.fromTokenContractAddress))
compare(sendBox.primaryText, "1000.123456789 DAI")
compare(sendBox.secondaryText, SQUtils.Utils.elideAndFormatWalletAddress(controlUnderTest.tokenContractAddress))
}

function test_tokenContextmenu() {
Expand All @@ -165,14 +165,14 @@ Item {

const externalLink = findChild(contextMenu, "externalLink")
verify(!!externalLink)
compare(externalLink.text, !!controlUnderTest.fromTokenSymbol ?
qsTr("View %1 %2 contract address on %3").arg(controlUnderTest.networkName).arg(controlUnderTest.fromTokenSymbol).arg("Etherscan")
compare(externalLink.text, !!controlUnderTest.tokenSymbol ?
qsTr("View %1 %2 contract address on %3").arg(controlUnderTest.networkName).arg(controlUnderTest.tokenSymbol).arg("Etherscan")
: qsTr("View %1 contract address on %2").arg(controlUnderTest.networkName).arg("Etherscan"))
compare(externalLink.icon.name, "external-link")
externalLink.triggered()
tryCompare(signalSpyOpenLink, "count", 1)
compare(signalSpyOpenLink.signalArguments[0][0],
"%1/%2/%3".arg(controlUnderTest.networkBlockExplorerUrl).arg(Constants.networkExplorerLinks.addressPath).arg(controlUnderTest.fromTokenContractAddress))
"%1/%2/%3".arg(controlUnderTest.networkBlockExplorerUrl).arg(Constants.networkExplorerLinks.addressPath).arg(controlUnderTest.tokenContractAddress))
verify(!contextMenu.opened)

contractInfoButtonWithMenu.clicked(0)
Expand Down Expand Up @@ -274,12 +274,12 @@ Item {
verify(!!loadingComponent)
verify(loadingComponent.visible)

const fromAccountSmartIdenticon = findChild(controlUnderTest.contentItem, "fromAccountSmartIdenticon")
verify(!!fromAccountSmartIdenticon)
compare(fromAccountSmartIdenticon.asset.name, "filled-account")
compare(fromAccountSmartIdenticon.asset.emoji, controlUnderTest.accountEmoji)
compare(fromAccountSmartIdenticon.asset.color, controlUnderTest.accountColor)
compare(fromAccountSmartIdenticon.asset.isLetterIdenticon, !!controlUnderTest.accountEmoji)
const accountSmartIdenticon = findChild(controlUnderTest.contentItem, "accountSmartIdenticon")
verify(!!accountSmartIdenticon)
compare(accountSmartIdenticon.asset.name, "filled-account")
compare(accountSmartIdenticon.asset.emoji, controlUnderTest.accountEmoji)
compare(accountSmartIdenticon.asset.color, controlUnderTest.accountColor)
compare(accountSmartIdenticon.asset.isLetterIdenticon, !!controlUnderTest.accountEmoji)

// send collectible box
const collectibleCaption = findChild(controlUnderTest.contentItem, "collectibleCaption")
Expand Down Expand Up @@ -325,7 +325,7 @@ Item {
blockchainExternalLink.triggered()
tryCompare(signalSpyOpenLink, "count", 2)
compare(signalSpyOpenLink.signalArguments[1][0],
"%1/nft/%2/%3".arg("Etherscan").arg(data.contractAddress).arg(data.tokenId))
"%1/nft/%2/%3".arg("https://etherscan.io/").arg(data.contractAddress).arg(data.tokenId))

const copyButton = findChild(moreMenu, "copyButton")
verify(!!copyButton)
Expand Down
99 changes: 99 additions & 0 deletions ui/app/AppLayouts/Wallet/adaptors/SignSendAdaptor.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import QtQuick 2.15

import StatusQ 0.1
import StatusQ.Core.Utils 0.1

/**
Adaptor transforming selected data from send to a format that
can be used in the sign modal
**/
QObject {
id: root

/** Account key used for filtering **/
required property string accountKey
/** network chainId used for filtering **/
required property int chainId
/** token key used for filtering **/
required property string tokenKey
/** amount selected in send modal for sending **/
required property string selectedAmountInBaseUnit
/**
Expected model structure:
name [int] - name of account
address [string] - address of account
emoji [string] - emoji of account
colorId [string] - colorId of account
**/
required property var accountsModel
/**
Expected model structure:
chainId [int] - network chain id
chainName [string] - name of network
iconUrl [string] - network icon url
**/
required property var networksModel
/**
Expected model structure:
key [int] - unique id of token
symbol [int] - symbol of token
decimals [string] - decimals of token
**/
required property var tokenBySymbolModel

/** output property of the account selected **/
readonly property var selectedAccount: selectedAccountEntry.item
/** output property of the network selected **/
readonly property var selectedNetwork: selectedNetworkEntry.item
/** output property of the asset (ERC20) selected **/
readonly property var selectedAsset: selectedAssetEntry.item
/** output property of the localised amount to send **/
readonly property string selectedAmount: {
const decimals = !!root.selectedAsset ? root.selectedAsset.decimals: 0
const divisor = AmountsArithmetic.fromExponent(decimals)
let amount = AmountsArithmetic.div(
AmountsArithmetic.fromString(root.selectedAmountInBaseUnit),
divisor).toFixed(decimals)
// removeDecimalTrailingZeros
amount = Utils.stripTrailingZeros(amount)
// localize
return amount.replace(".", Qt.locale().decimalPoint)
}
/** output property of the selected asset contract address on selected chainId **/
readonly property string selectedAssetContractAddress: selectedAssetContractEntry.available &&
!!selectedAssetContractEntry.item ?
selectedAssetContractEntry.item.address: ""

ModelEntry {
id: selectedAccountEntry
sourceModel: root.accountsModel
value: root.accountKey
key: "address"
}

ModelEntry {
id: selectedNetworkEntry
sourceModel: root.networksModel
value: root.chainId
key: "chainId"
}

ModelEntry {
id: selectedAssetEntry
sourceModel: root.tokenBySymbolModel
value: root.tokenKey
key: "key"
}

ModelEntry {
id: selectedAssetContractEntry
sourceModel: selectedAssetEntry.available &&
!!selectedAssetEntry.item ?
selectedAssetEntry.item.addressPerChain: null
value: root.chainId
key: "chainId"
}
}
1 change: 1 addition & 0 deletions ui/app/AppLayouts/Wallet/adaptors/qmldir
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
CollectiblesSelectionAdaptor 1.0 CollectiblesSelectionAdaptor.qml
TokenSelectorViewAdaptor 1.0 TokenSelectorViewAdaptor.qml
WalletAccountsSelectorAdaptor 1.0 WalletAccountsSelectorAdaptor.qml
SignSendAdaptor 1.0 SignSendAdaptor.qml
1 change: 1 addition & 0 deletions ui/app/AppLayouts/Wallet/controls/RouterErrorTag.qml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Control {

color: Theme.palette.dangerColor1
font.pixelSize: Theme.additionalTextSize
elide: Text.ElideRight
}
StatusButton {
id: addBalanceButton
Expand Down
21 changes: 15 additions & 6 deletions ui/app/AppLayouts/Wallet/panels/RecipientInfoButtonWithMenu.qml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import QtQuick 2.15

import StatusQ 0.1
import StatusQ.Core.Theme 0.1
Expand All @@ -9,31 +10,39 @@ import utils 1.0
StatusFlatButton {
id: root

/** Input property holding selected recipient address **/
required property string recipientAddress
/** Input property holding selected network name **/
required property string networkName
/** Input property holding selected network short name **/
required property string networkShortName
/** Input property holding selected network explorer url **/
required property string networkBlockExplorerUrl

/** Signal to launch link **/
signal openLink(string link)

QtObject {
id: d

function getExplorerName() {
return Utils.getChainExplorerName(root.networkShortName)
}
}

icon.name: "more"
icon.color: highlighted ? Theme.palette.directColor1 : Theme.palette.directColor5

highlighted: moreMenu.opened
onClicked: moreMenu.popup(root, 0, height + 4)

function getExplorerName() {
return Utils.getChainExplorerName(root.networkShortName)
}

StatusMenu {
id: moreMenu
objectName: "moreMenu"

StatusAction {
objectName: "externalLink"
//: e.g. "View receiver address on Etherscan"
text: qsTr("View receiver address on %1").arg(getExplorerName())
text: qsTr("View receiver address on %1").arg(d.getExplorerName())
icon.name: "external-link"
onTriggered: {
var link = "%1/%2/%3".arg(root.networkBlockExplorerUrl).arg(Constants.networkExplorerLinks.addressPath).arg(root.recipientAddress)
Expand Down
21 changes: 17 additions & 4 deletions ui/app/AppLayouts/Wallet/panels/SignCollectibleInfoBox.qml
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,30 @@ import AppLayouts.Wallet.views.collectibles 1.0
Control {
id: root

/** Input property holding collectible name **/
required property string name

required property string backgroundColor
/** Input property holding collectible background color **/
required property color backgroundColor
/** Input property holding if collectible has valid metadata **/
required property bool isMetadataValid
/** Input property holding collectible fallback image url **/
required property string fallbackImageUrl
/** Input property holding collectible contract address **/
required property string contractAddress
/** Input property holding collectible tokenId **/
required property string tokenId
/** Input property holding if collectible is loading **/
required property bool loading

/** Input property holding network short name **/
required property string networkShortName
/** Input property holding network explorer url **/
required property string networkBlockExplorerUrl

/** Input property holding openSea explorer url **/
required property string openSeaExplorerUrl

/** Signal to launch link **/
signal openLink(string link)

QtObject {
Expand All @@ -38,10 +50,10 @@ Control {

readonly property string collectibleBlockExplorerLink: {
if (root.networkShortName === Constants.networkShortChainNames.mainnet) {
return "%1/nft/%2/%3".arg(getExplorerName()).arg(root.contractAddress).arg(root.tokenId)
return "%1/nft/%2/%3".arg(root.networkBlockExplorerUrl).arg(root.contractAddress).arg(root.tokenId)
}
else {
return "%1/token/%2?a=%3".arg(getExplorerName()).arg(root.contractAddress).arg(root.tokenId)
return "%1/token/%2?a=%3".arg(root.networkBlockExplorerUrl).arg(root.contractAddress).arg(root.tokenId)
}
}
}
Expand Down Expand Up @@ -73,6 +85,7 @@ Control {
Layout.preferredWidth: 40
Layout.preferredHeight: 40
radius: 4
isCollectibleLoading: root.loading
}

ColumnLayout {
Expand Down
Loading

0 comments on commit 595807e

Please sign in to comment.