I'm developing a game and I have an avatar resource with the following definition that stores accessory NFTs and includes an equip function that returns any accessory that was existing in the slot
pub resource Avatar {
pub let id: UInt64
pub let accessories: @{String: Accessory}
init() {
self.id = Avatar.totalMinted + 1
self.accessories <- {}
Avatar.totalMinted = Avatar.totalMinted + 1
}
destroy () {
Avatar.totalAvatars = Avatar.totalAvatars - 1
destroy self.accessories
}
pub fun equip(accessory: @Accessory): @Accessory? {
// Shift accessory into accessories dictionary and return old accessory
let oldAccessory <- self.accessories[accessory.getAccessoryData().slot] <- accessory
return <- oldAccessory
}
}
Now in my transaction I get the accessory from my collection and equip it, making sure i deposit the old accessory in the slot if that exists.
import Avatar from 0x03
import NonFungibleToken from 0x01
transaction(avatarId: UInt64, accessoryId: UInt64) {
let collection: &Avatar.Collection
let avatar: auth &Avatar.Avatar
let accessory: @Avatar.Accessory
prepare(signer: AuthAccount) {
self.collection = signer.borrow<&Avatar.Collection>(from: Avatar.CollectionStoragePath) ?? panic("could not borrow collection")
self.avatar = self.collection.borrowAuth(id: avatarId) as? auth &Avatar.Avatar ?? panic("problem")
self.accessory <- self.collection.withdraw(withdrawID: accessoryId) as! @Avatar.Accessory
}
execute {
if let oldAccessory <- self.avatar.equip(accessory: <- self.accessory) {
self.collection.deposit(token: <- oldAccessory)
}
}
}
I get the error field accessory of type Transaction is not invalidated (moved or destroyed). not invalidated - flow cadence
I have a feeling the type checker may not understand that the resource should be moved/destroyed by the end of this but maybe it's confused since it hands over the custody to Avatar.
Am I missing something?
Have you tried not using if let here? I am not sure that the compiler is smart enough to understand that the return from equip is nil even though you use if let