Skip to content

Commit

Permalink
feat!: integrate new ucanto and upload-client (#119)
Browse files Browse the repository at this point in the history
This PR makes breaking changes to core and framework components to
integrate the access agent (+ucanto 0.9) and the new upload client.

resolves #127

BREAKING CHANGE: core and framework components have changed
considerably. Please read the updated doucmentation.
  • Loading branch information
Alan Shaw authored Dec 2, 2022
1 parent fdb917f commit c824e44
Show file tree
Hide file tree
Showing 57 changed files with 16,035 additions and 9,445 deletions.
132 changes: 4 additions & 128 deletions docs/keyring-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,138 +14,14 @@ import * as KeyringCore from '@w3ui/keyring-core'

## Exports

* [`loadDefaultIdentity`](#loaddefaultidentity)
* [`loadIdentity`](#loadidentity)
* [`createIdentity`](#createidentity)
* [`sendVerificationEmail`](#sendverificationemail)
* [`waitIdentityVerification`](#waitidentityverification)
* [`registerIdentity`](#registeridentity)
* [`removeIdentity`](#removeidentity)
* [`storeIdentity`](#storeidentity)
* [`createAgent`](#createagent)

---

### `loadDefaultIdentity`
### `createAgent`

```ts
loadDefaultIdentity (): Promise<Identity | undefined>
createAgent (options: { url?: URL } = {}): Promise<Agent<RSASigner>>
```

Load the default identity on this device, returning `undefined` if none exist.

Example:

```js
const identity = await loadDefaultIdentity()
if (identity) {
console.log(`DID: ${identity.signingPrincipal.did()}`)
} else {
console.log('No identity registered')
}
```

### `loadIdentity`

```ts
loadIdentity ({ email: string }): Promise<Identity | undefined>
```

Load an identity matching the passed argument from secure storage, returning `undefined` if not found.

Example:

```js
const identity = await loadIdentity('test@example.com')
if (identity) {
console.log(`DID: ${identity.signingPrincipal.did()}`)
} else {
console.log('Not found')
}
```

### `createIdentity`

```ts
createIdentity ({ email: string }): Promise<UnverifiedIdentity>
```

Create a new identity.

Example:

```js
const unverifiedIdentity = await createIdentity('test@example.com')
console.log(`DID: ${unverifiedIdentity.signingPrincipal.did()}`)
```

### `sendVerificationEmail`

```ts
function sendVerificationEmail (identity: UnverifiedIdentity): Promise<void>
```

Example:

```js
const unverifiedIdentity = await createIdentity('test@example.com')
console.log(`DID: ${unverifiedIdentity.signingPrincipal.did()}`)
await sendVerificationEmail(unverifiedIdentity)
```

### `waitIdentityVerification`

```ts
function waitIdentityVerification (identity: UnverifiedIdentity, options?: { signal: AbortSignal }): Promise<{ identity: VerifiedIdentity, proof: Delegation<[IdentityRegister]> }>
```

Wait for identity verification to complete (user must click link in email).

Example:

```js
const unverifiedIdentity = await createIdentity('test@example.com')
console.log(`DID: ${unverifiedIdentity.signingPrincipal.did()}`)
await sendVerificationEmail(unverifiedIdentity)
const controller = new AbortController()
const { identity, proof } = await waitIdentityVerification(unverifiedIdentity, {
signal: controller.signal
})
```

### `registerIdentity`

```ts
registerIdentity (identity: VerifiedIdentity, proof: Delegation<[IdentityRegister]>): Promise<void>
```

Register a verified identity with the service, passing the proof of verification (a delegation allowing registration).

Example:

```js
const unverifiedIdentity = await createIdentity('test@example.com')
console.log(`DID: ${unverifiedIdentity.signingPrincipal.did()}`)
await sendVerificationEmail(unverifiedIdentity)
const controller = new AbortController()
const { identity, proof } = await waitIdentityVerification(unverifiedIdentity, {
signal: controller.signal
})
await registerIdentity(identity, proof)
```

### `removeIdentity`

```ts
removeIdentity (identity: Identity): Promise<void>
```

Remove the passed identity from secure storage.


# `storeIdentity`

```ts
storeIdentity (identity: Identity): Promise<void>
```

Store identity locally in secure storage and set the default.
Create the user agent and load account information from secure storage.
49 changes: 33 additions & 16 deletions docs/react-keyring.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,35 +46,52 @@ const auth = useAuth()
Hook to allow use of the [`AuthProvider`](#authprovider) value. The value returned is an `AuthContextValue`:

```ts
interface AuthContextValue {
interface AuthContextState {
/**
* The current identity
* The current user account.
*/
identity?: Identity
readonly account?: DID
/**
* Load the default identity from secure storage.
* The current user agent (this device).
*/
loadDefaultIdentity: () => Promise<void>
readonly agent?: DID
/**
* Unload the current identity from memory.
* Signing authority from the agent that is able to issue UCAN invocations.
*/
unloadIdentity: () => Promise<void>
readonly issuer?: Signer
/**
* Unload the current identity from memory and remove from secure storage.
* Authentication status of the current identity.
*/
unloadAndRemoveIdentity: () => Promise<void>
readonly authStatus: AuthStatus
}

interface AuthContextValue extends AuthContextState {
/**
* Register a new identity, verify the email address and store in secure
* storage. Use cancelRegisterAndStoreIdentity to abort.
* Load the user agent and all stored data from secure storage.
*/
registerAndStoreIdentity: (email: string) => Promise<void>
loadAgent: () => Promise<void>
/**
* Abort an ongoing identity registration.
* Unload the user agent and all stored data from secure storage. Note: this
* does not remove data, use `resetAgent` if that is desired.
*/
cancelRegisterAndStoreIdentity: () => void
unloadAgent: () => Promise<void>
/**
* Authentication status of the current identity.
* Unload the current account and agent from memory and remove from secure
* storage. Note: this removes all data and is unrecoverable.
*/
resetAgent: () => Promise<void>
/**
* Use a specific account.
*/
selectAccount: (did: DID) => Promise<void>
/**
* Register a new account, verify the email address and store in secure
* storage. Use cancelRegisterAccount to abort.
*/
registerAccount: (email: string) => Promise<void>
/**
* Abort an ongoing account registration.
*/
authStatus: AuthStatus
cancelRegisterAccount: () => void
}
```
11 changes: 8 additions & 3 deletions docs/react-uploader.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type UploaderContextValue = [
]

interface UploaderContextState {
uploadedCarChunks: CarChunkMeta[]
storedDAGShards: CARMetadata[]
}

interface UploaderContextActions {
Expand All @@ -65,9 +65,14 @@ interface UploaderContextActions {
*/
uploadDirectory: (files: File[]) => Promise<CID>
/**
* Upload CAR bytes to the service.
* Store a DAG (encoded as a CAR file) to the service.
*/
uploadCarChunks: (chunks: AsyncIterable<CarData>) => Promise<void>
storeDAG: (data: Blob) => Promise<CID>
/**
* Register an "upload" with the service. Note: only required when using
* `storeDAG`.
*/
registerUpload: (root: CID, shards: CID[]) => Promise<void>
}
```

41 changes: 27 additions & 14 deletions docs/solid-keyring.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,17 @@ Hook to allow use of the [`AuthProvider`](#authprovider) value. The value return
```ts
interface AuthContextState {
/**
* The current identity
* The current user account.
*/
readonly identity?: Identity
readonly account?: DID
/**
* The current user agent (this device).
*/
readonly agent?: DID
/**
* Signing authority from the agent that is able to issue UCAN invocations.
*/
readonly issuer?: Signer
/**
* Authentication status of the current identity.
*/
Expand All @@ -61,27 +69,32 @@ type AuthContextValue = [
state: AuthContextState,
actions: {
/**
* Load the default identity from secure storage. If the identity is not
* verified, the registration flow will be automatically resumed.
* Load the user agent and all stored data from secure storage.
*/
loadAgent: () => Promise<void>
/**
* Unload the user agent and all stored data from secure storage. Note: this
* does not remove data, use `resetAgent` if that is desired.
*/
loadDefaultIdentity: () => Promise<void>
unloadAgent: () => Promise<void>
/**
* Unload the current identity from memory.
* Unload the current account and agent from memory and remove from secure
* storage. Note: this removes all data and is unrecoverable.
*/
unloadIdentity: () => Promise<void>
resetAgent: () => Promise<void>
/**
* Unload the current identity from memory and remove from secure storage.
* Use a specific account.
*/
unloadAndRemoveIdentity: () => Promise<void>
selectAccount: (did: DID) => Promise<void>
/**
* Register a new identity, verify the email address and store in secure
* storage. Use cancelRegisterAndStoreIdentity to abort.
* Register a new account, verify the email address and store in secure
* storage. Use cancelRegisterAccount to abort.
*/
registerAndStoreIdentity: (email: string) => Promise<void>
registerAccount: (email: string) => Promise<void>
/**
* Abort an ongoing identity registration.
* Abort an ongoing account registration.
*/
cancelRegisterAndStoreIdentity: () => void
cancelRegisterAccount: () => void
}
]
```
17 changes: 11 additions & 6 deletions docs/solid-uploader.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ const [progress, uploader] = useUploader()
Hook to allow use of the [`UploaderProvider`](#uploaderprovider) value. The value returned is an `UploaderContextValue`:

```ts
export type UploaderContextValue = [
type UploaderContextValue = [
state: UploaderContextState,
actions: UploaderContextActions
]

export interface UploaderContextState {
uploadedCarChunks: CarChunkMeta[]
interface UploaderContextState {
storedDAGShards: CARMetadata[]
}

export interface UploaderContextActions {
interface UploaderContextActions {
/**
* Upload a single file to the service.
*/
Expand All @@ -65,8 +65,13 @@ export interface UploaderContextActions {
*/
uploadDirectory: (files: File[]) => Promise<CID>
/**
* Upload CAR bytes to the service.
* Store a DAG (encoded as a CAR file) to the service.
*/
uploadCarChunks: (chunks: AsyncIterable<CarData>) => Promise<void>
storeDAG: (data: Blob) => Promise<CID>
/**
* Register an "upload" with the service. Note: only required when using
* `storeDAG`.
*/
registerUpload: (root: CID, shards: CID[]) => Promise<void>
}
```
4 changes: 2 additions & 2 deletions docs/solid-uploads-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import * as SolidUploadsList from '@w3ui/solid-uploads-list'
### `createUploadsListResource`

```ts
function createUploadsListResource (source: ResourceSource<Identity>, options?: ResourceOptions<ListPage, Identity>): ResourceReturn<ListPage>
function createUploadsListResource (source: ResourceSource<UploadsListSource>, options?: ResourceOptions<ListPage, UploadsListSource>): ResourceReturn<ListPage>
```

Create a solid resource configured to fetch data from the service. Please see the docs for [`createResource`](https://www.solidjs.com/docs/latest/api#createresource) for parameter and return type descriptions.
Expand All @@ -42,7 +42,7 @@ function App () {
function List () {
const [auth] = useAuth()
const [data] = createUploadsListResource(() => auth.identity)
const [data] = createUploadsListResource(() => auth)
return (
<table className='mb3'>
{data() && data().results.map(({ dataCid }) => (
Expand Down
Loading

0 comments on commit c824e44

Please sign in to comment.