Adding
Decentralized IDs
and
User-Owned Storage
to a
React App
Friedger Müffke
Dev Day 2019
Berlin, 25 May 2019
slides.com/friedger/devday19-berlin/live
Friedger Müffke
PhD in Bristol, UK
Android/Web Developer

friedger.id
@friedger
@social.nasqueron.org
@fmdroid@twitter
Engineering Partner
Blockstack
Founder Droidcon
Founder OpenIntents
1960
2020
2000
1980
2040
Mainframe era
IBM
Decentralized era
Blockstack ?
Cloud era
Google
Desktop era
Microsoft
Next Era in Computing


All About
Data
Become a User
- Use decentralized app (app.co)
- Share your experience
Open source!
Contribute and get rewarded!

Decentralized Applications
Components



Decentralized Applications
Verticals



Decentralized Applications
Components



Decentralized Identity

You
You to Carol as sibling
You to PwC as employee
You to Germany as citizen
You to Bob as friend
Relationships
You
Your facts of birth
Your credit history
Your health records
Your education
Attributes
You
Your cloud service
Your mobile device
Your lawyer
Your broker
Agents
You
Relationships
Attributes
Agents
You are all
of these
Decentralized Identity
- Self-sovereign
- Cryptographically verifiable
- Person vs. profiles
- No more passwords, no more social logins
- W3C working group
- 27 identity provider methods
did:example:123456789abcdefghi

App
App
App
Authenticator
Network
Decentralized Identifier
Login Request

© microsoft.com/ownyouridentity
blockstack.org/install
browser.blockstack.org

Create Blockstack ID

Create Blockstack ID

Protect Blockstack ID

Recover Blockstack ID

Use Blockstack ID

Sign In


Define your App Configuration:
- Scope
- App domain
- Redirect path
- Manifest path
Sign In
yarn add blockstack
import {UserSession} from 'blockstack' const userSession = new UserSession()
Provide a sign in button

Sign In
document.getElementById('signin').onclick = () => { userSession.redirectToSignIn() }
And call redirectToSignIn()

- The domain name your app is served from.
- The permissions and data your app is requesting.
- Your app's name.
- Your app's logo.
Sign In
Sign In
// Check for the auth response token in the URL,
// provided by the browser redirect.
if (userSession.isSignInPending()) {
// Decodes the token and retrieves user data.
userSession.handlePendingSignIn()
.then((userData) => {
// Refresh main page once signed in.
window.location = window.origin }) }
Sign In
if (userSession.isSignInPending()) {
...
} else if (userSession.isUserSignedIn()) {
var userData = userSession.loadUserData()
// Do something with user profile data..
showProfile(userData.profile)
}
Sign In
{
"username": "matt.id",
"profile": {
"name": "Matthew Little",
"image": [{
"name": "avatar",
"contentUrl": "https://gaia-matt.com/1159ZPz88pypemHP84SMacuJWa3XmFSKcv/avatar.png"
}]
},
"email": "matthew@blockstack.com",
"decentralizedID": "did:stack:1159ZPz88pypemHP84SMacuJWa3XmFSKcv",
"hubUrl": "https://gaia-matt.digitaloceanspaces.com/1QHGBN4d2WtnHgEFhsMpAqcJAL2Sy76zoK/",
"appPrivateKey": "6660d3ce7f79038aa5cadb7305897d9a20cfd95ed764c28bd3ffd2618c610553"
}
Example User Data
Sign In
{
"username": "matt.id",
"profile": {
"name": "Matthew Little",
"image": [{
"name": "avatar",
"contentUrl": "https://gaia-matt.example.com/1159ZPz88pypemHP84SMacuJWa3XmFSKcv/avatar.png"
}]
},
"email": "matthew@blockstack.com",
"decentralizedID": "did:stack:1159ZPz88pypemHP84SMacuJWa3XmFSKcv",
"hubUrl": "https://gaia-matt.digitaloceanspaces.com/1QHGBN4d2WtnHgEFhsMpAqcJAL2Sy76zoK/",
"appPrivateKey": "6660d3ce7f79038aa5cadb7305897d9a20cfd95ed764c28bd3ffd2618c610553"
}
Example User Data
App Key Generation

