Browse Source

WIP

Signed-off-by: moxiegirl <mary@blockstack.com>
feat/clarity-updates
moxiegirl 6 years ago
parent
commit
17fb737c9f
  1. 5
      _common/core_ref.md
  2. 8
      _common/glossary.md
  3. 5
      _common/javascript_ref.md
  4. 8
      _config.yml
  5. 6
      _data/navigation_auth.yml
  6. 20
      _data/navigation_bns.yml
  7. 0
      _data/navigation_general.yml
  8. 4
      _data/navigation_home.yml
  9. 9
      _data/navigation_learn.yml
  10. 4
      _data/navigation_newinternet.yml
  11. 4
      _data/navigation_usenew.yml
  12. 0
      _includes/related-usenew.html
  13. 2
      _layouts/externalurl.html
  14. 2
      _layouts/general.html
  15. 8
      _layouts/learn.html
  16. 4
      _layouts/usenew.html
  17. 1
      _newinternet/.svn/entries
  18. 1
      _newinternet/.svn/format
  19. BIN
      _newinternet/.svn/pristine/04/04f3a32b0bc311047a20e12c72428e50812cdbd9.svn-base
  20. 820
      _newinternet/.svn/pristine/06/06ac8c280c67cb7b75009090ad026cd0b9ee02f1.svn-base
  21. BIN
      _newinternet/.svn/pristine/08/085c1a3260d4d04fcd82252787ba093d06446210.svn-base
  22. BIN
      _newinternet/.svn/pristine/12/1284f902d27c0fdb01787c315fa61ee525538d65.svn-base
  23. BIN
      _newinternet/.svn/pristine/28/28885ce546124804666f1c735f1fb916582a1a98.svn-base
  24. 160
      _newinternet/.svn/pristine/2c/2c449d55764fd5c58aa58d0545b65bf56d987f45.svn-base
  25. BIN
      _newinternet/.svn/pristine/2c/2cb66479d94646ba1c3c651f26dbd9683e929114.svn-base
  26. BIN
      _newinternet/.svn/pristine/2e/2e837afccc4a402a90dc0b7e580109e49e3252e2.svn-base
  27. BIN
      _newinternet/.svn/pristine/2f/2f00af279deecacd5b47bdc32a0106e23b2a2f64.svn-base
  28. 294
      _newinternet/.svn/pristine/2f/2faca6601417cdd2ab9ddb70cf3d9a9c0170e27b.svn-base
  29. BIN
      _newinternet/.svn/pristine/30/30473db14d0ed5ac772c32ab2e89375faa2b0133.svn-base
  30. 27
      _newinternet/.svn/pristine/30/30e89a5d274e5137e687939f31ca471aea7462a3.svn-base
  31. BIN
      _newinternet/.svn/pristine/33/33f4fbc3c99fe5df9c5eb23cc4aaf25165722419.svn-base
  32. BIN
      _newinternet/.svn/pristine/37/373b7d67a3d5c2de4723fcd45470854cf0c5ca6e.svn-base
  33. BIN
      _newinternet/.svn/pristine/3f/3f89163556affc6e77a6630136bf6897bc9ae8f6.svn-base
  34. BIN
      _newinternet/.svn/pristine/42/423c91a747d0f3570fb0d63199c9adcbe6baef1d.svn-base
  35. BIN
      _newinternet/.svn/pristine/55/5500a797259a620714f1c576c579f117982590db.svn-base
  36. 330
      _newinternet/.svn/pristine/5a/5aacc2dc2b8ec564a24b587ff0deb80671cfd910.svn-base
  37. BIN
      _newinternet/.svn/pristine/63/6326880dd17c45162090e3bb4902adefbccfcb15.svn-base
  38. BIN
      _newinternet/.svn/pristine/6c/6cf236705739b3dc1eaa714fab9bace84b283e8b.svn-base
  39. BIN
      _newinternet/.svn/pristine/7d/7d026a516855c1ccedf5ee6a2fe63126d09c8e26.svn-base
  40. BIN
      _newinternet/.svn/pristine/7e/7e40e7b1ee5b4f12d441e53a6ab89e94ad1fca90.svn-base
  41. BIN
      _newinternet/.svn/pristine/85/85996c7ad7783aa09fc9583b4befe746d24be5e5.svn-base
  42. BIN
      _newinternet/.svn/pristine/88/880a628c402d072057a35178bbbc13b8437c46bb.svn-base
  43. BIN
      _newinternet/.svn/pristine/89/8917230875187dc926ba9f5a9a86e781975585ad.svn-base
  44. BIN
      _newinternet/.svn/pristine/8e/8e3163bec841bf2fb8cc6ecbbf49f02e64b1e2d8.svn-base
  45. BIN
      _newinternet/.svn/pristine/94/9400d6428e2bb287e9c7385bedb6ee563f5829d0.svn-base
  46. BIN
      _newinternet/.svn/pristine/a3/a388e8949737a271d80b69b8dfcf48d77dddb890.svn-base
  47. BIN
      _newinternet/.svn/pristine/a8/a8348770072ebc93d3d6669efb8fb2225bbb39de.svn-base
  48. BIN
      _newinternet/.svn/pristine/b0/b0150507ba3e8a583e83ad2c29256231c8b58373.svn-base
  49. BIN
      _newinternet/.svn/pristine/b7/b719720c84e885f3d96f0c0b14534214d6683f18.svn-base
  50. BIN
      _newinternet/.svn/pristine/b9/b974564d6e487b3c718c87a3c3fa821b4ac3d833.svn-base
  51. 201
      _newinternet/.svn/pristine/bb/bb14c6df95533e53360cb280946fd54d65e88a8f.svn-base
  52. BIN
      _newinternet/.svn/pristine/bf/bfa77ea6b63530fb7273cc51c462f37d9479a75b.svn-base
  53. BIN
      _newinternet/.svn/pristine/ca/ca6de58cdaf847ead67cc9893c73b040cdd6fb08.svn-base
  54. BIN
      _newinternet/.svn/pristine/d0/d085d6df138e87cfea31a57a1e732327fbe01244.svn-base
  55. BIN
      _newinternet/.svn/pristine/d6/d6e6a8f19612c2353e5ff02ac49dc06762f7127c.svn-base
  56. BIN
      _newinternet/.svn/pristine/db/db11f02ca2f4fd6473c082112db7fd86c19d2039.svn-base
  57. BIN
      _newinternet/.svn/pristine/eb/ebb5e5f52918709d42ea6cbba0df6b008039e281.svn-base
  58. BIN
      _newinternet/.svn/pristine/ec/ec3db3fa698c68b7eb55535729ca0bf5306d33ba.svn-base
  59. 328
      _newinternet/.svn/pristine/ee/eef5a5c80676898fe5a63a3a5e1700a2c73f2b0d.svn-base
  60. BIN
      _newinternet/.svn/pristine/f1/f110c7b263eda5b8f71f1426dd9829625a5b1b31.svn-base
  61. BIN
      _newinternet/.svn/pristine/f2/f2da2a06b1ae6cece6cb9389f80dd5bb11cd7a98.svn-base
  62. BIN
      _newinternet/.svn/pristine/f7/f7d8196207101d3fd6bf9efa91cb074dcbea011d.svn-base
  63. 161
      _newinternet/.svn/pristine/f8/f81e6e4308c1f49f6ddca9caf4b065ca60bc6726.svn-base
  64. BIN
      _newinternet/.svn/pristine/fe/feb47456df368ff71ac8c50b94702abec6bf2619.svn-base
  65. BIN
      _newinternet/.svn/pristine/ff/ff4ec7f9dcc8b70af2d527b508b30c47a5386514.svn-base
  66. BIN
      _newinternet/.svn/wc.db
  67. 0
      _newinternet/.svn/wc.db-journal
  68. 27
      _newinternet/README.md
  69. 289
      _newinternet/browser-introduction.md
  70. 160
      _newinternet/cli-basics.md
  71. 333
      _newinternet/hello-blockstack.md
  72. 210
      _newinternet/ids-introduction.md
  73. 161
      _newinternet/managing-data-with-gaia.md
  74. 812
      _newinternet/multi-player-storage.md
  75. 328
      _newinternet/todo-list.md
  76. 62
      _plugins/include_absolute.rb
  77. 101
      _site/android/tutorial.html
  78. 29
      _site/browser/README.md
  79. 123
      _site/browser/browser-introduction.html
  80. 80
      _site/browser/dependencies.md
  81. 46
      _site/browser/design.md
  82. 429
      _site/browser/faq_general.html
  83. 99
      _site/browser/hello-blockstack.html
  84. 71
      _site/browser/hosted_browser.md
  85. 73
      _site/browser/ids-introduction.html
  86. 0
      _site/browser/images/blockstack-bar.png
  87. 0
      _site/browser/images/browser-on-mac-1.png
  88. 0
      _site/browser/images/browser-on-mac.png
  89. 0
      _site/browser/images/browser-uninstall.png
  90. 0
      _site/browser/images/create-id-0.png
  91. 0
      _site/browser/images/create-id-1.png
  92. 0
      _site/browser/images/create-id-2.png
  93. 0
      _site/browser/images/create-id-3.png
  94. 0
      _site/browser/images/display-complete.png
  95. 0
      _site/browser/images/dmg-notice.png
  96. 0
      _site/browser/images/eject-blockstack.png
  97. 0
      _site/browser/images/hw-loggedin.png
  98. 0
      _site/browser/images/initial-app.gif
  99. 0
      _site/browser/images/login-choice.png
  100. 0
      _site/browser/images/login-no-auth.png

5
_common/core_ref.md

@ -0,0 +1,5 @@
---
layout: externalurl
redirect_url: https://core.blockstack.org/
title: "Blockstack CORE API"
---

8
_site/core/glossary.md → _common/glossary.md

