diff --git a/packages/access-client/readme.md b/packages/access-client/readme.md index 6a1b24e94..9cee82755 100644 --- a/packages/access-client/readme.md +++ b/packages/access-client/readme.md @@ -1,6 +1,18 @@
The access client for https://web3.storage
+## About + +The `@web3-storage/access` package provides an API for creating and managing "Agents," which are software entities that control private signing keys and can invoke capabilities on behalf of a user (or another Agent). + +Agents are used to invoke capabilities provided by the w3up service layer, using the [ucanto](https://github.com/web3-storage/ucanto) RPC framework. Agents are created locally on an end-user's device, and users are encouraged to create new Agents for each device (or browser) that they want to use, rather than sharing Agent keys between devices. + +An Agent can create "Spaces," which are namespaces for content stored on the w3up platform. Each Space has its own keypair, the public half of which is used to form a `did:key:` URI that uniquely identifies the Space. The Space's private key is used to delegate capabilities to a primary Agent, which then issues ucanto requests related to the Space. + +Although Agents (and Spaces) are created locally by generating keypairs, the w3up services will only act upon Spaces that have been registered with the w3up access service. By default, a newly-created Agent will be configured to use the production access service for remote operations, including registration. + +Please note that the `@web3-storage/access` package is a fairly "low level" component of the w3up JavaScript stack, and most users will be better served by [`@web3-storage/w3up-client`](https://github.com/web3-storage/w3up-client), which combines this package with a client for the upload and storage service and presents a simpler API. + ## Install Install the package: @@ -13,21 +25,144 @@ npm install @web3-storage/access [API Reference](https://web3-storage.github.io/w3protocol/modules/_web3_storage_access.html) +### Agent creation + +To create an Agent, you must first create a `Store`, which the Agent will use to store and manage persistent state, including private keys. + +If you're running in a web browser, use [`StoreIndexedDB`](https://web3-storage.github.io/w3protocol/classes/_web3_storage_access.StoreIndexedDB.html), which uses IndexedDB to store non-extractable [`CryptoKey`](https://www.w3.org/TR/WebCryptoAPI/#dfn-CryptoKey) objects. This prevents the private key material from ever being exposed to the JavaScript environment. + +Agents in a browser use RSA keys, which can be generated using the async `generate` function from `@ucanto/principal/rsa`. + ```js -import { Agent, connection } from '@web3-storage/access/agent' -import * as Encoding from '@web3-storage/access/encoding' -import { StoreConf } from '@web3-storage/access/stores/store-conf' -// for browsers +import { Agent } from '@web3-storage/access/agent' import { StoreIndexedDB } from '@web3-storage/access/stores/store-indexeddb' +import { generate } from '@ucanto/principal/rsa' + +async function createAgent() { + const store = await StoreIndexedDB.open('my-db-name') + + // if agent data already exists in the store, use it to create an Agent. + const data = await store.load() + if (data) { + return Agent.from(data, { store }) + } + + // otherwise, generate a new RSA signing key to act as the Agent's principal + // and create a new Agent, passing in the store so the Agent can persist its state + const principal = await generate() + const agentData = { + meta: { name: 'my-browser-agent' }, + principal + } + return Agent.create(agentData, { store }) +} +``` + +On node.js, use [`StoreConf`](https://web3-storage.github.io/w3protocol/classes/_web3_storage_access.StoreConf.html), which uses the [`conf` package](https://www.npmjs.com/package/conf) to store keys and metadata in the user's platform-specific default configuration location (usually in their home directory). + +Agents on node should use Ed25519 keys, + +```js +import { Agent } from '@web3-storage/access/agent' +import { StoreConf } from '@web3-storage/access/stores/store-conf' +import { generate } from '@ucanto/principal/ed25519' + +async function createAgent() { + const store = new StoreConf({ profile: 'my-w3up-app' }) + if (!(await store.exists())) { + await store.init({}) + } + + // if agent data already exists in the store, use it to create an Agent. + const data = await store.load() + if (data) { + return Agent.from(data, { store }) + } + + // otherwise, generate a new Ed25519 signing key to act as the Agent's principal + // and create a new Agent, passing in the store so the Agent can persist its state + const principal = await generate() + const agentData = { + meta: { name: 'my-nodejs-agent' }, + principal + } + return Agent.create(agentData, { store }) +} + +``` + +See the [`AgentCreateOptions` reference](https://web3-storage.github.io/w3protocol/interfaces/_web3_storage_access._internal_.AgentCreateOptions.html) if you want to configure the Agent to use a non-production service connection. + +### Space creation + +A newly-created Agent does not have access to any Spaces, and is thus unable to store data using the w3up platform. + +To create a new Space, use [`agent.createSpace`](https://web3-storage.github.io/w3protocol/classes/_web3_storage_access.Agent.html#createSpace), optionally passing in a human-readable name. + +This will create a new signing keypair for the Space and use it to issue a non-expiring delegation for all Space-related capabilities to the Agent, which will persist the delegation in its Store for future use. + +The `createSpace` method returns an object describing the space: -const store = new StoreConf({ profile: 'app' }) -if (!(await store.exists())) { - await store.init({}) +```ts +interface CreateSpaceResult { + /** The Space's Decentralized Identity Document (DID) */ + did: string, + + /** + * Metadata for the Space, including optional friendly `name` and an `isRegistered` flag. + * Persisted locally in the Agent's Store. + */ + meta: Record