Skip to content

Commit

Permalink
Merge pull request #156 from onflow/bastian/27-publish-and-claim-capa…
Browse files Browse the repository at this point in the history
…bility

Add examples for publishing and claiming capability
  • Loading branch information
turbolent authored Sep 25, 2024
2 parents 48d921c + af5a4d0 commit d6354c8
Showing 1 changed file with 70 additions and 16 deletions.
86 changes: 70 additions & 16 deletions docs/design-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -424,29 +424,83 @@ from one account and delivering it to the other.

### Solution

The solution to the bootstrapping problem in Cadence is provided by the [Inbox API](./language/accounts/inbox.mdx).

Account A (which we will call the provider) creates the capability they wish to send to B (which we will call the recipient),
and stores this capability on their account in a place where the recipient can access it using the `Inbox.publish` function on their account.
They choose a name for the capability that the recipient can later use to identify it, and specify the recipient's address when calling `publish`.
This call to `publish` will emit an `InboxValuePublished` event that the recipient can listen for off-chain to know that the Capability is ready for them to claim.

The recipient then later can use the `Inbox.claim` function to securely grab the capability from the provider's account.
They must provide the name and type with which the capability was published, as well as the address of the provider's account
The solution to the bootstrapping problem in Cadence is provided by the
[Inbox API](./language/accounts/inbox.mdx).

Account A (which we will call the provider) creates the capability they wish to send to account B
(which we will call the recipient),
and stores this capability on their account in a place where the recipient can access it
using the `Inbox.publish` function on their account.
They choose a name for the capability that the recipient can later use to identify it,
and specify the recipient's address when calling `publish`.
This call to `publish` will emit an `InboxValuePublished` event
that the recipient can listen for off-chain to know that the Capability is ready for them to claim.

The recipient then later can use the `Inbox.claim` function to securely claim the capability
from the provider's account.
They must provide the name and type with which the capability was published,
as well as the address of the provider's account
(all of this information is available in the `InboxValuePublished` event emitted on `publish`).
This will remove the capability from the provider's account and emit an `InboxValueClaimed` event that the provider can listen for off-chain.
This will remove the capability from the provider's account and emit an `InboxValueClaimed` event
that the provider can listen for off-chain.

One important caveat to this is that the published capability is stored on the provider's account until the recipient claims it,
so the provider can also use the `Inbox.unpublish` function to remove the capability from their account if they no longer wish to pay for storage for it.
One important caveat to this is that the published capability is stored on the provider's account
until the recipient claims it,
so the provider can also use the `Inbox.unpublish` function to remove the capability from their account
if they no longer wish to pay for storage for it.
This also requires the name and type which the capability was published,
and emits an `InboxValueUnpublished` event that the recipient can listen for off-chain.

It is also important to note that the recipient becomes the owner of the capability object once they have claimed it,
and can thus store it or copy it anywhere they have access to.
It is also important to note that the recipient becomes the owner of the capability object
once they have claimed it, and can thus store it or copy it anywhere they have access to.
This means providers should only publish capabilities to recipients they trust to use them properly,
or limit the type with which the capability is authorized in order to only give recipients access to the functionality
or limit the type with which the capability is authorized
in order to only give recipients access to the functionality
that the provider is willing to allow them to copy.

```cadence
import "BasicNFT"
transaction(receiver: Address, name: String) {
prepare(signer: auth(IssueStorageCapabilityController, PublishInboxCapability) &Account) {
// Issue a capability controller for the storage path
let capability = signer.capabilities.storage.issue<&BasicNFT.Minter>(BasicNFT.minterPath)
// Set the name as tag so it is easy for us to remember its purpose
let controller = signer.capabilities.storage.getController(byCapabilityID: capability.id)
?? panic("Cannot get the storage capability controller with ID "
.concat(capabilityID.toString())
.concat(" from the signer's account! Make sure the ID belongs to a capability that the owner controls and that it is a storage capability.")
controller.setTag(name)
// Publish the capability, so it can be later claimed by the receiver
signer.inbox.publish(capability, name: name, recipient: receiver)
}
}
```

```cadence
import "BasicNFT"
transaction(provider: Address, name: String) {
prepare(signer: auth(ClaimInboxCapability, SaveValue) &Account) {
// Claim the capability from our inbox
let capability = signer.inbox.claim<&BasicNFT.Minter>(name, provider: provider)
?? panic("Cannot claim the storage capability controller with name "
.concat(name).concat(" from the provider account (").concat(provider.toString())
.concat("! Make sure the provider address is correct and that they have published "
.concat(" a capability with the desired name.")
// Save the capability to our storage so we can later retrieve and use it
signer.storage.save(capability, to: BasicNFT.minterPath)
}
}
```

## Check for existing capability before publishing new one

### Problem
Expand Down Expand Up @@ -512,4 +566,4 @@ transaction(capabilityID: UInt64) {
controller.delete()
}
}
```
```

0 comments on commit d6354c8

Please sign in to comment.