@ -55,6 +55,10 @@ bound to a blockchain transaction. This includes all data stored in the Atlas
network (such as your Blockstack ID's zone file),
as well as any data whose hash is stored in the Atlas network.
## mnemonic
A human-friendly representation of a seed.
## Mutable Data
This is the general term for data that is (1) signed by your Blockstack ID, and
@ -108,6 +112,10 @@ An online service that lets you sign up for and manage the profiles of Blockstac
An online service that displays zonefile and profile data for a Blockstack ID. [The Blockstack Explorer](https://explorer.blockstack.org) is a resolver.
## Seed
A 128 or 256 bits of random data used to generate a master public and privte key pair.
## Social proof
A post in an account on an existing Web service like Twitter, Facebook, or GitHub that points back to a Blockstack ID. Used to provide some evidence that the person who owns the Blockstack ID is also the person who owns the Web service account.

5
_common/javascript_ref.md

@ -0,0 +1,5 @@
---
layout: externalurl
redirect_url: https://blockstack.github.io/blockstack.js/
title: "Blockstack Javascript Reference"
---

8
_config.yml

@ -108,6 +108,8 @@ exclude:
- THEME_README.md
- collections.json
- get-content.sh
- _core/aglio_templates
- _core/attic
sass:
style: compressed
@ -131,9 +133,9 @@ collections:
browser:
output: true
basepath: "blockstack/blockstack-browser/blob/master/docs"
newinternet:
output: true
basepath: "moxiegirl/docs-new/blob/master/docs"
ios:
output: true
basepath: "blockstack/blockstack-ios/blob/master/docs"
common:
output: true
basepath: "moxiegirl/docs.blockstack"

6
_data/navigation_auth.yml

@ -1,4 +1,4 @@
- docs:
- core/auth/overview
- core/auth/howitworks
- core/auth/howtouse
- core/atlas/overview
- core/atlas/howitworks
- core/atlas/howtouse

20
_data/navigation_bns.yml

@ -3,11 +3,14 @@
- core/naming/introduction
- core/naming/architecture
- core/naming/namespaces
- core/naming/comparison
- title: Tutorials
- title: Tutorials & Cookbooks
docs:
- core/naming/tutorial_creation
- core/naming/tutorial_subdomains
- core/naming/search
- core/naming/openbazaar
- title: How to use BNS
@ -19,8 +22,19 @@
- core/naming/manage
- core/naming/subdomains
- title: Other topics
- title: Forks and Dids
docs:
- core/naming/forks
- core/naming/did
- core/naming/comparison
- title: Atlas
docs:
- core/atlas/overview
- core/atlas/howitworks
- core/atlas/howtouse
- title: Reference
docs:
- common/javascript_ref
- common/core_ref
- core/faq_technical

0
_data/navigation_docs.yml → _data/navigation_general.yml

4
_data/navigation_home.yml

@ -8,7 +8,7 @@
- title: Use the New Internet
desc: Learn about the New Internet and its applications. Create an identity and learn how to use it.
icon: settings
doc: newinternet/browser-introduction
doc: browser/browser-introduction
- title: Build Apps and Earn Money
desc: Learn how to build an application that earns with Blockstack.
@ -23,7 +23,7 @@
- title: Implement Authentication
desc: Managing your account, creating new users and exporting data
icon: cog
doc: core/auth/overview
doc: core/atlas/overview
- title: Implement Storage with GAIA
desc: Backend storage drivers and interactions between developer APIs and the Gaia service.

9
_data/navigation_learn.yml

@ -1,9 +1,14 @@
- title: Try a tutorial
docs:
- newinternet/hello-blockstack
- newinternet/multi-player-storage
- browser/hello-blockstack
- browser/multi-player-storage
- title: Work with an SDK
docs:
- android/tutorial
- ios/tutorial
- title: Reference
docs:
- core/faq_developer
- common/javascript_ref

4
_data/navigation_newinternet.yml

@ -1,4 +0,0 @@
- title: Get started
docs:
- newinternet/browser-introduction
- newinternet/ids-introduction

4
_data/navigation_usenew.yml

@ -0,0 +1,4 @@
- docs:
- browser/ids-introduction
- browser/browser-introduction
- browser/faq_general

0
_includes/related-newinternet.html → _includes/related-usenew.html

2
_layouts/externalurl.html

@ -0,0 +1,2 @@
<title>{{page.title}}</title>
<meta http-equiv="refresh" content="0; url={{ page.redirect_url }}">

2
_layouts/doc.html → _layouts/general.html

@ -8,7 +8,7 @@ layout: default
<div class="sidebar-fixed-width uk-visible@m">
<div class="sidebar-docs uk-position-fixed">
{% for section in site.data.navigation_docs %}
{% for section in site.data.navigation_general %}
<h5>{{ section.title }}</h5>
<ul class="uk-nav uk-nav-default doc-nav">
{% for doc in section.docs %}

8
_layouts/learn.html

@ -8,8 +8,11 @@ layout: default
<div class="sidebar-fixed-width uk-visible@m">
<div class="sidebar-docs uk-position-fixed">
<!-- -->
{% for section in site.data.navigation_learn %}
{% if section.title %}
<h5>{{ section.title }}</h5>
{% endif %}
<ul class="uk-nav uk-nav-default doc-nav">
{% for doc in section.docs %}
{% assign doc_url = doc | prepend:"/" | append:".html" %}
@ -27,6 +30,7 @@ layout: default
{% endfor %}
</ul>
{% endfor %}
<!-- -->
</div>
</div>
@ -38,6 +42,7 @@ layout: default
{% if page.subtitle %}<p class="subtitle uk-text-lead uk-text-muted">{{ page.subtitle }}</p>{% endif %}
<div class="uk-article-meta uk-margin-top uk-margin-medium-bottom">
{% include post-meta.html %}
</div>
@ -51,9 +56,8 @@ layout: default
{% include paginate-doc.html %}
{% include related-learn.html %}
<!-- {% include related-learn.html %} -->
{% if site.disqus.shortname %} {% include disqus_comments.html %} {% endif %}
</article>
<script>

4
_layouts/newinternet.html → _layouts/usenew.html

@ -9,7 +9,7 @@ layout: default
<div class="sidebar-fixed-width uk-visible@m">
<div class="sidebar-docs uk-position-fixed">
<!-- -->
{% for section in site.data.navigation_newinternet %}
{% for section in site.data.navigation_usenew %}
{% if section.title %}
<h5>{{ section.title }}</h5>
{% endif %}
@ -56,7 +56,7 @@ layout: default
{% include paginate-doc.html %}
<!-- {% include related-auth.html %} -->
<!-- {% include related-usenew.html %} -->
</article>

1
_newinternet/.svn/entries

@ -1 +0,0 @@
12

1
_newinternet/.svn/format

@ -1 +0,0 @@
12

BIN
_newinternet/.svn/pristine/04/04f3a32b0bc311047a20e12c72428e50812cdbd9.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

820
_newinternet/.svn/pristine/06/06ac8c280c67cb7b75009090ad026cd0b9ee02f1.svn-base

@ -1,820 +0,0 @@
---
title: Multi-player Storage Tutorial
description: Build a decentralized micro-blogging app using multi-player storage in Gaia.
image: /images/tutorials/multi-player-storage.png
youtube: https://www.youtube.com/embed/w7Sa54H-CGg
---
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:
- [About this tutorial and the prerequisites you need](#about-this-tutorial-and-the-prerequisites-you-need)
- [Use npm to install Yeoman and the Blockstack App Generator](#use-npm-to-install-yeoman-and-the-blockstack-app-generator)
- [Generate and launch the public application](#generate-and-launch-the-public-application)
- [Add the `publish_data` scope to sign in requests](#add-the-publishdata-scope-to-sign-in-requests)
- [Allow the user to submit a status](#allow-the-user-to-submit-a-status)
- [Fetch and display statuses](#fetch-and-display-statuses)
- [Lookup user profiles](#lookup-user-profiles)
- [Add a new route](#add-a-new-route)
- [Add a rule to process URL paths with . (dot)](#add-a-rule-to-process-url-paths-with-dot)
- [Put it all together](#put-it-all-together)
- [Wrapping up](#wrapping-up)
This tutorial does not teach you about authentication. That is covered in depth [in the hello-blockstack tutorial](hello-blockstack.md).
<!--TODO: authentication tutorial-->
<!--Strictly speaking not sure it is necessary here to send them out-->
## 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.md).
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
```
<!-- Need to find out if user is required to have React installed before running Yeoman. Doesn't appear to be the case. -->
## 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 ?
<div className="container">
<div className="row">
<div className="col-md-offset-3 col-md-6">
<div className="col-md-12">
<div className="avatar-section">
<img
src={ person.avatarUrl() ? person.avatarUrl() : avatarFallbackImage }
className="img-rounded avatar"
id="avatar-image"
/>
<div className="username">
<h1>
<span id="heading-name">{ person.name() ? person.name()
: 'Nameless Person' }</span>
</h1>
<span>{username}</span>
<span>
&nbsp;|&nbsp;
<a onClick={ handleSignOut.bind(this) }>(Logout)</a>
</span>
</div>
</div>
</div>
<div className="new-status">
<div className="col-md-12">
<textarea className="input-status"
value={this.state.newStatus}
onChange={e => this.handleNewStatusChange(e)}
placeholder="Enter a status"
/>
</div>
<div className="col-md-12">
<button
className="btn btn-primary btn-lg"
onClick={e => this.handleNewStatusSubmit(e)}
>
Submit
</button>
</div>
</div>
</div>
</div>
</div> : null
);
}
```
This code allows the application to post statuses. It also displays the
user's Blockstack ID. To display this, your app must extract the ID from the
user profile data.
6. Locate the `componentWillMount()` method.
7. Add the `username` property below the `person` property.
You'll use the Blockstack `loadUserData()` method to access the `username`.
```javascript
componentWillMount() {
this.setState({
person: new Person(loadUserData().profile),
username: loadUserData().username
});
}
```
7. Add two methods to handle the status input events:
```javascript
handleNewStatusChange(event) {
this.setState({newStatus: event.target.value})
}
handleNewStatusSubmit(event) {
this.saveNewStatus(this.state.newStatus)
this.setState({
newStatus: ""
})
}
```
8. Add a `saveNewStatus()` method to save the new statuses.
```javascript
saveNewStatus(statusText) {
let statuses = this.state.statuses
let status = {
id: this.state.statusIndex++,
text: statusText.trim(),
created_at: Date.now()
}
statuses.unshift(status)
const options = { encrypt: false }
putFile('statuses.json', JSON.stringify(statuses), options)
.then(() => {
this.setState({
statuses: statuses
})
})
}
```
9. Save the `Profile.jsk` file.
After the application compiles successfully, your application should appears as follows:
![](images/display-complete.png)
10. Enter your status in the text box and press the **Submit** button.
At this point, nothing is blogged. In the next section you add code to display
the statuses back to the user as a blog entry.
## Fetch and display statuses
Update `Profile.jsx` again.
1. Go back to the `render()` method.
2. Locate the `<div className="new-status">` containing the text input and **Submit** button.
3. Right after this opening `div` element, add this block.
```javascript
<div className="col-md-12 statuses">
{this.state.isLoading && <span>Loading...</span>}
{this.state.statuses.map((status) => (
<div className="status" key={status.id}>
{status.text}
</div>
)
)}
</div>
```
This loads existing state. Your code needs to fetch statuses on page load.
4. Add a new method called `fetchData()` after the `statuses.unshift(status)` section.
```javascript
fetchData() {
this.setState({ isLoading: true })
const options = { decrypt: false }
getFile('statuses.json', options)
.then((file) => {
var statuses = JSON.parse(file || '[]')
this.setState({
person: new Person(loadUserData().profile),
username: loadUserData().username,
statusIndex: statuses.length,
statuses: statuses,
})
})
.finally(() => {
this.setState({ isLoading: false })
})
}
```
5. Call `fetchData()` from the `componentDidMount()` method
```javascript
componentDidMount() {
this.fetchData()
}
```
6. Save the file.
After the application compiles successfully, users are able to **Submit**
multiple statuses and review them in the app.
![](images/saving-status.png)
## Change the style
1. Edit the `src/styles/style.css` file.
2. Replace the content with the following:
```css
/* Globals */
a,a:focus,a:hover{color:#fff;}
html,body{height:100%;text-align:center;background-color:#191b22;}
body{color:#fff}
.hide{display:none;}
.landing-heading{font-family:'Lato',Sans-Serif;font-weight:400;}
/* Buttons */
.btn{font-family:'Lato',Sans-Serif;padding:0.5625rem 2.5rem;font-size:0.8125rem;font-weight:400;line-height:1.75rem;border-radius:0!important;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}
.btn-lg{font-size:1.5rem;padding:0.6875rem 3.4375rem;line-height:2.5rem;}
.btn:focus,.btn:active:focus,.btn.active:focus{outline:none;}
.btn-primary{color:#fff;border:1px solid #2C96FF;background-color:#2C96FF;}
.btn-primary:hover,.btn-primary:focus,.btn-primary:active{color:#fff;border:1px solid #1a6ec0;background-color:#1a6ec0;}
/* Avatar */
.avatar{width:100px;height:100px;}
.avatar-section{margin-bottom:25px;display:flex;text-align:left;}
.username{margin-left:20px;}
/* Scaffolding */
.site-wrapper{display:table;width:100%;height:100vh;min-height:100%;}
.site-wrapper-inner{display:flex;flex-direction:column;justify-content:center;margin-right:auto;margin-left:auto;width:100%;height:100vh;}
.panel-authed{padding:0 0 0 0;}
/* Home button */
.btn-home-hello{position:absolute;font-family:'Source Code Pro',monospace;font-size:11px;font-weight:400;color:rgba(255,255,255,0.85);top:15px;left:15px;padding:3px 20px;background-color:rgba(255,255,255,0.15);border-radius:6px;-webkit-box-shadow:0px 0px 20px 0px rgba(0,0,0,0.15);-moz-box-shadow:0px 0px 20px 0px rgba(0,0,0,0.15);box-shadow:0px 0px 20px 0px rgba(0,0,0,0.15);}
/* Input */
input, textarea{color:#000;padding:10px;}
.input-status{width:100%;height:70px;border-radius:6px;}
.new-status{text-align:right;}
/* Statuses */
.statuses{padding-top:30px;}
.status{margin:15px 0px;padding:20px;background-color:#2e2e2e;border-radius:6px}
```
3. Save and close the `src/styles/style.css` file.
After the application compiles, you should see the following:
![Multi-reader storage authentication](/images/multi-player-storage-status.png)
At this point, you have a basic micro-blogging app that users can use to post and
view statuses. However, there's no way to view other users' statuses. You'll add
that in the next section.
## Lookup user profiles
Let's now modify the `Profile.jsx` file to display profiles of other users. You'll
be using the `lookupProfile()` method that you added to the `import` statement
earlier. `lookupProfile()` takes a single parameter that is the Blockstack ID of
the profile and returns a profile object.
### Add a new route
Make some changes to the routing structure of your app so that users can view
other users' profiles by visiting `http://localhost:8080/other_user.id`
1. Make sure you are in the root of your `publik` project.
2. Install `react-router`:
```bash
npm install --save react-router-dom
```
3. Edit `src/index.js` file.
4. Add an `import` to the file at the top:
```javascript
import { BrowserRouter } from 'react-router-dom'
```
5. Change the `ReactDOM.render()` method in `src/index.js` to:
```javascript
ReactDOM.render((
<BrowserRouter>
<App />
</BrowserRouter>
), document.getElementById('root'));
```
6. Save and close the `src/index.js` file.
7. Edit the `src/components/App.jsx` file.
8. Add the new route by importing the `Switch` and `Route` components from `react-router-dom`:
```javascript
import { Switch, Route } from 'react-router-dom'
```
9. Locate this line below in the `render()` method:
```javascript
: <Profile handleSignOut={ this.handleSignOut } />
```
10. Replace it with the following:
```javascript
:
<Switch>
<Route
path='/:username?'
render={
routeProps => <Profile handleSignOut={ this.handleSignOut } {...routeProps} />
}
/>
</Switch>
```
This sets up a route and captures the route parameter the app will use as the profile lookup username.
11. Save and close the the `src/components/App.jsx` file.
### Add a rule to process URL paths with . (dot)
You also need to add a rule to your webpack config so that you can properly
process URL paths that contain the `.` (dot) character for example,
`http://localhost:8080/other_user.id`
**NOTE**: In a production app, you must ensure the web server is configured to handle this.
1. Open `webpack.config.js` in the root project directory and locate the following line:
```javascript
historyApiFallback: true,
```
2. Replace it with this:
```javascript
historyApiFallback: {
disableDotRule: true
},
```
You will need to run `npm start` again for this change to take effect. Don't
worry, there is a later step for that to remind you.
3. Save and close the `webpack.config.js` file.
4. Edit the `src/components/Profile.jsx` file.
5. Add a single method that determines if the app is viewing the local user's profile or another user's profile.
```javascript
isLocal() {
return this.props.match.params.username ? false : true
}
```
You use `isLocal()` to check if the user is viewing the local user profile or another user's profile. If it's the local user profile, the app runs the `getFile()` function you added in an earlier step. Otherwise, the app looks up the profile belonging to the `username` using the `lookupProfile()` method.
6. Modify the `fetchData()` method like so:
```javascript
fetchData() {
this.setState({ isLoading: true })
if (this.isLocal()) {
const options = { decrypt: false }
getFile('statuses.json', options)
.then((file) => {
var statuses = JSON.parse(file || '[]')
this.setState({
person: new Person(loadUserData().profile),
username: loadUserData().username,
statusIndex: statuses.length,
statuses: statuses,
})
})
.finally(() => {
this.setState({ isLoading: false })
})
} else {
const username = this.props.match.params.username
lookupProfile(username)
.then((profile) => {
this.setState({
person: new Person(profile),
username: username
})
})
.catch((error) => {
console.log('could not resolve profile')
})
}
}
```
**NOTE**: For `https` deployments, the default Blockstack Core API endpoint for name
lookups should be changed to point to a core API served over `https`.
Otherwise, name lookups fail due to browsers blocking mixed content.
Refer to the [Blockstack.js
documentation](http://blockstack.github.io/blockstack.js/#getfile) for
details.
7. Add the following block to `fetchData()` right after the call to `lookupProfile(username)... catch((error)=>{..}` block:
```javascript
const options = { username: username, decrypt: false }
getFile('statuses.json', options)
.then((file) => {
var statuses = JSON.parse(file || '[]')
this.setState({
statusIndex: statuses.length,
statuses: statuses
})
})
.catch((error) => {
console.log('could not fetch statuses')
})
.finally(() => {
this.setState({ isLoading: false })
})
```
This fetches the user statuses.
Finally, you must conditionally render the logout button, status input textbox, and submit button so they don't show up when viewing another user's profile.
8. Replace the `render()` method with the following:
```javascript
render() {
const { handleSignOut } = this.props;
const { person } = this.state;
const { username } = this.state;
return (
!isSignInPending() && person ?
<div className="container">
<div className="row">
<div className="col-md-offset-3 col-md-6">
<div className="col-md-12">
<div className="avatar-section">
<img
src={ person.avatarUrl() ? person.avatarUrl() : avatarFallbackImage }
className="img-rounded avatar"
id="avatar-image"
/>
<div className="username">
<h1>
<span id="heading-name">{ person.name() ? person.name()
: 'Nameless Person' }</span>
</h1>
<span>{username}</span>
{this.isLocal() &&
<span>
&nbsp;|&nbsp;
<a onClick={ handleSignOut.bind(this) }>(Logout)</a>
</span>
}
</div>
</div>
</div>
{this.isLocal() &&
<div className="new-status">
<div className="col-md-12">
<textarea className="input-status"
value={this.state.newStatus}
onChange={e => this.handleNewStatusChange(e)}
placeholder="What's on your mind?"
/>
</div>
<div className="col-md-12 text-right">
<button
className="btn btn-primary btn-lg"
onClick={e => this.handleNewStatusSubmit(e)}
>
Submit
</button>
</div>
</div>
}
<div className="col-md-12 statuses">
{this.state.isLoading && <span>Loading...</span>}
{this.state.statuses.map((status) => (
<div className="status" key={status.id}>
{status.text}
</div>
)
)}
</div>
</div>
</div>
</div> : null
);
}
```
### This checks to ensure that users are viewing their own profile, by wrapping the **Logout** button and inputs with the `{isLocal() && ...}` condition.
### Put it all together
1. Stop the running application by sending a CTL-C.
2. Restart the application so that the disabling of the `.` (dot) rule takes effect.
```bash
npm start
```
3. Point your browser to `http://localhost:8080/your_blockstack.id` to see the final application.
## Wrapping up
Congratulations, you are all done! We hope you've enjoyed learning a bit more
about Blockstack. To use a working version of the app go
[here](http://publik.ykliao.com).

BIN
_newinternet/.svn/pristine/08/085c1a3260d4d04fcd82252787ba093d06446210.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

BIN
_newinternet/.svn/pristine/12/1284f902d27c0fdb01787c315fa61ee525538d65.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

BIN
_newinternet/.svn/pristine/28/28885ce546124804666f1c735f1fb916582a1a98.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

160
_newinternet/.svn/pristine/2c/2c449d55764fd5c58aa58d0545b65bf56d987f45.svn-base

@ -1,160 +0,0 @@
---
title: CLI Basics
description: Walk through the basics of the command line interface, like looking up names, getting name prices, and registering names.
image: /images/article-photos/chalkboard.jpg
youtube: https://www.youtube.com/embed/GWjEGlb1aEs
---
Welcome!
In this tutorial, we're going to walk through the basics of the Blockstack command line interface.
### Lookups
Now, to perform a name lookup, run this command:
```bash
$ blockstack lookup timblee.id
```
You should get a response like this:
```
{
"profile": {
"@type": "Person",
"account": [
{
"@type": "Account",
"identifier": "timbl",
"proofType": "http",
"proofUrl": "https://gist.github.com/timbl/04e8ac7c81cd2dee2f51a5e8c672188d",
"service": "github"
},
{
"@type": "Account",
"identifier": "timberners_lee",
"proofType": "http",
"proofUrl": "https://twitter.com/timberners_lee/status/740677355950080001",
"service": "twitter"
}
],
"image": [
{
"@type": "ImageObject",
"contentUrl": "https://s3.amazonaws.com/97p/lUU.jpeg",
"name": "cover"
}
]
},
"zonefile": "$ORIGIN timblee.id\n$TTL 3600\n_http._tcp URI 10 1 \"https://blockstack.s3.amazonaws.com/timblee.id\"\n"
}
```
### Price Estimations
Every name costs a certain amount of money to register, and each namespace has it's own name pricing rules.
As an example, in the `.id` namespace 6-letter alphabetic-only names cost 0.001 bitcoins, but with every additional letter the names get 4x cheaper and with every fewer letter the names get 4x more expensive. In addition, names without vowels and names with numbers and special characters get a special discount.
To determine how much a name will cost to order a name (including all transaction fees), use the `price` command:
```bash
$ blockstack price <YOUR NAME>.id
```
Example response:
```json
{
"name_price": {
"btc": "0.00025",
"satoshis": "25000"
},
"preorder_tx_fee": {
"btc": "0.00047406",
"satoshis": "47406"
},
"register_tx_fee": {
"btc": "0.00046184",
"satoshis": "46184"
},
"total_estimated_cost": {
"btc": "0.00188394",
"satoshis": "188394"
},
"update_tx_fee": {
"btc": "0.00069804",
"satoshis": "69804"
}
}
```
### Deposits
Name registrations and name management operations cost money, so before you can do these things, you'll need to deposit bitcoins in your account.
*Note that in some cases you'll need to wait for one or more confirmations (about 10-60 minutes) before the Blockstack CLI will register the funds as fully deposited and allow you to proceed with registering names.*
To get the Bitcoin address where you should deposit your bitcoins, run the `deposit` command:
```bash
$ blockstack deposit
```
Example response:
```json
{
"address": "13aUoeUtQnHUTfRwbksKvyvMRMzN3Qf2iR",
"message": "Send bitcoins to the address specified."
}
```
### Registrations
After you get comfortable with looking up names, take the next step and register and manage a name for yourself. Run the following command:
```bash
$ blockstack register <YOUR NAME>.id
```
If the name hasn't been registered yet, you'll get a confirmation that your registration is pending:
```json
{
"success": true,
"transaction_hash": "f576313b2ff4cc7cb0d25545e1e38e2d0d48a6ef486b7118e5ca0f8e8b98ae45",
"message": "The name has been queued up for registration and will take a few hours to go through. You can check on the status at any time by running 'blockstack info'."
}
```
After a few hours, your registration should go through and you'll be able to update your DNS records for the name.
### Updates
To update the data record associated with a name you own, run the `blockstack update` command:
```bash
$ cat > new_zone_file.txt <<EOF
\$ORIGIN swiftonsecurity.id
\$TTL 3600
pubkey TXT "pubkey:data:04cabba0b5b9a871dbaa11c044066e281c5feb57243c7d2a452f06a0d708613a46ced59f9f806e601b3353931d1e4a98d7040127f31016311050bedc0d4f1f62ff"
_file IN URI 10 1 "file:///Users/TaylorSwift/.blockstack/storage-disk/mutable/swiftonsecurity.id"
_https._tcp IN URI 10 1 "https://blockstack.s3.amazonaws.com/swiftonsecurity.id"
_http._tcp IN URI 10 1 "http://node.blockstack.org:6264/RPC2#swiftonsecurity.id"
_dht._udp IN URI 10 1 "dht+udp://fc4d9c1481a6349fe99f0e3dd7261d67b23dadc5"
EOF
$ blockstack update swiftonsecurity.id new_zone_file.txt
```
Expected response:
```json
{
"success": true,
"transaction_hash": "4e1f292c09ad8e03a5f228b589d9a7dc3699b495862bee3b40f2432ac497b134",
"message": "The name has been queued up for update and will take ~1 hour to process. You can check on the status at any time by running 'blockstack info'."
}
```

BIN
_newinternet/.svn/pristine/2c/2cb66479d94646ba1c3c651f26dbd9683e929114.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

BIN
_newinternet/.svn/pristine/2e/2e837afccc4a402a90dc0b7e580109e49e3252e2.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

BIN
_newinternet/.svn/pristine/2f/2f00af279deecacd5b47bdc32a0106e23b2a2f64.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

294
_newinternet/.svn/pristine/2f/2faca6601417cdd2ab9ddb70cf3d9a9c0170e27b.svn-base

@ -1,294 +0,0 @@
# Use the Blockstack Authenticator
The Blockstack Authenticator gives users the ability to explore and use the
decentralized applications (dapps). The decentralized applications are a new way
to interact with the internet. Dapps give users control of their data. Data
about them personally, name, birthdate, phone number and data about what they do
such as visiting a website or buying an item.
<!-- TOC depthFrom:1 depthTo:6 withLinks:1 updateOnSave:1 orderedList:0 -->
- [Use the Blockstack Authenticator](#use-the-blockstack-browser)
- [Understand the Blockstack Authenticator](#understand-the-blockstack-browser)
- [Install the client edition](#install-the-local-browser)
- [On Mac](#on-mac)
- [On Windows](#on-windows)
- [On Linux](#on-linux)
- [Uninstall the browser](#uninstall-the-browser)
- [On Mac](#on-mac)
- [On Windows](#on-windows)
- [On Linux](#on-linux)
<!-- /TOC -->
## Understand the Blockstack Authenticator
Through the Blockstack authemticator application you can create an identity. An identity
represents you as you interact with others through Dapps. The Blockstack
authenticator is itself, a smiple Dapp. It allows you to:
* create one or more identities
* send and receive bitcoin
* manage the storage of your profile and application data
* find and launch Dapps
There are editorions of the Blockstack Authenticator, the web edition is an
application you access through your web browser by simply [visit the
applications' address](https://browser.blockstack.org/) in your computer's
browser. You can also install the authenticator as a client application on your
computer.
If all you want to do is create, manage, and fund an identity and then interact
with Dapps, you can simply use the web edition. If you have concerns about net
censorship, hightened security concerns, or develop a Dapp yourself, you may
want to download and install the authenticator's client edition.
## Using the Authenticator on public computers
Before you use the web application, it is important to note that once you log
into the application with the brower, your session does not expire until you
choose **Settings > RESET BROWSER**. For this reason, you should be careful
when using the authenticator on public computers.
If you are in a library, for example, and log into the authenticator, simply
closing the tab or even rebooting the computer does not log you out. Instead,
you should be sure to choose **Settings > RESET BROWSER** before leaving the web
application.
For more informatin about your identity and the authenticator, see [Get and use a Blockstack IDs](ids-introduction.md).
## Install the client edition
Remember, for most users the Blockstack Authenticator web application should
suffice. You only need to install the client if you have additional, advanced
concerns about Internet or identity. Though not required, some Dapp developrs
may find it useful to install the client edition.
The Blockstack Authenticator installer is a _multiple-context_ installer. If you
run it as a user, the installation is avalable only for that user. If you
install as administrator, the installation installs for all users. To find an
installer for your operating system, visit [the Blockstack install
page](https://blockstack.org/install).
### On Mac
Installation requires that you have macOS High Sierra 10.12 or higher. Do the following to install:
1. Download the OSX installer from from <a href="https://blockstack.org/install" target="_blank">the browser installation page</a>.
2. Double-click the downloaded DMG file to launch the installer.
![](images/ubuntu-browser.png)
3. Drag the Blockstack.app to the `Applications` folder.
4. Double-click the Blockstack.app to launch it.
The system displays a notice about opening the file:
![](images/dmg-notice.png)
5. Choose **Open**.
The system opens your default browser with the Blockstack Authenticator
application, running from your machine (localhost). You'll also see the
Blockstack icon in your machine's
![](images/browser-on-mac.png)
If you have loaded an identity already via the Blockstack web application,
you are already logged into the local application:
![](images/browser-on-mac-1.png)
### On Windows
Installation requires that you have Windows 10 or higher. Do the following to
install:
1. Download the Windows installer from from <a href="https://blockstack.org/install" target="_blank">the browser installation page</a>.
2. Double-click the installer package to launch it.
![](images/windows-installer.png)
3. Open the Wiindows **Start** menu and click on the recently added **Blockstack Authenticator**.
![](images/windows-start.png)
The system displays a Windows Security Alert.
![](images/windows-security.png)
4. Choose to **Allow access**.
The system opens in the Blockstack Authenticator application.
![](images/windows-browser.png)
### On Linux
The Blockstack installation on Linux requires Docker. Before installing
Blockstack, <a href=“https://docs.docker.com/install/” target="_blank">install
the version of Docker appropriate for your operating system</a>.
>**Note**: The Blockstack script used in this procedure runs `docker` commands. Depending on how you installed and configure Dockered on your system, it may or may not be necessary to have `root` or `sudo` privileges. For this reason, the commands below show the use of `sudo` when interacting with the script or the `docker` executable. If your installation allows running Docker with lower privileges, you can omit it.
1. Download the Linux installer from from <a href="https://blockstack.org/install" target="_blank">the browser installation page</a>.
This downloads a `Blockstack-for-Linux-v0.30.0.sh` script to your local drive.
2. Open a terminal and navigate to the directory containing the downloaded script.
When the script downloads, it is not executable.
3. Set the executable bit on the file.
```bash
$ chmod u+x Blockstack-for-Linux-v0.309.0.0.sh
```
4. Enter the command without any arguments to see the available subcommands.
```bash
$ sudo ./Blockstack-for-Linux-v0.309.0.0.sh
blockstack docker launcher commands:
Install-protocol-handler -> install a protocol handler for blockstack:// links
...
```
5. Use the script to `pull` the Blockstack Docker images you need.
```bash
$ sudo ./Blockstack-for-Linux-v0.309.0.0.sh pull
```
Depending on your network speed, this can take some time.
7. Use the `docker image ls` command to confirm you have the image.
```bash
$ sudo docker image Is
REPOSITORY TAG IMAGE ID CREATED
quay.io/blockstack/blockstack-browser v0.30.0 ad05fd844f59 2 days ago
```
8. Install the protocol handler
```bash
$ sudo ./Blockstack-for-Linux-vO.30.0.sh install-protocol-handler

Registering protocol handler
```
9. Start the Blockstack containers.
```bash
$ sudo ./Blockstack-for-Linux-vO.30.0.sh start
c3092592e59abe3559fdb49d070a7aa5e99165c7d9f2flla20ecaf4e0dfc2f46

cd92f61ae473d54398da987f5023f5462b29c03f08584ebb3c9fIbb4cd790c69

Registering protocol handler
```
The system launches the Blockstack Authenticator application for you.
![](images/ubuntu-browser.png)
Until you stop the Blockstack containers, the application will continue to run on your system. To display the status of the Blockstack containers, you can use the `docker container ls` command.
```bash
$ sudo docker container ls --format '{{.ID}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}'
```
Use `./Blockstack-for-Linux-vO.30.0.sh stop` to stop the Blockstack Authenticator and its containers.
## Uninstall the browser
If you installed the browser using an installer, follow the instructions for
your operating system.
### On Mac
1. Quit the Blockstack application if it is running.
![](images/quit-blockstack.png)
2. Check if you have a Blockstack device and eject it if you do.
![](images/eject-blockstack.png)
3. Use the Finder to open the **Applications** folder.
4. Locate the Blockstack application.
5. Open your `Applications` folder and locate the **Blockstack.app**.
6. Drag the appliation to the trash.
7. Delete the `/Users/USERNAME/Library/Application Support/Blockstack` folder.
From the command line:
```bash
$ rm -r /Users/moxiegirl/Library/Application\ Support/Blockstack
```
### On Windows
1. Open the **Start** menu.
2. Click **Settings > System**.
3. Open for the **Apps & features** item.
![](images/eject-blockstack.png)
4. Locate the **Blockstack Authenticator** and choose **Uninstall**.
![](images/browser-uninstall.png)
### On Linux
Your Blockstack instalaltion relies on Docker containers and their associated
images. It also includes a supporting protocol handler you must remove. If you
installed Docker so that you can run Blockstack, you can uninstall Docker as well,
but that is not explained here.
Do the following to uninstall Blockstack:
1. Stop and remove the Docker containers if they are running.
```bash
$ sudo ./Blockstack-for-Linux-vO.30.0.sh stop
stopping the running blockstack-browser containers
69a686799d4f
56fc6189ff97
69a686799d4f
56fc6189ff97
```
2. Remove the associated Blockstack images.
```bash
$ sudo docker image ls
REPOSITORY TAG IMAGE ID CREATED
quay.io/blockstack/blockstack-browser v0.30.0 ad05fd844f59 3 days ago
$ sudo docker image rm ad05fd844f59

Untagged : quay.io/blockstack/blockstack- browser :vO.30.0
Untagged: quay.io/blockstack/blockstack-browser@sha256:b20c9514c56b99398fd4946af39e7537b807e85694943ac3b8807dlb3625833b
Deleted: Sha256:ad05fd844f5948blee06a0a09228df946478393c0a7588cbc65dlb8817f5b34e
Deleted: Sha256:7c3d0043f2ba01cf285f3fe09701b086c349b6380c2e42f25b31ac65c6626ec8
Deleted: sha256:54ea2aa7d7d000e7483f299eeca9e5466fa86231f4cd4cld3c3096d97e61c5df
Deleted: sha256:38e61054355adefc3c2de031462114a9946cfc0e44444a38a27d0f115aba0da2
....
```
3. Use the script to remove the protocol handler
```bash
$ sudo ./Blockstack-for-Linux-vO.30.0.sh remove-protocol-handler
```
4. Delete the script.
```bash
$ rm Blockstack-for-Linux-vO.30.0.sh
```

BIN
_newinternet/.svn/pristine/30/30473db14d0ed5ac772c32ab2e89375faa2b0133.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

27
_newinternet/.svn/pristine/30/30e89a5d274e5137e687939f31ca471aea7462a3.svn-base

@ -1,27 +0,0 @@
# 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.

BIN
_newinternet/.svn/pristine/33/33f4fbc3c99fe5df9c5eb23cc4aaf25165722419.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

BIN
_newinternet/.svn/pristine/37/373b7d67a3d5c2de4723fcd45470854cf0c5ca6e.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

BIN
_newinternet/.svn/pristine/3f/3f89163556affc6e77a6630136bf6897bc9ae8f6.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

BIN
_newinternet/.svn/pristine/42/423c91a747d0f3570fb0d63199c9adcbe6baef1d.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

BIN
_newinternet/.svn/pristine/55/5500a797259a620714f1c576c579f117982590db.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

330
_newinternet/.svn/pristine/5a/5aacc2dc2b8ec564a24b587ff0deb80671cfd910.svn-base

@ -1,330 +0,0 @@
---
title: Hello, Blockstack Tutorial
description: Tutorial on building a hello world application.
image: /images/visuals/hello-blockstack-tutorial.png
youtube: https://www.youtube.com/embed/UbZ6PlX5rF8
---
In this tutorial, you build a simple application on Blockstack. The application
is a single-page application (SPA) that runs completely client-side. The
application has no backend API to talk to, other than the identity and storage
API that the user provides. In this sense, the application is a completely
decentralized, server-less application.
For this tutorial, we will use the following tools:
- `npm` to manage dependencies and scripts
- `browserify` to compile node code into browser-ready code
- `blockstack.js` to authenticate the user and work with the user's identity/profile information
## 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.
The tutorial relies on the `npm` dependency manager. Before you begin, verify
you have installed `npm` using the `which` command to verify.
```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]() to check your work against.
Finally, make sure you have [created at least one Blockstack ID](ids-introduction.md#create-an-initial-blockstack-id). You'll use this ID to interat with the application.
## 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 an initial Blockstack application
In this section, you build an initial React.js application called `hello-world-tutorial`.
1. Create the `hello-world-tutorial` directory.
```bash
mkdir hello-world-tutorial
```
2. Change into your new directory.
```bash
cd hello-world-tutorial
```
3. Use Yeoman and the Blockstack application generator to create your initial `hello-world-tutorial` application.
```bash
yo blockstack
```
You should see several interactive prompts.
```bash
$ yo blockstack
_-----_ ╭──────────────────────────╮
| | │ 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
...
create public/icon-192x192.png
create public/index.html
create public/robots.txt
create public/manifest.json
I'm all done. Running npm install for you to install the required dependencies. If this fails, try running the command yourself.
```
Depending on your environment you may have some problems with the `npm` packages. Go ahead and fix these before continuing to the next section.
## Review the basic application structure
The initial application you create is a generic Javascript application you run
with a local express node. Before you continue, take a moment to examine the
structure of this generic application structure:
| File | Description |
|------------------|-----------------------------------|
| .editorconfig | Sets universal values for editor. |
| .gitignore | Git configuration file. |
| firebase.json | Configuragion for mobile application.|
| package.json | Specifies required packages. |
| requires.js | A Javascript module loader. |
| server.js | Simple static server configuration.|
In the `public` folder you find these files:
| File | Description |
|------------------|-----------------------------------|
| app.css | Contains application styles. |
| app.js | Main application file. |
| boostrap.min.css | Minifield css for production. |
| icon-192x192.png | Application icon |
| index.html | Single page. |
| manifest.json | Tells the browser about the application and how it should behave.|
| robots.txt | Configures crawling and indexing. |
The simple static file server in the `server.js`file serves all of the files in
the `/public` directory, including `index.html`, `app.js`, `bootstrap.min.css`
and `app.css`. The main file of the application is in the `app.js`. It contains
the majority of the application logic.
## Start the server and view the application
When you start the server, it will create a Node.js server, start it locally,
and open your browser 'http://localhost:5000'. From the root of your new application directory:
1. Start the application server.
```bash
npm start
```
The first time you run it, your system prompts you to accept incoming connections.
![Network Connection](/images/network-connections.gif)
2. Choose **Allow**.
3. Open your browser to `http://localhost:8080`.
You should see a simple application:
![](/images/initial-app.gif)
4. Choose **Sign In with Blockstack**.
The application detects whether the user has the Blockstack client edition installed or
not. This is done automatically by the Blockstack API, more about this later.
What the authenticator displays depends on the users' current state.
| Using web app | Has client edition installed |
|------------------|-----------------------------------|
| ![](images/login-choice.png) | ![](images/login.gif) |
If the user logged into the Blockstack authenticator but not reset it, the user can
simply use the exiting identity.
![](images/login-no-auth.png)
If the user chooses **Deny**, the Blockstack authenticator displays its
**Home** page but the user is not logged into the sample application.
5. Leave your new application running and move onto the next section.
## Understand the application code
In this section, you look at the main application code which is located in the
`public/app.css` file. Open this file now.
All of the code in the file is wrapped in an event
listener.
```js
document.addEventListener("DOMContentLoaded", function(event) {
})
```
This listener that waits until the DOM content is loaded. Then, it creates an auth request and redirects the user to sign in:
```js
document.getElementById('signin-button').addEventListener('click', function() {
blockstack.redirectUserToSignIn()
})
```
You can find the `redirectUserToSignIn()` function is part of the [Blockstack Javascript documentation](https://blockstack.github.io/blockstack.js/). There is also a sign out button handler. This handler deletes the local user data and signs the user out:
```js
document.getElementById('signout-button').addEventListener('click', function() {
blockstack.signUserOut(window.location.origin)
})
```
The handlers are followed by a `showProfile()` function for showing the user's profile:
```js
function showProfile(profile) {
var person = new blockstack.Person(profile)
document.getElementById('heading-name').innerHTML = person.name() ? person.name() : "Nameless Person"
if(person.avatarUrl()) {
document.getElementById('avatar-image').setAttribute('src', person.avatarUrl())
}
document.getElementById('section-1').style.display = 'none'
document.getElementById('section-2').style.display = 'block'
}
```
Each `getElementById()` function refers to elemments in the `index.html` file.
Once a user is successfully signed in, there is logic for loading the user
profile and displaying the application. As illustrated earlier, there are
several states the user can be in:
- The user is already signed in
- The user has a pending sign in request
- The user is signed out
The application handles these situtations as followed:
```js
if (blockstack.isUserSignedIn()) {
var profile = blockstack.loadUserData().profile
showProfile(profile)
} else if (blockstack.isSignInPending()) {
blockstack.handlePendingSignIn().then(function(userData) {
window.location = window.location.origin
})
}
```
When the user is signed in, Blockstack loads the user data from local storage
and displays the profile with the `showProfile()` function. When the user has a
pending sign in request, the appplication signs the user in and redirects the
user back to the home page.
### Application manifest
The application's `/public/manifest.json` file configures your app. The
configurations dictate how the application is displayed in auth views and on
user home screens. The contents are very simple:
```json
{
"name": "Hello, Blockstack",
"start_url": "localhost:5000",
"description": "A simple demo of Blockstack Auth",
"icons": [{
"src": "https://helloblockstack.com/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
}]
}
```
Keep it as is or fill it in with new information that describes your app.
### Save your application code
Complete the tutorial by storing your app code on GitHub. Before you begin, make sure you have a GitHub account and have configured your environment to use it.
1. Initialize the application code as a Git repo.
```bash
git init
```
2. Add and commit all of the files:
```bash
git add . && git commit -m "first commit"
```
3. In GitHub, create a `hello-blockstack` repository.
4. Back in your termininal window, add a remote for GitHub.
Make sure to fill in your username:
```bash
git remote add origin git@github.com:YOUR_USERNAME_HERE/hello-blockstack.git
```
5. Push your new code to the master branch of the remote repo:
```
git push origin master
```
You're done! You just built your first Blockstack app and shipped the code.
You're well on your way to becoming a Blockstack app legend.

BIN
_newinternet/.svn/pristine/63/6326880dd17c45162090e3bb4902adefbccfcb15.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

BIN
_newinternet/.svn/pristine/6c/6cf236705739b3dc1eaa714fab9bace84b283e8b.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

BIN
_newinternet/.svn/pristine/7d/7d026a516855c1ccedf5ee6a2fe63126d09c8e26.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

BIN
_newinternet/.svn/pristine/7e/7e40e7b1ee5b4f12d441e53a6ab89e94ad1fca90.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

BIN
_newinternet/.svn/pristine/85/85996c7ad7783aa09fc9583b4befe746d24be5e5.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

BIN
_newinternet/.svn/pristine/88/880a628c402d072057a35178bbbc13b8437c46bb.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

BIN
_newinternet/.svn/pristine/89/8917230875187dc926ba9f5a9a86e781975585ad.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

BIN
_newinternet/.svn/pristine/8e/8e3163bec841bf2fb8cc6ecbbf49f02e64b1e2d8.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

BIN
_newinternet/.svn/pristine/94/9400d6428e2bb287e9c7385bedb6ee563f5829d0.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

BIN
_newinternet/.svn/pristine/a3/a388e8949737a271d80b69b8dfcf48d77dddb890.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

BIN
_newinternet/.svn/pristine/a8/a8348770072ebc93d3d6669efb8fb2225bbb39de.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

BIN
_newinternet/.svn/pristine/b0/b0150507ba3e8a583e83ad2c29256231c8b58373.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

BIN
_newinternet/.svn/pristine/b7/b719720c84e885f3d96f0c0b14534214d6683f18.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

BIN
_newinternet/.svn/pristine/b9/b974564d6e487b3c718c87a3c3fa821b4ac3d833.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

201
_newinternet/.svn/pristine/bb/bb14c6df95533e53360cb280946fd54d65e88a8f.svn-base

@ -1,201 +0,0 @@
# Get and use a Blockstack IDs
Through the Blockstack browser you can create an identity. Your identity is a
point of contact as you interact with others through Dapps. Others may be
individual users or companies or software. Unless you allow it, none of these
others have access to anything other than your identity label, for example
`moxiegirl.id.blockstack`. To learn more about you, others must ask and you can
choose to share -- or not.
This document explains one type of identity, the Blockstack ID. You learn how to
create them, as well as when and how to restore them.
## Understand Blockstack IDs
Interacting within the decentralized internet requires that you have at least
one identity, though you can create several. Your identity is created through a
registrar. Blockstack maintains a registrar for creating identities that you
can use to interact with distributed applications (Dapps).
To use the Blockstack Browser or to develop a decentralized application you
require a Blockstack ID, for example `moxiegirl.id.blockstack`. A Blockstack ID
is a digital identity that is registered With Blockstack. Your personal data and
storage are built around this ID. Decentralized applications that want to access
your data need your identity and your permission.
When you first sign up through the Blockstack browser, you create an initial
human-readable identity in the `id.blockstack` domain. This initial identity has
the format:
_`USERNAME`_`.id.blockstack`
The _`USERNAME`_ portion must be unique. You enter an email and password to
create the initial identity. Blockstack uses the password to:
* seed a _recovery code_ an encrypted string, for example `36mWivFdy0YPH2z31EflpQz/Y0UMrOrJ++lH=0EI7c3mop2JuRBm5W1P0BwXxSTazJsUjOAmC55rFUWINqDqGccLio0iwzGclAhaHGZQ5M52`
* seed a _recovery key_ which is a squence of words `applied binge crisp pictorial fiery dancing agreeable frogs light finish ping apple`
The email is provided to allow either Blockstack or a decentralized application
to communicate information to you. In Blockstacks' case, the email is used to
send you reovery information.
While Blockstack registers your human readable ID and the recovery key. _You_ must
record the:
* recovery key
* recovery code (in the order the words apepar)
* initial password
Blockstack does not store them, so it can't give them to you later if they are
lost.
Your initial ID is created in the `id.blockstack` domain. The initial identity
remains primary, and you need this primary ID and its associated information
(recovery code, recovery key, and password) to use the browser again.
Finally, the `id.blockstack` domain is sponsored by the Blockstack registrar and
identities on it are free. Once you are using the Blockstack Browser, you can
create additional identities outside of this domain and controlled by other
registrars. Coin is required to purchase identities on other domains.
## Create an initial Blockstack ID
To create an inititial Blockstack ID, do the following:
1. Open the [Blockstack web applicatin in your browser](https://browser.blockstack.org/sign-up?redirect=%2F).
The application prompts you for an email address.
![](images/create-id-0.png)
Blockstack uses this email address to send you recovery information.
2. Enter an email address and press **Next**.
The application prompts you to enter a password. Blockstack users this
password to encrypt your recovery code. You must record and save this
initial password.
**NOTE**:The Blockstack team cannot restore your password for you.
3. Enter a password, confirm it, and press **Next**.
![](images/create-id-1.png)
The browser prompts you to register a unique username in the `id.blockstack`
domain. This is your identity in the decentralized internet. The format of the id
is:
_`username`_`.id.blockstack`
You'll use this initial ID to access the Blockstack Browser.
3. Enter a unique username and press **Check Availability**.
![](images/create-id-2.png)
When you choose an ID that is available, the system responds with the following:
![](images/create-id-3.png)
4. Press **Continue**.
The system prompts you to save your **recovery code**. A recovery code is a
sequence of words. These words allow you to recover an `id.blockstack`
that you've created. You should store the words along with their order, for
example, `#1 applied` and so forth.
5. Click **I have written down all the words** when you are done.
The system places you in the Blockstack browser. You can begin exploring and
using Dapps.
## Restore a Blockstack ID
When you return to the Blockstack Browser, the browser prompts you to create a
new Blockstack ID or restore an existing Blockstack ID. If you have a
Blockstack identity, you can open the browser by restoring the identity. To
restore an identity, there are two available methods.
Method 1: Supply the identity recovery code (`36mWivFdy0YPH2z31E...`) and the
password you provided when you _initially_ created your identity. Method 2:
Supply the recovery key which is a sequence of words (`applied binge ...`)
If you loose either the recovery code or the password you provided when you
_initially_ created your identity, you can no longer use method 1 to restore
your identity. If you lose the recovery key, you can no longer use method 2.
Once you no longer have access to either method, your identity is estranged and
not accessible by anyone.
### Restore with a recovery key
1. Open the [Blockstack web application in your browser](https://browser.blockstack.org/sign-up?redirect=%2F).
2. Choose **Restore a Blockstack ID**.
The system displays a dialog where you can enter your recovery code or a
recovery key.
3. Enter the recovery key.
The recovery key is a squence of words.
![](images/recovery-code.png)
4. Press **Next**.
The system prompts you for an email address. This email can be one you
entered previously or an entirely new one. Blockstack doesn't store this
address; it is used during your current Blockstack browser interaction to communicate
important information with you.
5. Enter an email and press **Next**.
The system prompts you for an password and its confirmation. This password
can be one you entered previously or an entirely new one. Write this password
down. You can use the password during your current Blockstack browser
interaction to reveal your keychain or change your password. Blockstack does
not store this information past the session.
6. Enter a password and press **Next**.
The system welcomes you back.
![](images/welcome-back.png)
At this point, you can go onto work with Dapps or you can review your recovery key.
### Restore with a recovery code and original password
1. Open the [Blockstack web application in your browser](https://browser.blockstack.org/sign-up?redirect=%2F).
2. Choose **Restore a Blockstack ID**.
The system displays a dialog where you can enter your recovery code or a
recovery key.
3. Enter your recovery code.
The recovery code is an encrypted string.
![](images/recovery-code.png)
4. Press **Next**.
The system prompts you for an email address. This email can be one you
entered previously or an entirely new one. Blockstack doesn't store this
address; it is used during your current Blockstack browser interaction to
communicate important information with you.
5. Enter an email and press **Next**.
The system prompts you for an password. This must be the password entered
when you first created your identity. If you have forgetten this passowrd,
Blockstack cannot provide it to you. Instead, you must switch to using your
recovery key rather than your code to restore your identity.
6. Enter your origin password and press **Next**.
The system welcomes you back.
![](images/welcome-back.png)
At this point, you can go work with Dapps or you can review your recovery key.

BIN
_newinternet/.svn/pristine/bf/bfa77ea6b63530fb7273cc51c462f37d9479a75b.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

BIN
_newinternet/.svn/pristine/ca/ca6de58cdaf847ead67cc9893c73b040cdd6fb08.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

BIN
_newinternet/.svn/pristine/d0/d085d6df138e87cfea31a57a1e732327fbe01244.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

BIN
_newinternet/.svn/pristine/d6/d6e6a8f19612c2353e5ff02ac49dc06762f7127c.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

BIN
_newinternet/.svn/pristine/db/db11f02ca2f4fd6473c082112db7fd86c19d2039.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

BIN
_newinternet/.svn/pristine/eb/ebb5e5f52918709d42ea6cbba0df6b008039e281.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

BIN
_newinternet/.svn/pristine/ec/ec3db3fa698c68b7eb55535729ca0bf5306d33ba.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

328
_newinternet/.svn/pristine/ee/eef5a5c80676898fe5a63a3a5e1700a2c73f2b0d.svn-base

@ -1,328 +0,0 @@
---
title: Tour of a Blockstack application
description: Walk through creating a basic Todo application with Blockstack. Learn about Sign In flow and Gaia storage.
image: /images/article-photos/chalkboard.jpg
youtube: https://www.youtube.com/embed/oyvg-h0obFw
---
In this tutorial, you build the code for and run a single-page application (SPA)
with Blockstack and Vue.js. Once the application is running, you take a tour
through the applications' Blockstack functionality. You'll learn how it manages
authentiation using a Blockstack ID and how it stores information associated
with that ID using Blockstack Storage (Gaia).
## Prerequisites
Make sure you have [created at least one Blockstack ID](ids-introduction.md#create-an-initial-blockstack-id). You'll use this ID to Finteract with the Todo application.
The applicaton code relies on both the `npm` and the `yarn` package managers.
Before you begin, verify you have these tools `npm` using the `which` command to
verify.
```bash
$ which npm
/usr/local/bin/npm
$ which yarn
/usr/local/bin/yarn
```
[Install npm](https://www.npmjs.com/get-npm), [install
yarn](https://yarnpkg.com/lang/en/docs/install/#mac-stable), or both as needed. You
While it stands alone, this tour does on the information from the [Hello
Blockstack tutorial](hello-blockstack.md). If you haven't worked through that
tutorial, you may want to do that before continuing.
## Install the applicaton code and retrieve the dependencies
You can clone the source code with `git` or [download and unzip the code from
the
repository](https://github.com/blockstack/blockstack-todos/archive/master.zip).
These instructions assume you are cloning.
1. Install the code by cloning it.
```
$ git clone git@github.com:blockstack/blockstack-todos.git
```
2. Change to directory to the root of the code.
```
$ cd blockstack-todos
```
2. Use yarn to install the dependencies.
```
$ yarn install
yarn install v1.9.2
info No lockfile found.
...
[4/5] 🔗 Linking dependencies...
[5/5] 📃 Building fresh packages...
success Saved lockfile.
✨ Done in 19.90s.
```
## Understand the important application files
The Todo application has a basic Vue.js structure. There are several configuration files but the central programming files are in the `src` directory:
| File | Description |
|-----------------|-------------|
| `main.js` | Application initialization. |
| `App.vue ` | Code for handling the `authResponse`. |
| `Landing.vue ` | Code for the initial sign on page. |
| `Dashboard.vue` | Application data storage and user sign out. |
The example application runs in a node server on your local host. In the next section, you start the application and interact with it.
1. Start the application.
```
$ npm run start
```
You should see a simple application:
![](images/todo-sign-in.png)
2. Choose **Sign In with Blockstack**.
## Understand the sign in process
At startup, the Todo application detects whether the user has the Blockstack client edition
installed or not. This is done automatically by the Blockstack API, more
about this later. What the authenticator displays depends on which whether the user has installed the Blockstack Authenticator client edition or not.
| Client edition installed | Not installed |
|------------------|-----------------------------------|
| ![](images/login.gif) | ![](images/login-choice.png)|
If the user was logged into the Blockstack authenticator (web or client) but
did not reset it, the web application to use the current identity:
![](images/login-no-auth.png)
If the user chooses **Deny**, the Blockstack authenticator opens but the user
is not logged into the sample application.
![](images/windows-browser.png)
If the login to the application is successful, the user is presented with the application:
![](images/todo-app.png)
Clicking the **Sign In With Blockstack** button brings up a modal that prompts
you to use an existing ID's session, create a new ID, or reset the browser with
another ID. When Blockstack is provided an ID, it generates an _ephemeral key_
within the application. An ephemeral key is generated for each execution of a
key establishment process. This key is just used for the particular instance of
the application, in this case to sign a **Sign In** request.
Blockstack also generates a public key token which is sent to the authenticator
as an `authRequest` from the authenticator to your local blockstack-core node.
The signed authentication request is sent to Blockstack through a JSON Web
Token. The JWT is passed in via a URL query string in the `authRequest`
parameter:
`https://browser.blockstack.org/auth?authRequest=j902120cn829n1jnvoa...`. To
decode the token and see what information it holds:
1. Copy the `authRequest` string from the URL.
2. Navigate to [jwt.io](http://jwt.io/).
3. Paste the full token there.
The output should look similar to below:
```json
{
"jti": "3i96e3ad-0626-4e32-a316-b243154212e2",
"iat": 1533136622,
"exp": 1533140228,
"iss": "did:btc-addr:1Nh8oQTunbEQWjrL666HBx2qMc81puLmMt",
"public_keys": [
"0362173da080c6e1dec0653fa9a3eff5f5660546e387ce6c24u04a90c2fe1fdu73"
],
"domain_name": "http://localhost:8080",
"manifest_uri": "http://localhost:8080/manifest.json",
"redirect_uri": "http://localhost:8080/",
"version": "1.2.0",
"do_not_include_profile": true,
"supports_hub_url": true,
"scopes": [
"store_write"
]
}
```
>**Note**:
> 1. The `iss` property is a decentralized identifier or `did`. This identifies you and your name to the application. The specific `did` is a `btc-addr`.
> 2. The Blockstack JWT implementation is different from other implementations because of the underlying cryptography we employ. There are libraries in [Javascript](https://github.com/blockstack/jsontokens-js) and [Ruby](https://github.com/blockstack/ruby-jwt-blockstack) available on the Blockstack Github to allow you to work with these tokens.
When the blockstack-core receives the `authRequest`, it generates a session token and
returns an authentication response to the application. This response is similar
to the `authRequest` above in that the `authResponse` includes a private key
intended only for the application. This allows the application to encrypt data
on your personal Blockstack storage.
You are now logged into the Todo application!
## Undder the covers in the sign in code
Now, go to the underlying `blockstack-todo` code you cloned or downloaded. Sign
in and sign out is handled in each of these files:
| File | Description |
|-----------------|-------------|
| `App.vue ` | Handles the `authResponse`. |
| `Landing.vue ` | Generates the `authRequest`. |
| `Dashboard.vue` | Handles sign out. |
The `src/components/Landing.vue` code calls a [`redirectToSignIn()`](https://blockstack.github.io/blockstack.js#redirectToSignIn) function which generates the `authRequest` and redirects the user to the Blockstack authenticator:
```js
signIn () {
const blockstack = this.blockstack
blockstack.redirectToSignIn()
}
```
Once the user authenticates, the application handles the `authResponse` in the `src/App.vue` file. :
```js
if (blockstack.isUserSignedIn()) {
this.user = blockstack.loadUserData().profile
} else if (blockstack.isSignInPending()) {
blockstack.handlePendingSignIn()
.then((userData) => {
window.location = window.location.origin
})
}
```
If [`blockstack.isUserSignedIn()`](https://blockstack.github.io/blockstack.js/#isusersignedin) is true, the user was previously signed in so Blockstack pulls the data from the browser and uses it in our application. If the check on [`blockstack.isSignInPending()`](https://blockstack.github.io/blockstack.js/#issigninpending) is true, a previous `authResponse` was sent to the application but hasn't been processed yet. The `handlePendingSignIn()` function processes any pending sign in.
Signout is handled in `src/components/Dashboard.vue`.
```js
signOut () {
this.blockstack.signUserOut(window.location.href)
}
```
The method allows the application creator to decide where to redirect the user upon Sign Out:
## Working with the application
Now trying adding a few todos using the application. For example, try making a list of applications you want to see built on top of Blockstack:
![](images/make-a-list.png)
Each list is immediately stored in the Gaia Hub linked to your Blockstack ID.
For more information about the Gaia hub, see the [hub
repository](https://github.com/blockstack/gaia). You can fetch the `todos.json`
file you just added by opening the Javascript console and running the following
command:
```Javascript
blockstack.getFile("todos.json", { decrypt: true }).then((file) => {console.log(file)})
```
You should see a JSON with the todos you just added:
```json
[
{
"id":2,
"text":"Software package manager secured by the blockchain",
"completed":false
},
{
"id":1,
"text":"Mutable torrents with human readable names",
"completed":false
},
{
"id":0,
"text":"Decentralized twitter",
"completed":false
}
]
```
Now, add another todo and check it off. When you fetch the newly generated file
using the Javascript console it will reflect the change look for `"completed":true`:
```json
[
{
"id":3,
"text":"Blockstack Todo",
"completed":true
},
{
"id":2,
"text":"Software package manager secured by the blockchain",
"completed":false
},
...
]
```
Now that you have seen the application in action, dig into how it works.
## Implementing storage
Now, go to the underlying `blockstack-todo` code you cloned or downloaded. The
application interactions with your Gaia Hub originate in the
`src/components/Dashboard.vue` file. First lets see where the changes to the
Todos are processed:
```js
todos: {
handler: function (todos) {
const blockstack = this.blockstack
// encryption is now enabled by default
return blockstack.putFile(STORAGE_FILE, JSON.stringify(todos))
},
deep: true
}
```
Tje `todos` JSON object is passed in and the [`blockstack.putFile()`](https://blockstack.github.io/blockstack.js/#putfile) method to store it in our Gaia Hub.
The code needs to read the Todo items from the storage with the [`blockstack.getFile()`](https://blockstack.github.io/blockstack.js/#getfile) method which returns a promise:
```js
fetchData () {
const blockstack = this.blockstack
blockstack.getFile(STORAGE_FILE) // decryption is enabled by default
.then((todosText) => {
var todos = JSON.parse(todosText || '[]')
todos.forEach(function (todo, index) {
todo.id = index
})
this.uidCount = todos.length
this.todos = todos
})
},
```
The `todos` data is retrieved from the promise.
## Summary
You now have everything you need to construct complex applications complete with authentication and storage on the Decentralized Internet. Why not try coding [a sample application that accesses multiple profiles](multi-player-storage.md).
If you would like to explore the Blockstack APIs, you can visit the [Blockstack Core API](https://core.blockstack.org/) documentation or the [Blockstack JS API](https://blockstack.github.io/blockstack.js).
Go forth and build!

BIN
_newinternet/.svn/pristine/f1/f110c7b263eda5b8f71f1426dd9829625a5b1b31.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

BIN
_newinternet/.svn/pristine/f2/f2da2a06b1ae6cece6cb9389f80dd5bb11cd7a98.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

BIN
_newinternet/.svn/pristine/f7/f7d8196207101d3fd6bf9efa91cb074dcbea011d.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

161
_newinternet/.svn/pristine/f8/f81e6e4308c1f49f6ddca9caf4b065ca60bc6726.svn-base

@ -1,161 +0,0 @@
---
title: Managing Data with Gaia
description: This series will focus on teaching you to think like a Blockstack developer working with Gaia.
image: /images/tutorials/managing-data-with-gaia.png
---
If you’ve gone through tutorials and documentation for blockstack.js and Gaia,
you’ll know the `blockstack.js` interface is dead simple. First, you
authenticate a user into your app. Once that’s complete, you’re free to read and
write app data in the user’s storage provider with two data operations:
- `putFile`: Writes to a specified path
- `getFile`: Gets the file at a specified path
That’s it. You’re reading files and you’re writing files. All file types are
supported, so you can choose to manage data with sql, markdown, json, or even
your own custom format! Gaia operations are purposefully left primitive so that
you have complete control over which tools you use on top. In the future, we
imagine a variety of data management libraries will emerge that wrap Gaia and
help you interact with your data layer via expressive APIs.
If you’re anything like most developers, you’re probably used to working with
highly abstracted libraries that offer collection management, querying,
pagination, documented schema models, and more. Developing apps on Blockstack is
thrilling because you quickly learn that you don’t need training wheels. You can
create a meaningful and complex data layer using two methods: `putFile` and
`getFile`. This limited interface forces you to think about your fundamental
data architecture and make some decisions about how you’re modeling data to gain
back the benefits you get with large frameworks.
This series will focus on teaching you to think like a Blockstack developer
working with Gaia. Let’s get started!
## Working with Data Collections
For the purposes of this tutorial, let’s pretend that we’re building a simple
grocery list app called Grublist. As a user of Grublist, you should be able to
create, read, update, and delete grocery lists.
Let’s think in terms of JSON since it’s easy and familiar.
### Single-File Collection Approach
Here’s a Single-File Collection approach to modeling our data:
```
// grocerylists.json
{
"3255": {
"items": [
"1 Head of Lettuce",
"Haralson apples"
]
},
// ...more lists with items
}
```
Notice that items are stored as an array nested inside of each grocery list.
This is conceptually the simplest way to manage your grocery lists. It’s very
easy to wrap your brain around what’s going on with the data. When you read the
`/grocerylists.json` file, you get back exactly what you need: grocery lists and
their items. When you write, you’re always writing to one place.
There is one caveat to this approach that you should seriously consider: Every
time you update one of your grocery lists in any way, you’re overwriting the
entire file of all your grocery lists. This is because using the `putFile`
method will overwrite anything at `/grocerylists.json` if it exists, so if
you’re doing a write operation for a new grocery list, you must submit all
previous grocery lists plus the new grocery list.
That’s actually kind of scary, especially considering this code is running on
the client where anything can go wrong. Imagine your client-side code encounters
a parsing error with a user-input value and you overwrite two years worth of a
user’s grocery lists with:
```
"line 6: Parsing Error: Unexpected token ."
```
**To summarize the Single-File Collection approach:**
Pros:
- **Simplified reads**: Just request a single file and get back a list of all your data.
- **Simplified writes**: Some people might be more comfortable working with a Javascript array of items on the client.
Cons:
- **Pagination is impossible**: Using a simple storage strategy like this, you have no choice but to download the entire file of all grocery lists. A user could have 1000 grocery lists, and every time they enter your app they would be forced to download all 1000 grocery lists worth of data.
- **Too heavy-handed**: This is the issue I mentioned above about overwriting an entire file of all grocery lists. Generally, you should try to avoid managing entire collections of data at a time.
- **Less control over file permissions**: You’ll need to perform data acrobatics if you want to share only a single grocery list with a trusted party.
### Multi-File Collection Approach
It would be great if we could split out grocery lists into their own files to
minimize the risk of destroying all the user’s grocery list data and make it
easier to paginate the lists.
Here’s a diagram of a Multi-File Collection approach:
<img src="/images/tutorials/grocery-lists.png" style="max-width: 80%;" />
With this approach, we maintain an index file that stores an array of list IDs.
Each list ID is predictably the name of a file under a `grocerylists` folder.
**To summarize the Multi-File Collection approach:**
Pros:
- **Performant pagination**: Just request the `grocerylists.json` file, and from there you can request as many of the collection items as you need.
- **Less risk of data corruption**: By only manipulating one grocery list at a time, you can guarantee that if something goes wrong with your write operation, it won’t affect the other grocery list data. You might say, “but I still need to overwrite the list of IDs every time I operate.” That’s true, but you can optimize your code so that you’re only updating that file when you add or remove a grocery list. Managing a list of IDs is also much more manageable than a big list of user input data.
- **More control over file permissions**: If you wanted to share only a single grocery list with a trusted party, it’s much easier to do when the list data is isolated to its own file.
Cons
- **More network requests**: If you have 10 grocery lists and want to fetch them all, you’re going to be making 11 network requests. Using HTTP/2 and requesting limited items at a time will help with performance.
- **More complex architecture**: Rather than simply requesting the file of all your data, you now have to request each item individually and stitch them all together once all requests have finished.
### Implementing these approaches
We’ve shown you conceptually how you might think about organizing your data, but
you have not seen much implementation code. Check out the sandbox linked below
for an implementation of services that can accommodate either the single-file or
multi-file approaches for all of your collections.
Note that we’ve included an interstitial “driver” layer for a few reasons:
1. In the sandbox, we’re swapping out the Blockstack driver for a localstorage driver for demonstration purposes.
2. It’s good practice to have all data flow through an interface you control, so that you can add logging or perform other operations.
3. If the `blockstack.js` API changes in the future, you can update your code once in the driver.
4. You can DRY up your code by declaring the Gaia config once per collection.
Click the button below to spin up a sandbox environment:
[![](/images/tutorials/edit-sandbox.png)](https://codesandbox.io/s/8kzmjjr9nj)
## Summary
There are many valid ways to organize your data and you should pick what makes
the most sense for your needs. I would recommend using a single-file collection
approach for predictably small collections of data. For larger collections, the
risk of data corruption is too high to be passing around entire collections
worth of data with one `putFile` request, so opt for an architecture that looks
more like the multi-file collection model.
Most importantly, feel free to experiment with data architecture. There are
concepts and patterns you can introduce into this process that can help you
validate schema, migrate data, and more. Check out more of our tutorials for a
deeper dive into developing a sample app.

BIN
_newinternet/.svn/pristine/fe/feb47456df368ff71ac8c50b94702abec6bf2619.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

BIN
_newinternet/.svn/pristine/ff/ff4ec7f9dcc8b70af2d527b508b30c47a5386514.svn-base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

BIN
_newinternet/.svn/wc.db

Binary file not shown.

0
_newinternet/.svn/wc.db-journal

27
_newinternet/README.md

@ -1,27 +0,0 @@
# 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.

289
_newinternet/browser-introduction.md

@ -1,289 +0,0 @@
---
layout: newinternet
permalink: /:collection/:path.html
---
# Use the Blockstack Authenticator
{:.no_toc}
lockstack Authenticator gives users the ability to explore and use the
decentralized applications (dapps). The decentralized applications are a new way
to interact with the internet. Dapps give users control of their data. Data
about them personally, name, birthdate, phone number and data about what they do
such as visiting a website or buying an item.
* TOC
{:toc}
## Understand the Blockstack Authenticator
Through the Blockstack authemticator application you can create an identity. An identity
represents you as you interact with others through Dapps. The Blockstack
authenticator is itself, a smiple Dapp. It allows you to:
* create one or more identities
* send and receive bitcoin
* manage the storage of your profile and application data
* find and launch Dapps
There are editorions of the Blockstack Authenticator, the web edition is an
application you access through your web browser by simply [visit the
applications' address](https://browser.blockstack.org/) in your computer's
browser. You can also install the authenticator as a client application on your
computer.
If all you want to do is create, manage, and fund an identity and then interact
with Dapps, you can simply use the web edition. If you have concerns about net
censorship, hightened security concerns, or develop a Dapp yourself, you may
want to download and install the authenticator's client edition.
## Using the Authenticator on public computers
Before you use the web application, it is important to note that once you log
into the application with the brower, your session does not expire until you
choose **Settings > RESET BROWSER**. For this reason, you should be careful
when using the authenticator on public computers.
If you are in a library, for example, and log into the authenticator, simply
closing the tab or even rebooting the computer does not log you out. Instead,
you should be sure to choose **Settings > RESET BROWSER** before leaving the web
application.
For more informatin about your identity and the authenticator, see [Get and use a Blockstack IDs](ids-introduction.md).
## Install the client edition
Remember, for most users the Blockstack Authenticator web application should
suffice. You only need to install the client if you have additional, advanced
concerns about Internet or identity. Though not required, some Dapp developrs
may find it useful to install the client edition.
The Blockstack Authenticator installer is a _multiple-context_ installer. If you
run it as a user, the installation is avalable only for that user. If you
install as administrator, the installation installs for all users. To find an
installer for your operating system, visit [the Blockstack install
page](https://blockstack.org/install).
### On Mac
Installation requires that you have macOS High Sierra 10.12 or higher. Do the following to install:
1. Download the OSX installer from from <a href="https://blockstack.org/install" target="_blank">the browser installation page</a>.
2. Double-click the downloaded DMG file to launch the installer.
![](images/ubuntu-browser.png)
3. Drag the Blockstack.app to the `Applications` folder.
4. Double-click the Blockstack.app to launch it.
The system displays a notice about opening the file:
![](images/dmg-notice.png)
5. Choose **Open**.
The system opens your default browser with the Blockstack Authenticator
application, running from your machine (localhost). You'll also see the
Blockstack icon in your machine's
![](images/browser-on-mac.png)
If you have loaded an identity already via the Blockstack web application,
you are already logged into the local application:
![](images/browser-on-mac-1.png)
### On Windows
Installation requires that you have Windows 10 or higher. Do the following to
install:
1. Download the Windows installer from from <a href="https://blockstack.org/install" target="_blank">the browser installation page</a>.
2. Double-click the installer package to launch it.
![](images/windows-installer.png)
3. Open the Wiindows **Start** menu and click on the recently added **Blockstack Authenticator**.
![](images/windows-start.png)
The system displays a Windows Security Alert.
![](images/windows-security.png)
4. Choose to **Allow access**.
The system opens in the Blockstack Authenticator application.
![](images/windows-browser.png)
### On Linux
The Blockstack installation on Linux requires Docker. Before installing
Blockstack, <a href=“https://docs.docker.com/install/” target="_blank">install
the version of Docker appropriate for your operating system</a>.
>**Note**: The Blockstack script used in this procedure runs `docker` commands. Depending on how you installed and configure Dockered on your system, it may or may not be necessary to have `root` or `sudo` privileges. For this reason, the commands below show the use of `sudo` when interacting with the script or the `docker` executable. If your installation allows running Docker with lower privileges, you can omit it.
1. Download the Linux installer from from <a href="https://blockstack.org/install" target="_blank">the browser installation page</a>.
This downloads a `Blockstack-for-Linux-v0.30.0.sh` script to your local drive.
2. Open a terminal and navigate to the directory containing the downloaded script.
When the script downloads, it is not executable.
3. Set the executable bit on the file.
```bash
$ chmod u+x Blockstack-for-Linux-v0.309.0.0.sh
```
4. Enter the command without any arguments to see the available subcommands.
```bash
$ sudo ./Blockstack-for-Linux-v0.309.0.0.sh
blockstack docker launcher commands:
Install-protocol-handler -> install a protocol handler for blockstack:// links
...
```
5. Use the script to `pull` the Blockstack Docker images you need.
```bash
$ sudo ./Blockstack-for-Linux-v0.309.0.0.sh pull
```
Depending on your network speed, this can take some time.
7. Use the `docker image ls` command to confirm you have the image.
```bash
$ sudo docker image Is
REPOSITORY TAG IMAGE ID CREATED
quay.io/blockstack/blockstack-browser v0.30.0 ad05fd844f59 2 days ago
```
8. Install the protocol handler
```bash
$ sudo ./Blockstack-for-Linux-vO.30.0.sh install-protocol-handler

Registering protocol handler
```
9. Start the Blockstack containers.
```bash
$ sudo ./Blockstack-for-Linux-vO.30.0.sh start
c3092592e59abe3559fdb49d070a7aa5e99165c7d9f2flla20ecaf4e0dfc2f46

cd92f61ae473d54398da987f5023f5462b29c03f08584ebb3c9fIbb4cd790c69

Registering protocol handler
```
The system launches the Blockstack Authenticator application for you.
![](images/ubuntu-browser.png)
Until you stop the Blockstack containers, the application will continue to run
on your system. To display the status of the Blockstack containers, you can use
the `docker container ls` command.
{% raw %}
```bash
$ sudo docker container ls --format '{{.ID}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}'
```
{% endraw %}
Use `./Blockstack-for-Linux-vO.30.0.sh stop` to stop the Blockstack Authenticator and its containers.
## Uninstall the browser
If you installed the browser using an installer, follow the instructions for
your operating system.
### On Mac
1. Quit the Blockstack application if it is running.
![](images/quit-blockstack.png)
2. Check if you have a Blockstack device and eject it if you do.
![](images/eject-blockstack.png)
3. Use the Finder to open the **Applications** folder.
4. Locate the Blockstack application.
5. Open your `Applications` folder and locate the **Blockstack.app**.
6. Drag the appliation to the trash.
7. Delete the `/Users/USERNAME/Library/Application Support/Blockstack` folder.
From the command line:
```bash
$ rm -r /Users/moxiegirl/Library/Application\ Support/Blockstack
```
### On Windows
1. Open the **Start** menu.
2. Click **Settings > System**.
3. Open for the **Apps & features** item.
![](images/eject-blockstack.png)
4. Locate the **Blockstack Authenticator** and choose **Uninstall**.
![](images/browser-uninstall.png)
### On Linux
Your Blockstack instalaltion relies on Docker containers and their associated
images. It also includes a supporting protocol handler you must remove. If you
installed Docker so that you can run Blockstack, you can uninstall Docker as well,
but that is not explained here.
Do the following to uninstall Blockstack:
1. Stop and remove the Docker containers if they are running.
```bash
$ sudo ./Blockstack-for-Linux-vO.30.0.sh stop
stopping the running blockstack-browser containers
69a686799d4f
56fc6189ff97
69a686799d4f
56fc6189ff97
```
2. Remove the associated Blockstack images.
```bash
$ sudo docker image ls
REPOSITORY TAG IMAGE ID CREATED
quay.io/blockstack/blockstack-browser v0.30.0 ad05fd844f59 3 days ago
$ sudo docker image rm ad05fd844f59

Untagged : quay.io/blockstack/blockstack- browser :vO.30.0
Untagged: quay.io/blockstack/blockstack-browser@sha256:b20c9514c56b99398fd4946af39e7537b807e85694943ac3b8807dlb3625833b
Deleted: Sha256:ad05fd844f5948blee06a0a09228df946478393c0a7588cbc65dlb8817f5b34e
Deleted: Sha256:7c3d0043f2ba01cf285f3fe09701b086c349b6380c2e42f25b31ac65c6626ec8
Deleted: sha256:54ea2aa7d7d000e7483f299eeca9e5466fa86231f4cd4cld3c3096d97e61c5df
Deleted: sha256:38e61054355adefc3c2de031462114a9946cfc0e44444a38a27d0f115aba0da2
....
```
3. Use the script to remove the protocol handler
```bash
$ sudo ./Blockstack-for-Linux-vO.30.0.sh remove-protocol-handler
```
4. Delete the script.
```bash
$ rm Blockstack-for-Linux-vO.30.0.sh
```

160
_newinternet/cli-basics.md

@ -1,160 +0,0 @@
---
title: CLI Basics
description: Walk through the basics of the command line interface, like looking up names, getting name prices, and registering names.
image: /images/article-photos/chalkboard.jpg
youtube: https://www.youtube.com/embed/GWjEGlb1aEs
---
Welcome!
In this tutorial, we're going to walk through the basics of the Blockstack command line interface.
### Lookups
Now, to perform a name lookup, run this command:
```bash
$ blockstack lookup timblee.id
```
You should get a response like this:
```
{
"profile": {
"@type": "Person",
"account": [
{
"@type": "Account",
"identifier": "timbl",
"proofType": "http",
"proofUrl": "https://gist.github.com/timbl/04e8ac7c81cd2dee2f51a5e8c672188d",
"service": "github"
},
{
"@type": "Account",
"identifier": "timberners_lee",
"proofType": "http",
"proofUrl": "https://twitter.com/timberners_lee/status/740677355950080001",
"service": "twitter"
}
],
"image": [
{
"@type": "ImageObject",
"contentUrl": "https://s3.amazonaws.com/97p/lUU.jpeg",
"name": "cover"
}
]
},
"zonefile": "$ORIGIN timblee.id\n$TTL 3600\n_http._tcp URI 10 1 \"https://blockstack.s3.amazonaws.com/timblee.id\"\n"
}
```
### Price Estimations
Every name costs a certain amount of money to register, and each namespace has it's own name pricing rules.
As an example, in the `.id` namespace 6-letter alphabetic-only names cost 0.001 bitcoins, but with every additional letter the names get 4x cheaper and with every fewer letter the names get 4x more expensive. In addition, names without vowels and names with numbers and special characters get a special discount.
To determine how much a name will cost to order a name (including all transaction fees), use the `price` command:
```bash
$ blockstack price <YOUR NAME>.id
```
Example response:
```json
{
"name_price": {
"btc": "0.00025",
"satoshis": "25000"
},
"preorder_tx_fee": {
"btc": "0.00047406",
"satoshis": "47406"
},
"register_tx_fee": {
"btc": "0.00046184",
"satoshis": "46184"
},
"total_estimated_cost": {
"btc": "0.00188394",
"satoshis": "188394"
},
"update_tx_fee": {
"btc": "0.00069804",
"satoshis": "69804"
}
}
```
### Deposits
Name registrations and name management operations cost money, so before you can do these things, you'll need to deposit bitcoins in your account.
*Note that in some cases you'll need to wait for one or more confirmations (about 10-60 minutes) before the Blockstack CLI will register the funds as fully deposited and allow you to proceed with registering names.*
To get the Bitcoin address where you should deposit your bitcoins, run the `deposit` command:
```bash
$ blockstack deposit
```
Example response:
```json
{
"address": "13aUoeUtQnHUTfRwbksKvyvMRMzN3Qf2iR",
"message": "Send bitcoins to the address specified."
}
```
### Registrations
After you get comfortable with looking up names, take the next step and register and manage a name for yourself. Run the following command:
```bash
$ blockstack register <YOUR NAME>.id
```
If the name hasn't been registered yet, you'll get a confirmation that your registration is pending:
```json
{
"success": true,
"transaction_hash": "f576313b2ff4cc7cb0d25545e1e38e2d0d48a6ef486b7118e5ca0f8e8b98ae45",
"message": "The name has been queued up for registration and will take a few hours to go through. You can check on the status at any time by running 'blockstack info'."
}
```
After a few hours, your registration should go through and you'll be able to update your DNS records for the name.
### Updates
To update the data record associated with a name you own, run the `blockstack update` command:
```bash
$ cat > new_zone_file.txt <<EOF
\$ORIGIN swiftonsecurity.id
\$TTL 3600
pubkey TXT "pubkey:data:04cabba0b5b9a871dbaa11c044066e281c5feb57243c7d2a452f06a0d708613a46ced59f9f806e601b3353931d1e4a98d7040127f31016311050bedc0d4f1f62ff"
_file IN URI 10 1 "file:///Users/TaylorSwift/.blockstack/storage-disk/mutable/swiftonsecurity.id"
_https._tcp IN URI 10 1 "https://blockstack.s3.amazonaws.com/swiftonsecurity.id"
_http._tcp IN URI 10 1 "http://node.blockstack.org:6264/RPC2#swiftonsecurity.id"
_dht._udp IN URI 10 1 "dht+udp://fc4d9c1481a6349fe99f0e3dd7261d67b23dadc5"
EOF
$ blockstack update swiftonsecurity.id new_zone_file.txt
```
Expected response:
```json
{
"success": true,
"transaction_hash": "4e1f292c09ad8e03a5f228b589d9a7dc3699b495862bee3b40f2432ac497b134",
"message": "The name has been queued up for update and will take ~1 hour to process. You can check on the status at any time by running 'blockstack info'."
}
```

333
_newinternet/hello-blockstack.md

@ -1,333 +0,0 @@
---
layout: learn
permalink: /:collection/:path.html
---
# Hello, Blockstack Tutorial
In this tutorial, you build a simple application on Blockstack. The application
is a single-page application (SPA) that runs completely client-side. The
application has no backend API to talk to, other than the identity and storage
API that the user provides. In this sense, the application is a completely
decentralized, server-less application. You work through the following sections:
* TOC
{:toc}
## About this tutorial and the prerequisites you need
For this tutorial, we will use the following tools:
- `npm` to manage dependencies and scripts
- `browserify` to compile node code into browser-ready code
- `blockstack.js` to authenticate the user and work with the user's identity/profile information
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.
The tutorial relies on the `npm` dependency manager. Before you begin, verify
you have installed `npm` using the `which` command to verify.
```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]() to check your work against.
Finally, make sure you have [created at least one Blockstack ID](ids-introduction.md#create-an-initial-blockstack-id). You'll use this ID to interat with the application.
## 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 an initial Blockstack application
In this section, you build an initial React.js application called `hello-world-tutorial`.
1. Create the `hello-world-tutorial` directory.
```bash
mkdir hello-world-tutorial
```
2. Change into your new directory.
```bash
cd hello-world-tutorial
```
3. Use Yeoman and the Blockstack application generator to create your initial `hello-world-tutorial` application.
```bash
yo blockstack
```
You should see several interactive prompts.
```bash
$ yo blockstack
_-----_ ╭──────────────────────────╮
| | │ 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
...
create public/icon-192x192.png
create public/index.html
create public/robots.txt
create public/manifest.json
I'm all done. Running npm install for you to install the required dependencies. If this fails, try running the command yourself.
```
Depending on your environment you may have some problems with the `npm` packages. Go ahead and fix these before continuing to the next section.
## Review the basic application structure
The initial application you create is a generic Javascript application you run
with a local express node. Before you continue, take a moment to examine the
structure of this generic application structure:
| File | Description |
|------------------|-----------------------------------|
| .editorconfig | Sets universal values for editor. |
| .gitignore | Git configuration file. |
| firebase.json | Configuragion for mobile application.|
| package.json | Specifies required packages. |
| requires.js | A Javascript module loader. |
| server.js | Simple static server configuration.|
In the `public` folder you find these files:
| File | Description |
|------------------|-----------------------------------|
| app.css | Contains application styles. |
| app.js | Main application file. |
| boostrap.min.css | Minifield css for production. |
| icon-192x192.png | Application icon |
| index.html | Single page. |
| manifest.json | Tells the browser about the application and how it should behave.|
| robots.txt | Configures crawling and indexing. |
The simple static file server in the `server.js`file serves all of the files in
the `/public` directory, including `index.html`, `app.js`, `bootstrap.min.css`
and `app.css`. The main file of the application is in the `app.js`. It contains
the majority of the application logic.
## Start the server and view the application
When you start the server, it will create a Node.js server, start it locally,
and open your browser 'http://localhost:5000'. From the root of your new application directory:
1. Start the application server.
```bash
npm start
```
The first time you run it, your system prompts you to accept incoming connections.
![Network Connection](images/network-connections.gif)
2. Choose **Allow**.
3. Open your browser to `http://localhost:8080`.
You should see a simple application:
![](images/initial-app.gif)
4. Choose **Sign In with Blockstack**.
The application detects whether the user has the Blockstack client edition installed or
not. This is done automatically by the Blockstack API, more about this later.
What the authenticator displays depends on the users' current state.
| Using web app | Has client edition installed |
|------------------|-----------------------------------|
| ![](images/login-choice.png) | ![](images/login.gif) |
If the user logged into the Blockstack authenticator but not reset it, the user can
simply use the exiting identity.
![](images/login-no-auth.png)
If the user chooses **Deny**, the Blockstack authenticator displays its
**Home** page but the user is not logged into the sample application.
5. Leave your new application running and move onto the next section.
## Understand the application code
In this section, you look at the main application code which is located in the
`public/app.css` file. Open this file now.
All of the code in the file is wrapped in an event
listener.
```js
document.addEventListener("DOMContentLoaded", function(event) {
})
```
This listener that waits until the DOM content is loaded. Then, it creates an auth request and redirects the user to sign in:
```js
document.getElementById('signin-button').addEventListener('click', function() {
blockstack.redirectUserToSignIn()
})
```
You can find the `redirectUserToSignIn()` function is part of the [Blockstack Javascript documentation](https://blockstack.github.io/blockstack.js/). There is also a sign out button handler. This handler deletes the local user data and signs the user out:
```js
document.getElementById('signout-button').addEventListener('click', function() {
blockstack.signUserOut(window.location.origin)
})
```
The handlers are followed by a `showProfile()` function for showing the user's profile:
```js
function showProfile(profile) {
var person = new blockstack.Person(profile)
document.getElementById('heading-name').innerHTML = person.name() ? person.name() : "Nameless Person"
if(person.avatarUrl()) {
document.getElementById('avatar-image').setAttribute('src', person.avatarUrl())
}
document.getElementById('section-1').style.display = 'none'
document.getElementById('section-2').style.display = 'block'
}
```
Each `getElementById()` function refers to elemments in the `index.html` file.
Once a user is successfully signed in, there is logic for loading the user
profile and displaying the application. As illustrated earlier, there are
several states the user can be in:
- The user is already signed in
- The user has a pending sign in request
- The user is signed out
The application handles these situtations as followed:
```js
if (blockstack.isUserSignedIn()) {
var profile = blockstack.loadUserData().profile
showProfile(profile)
} else if (blockstack.isSignInPending()) {
blockstack.handlePendingSignIn().then(function(userData) {
window.location = window.location.origin
})
}
```
When the user is signed in, Blockstack loads the user data from local storage
and displays the profile with the `showProfile()` function. When the user has a
pending sign in request, the appplication signs the user in and redirects the
user back to the home page.
### Application manifest
The application's `/public/manifest.json` file configures your app. The
configurations dictate how the application is displayed in auth views and on
user home screens. The contents are very simple:
```json
{
"name": "Hello, Blockstack",
"start_url": "localhost:5000",
"description": "A simple demo of Blockstack Auth",
"icons": [{
"src": "https://helloblockstack.com/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
}]
}
```
Keep it as is or fill it in with new information that describes your app.
### Save your application code
Complete the tutorial by storing your app code on GitHub. Before you begin, make sure you have a GitHub account and have configured your environment to use it.
1. Initialize the application code as a Git repo.
```bash
git init
```
2. Add and commit all of the files:
```bash
git add . && git commit -m "first commit"
```
3. In GitHub, create a `hello-blockstack` repository.
4. Back in your termininal window, add a remote for GitHub.
Make sure to fill in your username:
```bash
git remote add origin git@github.com:YOUR_USERNAME_HERE/hello-blockstack.git
```
5. Push your new code to the master branch of the remote repo:
```
git push origin master
```
You're done! You just built your first Blockstack app and shipped the code.
You're well on your way to becoming a Blockstack app legend.

210
_newinternet/ids-introduction.md

@ -1,210 +0,0 @@
---
layout: newinternet
permalink: /:collection/:path.html
---
# Get and use a Blockstack ID
{:.no_toc}
Through the Blockstack browser you can create an identity. Your identity is a
point of contact as you interact with others through Dapps. Others may be
individual users or companies or software. Unless you allow it, none of these
others have access to anything other than your identity label, for example
`moxiegirl.id.blockstack`. To learn more about you, others must ask and you can
choose to share -- or not.
This document explains one type of identity, the Blockstack ID. You learn how to
create them, as well as when and how to restore them. It contains the following sections:
* TOC
{:toc}
## Understand Blockstack IDs
Interacting within the decentralized internet requires that you have at least
one identity, though you can create several. Your identity is created through a
registrar. Blockstack maintains a registrar for creating identities that you
can use to interact with distributed applications (Dapps).
To use the Blockstack Browser or to develop a decentralized application you
require a Blockstack ID, for example `moxiegirl.id.blockstack`. A Blockstack ID
is a digital identity that is registered With Blockstack. Your personal data and
storage are built around this ID. Decentralized applications that want to access
your data need your identity and your permission.
When you first sign up through the Blockstack browser, you create an initial
human-readable identity in the `id.blockstack` domain. This initial identity has
the format:
_`USERNAME`_`.id.blockstack`
The _`USERNAME`_ portion must be unique. You enter an email and password to
create the initial identity. Blockstack uses the password to:
* seed a _recovery code_ an encrypted string, for example `36mWivFdy0YPH2z31EflpQz/Y0UMrOrJ++lH=0EI7c3mop2JuRBm5W1P0BwXxSTazJsUjOAmC55rFUWINqDqGccLio0iwzGclAhaHGZQ5M52`
* seed a _recovery key_ which is a squence of words `applied binge crisp pictorial fiery dancing agreeable frogs light finish ping apple`
The email is provided to allow either Blockstack or a decentralized application
to communicate information to you. In Blockstacks' case, the email is used to
send you reovery information.
While Blockstack registers your human readable ID and the recovery key. _You_ must
record the:
* recovery key
* recovery code (in the order the words apepar)
* initial password
Blockstack does not store them, so it can't give them to you later if they are
lost.
Your initial ID is created in the `id.blockstack` domain. The initial identity
remains primary, and you need this primary ID and its associated information
(recovery code, recovery key, and password) to use the browser again.
Finally, the `id.blockstack` domain is sponsored by the Blockstack registrar and
identities on it are free. Once you are using the Blockstack Browser, you can
create additional identities outside of this domain and controlled by other
registrars. Coin is required to purchase identities on other domains.
## Create an initial Blockstack ID
To create an inititial Blockstack ID, do the following:
1. Open the [Blockstack web applicatin in your browser](https://browser.blockstack.org/sign-up?redirect=%2F).
The application prompts you for an email address.
![](images/create-id-0.png)
Blockstack uses this email address to send you recovery information.
2. Enter an email address and press **Next**.
The application prompts you to enter a password. Blockstack users this
password to encrypt your recovery code. You must record and save this
initial password.
**NOTE**:The Blockstack team cannot restore your password for you.
3. Enter a password, confirm it, and press **Next**.
![](images/create-id-1.png)
The browser prompts you to register a unique username in the `id.blockstack`
domain. This is your identity in the decentralized internet. The format of the id
is:
_`username`_`.id.blockstack`
You'll use this initial ID to access the Blockstack Browser.
3. Enter a unique username and press **Check Availability**.
![](images/create-id-2.png)
When you choose an ID that is available, the system responds with the following:
![](images/create-id-3.png)
4. Press **Continue**.
The system prompts you to save your **recovery code**. A recovery code is a
sequence of words. These words allow you to recover an `id.blockstack`
that you've created. You should store the words along with their order, for
example, `#1 applied` and so forth.
5. Click **I have written down all the words** when you are done.
The system places you in the Blockstack browser. You can begin exploring and
using Dapps.
## Restore a Blockstack ID
When you return to the Blockstack Browser, the browser prompts you to create a
new Blockstack ID or restore an existing Blockstack ID. If you have a
Blockstack identity, you can open the browser by restoring the identity. To
restore an identity, there are two available methods.
Method 1: Supply the identity recovery code (`36mWivFdy0YPH2z31E...`) and the
password you provided when you _initially_ created your identity. Method 2:
Supply the recovery key which is a sequence of words (`applied binge ...`)
If you loose either the recovery code or the password you provided when you
_initially_ created your identity, you can no longer use method 1 to restore
your identity. If you lose the recovery key, you can no longer use method 2.
Once you no longer have access to either method, your identity is estranged and
not accessible by anyone.
### Restore with a recovery key
1. Open the [Blockstack web application in your browser](https://browser.blockstack.org/sign-up?redirect=%2F).
2. Choose **Restore a Blockstack ID**.
The system displays a dialog where you can enter your recovery code or a
recovery key.
3. Enter the recovery key.
The recovery key is a squence of words.
![](images/recovery-code.png)
4. Press **Next**.
The system prompts you for an email address. This email can be one you
entered previously or an entirely new one. Blockstack doesn't store this
address; it is used during your current Blockstack browser interaction to communicate
important information with you.
5. Enter an email and press **Next**.
The system prompts you for an password and its confirmation. This password
can be one you entered previously or an entirely new one. Write this password
down. You can use the password during your current Blockstack browser
interaction to reveal your keychain or change your password. Blockstack does
not store this information past the session.
6. Enter a password and press **Next**.
The system welcomes you back.
![](images/welcome-back.png)
At this point, you can go onto work with Dapps or you can review your recovery key.
### Restore with a recovery code and original password
1. Open the [Blockstack web application in your browser](https://browser.blockstack.org/sign-up?redirect=%2F).
2. Choose **Restore a Blockstack ID**.
The system displays a dialog where you can enter your recovery code or a
recovery key.
3. Enter your recovery code.
The recovery code is an encrypted string.
![](images/recovery-code.png)
4. Press **Next**.
The system prompts you for an email address. This email can be one you
entered previously or an entirely new one. Blockstack doesn't store this
address; it is used during your current Blockstack browser interaction to
communicate important information with you.
5. Enter an email and press **Next**.
The system prompts you for an password. This must be the password entered
when you first created your identity. If you have forgetten this passowrd,
Blockstack cannot provide it to you. Instead, you must switch to using your
recovery key rather than your code to restore your identity.
6. Enter your origin password and press **Next**.
The system welcomes you back.
![](images/welcome-back.png)
At this point, you can go work with Dapps or you can review your recovery key.

161
_newinternet/managing-data-with-gaia.md

@ -1,161 +0,0 @@
---
title: Managing Data with Gaia
description: This series will focus on teaching you to think like a Blockstack developer working with Gaia.
image: /images/tutorials/managing-data-with-gaia.png
---
If you’ve gone through tutorials and documentation for blockstack.js and Gaia,
you’ll know the `blockstack.js` interface is dead simple. First, you
authenticate a user into your app. Once that’s complete, you’re free to read and
write app data in the user’s storage provider with two data operations:
- `putFile`: Writes to a specified path
- `getFile`: Gets the file at a specified path
That’s it. You’re reading files and you’re writing files. All file types are
supported, so you can choose to manage data with sql, markdown, json, or even
your own custom format! Gaia operations are purposefully left primitive so that
you have complete control over which tools you use on top. In the future, we
imagine a variety of data management libraries will emerge that wrap Gaia and
help you interact with your data layer via expressive APIs.
If you’re anything like most developers, you’re probably used to working with
highly abstracted libraries that offer collection management, querying,
pagination, documented schema models, and more. Developing apps on Blockstack is
thrilling because you quickly learn that you don’t need training wheels. You can
create a meaningful and complex data layer using two methods: `putFile` and
`getFile`. This limited interface forces you to think about your fundamental
data architecture and make some decisions about how you’re modeling data to gain
back the benefits you get with large frameworks.
This series will focus on teaching you to think like a Blockstack developer
working with Gaia. Let’s get started!
## Working with Data Collections
For the purposes of this tutorial, let’s pretend that we’re building a simple
grocery list app called Grublist. As a user of Grublist, you should be able to
create, read, update, and delete grocery lists.
Let’s think in terms of JSON since it’s easy and familiar.
### Single-File Collection Approach
Here’s a Single-File Collection approach to modeling our data:
```
// grocerylists.json
{
"3255": {
"items": [
"1 Head of Lettuce",
"Haralson apples"
]
},
// ...more lists with items
}
```
Notice that items are stored as an array nested inside of each grocery list.
This is conceptually the simplest way to manage your grocery lists. It’s very
easy to wrap your brain around what’s going on with the data. When you read the
`/grocerylists.json` file, you get back exactly what you need: grocery lists and
their items. When you write, you’re always writing to one place.
There is one caveat to this approach that you should seriously consider: Every
time you update one of your grocery lists in any way, you’re overwriting the
entire file of all your grocery lists. This is because using the `putFile`
method will overwrite anything at `/grocerylists.json` if it exists, so if
you’re doing a write operation for a new grocery list, you must submit all
previous grocery lists plus the new grocery list.
That’s actually kind of scary, especially considering this code is running on
the client where anything can go wrong. Imagine your client-side code encounters
a parsing error with a user-input value and you overwrite two years worth of a
user’s grocery lists with:
```
"line 6: Parsing Error: Unexpected token ."
```
**To summarize the Single-File Collection approach:**
Pros:
- **Simplified reads**: Just request a single file and get back a list of all your data.
- **Simplified writes**: Some people might be more comfortable working with a Javascript array of items on the client.
Cons:
- **Pagination is impossible**: Using a simple storage strategy like this, you have no choice but to download the entire file of all grocery lists. A user could have 1000 grocery lists, and every time they enter your app they would be forced to download all 1000 grocery lists worth of data.
- **Too heavy-handed**: This is the issue I mentioned above about overwriting an entire file of all grocery lists. Generally, you should try to avoid managing entire collections of data at a time.
- **Less control over file permissions**: You’ll need to perform data acrobatics if you want to share only a single grocery list with a trusted party.
### Multi-File Collection Approach
It would be great if we could split out grocery lists into their own files to
minimize the risk of destroying all the user’s grocery list data and make it
easier to paginate the lists.
Here’s a diagram of a Multi-File Collection approach:
<img src="/images/tutorials/grocery-lists.png" style="max-width: 80%;" />
With this approach, we maintain an index file that stores an array of list IDs.
Each list ID is predictably the name of a file under a `grocerylists` folder.
**To summarize the Multi-File Collection approach:**
Pros:
- **Performant pagination**: Just request the `grocerylists.json` file, and from there you can request as many of the collection items as you need.
- **Less risk of data corruption**: By only manipulating one grocery list at a time, you can guarantee that if something goes wrong with your write operation, it won’t affect the other grocery list data. You might say, “but I still need to overwrite the list of IDs every time I operate.” That’s true, but you can optimize your code so that you’re only updating that file when you add or remove a grocery list. Managing a list of IDs is also much more manageable than a big list of user input data.
- **More control over file permissions**: If you wanted to share only a single grocery list with a trusted party, it’s much easier to do when the list data is isolated to its own file.
Cons
- **More network requests**: If you have 10 grocery lists and want to fetch them all, you’re going to be making 11 network requests. Using HTTP/2 and requesting limited items at a time will help with performance.
- **More complex architecture**: Rather than simply requesting the file of all your data, you now have to request each item individually and stitch them all together once all requests have finished.
### Implementing these approaches
We’ve shown you conceptually how you might think about organizing your data, but
you have not seen much implementation code. Check out the sandbox linked below
for an implementation of services that can accommodate either the single-file or
multi-file approaches for all of your collections.
Note that we’ve included an interstitial “driver” layer for a few reasons:
1. In the sandbox, we’re swapping out the Blockstack driver for a localstorage driver for demonstration purposes.
2. It’s good practice to have all data flow through an interface you control, so that you can add logging or perform other operations.
3. If the `blockstack.js` API changes in the future, you can update your code once in the driver.
4. You can DRY up your code by declaring the Gaia config once per collection.
Click the button below to spin up a sandbox environment:
[![](images/tutorials/edit-sandbox.png)](https://codesandbox.io/s/8kzmjjr9nj)
## Summary
There are many valid ways to organize your data and you should pick what makes
the most sense for your needs. I would recommend using a single-file collection
approach for predictably small collections of data. For larger collections, the
risk of data corruption is too high to be passing around entire collections
worth of data with one `putFile` request, so opt for an architecture that looks
more like the multi-file collection model.
Most importantly, feel free to experiment with data architecture. There are
concepts and patterns you can introduce into this process that can help you
validate schema, migrate data, and more. Check out more of our tutorials for a
deeper dive into developing a sample app.

812
_newinternet/multi-player-storage.md

@ -1,812 +0,0 @@
---
layout: learn
permalink: /:collection/:path.html
---
# Manage Data with Gaia
{:.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.md).
<!--TODO: authentication tutorial-->
<!--Strictly speaking not sure it is necessary here to send them out-->
## 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.md).
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
```
<!-- Need to find out if user is required to have React installed before running Yeoman. Doesn't appear to be the case. -->
## 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 ?
<div className="container">
<div className="row">
<div className="col-md-offset-3 col-md-6">
<div className="col-md-12">
<div className="avatar-section">
<img
src={ person.avatarUrl() ? person.avatarUrl() : avatarFallbackImage }
className="img-rounded avatar"
id="avatar-image"
/>
<div className="username">
<h1>
<span id="heading-name">{ person.name() ? person.name()
: 'Nameless Person' }</span>
</h1>
<span>{username}</span>
<span>
&nbsp;|&nbsp;
<a onClick={ handleSignOut.bind(this) }>(Logout)</a>
</span>
</div>
</div>
</div>
<div className="new-status">
<div className="col-md-12">
<textarea className="input-status"
value={this.state.newStatus}
onChange={e => this.handleNewStatusChange(e)}
placeholder="Enter a status"
/>
</div>
<div className="col-md-12">
<button
className="btn btn-primary btn-lg"
onClick={e => this.handleNewStatusSubmit(e)}
>
Submit
</button>
</div>
</div>
</div>
</div>
</div> : null
);
}
```
This code allows the application to post statuses. It also displays the
user's Blockstack ID. To display this, your app must extract the ID from the
user profile data.
6. Locate the `componentWillMount()` method.
7. Add the `username` property below the `person` property.
You'll use the Blockstack `loadUserData()` method to access the `username`.
```javascript
componentWillMount() {
this.setState({
person: new Person(loadUserData().profile),
username: loadUserData().username
});
}
```
7. Add two methods to handle the status input events:
```javascript
handleNewStatusChange(event) {
this.setState({newStatus: event.target.value})
}
handleNewStatusSubmit(event) {
this.saveNewStatus(this.state.newStatus)
this.setState({
newStatus: ""
})
}
```
8. Add a `saveNewStatus()` method to save the new statuses.
```javascript
saveNewStatus(statusText) {
let statuses = this.state.statuses
let status = {
id: this.state.statusIndex++,
text: statusText.trim(),
created_at: Date.now()
}
statuses.unshift(status)
const options = { encrypt: false }
putFile('statuses.json', JSON.stringify(statuses), options)
.then(() => {
this.setState({
statuses: statuses
})
})
}
```
9. Save the `Profile.jsk` file.
After the application compiles successfully, your application should appears as follows:
![](images/display-complete.png)
10. Enter your status in the text box and press the **Submit** button.
At this point, nothing is blogged. In the next section you add code to display
the statuses back to the user as a blog entry.
## Fetch and display statuses
Update `Profile.jsx` again.
1. Go back to the `render()` method.
2. Locate the `<div className="new-status">` containing the text input and **Submit** button.
3. Right after this opening `div` element, add this block.
```javascript
<div className="col-md-12 statuses">
{this.state.isLoading && <span>Loading...</span>}
{this.state.statuses.map((status) => (
<div className="status" key={status.id}>
{status.text}
</div>
)
)}
</div>
```
This loads existing state. Your code needs to fetch statuses on page load.
4. Add a new method called `fetchData()` after the `statuses.unshift(status)` section.
```javascript
fetchData() {
this.setState({ isLoading: true })
const options = { decrypt: false }
getFile('statuses.json', options)
.then((file) => {
var statuses = JSON.parse(file || '[]')
this.setState({
person: new Person(loadUserData().profile),
username: loadUserData().username,
statusIndex: statuses.length,
statuses: statuses,
})
})
.finally(() => {
this.setState({ isLoading: false })
})
}
```
5. Call `fetchData()` from the `componentDidMount()` method
```javascript
componentDidMount() {
this.fetchData()
}
```
6. Save the file.
After the application compiles successfully, users are able to **Submit**
multiple statuses and review them in the app.
![](images/saving-status.png)
## Change the style
1. Edit the `src/styles/style.css` file.
2. Replace the content with the following:
```css
/* Globals */
a,a:focus,a:hover{color:#fff;}
html,body{height:100%;text-align:center;background-color:#191b22;}
body{color:#fff}
.hide{display:none;}
.landing-heading{font-family:'Lato',Sans-Serif;font-weight:400;}
/* Buttons */
.btn{font-family:'Lato',Sans-Serif;padding:0.5625rem 2.5rem;font-size:0.8125rem;font-weight:400;line-height:1.75rem;border-radius:0!important;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}
.btn-lg{font-size:1.5rem;padding:0.6875rem 3.4375rem;line-height:2.5rem;}
.btn:focus,.btn:active:focus,.btn.active:focus{outline:none;}
.btn-primary{color:#fff;border:1px solid #2C96FF;background-color:#2C96FF;}
.btn-primary:hover,.btn-primary:focus,.btn-primary:active{color:#fff;border:1px solid #1a6ec0;background-color:#1a6ec0;}
/* Avatar */
.avatar{width:100px;height:100px;}
.avatar-section{margin-bottom:25px;display:flex;text-align:left;}
.username{margin-left:20px;}
/* Scaffolding */
.site-wrapper{display:table;width:100%;height:100vh;min-height:100%;}
.site-wrapper-inner{display:flex;flex-direction:column;justify-content:center;margin-right:auto;margin-left:auto;width:100%;height:100vh;}
.panel-authed{padding:0 0 0 0;}
/* Home button */
.btn-home-hello{position:absolute;font-family:'Source Code Pro',monospace;font-size:11px;font-weight:400;color:rgba(255,255,255,0.85);top:15px;left:15px;padding:3px 20px;background-color:rgba(255,255,255,0.15);border-radius:6px;-webkit-box-shadow:0px 0px 20px 0px rgba(0,0,0,0.15);-moz-box-shadow:0px 0px 20px 0px rgba(0,0,0,0.15);box-shadow:0px 0px 20px 0px rgba(0,0,0,0.15);}
/* Input */
input, textarea{color:#000;padding:10px;}
.input-status{width:100%;height:70px;border-radius:6px;}
.new-status{text-align:right;}
/* Statuses */
.statuses{padding-top:30px;}
.status{margin:15px 0px;padding:20px;background-color:#2e2e2e;border-radius:6px}
```
3. Save and close the `src/styles/style.css` file.
After the application compiles, you should see the following:
![Multi-reader storage authentication](images/multi-player-storage-status.png)
At this point, you have a basic micro-blogging app that users can use to post and
view statuses. However, there's no way to view other users' statuses. You'll add
that in the next section.
## Lookup user profiles
Let's now modify the `Profile.jsx` file to display profiles of other users. You'll
be using the `lookupProfile()` method that you added to the `import` statement
earlier. `lookupProfile()` takes a single parameter that is the Blockstack ID of
the profile and returns a profile object.
### Add a new route
Make some changes to the routing structure of your app so that users can view
other users' profiles by visiting `http://localhost:8080/other_user.id`
1. Make sure you are in the root of your `publik` project.
2. Install `react-router`:
```bash
npm install --save react-router-dom
```
3. Edit `src/index.js` file.
4. Add an `import` to the file at the top:
```javascript
import { BrowserRouter } from 'react-router-dom'
```
5. Change the `ReactDOM.render()` method in `src/index.js` to:
```javascript
ReactDOM.render((
<BrowserRouter>
<App />
</BrowserRouter>
), document.getElementById('root'));
```
6. Save and close the `src/index.js` file.
7. Edit the `src/components/App.jsx` file.
8. Add the new route by importing the `Switch` and `Route` components from `react-router-dom`:
```javascript
import { Switch, Route } from 'react-router-dom'
```
9. Locate this line below in the `render()` method:
```javascript
: <Profile handleSignOut={ this.handleSignOut } />
```
10. Replace it with the following:
```javascript
:
<Switch>
<Route
path='/:username?'
render={
routeProps => <Profile handleSignOut={ this.handleSignOut } {...routeProps} />
}
/>
</Switch>
```
This sets up a route and captures the route parameter the app will use as the profile lookup username.
11. Save and close the the `src/components/App.jsx` file.
### Add a rule to process URL paths with . (dot)
You also need to add a rule to your webpack config so that you can properly
process URL paths that contain the `.` (dot) character for example,
`http://localhost:8080/other_user.id`
**NOTE**: In a production app, you must ensure the web server is configured to handle this.
1. Open `webpack.config.js` in the root project directory and locate the following line:
```javascript
historyApiFallback: true,
```
2. Replace it with this:
```javascript
historyApiFallback: {
disableDotRule: true
},
```
You will need to run `npm start` again for this change to take effect. Don't
worry, there is a later step for that to remind you.
3. Save and close the `webpack.config.js` file.
4. Edit the `src/components/Profile.jsx` file.
5. Add a single method that determines if the app is viewing the local user's profile or another user's profile.
```javascript
isLocal() {
return this.props.match.params.username ? false : true
}
```
You use `isLocal()` to check if the user is viewing the local user profile or another user's profile. If it's the local user profile, the app runs the `getFile()` function you added in an earlier step. Otherwise, the app looks up the profile belonging to the `username` using the `lookupProfile()` method.
6. Modify the `fetchData()` method like so:
```javascript
fetchData() {
this.setState({ isLoading: true })
if (this.isLocal()) {
const options = { decrypt: false }
getFile('statuses.json', options)
.then((file) => {
var statuses = JSON.parse(file || '[]')
this.setState({
person: new Person(loadUserData().profile),
username: loadUserData().username,
statusIndex: statuses.length,
statuses: statuses,
})
})
.finally(() => {
this.setState({ isLoading: false })
})
} else {
const username = this.props.match.params.username
lookupProfile(username)
.then((profile) => {
this.setState({
person: new Person(profile),
username: username
})
})
.catch((error) => {
console.log('could not resolve profile')
})
}
}
```
**NOTE**: For `https` deployments, the default Blockstack Core API endpoint for name
lookups should be changed to point to a core API served over `https`.
Otherwise, name lookups fail due to browsers blocking mixed content.
Refer to the [Blockstack.js
documentation](http://blockstack.github.io/blockstack.js/#getfile) for
details.
7. Add the following block to `fetchData()` right after the call to `lookupProfile(username)... catch((error)=>{..}` block:
```javascript
const options = { username: username, decrypt: false }
getFile('statuses.json', options)
.then((file) => {
var statuses = JSON.parse(file || '[]')
this.setState({
statusIndex: statuses.length,
statuses: statuses
})
})
.catch((error) => {
console.log('could not fetch statuses')
})
.finally(() => {
this.setState({ isLoading: false })
})
```
This fetches the user statuses.
Finally, you must conditionally render the logout button, status input textbox, and submit button so they don't show up when viewing another user's profile.
8. Replace the `render()` method with the following:
```javascript
render() {
const { handleSignOut } = this.props;
const { person } = this.state;
const { username } = this.state;
return (
!isSignInPending() && person ?
<div className="container">
<div className="row">
<div className="col-md-offset-3 col-md-6">
<div className="col-md-12">
<div className="avatar-section">
<img
src={ person.avatarUrl() ? person.avatarUrl() : avatarFallbackImage }
className="img-rounded avatar"
id="avatar-image"
/>
<div className="username">
<h1>
<span id="heading-name">{ person.name() ? person.name()
: 'Nameless Person' }</span>
</h1>
<span>{username}</span>
{this.isLocal() &&
<span>
&nbsp;|&nbsp;
<a onClick={ handleSignOut.bind(this) }>(Logout)</a>
</span>
}
</div>
</div>
</div>
{this.isLocal() &&
<div className="new-status">
<div className="col-md-12">
<textarea className="input-status"
value={this.state.newStatus}
onChange={e => this.handleNewStatusChange(e)}
placeholder="What's on your mind?"
/>
</div>
<div className="col-md-12 text-right">
<button
className="btn btn-primary btn-lg"
onClick={e => this.handleNewStatusSubmit(e)}
>
Submit
</button>
</div>
</div>
}
<div className="col-md-12 statuses">
{this.state.isLoading && <span>Loading...</span>}
{this.state.statuses.map((status) => (
<div className="status" key={status.id}>
{status.text}
</div>
)
)}
</div>
</div>
</div>
</div> : null
);
}
```
### This checks to ensure that users are viewing their own profile, by wrapping the **Logout** button and inputs with the `{isLocal() && ...}` condition.
### Put it all together
1. Stop the running application by sending a CTL-C.
2. Restart the application so that the disabling of the `.` (dot) rule takes effect.
```bash
npm start
```
3. Point your browser to `http://localhost:8080/your_blockstack.id` to see the final application.
## Wrapping up
Congratulations, you are all done! We hope you've enjoyed learning a bit more
about Blockstack. To use a working version of the app go
[here](http://publik.ykliao.com).

328
_newinternet/todo-list.md

@ -1,328 +0,0 @@
---
title: Tour of a Blockstack application
description: Walk through creating a basic Todo application with Blockstack. Learn about Sign In flow and Gaia storage.
image: /images/article-photos/chalkboard.jpg
youtube: https://www.youtube.com/embed/oyvg-h0obFw
---
In this tutorial, you build the code for and run a single-page application (SPA)
with Blockstack and Vue.js. Once the application is running, you take a tour
through the applications' Blockstack functionality. You'll learn how it manages
authentiation using a Blockstack ID and how it stores information associated
with that ID using Blockstack Storage (Gaia).
## Prerequisites
Make sure you have [created at least one Blockstack ID](ids-introduction.md#create-an-initial-blockstack-id). You'll use this ID to Finteract with the Todo application.
The applicaton code relies on both the `npm` and the `yarn` package managers.
Before you begin, verify you have these tools `npm` using the `which` command to
verify.
```bash
$ which npm
/usr/local/bin/npm
$ which yarn
/usr/local/bin/yarn
```
[Install npm](https://www.npmjs.com/get-npm), [install
yarn](https://yarnpkg.com/lang/en/docs/install/#mac-stable), or both as needed. You
While it stands alone, this tour does on the information from the [Hello
Blockstack tutorial](hello-blockstack.md). If you haven't worked through that
tutorial, you may want to do that before continuing.
## Install the applicaton code and retrieve the dependencies
You can clone the source code with `git` or [download and unzip the code from
the
repository](https://github.com/blockstack/blockstack-todos/archive/master.zip).
These instructions assume you are cloning.
1. Install the code by cloning it.
```
$ git clone git@github.com:blockstack/blockstack-todos.git
```
2. Change to directory to the root of the code.
```
$ cd blockstack-todos
```
2. Use yarn to install the dependencies.
```
$ yarn install
yarn install v1.9.2
info No lockfile found.
...
[4/5] 🔗 Linking dependencies...
[5/5] 📃 Building fresh packages...
success Saved lockfile.
✨ Done in 19.90s.
```
## Understand the important application files
The Todo application has a basic Vue.js structure. There are several configuration files but the central programming files are in the `src` directory:
| File | Description |
|-----------------|-------------|
| `main.js` | Application initialization. |
| `App.vue ` | Code for handling the `authResponse`. |
| `Landing.vue ` | Code for the initial sign on page. |
| `Dashboard.vue` | Application data storage and user sign out. |
The example application runs in a node server on your local host. In the next section, you start the application and interact with it.
1. Start the application.
```
$ npm run start
```
You should see a simple application:
![](images/todo-sign-in.png)
2. Choose **Sign In with Blockstack**.
## Understand the sign in process
At startup, the Todo application detects whether the user has the Blockstack client edition
installed or not. This is done automatically by the Blockstack API, more
about this later. What the authenticator displays depends on which whether the user has installed the Blockstack Authenticator client edition or not.
| Client edition installed | Not installed |
|------------------|-----------------------------------|
| ![](images/login.gif) | ![](images/login-choice.png)|
If the user was logged into the Blockstack authenticator (web or client) but
did not reset it, the web application to use the current identity:
![](images/login-no-auth.png)
If the user chooses **Deny**, the Blockstack authenticator opens but the user
is not logged into the sample application.
![](images/windows-browser.png)
If the login to the application is successful, the user is presented with the application:
![](images/todo-app.png)
Clicking the **Sign In With Blockstack** button brings up a modal that prompts
you to use an existing ID's session, create a new ID, or reset the browser with
another ID. When Blockstack is provided an ID, it generates an _ephemeral key_
within the application. An ephemeral key is generated for each execution of a
key establishment process. This key is just used for the particular instance of
the application, in this case to sign a **Sign In** request.
Blockstack also generates a public key token which is sent to the authenticator
as an `authRequest` from the authenticator to your local blockstack-core node.
The signed authentication request is sent to Blockstack through a JSON Web
Token. The JWT is passed in via a URL query string in the `authRequest`
parameter:
`https://browser.blockstack.org/auth?authRequest=j902120cn829n1jnvoa...`. To
decode the token and see what information it holds:
1. Copy the `authRequest` string from the URL.
2. Navigate to [jwt.io](http://jwt.io/).
3. Paste the full token there.
The output should look similar to below:
```json
{
"jti": "3i96e3ad-0626-4e32-a316-b243154212e2",
"iat": 1533136622,
"exp": 1533140228,
"iss": "did:btc-addr:1Nh8oQTunbEQWjrL666HBx2qMc81puLmMt",
"public_keys": [
"0362173da080c6e1dec0653fa9a3eff5f5660546e387ce6c24u04a90c2fe1fdu73"
],
"domain_name": "http://localhost:8080",
"manifest_uri": "http://localhost:8080/manifest.json",
"redirect_uri": "http://localhost:8080/",
"version": "1.2.0",
"do_not_include_profile": true,
"supports_hub_url": true,
"scopes": [
"store_write"
]
}
```
>**Note**:
> 1. The `iss` property is a decentralized identifier or `did`. This identifies you and your name to the application. The specific `did` is a `btc-addr`.
> 2. The Blockstack JWT implementation is different from other implementations because of the underlying cryptography we employ. There are libraries in [Javascript](https://github.com/blockstack/jsontokens-js) and [Ruby](https://github.com/blockstack/ruby-jwt-blockstack) available on the Blockstack Github to allow you to work with these tokens.
When the blockstack-core receives the `authRequest`, it generates a session token and
returns an authentication response to the application. This response is similar
to the `authRequest` above in that the `authResponse` includes a private key
intended only for the application. This allows the application to encrypt data
on your personal Blockstack storage.
You are now logged into the Todo application!
## Undder the covers in the sign in code
Now, go to the underlying `blockstack-todo` code you cloned or downloaded. Sign
in and sign out is handled in each of these files:
| File | Description |
|-----------------|-------------|
| `App.vue ` | Handles the `authResponse`. |
| `Landing.vue ` | Generates the `authRequest`. |
| `Dashboard.vue` | Handles sign out. |
The `src/components/Landing.vue` code calls a [`redirectToSignIn()`](https://blockstack.github.io/blockstack.js#redirectToSignIn) function which generates the `authRequest` and redirects the user to the Blockstack authenticator:
```js
signIn () {
const blockstack = this.blockstack
blockstack.redirectToSignIn()
}
```
Once the user authenticates, the application handles the `authResponse` in the `src/App.vue` file. :
```js
if (blockstack.isUserSignedIn()) {
this.user = blockstack.loadUserData().profile
} else if (blockstack.isSignInPending()) {
blockstack.handlePendingSignIn()
.then((userData) => {
window.location = window.location.origin
})
}
```
If [`blockstack.isUserSignedIn()`](https://blockstack.github.io/blockstack.js/#isusersignedin) is true, the user was previously signed in so Blockstack pulls the data from the browser and uses it in our application. If the check on [`blockstack.isSignInPending()`](https://blockstack.github.io/blockstack.js/#issigninpending) is true, a previous `authResponse` was sent to the application but hasn't been processed yet. The `handlePendingSignIn()` function processes any pending sign in.
Signout is handled in `src/components/Dashboard.vue`.
```js
signOut () {
this.blockstack.signUserOut(window.location.href)
}
```
The method allows the application creator to decide where to redirect the user upon Sign Out:
## Working with the application
Now trying adding a few todos using the application. For example, try making a list of applications you want to see built on top of Blockstack:
![](images/make-a-list.png)
Each list is immediately stored in the Gaia Hub linked to your Blockstack ID.
For more information about the Gaia hub, see the [hub
repository](https://github.com/blockstack/gaia). You can fetch the `todos.json`
file you just added by opening the Javascript console and running the following
command:
```Javascript
blockstack.getFile("todos.json", { decrypt: true }).then((file) => {console.log(file)})
```
You should see a JSON with the todos you just added:
```json
[
{
"id":2,
"text":"Software package manager secured by the blockchain",
"completed":false
},
{
"id":1,
"text":"Mutable torrents with human readable names",
"completed":false
},
{
"id":0,
"text":"Decentralized twitter",
"completed":false
}
]
```
Now, add another todo and check it off. When you fetch the newly generated file
using the Javascript console it will reflect the change look for `"completed":true`:
```json
[
{
"id":3,
"text":"Blockstack Todo",
"completed":true
},
{
"id":2,
"text":"Software package manager secured by the blockchain",
"completed":false
},
...
]
```
Now that you have seen the application in action, dig into how it works.
## Implementing storage
Now, go to the underlying `blockstack-todo` code you cloned or downloaded. The
application interactions with your Gaia Hub originate in the
`src/components/Dashboard.vue` file. First lets see where the changes to the
Todos are processed:
```js
todos: {
handler: function (todos) {
const blockstack = this.blockstack
// encryption is now enabled by default
return blockstack.putFile(STORAGE_FILE, JSON.stringify(todos))
},
deep: true
}
```
Tje `todos` JSON object is passed in and the [`blockstack.putFile()`](https://blockstack.github.io/blockstack.js/#putfile) method to store it in our Gaia Hub.
The code needs to read the Todo items from the storage with the [`blockstack.getFile()`](https://blockstack.github.io/blockstack.js/#getfile) method which returns a promise:
```js
fetchData () {
const blockstack = this.blockstack
blockstack.getFile(STORAGE_FILE) // decryption is enabled by default
.then((todosText) => {
var todos = JSON.parse(todosText || '[]')
todos.forEach(function (todo, index) {
todo.id = index
})
this.uidCount = todos.length
this.todos = todos
})
},
```
The `todos` data is retrieved from the promise.
## Summary
You now have everything you need to construct complex applications complete with authentication and storage on the Decentralized Internet. Why not try coding [a sample application that accesses multiple profiles](multi-player-storage.md).
If you would like to explore the Blockstack APIs, you can visit the [Blockstack Core API](https://core.blockstack.org/) documentation or the [Blockstack JS API](https://blockstack.github.io/blockstack.js).
Go forth and build!

62
_plugins/include_absolute.rb

@ -0,0 +1,62 @@
# Allows for relative links includes
module Jekyll
class IncludeTagError < StandardError
attr_accessor :path
def initialize(msg, path)
super(msg)
@path = path
end
end
class IncludeAbsoluteTag < Liquid::Tag
VARIABLE_SYNTAX = %r!
(?<variable>[^{]*(\{\{\s*[\w\-\.]+\s*(\|.*)?\}\}[^\s{}]*)+)
(?<params>.*)
!x
def initialize(tag_name, markup, tokens)
super
@file = markup.strip
end
# Render the variable if required (@see https://goo.gl/N5sMV3)
def render_variable(context)
if @file.match(VARIABLE_SYNTAX)
partial = context.registers[:site]
.liquid_renderer
.file("(variable)")
.parse(@file)
partial.render!(context)
end
end
def render(context)
file = render_variable(context) || @file
source = File.expand_path(context.registers[:site].config['source']).freeze
path = File.join(source, file)
begin
partial = Liquid::Template.parse(read_file(path, context))
context.stack do
context['include'] = parse_params(context) if @params
partial.render!(context)
end
rescue => e
raise IncludeTagError.new e.message, path
end
end
def read_file(file, context)
File.read(file, file_read_opts(context))
end
def file_read_opts(context)
context.registers[:site].file_read_opts
end
end
end
Liquid::Template.register_tag('include_absolute', Jekyll::IncludeAbsoluteTag)

101
_site/android/tutorial.html

@ -17,9 +17,9 @@
<meta property="og:url" content="https://zbabystack.netlify.com/android/tutorial.html" />
<meta property="og:site_name" content="Blockstack" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2018-09-08T19:24:57-07:00" />
<meta property="article:published_time" content="2018-09-10T15:18:11-07:00" />
<script type="application/ld+json">
{"description":"Android SDK Tutorial (Pre-release)","author":{"@type":"Person","name":"Blockstack"},"@type":"BlogPosting","url":"https://zbabystack.netlify.com/android/tutorial.html","headline":"Android SDK Tutorial (Pre-release)","dateModified":"2018-09-08T19:24:57-07:00","datePublished":"2018-09-08T19:24:57-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://zbabystack.netlify.com/android/tutorial.html"},"@context":"http://schema.org"}</script>
{"description":"Android SDK Tutorial (Pre-release)","author":{"@type":"Person","name":"Blockstack"},"@type":"BlogPosting","url":"https://zbabystack.netlify.com/android/tutorial.html","headline":"Android SDK Tutorial (Pre-release)","dateModified":"2018-09-10T15:18:11-07:00","datePublished":"2018-09-10T15:18:11-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://zbabystack.netlify.com/android/tutorial.html"},"@context":"http://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<!-- <meta property="og:image" content="https://zbabystack.netlify.com/assets/posts/logo.png"/> -->
@ -99,23 +99,28 @@
<div class="sidebar-fixed-width uk-visible@m">
<div class="sidebar-docs uk-position-fixed">
<!-- -->
<h5>Try a tutorial</h5>
<ul class="uk-nav uk-nav-default doc-nav">
<!-- -->
<li class=""><a href="/newinternet/hello-blockstack.html">Hello, Blockstack Tutorial</a></li>
<li class=""><a href="/browser/hello-blockstack.html">Hello, Blockstack Tutorial</a></li>
<!-- -->
<li class=""><a href="/newinternet/multi-player-storage.html">Manage Data with Gaia</a></li>
<li class=""><a href="/browser/multi-player-storage.html">Manage Data with Gaia</a></li>
</ul>
<h5>Work with an SDK</h5>
<ul class="uk-nav uk-nav-default doc-nav">
@ -130,6 +135,24 @@
</ul>
<h5>Reference</h5>
<ul class="uk-nav uk-nav-default doc-nav">
<!-- -->
<li class=""><a href="/core/faq_developer.html">Developer FAQs</a></li>
<!-- -->
<li class=""><a href="/common/javascript_ref.html">Blockstack Javascript Reference</a></li>
</ul>
<!-- -->
</div>
</div>
@ -141,6 +164,7 @@
<div class="uk-article-meta uk-margin-top uk-margin-medium-bottom">
@ -152,13 +176,13 @@
<!-- Written by <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Blockstack</span></span><br> -->
<time datetime="2018-09-08T19:24:57-07:00" itemprop="datePublished">
<time datetime="2018-09-10T15:18:11-07:00" itemprop="datePublished">
<a "target="_blank" href="https://github.com/blockstack/blockstack-android/blob/master/docs/tutorial.md" class="btn btn-default githubEditButton" role="button">
<span data-uk-icon="icon: pencil; ratio: 1.2"></span> Edit this page on Github</a>
<span style="font-family:Wingdings">&#119;</span> Sep 8, 2018
<span style="font-family:Wingdings">&#119;</span> Sep 10, 2018
</time>
</div>
@ -226,7 +250,7 @@ application by doing the following:</p>
<h2 id="set-up-your-environment">Set up your environment</h2>
<p>This sample application has two code bases, a BlockStack <code class="highlighter-rouge">hello-blockstack</code>
<p>This sample application has two code bases, a Blockstack <code class="highlighter-rouge">hello-blockstack</code>
application and a <code class="highlighter-rouge">hello-andriod</code> Android application. Before you start
developing the sample, there are a few elements you need in your environment.</p>
@ -260,13 +284,13 @@ it</a>.</p>
<h3 id="install-the-blockstack-test-rig">Install the Blockstack test rig</h3>
<p>Users interact with Blockstack-enabled applications through a web browser. You
can BlockStack in test mode, on <code class="highlighter-rouge">localhost</code> or you can interact with completed
can Blockstack in test mode, on <code class="highlighter-rouge">localhost</code> or you can interact with completed
apps through the Blockstack webapp which is available at
[https://browser.blockstack.org/].</p>
<p>If you have already installed Blockstack for testing locally and have an
existing Blockstack ID, skip this section. Otherwise, continue onto install
BlockStack.</p>
Blockstack.</p>
<ol>
<li>
@ -581,6 +605,16 @@ iniatial state by creating an emulator to run it in. Open Android Studio and do
<ol>
<li>In studio, open the <code class="highlighter-rouge">AndroidManifest.xml</code> file.</li>
<li>
<p>Add the a <code class="highlighter-rouge">launchMode</code> to the <code class="highlighter-rouge">.MainActivity</code> definition.</p>
<pre><code class="language-XML"> &lt;activity android:name=".MainActivity" android:launchMode="singleTask"&gt;
</code></pre>
<p>Blockstack requires that the activity that starts the sign-in process also
handles the auth reponse token. This means that the activity needs to run in
<code class="highlighter-rouge">singleTask</code> launch mode.</p>
</li>
<li>
<p>Add an <code class="highlighter-rouge">&lt;intent-filter&gt;</code> with the custom handler for Blockstack.</p>
@ -762,7 +796,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
</div>
</li>
<li>
<p>Replae the existing the <code class="highlighter-rouge">onCreate</code> function with the following:</p>
<p>Replace the existing the <code class="highlighter-rouge">onCreate</code> function with the following:</p>
<div class="language-kotlin highlighter-rouge"><pre class="highlight"><code> <span class="k">override</span> <span class="k">fun</span> <span class="nf">onCreate</span><span class="p">(</span><span class="n">savedInstanceState</span><span class="p">:</span> <span class="n">Bundle</span><span class="p">?)</span> <span class="p">{</span>
<span class="k">super</span><span class="p">.</span><span class="n">onCreate</span><span class="p">(</span><span class="n">savedInstanceState</span><span class="p">)</span>
@ -1023,49 +1057,7 @@ know about your experience by tweeting to
<div class="uk-margin-large-top">
<!-- <div class="uk-margin-large-top">
<h3>Related Articles</h3>
@ -1076,8 +1068,7 @@ know about your experience by tweeting to
</ul>
</div>
-->
</article>

29
_site/browser/README.md

@ -1,4 +1,27 @@
# Docs
# Tutorials
- [Dependencies](/docs/dependencies.md)
- [Pixels to REM Units](/docs/px-rem.md)
**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.

123
_site/newinternet/browser-introduction.html → _site/browser/browser-introduction.html

@ -6,20 +6,20 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Begin Jekyll SEO tag v2.5.0 -->
<title>Use the Blockstack Authenticator | Blockstack</title>
<title>Use the Blockstack Browser | Blockstack</title>
<meta name="generator" content="Jekyll v3.8.3" />
<meta property="og:title" content="Use the Blockstack Authenticator" />
<meta property="og:title" content="Use the Blockstack Browser" />
<meta name="author" content="Blockstack" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Use the Blockstack Authenticator" />
<meta property="og:description" content="Use the Blockstack Authenticator" />
<link rel="canonical" href="https://zbabystack.netlify.com/newinternet/browser-introduction.html" />
<meta property="og:url" content="https://zbabystack.netlify.com/newinternet/browser-introduction.html" />
<meta name="description" content="Use the Blockstack Browser" />
<meta property="og:description" content="Use the Blockstack Browser" />
<link rel="canonical" href="https://zbabystack.netlify.com/browser/browser-introduction.html" />
<meta property="og:url" content="https://zbabystack.netlify.com/browser/browser-introduction.html" />
<meta property="og:site_name" content="Blockstack" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2018-09-08T19:24:57-07:00" />
<meta property="article:published_time" content="2018-09-10T15:18:11-07:00" />
<script type="application/ld+json">
{"description":"Use the Blockstack Authenticator","author":{"@type":"Person","name":"Blockstack"},"@type":"BlogPosting","url":"https://zbabystack.netlify.com/newinternet/browser-introduction.html","headline":"Use the Blockstack Authenticator","dateModified":"2018-09-08T19:24:57-07:00","datePublished":"2018-09-08T19:24:57-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://zbabystack.netlify.com/newinternet/browser-introduction.html"},"@context":"http://schema.org"}</script>
{"description":"Use the Blockstack Browser","author":{"@type":"Person","name":"Blockstack"},"@type":"BlogPosting","url":"https://zbabystack.netlify.com/browser/browser-introduction.html","headline":"Use the Blockstack Browser","dateModified":"2018-09-10T15:18:11-07:00","datePublished":"2018-09-10T15:18:11-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://zbabystack.netlify.com/browser/browser-introduction.html"},"@context":"http://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<!-- <meta property="og:image" content="https://zbabystack.netlify.com/assets/posts/logo.png"/> -->
@ -102,19 +102,22 @@
<!-- -->
<h5>Get started</h5>
<ul class="uk-nav uk-nav-default doc-nav">
<!-- -->
<li class="uk-active"><a href="/newinternet/browser-introduction.html">Use the Blockstack Authenticator</a></li>
<li class=""><a href="/browser/ids-introduction.html">Get and use a Blockstack ID</a></li>
<!-- -->
<li class="uk-active"><a href="/browser/browser-introduction.html">Use the Blockstack Browser</a></li>
<!-- -->
<li class=""><a href="/newinternet/ids-introduction.html">Get and use a Blockstack ID</a></li>
<li class=""><a href="/browser/faq_general.html">Users Frequently Asked Questions (FAQ)</a></li>
</ul>
@ -126,7 +129,7 @@
<article class="uk-article">
<h1 class="uk-article-title">Use the Blockstack Authenticator</h1>
<h1 class="uk-article-title">Use the Blockstack Browser</h1>
@ -142,28 +145,28 @@
<!-- Written by <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Blockstack</span></span><br> -->
<time datetime="2018-09-08T19:24:57-07:00" itemprop="datePublished">
<time datetime="2018-09-10T15:18:11-07:00" itemprop="datePublished">
<a "target="_blank" href="https://github.com/moxiegirl/docs-new/blob/master/docs/browser-introduction.md" class="btn btn-default githubEditButton" role="button">
<a "target="_blank" href="https://github.com/blockstack/blockstack-browser/blob/master/docs/browser-introduction.md" class="btn btn-default githubEditButton" role="button">
<span data-uk-icon="icon: pencil; ratio: 1.2"></span> Edit this page on Github</a>
<span style="font-family:Wingdings">&#119;</span> Sep 8, 2018
<span style="font-family:Wingdings">&#119;</span> Sep 10, 2018
</time>
</div>
<div class="article-content">
<p class="no_toc">lockstack Authenticator gives users the ability to explore and use the
<p class="no_toc">The Blockstack Browser gives users the ability to explore and use the
decentralized applications (dapps). The decentralized applications are a new way
to interact with the internet. Dapps give users control of their data. Data
about them personally, name, birthdate, phone number and data about what they do
such as visiting a website or buying an item.</p>
<ul id="markdown-toc">
<li><a href="#understand-the-blockstack-authenticator" id="markdown-toc-understand-the-blockstack-authenticator">Understand the Blockstack Authenticator</a></li>
<li><a href="#using-the-authenticator-on-public-computers" id="markdown-toc-using-the-authenticator-on-public-computers">Using the Authenticator on public computers</a></li>
<li><a href="#understand-the-blockstack-browser" id="markdown-toc-understand-the-blockstack-browser">Understand the Blockstack Browser</a></li>
<li><a href="#using-the-browser-on-public-computers" id="markdown-toc-using-the-browser-on-public-computers">Using the Browser on public computers</a></li>
<li><a href="#install-the-client-edition" id="markdown-toc-install-the-client-edition">Install the client edition</a> <ul>
<li><a href="#on-mac" id="markdown-toc-on-mac">On Mac</a></li>
<li><a href="#on-windows" id="markdown-toc-on-windows">On Windows</a></li>
@ -178,11 +181,11 @@ such as visiting a website or buying an item.</p>
</li>
</ul>
<h2 id="understand-the-blockstack-authenticator">Understand the Blockstack Authenticator</h2>
<h2 id="understand-the-blockstack-browser">Understand the Blockstack Browser</h2>
<p>Through the Blockstack authemticator application you can create an identity. An identity
<p>Through the Blockstack browser application you can create an identity. An identity
represents you as you interact with others through Dapps. The Blockstack
authenticator is itself, a smiple Dapp. It allows you to:</p>
Browser is itself, a simple Dapp. It allows you to:</p>
<ul>
<li>create one or more identities</li>
@ -191,39 +194,39 @@ authenticator is itself, a smiple Dapp. It allows you to:</p>
<li>find and launch Dapps</li>
</ul>
<p>There are editorions of the Blockstack Authenticator, the web edition is an
<p>There are editorions of the Blockstack Browser, the web edition is an
application you access through your web browser by simply <a href="https://browser.blockstack.org/">visit the
applications’ address</a> in your computer’s
browser. You can also install the authenticator as a client application on your
browser. You can also install the browser as a client application on your
computer.</p>
<p>If all you want to do is create, manage, and fund an identity and then interact
with Dapps, you can simply use the web edition. If you have concerns about net
censorship, hightened security concerns, or develop a Dapp yourself, you may
want to download and install the authenticator’s client edition.</p>
want to download and install the browser’s client edition.</p>
<h2 id="using-the-authenticator-on-public-computers">Using the Authenticator on public computers</h2>
<h2 id="using-the-browser-on-public-computers">Using the Browser on public computers</h2>
<p>Before you use the web application, it is important to note that once you log
into the application with the brower, your session does not expire until you
choose <strong>Settings &gt; RESET BROWSER</strong>. For this reason, you should be careful
when using the authenticator on public computers.</p>
when using the browser on public computers.</p>
<p>If you are in a library, for example, and log into the authenticator, simply
<p>If you are in a library, for example, and log into the browser, simply
closing the tab or even rebooting the computer does not log you out. Instead,
you should be sure to choose <strong>Settings &gt; RESET BROWSER</strong> before leaving the web
application.</p>
<p>For more informatin about your identity and the authenticator, see <a href="ids-introduction.md">Get and use a Blockstack IDs</a>.</p>
<p>For more informatin about your identity and the browser, see <a href="ids-introduction.md">Get and use a Blockstack IDs</a>.</p>
<h2 id="install-the-client-edition">Install the client edition</h2>
<p>Remember, for most users the Blockstack Authenticator web application should
<p>Remember, for most users the Blockstack Browser web application should
suffice. You only need to install the client if you have additional, advanced
concerns about Internet or identity. Though not required, some Dapp developrs
may find it useful to install the client edition.</p>
<p>The Blockstack Authenticator installer is a <em>multiple-context</em> installer. If you
<p>The Blockstack Browser installer is a <em>multiple-context</em> installer. If you
run it as a user, the installation is avalable only for that user. If you
install as administrator, the installation installs for all users. To find an
installer for your operating system, visit <a href="https://blockstack.org/install">the Blockstack install
@ -251,7 +254,7 @@ page</a>.</p>
<li>
<p>Choose <strong>Open</strong>.</p>
<p>The system opens your default browser with the Blockstack Authenticator
<p>The system opens your default browser with the Blockstack Browser
application, running from your machine (localhost). You’ll also see the
Blockstack icon in your machine’s</p>
@ -277,7 +280,7 @@ install:</p>
<p><img src="images/windows-installer.png" alt="" /></p>
</li>
<li>
<p>Open the Wiindows <strong>Start</strong> menu and click on the recently added <strong>Blockstack Authenticator</strong>.</p>
<p>Open the Wiindows <strong>Start</strong> menu and click on the recently added <strong>Blockstack Browser</strong>.</p>
<p><img src="images/windows-start.png" alt="" /></p>
@ -288,7 +291,7 @@ install:</p>
<li>
<p>Choose to <strong>Allow access</strong>.</p>
<p>The system opens in the Blockstack Authenticator application.</p>
<p>The system opens in the Blockstack Browser application.</p>
<p><img src="images/windows-browser.png" alt="" /></p>
</li>
@ -368,7 +371,7 @@ the version of Docker appropriate for your operating system&lt;/a&gt;.</p>
</code></pre>
</div>
<p>The system launches the Blockstack Authenticator application for you.</p>
<p>The system launches the Blockstack Browser application for you.</p>
<p><img src="images/ubuntu-browser.png" alt="" /></p>
</li>
@ -382,7 +385,7 @@ the <code class="highlighter-rouge">docker container ls</code> command.</p>
</code></pre>
</div>
<p>Use <code class="highlighter-rouge">./Blockstack-for-Linux-vO.30.0.sh stop</code> to stop the Blockstack Authenticator and its containers.</p>
<p>Use <code class="highlighter-rouge">./Blockstack-for-Linux-vO.30.0.sh stop</code> to stop the Blockstack Browser and its containers.</p>
<h2 id="uninstall-the-browser">Uninstall the browser</h2>
@ -428,7 +431,7 @@ your operating system.</p>
<p><img src="images/eject-blockstack.png" alt="" /></p>
</li>
<li>
<p>Locate the <strong>Blockstack Authenticator</strong> and choose <strong>Uninstall</strong>.</p>
<p>Locate the <strong>Blockstack Browser</strong> and choose <strong>Uninstall</strong>.</p>
<p><img src="images/browser-uninstall.png" alt="" /></p>
</li>
@ -490,8 +493,8 @@ but that is not explained here.</p>
</ol>
<div class="share uk-text-center">
<a href="https://twitter.com/intent/tweet?text=Use the Blockstack Authenticator&url=https://zbabystack.netlify.com/newinternet/browser-introduction.html&via=&related=" rel="nofollow" target="_blank" title="Share on Twitter" onclick="window.open(this.href, 'twitter', 'width=550,height=235');return false;"><span data-uk-icon="icon: twitter; ratio: 1.2"></span></a>
<a class="uk-margin-small-left" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fzbabystack.netlify.com%2Fnewinternet%2Fbrowser-introduction.html" rel="nofollow" target="_blank" title="Share on Facebook" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;"><span data-uk-icon="icon: facebook; ratio: 1.2"></span></a>
<a href="https://twitter.com/intent/tweet?text=Use the Blockstack Browser&url=https://zbabystack.netlify.com/browser/browser-introduction.html&via=&related=" rel="nofollow" target="_blank" title="Share on Twitter" onclick="window.open(this.href, 'twitter', 'width=550,height=235');return false;"><span data-uk-icon="icon: twitter; ratio: 1.2"></span></a>
<a class="uk-margin-small-left" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fzbabystack.netlify.com%2Fbrowser%2Fbrowser-introduction.html" rel="nofollow" target="_blank" title="Share on Facebook" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;"><span data-uk-icon="icon: facebook; ratio: 1.2"></span></a>
</div>
</div>
@ -503,48 +506,6 @@ but that is not explained here.</p>
<!-- <div class="uk-margin-large-top">
<h3>Related Articles</h3>

80
_site/browser/dependencies.md

@ -1,80 +0,0 @@
# Dependencies
### ReactJS
ReactJS is a "declarative, efficient, and flexible JavaScript library for building user interfaces."
- "**Just the UI**: Lots of people use React as the V in MVC. Since React makes no assumptions about the rest of your technology stack, it's easy to try it out on a small feature in an existing project."
- "**Virtual DOM**: React uses a virtual DOM diff implementation for ultra-high performance. It can also render on the server using Node.js — no heavy browser DOM required."
- "**Data flow**: React implements one-way reactive data flow which reduces boilerplate and is easier to reason about than traditional data binding."
The ReactJS files are all located within `/app/js`, structured in the following manner:
```
/components
- Footer.js (Simple, static footer component rendered on all pages.)
- Header.js (Simple, static header component rendered on all pages.)
/pages
- HomePage.js (Example home page, serving as the default route.)
- NotFoundPage.js (Displayed any time the user requests a non-existent route.)
- SearchPage.js (Example search page to demonstrate navigation and individual pages.)
/utils
- APIUtils.js (General wrappers for API interaction via Superagent.)
- AuthAPI.js (Example functions for user authorization via a remote API.)
App.js (The main container component, rendered to the DOM and then responsible for rendering all pages.)
index.js (The main javascript file watched by Browserify, responsible for requiring the app and running the router.)
Routes.js (Defines the routing structure, along with each individual route path and handler.)
```
Each module you add to your project should be placed in the appropriate directory, and required in the necessary files. Once required, they will be automatically detected and compiled by Browserify (discussed later).
---
### RefluxJS
RefluxJS is a "simple library for unidirectional dataflow architecture inspired by ReactJS Flux."
"The pattern is composed of actions and data stores, where actions initiate new data to pass through data stores before coming back to the view components again. If a view component has an event that needs to make a change in the application's data stores, they need to do so by signalling to the stores through the actions available."
The RefluxJS files are also all locationed within `/app/js`, structured in the following manner:
```
/actions
- CurrentUserActions.js (Possible actions relevant to the current user. i.e. `checkAuth`, `login`, and `logout`.)
/stores
- CurrentUserStore.js (Responsible for storing the current user data, while listening to any `CurrentUserActions`.)
```
Each action or store you add to your project should be placed in the appropriate directory, and required in the necessary files. The necessary logic to trigger actions and listen to stores should also be added.
---
### React Router
React Router is a "complete routing library for React." It uses the JSX syntax to easily define route URLs and handlers, providing an easy-to-understand architecture and thus makes it easy to add new pages and routes.
The relevant files are all located within `/app/js`, structured in the following manner:
```
/pages (Each individual page to handle the defined routes and be rendered inside the app.)
App.js (The main component which is rendered to the DOM and responsible for rendering the current page.)
index.js (The main javascript file watched by Browserify, requiring the app and running the router.)
Routes.js (Defines the routing structure, along with each individual route path and handler.)
```
Any pages added to your project should be placed within the `app/js/pages` directory, and be required and assigned to a route inside `Routes.js`. If more complex nesting is required, any page can have a new `RouteHandler` as a child component.
---
### SASS
SASS, standing for 'Syntactically Awesome Style Sheets', is a CSS extension language adding things like extending, variables, and mixins to the language. This boilerplate provides a barebones file structure for your styles, with explicit imports into `app/styles/main.scss`. A Gulp task (discussed later) is provided for compilation and minification of the stylesheets based on this file.
---
### Webpack
Webpack bundles all of our code and assets and organizes any manipulation to
them with modules like `babel`. It also handles hot reloading in development,
and minification in production. You can find the configuration for it in
`webpack.config.js` in the root directory.

46
_site/browser/design.md

@ -1,46 +0,0 @@
# Blockstack Human Interface Design Guide
Blockstack is a progressive open source platform that values user experience and usercentric design. As a result of this passion we have developed design elements and recommendations to assist developers building on Blockstack to quickly and easily provide an optimal and consistent user experience.
## Status Bar
The reasoning behind the Blockstack browser status bar is to provide users with an intuitive way to navigate back to their home screen and possibly other useful information.
What we have discovered in building these new decentralized applications was that, if the developer is left with creating their own home screen button they will place it in a consistent position than it's application peers.
The other secondary objective of the Blockstack browser status bar is to provide developers with a quick and easy way to implement this global standard. It is imperative that developers can quickly and easily grab a small snippet of code, paste it into their application and deploy.
### Positioning & sizing
The Blockstack browser status bar is a appears along the upper edge of the screen with a full width. `width: 100%;`. And height of `height: 38px;`.
Although the developer may choose to utilize either the `status-bar-light`, `status-bar status-bar-dark`, `status-bar status-bar-transparent-light` or `status-bar status-bar-transparent-dark` status bar, we highly recommend leaving the top 38px the space required for future information that may appear in the status bar.
### Fonts
Size: Status Bar font size is 12px `font-size: 12px;`. The font is small as some elements are placed in the highest real estate regions of the Document Object Model (DOM).
Font-family: other than symbols, the font-family for the status bar is
```
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
```
_NOTE: Further research on this has revealed a strong case for going with a traditional [web safe font](https://en.wikipedia.org/wiki/Web_typography#Web-safe_fonts) such as **Arial** or even going with a **Helvetica** with a fall-back font of **Arial** would be better than setting the brand type to be a third party typeface that requires installation and/or use of an API._
### Symbols
The status bar utilizes symbols from the [Font Awesome](http://fontawesome.io/) desktop/web font.
#### Current symbols
| Symbol | Class Name | Cheat Sheet Visual |
| ------------- | ------------- | ------------- |
| **Home screen arrow** | `fa-angle-left [&#xf104;]` | <img width="164" alt="screenshot 2017-03-17 16 08 25" src="https://cloud.githubusercontent.com/assets/1711854/24061005/16a01ad2-0b2c-11e7-87ea-969558bf2f5c.png"> |
Reference:
- http://fontawesome.io/cheatsheet/
### Best practices
We highly recommend utilizing one of the 4 status bar options to choose from;
`status-bar status-bar-light`
`status-bar status-bar-dark`
`status-bar status-bar-transparent-light`
`status-bar status-bar-transparent-dark`
<img width="1148" alt="screenshot 2017-03-23 15 30 25" src="https://cloud.githubusercontent.com/assets/1711854/24266578/a8923dd4-0fdd-11e7-9994-e6a5d564f6a4.png">

429
_site/browser/faq_general.html

@ -0,0 +1,429 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Begin Jekyll SEO tag v2.5.0 -->
<title>Users Frequently Asked Questions (FAQ) | Blockstack</title>
<meta name="generator" content="Jekyll v3.8.3" />
<meta property="og:title" content="Users Frequently Asked Questions (FAQ)" />
<meta name="author" content="Blockstack" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Users Frequently Asked Questions (FAQ)" />
<meta property="og:description" content="Users Frequently Asked Questions (FAQ)" />
<link rel="canonical" href="https://zbabystack.netlify.com/browser/faq_general.html" />
<meta property="og:url" content="https://zbabystack.netlify.com/browser/faq_general.html" />
<meta property="og:site_name" content="Blockstack" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2018-09-10T15:18:11-07:00" />
<script type="application/ld+json">
{"description":"Users Frequently Asked Questions (FAQ)","author":{"@type":"Person","name":"Blockstack"},"@type":"BlogPosting","url":"https://zbabystack.netlify.com/browser/faq_general.html","headline":"Users Frequently Asked Questions (FAQ)","dateModified":"2018-09-10T15:18:11-07:00","datePublished":"2018-09-10T15:18:11-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://zbabystack.netlify.com/browser/faq_general.html"},"@context":"http://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<!-- <meta property="og:image" content="https://zbabystack.netlify.com/assets/posts/logo.png"/> -->
<meta property="og:image" content="/assets/posts/logo.png"/>
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="shortcut icon" type="image/png" href="/assets/img/touch-icon.png" >
<link rel="alternate" type="application/rss+xml" title="Blockstack" href="/feed.xml">
<script src="/assets/js/main.js"></script>
</head>
<body>
<header class="uk-background-secondary">
<div data-uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky" class="uk-sticky uk-sticky-fixed" style="position: fixed; top: 0px; width: 1904px;">
<nav class="uk-navbar-container">
<div class="uk-container">
<div data-uk-navbar>
<div class="uk-navbar-left">
<!-- <a class="uk-navbar-item uk-logo" href="/"><img src="https://zbabystack.netlify.com/assets/posts/logo.png" alt="Docs"></a> -->
<a class="uk-navbar-item uk-logo" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a>
</div>
<div class="uk-navbar-right">
<ul class="uk-navbar-nav uk-visible@m">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div>
<a class="uk-navbar-toggle" uk-search-icon href="#"></a>
<div class="uk-drop uk-background-default uk-border-rounded" uk-drop="mode: click; pos: left-center; offset: 0">
<form class="uk-search uk-search-navbar uk-width-1-1" onsubmit="return false;">
<input id="searchBox" class="uk-search-input" type="search" placeholder="Search..." autofocus>
</form>
<ul id="searchBox-results" class="uk-position-absolute uk-width-1-1 uk-list"></ul>
</div>
</div>
<a class="uk-navbar-toggle uk-hidden@m" href="#offcanvas" data-uk-navbar-toggle-icon data-uk-toggle></a>
</div>
</div>
</div>
</nav>
</div>
</header>
<div class="uk-section">
<div class="uk-container">
<div class="uk-grid-large" data-uk-grid>
<div class="sidebar-fixed-width uk-visible@m">
<div class="sidebar-docs uk-position-fixed">
<!-- -->
<ul class="uk-nav uk-nav-default doc-nav">
<!-- -->
<li class=""><a href="/browser/ids-introduction.html">Get and use a Blockstack ID</a></li>
<!-- -->
<li class=""><a href="/browser/browser-introduction.html">Use the Blockstack Browser</a></li>
<!-- -->
<li class="uk-active"><a href="/browser/faq_general.html">Users Frequently Asked Questions (FAQ)</a></li>
</ul>
<!-- -->
</div>
</div>
<div class="uk-width-1-1 uk-width-expand@m">
<article class="uk-article">
<h1 class="uk-article-title">Users Frequently Asked Questions (FAQ)</h1>
<div class="uk-article-meta uk-margin-top uk-margin-medium-bottom">
<!-- <img class="avatar avatar-small" alt="Blockstack" width="32" height="32" data-proofer-ignore="true" src="https://avatars2.githubusercontent.com/Blockstack?v=3&s=32" srcset="https://avatars2.githubusercontent.com/Blockstack?v=3&s=32 1x, https://avatars2.githubusercontent.com/Blockstack?v=3&s=64 2x, https://avatars2.githubusercontent.com/Blockstack?v=3&s=96 3x, https://avatars2.githubusercontent.com/Blockstack?v=3&s=128 4x" /> -->
<!-- Written by <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Blockstack</span></span><br> -->
<time datetime="2018-09-10T15:18:11-07:00" itemprop="datePublished">
<a "target="_blank" href="https://github.com/blockstack/blockstack-browser/blob/master/docs/faq_general.md" class="btn btn-default githubEditButton" role="button">
<span data-uk-icon="icon: pencil; ratio: 1.2"></span> Edit this page on Github</a>
<span style="font-family:Wingdings">&#119;</span> Sep 10, 2018
</time>
</div>
<div class="article-content">
<p class="no_toc">This is a general FAQ intended for users of decentralized applications. If you are a developer, refer to the [technical FAQ].</p>
<ul id="markdown-toc">
<li><a href="#what-is-the-decentralized-internet" id="markdown-toc-what-is-the-decentralized-internet">What is the decentralized internet?</a></li>
<li><a href="#what-is-blockstack" id="markdown-toc-what-is-blockstack">What is Blockstack?</a></li>
<li><a href="#how-do-dapps-differ-applications-i-typically-use" id="markdown-toc-how-do-dapps-differ-applications-i-typically-use">How do Dapps differ applications I typically use?</a></li>
<li><a href="#where-is-my-identity-kept" id="markdown-toc-where-is-my-identity-kept">Where is my identity kept?</a></li>
<li><a href="#can-blockstack-control-my-data-or-id-when-i-use-it" id="markdown-toc-can-blockstack-control-my-data-or-id-when-i-use-it">Can Blockstack control my data or ID when I use it?</a></li>
<li><a href="#do-dapps-uwork-with-a-regular-browser" id="markdown-toc-do-dapps-uwork-with-a-regular-browser">Do Dapps uwork with a regular browser?</a></li>
<li><a href="#what-is-the-blockstack-browser" id="markdown-toc-what-is-the-blockstack-browser">What is the Blockstack Browser?</a></li>
<li><a href="#are-blockstack-applications-usable-today" id="markdown-toc-are-blockstack-applications-usable-today">Are Blockstack applications usable today?</a></li>
</ul>
<h2 id="what-is-the-decentralized-internet">What is the decentralized internet?</h2>
<p>The Blockstack ecosystem enables the new decentralized internet. Decentralization means authority moving from central authority to local authority. Simply put, in a decentralized interent, you your data, not the applications or services you use.</p>
<p>Blockstack envisions a world where users control their own data, and power flows back to the users. For example, when you buy something from an online company, that company collects and stores data about you:</p>
<ul>
<li>your name</li>
<li>the information about the product you bought</li>
<li>the number on your credit card</li>
</ul>
<p>In the decentralied internet, that information stays with you and it isn’t
collected or stored by anyone. Applications that operate in the decentralized
internet are called <em>decentralized applications</em> or Dapps for short.</p>
<h2 id="what-is-blockstack">What is Blockstack?</h2>
<p>Blockstack is an ecosystem to support both Dapp users and Dapp developers. For
users, Blockstack makes software to create Blockstack identities and find Dapps.
For developers, Blockstack develops an ecosystem of software and services that developrs can use to build Dapps.</p>
<p>Blockstack through its</p>
<h2 id="how-do-dapps-differ-applications-i-typically-use">How do Dapps differ applications I typically use?</h2>
<p>Dapps differ from Web applications in two ways:</p>
<ul>
<li><strong>Users have identities not accounts</strong>. The user brings their identity to the
applications; applications do not require the user to create accounts and
passwords.</li>
<li><strong>Users own their data</strong>. Users control access to their data. Users decide where to store their data and which applications can read or write to your. Companies and their applications in the new Internet don’t keep or save your data.</li>
</ul>
<h2 id="where-is-my-identity-kept">Where is my identity kept?</h2>
<p>Your identity is a unique string you and other people can read such as <code class="highlighter-rouge">moxiegirl.id</code>. A private key is a string of letters only you know. When you create an identity, a <strong>hash</strong> is made of your id and your private key registered with Blockstack.</p>
<p>Your personal data storage is built around this ID. Apps that want to access your data use your permission and identity to find it.</p>
<p>You have to remember and keep your private key in a safe place like a password manager. If you lose a private key, <em>no one else, no person, no software, can help you get your identity back</em>.</p>
<h2 id="can-blockstack-control-my-data-or-id-when-i-use-it">Can Blockstack control my data or ID when I use it?</h2>
<p>No. When you’re using a Blockstack client you control your data and ID with a
private key. As long as no one gets access to your private key, no one can
control your data or ID. When you use Blockstack, by design, your private keys
are never sent to any remote servers.</p>
<h2 id="do-dapps-uwork-with-a-regular-browser">Do Dapps uwork with a regular browser?</h2>
<p>Yes! Dapps run in the web browsers (Chrome, Safari, Internet Explorer, etc.) you know and love.</p>
<h2 id="what-is-the-blockstack-browser">What is the Blockstack Browser?</h2>
<p>The Blockstack Browser is the Dapp users use to create and manage their identities and configure their data storage. The browser is also where users can go to discover and use apps using Blockstack.</p>
<p>The Blockstack Browser also handles login requests from Dapps that allow their users to log in with Blockstack. When a user clicks a <strong>Log In with Blockstack</strong> button, they are redirected to the Blockstack Browser to approve the request before being logged into the app.</p>
<h2 id="are-blockstack-applications-usable-today">Are Blockstack applications usable today?</h2>
<p>Yes! Blockstack applications are as easy to use as normal Web applications, if
not easier. Moreover, they are just as performant if not more so.</p>
<p>If you install the <a href="https://github.com/blockstack/blockstack-browser">Blockstack
Browser</a>, or use our
<a href="https://browser.blockstack.org">Web-hosted Blockstack Browser</a>, you can get
started with them right away.</p>
<div class="share uk-text-center">
<a href="https://twitter.com/intent/tweet?text=Users Frequently Asked Questions (FAQ)&url=https://zbabystack.netlify.com/browser/faq_general.html&via=&related=" rel="nofollow" target="_blank" title="Share on Twitter" onclick="window.open(this.href, 'twitter', 'width=550,height=235');return false;"><span data-uk-icon="icon: twitter; ratio: 1.2"></span></a>
<a class="uk-margin-small-left" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fzbabystack.netlify.com%2Fbrowser%2Ffaq_general.html" rel="nofollow" target="_blank" title="Share on Facebook" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;"><span data-uk-icon="icon: facebook; ratio: 1.2"></span></a>
</div>
</div>
<hr class="uk-margin-medium">
<!-- <div class="uk-margin-large-top">
<h3>Related Articles</h3>
<ul class="uk-list">
</ul>
</div>
-->
</article>
<script>
// Table of contents scroll to
UIkit.scroll('#markdown-toc a', {
duration: 400,
offset: 120
});
</script>
</div>
</div>
</div>
<div id="offcanvas" data-uk-offcanvas="flip: true; overlay: true">
<div class="uk-offcanvas-bar">
<button class="uk-offcanvas-close" type="button" data-uk-close></button>
<ul class="uk-nav uk-nav-default">
<!-- <li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="https://zbabystack.netlify.com/assets/posts/logo.png" alt="Docs"></a></li> -->
<li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a></li>
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div class="uk-margin-small-top uk-text-center uk-text-muted uk-link-muted">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
</div>
</div>
<footer class="uk-section uk-text-center uk-text-muted uk-link-muted">
<div class="uk-container uk-container-small">
<!-- <div>
<ul class="uk-subnav uk-flex-center">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
</div>
<div class="uk-margin-medium">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div> -->
<div class="uk-margin-medium uk-text-small copyright">&copy; 2018 Blockstack</div>
</div>
</footer>
<script type="text/javascript">
/* Create a configuration object */
var ss360Config = {
/* Your site id */
siteId: 'blockstack',
/* A CSS selector that points to your search box */
searchBox: {selector: '#searchBox'}
};
</script>
<script src="https://cdn.sitesearch360.com/sitesearch360-v11.min.js" async></script>
</body>
</html>

99
_site/newinternet/hello-blockstack.html → _site/browser/hello-blockstack.html

@ -13,13 +13,13 @@
<meta property="og:locale" content="en_US" />
<meta name="description" content="Hello, Blockstack Tutorial" />
<meta property="og:description" content="Hello, Blockstack Tutorial" />
<link rel="canonical" href="https://zbabystack.netlify.com/newinternet/hello-blockstack.html" />
<meta property="og:url" content="https://zbabystack.netlify.com/newinternet/hello-blockstack.html" />
<link rel="canonical" href="https://zbabystack.netlify.com/browser/hello-blockstack.html" />
<meta property="og:url" content="https://zbabystack.netlify.com/browser/hello-blockstack.html" />
<meta property="og:site_name" content="Blockstack" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2018-09-08T19:24:57-07:00" />
<meta property="article:published_time" content="2018-09-10T15:18:11-07:00" />
<script type="application/ld+json">
{"description":"Hello, Blockstack Tutorial","author":{"@type":"Person","name":"Blockstack"},"@type":"BlogPosting","url":"https://zbabystack.netlify.com/newinternet/hello-blockstack.html","headline":"Hello, Blockstack Tutorial","dateModified":"2018-09-08T19:24:57-07:00","datePublished":"2018-09-08T19:24:57-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://zbabystack.netlify.com/newinternet/hello-blockstack.html"},"@context":"http://schema.org"}</script>
{"description":"Hello, Blockstack Tutorial","author":{"@type":"Person","name":"Blockstack"},"@type":"BlogPosting","url":"https://zbabystack.netlify.com/browser/hello-blockstack.html","headline":"Hello, Blockstack Tutorial","dateModified":"2018-09-10T15:18:11-07:00","datePublished":"2018-09-10T15:18:11-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://zbabystack.netlify.com/browser/hello-blockstack.html"},"@context":"http://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<!-- <meta property="og:image" content="https://zbabystack.netlify.com/assets/posts/logo.png"/> -->
@ -99,23 +99,28 @@
<div class="sidebar-fixed-width uk-visible@m">
<div class="sidebar-docs uk-position-fixed">
<!-- -->
<h5>Try a tutorial</h5>
<ul class="uk-nav uk-nav-default doc-nav">
<!-- -->
<li class="uk-active"><a href="/newinternet/hello-blockstack.html">Hello, Blockstack Tutorial</a></li>
<li class="uk-active"><a href="/browser/hello-blockstack.html">Hello, Blockstack Tutorial</a></li>
<!-- -->
<li class=""><a href="/newinternet/multi-player-storage.html">Manage Data with Gaia</a></li>
<li class=""><a href="/browser/multi-player-storage.html">Manage Data with Gaia</a></li>
</ul>
<h5>Work with an SDK</h5>
<ul class="uk-nav uk-nav-default doc-nav">
@ -130,6 +135,24 @@
</ul>
<h5>Reference</h5>
<ul class="uk-nav uk-nav-default doc-nav">
<!-- -->
<li class=""><a href="/core/faq_developer.html">Developer FAQs</a></li>
<!-- -->
<li class=""><a href="/common/javascript_ref.html">Blockstack Javascript Reference</a></li>
</ul>
<!-- -->
</div>
</div>
@ -141,6 +164,7 @@
<div class="uk-article-meta uk-margin-top uk-margin-medium-bottom">
@ -152,13 +176,13 @@
<!-- Written by <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Blockstack</span></span><br> -->
<time datetime="2018-09-08T19:24:57-07:00" itemprop="datePublished">
<time datetime="2018-09-10T15:18:11-07:00" itemprop="datePublished">
<a "target="_blank" href="https://github.com/moxiegirl/docs-new/blob/master/docs/hello-blockstack.md" class="btn btn-default githubEditButton" role="button">
<a "target="_blank" href="https://github.com/blockstack/blockstack-browser/blob/master/docs/hello-blockstack.md" class="btn btn-default githubEditButton" role="button">
<span data-uk-icon="icon: pencil; ratio: 1.2"></span> Edit this page on Github</a>
<span style="font-family:Wingdings">&#119;</span> Sep 8, 2018
<span style="font-family:Wingdings">&#119;</span> Sep 10, 2018
</time>
</div>
@ -433,7 +457,7 @@ and open your browser ‘http://localhost:5000’. From the root of your new ap
<p>The application detects whether the user has the Blockstack client edition installed or
not. This is done automatically by the Blockstack API, more about this later.
What the authenticator displays depends on the users’ current state.</p>
What the browser displays depends on the users’ current state.</p>
<table>
<thead>
@ -450,12 +474,12 @@ and open your browser ‘http://localhost:5000’. From the root of your new ap
</tbody>
</table>
<p>If the user logged into the Blockstack authenticator but not reset it, the user can
<p>If the user logged into the Blockstack Browser but not reset it, the user can
simply use the exiting identity.</p>
<p><img src="images/login-no-auth.png" alt="" /></p>
<p>If the user chooses <strong>Deny</strong>, the Blockstack authenticator displays its
<p>If the user chooses <strong>Deny</strong>, the Blockstack Browser displays its
<strong>Home</strong> page but the user is not logged into the sample application.</p>
</li>
<li>
@ -601,8 +625,8 @@ user home screens. The contents are very simple:</p>
You’re well on your way to becoming a Blockstack app legend.</p>
<div class="share uk-text-center">
<a href="https://twitter.com/intent/tweet?text=Hello, Blockstack Tutorial&url=https://zbabystack.netlify.com/newinternet/hello-blockstack.html&via=&related=" rel="nofollow" target="_blank" title="Share on Twitter" onclick="window.open(this.href, 'twitter', 'width=550,height=235');return false;"><span data-uk-icon="icon: twitter; ratio: 1.2"></span></a>
<a class="uk-margin-small-left" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fzbabystack.netlify.com%2Fnewinternet%2Fhello-blockstack.html" rel="nofollow" target="_blank" title="Share on Facebook" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;"><span data-uk-icon="icon: facebook; ratio: 1.2"></span></a>
<a href="https://twitter.com/intent/tweet?text=Hello, Blockstack Tutorial&url=https://zbabystack.netlify.com/browser/hello-blockstack.html&via=&related=" rel="nofollow" target="_blank" title="Share on Twitter" onclick="window.open(this.href, 'twitter', 'width=550,height=235');return false;"><span data-uk-icon="icon: twitter; ratio: 1.2"></span></a>
<a class="uk-margin-small-left" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fzbabystack.netlify.com%2Fbrowser%2Fhello-blockstack.html" rel="nofollow" target="_blank" title="Share on Facebook" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;"><span data-uk-icon="icon: facebook; ratio: 1.2"></span></a>
</div>
</div>
@ -614,49 +638,7 @@ You’re well on your way to becoming a Blockstack app legend.</p>
<div class="uk-margin-large-top">
<!-- <div class="uk-margin-large-top">
<h3>Related Articles</h3>
@ -667,8 +649,7 @@ You’re well on your way to becoming a Blockstack app legend.</p>
</ul>
</div>
-->
</article>

71
_site/browser/hosted_browser.md

@ -1,71 +0,0 @@
### The Blockstack Browser
Blockstack is a new internet for decentralized apps. It reuses the transport layer, and below, of the traditional internet and focuses on decentralizing the application layer (Domain Name System, Public-key Infrastructure, auth protocols, data storage).
The Blockstack network has been operational for years and the best way to experience it is by using the Blockstack Browser. More specifically, there is a hosted version that quickly gives a preview:
* Hosted version of the Blockstack application:
* https://browser.blockstack.org
We recommend that everyone should [download and install the Blockstack Browser](https://blockstack.org/install) for any serious use outside of a quick preview.
You can think of the Blockstack Browser as a "gateway" to a new internet for decentralized apps. The Blockstack Browser is an application which allows a user to create and manage a decentralized Blockstack identity. This identity is used to authenticate and provide
user-controlled storage to decentralized web applications.
The user instantiates a private keychain, backed up with a 12-word phrase, and stored in the user's web
browser's `localStorage` encrypted with a user-provided password. This keychain is a master keychain for
generating identity addresses which can own Blockstack names (a decentralized naming protocol implemented
on top of a virtual blockchain -- see [github.com/blockstack/virtualchain](https://github.com/blockstack/virtualchain)). Names in this system are indexed
by the Blockstack core (see [github.com/blockstack/blockstack-core](https://github.com/blockstack/blockstack-core))
The Browser supports registering Blockstack names via communication with a local Blockstack Core node. Our
macOS app sets up this system automatically for users. For Windows users and our hosted version of the Browser,
however, we do not currently have support for communicating directly with a local node. However, on these
platforms, you _can_ still construct a private keychain, which can be used to create profiles associated with
identity addresses. These addresses can even have names sent to them, e.g., from Onename (https://www.onename.com)
or another user via the Blockstack core cli (try `$ blockstack transfer foo.id`)
### Authentication with Applications
One of the core features of the Blockstack Browser is authenticating with applications using a decentralized
identifier. Users control their own addresses, and validate their login through a cryptographic signature.
In fact, the Blockstack token voucher registration process uses this system (for a detailed walkthrough
of this, see https://www.larrysalibra.com/blog/blockstack-token-sale-voucher-registration-walkthrough/).
In order to associate the cryptographic identities of the Blockstack Browser with (potentially!) real
people, the app supports adding "social proofs" -- a tweet from some account that asserts that the account
is controlled by the same person as the address. For example:
https://twitter.com/AaronBlankstein/status/918927256738811904
Applications can also use this to associate a given login with an account somewhere else.
### Application Keychains
One of the really cool things about Blockstack as a user (and developer of applications) is that
users are on-boarded with a hierarchical keychain. The master backup phrase backs-up _all_ of their
identity addresses. But in addition, each application that a user signs into also receives a unique
key, derived from the user's master key. For people familiar with Bitcoin's hierarchical derivation
wallets, this is not so surprising. However, it enables rapid development of many different kinds
of applications in the cryptocurrency space (for example, a simple application wallet for a currency
of your choice -- Larry Salibra demoed a three line receive wallet for Ethereum at the ETC summit:
https://twitter.com/larrysalibra/status/929660024988753921)
### Authenticating with Storage Providers
Our user experience currently requires that a user connect to our default storage provider. We host
that storage service, however the system (called Gaia) can be deployed by anyone (see the `hub` directory in
github.com/blockstack/gaia). This system allows authorized _writes_ to a connected storage backend, and then
returns a public URL for servicing reads. By separating the logic for these two paths, we can employ standard
improvements to the read path (e.g., CDNs), while supporting our own protocol for the write path. The storage
system allows users to write to paths they own -- for example, my Blockstack profile is stored at:
```
https://gaia.blockstack.org/hub/15GAGiT2j2F1EzZrvjk3B8vBCfwVEzQaZx/0/profile.json
```
And my browser can write to this path by signing its request with the public key associated with that
address (for more details on how an ECDSA public key can become an address, check out: https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses)
We think the [hosted version of the Blockstack Browser](https://browser.blockstack.org) makes it significantly easier for a person to take the first step into the new internet for decentralized apps by allowing them to get started without having to download or install any software.
[Try it out](https://browser.blockstack.org) and [let us know what you think](https://twitter.com/blockstack)!

73
_site/newinternet/ids-introduction.html → _site/browser/ids-introduction.html

@ -13,13 +13,13 @@
<meta property="og:locale" content="en_US" />
<meta name="description" content="Get and use a Blockstack ID" />
<meta property="og:description" content="Get and use a Blockstack ID" />
<link rel="canonical" href="https://zbabystack.netlify.com/newinternet/ids-introduction.html" />
<meta property="og:url" content="https://zbabystack.netlify.com/newinternet/ids-introduction.html" />
<link rel="canonical" href="https://zbabystack.netlify.com/browser/ids-introduction.html" />
<meta property="og:url" content="https://zbabystack.netlify.com/browser/ids-introduction.html" />
<meta property="og:site_name" content="Blockstack" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2018-09-08T19:24:57-07:00" />
<meta property="article:published_time" content="2018-09-10T15:18:11-07:00" />
<script type="application/ld+json">
{"description":"Get and use a Blockstack ID","author":{"@type":"Person","name":"Blockstack"},"@type":"BlogPosting","url":"https://zbabystack.netlify.com/newinternet/ids-introduction.html","headline":"Get and use a Blockstack ID","dateModified":"2018-09-08T19:24:57-07:00","datePublished":"2018-09-08T19:24:57-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://zbabystack.netlify.com/newinternet/ids-introduction.html"},"@context":"http://schema.org"}</script>
{"description":"Get and use a Blockstack ID","author":{"@type":"Person","name":"Blockstack"},"@type":"BlogPosting","url":"https://zbabystack.netlify.com/browser/ids-introduction.html","headline":"Get and use a Blockstack ID","dateModified":"2018-09-10T15:18:11-07:00","datePublished":"2018-09-10T15:18:11-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://zbabystack.netlify.com/browser/ids-introduction.html"},"@context":"http://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<!-- <meta property="og:image" content="https://zbabystack.netlify.com/assets/posts/logo.png"/> -->
@ -102,19 +102,22 @@
<!-- -->
<h5>Get started</h5>
<ul class="uk-nav uk-nav-default doc-nav">
<!-- -->
<li class=""><a href="/newinternet/browser-introduction.html">Use the Blockstack Authenticator</a></li>
<li class="uk-active"><a href="/browser/ids-introduction.html">Get and use a Blockstack ID</a></li>
<!-- -->
<li class=""><a href="/browser/browser-introduction.html">Use the Blockstack Browser</a></li>
<!-- -->
<li class="uk-active"><a href="/newinternet/ids-introduction.html">Get and use a Blockstack ID</a></li>
<li class=""><a href="/browser/faq_general.html">Users Frequently Asked Questions (FAQ)</a></li>
</ul>
@ -142,13 +145,13 @@
<!-- Written by <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Blockstack</span></span><br> -->
<time datetime="2018-09-08T19:24:57-07:00" itemprop="datePublished">
<time datetime="2018-09-10T15:18:11-07:00" itemprop="datePublished">
<a "target="_blank" href="https://github.com/moxiegirl/docs-new/blob/master/docs/ids-introduction.md" class="btn btn-default githubEditButton" role="button">
<a "target="_blank" href="https://github.com/blockstack/blockstack-browser/blob/master/docs/ids-introduction.md" class="btn btn-default githubEditButton" role="button">
<span data-uk-icon="icon: pencil; ratio: 1.2"></span> Edit this page on Github</a>
<span style="font-family:Wingdings">&#119;</span> Sep 8, 2018
<span style="font-family:Wingdings">&#119;</span> Sep 10, 2018
</time>
</div>
@ -233,7 +236,7 @@ registrars. Coin is required to purchase identities on other domains.</p>
<ol>
<li>
<p>Open the <a href="https://browser.blockstack.org/sign-up?redirect=%2F">Blockstack web applicatin in your browser</a>.</p>
<p>Open the <a href="https://browser.blockstack.org/sign-up?redirect=%2F">Blockstack web application in your browser</a>.</p>
<p>The application prompts you for an email address.</p>
@ -396,8 +399,8 @@ recovery key rather than your code to restore your identity.</p>
<p>At this point, you can go work with Dapps or you can review your recovery key.</p>
<div class="share uk-text-center">
<a href="https://twitter.com/intent/tweet?text=Get and use a Blockstack ID&url=https://zbabystack.netlify.com/newinternet/ids-introduction.html&via=&related=" rel="nofollow" target="_blank" title="Share on Twitter" onclick="window.open(this.href, 'twitter', 'width=550,height=235');return false;"><span data-uk-icon="icon: twitter; ratio: 1.2"></span></a>
<a class="uk-margin-small-left" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fzbabystack.netlify.com%2Fnewinternet%2Fids-introduction.html" rel="nofollow" target="_blank" title="Share on Facebook" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;"><span data-uk-icon="icon: facebook; ratio: 1.2"></span></a>
<a href="https://twitter.com/intent/tweet?text=Get and use a Blockstack ID&url=https://zbabystack.netlify.com/browser/ids-introduction.html&via=&related=" rel="nofollow" target="_blank" title="Share on Twitter" onclick="window.open(this.href, 'twitter', 'width=550,height=235');return false;"><span data-uk-icon="icon: twitter; ratio: 1.2"></span></a>
<a class="uk-margin-small-left" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fzbabystack.netlify.com%2Fbrowser%2Fids-introduction.html" rel="nofollow" target="_blank" title="Share on Facebook" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;"><span data-uk-icon="icon: facebook; ratio: 1.2"></span></a>
</div>
</div>
@ -409,48 +412,6 @@ recovery key rather than your code to restore your identity.</p>
<!-- <div class="uk-margin-large-top">
<h3>Related Articles</h3>

0
_newinternet/images/blockstack-bar.png → _site/browser/images/blockstack-bar.png

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

0
_newinternet/images/browser-on-mac-1.png → _site/browser/images/browser-on-mac-1.png

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 84 KiB

0
_newinternet/images/browser-on-mac.png → _site/browser/images/browser-on-mac.png

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

0
_newinternet/images/browser-uninstall.png → _site/browser/images/browser-uninstall.png

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

0
_newinternet/images/create-id-0.png → _site/browser/images/create-id-0.png

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

0
_newinternet/images/create-id-1.png → _site/browser/images/create-id-1.png

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

0
_newinternet/images/create-id-2.png → _site/browser/images/create-id-2.png

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

0
_newinternet/images/create-id-3.png → _site/browser/images/create-id-3.png

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

0
_newinternet/images/display-complete.png → _site/browser/images/display-complete.png

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

0
_newinternet/images/dmg-notice.png → _site/browser/images/dmg-notice.png

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

0
_newinternet/images/eject-blockstack.png → _site/browser/images/eject-blockstack.png

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

0
_newinternet/images/hw-loggedin.png → _site/browser/images/hw-loggedin.png

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

0
_newinternet/images/initial-app.gif → _site/browser/images/initial-app.gif

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

0
_newinternet/images/login-choice.png → _site/browser/images/login-choice.png

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

0
_newinternet/images/login-no-auth.png → _site/browser/images/login-no-auth.png

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 109 KiB

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save