Skip to content

Commit

Permalink
Add Record class, DID Manager, and Stabilize API (#43)
Browse files Browse the repository at this point in the history
* Commit to resolve merge conflicts

Signed-off-by: Frank Hinek <[email protected]>

* Delete duplicate Storage.js

Caused by git ignoring case

* Delete duplicate file

Caused by git ignoring case

* Revert status code for 'No DWN endpoints present in DID document' back to 422

Co-authored-by: Frank Hinek <[email protected]>
Co-authored-by: Devin Rousso <[email protected]>

* Bump dwn-sdk-js to 0.0.30

Signed-off-by: Frank Hinek <[email protected]>

* Clean-up git case insensitivity issue

* Make the Web5Did didStore private

Signed-off-by: Frank Hinek <[email protected]>

* Move Web5 response types to be adjacent to functions that return this type

Signed-off-by: Frank Hinek <[email protected]>

* Minor syntax changes to Record class

Signed-off-by: Frank Hinek <[email protected]>

* Change Record.create from getter to function

Signed-off-by: Frank Hinek <[email protected]>

* Change frozen/deleted terminology to be more descriptive/intuitive

Signed-off-by: Frank Hinek <[email protected]>

* Making named exports consistent throughout project

Signed-off-by: Frank Hinek <[email protected]>

* Update simple-agent example to define location for EventLog

Signed-off-by: Frank Hinek <[email protected]>

* Refactor DID Manager

Signed-off-by: Frank Hinek <[email protected]>

* Address minor nits

Signed-off-by: Frank Hinek <[email protected]>

* Revert change from storage classes

Signed-off-by: Frank Hinek <[email protected]>

* Collection of small enhancements

Signed-off-by: Frank Hinek <[email protected]>

* Improve defensiveness and readability of send functions for Web5 and HTTP transport

Signed-off-by: Frank Hinek <[email protected]>

* Bump ION tools

Signed-off-by: Frank Hinek <[email protected]>

---------

Signed-off-by: Frank Hinek <[email protected]>
Co-authored-by: Devin Rousso <[email protected]>
  • Loading branch information
frankhinek and dcrousso authored Apr 21, 2023
1 parent a7b0e83 commit 3e81ed1
Show file tree
Hide file tree
Showing 44 changed files with 3,009 additions and 1,047 deletions.
9 changes: 4 additions & 5 deletions examples/simple-agent/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Agent Specific

BLOCKSTORE/
DATASTORE/
INDEX/
DATASTORE-*
EVENTLOG-*
INDEX-*
MESSAGESTORE-*
6 changes: 3 additions & 3 deletions examples/simple-agent/etc/did.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"content": {
"publicKeys": [
{
"id": "key-1",
"id": "dwn",
"type": "JsonWebKey2020",
"purposes": [
"authentication"
Expand Down Expand Up @@ -68,9 +68,9 @@
],
"keys": [
{
"id": "key-1",
"id": "dwn",
"type": "JsonWebKey2020",
"keypair": {
"keyPair": {
"publicJwk": {
"kty": "EC",
"crv": "secp256k1",
Expand Down
2 changes: 1 addition & 1 deletion examples/simple-agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"dependencies": {
"@koa/cors": "4.0.0",
"@koa/router": "12.0.0",
"@tbd54566975/web5": "0.3.1-unstable.e2dfe57-2023.3.23-19-07-37",
"@tbd54566975/web5": "0.5.0",
"koa": "2.14.1",
"koa-body": "6.0.1",
"mkdirp": "2.1.5",
Expand Down
14 changes: 10 additions & 4 deletions examples/simple-agent/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,16 @@ router.post('/dwn', async (ctx, _next) => {
try {
const response = await receiveHttp(ctx);

// Normalize DWN MessageReply and HTTP Reponse
ctx.status = response?.status?.code ?? response?.status;
ctx.statusText = response?.status?.detail ?? response?.statusText;
ctx.body = 'entries' in response ? { entries: response.entries } : response.body;
console.log('SIMPLE AGENT receiveHTTP response:', response);

// // All DWN MessageReply responses contain a `status` object.
// // DWN RecordsQuery responses contain an `entries` array of query results.
// // DWN RecordsRead responses contain a data property which is a Readable stream.
// const { message, ...retainedResponse } = response;

// ctx.body = retainedResponse;
// ctx.status = retainedResponse?.status?.code;
// ctx.statusText = retainedResponse?.status?.detail;
}
catch(err) {
console.error(err);
Expand Down
41 changes: 21 additions & 20 deletions examples/simple-agent/src/utils.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
import getRawBody from 'raw-body';
import { DataStoreLevel, Dwn, EventLogLevel, MessageStoreLevel } from '@tbd54566975/dwn-sdk-js';
import { Web5 } from '@tbd54566975/web5';
import fs from 'node:fs';
import mkdirp from 'mkdirp';
import { createRequire } from 'node:module';

const web5 = new Web5();
// Use custom names for the block, message, and data stores to make it possible to launch multiple simple agents
// in the same directory. If you don't do this, you will get LevelDB lock errors.
const port = await getPort(process.argv);
const dataStore = new DataStoreLevel({ blockstoreLocation: `DATASTORE-${port}` });
const eventLog = new EventLogLevel({ location: `EVENTLOG-${port}` });
const messageStore = new MessageStoreLevel({
blockstoreLocation : `MESSAGESTORE-${port}`,
indexLocation : `INDEX-${port}`,
});

const dwnNode = await Dwn.create({ dataStore, eventLog, messageStore });

export const web5 = new Web5({ dwn: { node: dwnNode }});

const etcPath = './etc';
const didStoragePath = `${etcPath}/did.json`;
Expand All @@ -14,7 +27,7 @@ const require = createRequire(import.meta.url);
const testProtocol = require('../resources/test-protocol.json');
const protocols = [testProtocol];

async function getPort(processArgv) {
export async function getPort(processArgv) {
const defaultPort = 8080;

// Find the -p option and get the port number
Expand All @@ -27,7 +40,7 @@ async function getPort(processArgv) {
return port;
}

async function loadConfig() {
export async function loadConfig() {
if (!fs.existsSync(etcPath)) {
// ensure that directory for persistent storage exists
mkdirp.sync(etcPath);
Expand All @@ -42,15 +55,14 @@ async function loadConfig() {
didState = await initOperatorDid();
fs.writeFileSync(didStoragePath, JSON.stringify(didState, null, 2));
}
web5.did.register({
web5.did.manager.set(didState.id, {
connected: true,
did: didState.id,
endpoint: 'app://dwn',
keys: didState.keys[0].keypair,
keys: { ['#dwn']: { keyPair: didState.keys[0].keyPair} },
});
}

async function initOperatorDid() {
export async function initOperatorDid() {
const operatorDid = await web5.did.create('ion', {
services: [
{
Expand All @@ -65,7 +77,7 @@ async function initOperatorDid() {
return operatorDid;
}

async function initializeProtocols() {
export async function initializeProtocols() {
for (let { protocol, definition } of protocols) {
const queryResponse = await web5.dwn.protocols.query(didState.id, {
author: didState.id,
Expand All @@ -87,7 +99,7 @@ async function initializeProtocols() {
}
}

async function receiveHttp(ctx) {
export async function receiveHttp(ctx) {
const encodedMessage = ctx.get(web5.transports.http.ENCODED_MESSAGE_HEADER);
if (!encodedMessage) throw 'Message is missing or malformed';

Expand All @@ -99,20 +111,9 @@ async function receiveHttp(ctx) {

const data = await getRawBody(ctx.req);

console.log('TRACE - receiveHttp() - message:', message);

return await web5.send(target, {
author,
data,
message,
});
}

export {
getPort,
initializeProtocols,
initOperatorDid,
loadConfig,
receiveHttp,
web5,
};
Loading

0 comments on commit 3e81ed1

Please sign in to comment.