diff --git a/docs/web5/_quickstart-02-prereqs-and-installation.mdx b/docs/web5/_quickstart-02-prereqs-and-installation.mdx index 457341a45..81480e54b 100644 --- a/docs/web5/_quickstart-02-prereqs-and-installation.mdx +++ b/docs/web5/_quickstart-02-prereqs-and-installation.mdx @@ -9,10 +9,13 @@ import TabItem from '@theme/TabItem'; :::info

Prerequisites

::: @@ -29,7 +32,7 @@ cd web5-app

Use NPM to install Web5:

```bash -npm install @tbd54566975/web5@0.6.0 +npm install @tbd54566975/web5@0.7.2 ``` :::note @@ -41,7 +44,7 @@ This will create a `package.json` in the root of your project. Open `package.jso ```js { "dependencies": { - "@tbd54566975/web5": "^0.6.0" + "@tbd54566975/web5": "0.7.2" }, "type": "module" } diff --git a/docs/web5/_quickstart-03-create-did.mdx b/docs/web5/_quickstart-03-create-did.mdx index 5d313aeb2..367e3215d 100644 --- a/docs/web5/_quickstart-03-create-did.mdx +++ b/docs/web5/_quickstart-03-create-did.mdx @@ -1,43 +1,33 @@
-## Start Building +## 1. Instantiate Web5 -### 1. Create a Web5 instance +The `Web5` class is an isolated API object for doing all things Web5 and the connect() function creates an instance of Web5. -The `Web5` class is an isolated API object for doing all things Web5. In `index.js` below the import statement, create a new instance of `Web5`: +In Web5 apps, a user’s unique identifier - like an email address - is called a [Decentralized Identifier (DID)](/docs/web5/learn/decentralized-identifiers). +We are building a decentralized app, so your users are using identifiers that aren't tied to a centralized authority. +In `index.js` below the import statement, create a new instance of `Web5`: ```js -const web5 = new Web5(); +const { web5, did: aliceDid } = await Web5.connect(); ``` +This Web5 instance is what you'll use to access the other objects of Web5 such as `did` and `dwn`. Within the connect function we’re using `ion` as the DID method. Learn more about ION and other [DID methods](/docs/web5/learn/decentralized-identifiers#methods). + :::info Web5 is split into three main top-level objects: - web5.did - web5.dwn - web5.vc - -We're going to focus on `web5.did` and `web5.dwn` in this Quickstart. ::: -### 2. Create a DID - -In Web5 apps, a user’s unique identifier - like an email address - is called a [Decentralized Identifier (DID)](/docs/web5/learn/decentralized-identifiers). -We are building a decentralized app, so your users are using identifiers that aren't tied to a centralized authority. - -Assuming a brand new user who does not yet have a DID, let’s create their DID using the Web5 API. Below the Web5 instantiation, add: -```js -const did = await web5.did.create('ion'); -``` - -We’re using `ion` as the DID method. Learn more about ION and other [DID methods](/docs/web5/learn/decentralized-identifiers#methods). -
Test your code

