Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Publish and Claim: Inbox API for Capability Bootstrapping #1983

Merged
merged 43 commits into from
Oct 6, 2022
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
4527cfe
add types for publish, unpublish, and claim to AuthAccount
dsainati1 Sep 13, 2022
d62f381
move functions to nested Inbox struct type
dsainati1 Sep 14, 2022
28679da
publish returns a Bool
dsainati1 Sep 14, 2022
6b3ddab
add permit function
dsainati1 Sep 14, 2022
ccc0c98
add unpermit function
dsainati1 Sep 14, 2022
7b6a49b
add allowlist field
dsainati1 Sep 14, 2022
9dcce96
add allowlist to public account inbox
dsainati1 Sep 15, 2022
948aeb4
add constructors for inbox values
dsainati1 Sep 15, 2022
0c47d0b
add constructors for inbox values
dsainati1 Sep 15, 2022
f247b60
implement computed field for allowlist
dsainati1 Sep 15, 2022
5c03729
implement permit function
dsainati1 Sep 15, 2022
d744581
implement unpermit function
dsainati1 Sep 16, 2022
4646884
implementation for publish
dsainati1 Sep 16, 2022
e1ee4f2
implementation of unpublish
dsainati1 Sep 16, 2022
1106d4b
type assertion when unpublishing
dsainati1 Sep 16, 2022
263f3ff
update type signatures to reflect requirement that they be capabilities
dsainati1 Sep 16, 2022
2d1c888
implement claim
dsainati1 Sep 19, 2022
5b6f120
add tests for publish and unpublish
dsainati1 Sep 19, 2022
20031b1
tests for claim
dsainati1 Sep 19, 2022
93e469a
fix tests
dsainati1 Sep 19, 2022
cb0de89
Merge branch 'master' of github.com:onflow/cadence into sainati/1951-…
dsainati1 Sep 26, 2022
0c7cd5c
remove allowlist, permit and unpermit
dsainati1 Sep 26, 2022
cb73d1b
add events on publish and claim
dsainati1 Sep 26, 2022
c90d0ca
Update runtime/account_test.go
dsainati1 Sep 29, 2022
0073d91
add documentation for inbox API
dsainati1 Sep 30, 2022
b7e5e2f
Merge branch 'master' of github.com:onflow/cadence into sainati/1951-…
dsainati1 Sep 30, 2022
ccaf768
Merge branch 'sainati/1951-publish-claim' of github.com:onflow/cadenc…
dsainati1 Sep 30, 2022
43831ea
Apply suggestions from code review
dsainati1 Oct 3, 2022
922cda6
Apply suggestions from code review
dsainati1 Oct 3, 2022
f024efe
Merge branch 'master' of github.com:onflow/cadence into sainati/1951-…
dsainati1 Oct 3, 2022
a6ce50d
use a new PublishedValue type to store published values instead of ha…
dsainati1 Oct 3, 2022
8ab3220
fix lint
dsainati1 Oct 3, 2022
cb9adb7
Merge branch 'master' of github.com:onflow/cadence into sainati/1951-…
dsainati1 Oct 5, 2022
7445bd6
respond to review
dsainati1 Oct 5, 2022
e3da05b
fix statictype enum changes
dsainati1 Oct 5, 2022
d24a53f
add comment to primitive static type test
dsainati1 Oct 5, 2022
a786026
Merge branch 'master' of github.com:onflow/cadence into sainati/1951-…
dsainati1 Oct 5, 2022
d8b7d46
merge
dsainati1 Oct 5, 2022
fdf8b75
Update docs/language/accounts.mdx
dsainati1 Oct 6, 2022
64f8581
Merge branch 'master' of github.com:onflow/cadence into sainati/1951-…
dsainati1 Oct 6, 2022
3e00678
respond to review
dsainati1 Oct 6, 2022
e8eea18
split InboxValueRemoved into two events for unpublish and claim
dsainati1 Oct 6, 2022
23a228d
Merge branch 'sainati/1951-publish-claim' of github.com:onflow/cadenc…
dsainati1 Oct 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions docs/language/accounts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ to the `prepare` phase of the transaction.

let keys: AuthAccount.Keys

// Provides a API for bootstrapping (sending and receiving) capabilities

let inbox: AuthAccount.Inbox

// All the paths associated with this account
let publicPaths: [PublicPath]
let privatePaths: [PrivatePath]
Expand Down Expand Up @@ -165,6 +169,21 @@ to the `prepare` phase of the transaction.
// Returns the revoked key if it exists, or nil otherwise.
fun revoke(keyIndex: Int): AccountKey?
}

struct Inbox {
// Publishes a new Capability under the given name, to be claimed by the specified recipient
fun publish(_ value: Capability, name: String, recipient: Address)

// Unpublishes a Capability previously published by this account.
// Returns `nil` if no Capability is published under the given name.
// Errors if the Capability under that name does not match the provided type.
fun unpublish<T: &Any>(_ name: String): Capability<T>?

// Claims a Capability previously published by the specified provider.
// Returns `nil` if no Capability is published under the given name, or if this account is not its intended recipient.
// Errors if the Capability under that name does not match the provided type.
fun claim<T: &Any>(_ name: String, provider: Address): Capability<T>?
}
}

