In accumsan lacus ac neque maximus dictum. Phasellus eleifend leo id mattis bibendum. Curabitur et purus turpis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
Cras at dolor eget urna varius faucibus tempus in elit. Cras a dui imperdiet, tempus metus quis, pharetra turpis. Phasellus at massa sit amet ante semper fermentum sed eget lectus. Quisque id dictum magna turpis.
@@ -356,24 +359,27 @@ modify the hello-world to interact with t
Create a hello-blockstack directory.
-
mkdir hello-blockstack
-
+
mkdir hello-blockstack
+
+
Change into your new directory.
-
cd hello-blockstack
-
+
cd hello-blockstack
+
+
Use Yeoman and the Blockstack application generator to create your initial hello-blockstack application.
-
yo blockstack:react
-
+
yo blockstack:react
+
+
You should see several interactive prompts.
-
$ yo blockstack:react
+
$ yo blockstack:react
==========================================================================
We are constantly looking for ways to make yo better!
May we anonymously report usage statistics to improve the tool over time?
@@ -382,8 +388,8 @@ modify the hello-world to interact with t
_-----_ ╭──────────────────────────╮
| | │ Welcome to the │
- |--(o)--| │ Blockstack app │
- --------- │ generator! │
+ |--(o)--| │ Blockstack app │
+ --------- │ generator! │
( _U_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
@@ -391,26 +397,28 @@ modify the hello-world to interact with t
|° Y
? Are you ready to build a Blockstack app in React? (Y/n)
-
+
+
Respond to the prompts to populate the initial app.
After the process completes successfully, you see a prompt similar to the following:
-
[fsevents] Success:
+
[fsevents] Success:
"/Users/theuser/repos/hello-blockstack/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
-
+
+
Run the initial application.
-
$ npm start
+
$ npm start
- > hello-blockstack@0.0.0 start /Users/moxiegirl/repos/hello-blockstack
- > webpack-dev-server
+ > hello-blockstack@0.0.0 start /Users/moxiegirl/repos/hello-blockstack
+ > webpack-dev-server
Project is running at http://localhost:8080/
webpack output is served from /
@@ -427,7 +435,8 @@ modify the hello-world to interact with t
[2] (webpack)/buildin/global.js 509 bytes {0}[built]
[3] (webpack)/buildin/module.js 517 bytes {0}[built]
webpack: Compiled successfully.
-
+
+
The system opens a browser displaying your running application.
@@ -472,13 +481,14 @@ application directory.
This endpoint on the web version of your app will redirect Android users back
to your mobile app.
Blockstack apps are identified by their domain names. The endpoint will
receive a get request with the query parameter authResponse=XXXX and
@@ -773,7 +784,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
When you are done, your imports should appear as follows:
-
+
importandroid.support.v7.app.AppCompatActivityimportandroid.os.Bundle
@@ -784,27 +795,29 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
importorg.blockstack.android.sdk.Scopeimportorg.blockstack.android.sdk.UserDataimportjava.net.URI
-
+
+
Add a variable for the Blockstack session before onCreate.
overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)
@@ -829,7 +842,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
})
- signInButton.setOnClickListener{view:View->
+ signInButton.setOnClickListener{view:View->blockstackSession().redirectUserToSignIn{userData->if(userData.hasValue){runOnUiThread{
@@ -839,11 +852,12 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
}}if(intent?.action==Intent.ACTION_VIEW){
- // handle the redirect from sign in
- handleAuthResponse(intent)
+ // handle the redirect from sign in
+handleAuthResponse(intent)}}
-
+
+
This new onCreate does several things:
@@ -863,13 +877,14 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
Add a private function to reflect when a user successfully signs in.
-
privatefunonSignIn(userData:UserData){
+
privatefunonSignIn(userData:UserData){userDataTextView.text="Signed in as ${userData.decentralizedID}"signInButton.isEnabled=false}
-
+
+
Handle sign in requests with an onNewIntent function if the activity was already opened when signing in
@@ -877,19 +892,20 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
Retrieve the authentication token from the custom protocol handler call and
send it to the Blockstack session.
privatefunhandleAuthResponse(intent:Intent){valresponse=intent.dataStringif(response!=null){valauthResponseTokens=response.split(':')
@@ -899,8 +915,8 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
blockstackSession().handlePendingSignIn(authResponse,{userData->if(userData.hasValue){
- // The user is now signed in!
- runOnUiThread{
+ // The user is now signed in!
+runOnUiThread{onSignIn(userData.value!!)}}
@@ -908,12 +924,13 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
}}}
-
+
+
Add the convenience method to access the blockstack session.
-
funblockstackSession():BlockstackSession{
+
funblockstackSession():BlockstackSession{valsession=_blockstackSessionif(session!=null){returnsession
@@ -921,17 +938,18 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
throwIllegalStateException("No session.")}}
-
+
+
Verify your final MainActivity.kt code looks like this:
-
classMainActivity:AppCompatActivity(){
+
classMainActivity:AppCompatActivity(){privatevar_blockstackSession:BlockstackSession?=null
- overridefunonCreate(savedInstanceState:Bundle?){
+ overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)
@@ -947,7 +965,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
})
- signInButton.setOnClickListener{view:View->
+ signInButton.setOnClickListener{view:View->blockstackSession().redirectUserToSignIn{userData->if(userData.hasValue){runOnUiThread{
@@ -961,14 +979,14 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
}}
- privatefunonSignIn(userData:UserData){
+ privatefunonSignIn(userData:UserData){userDataTextView.text="Signed in as ${userData.decentralizedID}"signInButton.isEnabled=false}
- overridefunonNewIntent(intent:Intent?){
+ overridefunonNewIntent(intent:Intent?){super.onNewIntent(intent)if(intent?.action==Intent.ACTION_VIEW){
@@ -976,7 +994,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
}}
- privatefunhandleAuthResponse(intent:Intent){
+ privatefunhandleAuthResponse(intent:Intent){valresponse=intent.dataStringif(response!=null){valauthResponseTokens=response.split(':')
@@ -986,8 +1004,8 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
blockstackSession().handlePendingSignIn(authResponse,{userData->if(userData.hasValue){
- // The user is now signed in!
- runOnUiThread{
+ // The user is now signed in!
+runOnUiThread{onSignIn(userData.value!!)}}
@@ -996,7 +1014,7 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
}}
- funblockstackSession():BlockstackSession{
+ funblockstackSession():BlockstackSession{valsession=_blockstackSessionif(session!=null){returnsession
@@ -1007,7 +1025,8 @@ the SDK. This SDK includes a themed “Sign in with Blockstack” button
}
-
+
+
diff --git a/_site/browser/blockstack_storage.html b/_site/browser/blockstack_storage.html
index 509f7b70..90817026 100644
--- a/_site/browser/blockstack_storage.html
+++ b/_site/browser/blockstack_storage.html
@@ -7,7 +7,7 @@
Blockstack Storage Tutorial | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/browser/blockstack_storage.html","headline":"Blockstack Storage Tutorial","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/blockstack_storage.html"},"description":"Blockstack Storage Tutorial","@type":"BlogPosting","@context":"http://schema.org"}
@@ -195,13 +195,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -259,9 +259,10 @@ the application, you need to have already registered
Use Yeoman and the Blockstack application generator to create your initial publik application.
-
yo blockstack:react
-
+
yo blockstack:react
+
+
You should see several interactive prompts.
-
$ yo blockstack:react
+
$ 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?
@@ -334,24 +340,27 @@ existing projects.
´ ` |° ´ Y `
? Are you ready to build a Blockstack app in React? (Y/n)
-
+
+
Respond to the prompts to populate the initial app.
After the process completes successfully, you see a prompt similar to the following:
-
[fsevents] Success:
+
[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
-
+
+
Run the initial application.
-
npm start
-
+
npm start
+
+
The system prompts you to accept incoming connections.
@@ -395,21 +404,23 @@ stored on Gaia are made visible to others via the handleSignIn handler method.
-
By default, authentication requests include the store_write scope which
enables storage. This is what allows you to store information to Gaia.
@@ -443,17 +454,18 @@ delete grocery lists.
A single file collection stores items as an array nested inside each grocery
list:
-
// grocerylists.json
+
// grocerylists.json{
- "3255":{
- "items":[
+ "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
@@ -492,26 +504,28 @@ or remove a grocery list; updating a list has no impact.
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:
-
+
When you are done, the import statement should look like the following:
+
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:
-
constructor(props){
- super(props);
+
constructor(props){
+ super(props);this.state={person:{
@@ -529,7 +543,8 @@ or remove a grocery list; updating a list has no impact.
isLoading:false};}
-
+
+
Locate the render() method.
@@ -538,10 +553,10 @@ or remove a grocery list; updating a list has no impact.
The following code echos the person.name and person.avatarURL
properties from the profile on the display:
render(){
+ const{handleSignOut}=this.props;
+ const{person}=this.state;
+ const{username}=this.state;return(!isSignInPending()&&person?
@@ -554,8 +569,8 @@ or remove a grocery list; updating a list has no impact.
src={person.avatarUrl()?person.avatarUrl():avatarFallbackImage}className="img-rounded avatar"id="avatar-image"
- />
- <divclassName="username">
+ />
+<divclassName="username"><h1><spanid="heading-name">{person.name()?person.name():'Nameless Person'}</span>
@@ -575,8 +590,8 @@ or remove a grocery list; updating a list has no impact.
value={this.state.newStatus}onChange={e=>this.handleNewStatusChange(e)}placeholder="Enter a status"
- />
- </div>
+ />
+</div>
<divclassName="col-md-12"><buttonclassName="btn btn-primary btn-lg"
@@ -592,7 +607,8 @@ or remove a grocery list; updating a list has no impact.
</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
@@ -604,18 +620,19 @@ user profile data.
You’ll use the Blockstack loadUserData() method to access the username.
@@ -675,7 +694,7 @@ the statuses back to the user as a blog entry.
Right after this opening div element, add this block.
-
<divclassName="col-md-12 statuses">
+
<divclassName="col-md-12 statuses">{this.state.isLoading&&<span>Loading...</span>}
{this.state.statuses.map((status)=>(<divclassName="status"key={status.id}>
@@ -684,16 +703,17 @@ the statuses back to the user as a blog entry.
))}</div>
-
+
+
This loads existing state. Your code needs to fetch statuses on page load.
Add a new method called fetchData() after the statuses.unshift(status) section.
-
+
fetchData(){this.setState({isLoading:true})
- constoptions={decrypt:false}
+ constoptions={decrypt:false}getFile('statuses.json',options).then((file)=>{varstatuses=JSON.parse(file||'[]')
@@ -708,16 +728,18 @@ the statuses back to the user as a blog entry.
this.setState({isLoading:false})})}
-
+
+
Call fetchData() from the componentDidMount() method
-
+
componentDidMount(){this.fetchData()}
-
+
+
Save the file.
@@ -736,7 +758,7 @@ the statuses back to the user as a blog entry.
Replace the content with the following:
-
/* Globals */
+
/* Globals */a,a:focus,a:hover{color:#fff;}html,body{height:100%;text-align:center;background-color:#191b22;}body{color:#fff}
@@ -771,7 +793,8 @@ the statuses back to the user as a blog entry.
/* Statuses */.statuses{padding-top:30px;}.status{margin:15px0px;padding:20px;background-color:#2e2e2e;border-radius:6px}
-
+
+
Save and close the src/styles/style.css file.
@@ -803,44 +826,49 @@ other users’ profiles by visiting http://local
Install react-router:
-
npm install--save react-router-dom
-
+
npm install --save react-router-dom
+
+
Edit src/index.js file.
Add an import to the file at the top:
-
import{BrowserRouter}from'react-router-dom'
-
+
import{BrowserRouter}from'react-router-dom'
+
+
Change the ReactDOM.render() method in src/index.js to:
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.
Modify the fetchData() method like so:
-
fetchData(){
+
fetchData(){this.setState({isLoading:true})if(this.isLocal()){
- constoptions={decrypt:false}
+ constoptions={decrypt:false}getFile('statuses.json',options).then((file)=>{varstatuses=JSON.parse(file||'[]')
@@ -917,7 +949,7 @@ process URL paths that contain the . (dot
this.setState({isLoading:false})})}else{
- constusername=this.props.match.params.username
+ constusername=this.props.match.params.usernamelookupProfile(username).then((profile)=>{
@@ -931,7 +963,8 @@ process URL paths that contain the . (dot
})}}
-
+
+
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.
@@ -943,7 +976,7 @@ process URL paths that contain the . (dot
Add the following block to fetchData() right after the call to lookupProfile(username)... catch((error)=>{..} block:
-
constoptions={username:username,decrypt:false}
+
constoptions={username:username,decrypt:false}getFile('statuses.json',options).then((file)=>{varstatuses=JSON.parse(file||'[]')
@@ -958,7 +991,8 @@ process URL paths that contain the . (dot
.finally(()=>{this.setState({isLoading:false})})
-
+
+
This fetches the user statuses.
@@ -967,10 +1001,10 @@ process URL paths that contain the . (dot
render(){
+ const{handleSignOut}=this.props;
+ const{person}=this.state;
+ const{username}=this.state;return(!isSignInPending()&&person?
@@ -983,8 +1017,8 @@ process URL paths that contain the . (dot
src={person.avatarUrl()?person.avatarUrl():avatarFallbackImage}className="img-rounded avatar"id="avatar-image"
- />
- <divclassName="username">
+ />
+<divclassName="username"><h1><spanid="heading-name">{person.name()?person.name():'Nameless Person'}</span>
@@ -1006,8 +1040,8 @@ process URL paths that contain the . (dot
value={this.state.newStatus}onChange={e=>this.handleNewStatusChange(e)}placeholder="What's on your mind?"
- />
- </div>
+ />
+</div>
<divclassName="col-md-12 text-right"><buttonclassName="btn btn-primary btn-lg"
@@ -1032,9 +1066,10 @@ process URL paths that contain the . (dot
</div> : null
);}
-
+
+
-
### This checks to ensure that users are viewing their own profile, by wrapping the Logout button and inputs with the {isLocal() && ...} condition.
+
### This checks to ensure that users are viewing their own profile, by wrapping the Logout button and inputs with the {isLocal()&&...} condition.
@@ -1045,8 +1080,9 @@ process URL paths that contain the . (dot
Restart the application so that the disabling of the . (dot) rule takes effect.
-
npm start
-
+
npm start
+
+
Point your browser to http://localhost:8080/your_blockstack.id to see the final application.
diff --git a/_site/browser/browser-introduction.html b/_site/browser/browser-introduction.html
index 2c300ae6..23ab55c7 100644
--- a/_site/browser/browser-introduction.html
+++ b/_site/browser/browser-introduction.html
@@ -7,7 +7,7 @@
Get the Blockstack Browser | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/browser/browser-introduction.html","headline":"Get the Blockstack Browser","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/browser-introduction.html"},"description":"Get the Blockstack Browser","@type":"BlogPosting","@context":"http://schema.org"}
@@ -159,13 +159,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -335,49 +335,55 @@ Blockstack, install the version of Do
Use Yeoman and the Blockstack application generator to create your initial hello-world-tutorial application.
-
yo blockstack
-
+
yo blockstack
+
+
You should see several interactive prompts.
-
$ yo blockstack
+
$ yo blockstack
_-----_ ╭──────────────────────────╮
| | │ Welcome to the │
- |--(o)--| │ Blockstack app │
- `---------´ │ generator! │
+ |--(o)--| │ Blockstack app │
+ `---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
@@ -326,14 +332,15 @@ existing projects.
´ ` |° ´ Y `
? Are you ready to build a Blockstack app in React? (Y/n)
-
+
+
Respond to the prompts to populate the initial app.
After the process completes successfully, you see a prompt similar to the following:
-
...
+
...
create public/icon-192x192.png
create public/index.html
create public/robots.txt
@@ -341,7 +348,8 @@ 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.
-
+
+
@@ -443,8 +451,9 @@ and open your browser ‘http://localhost:5000’. From the root of your new ap
Start the application server.
-
npm start
-
+
npm start
+
+
The first time you run it, your system prompts you to accept incoming connections.
@@ -505,27 +514,30 @@ in the public/app.css file. Open this fil
All of the code in the file is wrapped in an event
listener.
You can find the redirectUserToSignIn() function is part of the Blockstack Javascript documentation. There is also a sign out button handler. This handler deletes the local user data and signs the user out:
Each getElementById() function refers to elemments in the index.html file.
@@ -550,7 +563,7 @@ several states the user can be in:
The application handles these situtations as followed:
-
if(blockstack.isUserSignedIn()){
+
if(blockstack.isUserSignedIn()){varprofile=blockstack.loadUserData().profileshowProfile(profile)}elseif(blockstack.isSignInPending()){
@@ -558,7 +571,8 @@ several states the user can be in:
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
@@ -571,17 +585,18 @@ user back to the home page.
configurations dictate how the application is displayed in auth views and on
user home screens. The contents are very simple:
-
Push your new code to the master branch of the remote repo:
-
git push origin master
-
+
git push origin master
+
+
diff --git a/_site/browser/ids-introduction.html b/_site/browser/ids-introduction.html
index acc3917d..923cde61 100644
--- a/_site/browser/ids-introduction.html
+++ b/_site/browser/ids-introduction.html
@@ -7,7 +7,7 @@
Get and use a Blockstack ID | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/browser/ids-introduction.html","headline":"Get and use a Blockstack ID","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/ids-introduction.html"},"description":"Get and use a Blockstack ID","@type":"BlogPosting","@context":"http://schema.org"}
@@ -159,13 +159,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
diff --git a/_site/browser/multi-player-storage.html b/_site/browser/multi-player-storage.html
index 35bb324e..71463d57 100644
--- a/_site/browser/multi-player-storage.html
+++ b/_site/browser/multi-player-storage.html
@@ -7,7 +7,7 @@
Manage Data with Gaia | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/browser/multi-player-storage.html","headline":"Manage Data with Gaia","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/multi-player-storage.html"},"description":"Manage Data with Gaia","@type":"BlogPosting","@context":"http://schema.org"}
@@ -195,13 +195,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -259,9 +259,10 @@ the application, you need to have already register
Use Yeoman and the Blockstack application generator to create your initial publik application.
-
yo blockstack:react
-
+
yo blockstack:react
+
+
You should see several interactive prompts.
-
$ yo blockstack:react
+
$ 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?
@@ -334,24 +340,27 @@ existing projects.
´ ` |° ´ Y `
? Are you ready to build a Blockstack app in React? (Y/n)
-
+
+
Respond to the prompts to populate the initial app.
After the process completes successfully, you see a prompt similar to the following:
-
[fsevents] Success:
+
[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
-
+
+
Run the initial application.
-
npm start
-
+
npm start
+
+
The system prompts you to accept incoming connections.
@@ -395,21 +404,23 @@ stored on Gaia are made visible to others via the handleSignIn handler method.
-
By default, authentication requests include the store_write scope which
enables storage. This is what allows you to store information to Gaia.
@@ -443,17 +454,18 @@ delete grocery lists.
A single file collection stores items as an array nested inside each grocery
list:
-
// grocerylists.json
+
// grocerylists.json{
- "3255":{
- "items":[
+ "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
@@ -492,26 +504,28 @@ or remove a grocery list; updating a list has no impact.
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:
-
+
When you are done, the import statement should look like the following:
+
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:
-
constructor(props){
- super(props);
+
constructor(props){
+ super(props);this.state={person:{
@@ -529,7 +543,8 @@ or remove a grocery list; updating a list has no impact.
isLoading:false};}
-
+
+
Locate the render() method.
@@ -538,10 +553,10 @@ or remove a grocery list; updating a list has no impact.
The following code echos the person.name and person.avatarURL
properties from the profile on the display:
render(){
+ const{handleSignOut}=this.props;
+ const{person}=this.state;
+ const{username}=this.state;return(!isSignInPending()&&person?
@@ -554,8 +569,8 @@ or remove a grocery list; updating a list has no impact.
src={person.avatarUrl()?person.avatarUrl():avatarFallbackImage}className="img-rounded avatar"id="avatar-image"
- />
- <divclassName="username">
+ />
+<divclassName="username"><h1><spanid="heading-name">{person.name()?person.name():'Nameless Person'}</span>
@@ -575,8 +590,8 @@ or remove a grocery list; updating a list has no impact.
value={this.state.newStatus}onChange={e=>this.handleNewStatusChange(e)}placeholder="Enter a status"
- />
- </div>
+ />
+</div>
<divclassName="col-md-12"><buttonclassName="btn btn-primary btn-lg"
@@ -592,7 +607,8 @@ or remove a grocery list; updating a list has no impact.
</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
@@ -604,18 +620,19 @@ user profile data.
You’ll use the Blockstack loadUserData() method to access the username.
@@ -675,7 +694,7 @@ the statuses back to the user as a blog entry.
Right after this opening div element, add this block.
-
<divclassName="col-md-12 statuses">
+
<divclassName="col-md-12 statuses">{this.state.isLoading&&<span>Loading...</span>}
{this.state.statuses.map((status)=>(<divclassName="status"key={status.id}>
@@ -684,16 +703,17 @@ the statuses back to the user as a blog entry.
))}</div>
-
+
+
This loads existing state. Your code needs to fetch statuses on page load.
Add a new method called fetchData() after the statuses.unshift(status) section.
-
+
fetchData(){this.setState({isLoading:true})
- constoptions={decrypt:false}
+ constoptions={decrypt:false}getFile('statuses.json',options).then((file)=>{varstatuses=JSON.parse(file||'[]')
@@ -708,16 +728,18 @@ the statuses back to the user as a blog entry.
this.setState({isLoading:false})})}
-
+
+
Call fetchData() from the componentDidMount() method
-
+
componentDidMount(){this.fetchData()}
-
+
+
Save the file.
@@ -736,7 +758,7 @@ the statuses back to the user as a blog entry.
Replace the content with the following:
-
/* Globals */
+
/* Globals */a,a:focus,a:hover{color:#fff;}html,body{height:100%;text-align:center;background-color:#191b22;}body{color:#fff}
@@ -771,7 +793,8 @@ the statuses back to the user as a blog entry.
/* Statuses */.statuses{padding-top:30px;}.status{margin:15px0px;padding:20px;background-color:#2e2e2e;border-radius:6px}
-
+
+
Save and close the src/styles/style.css file.
@@ -803,44 +826,49 @@ other users’ profiles by visiting http://local
Install react-router:
-
npm install--save react-router-dom
-
+
npm install --save react-router-dom
+
+
Edit src/index.js file.
Add an import to the file at the top:
-
import{BrowserRouter}from'react-router-dom'
-
+
import{BrowserRouter}from'react-router-dom'
+
+
Change the ReactDOM.render() method in src/index.js to:
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.
Modify the fetchData() method like so:
-
fetchData(){
+
fetchData(){this.setState({isLoading:true})if(this.isLocal()){
- constoptions={decrypt:false}
+ constoptions={decrypt:false}getFile('statuses.json',options).then((file)=>{varstatuses=JSON.parse(file||'[]')
@@ -917,7 +949,7 @@ process URL paths that contain the . (dot
this.setState({isLoading:false})})}else{
- constusername=this.props.match.params.username
+ constusername=this.props.match.params.usernamelookupProfile(username).then((profile)=>{
@@ -931,7 +963,8 @@ process URL paths that contain the . (dot
})}}
-
+
+
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.
@@ -943,7 +976,7 @@ process URL paths that contain the . (dot
Add the following block to fetchData() right after the call to lookupProfile(username)... catch((error)=>{..} block:
-
constoptions={username:username,decrypt:false}
+
constoptions={username:username,decrypt:false}getFile('statuses.json',options).then((file)=>{varstatuses=JSON.parse(file||'[]')
@@ -958,7 +991,8 @@ process URL paths that contain the . (dot
.finally(()=>{this.setState({isLoading:false})})
-
+
+
This fetches the user statuses.
@@ -967,10 +1001,10 @@ process URL paths that contain the . (dot
render(){
+ const{handleSignOut}=this.props;
+ const{person}=this.state;
+ const{username}=this.state;return(!isSignInPending()&&person?
@@ -983,8 +1017,8 @@ process URL paths that contain the . (dot
src={person.avatarUrl()?person.avatarUrl():avatarFallbackImage}className="img-rounded avatar"id="avatar-image"
- />
- <divclassName="username">
+ />
+<divclassName="username"><h1><spanid="heading-name">{person.name()?person.name():'Nameless Person'}</span>
@@ -1006,8 +1040,8 @@ process URL paths that contain the . (dot
value={this.state.newStatus}onChange={e=>this.handleNewStatusChange(e)}placeholder="What's on your mind?"
- />
- </div>
+ />
+</div>
<divclassName="col-md-12 text-right"><buttonclassName="btn btn-primary btn-lg"
@@ -1032,9 +1066,10 @@ process URL paths that contain the . (dot
</div> : null
);}
-
+
+
-
### This checks to ensure that users are viewing their own profile, by wrapping the Logout button and inputs with the {isLocal() && ...} condition.
+
### This checks to ensure that users are viewing their own profile, by wrapping the Logout button and inputs with the {isLocal()&&...} condition.
@@ -1045,8 +1080,9 @@ process URL paths that contain the . (dot
Restart the application so that the disabling of the . (dot) rule takes effect.
-
npm start
-
+
npm start
+
+
Point your browser to http://localhost:8080/your_blockstack.id to see the final application.
diff --git a/_site/browser/todo-list.html b/_site/browser/todo-list.html
index ac811398..a0df0150 100644
--- a/_site/browser/todo-list.html
+++ b/_site/browser/todo-list.html
@@ -7,7 +7,7 @@
Todo List Application Tutorial | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/browser/todo-list.html","headline":"Todo List Application Tutorial","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/browser/todo-list.html"},"description":"Todo List Application Tutorial","@type":"BlogPosting","@context":"http://schema.org"}
@@ -195,13 +195,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -251,9 +251,10 @@ with that ID using Blockstack Storage (Gaia).
The tutorial relies on the npm dependency manager. Before you begin, verify you have installed npm using the which command to verify.
$ yarn install
yarn install v1.9.2
info No lockfile found.
...
@@ -290,7 +293,8 @@ These instructions assume you are cloning.
[5/5] 📃 Building fresh packages...
success Saved lockfile.
✨ Done in 19.90s.
-
+
+
@@ -331,15 +335,17 @@ These instructions assume you are cloning.
Make sure you are in the root of the code base.
-
$ pwd /Users/moxiegirl/repos/blockstack-todos
+
$ pwd /Users/moxiegirl/repos/blockstack-todos
Start the application.
-
@@ -453,15 +460,16 @@ in and sign out is handled in each of these files:
The src/components/Landing.vue code calls a redirectToSignIn() function which generates the authRequest and redirects the user to the Blockstack authenticator:
Once the user authenticates, the application handles the authResponse in the src/App.vue file. :
-
if(blockstack.isUserSignedIn()){
+
if(blockstack.isUserSignedIn()){this.user=blockstack.loadUserData().profile}elseif(blockstack.isSignInPending()){blockstack.handlePendingSignIn()
@@ -469,16 +477,18 @@ in and sign out is handled in each of these files:
window.location=window.location.origin})}
-
+
+
If blockstack.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() 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.
The method allows the application creator to decide where to redirect the user upon Sign Out:
@@ -499,42 +509,44 @@ command:
You should see a JSON with the todos you just added:
-
[
+
[{
- "id":2,
- "text":"Software package manager secured by the blockchain",
- "completed":false
+ "id":2,
+ "text":"Software package manager secured by the blockchain",
+ "completed":false},{
- "id":1,
- "text":"Mutable torrents with human readable names",
- "completed":false
+ "id":1,
+ "text":"Mutable torrents with human readable names",
+ "completed":false},{
- "id":0,
- "text":"Decentralized twitter",
- "completed":false
+ "id":0,
+ "text":"Decentralized twitter",
+ "completed":false}]
-
+
+
Add another todo and check it off. When you fetch the newly generated file
using the Javascript console, the results reflect your change. Look for "completed":true:
-
[
+
[{
- "id":3,
- "text":"Blockstack Todo",
- "completed":true
+ "id":3,
+ "text":"Blockstack Todo",
+ "completed":true},{
- "id":2,
- "text":"Software package manager secured by the blockchain",
- "completed":false
+ "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.
@@ -545,16 +557,17 @@ application interactions with your Gaia Hub originate in the
src/components/Dashboard.vue file. First, examine where the changes to the
Todos are processed:
-
todos:{
+
todos:{handler:function(todos){
- constblockstack=this.blockstack
+ constblockstack=this.blockstack// encryption is now enabled by defaultreturnblockstack.putFile(STORAGE_FILE,JSON.stringify(todos))},
- deep:true
+ deep:true}
-
+
+
The todos JSON object is passed in and the
blockstack.putFile()
@@ -562,8 +575,8 @@ method to store it in a Gaia Hub.
The code needs to read the Todo items from the storage with the blockstack.getFile() method which returns a promise:
-
fetchData(){
- constblockstack=this.blockstack
+
fetchData(){
+ constblockstack=this.blockstackblockstack.getFile(STORAGE_FILE)// decryption is enabled by default.then((todosText)=>{vartodos=JSON.parse(todosText||'[]')
@@ -574,7 +587,8 @@ method to store it in a Gaia Hub.
this.todos=todos})},
-
+
+
The todos data is retrieved from the promise.
diff --git a/_site/changelog/index.html b/_site/changelog/index.html
index 74fcd3f4..5f1aee5b 100644
--- a/_site/changelog/index.html
+++ b/_site/changelog/index.html
@@ -7,7 +7,7 @@
Changelog | Blockstack
-
+
@@ -17,7 +17,7 @@
+{"url":"https://docs.blockstack.org/changelog/","headline":"Changelog","author":{"@type":"Person","name":"Blockstack"},"description":"Docs","@type":"WebPage","@context":"http://schema.org"}
diff --git a/_site/common/construction.html b/_site/common/construction.html
index 471b4ce7..7dc9b50b 100644
--- a/_site/common/construction.html
+++ b/_site/common/construction.html
@@ -7,7 +7,7 @@
Excuse our dust! | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/common/construction.html","headline":"Excuse our dust!","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/common/construction.html"},"description":"Excuse our dust!","@type":"BlogPosting","@context":"http://schema.org"}
@@ -151,13 +151,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
diff --git a/_site/contact/index.html b/_site/contact/index.html
index b6710927..cbd610b9 100644
--- a/_site/contact/index.html
+++ b/_site/contact/index.html
@@ -7,7 +7,7 @@
Got Any Questions? | Blockstack
-
+
@@ -17,7 +17,7 @@
+{"url":"https://docs.blockstack.org/contact/","headline":"Got Any Questions?","author":{"@type":"Person","name":"Blockstack"},"description":"Docs","@type":"WebPage","@context":"http://schema.org"}
diff --git a/_site/core/atlas/howitworks.html b/_site/core/atlas/howitworks.html
index 44ee3c1e..5fd175bf 100644
--- a/_site/core/atlas/howitworks.html
+++ b/_site/core/atlas/howitworks.html
@@ -7,7 +7,7 @@
How Atlas Works | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/atlas/howitworks.html","headline":"How Atlas Works","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/atlas/howitworks.html"},"description":"How Atlas Works","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -429,7 +429,7 @@ find out which chunks they each have. Atlas nodes download chunks from
neighbors in rarest-first order in order to prioritize data replication for the
chunks that are currently most at-risk for disappearing due to node failure.
-
Name operation | chunk hashes | chunk data | Inventory
+
Name operation | chunk hashes | chunk data | Inventory
history | as name state | | vector
+-------------------+
@@ -457,18 +457,20 @@ it has and which ones it does not, and announces it to other Atlas peers so
they can fetch chunks they are missing. In this example, the node's
inventory vector is [1, 0, 1], since the 0th and 2nd chunks are present
but the 1st chunk is missing.
-
+
+
Querying Chunk Inventories
Developers can query a node’s inventory vector as follows:
The variable result['inv'] here is a big-endian bit vector, where the ith
bit is set to 1 if the ith chunk in the chunk sequence is present. The bit at
diff --git a/_site/core/atlas/howtouse.html b/_site/core/atlas/howtouse.html
index 494873b3..d64b5b15 100644
--- a/_site/core/atlas/howtouse.html
+++ b/_site/core/atlas/howtouse.html
@@ -7,7 +7,7 @@
How to Use the Atlas Network | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/atlas/howtouse.html","headline":"How to Use the Atlas Network","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/atlas/howtouse.html"},"description":"How to Use the Atlas Network","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -321,7 +321,7 @@ chunk data. A client can query up to 100 chunks in one RPC call.
the returned payload will be a dict with a zonefiles key that maps the chunk
hashes to their respective data.
-
>>>importblockstack
+
>>>importblockstack>>>data=blockstack.lib.client.get_zonefiles('https://node.blockstack.org:6263',['1b89a685f4c4ea245ce9433d0b29166c22175ab4'])>>>printdata['zonefiles']['1b89a685f4c4ea245ce9433d0b29166c22175ab4']$ORIGINduckduckgo_tor.id
@@ -329,7 +329,8 @@ hashes to their respective data.
torTXT"3g2upl4pq6kufc4m.onion">>>
-
+
+
(This particular chunk happens to be associated with the BNS name
duckduckgo_tor.id).
@@ -355,14 +356,15 @@ Browser
for doing this.
Once the name operation is confirmed, you can announce the data to the
Atlas network. You can do so with the Python client as follows:
-
>>>importblockstack
+
>>>importblockstack>>>importbase64
->>>data="..."# this is the chunk data you will announce
->>>data_b64=base64.b64encode(data)
+>>>data="..."# this is the chunk data you will announce
+>>>data_b64=base64.b64encode(data)>>>result=blockstack.lib.client.put_zonefiles('https://node.blockstack.org:6263',[data_b64])>>>assertresult['saved'][0]==1>>>
-
+
+
At most five chunks can be announced in one RPC call.
Note that the data must be base64-encoded before it can be announced.
@@ -390,22 +392,23 @@ peer graph, and replicate the chunk to each of them as well.
For example, this code will replicate the chunk to not only
https://node.blockstack.org:6263, but also to its immediate neighbors.
-
>>>importblockstack
+
>>>importblockstack>>>importbase64
->>>data="..."# this is the chunk you will replicate widely
->>>data_b64=base64.b64encode(data)
+>>>data="..."# this is the chunk you will replicate widely
+>>>data_b64=base64.b64encode(data)>>>>>>result=blockstack.lib.client.get_atlas_peers('https://node.blockstack.org:6263')>>>neighbors=result['peers']>>>print", ".join(neighbors)
-13.65.207.163:6264,52.225.128.191:6264,node.blockstack.org:6264,23.102.162.7:6264,52.167.230.235:6264,23.102.162.124:6264,52.151.59.26:6264,13.92.134.106:6264
+13.65.207.163:6264,52.225.128.191:6264,node.blockstack.org:6264,23.102.162.7:6264,52.167.230.235:6264,23.102.162.124:6264,52.151.59.26:6264,13.92.134.106:6264>>>>>>forneighborinneighbors:...result=blockstack.lib.client.put_zonefiles(neighbor,[data_b64])...assertresult['saved'][0]==1...>>>
-
+
+
This is not strictly necessary, but it does help accelerate chunk replication
and makes it less likely that a chunk will get lost due to individual node
diff --git a/_site/core/atlas/overview.html b/_site/core/atlas/overview.html
index 1b1630dd..8ca480b5 100644
--- a/_site/core/atlas/overview.html
+++ b/_site/core/atlas/overview.html
@@ -7,7 +7,7 @@
Overview of the Atlas network | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/atlas/overview.html","headline":"Overview of the Atlas network","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/atlas/overview.html"},"description":"Overview of the Atlas network","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -328,7 +328,7 @@ propagate them to the Atlas network. BNS API endpoints, including our
will automatically fetch zone files from Atlas when they need to look
up data in Gaia (such as profiles and app data).
-
+--------------+ +---------------+ +----------------+
clients | Blockstack | | blockstack.js | | BNS API module |
| Browser | | | | |
+--------------+ +---------------+ +----------------+
@@ -363,7 +363,8 @@ up zone files for names using the name's stat value as a zone file hash. Client
can broadcast zone files to the network if they match a previously-announced
hash. In practice, zone files store URLs to a name owner's Gaia hubs, thereby
allowing Blockstack apps to read and write data in Gaia.
-
+
+
Nevertheless, Atlas is a general-purpose content-addressed storage
system that advanced developers can use to host data in an immutable
diff --git a/_site/core/faq_developer.html b/_site/core/faq_developer.html
index c6136f6f..869928cf 100644
--- a/_site/core/faq_developer.html
+++ b/_site/core/faq_developer.html
@@ -7,7 +7,7 @@
Developer FAQs | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/faq_developer.html","headline":"Developer FAQs","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/faq_developer.html"},"description":"Developer FAQs","@type":"BlogPosting","@context":"http://schema.org"}
@@ -195,13 +195,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -296,15 +296,17 @@ profile. For example, here’s how you would get public data from the
+-------------------------------------------------------+
RESTful | +----------------+ +--------------------+ |
+--------+ API | | | private API | | |
| client |<------------>| BNS API module |<----------->| BNS indexer module | |
@@ -339,7 +339,8 @@ the blochchain via a blockchain peer, over the blockchain's peer network.
Blockstack Core currently implements the API module and indexer module as separate
daemons (`blockstack api` and `blockstack-core`, respectively). However, this
is an implementation detail, and may change in the future.
-
+
+
The BNS indexer implements the blockchain consensus rules and network protocols.
Its main responsibility is to build up and replicate all of the name state. It does
diff --git a/_site/core/naming/comparison.html b/_site/core/naming/comparison.html
index 122a4dfb..b6c30fff 100644
--- a/_site/core/naming/comparison.html
+++ b/_site/core/naming/comparison.html
@@ -7,7 +7,7 @@
Naming system feature comparison | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/comparison.html","headline":"Naming system feature comparison","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/comparison.html"},"description":"Naming system feature comparison","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
diff --git a/_site/core/naming/creationhowto.html b/_site/core/naming/creationhowto.html
index 44f6bb95..72e1041c 100644
--- a/_site/core/naming/creationhowto.html
+++ b/_site/core/naming/creationhowto.html
@@ -7,7 +7,7 @@
Creating a Namespace | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/creationhowto.html","headline":"Creating a Namespace","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/creationhowto.html"},"description":"Creating a Namespace","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
diff --git a/_site/core/naming/did.html b/_site/core/naming/did.html
index b90b53be..aca9d243 100644
--- a/_site/core/naming/did.html
+++ b/_site/core/naming/did.html
@@ -7,7 +7,7 @@
Decentralized Identifiers (DIDs) | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/did.html","headline":"Decentralized Identifiers (DIDs)","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/did.html"},"description":"Decentralized Identifiers (DIDs)","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -293,13 +293,14 @@ specification for decentralized identifiers (DIDs).
Each name in BNS has an associated DID. The DID format for BNS is:
-
did:stack:v0:{address}-{index}
-
+
did:stack:v0:{address}-{index}
+
+
Where:
-
{address} is an on-chain public key hash (e.g. a Bitcoin address).
-
{index} refers to the nth name this address created.
+
{address} is an on-chain public key hash (e.g. a Bitcoin address).
+
{index} refers to the nth name this address created.
For example, the DID for personal.id is
@@ -349,20 +350,20 @@ for subdomains, so the software can determine which code-path to take.
-
For on-chain BNS names, the {address} is the same as the Bitcoin address
+
For on-chain BNS names, the {address} is the same as the Bitcoin address
that owns the name. Currently, both version byte 0 and version byte 5
addresses are supported (i.e. addresses starting with 1 or 3, meaning p2pkh and
p2sh addresses).
-
For off-chain BNS subdomains, the {address} has version byte 63 for
+
For off-chain BNS subdomains, the {address} has version byte 63 for
subdomains owned by a single private key, and version byte 50 for subdomains
owned by a m-of-n set of private keys. That is, subdomain DID addresses start
with S or M, respectively.
-
The {index} field for a subdomain’s DID is distinct from the {index} field
+
The {index} field for a subdomain’s DID is distinct from the {index} field
for a BNS name’s DID, even if the same created both names and subdomains.
For example, the name abcdefgh123456.id has the DID did:stack:v0:16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg-0,
because it was the first name created by 16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg.
@@ -376,7 +377,7 @@ second is encoded with version byte 63).
You can see this play out in practice with the following code snippit:
-
>>>importblockstack
+
>>>importblockstack>>>blockstack.lib.client.get_name_record('jude.statism.id',hostport='https://node.blockstack.org:6263')['address']u'16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg'>>>importvirtualchain
@@ -384,7 +385,8 @@ second is encoded with version byte 63).
'SSXMcDiCZ7yFSQSUj7mWzmDcdwYhq97p2i'>>>blockstack.lib.client.resolve_DID('did:stack:v0:SSXMcDiCZ7yFSQSUj7mWzmDcdwYhq97p2i-0',hostport='https://node.blockstack.org:6263'){'public_key':'020fadbbcea0ff3b05f03195b41cd991d7a0af8bd38559943aec99cbdaf0b22cc8'}
-
+
+
diff --git a/_site/core/naming/forks.html b/_site/core/naming/forks.html
index 8a5cc2ad..206cd1ca 100644
--- a/_site/core/naming/forks.html
+++ b/_site/core/naming/forks.html
@@ -7,7 +7,7 @@
BNS Forks | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/forks.html","headline":"BNS Forks","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/forks.html"},"description":"BNS Forks","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
diff --git a/_site/core/naming/introduction.html b/_site/core/naming/introduction.html
index 169ea4b3..588ff507 100644
--- a/_site/core/naming/introduction.html
+++ b/_site/core/naming/introduction.html
@@ -7,7 +7,7 @@
Blockstack Naming Service (BNS) | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/introduction.html","headline":"Blockstack Naming Service (BNS)","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/introduction.html"},"description":"Blockstack Naming Service (BNS)","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
diff --git a/_site/core/naming/manage.html b/_site/core/naming/manage.html
index 3c076d1f..24fb2e47 100644
--- a/_site/core/naming/manage.html
+++ b/_site/core/naming/manage.html
@@ -7,7 +7,7 @@
Manage BNS Names | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/manage.html","headline":"Manage BNS Names","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/manage.html"},"description":"Manage BNS Names","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
diff --git a/_site/core/naming/namespaces.html b/_site/core/naming/namespaces.html
index 85955fe4..26814c70 100644
--- a/_site/core/naming/namespaces.html
+++ b/_site/core/naming/namespaces.html
@@ -7,7 +7,7 @@
Understand Namespaces | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/namespaces.html","headline":"Understand Namespaces","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/namespaces.html"},"description":"Understand Namespaces","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
diff --git a/_site/core/naming/pickname.html b/_site/core/naming/pickname.html
index edabc5ed..cc183029 100644
--- a/_site/core/naming/pickname.html
+++ b/_site/core/naming/pickname.html
@@ -7,7 +7,7 @@
Choose a name | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/pickname.html","headline":"Choose a name","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/pickname.html"},"description":"Choose a name","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -329,17 +329,18 @@ the BNS API.
A recent consensus hash is required to create a NAMESPACE_PREORDER transaction. The reference
BNS clients do this automatically. See the transaction format
diff --git a/_site/core/naming/register.html b/_site/core/naming/register.html
index cb475748..3f78cbab 100644
--- a/_site/core/naming/register.html
+++ b/_site/core/naming/register.html
@@ -7,7 +7,7 @@
Register a name | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/register.html","headline":"Register a name","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/register.html"},"description":"Register a name","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -367,12 +367,13 @@ ignored.
Note the use of jq -r to select the "name_price" field. This API
endpoint may return other ancilliary data regarding transaction fee estimation,
@@ -380,11 +381,12 @@ but this is the only field guaranteed by this specification to be present.
$ curl https://core.blockstack.org/v1/names?page=0
["judecn.id",
"3.id",
@@ -419,7 +420,8 @@ to the zonefile_hash field.
"df.id",
...
]
-
+
+
Each page returns 100 names. While no specific ordering is mandated by the
protocol, the reference implementation orders names by their order of creation
@@ -427,7 +429,7 @@ in the blockchain.
Look up the history of states a name was in (reference)
$ curl https://core.blockstack.org/v1/names/patrickstanley.id/history
{"445838": [{
@@ -530,7 +532,8 @@ in the blockchain.
}]}
-
+
+
All of the above information is extracted from the blockchain. Each top-level
field encodes the states the name transitioned to at the given block height (e.g.
@@ -554,7 +557,7 @@ under its previous owner, if the name expired and was reregistered.
Look up the list of names owned by a given public key hash (reference)
$ curl https://core.blockstack.org/v1/addresses/bitcoin/16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg
{"names": ["judecn.id",
@@ -566,7 +569,8 @@ under its previous owner, if the name expired and was reregistered.
"jude.statism.id"]}
-
+
+
Note that this API endpoint includes names and
subdomains.
diff --git a/_site/core/naming/search.html b/_site/core/naming/search.html
index be66b3d2..8578023d 100644
--- a/_site/core/naming/search.html
+++ b/_site/core/naming/search.html
@@ -7,7 +7,7 @@
How to build a Profile Search Index | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/search.html","headline":"How to build a Profile Search Index","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/search.html"},"description":"How to build a Profile Search Index","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -305,8 +305,9 @@ with data that follows structure of
Step 2: Make sure you have Blockstack Core running locally (see instructions). We highly
@@ -332,34 +334,38 @@ Blockstack Core for re-indexing and remote nodes can slow down performance.
Step 3: Fetch the data for the .id namespace and respective profiles. Note, you may want to redirect stderr to a file, as there is a lot of debug output.
diff --git a/_site/core/naming/subdomains.html b/_site/core/naming/subdomains.html
index 3ae467b6..978230f4 100644
--- a/_site/core/naming/subdomains.html
+++ b/_site/core/naming/subdomains.html
@@ -7,7 +7,7 @@
BNS Subdomains | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/subdomains.html","headline":"BNS Subdomains","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/subdomains.html"},"description":"BNS Subdomains","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -342,7 +342,7 @@ stored.
For example, the name verified.podcast once wrote the zone file hash 247121450ca0e9af45e85a82e61cd525cd7ba023,
which is the hash of the following zone file:
$ curl https://core.blockstack.org/v1/names/1yeardaily.verified.podcast
{"address": "1MwPD6dH4fE3gQ9mCov81L1DEQWT7E85qH",
"blockchain": "bitcoin",
@@ -369,7 +370,8 @@ For example, 1yeardaily.verified.podcast"zonefile_hash": "e7acc97fd42c48ed94fd4d41f674eddbee5557e3",
"zonefile_txt": "$ORIGIN 1yeardaily\n$TTL 3600\n_http._tcp URI 10 1 \"https://ph.dotpodcast.co/1yeardaily/head.json\"\n"}
-
+
+
This information was extracted from the 1yeardailyTXT resource record in the zone
file for verified.podcast.
@@ -384,7 +386,7 @@ updates; only the owner of 1yeardaily.verified.p
The lifecycle of a subdomain and its operations is shown in Figure 2.
-
subdomain subdomain subdomain
+
subdomain subdomain subdomain
creation update transfer
+----------------+ +----------------+ +----------------+
| cicero | | cicero | | cicero |
@@ -416,7 +418,8 @@ Thesubdomain-creation and subdomain-transfer transactions for
"cicero.res_publica.id" are broadcast by the owner of "res_publica.id".
However, any on-chain name ("jude.id" in this case) can broadcast a subdomain
update for "cicero.res_publica.id".
-
+
+
Subdomain operations are ordered by sequence number, starting at 0. Each new
subdomain operation must include:
@@ -444,7 +447,7 @@ Using the BNS API, a developer can:
Look up a subdomain’s public key and zone file (reference)
diff --git a/_site/core/naming/tutorial_subdomains.html b/_site/core/naming/tutorial_subdomains.html
index 8d6dc93c..3e48de5c 100644
--- a/_site/core/naming/tutorial_subdomains.html
+++ b/_site/core/naming/tutorial_subdomains.html
@@ -7,7 +7,7 @@
Subdomain Design and Implementation | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/core/naming/tutorial_subdomains.html","headline":"Subdomain Design and Implementation","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/core/naming/tutorial_subdomains.html"},"description":"Subdomain Design and Implementation","@type":"BlogPosting","@context":"http://schema.org"}
@@ -274,13 +274,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -359,12 +359,13 @@ so we chop up the zonefile.
When the registrar wakes up to prepare a transaction, it packs the queued
registrations together and issues an UPDATE.
@@ -445,24 +450,28 @@ registrations together and issues an UPDATE
This is an API call:
-
GET /status/{subdomain}
-
+
GET /status/{subdomain}
+
+
The registrar checks if the subdomain has propagated (i.e., the
registration is completed), in which case the following is returned:
-
{"status": "Subdomain already propagated"}
-
+
{"status":"Subdomain already propagated"}
+
+
Or, if the subdomain has already been submitted in a transaction:
-
{"status": "Your subdomain was registered in transaction 09a40d6ea362608c68da6e1ebeb3210367abf7aa39ece5fd57fd63d269336399 -- it should propagate on the network once it has 6 confirmations."}
-
+
{"status":"Your subdomain was registered in transaction 09a40d6ea362608c68da6e1ebeb3210367abf7aa39ece5fd57fd63d269336399 -- it should propagate on the network once it has 6 confirmations."}
+
+
If the subdomain still hasn’t been submitted yet:
-
{"status": "Subdomain is queued for update and should be announced within the next few blocks."}
-
+
{"status":"Subdomain is queued for update and should be announced within the next few blocks."}
+
+
If an error occurred trying to submit the UPDATE transaction, this endpoint will return an error
message in the "error" key of a JSON object.
@@ -497,7 +506,7 @@ The endpoints which are subdomain aware are marked as such in
The lookups work just like normal – it returns the user’s
profile object:
Once you see Test finished; doing checks in that container’s logs, the
registrar has started and is ready to accept requests. (We recommend
@@ -562,33 +574,37 @@ correct environment variables for it to run).
Once this environment has started, you can issue a registration request from curl:
This registers baz.foo.id – you can check the registrar’s status with
-
curl http://localhost:3000/status/baz
-
+
curl http://localhost:3000/status/baz
+
+
The API endpoints /v1/users/<foo.bar.tld>,
/v1/names/<foo.bar.tld>, and /v1/addresses/bitcoin/<foo.bar.tld> all work, so if you query the core API, you’ll get a response.
0 2 3 19 39
|-----|--|-----------------------------------|-----------------------|
magic op hash128(name.ns_id,consensus hash) zone file hash
-
+
+
Note that hash128(name.ns_id, consensus hash) is the first 16 bytes of a SHA256 hash over the name concatenated to the hexadecimal string of the consensus hash (not the bytes corresponding to that hex string).
See the Method Glossary below.
Some hashing primitives are used to construct the wire-format representation of each name operation. They are enumerated here:
-
B40_REGEX = '^[a-z0-9\-_.+]*$'
+
B40_REGEX = '^[a-z0-9\-_.+]*$'
def is_b40(s):
return isinstance(s, str) and re.match(B40_REGEX, s) is not None
@@ -869,7 +882,8 @@ def hash128(data):
first 16 bytes
"""
return hexlify(bin_sha256(data)[0:16])
-
+
+
diff --git a/_site/feed.xml b/_site/feed.xml
index 5e3cab86..2da7caa5 100644
--- a/_site/feed.xml
+++ b/_site/feed.xml
@@ -1,4 +1,4 @@
-Jekyll2018-10-17T09:26:44-07:00https://docs.blockstack.org/BlockstackDocsBlockstackSite tags2017-05-25T00:00:00-07:002017-05-25T00:00:00-07:00https://docs.blockstack.org/2017/05/25/post63<p>https://docs.blockstack.org/assets/posts/</p>
+Jekyll2018-10-22T10:20:43-07:00https://docs.blockstack.org/BlockstackDocsBlockstackSite tags2017-05-25T00:00:00-07:002017-05-25T00:00:00-07:00https://docs.blockstack.org/2017/05/25/post63<p>https://docs.blockstack.org/assets/posts/</p>
<p>/2017/05/25/post63.html</p>
@@ -26,7 +26,7 @@
<h2 id="example-of-code-block">Example Of Code Block</h2>
<p>In accumsan lacus ac neque maximus dictum. Phasellus eleifend leo id mattis bibendum. Curabitur et purus turpis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;</p>
-<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><head></span>
+<div class="language-html highlighter-rouge"><pre class="highlight"><code><span class="nt"><head></span>
<span class="nt"><meta</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">></span>
<span class="nt"><meta</span> <span class="na">http-equiv=</span><span class="s">"X-UA-Compatible"</span> <span class="na">content=</span><span class="s">"IE=edge"</span><span class="nt">></span>
<span class="nt"><meta</span> <span class="na">name=</span><span class="s">"viewport"</span> <span class="na">content=</span><span class="s">"width=device-width, initial-scale=1"</span><span class="nt">></span>
@@ -34,7 +34,8 @@
<span class="nt"><link</span> <span class="na">rel=</span><span class="s">"shortcut icon"</span> <span class="na">type=</span><span class="s">"image/png"</span> <span class="na">href=</span><span class="s">"/assets/img/favicon.png"</span> <span class="nt">></span>
<span class="nt"><script </span><span class="na">src=</span><span class="s">"/assets/js/main.js"</span><span class="nt">></script></span>
<span class="nt"></head></span>
-</code></pre></div></div>
+</code></pre>
+</div>
<h2 id="text-and-quote">Text and Quote</h2>
<p>Cras at dolor eget urna varius faucibus tempus in elit. Cras a dui imperdiet, tempus metus quis, pharetra turpis. Phasellus at massa sit amet ante semper fermentum sed eget lectus. Quisque id dictum magna turpis.</p>
diff --git a/_site/index.html b/_site/index.html
index 677e7348..8c168567 100644
--- a/_site/index.html
+++ b/_site/index.html
@@ -7,7 +7,7 @@
Blockstack | Docs
-
+
@@ -17,7 +17,7 @@
+{"url":"https://docs.blockstack.org/","headline":"Blockstack","author":{"@type":"Person","name":"Blockstack"},"description":"Docs","name":"Blockstack","@type":"WebSite","@context":"http://schema.org"}
@@ -210,7 +210,7 @@
-
+
diff --git a/_site/ios/tutorial.html b/_site/ios/tutorial.html
index 859b5742..cde5ebb0 100644
--- a/_site/ios/tutorial.html
+++ b/_site/ios/tutorial.html
@@ -7,7 +7,7 @@
iOS SDK Tutorial (Pre-release) | Blockstack
-
+
@@ -17,9 +17,9 @@
-
+
+{"url":"https://docs.blockstack.org/ios/tutorial.html","headline":"iOS SDK Tutorial (Pre-release)","dateModified":"2018-10-22T10:20:43-07:00","datePublished":"2018-10-22T10:20:43-07:00","author":{"@type":"Person","name":"Blockstack"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://docs.blockstack.org/ios/tutorial.html"},"description":"iOS SDK Tutorial (Pre-release)","@type":"BlogPosting","@context":"http://schema.org"}
@@ -195,13 +195,13 @@
-
+
Edit this page on Github
- w Oct 17, 2018
+ w Oct 22, 2018
@@ -292,9 +292,10 @@ Depending on your network connection, this can take between 15-30 minutes.
Before you begin, verify you have installed npm using the which command to
verify.
-
@@ -310,14 +311,16 @@ use libraries from the community in your project.
incapability between Cocoapods and XCode. Before starting the tutorial, confirm
you have installed CocoaPods.
-
$ pod --version
+
$ pod --version
1.6.0.beta.1
-
+
+
If you don’t have the CocoaPods beta version, install it:
-
sudo gem install cocoapods -v 1.6.0.beta.1
-
+
sudo gem install cocoapods -v 1.6.0.beta.1
+
+
Use npm to install Yeoman and the Blockstack App Generator
@@ -329,14 +332,16 @@ existing projects.
Install Yeoman.
-
npm install-g yo
-
+
npm install -g yo
+
+
Install the Blockstack application generator.
-
npm install-g generator-blockstack
-
+
npm install -g generator-blockstack
+
+
Build the Blockstack hello-world
@@ -353,24 +358,27 @@ modify the hello-world to interact with t
Create a hello-blockstack directory.
-
mkdir hello-blockstack
-
+
mkdir hello-blockstack
+
+
Change into your new directory.
-
cd hello-blockstack
-
+
cd hello-blockstack
+
+
Use Yeoman and the Blockstack application generator to create your initial hello-blockstack application.
-
yo blockstack:react
-
+
yo blockstack:react
+
+
You should see several interactive prompts.
-
$ yo blockstack:react
+
$ yo blockstack:react
==========================================================================
We are constantly looking for ways to make yo better!
May we anonymously report usage statistics to improve the tool over time?
@@ -379,8 +387,8 @@ modify the hello-world to interact with t
_-----_ ╭──────────────────────────╮
| | │ Welcome to the │
- |--(o)--| │ Blockstack app │
- `---------´ │ generator! │
+ |--(o)--| │ Blockstack app │
+ `---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
@@ -388,26 +396,28 @@ modify the hello-world to interact with t
´ ` |° ´ Y `
? Are you ready to build a Blockstack app in React? (Y/n)
-
+
+
Respond to the prompts to populate the initial app.
After the process completes successfully, you see a prompt similar to the following:
-
[fsevents] Success:
+
[fsevents] Success:
"/Users/theuser/repos/hello-blockstack/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
-
+
+
Run the initial application.
-
npm start
+
npm start
- > hello-blockstack@0.0.0 start /Users/moxiegirl/repos/hello-blockstack
- > webpack-dev-server
+ > hello-blockstack@0.0.0 start /Users/moxiegirl/repos/hello-blockstack
+ > webpack-dev-server
Project is running at http://localhost:8080/
webpack output is served from /
@@ -424,7 +434,8 @@ modify the hello-world to interact with t
[2] (webpack)/buildin/global.js 509 bytes {0}[built]
[3] (webpack)/buildin/module.js 517 bytes {0}[built]
webpack: Compiled successfully.
-
+
+
At this point, the browser is running a Blockstack server on your local host.
@@ -469,8 +480,9 @@ application directory.
Create a public directory.
-
$ mkdir public
-
+
$ mkdir public
+
+
Use the touch command to add a redirect endpoint to your application.
@@ -478,13 +490,14 @@ application directory.
This endpoint on the web version of your app will redirect iOS users back
to your mobile app.
-
$ touch public/redirect.html
-
+
$ touch public/redirect.html
+
+
Open redirect.html and add code to the endpoint.
-
<!DOCTYPE html>
+
<!DOCTYPE html><html><head><title>Hello, Blockstack!</title>
@@ -500,7 +513,8 @@ to your mobile app.
<body></body></html>
-
+
+
Blockstack apps are identified by their domain names. The endpoint will
receive a get request with the query parameter authResponse=XXXX and
@@ -564,14 +578,16 @@ lines after.
Navigate to and change directory into the root of your project directory.
-
$cdhello-blockstack-ios
-
+
$cdhello-blockstack-ios
+
+
Create a Podfile.
-
$ pod init
-
+
$ pod init
+
+
The command creates a Podfile in the directory.
@@ -579,7 +595,7 @@ lines after.
Add a line stating the Blockstack dependency.
-
# Uncomment the next line to define a global platform for your project
+
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'hello-blockstack-ios' do
@@ -594,7 +610,8 @@ target 'hello-blockstack-ios' do
# Pods for testing
end
end
-
+
+
Save and close the Podfile.
@@ -607,7 +624,7 @@ end
Initialize the project with Cocoapods.
-
$ pod install
+
$ pod install
Analyzing dependencies
Downloading dependencies
Installing Blockstack (0.2.0)
@@ -620,18 +637,20 @@ end
Pod installation complete! There is 1 dependency from the Podfile and 2 total pods installed.
[!] Automatically assigning platform `ios` with version `11.4` on target `hello-blockstack-ios` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.
-
+
+
This command creates a number of files
Review the files that the pod installation created:
-
$ ls
-Podfile hello-blockstack-ios hello-blockstack-iosTests
+
$ ls
+Podfile hello-blockstack-ios hello-blockstack-iosTests
Podfile.lock hello-blockstack-ios.xcodeproj
Pods hello-blockstack-ios.xcworkspace
-
+
+
Start XCode and choose Open another project.
@@ -707,7 +726,7 @@ the user back to your iOS app. In this example, you use <scenes> element with the following:
-
<scenes>
+
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
@@ -741,16 +760,18 @@ the user back to your iOS app. In this example, you use
+
+
Immediately after scenes but before the close of the </document> tag add the following <resources>.
Just before the didReceiveMemoryWarning function a private updateUI() function.
This function takes care of loading the user data from Blockstack.
-
privatefuncupdateUI(){
+
privatefuncupdateUI(){DispatchQueue.main.async{ifBlockstack.shared.isSignedIn(){// Read user profile data
@@ -913,7 +938,8 @@ this application in your mobile add for now. In XCode, do the following;
}}}
-
+
+
The function uses the Blockstack.shared.isSignedIn() method to determine if
the user is already logged into Blockstack or not. It then uses the
@@ -923,12 +949,13 @@ the application display with the username.
Replace the content of the viewDidLoad() function so that it calls this private function.
-
overridefuncviewDidLoad(){
+
overridefuncviewDidLoad(){super.viewDidLoad()// Do any additional setup after loading the view, typically from a nib.self.updateUI()}
-
+
+
Create a ‘signIn()’ function that handles both sign in and out.
@@ -936,7 +963,7 @@ the application display with the username.
The function uses the Blockstack.shared.signIn() and
Blockstack.shared.signOut() methods to sign the user into the application.
-
@IBActionfuncsignIn(_sender:UIButton){
+
@IBActionfuncsignIn(_sender:UIButton){ifBlockstack.shared.isSignedIn(){print("Currently signed in so signing out.")Blockstack.shared.signOut()
@@ -959,7 +986,8 @@ the application display with the username.
}}
-