(I’m posting here before creating a FLIP to get some feedback on the idea!)
Summary
While progress has been made in standardizing NFT and fungible token vault resource interfaces, there is no standard capability or set of capabilities that is always exposed by each project’s setup script. This results in a transaction pattern where some temporary capability link must be created for each collection and then unlinked at the end of the transaction. I think it would be good to create some syntactical sugar to combine these two actions into a temporaryLink
function that would allow creation of a capability that is automatically unlinked at the end of the transaction or perhaps after being used once.
Details on the problem
You can see an example of this link/unlink pattern in this transaction, which attempts to purchase multiple NFTs from different listings in one transaction. Because some NFT collections automatically link NonFungibleToken.CollectionPublic
, some link NonFungibleToken.Receiver
, and some link both or instead only link some custom capability, the transaction creates a temporary NonFungibleToken.Receiver
link for each collection involved, paths are stored, and then all are unlinked at the end of the transaction.
This same transaction pattern could also be applied to any transaction involving multiple fungible tokens, as the lack of standardized public and private linked capabilities also applies to those contracts. For example, if you wanted to create a contract that executes one or more purchases / sales based on some condition (such as a stop-loss order), you would have to make sure the end users have all the proper provider / receiver capabilities, potentially involving multiple one-off setup transactions.
Finally, the temporaryLink
functionality would also help to keep unnecessary, often duplicated, capabilities from filling up a user’s account storage and increasing the size of the entire blockchain state. If every smart contract engineer was no longer responsible for cleaning up the capabilities they create after use, the only capabilities that would be persistently stored on-chain would be those intentionally stored for future use.
Questions about the solution
My main question, aside from whether this is a good idea in the first place, is whether the temporary capability should be automatically destroyed at the end of the transaction or after a single use. I realize that having temporary capabilities exist until they are used once would likely require more updates to Flow/Cadence than just automatically destroying temporary capabilities at the end of the transaction, but I’m wondering if there are security-related advantages or disadvantages to each approach.
Also, I’m curious about whether the community thinks there should be further restrictions on this functionality. Would these temporary capabilities have to be for PrivatePaths only? Would they even need a CapabilityPath if they aren’t meant to be stored for future use? Are there other key questions I’m missing?
Thank you for reading, and thanks in advance for any feedback!