feat(wallet): Disable send for soulbound collectibles (#14327)

This commit is contained in:
Cuteivist 2024-04-09 16:16:03 +02:00 committed by GitHub
parent b84c1f20df
commit 277dda7533
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 40 additions and 5 deletions

View File

@ -320,6 +320,16 @@ QtObject:
read = getTokenType read = getTokenType
notify = tokenTypeChanged notify = tokenTypeChanged
proc soulboundChanged*(self: CollectiblesEntry) {.signal.}
proc getSoulbound*(self: CollectiblesEntry): bool {.slot.} =
if not self.hasCollectibleData() or isNone(self.getCollectibleData().soulbound):
return false
return self.getCollectibleData().soulbound.get()
QtProperty[bool] soulbound:
read = getSoulbound
notify = soulboundChanged
proc updateDataIfSameID*(self: CollectiblesEntry, update: backend.Collectible): bool = proc updateDataIfSameID*(self: CollectiblesEntry, update: backend.Collectible): bool =
if self.id != update.id: if self.id != update.id:
return false return false

View File

@ -27,6 +27,7 @@ type
CommunityPrivilegesLevel CommunityPrivilegesLevel
CommunityImage CommunityImage
TokenType TokenType
Soulbound
QtObject: QtObject:
type type
@ -149,6 +150,7 @@ QtObject:
CollectibleRole.CommunityPrivilegesLevel.int:"communityPrivilegesLevel", CollectibleRole.CommunityPrivilegesLevel.int:"communityPrivilegesLevel",
CollectibleRole.CommunityImage.int:"communityImage", CollectibleRole.CommunityImage.int:"communityImage",
CollectibleRole.TokenType.int:"tokenType", CollectibleRole.TokenType.int:"tokenType",
CollectibleRole.Soulbound.int:"soulbound"
}.toTable }.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant = method data(self: Model, index: QModelIndex, role: int): QVariant =
@ -203,6 +205,8 @@ QtObject:
result = newQVariant(item.getCommunityImage()) result = newQVariant(item.getCommunityImage())
of CollectibleRole.TokenType: of CollectibleRole.TokenType:
result = newQVariant(item.getTokenType()) result = newQVariant(item.getTokenType())
of CollectibleRole.Soulbound:
result = newQVariant(item.getSoulbound())
proc rowData(self: Model, index: int, column: string): string {.slot.} = proc rowData(self: Model, index: int, column: string): string {.slot.} =
if (index >= self.items.len): if (index >= self.items.len):

View File

@ -41,6 +41,7 @@ type
animationMediaType*: Option[string] animationMediaType*: Option[string]
traits*: Option[seq[CollectibleTrait]] traits*: Option[seq[CollectibleTrait]]
backgroundColor*: Option[string] backgroundColor*: Option[string]
soulbound*: Option[bool]
CollectionData* = ref object of RootObj CollectionData* = ref object of RootObj
name*: string name*: string
@ -229,7 +230,8 @@ proc `$`*(self: CollectibleData): string =
animationUrl:{self.animationUrl}, animationUrl:{self.animationUrl},
animationMediaType:{self.animationMediaType}, animationMediaType:{self.animationMediaType},
traits:{self.traits}, traits:{self.traits},
backgroundColor:{self.backgroundColor} backgroundColor:{self.backgroundColor},
soulbound:{self.soulbound}
)""" )"""
proc getCollectibleTraits*(t: JsonNode): Option[seq[CollectibleTrait]] = proc getCollectibleTraits*(t: JsonNode): Option[seq[CollectibleTrait]] =
@ -256,7 +258,7 @@ proc fromJson*(t: JsonNode, T: typedesc[CollectibleData]): CollectibleData =
else: else:
result.imageUrl = none(string) result.imageUrl = none(string)
let animationUrlNode = t{"animation_url"} let animationUrlNode = t{"animation_url"}
if animationUrlNode != nil and animationUrlNode.kind != JNull: if animationUrlNode != nil and animationUrlNode.kind != JBool:
result.animationUrl = some(animationUrlNode.getStr()) result.animationUrl = some(animationUrlNode.getStr())
else: else:
result.animationUrl = none(string) result.animationUrl = none(string)
@ -265,6 +267,11 @@ proc fromJson*(t: JsonNode, T: typedesc[CollectibleData]): CollectibleData =
result.animationMediaType = some(animationMediaTypeNode.getStr()) result.animationMediaType = some(animationMediaTypeNode.getStr())
else: else:
result.animationMediaType = none(string) result.animationMediaType = none(string)
let soulboundNode = t{"soulbound"}
if soulboundNode != nil and soulboundNode.kind != JNull:
result.soulbound = some(soulboundNode.getBool())
else:
result.soulbound = none(bool)
result.traits = getCollectibleTraits(t{"traits"}) result.traits = getCollectibleTraits(t{"traits"})
let backgroundColorNode = t{"background_color"} let backgroundColorNode = t{"background_color"}
if backgroundColorNode != nil and backgroundColorNode.kind != JNull: if backgroundColorNode != nil and backgroundColorNode.kind != JNull:

