Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .github/workflows/words-to-ignore.txt
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,4 @@ Unprocessable
satisfiable
CORS
cURL
lexicographically
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This repository contains the specs for the `w3up` protocol and associated subsystems.

The implementations of these specs can be found in <https://github.com/web3-storage/w3up>
The implementations of these specs can be found in [storacha/upload-service/packages/capabilities](https://github.com/storacha/upload-service/tree/main/packages/capabilities)

## Overview

Expand Down
189 changes: 169 additions & 20 deletions w3-account.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,39 +185,188 @@ The attestation signature is denoted by a [Nonstandard `VarSig` signature] with
{ "/": { "bytes": "gKADAA" } }
```

## Implementations
## Capabilities

### [`w3 login <email>` in w3cli](https://github.com/web3-storage/w3cli#w3-login-email)
### `account/usage/*`

- invokes [Account.login](https://github.com/web3-storage/w3cli/blob/fc97ee1b76551bced861f08a4d1e7a31440a6a14/bin.js#L56) which calls `login` on a `@web3-storage/w3up-client`
Capability can only be delegated (not invoked) to allow an audience to derive any `account/usage/*` prefixed capability for the account identified in the `with` field.

### [@web3-storage/w3up-client][]
```ts
type AccountUsage = {
can: 'account/usage/*'
with: AccountDID
}
```

- login method [returns](https://github.com/web3-storage/w3up/blob/main/packages/w3up-client/src/account.js#L82) an `Account` instance
- [used](https://github.com/web3-storage/w3cli/blob/fc97ee1b76551bced861f08a4d1e7a31440a6a14/account.js#L1) by w3cli
### `account/usage/get`

[@web3-storage/w3up-client]: https://github.com/web3-storage/w3up/tree/main/packages/w3up-client
Capability can be invoked by an agent to retrieve usage data for all, or a specified set, of spaces within an account for a given period.

### [@ucanto/*](https://github.com/web3-storage/ucanto/tree/main)
#### Capability schema

ucanto contains all kinds of tools for building application layer services aligned with the w3-account model.
```ipldsch
type AccountUsageGet struct {
with AccountDID
nb optional AccountUsageGetNB
}

Examples
type AccountUsageGetNB struct {
# Optional list of spaces to filter. If omitted, provider SHOULD aggregate all spaces the account is authorized to include.
spaces optional [SpaceDID]

- [@web3-storage/upload-api](https://github.com/web3-storage/w3up/tree/main/packages/upload-api) - application logic for up.web3.storage
- `createServer` [uses `@ucanto/server`](https://github.com/web3-storage/w3up/blob/main/packages/upload-api/src/lib.js#L29)
- example [invocation handler for `access/delegate`](https://github.com/web3-storage/w3up/blob/main/packages/upload-api/src/access/delegate.js#L17) using `@ucanto/types`
- [@web3-storage/access-client](https://github.com/web3-storage/w3up/tree/main/packages/access-client) - uses `@ucanto/client` to invoke `@web3-storage/upload/api`
# Optional time period (Unix timestamps in seconds).
# If omitted, provider MUST return a current snapshot.
# Semantics: from is inclusive; to is exclusive.
period optional Period
}

### [@web3-storage/did-mailto](https://github.com/web3-storage/w3up/tree/e34eed1fa3d6ef24ce2c01982764f2012dbf30d8/packages/did-mailto)
type Period struct {
from Int # inclusive
to Int # exclusive
}
```

- `fromEmail` and `toEmail` functions to encoded/decode `did:mailto` from email addresses.
- has `import("@web3-storage/did-mailto/types").DidMailto` typescript type
#### Invocation examples

> Example: getting the current total usage

```json
{
"iss": "did:key:z6MktfnQz8Kcz5nsC65oyXWFXhbbAZQavjg6LYuHOOOagent",
"aud": "did:web:storacha.network",
"att": [
{
"with": "did:mailto:web.mail:alice",
"can": "account/usage/get"
}
],
"prf": [
{ "/": "bafyAccountDelegationCid" },
{ "/": "bafySessionAttestationCid" }
],
"sig": "..."
}
```

Examples
> Example: filtering a single space and period

```json
{
"iss": "did:key:z6MktfnQz8Kcz5nsC65oyXWFXhbbAZQavjg6LYuHOOOagent",
"aud": "did:web:storacha.network",
"att": [
{
"with": "did:mailto:web.mail:alice",
"can": "account/usage/get",
"nb": {
"spaces": [
"did:key:z6MkuxVKbEvYzXw89c9ESd3xoZ988MFrCgqT5JF5wtBvuYWe"
],
"period": {
"from": 1754006400,
"to": 1758111728
}
}
}
],
"prf": [
{ "/": "bafyAccountDelegationCid" },
{ "/": "bafySessionAttestationCid" }
],
"sig": "..."
}
```

- [@web3-storage/w3cli for account management cli](https://github.com/web3-storage/w3cli/blob/fc97ee1b76551bced861f08a4d1e7a31440a6a14/account.js#L3)
- [@w3up-client](https://github.com/web3-storage/w3up/blob/e34eed1fa3d6ef24ce2c01982764f2012dbf30d8/packages/w3up-client/src/types.ts#L18)
#### Authorization requirements

The service MUST verify that the Account DID is authorized to access usage data for all requested spaces. If any requested space is not authorized, the entire invocation SHOULD fail with an error message indicating which spaces lack authorization.

#### Receipt

```ipldsch
type AccountUsageGetReceipt = {
ran: Link<AccountUsageGet>
out: Result<AccountUsageGetSuccess, AccountUsageGetFailure>
}

type AccountUsageGetFailure {
message: string
}

type AccountUsageGetSuccess {
total Int
spaces Record<SpaceDID, SpaceUsage> # keys MUST be sorted
}

type SpaceUsage {
total Int
providers Record<ProviderDID, UsageData> # keys MUST be sorted
}

# UsageData is shared with `usage/report`
type UsageData {
provider ProviderDID
space SpaceDID
period PeriodISO
size SizeDelta
events [UsageEvent]
}

type SizeDelta {
initial Int
final Int
}

type UsageEvent {
cause Link
delta Int
receiptAt ISO8601Date
}

type PeriodISO {
from ISO8601Date
to ISO8601Date
}

type ISO8601Date = string
type ProviderDID = string
```

In all responses, the keys of the `spaces` field in `AccountUsageGetSuccess` and the `providers` field in `SpaceUsage` MUST be sorted lexicographically by their respective key (`SpaceDID`, `ProviderDID`). This ensures that the same query produces the same output each time.

##### Receipt example (success)

```json
{
"total": 5356848797,
"spaces": {
"did:key:z6MkuxVKbEvYzXw89c9ESd3xoZ988MFrCgqT5JF5wtBvuYWe": {
"total": 5356848797,
"providers": {
"did:web:web3.storage": {
"provider": "did:web:web3.storage",
"space": "did:key:z6MkuxVKbEvYzXw89c9ESd3xoZ988MFrCgqT5JF5wtBvuYWe",
"period": {
"from": "2025-07-01T00:00:00.000Z",
"to": "2025-08-12T15:55:11.000Z"
},
"size": {
"initial": 1035217049,
"final": 5356848797
},
"events": [
{
"cause": { "/": "bafyreiafouslzry3vunc4okazrqpwpuanrq4d3ehb2oatn4vmrhnmj6rzy" },
"delta": 54394,
"receiptAt": "2025-07-01T14:34:50.947Z"
}
]
}
}
}
}
}
```

[Protocol Labs]:https://protocol.ai/
[Irakli Gozalishvili]:https://github.com/Gozala
Expand Down