Skip to content

Commit

Permalink
Update @web5/api to use latest web5 deps
Browse files Browse the repository at this point in the history
Signed-off-by: Frank Hinek <[email protected]>
  • Loading branch information
frankhinek committed Mar 12, 2024
1 parent 80968ad commit 4efc18b
Show file tree
Hide file tree
Showing 19 changed files with 828 additions and 976 deletions.
2 changes: 0 additions & 2 deletions packages/agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@
"ed25519-keygen": "0.4.11",
"level": "8.0.0",
"ms": "2.1.3",
"readable-stream": "4.4.2",
"readable-web-to-node-stream": "3.0.2",
"ulidx": "2.1.0"
},
Expand All @@ -90,7 +89,6 @@
"@types/mocha": "10.0.1",
"@types/ms": "0.7.31",
"@types/node": "20.11.19",
"@types/readable-stream": "4.0.6",
"@types/sinon": "17.0.2",
"@typescript-eslint/eslint-plugin": "6.4.0",
"@typescript-eslint/parser": "6.4.0",
Expand Down
7 changes: 5 additions & 2 deletions packages/api/.vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
"type": "node",
"request": "launch",
"name": "test:node",
"runtimeExecutable": "${workspaceFolder:root}/node_modules/.bin/mocha",
"runtimeExecutable": "${workspaceFolder:api}/node_modules/.bin/mocha",
"console": "internalConsole",
"preLaunchTask": "build tests",
"skipFiles": [
"<node_internals>/**"
]
],
"env": {
"TEST_DWN_URL": "http://localhost:3010"
}
}
]
}
58 changes: 53 additions & 5 deletions packages/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -453,23 +453,71 @@ console.log(protocols); // logs an array of protocol configurations installed on

#### **Request**

The query `request` must contain the following:
The `query` request object must contain the following:

- **`from`** - _`DID string`_ (_optional_): the decentralized identifier of the DWeb Node the query will fetch results from.
- **`message`** - _`object`_: The properties of the DWeb Node Message Descriptor that will be used to construct a valid record query:
- **`filter`** - _`object`_ (_optional_): properties against which results of the query will be filtered:
- **`protocol`** - _`URI string`_ (_optional_): the URI of the protocol bucket in which to query.

### **`web5.did.create(method, options)`**
### **`web5.did.create(request)`**

The `create` method under the `did` object enables generation of DIDs for a supported set of DID Methods ('ion'|'key'). The output is method-specific, and handles things like key generation and assembly of DID Documents that can be published to DID networks.
The `create` method under the `did` object enables generation of DIDs for a supported set of DID Methods ('dht'|'jwk').
The output is method-specific, and handles things like key generation and assembly of DID Documents that can be
published to DID networks.

> NOTE: You do not usually need to manually invoke this, as the `Web5.connect()` method already acquires a DID for the user (either by direct creation or connection to an identity agent app).
#### **Usage**

```javascript
const myDid = await Web5.did.create("ion");
const myDid = await web5.did.create("dht");
```

#### **Parameters**

The `create` request object must contain the following parameters:

- **`method`** - _`string`_: The DID method to use for generating the DID. Supported methods include 'dht' and 'jwk', among others that may be supported by the SDK.

- **`options`** - _`object`_ (_optional_): An object containing options specific to the DID method chosen. These options can influence how the DID is generated. For instance, they can dictate specifics about the cryptographic keys that are generated or associated with the new DID. Common options include:

- **`store`** - _`boolean`_ (_optional_): Determines whether the DID's cryptographic keys and metadata will be stored in
the user's DWeb Node.

#### **Notes**

- Typically developers will not manually invoke this method as the more common approach is to use the `Web5.connect()`
method to acquire a DID for the user (either by direct creation or connection to an identity agent app).

### **`web5.did.resolve(didUri, options)`**

The `resolve` method under the `did` object enables the resolution of a Decentralized Identifier (DID) to its
corresponding DID Document. This operation allows applications to fetch the public keys, service endpoints, and other
metadata associated with a DID.

