diff --git a/examples/simple-agent/.gitignore b/examples/simple-agent/.gitignore
index 0467ea0eb..cf58023e7 100644
--- a/examples/simple-agent/.gitignore
+++ b/examples/simple-agent/.gitignore
@@ -1,5 +1,3 @@
-# Agent Specific
-
-BLOCKSTORE/
-DATASTORE/
-INDEX/
\ No newline at end of file
+DATASTORE-*
+INDEX-*
+MESSAGESTORE-*
\ No newline at end of file
diff --git a/examples/simple-agent/etc/did.json b/examples/simple-agent/etc/did.json
index b3ddb677d..d18a28ca7 100644
--- a/examples/simple-agent/etc/did.json
+++ b/examples/simple-agent/etc/did.json
@@ -7,7 +7,7 @@
"content": {
"publicKeys": [
{
- "id": "key-1",
+ "id": "dwn",
"type": "JsonWebKey2020",
"purposes": [
"authentication"
@@ -68,9 +68,9 @@
],
"keys": [
{
- "id": "key-1",
+ "id": "dwn",
"type": "JsonWebKey2020",
- "keypair": {
+ "keyPair": {
"publicJwk": {
"kty": "EC",
"crv": "secp256k1",
diff --git a/examples/simple-agent/src/index.js b/examples/simple-agent/src/index.js
index 33a72f75f..c148bb011 100644
--- a/examples/simple-agent/src/index.js
+++ b/examples/simple-agent/src/index.js
@@ -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);
diff --git a/examples/simple-agent/src/utils.js b/examples/simple-agent/src/utils.js
index 27784bc2f..2384f2fb2 100644
--- a/examples/simple-agent/src/utils.js
+++ b/examples/simple-agent/src/utils.js
@@ -1,10 +1,22 @@
import getRawBody from 'raw-body';
+import { DataStoreLevel, Dwn, 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 messageStore = new MessageStoreLevel({
+ blockstoreLocation : `MESSAGESTORE-${port}`,
+ indexLocation : `INDEX-${port}`,
+});
+
+const dwnNode = await Dwn.create({ messageStore, dataStore });
+
+const web5 = new Web5({ dwn: { node: dwnNode }});
const etcPath = './etc';
const didStoragePath = `${etcPath}/did.json`;
@@ -42,11 +54,10 @@ 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: didState.keys['#dwn'].keyPair,
});
}
@@ -99,8 +110,6 @@ async function receiveHttp(ctx) {
const data = await getRawBody(ctx.req);
- console.log('TRACE - receiveHttp() - message:', message);
-
return await web5.send(target, {
author,
data,
diff --git a/examples/test-dashboard/desktop-agent-original.html b/examples/test-dashboard/desktop-agent-original.html
new file mode 100644
index 000000000..df1527f12
--- /dev/null
+++ b/examples/test-dashboard/desktop-agent-original.html
@@ -0,0 +1,937 @@
+
+
+
+
+
+
+ Agent Test Dashboard
+
+
+
+
+
+
+
+
+
+
+ Write Records
+
+
+
+
+
+ Query Records
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Read Records
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Delete Records
+
+
+
+
+
+
+
+
+
+
+
+ Protocols
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Custom Data Formats
+
+
+
+
+
+
+
+ New Tests
+
+
+
+ Write data authored by Alice's DID to Alice's DWN WITH local key chain
+
+
+
+
+
+
+ Write data authored by Alice's DID to Alice's DWN withOUT local key chain
+
+
+
+
+
+
+ Write data authored by Alice's DID to Bob's DWN WITH local key chain
+
+
+
+
+
+
+ Write data authored by Alice's DID to Bob's DWN withOUT local key chain
+
+
+
+
+
+
+ Query data authored by Alice's DID to Bob's DWN withOUT local key chain
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/test-dashboard/desktop-agent.html b/examples/test-dashboard/desktop-agent.html
index 3b2830875..f09f5ab5b 100644
--- a/examples/test-dashboard/desktop-agent.html
+++ b/examples/test-dashboard/desktop-agent.html
@@ -23,6 +23,7 @@
font-family: 'IBM Plex Mono';
padding: 0;
margin: 0;
+ max-width: 72rem;
}
input, button {
@@ -31,50 +32,35 @@
main {
color: rgb(250, 250, 250);
- padding: 0rem 1rem;
}
- .box {
- max-width: 52rem;
- display: flex;
- flex-direction: column;
- }
-
- .box>.row {
- display: flex;
- align-items: start;
- padding-top: 0.5em;
- }
-
- .box>.row>label {
- padding-right: 0.5em;
- padding-left: 0.5em;
+ fieldset {
+ border-width: 2px;
+ border-style: solid;
+ border-radius: 5px;
+ padding: 1.25rem;
+ padding-block-start: 0.5em;
+ margin: 0rem 1rem 2rem 1rem;
}
-
- .box>.row>button {
- margin-left: auto;
+
+ fieldset.yellow {
+ border-color: var(--color-yellow);
}
- .box>.row>input[type=text] {
- width: 8em;
+ fieldset.yellow>legend {
+ color: var(--color-yellow);
}
-
- .box>.row>textarea {
- width: 250px;
- height: 125px;
+
+ fieldset.blue {
+ border-color: var(--color-blue);
}
- fieldset {
- border: 2px solid var(--color-yellow);
- border-radius: 5px;
- padding: 20px;
- margin: 0rem 1rem;
+ fieldset.blue>legend {
+ color: var(--color-blue);
}
legend {
- color: var(--color-yellow);
font-size: 1.5rem;
- padding: 0 10px;
}
fieldset .buttons {
@@ -90,12 +76,13 @@
color: white;
cursor: pointer;
font-size: 14px;
+ min-width:fit-content;
+ white-space: nowrap;
padding: 0.5em 20px;
text-align: center;
}
button:hover {
- /* background-color: #45a049; */
filter: brightness(95%);
}
@@ -104,6 +91,20 @@
font-size: 1rem;
margin-top: 1rem;
text-align: center;
+
+ /* for smooth appearance transition */
+ opacity: 0;
+ max-height: 0;
+ overflow: hidden;
+ margin: 0;
+ padding: 0;
+ transition: opacity 0.4s ease, max-height 0.4s ease, margin 0.4s ease, padding 0.4s ease;
+ }
+
+ #container_connect_status.visible {
+ opacity: 1;
+ max-height: 1000px;
+ margin-top: 1rem;
}
#container_connect_status.success {
@@ -117,6 +118,20 @@
#container_security_code {
margin-top: 1rem;
text-align: center;
+
+ /* for smooth appearance transition */
+ opacity: 0;
+ max-height: 0;
+ overflow: hidden;
+ margin: 0;
+ padding: 0;
+ transition: opacity 0.4s ease, max-height 0.4s ease, margin 0.4s ease, padding 0.4s ease;
+ }
+
+ #container_security_code.visible {
+ opacity: 1;
+ max-height: 1000px;
+ margin-top: 1rem;
}
#container_security_code .label {
@@ -143,19 +158,75 @@
background-color: var(--color-blue-10);
line-height: 2.5rem; /* Vertically center the text */
}
+
+ main #output {
+ padding: 0 1rem;
+ }
+
+ main #output .row {
+ background-color: rgb(51, 51, 51);
+ border: none;
+ border-radius: 0.5rem;
+ font-size: 0.75rem;
+ margin: 1rem 0rem;
+ padding: 1rem;
+ white-space: pre-wrap;
+ }
+
+ main #output .error {
+ color: var(--color-red);
+ }
+
+ main .button-container {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ grid-auto-rows: 2rem;
+ column-gap: 1rem;
+ row-gap: 1rem;
+ width: 100%;
+ min-width: max-content;
+ /* max-width: 37.5rem; */
+ margin: 0 auto;
+ box-sizing: border-box;
+ }
+
+ @media (max-width: 27em) {
+ main .button-container {
+ grid-template-columns: repeat(2, 1fr);
+ }
+ }
+
+ main .output-status {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ padding-top: 1rem;
+ }
+
+ main .output-status .btn {
+ background-color: var(--color-red);
+ filter: brightness(70%);
+ }
+
+ main .output-status .btn:hover {
+ background-color: var(--color-red);
+ filter: brightness(95%);
+ }
-