struct DeployedContract {
Expand Down Expand Up @@ -321,6 +340,68 @@ transaction() {
However, this method is deprecated and is available only for the backward compatibility.
</Callout>

## Account Inbox

Accounts also possess an Inbox that can be used to make [Capabilities](capability-based-access-control) available to specific accounts.
The functions in this Inbox provide a convenient means to "bootstrap" Capabilities,
dsainati1 marked this conversation as resolved.
Show resolved Hide resolved
setting up an initial connection between two accounts that will later allow them to transfer data or permissions through a Capability.

### Publishing a Capability

An account (the Provider) that would like to provide a Capability to another account (the Recipient) can do so using the `publish` function:

```cadence
fun publish(_ value: Capability, name: String, recipient: Address)
```

This publishes the specified Capability using the provided string as an identifier, to be later claimed by the Recipient.
Note, however, that until the Recipient does claim this Capability, it is stored on the Provider's account,
dsainati1 marked this conversation as resolved.
Show resolved Hide resolved
and contributes towards their Account Storage total.

Calling this function emits an event, `InboxValuePublished`,
that includes the address of both the Provider and the Recipient, as well as the name and the type of the published Capability.
Refer to the [`Core Events` section](core-events#inbox-value-published) for more details on this event.

### Claiming a Capability

The intended Recipient of a Capability can claim that Capability from the Provider using the `claim` function:

```cadence
fun claim<T: &Any>(_ name: String, provider: Address): Capability<T>?
```

This looks up the specified name in the Provider's inbox, returning it to the Recipient if it is present,
conforms to the provided type argument, and is intended for the calling Recipient.
If the Provider has no Capability stored under the provided name,
or if the calling Recipient is not the intended recipient of the Capability, the function returns `nil`.
If the borrow type of the Capability is not a subtype of the provided type argument, the function will error at runtime.

Upon successful completion of the `claim` function, the claimed Capability is removed from the Provider's inbox.
Note that this means a given Capability can only be claimed once.

Calling this function emits an event, `InboxValueRemoved`,
that includes the address of both the Provider and the Recipient, as well as the name of the claimed Capability.
Refer to the [`Core Events` section](core-events#inbox-value-removed) for more details on this event.

### Unpublishing a Capability

If the Provider of a Capability no longer wishes for it to be published for some reason (e.g. they no longer wish to pay for its storage costs),
they can unpublish it using the `unpublish` function:

```cadence
fun unpublish<T: &Any>(_ name: String): Capability<T>?
```

This looks up the specified name in the Provider's inbox, returning it to the Provider if it is present and conforms to the provided type argument.
If the Provider has no Capability stored under the provided name, the function returns `nil`.
If the borrow type of the Capability is not a subtype of the provided type argument, the function will error at runtime.

Upon successful completion of the `unpublish` function, the unpublished Capability is removed from the Provider's inbox.

Calling this function emits an event, `InboxValueRemoved`,
that includes the address of the Provider, and the name of the claimed Capability.
Refer to the [`Core Events` section](core-events#inbox-value-removed) for more details on this event.

## Account Storage

All accounts have storage.
Expand Down
48 changes: 48 additions & 0 deletions docs/language/core-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,51 @@ pub event AccountContractRemoved(
| `address` | `Address` | The address of the account the contract gets removed from |
| `codeHash` | `[UInt8]` | Hash of the contract source code |
| `contract` | `String` | The name of the the contract |

### Inbox Value Published

Event that is emitted when a Capability is published from an account.

Event name: `flow.InboxValuePublished`

```cadence
pub event InboxValuePublished(provider: Address, recipient: Address, name: String, type: Type)
```

| Field | Type | Description |
| ----------------- | --------- | -------------------------------------------- |
| `provider` | `Address` | The address of the publishing account |
| `recipient` | `Address` | The address of the intended recipient |
| `name` | `String` | The name associated with the published value |
| `type` | `Type` | The type of the published value |

To reduce the potential for spam,
we recommend that user agents that display events do not display this event as-is to their users,
and allow users to restrict whom they see events from.

### Inbox Value Removed

Event that is emitted when a Capability is removed from an account.

Event name: `flow.InboxValueRemoved`
dsainati1 marked this conversation as resolved.
Show resolved Hide resolved

```cadence
pub event InboxValueRemoved(provider: Address, remover: Address, name: String)
```

| Field | Type | Description |
| --------------- | --------- | -------------------------------------------- |
| `provider` | `Address` | The address of the publishing account |
| `remover` | `Address` | The address of the removing account |
| `name` | `String` | The name associated with the published value |

When this event is emitted by a call to `AuthAccount.Inbox.claim`,
the `provider` field of this event will be the original `provider` of the Capability,
and the `remover` field will be the claiming `recipient`.

When this event is emitted by a call to `AuthAccount.Inbox.unpublish`,
both the `provider` and the `remover` field of this event will be the original `provider` of the Capability.

To reduce the potential for spam,
we recommend that user agents that display events do not display this event as-is to their users,
and allow users to restrict whom they see events from.
1 change: 1 addition & 0 deletions runtime/common/memorykind.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const (
MemoryKindBoundFunctionValue
MemoryKindBigInt
MemoryKindSimpleCompositeValue
MemoryKindPublishedValue

// Atree Nodes
MemoryKindAtreeArrayDataSlab
Expand Down
Loading