mirror of https://github.com/lukechilds/docs.git
committed by
GitHub
6 changed files with 451 additions and 1369 deletions
After Width: | Height: | Size: 22 KiB |
@ -1,802 +0,0 @@ |
|||||
--- |
|
||||
layout: learn |
|
||||
permalink: /:collection/:path.html |
|
||||
image: /assets/img/zero-to-dapp.png |
|
||||
--- |
|
||||
# 3. Build an Animal Kingdom DApp |
|
||||
{:.no_toc} |
|
||||
|
|
||||
**Zero to DAPP 3 of 4** |
|
||||
|
|
||||
In this part, you follow a tutorial which builds, runs, and modifies a DAPP |
|
||||
called Animal Kingdom. Through this exercise, you'll learn about the |
|
||||
interactions between a Blockstack identity and a DApp. You'll also learn about |
|
||||
the Blockstack Javascript calls in a typical DApp. |
|
||||
|
|
||||
* TOC |
|
||||
{:toc} |
|
||||
|
|
||||
### Skills you need to build Animal Kingdom |
|
||||
|
|
||||
This tutorial is designed for a wide audience. Anyone with access to a Windows, |
|
||||
Mac, or Linux computer and some familiarity with a command line can build the |
|
||||
Animal Kingdom DApp. |
|
||||
|
|
||||
If you are good at following directions, chances are you can complete this |
|
||||
tutorial even if you have no programming experience. Knowledgeable developers |
|
||||
should easily be able to complete the tutorial within an hour by following |
|
||||
along. |
|
||||
|
|
||||
If you are a developer superhero, you may want to skip ahead or move |
|
||||
quickly and that's fine too. |
|
||||
|
|
||||
## Get prerequisites and set up your environment |
|
||||
|
|
||||
To follow this tutorial, you need the following: |
|
||||
|
|
||||
* A Blockstack ID (identity) to test your Animal Kingdom. |
|
||||
* Access to the Mac terminal window and some familiarity with the command line it provides. |
|
||||
* An installation of the XCode command-line tools to support Node Package Manager (`npm`) |
|
||||
* The Node Package Manager package manager. |
|
||||
|
|
||||
Follow the procedures in this section to install these components. |
|
||||
|
|
||||
### Confirm or get a Blockstack ID |
|
||||
{:.no_toc} |
|
||||
|
|
||||
Confirm you have a Blockstack ID also known as an identity; `joe.id.blockstack` |
|
||||
is an example of an identity. |
|
||||
|
|
||||
* If you have an existing ID, log into the <a href="https://browser.blockstack.org/" target="\_blank">Blockstack Browser</a> in your browser. |
|
||||
|
|
||||
The Blockstack Browser is itself a DApp. Logging in confirms you have a valid |
|
||||
ID with the required _secret recovery key_ or _magic recovery code_. The |
|
||||
secret recovery key is a 12 or 24 word phrase you recorded when you created |
|
||||
the ID. The magic recovery code is a string of characters Blockstack emailed |
|
||||
to you when you created your identity. You can confirm your identity with either. |
|
||||
|
|
||||
* If you do not yet have a Blockstack ID, <a href="https://browser.blockstack.org/" target="\_blank">create one through the Blockstack Browser</a> . |
|
||||
|
|
||||
Instructions for creating an ID are <a href="{{ site.baseurl }}/browser/ids-introduction.html#create-an-initial-blockstack-id" target="\_blank">available in this documentation</a>. |
|
||||
|
|
||||
|
|
||||
### Ensure command-line access |
|
||||
{:.no_toc} |
|
||||
|
|
||||
If you are using a Mac, you can find the **terminal** in the **Application > |
|
||||
Launchpad > Other** folder. |
|
||||
|
|
||||
<img src="images/terminal.png" alt=""> |
|
||||
|
|
||||
If you don't often use the command line, take a moment to test some common commands. |
|
||||
|
|
||||
<table class="uk-table uk-table-small uk-table-divider"> |
|
||||
<tr> |
|
||||
<th>Command</th> |
|
||||
<th>What it does</th> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td><code>ls</code></td> |
|
||||
<td>Lists the files and directories in the current directory.</td> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td><code>cd</code></td> |
|
||||
<td>Change directory to navigate to locations in your file system.</td> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td><code>pwd</code></td> |
|
||||
<td>Print the working directory, the location you are working in.</td> |
|
||||
</tr> |
|
||||
</table> |
|
||||
|
|
||||
### Install XCode Command Line tools |
|
||||
{:.no_toc} |
|
||||
|
|
||||
The Command Line Tool package gives Mac terminal users many commonly used tools, |
|
||||
utilities, and compilers. Some of the contents installed by NPM require XCode. |
|
||||
|
|
||||
1. Open a terminal window on your system. |
|
||||
2. Enter the `xcode-select` command string: |
|
||||
|
|
||||
```bash |
|
||||
$ xcode-select --install |
|
||||
``` |
|
||||
|
|
||||
<img src="images/install-command-line-tools-os-x.jpg" alt=""> |
|
||||
|
|
||||
A software update dialog displays: |
|
||||
|
|
||||
<img src="images/confirm-install-command-line-tools-mac-os-x.jpg" alt=""> |
|
||||
|
|
||||
3. Click **Install** to confirm. |
|
||||
|
|
||||
You are prompted to agree to the terms of service. |
|
||||
|
|
||||
4. Agree to the terms of services. |
|
||||
|
|
||||
The tools are installed. This is fairly quick depending on your connection speed. |
|
||||
|
|
||||
|
|
||||
### Install Node Package Manager (NPM) |
|
||||
{:.no_toc} |
|
||||
|
|
||||
Open source developers from every continent use NPM to share software components |
|
||||
called packages. The Animal Kingdom uses React, Babel, and many other |
|
||||
components. You'll use the `npm` command to install these packaged components. |
|
||||
|
|
||||
|
|
||||
1. Verify you have installed `npm` using the `which` command. |
|
||||
|
|
||||
<img src="images/command-line.png" alt=""> |
|
||||
|
|
||||
If `npm` is installed, `which` returns the command's location in your environment. |
|
||||
|
|
||||
3. If the `npm` command is not in your system, <a href="https://www.npmjs.com/get-npm" target="\_blank">install it</a>. |
|
||||
|
|
||||
Installing the NPM tool can take several minutes depending on your connection speed. |
|
||||
|
|
||||
|
|
||||
## Overview of the Animal Kingdom DApp |
|
||||
|
|
||||
You are going to build a DApp called AnimalKingdom. Animal Kingdom is a DApp for |
|
||||
the web. Users log into it and create an animal persona that rules over a |
|
||||
specific territory. The combination of persona and territory is a kingdom. Once |
|
||||
you create a kingdom, you can add subjects from other kingdoms. |
|
||||
|
|
||||
The Animal Kingdom interacts with two Blockstack services, the Blockstack |
|
||||
Browser (https://browser.blockstack.org) and the Gaia data storage hub |
|
||||
(https://hub.blockstack.org/). The Blockstack Browser is itself |
|
||||
a DApp. The storage hub is purely a service without user-facing functionality. |
|
||||
|
|
||||
The following table describes the key interactions and screens in the DApp. |
|
||||
|
|
||||
<table class="uk-table uk-table-striped"> |
|
||||
<tr> |
|
||||
<th>Click to enlarge</th> |
|
||||
<th> Description</th> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td><div uk-lightbox="animation: slide"> |
|
||||
<a class="uk-inline" href="images/kingdom-enter.png" data-caption="Users must login with a Blockstack identity."> |
|
||||
<img src="images/kingdom-enter.png" alt=""> |
|
||||
</a> |
|
||||
</div> |
|
||||
</td> |
|
||||
<td><p>Users log in (authenticate) with a Blockstack identity. By authenticating, the user gives the application the ability to get and put data in the user's Gaia storage hub.</p></td> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td><div uk-lightbox="animation: slide"> |
|
||||
<a class="uk-inline" href="images/kingdom-signin.png" data-caption="Blockstack login dialogs."> |
|
||||
<img src="images/kingdom-signin.png" alt=""> |
|
||||
</a> |
|
||||
</div> |
|
||||
</td> |
|
||||
<td><p>The Blockstack login dialogs are part of the Blockstack Browser which is itself |
|
||||
a DApp. Once a user authenticates, the DApp code automatically |
|
||||
returns them to the Kingdom they were attempting to enter.</p></td> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td><div uk-lightbox="animation: slide"> |
|
||||
<a class="uk-inline" href="images/kingdom-new.png" data-caption="Choose a persona and territory."> |
|
||||
<img src="images/kingdom-new.png" alt=""> |
|
||||
</a> |
|
||||
</div></td> |
|
||||
<td><p>First-time visitors to a kingdom are prompted to create an animal persona and |
|
||||
a territory to rule. Once they make a selection, users click <strong>Done</strong> to create a |
|
||||
kingdom to rule. Behind the scenes, the data about the user's selection is stored in the user's GAIA hub. |
|
||||
</p> |
|
||||
</td> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td> <div uk-lightbox="animation: slide"> |
|
||||
<a class="uk-inline" href="images/kingdom-choices.gif" data-caption="Choose a persona and territory."> |
|
||||
<img src="images/kingdom-choices.gif" alt=""> |
|
||||
</a> |
|
||||
</div></td> |
|
||||
<td><p>Each kingdom has animals and territories. Users can edit their original persona/animal combination. You'll learn how to modify the Animal Kingdom code to add new animals and territories.</p></td> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td><div uk-lightbox="animation: slide"> |
|
||||
<a class="uk-inline" href="images/kingdom-subjects.gif" data-caption="Adding subjects"> |
|
||||
<img src="images/kingdom-subjects.gif" alt=""> |
|
||||
</a> |
|
||||
</div></td> |
|
||||
<td> |
|
||||
<p>Users can add subjects from territories in their own Animal Kingdom. The DApp updates the user's GAI hub each time the user adds a subject. Users can also visit other Animal Kingdom installations and add subjects from these as well. You'll learn how to modify the <b>Other Kingdoms</b> available in your installation. |
|
||||
</p> |
|
||||
</td> |
|
||||
</tr> |
|
||||
</table> |
|
||||
|
|
||||
|
|
||||
## Get the Animal Kingdom code |
|
||||
|
|
||||
In this section, you copy the code for Animal Kingdom to your workstation. |
|
||||
|
|
||||
1. In your browser (Chrome, Safari, etc), <a href="https://github.com/blockstack/animal-kingdom" target="\_blank">open the Animal Kingdom code repository</a>. |
|
||||
|
|
||||
The AnimalKingdom code is kept in a public GitHub repository. |
|
||||
|
|
||||
2. Click the **Clone or download** button. |
|
||||
|
|
||||
If you have a GitHub account you can choose to clone the original repository |
|
||||
or fork it and then clone it. These instructions assume you are downloading |
|
||||
the code. |
|
||||
|
|
||||
3. Choose the **Download ZIP** for Animal Kingdom. |
|
||||
|
|
||||
<img src="images/kingdom-copy.png" alt=""> |
|
||||
|
|
||||
3. Check your download directory for the `animal-kingdom-master.zip` file. |
|
||||
4. Copy the download zip file to a directory where you keep code projects. |
|
||||
4. Unzip the file. |
|
||||
|
|
||||
<img src="images/kingdom-download.png" alt=""> |
|
||||
|
|
||||
After unzipping the file you should have an `animal-kingdom-master` directory. |
|
||||
|
|
||||
5. In your terminal change directory into the top of the directory by entering: |
|
||||
|
|
||||
```bash |
|
||||
$ cd animal-kingdom-master |
|
||||
``` |
|
||||
|
|
||||
Use the `pwd` command to confirm which directory you are in. |
|
||||
|
|
||||
```bash |
|
||||
$ pwd |
|
||||
/Users/manthony/animal-kingdom-master |
|
||||
``` |
|
||||
|
|
||||
6. Take a minute review the files and subdirectories in your Animal Kingdom project. |
|
||||
|
|
||||
Use the `ls` command to list directory contents. |
|
||||
|
|
||||
<table class="uk-table uk-table-striped"> |
|
||||
<tr> |
|
||||
<th><b>Name</b> </th> |
|
||||
<th><b>Description</b></th> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td><code>README.md</code></td> |
|
||||
<td>Contains a quick reference for building and running Animal Kingdom. </td> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td><code>package.json</code></td> |
|
||||
<td>An NPM project file.</td> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td><code>config</code></td> |
|
||||
<td>Environment configuration files written in Javascript.</td> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td><code>public</code></td> |
|
||||
<td>Files that are copied into the root of the site you are building.</td> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td><code>scripts</code></td> |
|
||||
<td>NPM scripts used to do common tasks in the project.</td> |
|
||||
</tr> |
|
||||
<tr> |
|
||||
<td><code>src</code></td> |
|
||||
<td>Vue.js code source code for the site. This contains configuration files.</td> |
|
||||
</tr> |
|
||||
</table> |
|
||||
|
|
||||
## Build and run the sample in development mode |
|
||||
|
|
||||
You can build and run the Animal Kingdom on your local workstation. Before you |
|
||||
can run the program you use NPM to get all the dependent packages. |
|
||||
|
|
||||
1. Make sure you are in the root directory of the project. |
|
||||
|
|
||||
```bash |
|
||||
cd ~/animal-kingdom-master |
|
||||
pwd |
|
||||
/Users/manthony/animal-kingdom-master |
|
||||
``` |
|
||||
|
|
||||
2. Enter `npm install` to get the software components Animal Kingdom needs. |
|
||||
|
|
||||
```bash |
|
||||
$ npm install |
|
||||
|
|
||||
> fsevents@1.2.4 install /Users/manthony/animal-kingdom-master/node_modules/fsevents |
|
||||
> node install |
|
||||
|
|
||||
node-pre-gyp WARN Tried to download(404): https://fsevents-binaries.s3-us-west-2.amazonaws.com/v1.2.4/fse-v1.2.4-node-v67-darwin-x64.tar.gz |
|
||||
node-pre-gyp WARN Pre-built binaries not found for fsevents@1.2.4 and node@11.1.0 (node-v67 ABI, unknown) (falling back to source compile with node-gyp) |
|
||||
SOLINK_MODULE(target) Release/.node |
|
||||
CXX(target) Release/obj.target/fse/fsevents.o |
|
||||
In file included from ../fsevents.cc:6: |
|
||||
|
|
||||
... |
|
||||
|
|
||||
added 1390 packages from 766 contributors and audited 15238 packages in 16.11s |
|
||||
found 1 high severity vulnerability |
|
||||
run `npm audit fix` to fix them, or `npm audit` for details |
|
||||
$ |
|
||||
``` |
|
||||
|
|
||||
This command creates a `node_modules` subdirectory to your project code and |
|
||||
installs all the code libraries you need for your Animal Kingdom project. |
|
||||
|
|
||||
3. Enter the `ls` command to list the contents of your project directory to verify `npm` installed correctly. |
|
||||
|
|
||||
``` |
|
||||
$ ls |
|
||||
``` |
|
||||
|
|
||||
The `node_modules`directory contains many core libraries used by Animal |
|
||||
Kingdom. For example, the Blockstack Javascript library is in the |
|
||||
`nodule_modules/blockstack/lib` subdirectory. |
|
||||
|
|
||||
4. Start the Animal Kingdom DApp running on your workstation by entering: |
|
||||
|
|
||||
```bash |
|
||||
npm start |
|
||||
``` |
|
||||
|
|
||||
The `npm` program compiles the Animal Kingdom code. Once the code compiles, |
|
||||
the DApp opens Animal Kingdom running at the `http://localhost:3000` URL in |
|
||||
your browser. |
|
||||
|
|
||||
4. From the initial Animal Kingdom screen, choose an animal person and a territory. |
|
||||
5. Press **Done** at the bottom of the page. |
|
||||
|
|
||||
The Animal Kingdom makes a call to the Gaia hub to store your selection. |
|
||||
After a brief pause, the DApp returns you to the **Your Kingdom** page. If |
|
||||
you have problems, refresh the page and click **Your Kingdom** in the |
|
||||
menu. |
|
||||
|
|
||||
<img src="images/kingdom-ruler.png" alt=""> |
|
||||
|
|
||||
6. Spend a little time exploring the application. |
|
||||
|
|
||||
For example, you could edit your animal or visit the other pages such as **Animals** or **Territories**. |
|
||||
|
|
||||
7. Go back to your terminal where you started you application is running. |
|
||||
8. Press `CTRL-C` to stop the application. |
|
||||
|
|
||||
<img src="images/kingdom-stop.png" alt=""> |
|
||||
|
|
||||
You can start it again with `npm start` as you will later in this tutorial. |
|
||||
|
|
||||
|
|
||||
## Understand the application code |
|
||||
|
|
||||
The application has two major components, React and Blockstack. React is used to |
|
||||
build all the web components and interactions. You could replace React with any |
|
||||
framework that you like; Blockstack is web framework agnostic. This section does |
|
||||
not explain the React in any detail; The discussion focuses on the Blockstack |
|
||||
Javascript library the DApp instead. |
|
||||
|
|
||||
The <a href="https://blockstack.github.io/blockstack.js/" |
|
||||
target="\_blank">Blockstack Javascript library is all a developer needs to |
|
||||
create a DApp. It grants</a> the application the ability to authenticate a |
|
||||
Blockstack identity and to read and write to the user's data stored in a Gaia |
|
||||
hub. |
|
||||
|
|
||||
### Authenticating user identity |
|
||||
{:.no_toc} |
|
||||
|
|
||||
The `src/App.js` file creates a Blockstack `UserSession` and uses that session's |
|
||||
`isUserSignedIn()` method to determine if the user is signed in or out of the |
|
||||
application. Depending on the result of this method. The application redirects |
|
||||
to the `src/SignedIn` page or to the `src/Landing.js` page. |
|
||||
|
|
||||
```js |
|
||||
import React, { Component } from 'react' |
|
||||
import './App.css' |
|
||||
import { UserSession } from 'blockstack' |
|
||||
|
|
||||
import Landing from './Landing' |
|
||||
import SignedIn from './SignedIn' |
|
||||
|
|
||||
class App extends Component { |
|
||||
|
|
||||
constructor() { |
|
||||
super() |
|
||||
this.userSession = new UserSession() |
|
||||
} |
|
||||
|
|
||||
componentWillMount() { |
|
||||
const session = this.userSession |
|
||||
if(!session.isUserSignedIn() && session.isSignInPending()) { |
|
||||
session.handlePendingSignIn() |
|
||||
.then((userData) => { |
|
||||
if(!userData.username) { |
|
||||
throw new Error('This app requires a username.') |
|
||||
} |
|
||||
window.location = `/kingdom/${userData.username}` |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
render() { |
|
||||
return ( |
|
||||
<main role="main"> |
|
||||
{this.userSession.isUserSignedIn() ? |
|
||||
<SignedIn /> |
|
||||
: |
|
||||
<Landing /> |
|
||||
} |
|
||||
</main> |
|
||||
); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export default App |
|
||||
``` |
|
||||
|
|
||||
The first time you start the application, this code determines if the user has |
|
||||
signed into the DApp previously. If not, it opens the `Landing.js` page. This |
|
||||
page offers the user an opportunity to **Sign in to Blockstack**. |
|
||||
|
|
||||
Clicking the button ends up calling the `redirectToSignIn()` method which generates an |
|
||||
authentication request and redirects the user to the Blockstack browser to |
|
||||
approve the sign in request. The actual Blockstack sign-in dialog depends on |
|
||||
whether the user already has an existing session in the Blockstack Browser. |
|
||||
|
|
||||
<img src="images/kingdom_notin.png" alt=""> |
|
||||
|
|
||||
Signing in with an identity is the means by which the user grants the DApp |
|
||||
access. Access means the DApp can read the user profile and read/write user data |
|
||||
for the DApp. Data is encrypted at a unique URL on a GAI storage hub. |
|
||||
|
|
||||
### Get and put user data to a GAIA Hub |
|
||||
{:.no_toc} |
|
||||
|
|
||||
GAI is the Blockstack data storage hub (https://hub.blockstack.org). Once a user |
|
||||
authenticates, the application can get and put application data in the user's |
|
||||
storage. After a user signs in, the `SignedIn.js` code checks the user's GAI |
|
||||
profile by running the `loadMe()` method. |
|
||||
|
|
||||
```js |
|
||||
loadMe() { |
|
||||
const options = { decrypt: false } |
|
||||
this.userSession.getFile(ME_FILENAME, options) |
|
||||
.then((content) => { |
|
||||
if(content) { |
|
||||
const me = JSON.parse(content) |
|
||||
this.setState({me, redirectToMe: false}) |
|
||||
} else { |
|
||||
const me = null |
|
||||
|
|
||||
this.setState({me, redirectToMe: true}) |
|
||||
} |
|
||||
}) |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
The `loadMe()` code uses the Blockstack's `getFile()` method to get the |
|
||||
specified file from the applications data store. If the users' data store on |
|
||||
GAIA does not have the data, which is the case for a new users, the Gaia hub |
|
||||
responds with HTTP `404` code and the `getFile` promise resolves to null. If you |
|
||||
are using a Chrome Developer Tools with the DApp, you'll see these errors in a |
|
||||
browser's developer **Console**. |
|
||||
|
|
||||
<img src="images/kingdom-errors.png" alt=""> |
|
||||
|
|
||||
After a user choses an animal persona and a territory, the user presses **Done** |
|
||||
and the application stores the user data on GAIA. |
|
||||
|
|
||||
```js |
|
||||
saveMe(me) { |
|
||||
this.setState({me, savingMe: true}) |
|
||||
const options = { encrypt: false } |
|
||||
this.userSession.putFile(ME_FILENAME, JSON.stringify(me), options) |
|
||||
.finally(() => { |
|
||||
this.setState({savingMe: false}) |
|
||||
}) |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
The Blockstack <a href="https://blockstack.github.io/blockstack.js/#putfile" |
|
||||
target="\_blank"><code>putFile()</code></a> stores the data provided in the |
|
||||
user's DApp data store. You can view the URL for the data store from a user's |
|
||||
profile. If you tested your Animal Kingdom, you can see this on your profile. |
|
||||
To see your profile, go to the Blockstack explorer and search for your ID: |
|
||||
|
|
||||
<img src="images/explorer.png" alt=""> |
|
||||
|
|
||||
In the next section, you extend your Kingdom's configuration. |
|
||||
|
|
||||
## Expand your kingdom |
|
||||
|
|
||||
Your DApp contains three pages **Animals**, **Territories**, and **Other |
|
||||
Kingdoms** that are derived from three code elements: |
|
||||
|
|
||||
* The `src/constants.js` file defines the application's data profile. |
|
||||
* The `public/animals` directory which contains images. |
|
||||
* The `public/territories` directory which contains images. |
|
||||
|
|
||||
In this section, you learn how to add another kingdom to the available **Other |
|
||||
Kingdoms** and how to add another territory. |
|
||||
|
|
||||
### Add a territory |
|
||||
{:.no_toc} |
|
||||
|
|
||||
If your application is still running in localhost stop it with a `CTRL-C` from |
|
||||
your keyboard. |
|
||||
|
|
||||
1. Decide what kind of territory to add &emdash; desert, ocean, or city! |
|
||||
|
|
||||
This example adds Westeros, a fictional territory. |
|
||||
|
|
||||
2. Search for an image to represent your new territory. |
|
||||
|
|
||||
Google images is a good place to find <a href="images/westeros.jpg" target="\_blank">a JPEG image of Westeros</a>. |
|
||||
|
|
||||
3. Save the image to the `public/territories` folder in your Animal Kingdom project code. |
|
||||
|
|
||||
{% include warning.html content="The territory filename must be all lower case and have a <code>.jpg</code> extension. |
|
||||
For this example, the territory image is saved in the <code>westeros.jpg</code> file." %} |
|
||||
|
|
||||
4. Use the `ls` command to confirm your file appears in `territories` directory and has the correct name. |
|
||||
|
|
||||
```bash |
|
||||
ls public/territories/ |
|
||||
forest.jpg tundra.jpg westeros.jpg |
|
||||
``` |
|
||||
|
|
||||
4. Open the `src/constant.js` file in your favorite editor. |
|
||||
5. Scroll down to the section that defines the **Territories**. |
|
||||
|
|
||||
```js |
|
||||
export const TERRITORIES = [ |
|
||||
{ |
|
||||
id: 'forest', |
|
||||
name: 'Forest', |
|
||||
superpower: 'Trees!' |
|
||||
}, |
|
||||
{ |
|
||||
id: 'tundra', |
|
||||
name: 'Tundra', |
|
||||
superpower: 'Let it snow!' |
|
||||
} |
|
||||
] |
|
||||
``` |
|
||||
|
|
||||
6. Add your new territory. |
|
||||
|
|
||||
```js |
|
||||
export const TERRITORIES = [ |
|
||||
{ |
|
||||
id: 'forest', |
|
||||
name: 'Forest', |
|
||||
superpower: 'Trees!' |
|
||||
}, |
|
||||
{ |
|
||||
id: 'tundra', |
|
||||
name: 'Tundra', |
|
||||
superpower: 'Let it snow!' |
|
||||
}, |
|
||||
{ |
|
||||
id: 'westeros', |
|
||||
name: 'Westeros', |
|
||||
superpower: 'The Iron Throne!' |
|
||||
} |
|
||||
] |
|
||||
``` |
|
||||
7. Save and close the `contstant.js` file. |
|
||||
8. Back in a terminal window, restart your application. |
|
||||
|
|
||||
```bash |
|
||||
$ npm start |
|
||||
``` |
|
||||
9. After the application starts, navigate to the **Territories** page and look for your `Westeros` territory. |
|
||||
|
|
||||
<img src="images/kingdom-throne.png" alt=""> |
|
||||
|
|
||||
### Add the Blockstack kingdom |
|
||||
{:.no_toc} |
|
||||
|
|
||||
Your Animal Kingdom has only recognizes two **Other Kingdoms**. In this section, |
|
||||
you add a third, the Blockstack kingdom (`https://animalkingdoms.netlify.com`). |
|
||||
|
|
||||
1. Open the `src/constant.js` file in your favorite editor. |
|
||||
|
|
||||
On Mac you can use TextEdit or Vim. |
|
||||
|
|
||||
2. Scroll down to the section that defines the **Other Kingdoms** |
|
||||
|
|
||||
```js |
|
||||
export const OTHER_KINGDOMS = [ |
|
||||
{ |
|
||||
app: 'https://animal-kingdom-1.firebaseapp.com', |
|
||||
ruler: 'larry.id' |
|
||||
}, |
|
||||
{ |
|
||||
app: 'http://localhost:3001', |
|
||||
ruler: 'larz.id' |
|
||||
} |
|
||||
] |
|
||||
``` |
|
||||
|
|
||||
To add a kingdom, you need its URL and the ID of its owner. |
|
||||
|
|
||||
3. Edit the file and add the `https://animalkingdoms.netlify.com` which is owned by `moxiegirl.id.blockstack`. |
|
||||
|
|
||||
When you are done the file will look like this. |
|
||||
|
|
||||
|
|
||||
```js |
|
||||
export const OTHER_KINGDOMS = [ |
|
||||
{ |
|
||||
app: 'https://animal-kingdom-1.firebaseapp.com', |
|
||||
ruler: 'larry.id' |
|
||||
}, |
|
||||
{ |
|
||||
app: 'http://localhost:3001', |
|
||||
ruler: 'larz.id' |
|
||||
}, |
|
||||
{ |
|
||||
app: 'https://animalkingdoms.netlify.com', |
|
||||
ruler: 'moxiegirl.id.blockstack' |
|
||||
} |
|
||||
] |
|
||||
``` |
|
||||
|
|
||||
4. Save and close the `constants.js` file. |
|
||||
5. Back in your browser, navigate to the **Other Kingdoms** page. |
|
||||
|
|
||||
<img src="images/kingdom-moxiegirl.png" alt=""> |
|
||||
|
|
||||
7. Got to the `moxiegirl` kingdom by clicking on her kingdom. |
|
||||
8. Try adding a subject from Moxiegirl's kingdom to yours. |
|
||||
|
|
||||
|
|
||||
## Go live on the Internet |
|
||||
|
|
||||
In this section you use a free Netlify account and a free GitHub account to take |
|
||||
your kingdom live on the internet. Netlify provides hosting and serverless |
|
||||
backend services for static websites. GitHub is a code hosting site. |
|
||||
|
|
||||
### Run your Kingdom on the internet |
|
||||
{:.no_toc} |
|
||||
|
|
||||
So far, you've been running the application locally. This means you are the only |
|
||||
person that can use it to create a kingdom. You can make your application |
|
||||
available to others by hosting it out on the internet. You can do this for free |
|
||||
with a Netlify account. |
|
||||
|
|
||||
Before you begin, you need to build a site that is ready to deploy. |
|
||||
|
|
||||
1. In your terminal, press `CTRL-C` on your keyboard to stop your `npm start` build. |
|
||||
2. Build a website from your code by entering the `npm run build` command: |
|
||||
|
|
||||
```bash |
|
||||
npm run build |
|
||||
``` |
|
||||
|
|
||||
<img src="images/run-build.png" alt=""> |
|
||||
|
|
||||
When the command completes, you should have a new `build` subdirectory in your project. |
|
||||
|
|
||||
3. Open your project in the Finder. |
|
||||
4. Locate the newly created `build` subfolder. |
|
||||
|
|
||||
<img src="images/finder-build.png" alt=""> |
|
||||
|
|
||||
5. <a href="https://app.netlify.com/signup" target="\_blank">Sign up for a free Netlify account</a> |
|
||||
|
|
||||
<img src="images/netlify-account.gif" alt=""> |
|
||||
|
|
||||
6. In your email inbox, find Netlify's welcome email and verify your account. |
|
||||
|
|
||||
<img src="images/netlify-verify.png" alt=""> |
|
||||
|
|
||||
7. Log into Netlify and go to the **Overview** page in your browser. |
|
||||
8. Drag your `build` subdirectory from the Finder into the drop zone in Netlify. |
|
||||
|
|
||||
<img src="images/netlify-deploy.gif" alt=""> |
|
||||
|
|
||||
After a moment, Netlify builds your code and displays the location of your new webiste. |
|
||||
|
|
||||
<img src="images/kingdom-build.png" alt=""> |
|
||||
|
|
||||
9. Click on your website name to display the website. |
|
||||
|
|
||||
You are prompted to sign into this new site with your Blockstack ID. |
|
||||
|
|
||||
10. Click **Sign in with Blockstack**. |
|
||||
|
|
||||
After you sign in, your website presents you with this message: |
|
||||
|
|
||||
<img src="images/kingdom-failed.png" alt=""> |
|
||||
|
|
||||
You get this message because, when you authenticates, your DApp at one URL |
|
||||
requested a resource (an identity) from another DApp, the Blockstack |
|
||||
Browser. A request for a resource outside of the origin (your new website) |
|
||||
is called as a _cross-origin request_(CORs). Getting data in this manner can |
|
||||
be risky, so you must configure your website security to allow interactions |
|
||||
across origins. |
|
||||
|
|
||||
<div class="uk-inline"> |
|
||||
<button class="uk-button uk-button-primary" enter="button">Read a bit more, fun, explanation of CORS</button> |
|
||||
<div uk-dropdown> |
|
||||
You can think of CORS interactions as an apartment building with Security. |
|
||||
For example, if you need to borrow a ladder, you could ask a neighbor in |
|
||||
your building who has one. Security would likely not have a problem with |
|
||||
this request (i.e., same-origin, your building). If you needed a particular |
|
||||
tool, however, and you ordered it delivered from an online hardware store |
|
||||
(i.e., cross-origin, another site), Security may request identificatin |
|
||||
before allowing the delivery man into the apartment building. |
|
||||
<br> |
|
||||
Credit: <a href="https://www.codecademy.com/articles/what-is-cors" target="\_blank">Codecademy</a> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
The way you configure CORs depends on which company is serving your website. |
|
||||
You are using Netlify for this example. |
|
||||
|
|
||||
11. Locate the `cors/_headers` and `cors/_redirects` in your project. |
|
||||
|
|
||||
You can use the Finder or the `ls` command. |
|
||||
|
|
||||
|
|
||||
12. Copy them into your `public` directory. |
|
||||
|
|
||||
To copy them with the `ls` command, enter the following in the root of the `animal-kingdom-master` project. |
|
||||
|
|
||||
```bash |
|
||||
cp cors/_headers public |
|
||||
cp cors/_redirects public |
|
||||
``` |
|
||||
|
|
||||
The name of each file, with the underscore, is essential. |
|
||||
|
|
||||
13. Make sure you are in the `animal-kingdom-master` directory, run the `npm run build` command again. |
|
||||
15. Drag the `build` file back into the Netlify drop zone. |
|
||||
|
|
||||
After a moment, Netlify publishes your site. Check the published location, it may have changed. |
|
||||
|
|
||||
16. Click on the link and log into your Animal Kingdom. |
|
||||
17. Recreate your animal person and territory. |
|
||||
|
|
||||
The Animal Kingdom is identified by its location on the Internet, remember? |
|
||||
So, the animal kingdom you created on your local workstation is different |
|
||||
than the one you create on Netlify. |
|
||||
|
|
||||
### Add your Kingdom to our Clan |
|
||||
{:.no_toc} |
|
||||
|
|
||||
At this point, your kingdom is isolated. If you know another kingdom, you can |
|
||||
add subjects from that kingdom but other kingdoms can access your subjects. In |
|
||||
this section, you use a free GitHub account to add your kingdom to the |
|
||||
Blockstack kingdom. |
|
||||
|
|
||||
1. If you have a GitHub account, go to step 2 otherwise go to GitHub <a href="https://github.com/" target="\_blank">site and create a new account</a>. |
|
||||
2. Go to the <a href="https://github.com/blockstack/animal-kingdom/issues" target="\_blank">https://github.com/blockstack/animal-kingdom/issues</a> repository on Github. |
|
||||
2. Click **New Issue**. |
|
||||
|
|
||||
The new issue dialog appears. |
|
||||
|
|
||||
3. Fill out the issue with the URL from Netlify and your Blockstack id. |
|
||||
|
|
||||
When you are done, your issue will look like the following: |
|
||||
|
|
||||
<img src="images/kingdom-issue.png" alt=""> |
|
||||
|
|
||||
4. Press **Submit new issue**. |
|
||||
|
|
||||
The Blockstack team will add your Netlify kingdom to ours. When we do that, we will notify you on the issue and you'll also get an email. |
|
||||
|
|
||||
5. When you receive the email, login into the Blockstack Animal kingdom to see your kingdom under **Other Kingdoms**. |
|
||||
|
|
||||
|
|
||||
## Next Steps |
|
||||
{:.no_toc} |
|
||||
|
|
||||
Well, you have produced your very first DApp. Congratulations! If you have a |
|
||||
twitter account, why not tell some folks? |
|
||||
|
|
||||
<a href="https://twitter.com/share?ref_src=twsrc%5Etfw" |
|
||||
class="twitter-share-button" data-size="large" data-text="I just built a DApp |
|
||||
using @blockstacks's Zero to DApp tutorial! " data-hashtags="blockstack, |
|
||||
blockchain, blockchainnopain, blockchainnopainblockstack" |
|
||||
data-show-count="false">Tweet your work!</a><script async |
|
||||
src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> | |
|
||||
|
|
||||
In the next section, you submit your [DApp to our listings on App.co](#). |
|
Loading…
Reference in new issue