© Cogarius, Brussels



More APIs
None for private key so far
Decentralized Storage

Decentralized Storage
- Diversity in locations
- Distributed vs. self-controlled
Server-less apps
User based (S3, Azure,..)
Content based (IPFS, Storj, SSB, ..)
Address based (Gaia)

Gaia Storage

Address-based access protocol
Apps for My Data



My storage
Alice's storage
Apps for My Data



My storage

Write data
var statusMsg = 'Hello! 🚀' userSession.putFile('status.txt', statusMsg) .then(() => { console.log('file updated!') })
Gaia Storage
Read data
userSession.getFile('status.txt') .then((statusMsg) => { console.log('Status: ' + statusMsg) })
Gaia Storage
Console > Status: Hello! 🚀
Sharing Data/Multi-user apps
"apps": {
"https://app.graphitedocs.com": "https://gaia-matt.com/1QHGBN4d2WtnHgEFhsMpAqcJAL2Sy76zoK/",
"https://helloblockstack.com": "https://gaia-matt.com/1KBU9qxDg8xMgyFdwiVDGU4RZr16Z7TB2S/"
}
Gaia Storage
publish_data
scope in AppConfig:
Sharing Data/Multi-user apps
// Upload unencrypted, public file (logged in as friedger.id)
var options = { encrypt: false }
var statusMsg = 'Hello! 🚀'
userSession.putFile('status.txt', statusMsg, options).then(() => {
console.log('uploaded publicly accessible file!')
})
Gaia Storage
Sharing Data/Multi-user apps
// Get file for specific user (logged in as alice.id)
var options = {
username: 'friedger.id',
decrypt: false
}
userSession.getFile('status.txt', options).then((msg) => {
console.log(`Got status for ${options.username}: ${msg}`)
})
Gaia Storage
Sharing Data/Multi-user apps
// Upload unencrypted, public file (logged in as friedger.id)
var options = { encrypt: false }
var statusMsg = userSession.encryptContent('Hello! 🚀',
{ publicKey: alicePubKey })
userSession.putFile('status.txt', statusMsg, options).then(() => {
console.log('uploaded publicly accessible file!')
})
Gaia Storage
Sharing Data/Multi-user apps
// Get file for specific user (logged in as alice.id)
var options = {
username: 'friedger.id',
decrypt: false
}
userSession.getFile('status.txt', options).then((encMsg) => {
var msg = userSession.decryptContent(encMsg,
{ privateKey: myPrivKey})
console.log(`Got status for ${options.username}: ${msg}`)
})
Gaia Storage

Indexer
Data Flow

Share document privately
OI Calendar
cal.openintents.org
react-redux CRUD + bigcalendar
https://github.com/yasnaraj/react-calendar-events-example

Add Auth Reducer


Update Event Reducer
Developer Tools
- Authentication
- Storage (Gaia)
- Files
- Collections
- Encryption
- In-app payment
Javascript
Android, iOS, React Native
Gatsby starter library
yeoman generator-blockstack
Client side
Developer Tools
Infrastructure
blockstack-core
gaia
Integrations
omniauth-blockstack
blockstack-ruby
Server side
App Mining

The better the app,
the more you earn.
- app.co/mining
- Monthly rating
- Monthly payout
currently: $100k
App Reviewers
- Product Hunt: Innovation
- TryMyUI: Usability
- New Internet Labs: Good Citizenship
- Awario: Awareness
Ranking

Rewards

Review the reviewers

Future
- Bigger monthly payout
- Long-tail
- Payout in STX
(mining reward distribution)

Hackathon
Adding Decentralized IDs and User-Owned Storage to a React App
By friedger
Adding Decentralized IDs and User-Owned Storage to a React App
DevDay 2019
- 1,236