diff --git a/docs/README.md b/docs/README.md index 787392e19..dc9d25004 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,27 +1 @@ -# Tutorials - -**Note: This data is being digested by blockstack.org. Do not change the formatting of this list unless you first make an adjustment to the code on blockstack.org.** - -### Multi-player Storage - -- urlSlug: multi-player-storage -- image: /images/tutorials/multi-player-storage.png -- description: Build a decentralized micro-blogging app using multi-player Gaia storage. - -### Managing Data with Gaia - -- urlSlug: managing-data-with-gaia -- image: /images/tutorials/managing-data-with-gaia.png -- description: This series will focus on teaching you to think like a Blockstack developer working with Gaia. - -### Blockstack Todo - -- urlSlug: todo-list -- image: /images/tutorials/todo-list.png -- description: Walk through creating a basic Todo application with Blockstack. Learn about Sign In flow and Gaia storage. - -### Hello Blockstack - -- urlSlug: hello-blockstack -- image: /images/tutorials/hello-blockstack.jpg -- description: Build a simple single-page JavaScript application that runs completely client-side without any servers. +Documentation for the browser can be found online here: https://docs.blockstack.org/browser/browser-introduction.html \ No newline at end of file diff --git a/docs/blockstack_storage.md b/docs/blockstack_storage.md deleted file mode 100644 index 8fa411cb4..000000000 --- a/docs/blockstack_storage.md +++ /dev/null @@ -1,812 +0,0 @@ ---- -layout: learn -permalink: /:collection/:path.html ---- -# Blockstack Storage Tutorial -{:.no_toc} - -In this tutorial, you build a micro-blogging application using multi-player Gaia -storage. Gaia is Blockstack's [decentralized high-performance storage -system](https://github.com/blockstack/gaia). The tutorial contains the following -topics: - -* TOC -{:toc} - -This tutorial does not teach you about authentication. That is covered in depth [in the hello-blockstack tutorial](hello-blockstack). - - - - -## About this tutorial and the prerequisites you need - -At minimum, Blockstack requires macOS High Sierra. This tutorial was written for -a user running macOS High Sierra 10.13.4. The application you build is a -React.js application that is completely decentralized and server-less. While -not strictly required to follow along, basic familiarity with React.js is -helpful. - -When complete, the app is capable of the following: - -- authenticating users using Blockstack -- posting new statuses -- displaying statuses in the user profile -- looking up the profiles and statuses of other users - -The basic identity and storage services are provided by `blockstack.js`. To test -the application, you need to have already [registered a Blockstack ID](ids-introduction). - -The tutorial relies on the `npm` dependency manager. Before you begin, verify -you have installed `npm` using the `which` command. - -```bash -$ which npm -/usr/local/bin/npm -``` - -If you don't find `npm` in your system, [install -it](https://www.npmjs.com/get-npm). Finally, if you get stuck at any point -while working on the tutorial, the completed [source code is available for -you](https://github.com/larrysalibra/publik) to check your work against. - -## Use npm to install Yeoman and the Blockstack App Generator - -You use `npm` to install Yeoman. Yeoman is a generic scaffolding system that -helps users rapidly start new projects and streamline the maintenance of -existing projects. - - -1. Install Yeoman. - - ```bash - npm install -g yo - ``` -2. Install the Blockstack application generator. - - ```bash - npm install -g generator-blockstack - ``` - - - -## Generate and launch the public application - -In this section, you build an initial React.js application called Publik. - -1. Create a the `publik` directory. - - ```bash - mkdir publik - ``` - -2. Change into your new directory. - - ```bash - cd publik - ``` - -3. Use Yeoman and the Blockstack application generator to create your initial `publik` application. - - ```bash - yo blockstack:react - ``` - - You should see several interactive prompts. - - ```bash - $ yo blockstack:react - ? ========================================================================== - We're constantly looking for ways to make yo better! - May we anonymously report usage statistics to improve the tool over time? - More info: https://github.com/yeoman/insight & http://yeoman.io - ========================================================================== No - - _-----_ ╭──────────────────────────╮ - | | │ Welcome to the │ - |--(o)--| │ Blockstack app │ - `---------´ │ generator! │ - ( _´U`_ ) ╰──────────────────────────╯ - /___A___\ / - | ~ | - __'.___.'__ - ´ ` |° ´ Y ` - - ? Are you ready to build a Blockstack app in React? (Y/n) - ``` - -4. Respond to the prompts to populate the initial app. - - After the process completes successfully, you see a prompt similar to the following: - - ```bash - [fsevents] Success: - "/Users/theuser/repos/publik/node_modules/fsevents/lib/binding/Release/node-v59-darwin-x64/fse.node" - is installed via remote npm notice created a lockfile as package-lock.json. - You should commit this file. added 1060 packages in 26.901s - ``` - -5. Run the initial application. - - ```bash - npm start - ``` - - The system prompts you to accept incoming connections. - - ![Network Connection](./images/network-connections.gif) - -6. Choose **Allow**. - -7. Open your browser to `http://localhost:8080`. - - You should see a simple React app. - - ![](images/initial-app.gif) - -8. Choose **Sign In with Blockstack**. - - The application tells you it will **Read your basic info**. - - ![](images/login.png) - -Leave your new application running and move onto the next section. - -## Add the `publish_data` scope to sign in requests - -Every app that uses Gaia storage must add itself to the user's `profile.json` -file. The Blockstack browser does this automatically when the `publish_data` -scope is requested during authentication. For this application, the user files -stored on Gaia are made visible to others via the `apps` property in the user's -`profile.json` file. - -Modify your authentication request to include the `publish_data` scope. - -1. Open `src/components/App.jsx` file. - -2. Locate the `handleSignIn` handler method. - - ```javascript - handleSignIn(e) { - e.preventDefault(); - redirectToSignIn(); - } - ``` - -2. Modify the method to this: - - ```javascript - handleSignIn(e) { - e.preventDefault(); - const origin = window.location.origin - redirectToSignIn(origin, origin + '/manifest.json', ['store_write', 'publish_data']) - } - ``` - - By default, authentication requests include the `store_write` scope which - enables storage. This is what allows you to store information to Gaia. - -3. Save your changes. -4. Go back to your app at `http://localhost:8080/`. -5. Log out and sign in again. - - The authentication request now prompts the user for permission to **Publish - data stored for the app**. - - ![](images/publish-data-perm.png) - -## Understand Gaia storage methods - -Once you authenticate a user with `store_write` and `publish_data`, you can -begin to manage data for your users. Blockstack JS provides two methods -`getFile()` and `putFile()` for interacting with Gaia storage. The storage -methods support all file types. This means you can store SQL, Markdown, JSON, or -even a custom format. - -You can create a meaningful and complex data layer using these two methods. -Before creating an application, consider fundamental data architecture and make -some decisions about how you’re modeling data. For example, consider building a -simple grocery list app. A user should be able to create, read, update, and -delete grocery lists. - -A single file collection stores items as an array nested inside each grocery -list: - -```js -// grocerylists.json -{ - "3255": { - "items": [ - "1 Head of Lettuce", - "Haralson apples" - ] - }, - // ...more lists with items -} -``` - -This is conceptually the simplest way to manage grocery lists. When you read a -`/grocerylists.json` file with `getFile()`, you get back one or more grocery -lists and their items. When you write a single list, the `putFile()` method -overwrites the entire list. So, a write operation for a new or updated grocery -list must submit all existings lists as well. - -Further, because this runs on the client where anything can go wrong. If the -client-side code encounters a parsing error with a user-input value and you -could overwrite the entire file with: - -`line 6: Parsing Error: Unexpected token.` - -Further, a single file makes pagination impossible and if your app stores a -single file for all list you have less control over file permissions. To avoid -these issues, you can create an index file that stores an array of IDs. These -IDs point to a name of another file in a `grocerylists` folder. - -![](images/multiple-lists.png) - -This design allows you to get only the files you need and avoid accidentally -overwriting all lists. Further, you’re only updating the index file when you add -or remove a grocery list; updating a list has no impact. - - -## Add support for user status submission and lookup - -In this step, you add three `blockstack.js` methods that support posting of "statuses". These are the `putFile()`, `getFile()`, and `lookupProfile()` methods. - -1. Open the `src/components/Profile.jsx` file. - -2. Expand the `import from blockstack` statement with data methods. - - The `Person` object holds a Blockstack profile. Add `putFile`, `getFile`, - and `lookupProfile` after `Person`. - - When you are done, the import statement should look like the following: - - ```javascript - import { - isSignInPending, - loadUserData, - Person, - getFile, - putFile, - lookupProfile - } from 'blockstack'; - ``` - -3. Replace the `constructor()` initial state so that it holds the key properties required by the app. - - This code constructs a Blockstack `Person` object to hold the profile. Your constructor should look like this: - - ```javascript - constructor(props) { - super(props); - - this.state = { - person: { - name() { - return 'Anonymous'; - }, - avatarUrl() { - return avatarFallbackImage; - }, - }, - username: "", - newStatus: "", - statuses: [], - statusIndex: 0, - isLoading: false - }; - } - ``` - - -4. Locate the `render()` method. -5. Modify the `render()` method to add a text input and submit button to the application. - - The following code echos the `person.name` and `person.avatarURL` - properties from the profile on the display: - - ```javascript - render() { - const { handleSignOut } = this.props; - const { person } = this.state; - const { username } = this.state; - - return ( - !isSignInPending() && person ? -
-
-
-
-
- -
-

- { person.name() ? person.name() - : 'Nameless Person' } -

- {username} - -  |  - (Logout) - -
-
-
- -
-
-