View File

@ -262,7 +262,15 @@ Item {
walletStore: RootStore walletStore: RootStore
networkConnectionStore: root.networkConnectionStore networkConnectionStore: root.networkConnectionStore
isCommunityOwnershipTransfer: footer.isHoldingSelected && footer.isOwnerCommunityCollectible isCommunityOwnershipTransfer: footer.isHoldingSelected && footer.isOwnerCommunityCollectible
communityName: !!walletStore.currentViewedCollectible ? walletStore.currentViewedCollectible.communityName : "" communityName: {
if (!walletStore.currentViewedCollectible)
return ""
const name = walletStore.currentViewedCollectible.communityName
const id = walletStore.currentViewedCollectible.communityId
if (name === id)
return Utils.compactAddress(id, 4)
return name
}
onLaunchShareAddressModal: Global.openShowQRPopup({ onLaunchShareAddressModal: Global.openShowQRPopup({
switchingAccounsEnabled: true, switchingAccounsEnabled: true,
changingPreferredChainsEnabled: true, changingPreferredChainsEnabled: true,

View File

@ -28,6 +28,12 @@ Rectangle {
color: Theme.palette.statusAppLayout.rightPanelBackgroundColor color: Theme.palette.statusAppLayout.rightPanelBackgroundColor
QtObject {
id: d
readonly property bool isCollectibleViewed: !!walletStore.currentViewedCollectible
readonly property bool isCollectibleSoulbound: d.isCollectibleViewed && walletStore.currentViewedCollectible.soulbound
}
StatusModalDivider { StatusModalDivider {
anchors.top: parent.top anchors.top: parent.top
width: parent.width width: parent.width
@ -42,9 +48,9 @@ Rectangle {
objectName: "walletFooterSendButton" objectName: "walletFooterSendButton"
icon.name: "send" icon.name: "send"
text: root.isCommunityOwnershipTransfer ? qsTr("Send Owner token to transfer %1 Community ownership").arg(root.communityName) : qsTr("Send") text: root.isCommunityOwnershipTransfer ? qsTr("Send Owner token to transfer %1 Community ownership").arg(root.communityName) : qsTr("Send")
interactive: networkConnectionStore.sendBuyBridgeEnabled interactive: !d.isCollectibleSoulbound && networkConnectionStore.sendBuyBridgeEnabled
onClicked: root.launchSendModal() onClicked: root.launchSendModal()
tooltip.text: networkConnectionStore.sendBuyBridgeToolTipText tooltip.text: d.isCollectibleSoulbound ? qsTr("Soulbound collectibles cannot be sent to another wallet") : networkConnectionStore.sendBuyBridgeToolTipText
visible: !walletStore.overview.isWatchOnlyAccount && walletStore.overview.canSend visible: !walletStore.overview.isWatchOnlyAccount && walletStore.overview.canSend
} }