Wanna see the DID you just created? In index.js, add the following line and save your file: ```js - console.log(did.id); + console.log(aliceDid); ``` Then from your CLI, run: @@ -51,4 +41,4 @@ We’re using `ion` as the DID method. Learn more about ION and other [DID metho #### Try it! -

\ No newline at end of file + diff --git a/docs/web5/_quickstart-04-register-did.mdx b/docs/web5/_quickstart-04-register-did.mdx deleted file mode 100644 index c4160c50c..000000000 --- a/docs/web5/_quickstart-04-register-did.mdx +++ /dev/null @@ -1,30 +0,0 @@ -
- -### 3. Associate DID with Storage - -When you instantiate Web5, the SDK internally creates a [Decentralized Web Node(DWN)](/docs/web5/learn/decentralized-web-nodes) to act as a personal data store to hold your user's content. - -Operations will return results in the form of a `record`, which is a JSON object. `record` objects provide a suite of -helper methods to make it easy to work with DWN. - -To store the user's DID as well as save and encrypt their keys, add the following to `index.js`: - -```js -await web5.did.manager.set(did.id, { - connected: true, - endpoint: 'app://dwn', //this points to the user's local DWN - keys: { - ['#dwn']: { - keyPair: did.keys.find(key => key.id === 'dwn').keyPair, - }, - }, -}); -``` - -:::note -In production apps, before doing this step, you'd check to make sure the user doesn't already have an existing DWN. -::: - -#### Try it! - -
\ No newline at end of file diff --git a/docs/web5/_quickstart-05-write-record.mdx b/docs/web5/_quickstart-05-write-record.mdx index 5105caf9c..dd5ccad4a 100644 --- a/docs/web5/_quickstart-05-write-record.mdx +++ b/docs/web5/_quickstart-05-write-record.mdx @@ -1,8 +1,8 @@
-### 4. Write DWN Records +## 2. Write DWN Records -Now you’re able to write records in the user's [Decentralized Web Node(DWN)](/docs/web5/learn/decentralized-web-nodes). +Now you’re able to write records in the user's [Decentralized Web Node(DWN)](/docs/web5/learn/decentralized-web-nodes). A DWN is a personal data store - a platform for messages, pictures, videos, medical records, and just about any content a user may want to store. @@ -11,25 +11,22 @@ A DWN is a personal data store - a platform for messages, pictures, videos, medi

Your app should not store users' data in your centralized database. Instead, their data should be stored in their DWN. This is how the user retains ownership over their content. Through permissions, users can decide which apps can read, write, and delete content from their DWN. -The DWN exists in local storage under the name `dwn-info`. The DWN persists across browser sessions and can be synched across a user's devices. +The DWN exists in local storage under the name `dwn-info`. The DWN persists across browser sessions and can be synched across a user's devices. -A user can host their DWN in mulitple locations. The Web5 SDK is both browser and Node.js compliant, meaning you can use the same APIs on both client side and serverside. +A user can host their DWN in mulitple locations. The Web5 SDK is both browser and Node.js compliant, meaning you can use the same APIs on both client side and serverside.

- Add the following to `index.js`: ```js -const {record} = await web5.dwn.records.create(did.id, { - author: did.id, - data: "Hello Web5", - message: { - dataFormat: 'text/plain', - }, +const { record } = await web5.dwn.records.create({ + data: "Hello Web5", + message: { + dataFormat: 'text/plain', + }, }); ``` -
Test your code

@@ -56,4 +53,4 @@ Enter "Hello Web5" in the input field and click "Run" to write a record to the s #### Try it! -

\ No newline at end of file + diff --git a/docs/web5/_quickstart-06-read-record.mdx b/docs/web5/_quickstart-06-read-record.mdx index 1b46bc93f..8657f631e 100644 --- a/docs/web5/_quickstart-06-read-record.mdx +++ b/docs/web5/_quickstart-06-read-record.mdx @@ -1,10 +1,9 @@
-### 5. Read DWN Records +## 3. Read DWN Records If the user has given your app read permissions to their DWN, you can read their data by accessing it through the `record` property. - To return the text data stored in the `record`, add the following to `index.js`: ```js const readResult = await record.data.text(); @@ -16,13 +15,13 @@ const readResult = await record.data.text(); To see the record that was read from the DWN, add the following to index.js: ```js -console.log('Read result: ', readResult); +console.log('readResult', readResult) ``` The output will resemble: -```js -Read result: Hello Web5 +``` +Hello Web5 ```

diff --git a/docs/web5/_quickstart-07-read-record.mdx b/docs/web5/_quickstart-07-read-record.mdx deleted file mode 100644 index f326fdcb3..000000000 --- a/docs/web5/_quickstart-07-read-record.mdx +++ /dev/null @@ -1,14 +0,0 @@ -## 7. Reading messages in your DWN - -If the user has given your app read permissions to their DWN, you can read specific records using a `recordId`. In the code snippet below, we are using the `queryResult` from Step 6 to obtain the `recordId`. - -```js -let readResult = await web5.dwn.records.read(did.id, { - author: did.id, - message: { - recordId: queryResult.entries[0].recordId, - }, -}); -``` - -Let's have a look at the data stored earlier: \ No newline at end of file diff --git a/docs/web5/_quickstart-07-update-record.mdx b/docs/web5/_quickstart-07-update-record.mdx index aa91071ec..1094d5d2e 100644 --- a/docs/web5/_quickstart-07-update-record.mdx +++ b/docs/web5/_quickstart-07-update-record.mdx @@ -1,6 +1,6 @@
-### 6. Update DWN Records +## 4. Update DWN Records To update the record, call `update` on the `record` object itself. @@ -15,13 +15,12 @@ const updateResult = await record.update({data: "Hello, I'm updated!"}); To see the record that was updated in the DWN, add the following to index.js: ```js -console.log('Update result: ', await record.data.text()); +​console.log('updateResult', await record.data.text()) ``` The output will resemble: - ``` -Update result: Hello, I'm updated! +updateResult Hello, I'm updated! ```

@@ -31,4 +30,4 @@ Enter "Hello, I'm updated" in the input field and click "Run!" to update the rec #### Try it! -
\ No newline at end of file +
diff --git a/docs/web5/_quickstart-08-delete-record.mdx b/docs/web5/_quickstart-08-delete-record.mdx index 560420245..9b9bb74b3 100644 --- a/docs/web5/_quickstart-08-delete-record.mdx +++ b/docs/web5/_quickstart-08-delete-record.mdx @@ -1,6 +1,6 @@
-### 7. Delete DWN Records +## 5. Delete DWN Records Given permission from the user, your app can delete records from their DWN. Similar to reading, we’ll use the `record` object to remove the record. @@ -15,13 +15,13 @@ const deleteResult = await record.delete(); To see the status of the delete transaction, add the following to index.js: ```js -console.log('Delete result: ', deleteResult.status); +console.log('deleteResult', deleteResult) ``` The output will resemble: -```js -Delete result: { code: 202, detail: 'Accepted' }, +``` +{ status: { code: 202, detail: 'Accepted' } } ```

@@ -29,4 +29,4 @@ Delete result: { code: 202, detail: 'Accepted' }, #### Try it! -
+ \ No newline at end of file diff --git a/docs/web5/_quickstart-09-query-record.mdx b/docs/web5/_quickstart-09-query-record.mdx deleted file mode 100644 index 80b775e52..000000000 --- a/docs/web5/_quickstart-09-query-record.mdx +++ /dev/null @@ -1,57 +0,0 @@ -## 9. Query DWN Records - -Querying a DWN allows you to search records depending on the filter params you pass to it. In the code snippet below, we're querying a DWN for messages that have a MIME type of `text/plain`. - -:::note -You don't have to query based on MIME type, there are many different attributes you can use to query, such as protocol, schema, contextId, etc. -::: - -Add the following to `index.js`: -```js -const queryResult = await web5.dwn.records.query(did.id, { - author: did.id, - message: { - filter: { - dataFormat: 'text/plain', - }, - }, -}); -``` - -
-Test your code -

-To see the DWN records that have the text/plain data format, add the following line to index.js: - -```js -console.log('query result', queryResult); -``` - - Then from the terminal, run: - ```bash - node src/index.js - ``` - -Your output will resemble: - -```js -query result { - status: { code: 200, detail: 'OK' }, - entries: [ _Record {} ], - data: undefined, - message: { - recordId: null, - descriptor: { - interface: 'Records', - method: 'Query', - dateCreated: '2023-04-25T18:52:46.648765Z', - filter: [Object] - } - } -} -``` - -

-
- -Click "Run!" to query the sandbox DWN for records with an `image/png` data format: diff --git a/docs/web5/_quickstart-10-next-steps.mdx b/docs/web5/_quickstart-10-next-steps.mdx index d51b6e781..316342227 100644 --- a/docs/web5/_quickstart-10-next-steps.mdx +++ b/docs/web5/_quickstart-10-next-steps.mdx @@ -3,15 +3,12 @@ ## Summary Congrats! You've just created a local DWN to serve as your user's -personal data store. - -Given a user's DID and appropriate permissions, your app can read, write, or delete data from the user's DWN, while -leaving them in full control of their content. Other apps can query local storage to determine if the user already has a DWN on their device, and -can also read and write from this same data store - essentially, making the user's data portable across multiple applications. +personal data store. Given a user's DID and appropriate permissions, your app can read, write, or delete data from the user's DWN, while +leaving them in full control of their content. :::info * [Download the completed index.js file](/files/index.txt) -* [View source code for the interactive sandbox of this Quickstart](https://raw.githubusercontent.com/TBD54566975/web5-quickstart-widgets/0.6.0/index.html) +* [View source code for the interactive sandbox of this Quickstart](https://raw.githubusercontent.com/TBD54566975/web5-quickstart-widgets/0.7.0/index.html) * [Run interactive sandbox directly in your browser](https://moonlit-centaur-0d7b4f.netlify.app/) ::: diff --git a/docs/web5/build/apps/todo-app-tutorial.mdx b/docs/web5/build/apps/todo-app-tutorial.mdx index 4951e5ed0..ad1518f43 100644 --- a/docs/web5/build/apps/todo-app-tutorial.mdx +++ b/docs/web5/build/apps/todo-app-tutorial.mdx @@ -13,7 +13,8 @@ Download a copy of the skeleton ToDo app by running: ```bash git clone https://github.com/TBD54566975/web5-tutorials.git cd web5-tutorials -git checkout tags/0.1.1 -b todo-app-tutorial +git checkout tags/0.2.0 -b todo-app-tutorial +cd todo-app ``` In this tutorial, you’ll work through completing the `/todo-app/src/App.vue` file to use `web5.js`. @@ -26,7 +27,7 @@ If you’d like to skip ahead and see the finished version of this tutorial, you ```bash git clone https://github.com/TBD54566975/incubating-web5-labs.git cd incubating-web5-labs -git checkout tags/0.1.0 -b todo-app-finished +git checkout tags/0.2.0 -b incubating-web5-labs-todo-app cd todo-app npm install npm run dev @@ -39,10 +40,14 @@ There is also a hosted example deployed at [https://unrivaled-crumble-56ce70.net ## Setup +Add `Web5` to package.json in the `dependencies` section: +```bash + "@tbd54566975/web5": "0.7.2", +``` + Download the necessary packages by running these commands: ```bash -cd todo-app npm install npm run dev ``` @@ -67,17 +72,24 @@ Because we’ve built this sample using `Vue.js`, you’ll find both the HTML st ## Initialize Constants and Variables -First we'll set up some instances to hold data you'll use throughout your application. Copy the following block into the template, under the `import` statements, in the section marked `// Initialize variables here`. +Open `src/Vue.js` in your editor and add this next to the other imports: +```js +import { Web5 } from '@tbd54566975/web5'; +``` + +First we'll set up instances to hold data you'll use throughout your application. + +Copy the following block and paste under all `import` statements in `src/Vue.js`: ```js -const web5 = new Web5(); -const todos = ref([]); +let web5; let myDid; +const todos = ref([]); ``` -The `web5` instance is the single entry point for all Web5 operations. You've also set up a `todos` array to hold your ToDos, and a variable to remember the app user's decentralized identifier (DID) as `myDid`, which you'll create or load in a moment. +The `web5` object is the single entry point for all Web5 operations. You've also set up a `todos` array to hold your ToDos, and a variable to remember the app user's decentralized identifier (DID) as `myDid`. -## Loading or Creating User Data +## Create DID and Web5 Instance The first time a user accesses your ToDo app, you’ll need to handle creating an “account” for them - this means ensuring they have a DID and DWN available to access their app data. Once they come back for subsequent sessions, you’ll want to fetch and load that data for them. @@ -85,73 +97,44 @@ Add to `src/App.vue`: ```js onBeforeMount(async () => { - let registerInfo; - // Load DWN DID from local storage or create a new one - if(localStorage.getItem('registerInfo') && localStorage.getItem('myDid')){ - // User has an "account," so load their data - registerInfo = JSON.parse(localStorage.getItem('registerInfo')); - myDid = JSON.parse(localStorage.getItem('myDid')); - } else { - // User does not have an "account," so create one for them - myDid = await web5.did.create('ion'); - registerInfo = { - connected : true, - endpoint : 'app://dwn', - keys: { - ['#dwn']: { - keyPair: myDid.keys[0].keyPair, - }, - } - }; - - localStorage.setItem('myDid', JSON.stringify(myDid)); - localStorage.setItem('registerInfo', JSON.stringify(registerInfo)); - } - - // Associate DID with DWN - await web5.did.manager.set(myDid.id, registerInfo); - - // Put DWN query code here; this is covered in the next section -}); + ({ web5, did: myDid } = await Web5.connect()); ``` -In the snippet above, we’re using the `Vue.js` -provided `localStorage` to attempt to fetch the user’s `registerInfo` from local storage. - -If the data is available we can use that to access their DWN via `Web5.js`, otherwise we create a new decentralized identifier (DID) for them and a DWN to store their data. - ## Displaying Todos -Once you’ve called `web5.did.manager.set()`, you can now make calls to the DWN to fetch, write, and delete data. To load your user’s existing ToDos, call: +You can now make calls to the DWN to fetch, write, and delete data. To load your user’s existing ToDos, call: ```js - // DWN query code - - // Populate Todos from DWN - const queryResponse = await web5.dwn.records.query(myDid.id, { - author : myDid.id, - message : { - filter: { - schema: 'http://some-schema-registry.org/todo' - }, - dateSort: 'createdAscending' - }}); - - // Put ToDo object code here; this is covered in the next section +onBeforeMount(async () => { + ... + // Populate ToDos from DWN + const { records } = await web5.dwn.records.query({ + message: { + filter: { + schema: 'http://some-schema-registry.org/todo' + }, + dateSort: 'createdAscending' + } + }); ``` Once you’ve loaded the query data, you can map this data from the DWN into an object for your app to use: ```js - // ToDo object code - - // Add entry to Todo array - for (let record of queryResponse.entries) { - const todo = { record, data: await record.data.json(), id: record.id }; +onBeforeMount(async () => { + ... + // Add entry to ToDos array + for (let record of records) { + const data = await record.data.json(); + const todo = { record, data, id: record.id }; todos.value.push(todo); } +}); ``` -Now that your app user's ToDos are stored in their DWN, you can display them by using the `todos` object. In this example, you can do it by adding the following HTML code to the Vue app below the JS, just as you would in any non-Web5 app. In the template there is a comment marked `` where this code block fits nicely: +Now that your app user's ToDos are stored in their DWN, you can display them by using the `todos` object. In this example, you can do it by adding the following HTML code to the Vue app below the JS, just as you would in any non-Web5 app. + +In the template where you see `` add this: ```jsx
@@ -171,10 +154,11 @@ Now that your app user's ToDos are stored in their DWN, you can display them by Note that this UI code fulfills more than just loading the ToDos - it also provides the ability to toggle completion status and delete ToDos, which we’ll get to in a bit. ::: -## Adding Todos +## Adding ToDos -To allow for add functionality, begin by creating the UI needed to add ToDos. In the template there is a section marked `` where this block may go: +To allow for add functionality, begin by creating the UI needed to add ToDos. +In the template add this code block to ``: ```jsx
@@ -196,7 +180,9 @@ To allow for add functionality, begin by creating the UI needed to add ToDos. In Then, writing a ToDo into storage is done by binding a `addTodo()` method to the UI and leveraging the `newTodoDescription` model referenced in the `textarea` to call the `web5` method `dwn.records.write`: ```js -// Adding Todos +// Adding ToDos +const newTodoDescription = ref(''); + async function addTodo() { const todoData = { completed : false, @@ -205,17 +191,14 @@ async function addTodo() { newTodoDescription.value = ''; - const { record } = await web5.dwn.records.write(myDid.id, { - author : myDid.id, + // Create the record in DWN + const { record } = await web5.dwn.records.create({ data : todoData, message : { schema : 'http://some-schema-registry.org/todo', dataFormat : 'application/json' } }); - - // Put ToDo object creation code here; this is covered in the next section -} ``` This code uses the `myDid` object we loaded or created in the `onBeforeMount` function and uses it to write into the DWN that `web5` is using to store your app user's data. @@ -223,9 +206,14 @@ This code uses the `myDid` object we loaded or created in the `onBeforeMount` fu Once we’ve written the data to storage, we’ll use the returned `record` to create your app's `todo` object, passing along the `record.id` : ```js - // ToDo object creation code - const todo = { record, data: await record.data.json(), id: record.id }; +async function addTodo() { +... + // add DWeb message recordId as a way to reference the message for further operations + // e.g. updating it or overwriting it + const data = await record.data.json(); + const todo = { record, data, id: record.id }; todos.value.push(todo); +} ``` ## Deleting ToDos @@ -233,6 +221,7 @@ Once we’ve written the data to storage, we’ll use the returned `record` to c Deleting ToDos can be done by using the `deleteTodo` method, passing the `todoItem`: ```js +// Delete ToDo async function deleteTodo(todoItem) { let deletedTodo; let index = 0; @@ -247,9 +236,9 @@ async function deleteTodo(todoItem) { todos.value.splice(index, 1); - await web5.dwn.records.delete(myDid.id, { - author : myDid.id, - message : { + // Delete the record in DWN + await web5.dwn.records.delete({ + message: { recordId: deletedTodo.id } }); @@ -271,6 +260,7 @@ We’ll connect that to the UI with the following code. This replaces the `