cadence
cadence copied to clipboard
Allow borrowing a concrete reference type to a capability linked as an interface type
Issue to be solved
In Cadence 1.0, with the addition of entitlements, references that are restricted to an interface type can be cast to the concrete type if it is known. Because of this, it would be nice to have the ability to borrow a concrete reference type directly from a capability that is only linked as an interface type instead of having to borrow and then cast.
The inability to do this may cause issues with some standard transactions. For example, many apps use a transaction like this one to set up an account based of only a reference to a generic NFT, without having imported the contract first. The transaction only links the new collection as NonFungibleToken.Receiver.
Many other transactions try to borrow the public collection as its concrete type though, ExampleToken.Collection. Because this isn't possible, many of these transactions would fail. If they were able to borrow it directly, then this wouldn't be a problem. This allows us to standardize more simple transactions that don't need boilerplate for borrowing as a reference before casting. We can always just borrow directly.
Suggested Solution
For a capability created like this:
// create a public capability for the collection
let collectionCap = signer.capabilities.storage.issue<&{NonFungibleToken.Receiver}>(
collectionData.storagePath
)
signer.capabilities.publish(collectionCap, at: publicPath)
Assuming ExampleNFT.Collection implements NonFungibleToken.Receiver, the reference should be borrowable like this:
// borrow a public reference to the receivers collection
let receiverCap = recipient.capabilities.get<&ExampleNFT.Collection>(collectionData.publicPath)
?? panic("Could not get the recipient's Receiver Capability")
We need to discuss this
Yes, this is very important to have IMO, but isn't necessarily a blocker.
If i want to get a Cap{NonFungibleToken.Receiver} should that not work if it linked as a concrete impl or any interface that implements NonFungibleToken.Receiver?
@bjartek That is possible and works currently I believe