#### **Usage**

```javascript
const { didDocument } = await web5.did.resolve('did:dht:qftx7z968xcpfy1a1diu75pg5meap3gdtg6ezagaw849wdh6oubo');
```

#### **Parameters**

- **`didUri`** - _`string`_: The DID URI to be resolved. This should be a fully qualified DID following the standard scheme `did:<method>:<identifier>`.

- **`options`** (_optional_): An object containing options for DID resolution. This can include method-specific parameters that influence the resolution process.

#### **Response**

The method returns a DID resolution result as a JavaScript object. The structure of this object adheres to the
[DID Core specifications](https://www.w3.org/TR/did-core/#did-resolution), containing the elements
`didResolutionMetadata`, `didDocument`, and `didDocumentMetadata`.

#### **Notes**

- The resolution process for some DID methods like DID DHT involve network requests to the relevant DID verifiable
data registry or a resolver endpoint, which may introduce latency based on the network conditions and the specific DID
method utilized.

## Project Resources

| Resource | Description |
Expand Down
22 changes: 7 additions & 15 deletions packages/api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@web5/api",
"version": "0.8.4",
"version": "0.9.0",
"description": "SDK for accessing the features and capabilities of Web5",
"type": "module",
"main": "./dist/cjs/index.js",
Expand Down Expand Up @@ -76,34 +76,26 @@
"node": ">=20.9.0"
},
"dependencies": {
"@tbd54566975/dwn-sdk-js": "0.2.16",
"@web5/agent": "0.2.6",
"@web5/common": "0.2.3",
"@web5/crypto": "0.2.2",
"@web5/dids": "0.2.4",
"@web5/user-agent": "0.2.6",
"level": "8.0.0",
"ms": "2.1.3",
"readable-stream": "4.4.2",
"readable-web-to-node-stream": "3.0.2"
"@tbd54566975/dwn-sdk-js": "0.2.18",
"@web5/agent": "0.3.0",
"@web5/common": "0.2.4",
"@web5/crypto": "0.4.0",
"@web5/dids": "0.4.1",
"@web5/user-agent": "0.3.0"
},
"devDependencies": {
"@playwright/test": "1.40.1",
"@types/chai": "4.3.6",
"@types/chai-as-promised": "7.1.5",
"@types/eslint": "8.44.2",
"@types/mocha": "10.0.1",
"@types/ms": "0.7.31",
"@types/node": "20.11.19",
"@types/readable-stream": "4.0.6",
"@types/sinon": "17.0.2",
"@typescript-eslint/eslint-plugin": "6.4.0",
"@typescript-eslint/parser": "6.4.0",
"@web/test-runner": "0.18.0",
"@web/test-runner-playwright": "0.11.0",
"c8": "9.0.0",
"chai": "4.3.10",
"chai-as-promised": "7.1.1",
"esbuild": "0.19.8",
"eslint": "8.47.0",
"eslint-plugin-mocha": "10.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/did-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class DidApi {
/**
* Resolves a DID to a DID Resolution Result.
*
* @param didUrl - The DID or DID URL to resolve.
* @param didUri - The DID or DID URL to resolve.
* @returns A promise that resolves to the DID Resolution Result.
*/
public async resolve(
Expand Down
99 changes: 44 additions & 55 deletions packages/api/src/dwn-api.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import type { DwnResponse, Web5Agent } from '@web5/agent';
import type { DwnResponse, ProcessDwnRequest, Web5Agent } from '@web5/agent';
import type {
PaginationCursor,
RecordsQueryReply,
RecordsReadOptions,
ProtocolsQueryReply,
RecordsQueryOptions,
RecordsWriteMessage,
RecordsWriteOptions,
RecordsDeleteOptions,
ProtocolsQueryOptions,
RecordsQueryReplyEntry,
ProtocolsConfigureMessage,
ProtocolsConfigureOptions,
ProtocolsConfigureDescriptor,
} from '@tbd54566975/dwn-sdk-js';

import { DwnInterface } from '@web5/agent';
import { isEmptyObject } from '@web5/common';
import { DwnInterfaceName, DwnMethodName, RecordsWrite } from '@tbd54566975/dwn-sdk-js';
import { RecordsWrite } from '@tbd54566975/dwn-sdk-js';

import { Record } from './record.js';
import { dataToBlob } from './utils.js';
Expand Down Expand Up @@ -203,18 +202,18 @@ export class DwnApi {
*/
configure: async (request: ProtocolsConfigureRequest): Promise<ProtocolsConfigureResponse> => {
const agentResponse = await this.agent.processDwnRequest({
target : this.connectedDid,
author : this.connectedDid,
messageOptions : request.message,
messageType : DwnInterfaceName.Protocols + DwnMethodName.Configure
author : this.connectedDid,
messageParams : request.message,
messageType : DwnInterface.ProtocolsConfigure,
target : this.connectedDid
});

const { message, messageCid, reply: { status }} = agentResponse;
const response: ProtocolsConfigureResponse = { status };

if (status.code < 300) {
const metadata = { author: this.connectedDid, messageCid };
response.protocol = new Protocol(this.agent, message as ProtocolsConfigureMessage, metadata);
response.protocol = new Protocol(this.agent, message, metadata);
}

return response;
Expand All @@ -224,31 +223,27 @@ export class DwnApi {
* Query the available protocols
*/
query: async (request: ProtocolsQueryRequest): Promise<ProtocolsQueryResponse> => {
const agentRequest = {
author : this.connectedDid,
messageOptions : request.message,
messageType : DwnInterfaceName.Protocols + DwnMethodName.Query,
target : request.from || this.connectedDid
const agentRequest: ProcessDwnRequest<DwnInterface.ProtocolsQuery> = {
author : this.connectedDid,
messageParams : request.message,
messageType : DwnInterface.ProtocolsQuery,
target : request.from || this.connectedDid
};

let agentResponse: DwnResponse;
let agentResponse: DwnResponse<DwnInterface.ProtocolsQuery>;

if (request.from) {
agentResponse = await this.agent.sendDwnRequest(agentRequest);
} else {
agentResponse = await this.agent.processDwnRequest(agentRequest);
}

const reply = agentResponse.reply as ProtocolsQueryReply;
const reply = agentResponse.reply;
const { entries = [], status } = reply;

const protocols = entries.map((entry: ProtocolsQueryReplyEntry) => {
const metadata = { author: this.connectedDid, };

// FIXME: dwn-sdk-js actually returns the entire ProtocolsConfigure message,
// but the type claims that it returns the message without authorization.
// When dwn-sdk-js fixes the type, we should remove `as ProtocolsConfigureMessage`
return new Protocol(this.agent, entry as ProtocolsConfigureMessage, metadata);
const protocols = entries.map((entry) => {
const metadata = { author: this.connectedDid };
return new Protocol(this.agent, entry, metadata);
});

return { protocols, status };
Expand Down Expand Up @@ -306,23 +301,23 @@ export class DwnApi {
* Delete a record
*/
delete: async (request: RecordsDeleteRequest): Promise<ResponseStatus> => {
const agentRequest = {
const agentRequest: ProcessDwnRequest<DwnInterface.RecordsDelete> = {
/**
* The `author` is the DID that will sign the message and must be the DID the Web5 app is
* connected with and is authorized to access the signing private key of.
*/
author : this.connectedDid,
messageOptions : request.message,
messageType : DwnInterfaceName.Records + DwnMethodName.Delete,
author : this.connectedDid,
messageParams : request.message,
messageType : DwnInterface.RecordsDelete,
/**
* The `target` is the DID of the DWN tenant under which the delete will be executed.
* If `from` is provided, the delete operation will be executed on a remote DWN.
* Otherwise, the record will be deleted on the local DWN.
*/
target : request.from || this.connectedDid
target : request.from || this.connectedDid
};

let agentResponse: DwnResponse;
let agentResponse: DwnResponse<DwnInterface.RecordsDelete>;

if (request.from) {
agentResponse = await this.agent.sendDwnRequest(agentRequest);
Expand All @@ -339,23 +334,23 @@ export class DwnApi {
* Query a single or multiple records based on the given filter
*/
query: async (request: RecordsQueryRequest): Promise<RecordsQueryResponse> => {
const agentRequest = {
const agentRequest: ProcessDwnRequest<DwnInterface.RecordsQuery> = {
/**
* The `author` is the DID that will sign the message and must be the DID the Web5 app is
* connected with and is authorized to access the signing private key of.
*/
author : this.connectedDid,
messageOptions : request.message,
messageType : DwnInterfaceName.Records + DwnMethodName.Query,
author : this.connectedDid,
messageParams : request.message,
messageType : DwnInterface.RecordsQuery,
/**
* The `target` is the DID of the DWN tenant under which the query will be executed.
* If `from` is provided, the query operation will be executed on a remote DWN.
* Otherwise, the local DWN will be queried.
*/
target : request.from || this.connectedDid
target : request.from || this.connectedDid
};

let agentResponse: DwnResponse;
let agentResponse: DwnResponse<DwnInterface.RecordsQuery>;

if (request.from) {
agentResponse = await this.agent.sendDwnRequest(agentRequest);
Expand Down Expand Up @@ -400,23 +395,23 @@ export class DwnApi {
* Read a single record based on the given filter
*/
read: async (request: RecordsReadRequest): Promise<RecordsReadResponse> => {
const agentRequest = {
const agentRequest: ProcessDwnRequest<DwnInterface.RecordsRead> = {
/**
* The `author` is the DID that will sign the message and must be the DID the Web5 app is
* connected with and is authorized to access the signing private key of.
*/
author : this.connectedDid,
messageOptions : request.message,
messageType : DwnInterfaceName.Records + DwnMethodName.Read,
author : this.connectedDid,
messageParams : request.message,
messageType : DwnInterface.RecordsRead,
/**
* The `target` is the DID of the DWN tenant under which the read will be executed.
* If `from` is provided, the read operation will be executed on a remote DWN.
* Otherwise, the read will occur on the local DWN.
*/
target : request.from || this.connectedDid
target : request.from || this.connectedDid
};

let agentResponse: DwnResponse;
let agentResponse: DwnResponse<DwnInterface.RecordsRead>;

if (request.from) {
agentResponse = await this.agent.sendDwnRequest(agentRequest);
Expand Down Expand Up @@ -466,24 +461,18 @@ export class DwnApi {
* requires fetching from the DWN datastore.
*/
write: async (request: RecordsWriteRequest): Promise<RecordsWriteResponse> => {
const messageOptions: Partial<RecordsWriteOptions> = {
...request.message
};

const { dataBlob, dataFormat } = dataToBlob(request.data, messageOptions.dataFormat);
messageOptions.dataFormat = dataFormat;
const { dataBlob, dataFormat } = dataToBlob(request.data, request.message?.dataFormat);

const agentResponse = await this.agent.processDwnRequest({
author : this.connectedDid,
dataStream : dataBlob,
messageOptions,
messageType : DwnInterfaceName.Records + DwnMethodName.Write,
store : request.store,
target : this.connectedDid
author : this.connectedDid,
dataStream : dataBlob,
messageParams : { ...request.message, dataFormat },
messageType : DwnInterface.RecordsWrite,
store : request.store,
target : this.connectedDid
});

const { message, reply: { status } } = agentResponse;
const responseMessage = message as RecordsWriteMessage;
const { message: responseMessage, reply: { status } } = agentResponse;

let record: Record;
if (200 <= status.code && status.code <= 299) {
Expand Down
Loading

0 comments on commit 4efc18b

Please sign in to comment.