diff --git a/public/images/app-sign-in.png b/public/images/app-sign-in.png
deleted file mode 100644
index abc74e88..00000000
Binary files a/public/images/app-sign-in.png and /dev/null differ
diff --git a/src/common/navigation.yaml b/src/common/navigation.yaml
index d9c3c975..4db9d673 100644
--- a/src/common/navigation.yaml
+++ b/src/common/navigation.yaml
@@ -59,19 +59,36 @@ sections:
usePageTitles: true
pages:
- path: /tutorials/todos
- - path: /tutorials/angular
- - path: /tutorials/indexing
- path: /tutorials/public-registry
+ - path: /tutorials/angular
+
+ - title: Stacks.js References
+ usePageTitles: true
+ pages:
+ - external:
+ href: 'https://github.com/blockstack/stacks.js/tree/master/packages/auth#stacksauth'
+ title: auth
+ - external:
+ href: 'https://github.com/blockstack/ux/tree/master/packages/connect#stacksconnect'
+ title: connect
+ - external:
+ href: 'https://github.com/blockstack/stacks.js/tree/master/packages/storage#stacksstorage'
+ title: storage
+ - external:
+ href: 'https://github.com/blockstack/stacks.js/tree/master/packages/network#stacksnetwork'
+ title: network
+ - external:
+ href: 'https://github.com/blockstack/stacks.js/tree/master/packages/stacking#stacksstacking'
+ title: stacking
+ - external:
+ href: 'https://github.com/blockstack/stacks.js/tree/master/packages/transactions#stackstransactions'
+ title: transactions
- - title: References
+ - title: Protocols
usePageTitles: true
pages:
- - path: /references/stacks-connect
- path: /references/bns
- path: /references/gaia
- - external:
- href: 'https://blockstack.github.io/stacks.js/'
- title: Stacks.js
- path: /start-mining
- path: /references
diff --git a/src/pages/build-apps/guides/authentication.md b/src/pages/build-apps/guides/authentication.md
index 8ce6e188..a8e7c191 100644
--- a/src/pages/build-apps/guides/authentication.md
+++ b/src/pages/build-apps/guides/authentication.md
@@ -11,7 +11,7 @@ images:
## Introduction
-This guide explains how to authenticate users with [the Stacks Connect protocol](/build-apps/references/stacks-connect) by implementing the `connect` package of [Stacks.js](https://blockstack.github.io/stacks.js/).
+This guide explains how to authenticate users with the [`connect`](https://github.com/blockstack/ux/tree/master/packages/connect#stacksconnect) package of Stacks.js.
Authentication provides a way for users to identify themselves to an app while retaining complete control over their credentials and personal details. It can be integrated alone or used in conjunction with [transaction signing](/build-apps/tutorials/transaction-signing) and [data storage](/build-apps/tutorials/data-storage), for which it is a prerequisite.
@@ -19,8 +19,64 @@ Users who register for your app can subsequently authenticate to any other app w
See [the Todos app tutorial](/build-apps/tutorials/todos) for a concrete example of this functionality in practice.
+## How it works
+
+The authentication flow with Stacks is similar to the typical client-server flow used by centralized sign in services (for example, OAuth). However, with Stacks the authentication flow happens entirely client-side.
+
+An app and authenticator, such as [the Stacks Wallet](https://blockstack.org/wallet), communicate during the authentication flow by passing back and forth two tokens. The requesting app sends the authenticator an `authRequest` token. Once a user approves authentication, the authenticator responds to the app with an `authResponse` token.
+
+These tokens are are based on [a JSON Web Token (JWT) standard](https://tools.ietf.org/html/rfc7519) with additional support for the `secp256k1` curve used by Bitcoin and many other cryptocurrencies. They are passed via URL query strings.
+
+See the [`authRequest`](#authrequest-payload-schema) and [`authResponse`](#authresponse-payload-schema) payload schemas below for more details about what data they contain.
+
+When a user chooses to authenticate an app, it sends the `authRequest` token to the authenticator via a URL query string with an equally named parameter:
+
+`https://wallet.hiro.so/...?authRequest=j902120cn829n1jnvoa...`
+
+When the authenticator receives the request, it generates an `authResponse` token for the app using an _ephemeral transit key_ . The ephemeral transit key is just used for the particular instance of the app, in this case, to sign the `authRequest`.
+
+The app stores the ephemeral transit key during request generation. The public portion of the transit key is passed in the `authRequest` token. The authenticator uses the public portion of the key to encrypt an _app private key_ which is returned via the `authResponse`.
+
+The authenticator generates the app private key from the user's _identity address private key_ and the app's domain. The app private key serves three functions:
+
+1. It is used to create credentials that give the app access to a storage bucket in the user's Gaia hub
+2. It is used in the end-to-end encryption of files stored for the app in the user's Gaia storage.
+3. It serves as a cryptographic secret that apps can use to perform other cryptographic functions.
+
+Finally, the app private key is deterministic, meaning that the same private key will always be generated for a given Stacks address and domain.
+
+The first two of these functions are particularly relevant to [data storage with Stacks.js](/build-apps/guides/data-storage).
+
+[Learn more about keypairs](#key-pairs) used by authentication.
+
+## Initiate userSession object
+
+Apps keep track of user authentication state with the `userSession` object, initiated with the `UserSession` and `AppConfig` classes:
+
+```js
+import { AppConfig, UserSession } from '@stacks/connect';
+
+const appConfig = new AppConfig(['store_write', 'publish_data']);
+const userSession = new UserSession({ appConfig });
+```
+
+The main thing to decide here is what permission scopes your app needs from the user during authentication.
+
+Apps may request any of the following scopes:
+
+| Scope | Definition |
+| -------------- | ------------------------------------------------------------------------------- |
+| `store_write` | Read and write data to the user's Gaia hub in an app-specific storage bucket. |
+| `publish_data` | Publish data so other users of the app can discover and interact with the user. |
+
+The default scopes are `['store_write']` if no `scopes` array is provided when initializing the `appConfig` object.
+
+We recommend you initiate the `userSession` object just once in your app then reference it using imports where needed.
+
## Initiate authentication flow
+Apps prompt both new and existing users to authenticate with the `showConnect` function:
+
```js
import { AppConfig, UserSession, showConnect } from '@stacks/connect';
@@ -35,14 +91,29 @@ function authenticate() {
},
redirectTo: '/',
finished: () => {
- window.location.reload();
+ let userData = userSession.loadUserData();
+ // Save or otherwise utilize userData post-authentication
},
userSession: userSession,
});
}
```
-## Handle pending sign in (still needed??)
+`showConnect` triggers the display of a modal that initiates the authentication process for users, one in which they'll authenticate with a _Secret Key_ that's used to encrypt their private data.
+
+![Modal displayed by showConnect function](/images/todos/get-started.png)
+
+The `showConnect` function accepts a number of properties within a parameter object such as:
+
+- The app's `name` and `icon`: provided as strings comprising the `appDetails` object property.
+- The `redirectTo` string: used to provide a URL to which the user should be redirected upon successful authentication. The `finished` callback serves a similar purpose by handling successful authentication within a context of a popup window.
+- The `userSession` object initiated above.
+
+Once the user selects the button presented in this modal, they are passed to the Stacks Wallet for authenticator with the `authRequest` token as a GET parameter. From there they can confirm authentication and generate a new _Secret Key_ or Stacks identity before doing so, as needed before coming back to the app.
+
+## Handle pending authentication
+
+Unless the user has confirmed authentication within the context of a popup window, they will get redirected back to the app via the `redirectTo` address provided above, at which point the app needs to handle the pending authentication state using the `authResponse` value provided as a GET parameter:
```jsx
import { AppConfig, UserSession, showConnect } from '@stacks/connect';
@@ -50,14 +121,130 @@ import { AppConfig, UserSession, showConnect } from '@stacks/connect';
const appConfig = new AppConfig(['store_write', 'publish_data']);
const userSession = new UserSession({ appConfig });
-function componentDidMount() {
+window.onload = function () {
if (userSession.isSignInPending()) {
userSession.handlePendingSignIn().then(userData => {
- window.history.replaceState({}, document.title, '/');
- this.setState({ userData: userData });
+ // Save or otherwise utilize userData post-authentication
});
} else if (userSession.isUserSignedIn()) {
- this.setState({ userData: userSession.loadUserData() });
+ // Handle case in which user is already authenticated
}
-}
+};
```
+
+The `isSignInPending` method of the `userSession` object is used to detect whether the user needs to handle a pending authentication state upon page load.
+
+The `handlePendingSignIn` method is then used to handle that state, returning a `userData` object with all the data needed to save the user's information into their session.
+
+The authenticated state can later be detected by the `isUserSignedIn` method in case any particular handling is needed then.
+
+~> Note that implementing `handlePendingSignIn` is especially important for supporting authentication within the context of mobile apps.
+
+If the user has indeed confirmed authentication in the context of a popup window, the authenticator will resolve the pending authentication state automatically with the app within the parent window.
+
+It will then trigger the `finished` function provided above, which can be used similarly to save the user's information into their session as retrieved with `userSession.loadUserData()`.
+
+## Key pairs
+
+Authentication with Stacks makes extensive use of public key cryptography generally and ECDSA with the `secp256k1` curve in particular.
+
+The following sections describe the three public-private key pairs used, including how they're generated, where they're used and to whom private keys are disclosed.
+
+### Transit private key
+
+The transit private is an ephemeral key that is used to encrypt secrets that
+need to be passed from the authenticator to the app during the
+authentication process. It is randomly generated by the app at the beginning of
+the authentication response.
+
+The public key that corresponds to the transit private key is stored in a single
+element array in the `public_keys` key of the authentication request token. The
+authenticator encrypts secret data such as the app private key using this
+public key and sends it back to the app when the user signs in to the app. The
+transit private key signs the app authentication request.
+
+### Identity address private key
+
+The identity address private key is derived from the user's keychain phrase and
+is the private key of the Stacks username that the user chooses to use to sign in
+to the app. It is a secret owned by the user and never leaves the user's
+instance of the authenticator.
+
+This private key signs the authentication response token for an app to indicate that the user approves sign in to that app.
+
+### App private key
+
+The app private key is an app-specific private key that is generated from the
+user's identity address private key using the `domain_name` as input. It is
+deterministic in that for a given Stacks username and `domain_name`, the same
+private key is generated each time.
+
+The app private key is securely shared with the app on each authentication, encrypted by the authenticator with the transit public key.
+
+## authRequest Payload Schema
+
+```jsx
+const requestPayload = {
+ jti, // UUID
+ iat, // JWT creation time in seconds
+ exp, // JWT expiration time in seconds
+ iss, // legacy decentralized identifier generated from transit key
+ public_keys, // single entry array with public key of transit key
+ domain_name, // app origin
+ manifest_uri, // url to manifest file - must be hosted on app origin
+ redirect_uri, // url to which the authenticator redirects user on auth approval - must be hosted on app origin
+ version, // version tuple
+ do_not_include_profile, // a boolean flag asking authenticator to send profile url instead of profile object
+ supports_hub_url, // a boolean flag indicating gaia hub support
+ scopes, // an array of string values indicating scopes requested by the app
+};
+```
+
+## authResponse Payload Schema
+
+```jsx
+const responsePayload = {
+ jti, // UUID
+ iat, // JWT creation time in seconds
+ exp, // JWT expiration time in seconds
+ iss, // legacy decentralized identifier (string prefix + identity address) - this uniquely identifies the user
+ private_key, // encrypted private key payload
+ public_keys, // single entry array with public key
+ profile, // profile object or null if passed by profile_url
+ username, // Stacks username (if any)
+ core_token, // encrypted core token payload
+ email, // email if email scope is requested & email available
+ profile_url, // url to signed profile token
+ hubUrl, // url pointing to user's gaia hub
+ version, // version tuple
+};
+```
+
+## Decode authRequest or authResponse
+
+To decode a token and see what data it holds:
+
+1. Copy the `authRequest` or `authResponse` string from the URL during authentication.
+2. Navigate to [jwt.io](https://jwt.io/).
+3. Paste the full token there.
+
+ The output should look similar to below:
+
+ ```json
+ {
+ "jti": "f65f02db-9f42-4523-bfa9-8034d8edf459",
+ "iat": 1555641911,
+ "exp": 1555645511,
+ "iss": "did:btc-addr:1ANL7TNdT7TTcjVnrvauP7Mq3tjcb8TsUX",
+ "public_keys": ["02f08d5541bf611ded745cc15db08f4447bfa55a55a2dd555648a1de9759aea5f9"],
+ "domain_name": "http://localhost:8080",
+ "manifest_uri": "http://localhost:8080/manifest.json",
+ "redirect_uri": "http://localhost:8080",
+ "version": "1.3.1",
+ "do_not_include_profile": true,
+ "supports_hub_url": true,
+ "scopes": ["store_write", "publish_data"]
+ }
+ ```
+
+ The `iss` property is a decentralized identifier or `did`. This identifies the user and the username to the app. The specific `did` is a `btc-addr`.
diff --git a/src/pages/build-apps/guides/data-storage.md b/src/pages/build-apps/guides/data-storage.md
index 08ea1cf7..ba94adbf 100644
--- a/src/pages/build-apps/guides/data-storage.md
+++ b/src/pages/build-apps/guides/data-storage.md
@@ -11,7 +11,7 @@ images:
## Introduction
-This guide explains how to save and retrieve data for users with [Gaia](/build-apps/references/gaia) by implementing the `connect` and `storage` packages of [Stacks.js](https://blockstack.github.io/stacks.js/).
+This guide explains how to save and retrieve data for users with [Gaia](/build-apps/references/gaia) by implementing the [`connect`](https://github.com/blockstack/ux/tree/master/packages/connect#stacksconnect) and [`storage`](https://github.com/blockstack/ux/tree/master/packages/storage#stacksstorage) packages of Stacks.js.
Data storage provides a way for users to save both public and private data off-chain while retaining complete control over it.
@@ -19,6 +19,10 @@ Storing data off of the blockchain ensures that apps can provide users with high
See [the Todos app tutorial](/build-apps/tutorials/todos) for a concrete example of this functionality in practice.
+## Authentication
+
+TODO: Add indicator that authentication guide should be followed first
+
## How data is stored
Gaia storage is a key-value store.
diff --git a/src/pages/build-apps/references/stacks-connect.md b/src/pages/build-apps/references/stacks-connect.md
deleted file mode 100644
index fe7ee248..00000000
--- a/src/pages/build-apps/references/stacks-connect.md
+++ /dev/null
@@ -1,285 +0,0 @@
----
-title: Stacks Connect
-description: Open protocol for connecting apps built with Stacks
-images:
- large: /images/pages/authentication.svg
- sm: /images/pages/authentication-sm.svg
----
-
-Stacks Connect is an open protocol for connecting apps built with the Stacks blockchain, such as consumer apps with authenticators and wallets.
-
-## Authentication flow
-
-For an application developer, the application flow is similar to the typical client-server flow used by centralized sign in services (for example, OAuth). However, with Stacks Connect, the authentication flow happens entirely client-side.
-
-An app and authenticator, such as [the Stacks Wallet](https://blockstack.org/wallet), communicate during the authentication flow by passing back and forth two tokens. The requesting application sends the authenticator an `authRequest` token. Once a user approves a sign-in, the authenticator responds to the application with an `authResponse` token. These tokens are JSON Web Tokens, and they are passed via URL query strings.
-
-![](/images/app-sign-in.png)
-
-When a user chooses to authenticate a decentralized application, it calls the `doOpenAuth()` method which sends an `authRequest` to the authenticator. Stacks auth passes the token in via a URL query string in the `authRequest` parameter:
-
-`https://app.blockstack.org/#/sign-up?authRequest=j902120cn829n1jnvoa...`
-
-When the authenticator receives the request, it generates an (`authResponse`) token to the application using an _ephemeral transit key_ . The ephemeral transit key is just used for the particular instance of the application, in this case, to sign the `authRequest`. The application stores the ephemeral transit key during the request generation. The public portion of the transit key is passed in the `authRequest` token. The authenticator uses the public portion of the key to encrypt an _app-private key_ which is returned via the `authResponse`.
-
-During sign in, the authenticator generates the app-private key from the user's _identity-address private_ key and the application's `appDomain`. The app private key serves three functions:
-
-- It is used to create the credentials that give an app access to the Gaia storage bucket for that specific app.
-- It is used in the end-to-end encryption of files stored for the app in the user's Gaia storage.
-- It serves as a cryptographic secret that apps can use to perform other cryptographic functions.
-
-Finally, the app private key is deterministic, meaning that for a given user ID and domain name, the same private key is generated each time.
-
-## Scopes
-
-Scopes define the permissions requested by an app for granting during authentication.
-
-Apps may request any of the following scopes:
-
-| Scope | Definition |
-| -------------- | ------------------------------------------------------------------------------------ |
-| `store_write` | Read and write data to the user's Gaia hub in an app-specific storage bucket. |
-| `publish_data` | Publish data so that other users of the app can discover and interact with the user. |
-
-The permissions scope should be specified through the [`AppConfig`](https://blockstack.github.io/stacks.js/classes/appconfig.html)
-object. If no `scopes` array is provided to the `redirectToSignIn` or `makeAuthRequest` functions, the default is to request `['store_write']`.
-
-## Manifest file
-
-Decentralized apps have a manifest file. This file is based on the [W3C web app manifest specification](https://w3c.github.io/manifest/).
-The following is an example manifest file.
-
-```json
-{
- "name": "Todo App",
- "start_url": "http://todos.blockstack.org",
- "description": "A simple todo app build on Stacks",
- "icons": [
- {
- "src": "http://todos.blockstack.org/logo.png",
- "sizes": "400x400",
- "type": "image/png"
- }
- ]
-}
-```
-
-The Stacks Wallet retrieves the manifest file from the app during the authentication process and displays the
-information in it such as the app `name` and to the user during sign in. The location of the app manifest file is specific
-in the authentication request token and **must** be on the same origin as the app requesting authentication.
-
-The manifest file **must** have [Cross-origin resource sharing (CORS) headers](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing)
-that allow the manifest file to be fetched from any arbitrary source. This usually means returning a header like this:
-
-```
-Access-Control-Allow-Origin: *
-```
-
-How you implement CORS depends in part on which platform/service you use to serve your application. For example, Netlify
-and Firebase have two different ways of configuring CORS. Consult your vendor documentation for more information.
-
-## Key pairs
-
-Stacks Auth makes extensive use of public key cryptography. Blockstack uses ECDSA with the `secp256k1` curve. The
-following sections describe the three public-private key pairs used in the authentication process:
-
-- how they're generated
-- where they're used
-- to whom the private key is disclosed
-
-### Transit private key
-
-The transit private is an ephemeral key that is used to encrypt secrets that
-need to be passed from the authenticator to the decentralized app during the
-authentication process. It is randomly generated by the app at the beginning of
-the authentication response.
-
-The public key that corresponds to the transit private key is stored in a single
-element array in the `public_keys` key of the authentication request token. The
-authenticator encrypts secret data such as the app private key using this
-public key and sends it back to the app when the user signs in to the app. The
-transit private key signs the app authentication request.
-
-### Identity address private key
-
-The identity address private key is derived from the user's keychain phrase and
-is the private key of the Stacks username that the user chooses to use to sign in
-to the app. It is a secret owned by the user and never leaves the user's
-instance of the authenticator.
-
-This private key signs the authentication response token for an app to indicate that the user approves sign in to that app.
-
-### App private key
-
-The app private key is an app-specific private key that is generated from the
-user's identity address private key using the `domain_name` as input. It is
-deterministic in that for a given Stacks username and `domain_name`, the same
-private key is generated each time.
-
-The app private key is securely shared with the app on each authentication, encrypted by the authenticator with the transit public key.
-
-## JSON Web Token signatures
-
-Both the `authRequest` and the `authResponse` tokens are [JSON Web Tokens](https://jwt.io/), and they are passed via URL query strings.
-
-Stacks authentication tokens are based on the [RFC 7519 OAuth JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519)
-with additional support for the `secp256k1` curve used by Bitcoin and many other
-cryptocurrencies.
-
-This signature algorithm is indicated by specifying `ES256K` in the token's
-`alg` key, specifying that the JWT signature uses ECDSA with the secp256k1
-curve. Stacks auth provide both [JavaScript](https://github.com/blockstack/jsontokens-js)
-and
-[Ruby](https://github.com/blockstack/ruby-jwt-blockstack/tree/ruby-jwt-blockstack)
-JWT libraries with support for this signing algorithm.
-
--> The Stacks JWT implementation is different from other implementations because of the underlying cryptography we employ. There are libraries in [JavaScript](https://github.com/blockstack/jsontokens-js) and [Ruby](https://github.com/blockstack/ruby-jwt-blockstack) available on the Blockstack Github to allow you to work with these tokens.
-
-### Example: authRequest payload schema
-
-```jsx
-const requestPayload = {
- jti, // UUID
- iat, // JWT creation time in seconds
- exp, // JWT expiration time in seconds
- iss, // legacy decentralized identifier generated from transit key
- public_keys, // single entry array with public key of transit key
- domain_name, // app origin
- manifest_uri, // url to manifest file - must be hosted on app origin
- redirect_uri, // url to which the authenticator redirects user on auth approval - must be hosted on app origin
- version, // version tuple
- do_not_include_profile, // a boolean flag asking authenticator to send profile url instead of profile object
- supports_hub_url, // a boolean flag indicating gaia hub support
- scopes, // an array of string values indicating scopes requested by the app
-};
-```
-
-### Example: authResponse payload schema
-
-```jsx
-const responsePayload = {
- jti, // UUID
- iat, // JWT creation time in seconds
- exp, // JWT expiration time in seconds
- iss, // legacy decentralized identifier (string prefix + identity address) - this uniquely identifies the user
- private_key, // encrypted private key payload
- public_keys, // single entry array with public key
- profile, // profile object or null if passed by profile_url
- username, // Stacks username (if any)
- core_token, // encrypted core token payload
- email, // email if email scope is requested & email available
- profile_url, // url to signed profile token
- hubUrl, // url pointing to user's gaia hub
- version, // version tuple
-};
-```
-
-## Decode authRequest
-
-To decode the token and see what information it holds:
-
-1. Copy the `authRequest` string from the URL.
-
-
-
-2. Navigate to [jwt.io](https://jwt.io/).
-3. Paste the full token there.
-
- The output should look similar to below:
-
- ```json
- {
- "jti": "f65f02db-9f42-4523-bfa9-8034d8edf459",
- "iat": 1555641911,
- "exp": 1555645511,
- "iss": "did:btc-addr:1ANL7TNdT7TTcjVnrvauP7Mq3tjcb8TsUX",
- "public_keys": ["02f08d5541bf611ded745cc15db08f4447bfa55a55a2dd555648a1de9759aea5f9"],
- "domain_name": "http://localhost:8080",
- "manifest_uri": "http://localhost:8080/manifest.json",
- "redirect_uri": "http://localhost:8080",
- "version": "1.3.1",
- "do_not_include_profile": true,
- "supports_hub_url": true,
- "scopes": ["store_write", "publish_data"]
- }
- ```
-
- The `iss` property is a decentralized identifier or `did`. This identifies the user and the user name to the application. The specific `did` is a `btc-addr`.
-
-## User profiles
-
-Profile data is stored using Gaia on the user's selected storage provider. An example of a `profile.json` file URL using
-default provided storage:
-
-```
-https://gaia.blockstack.org/hub/1EeZtGNdFrVB2AgLFsZbyBCF7UTZcEWhHk/profile.json
-```
-
-Follow these steps to create and register a profile for a BNS username (`identifier`):
-
-1. Create a JSON profile object
-2. Split up the profile into tokens, sign the tokens, and put them in a token file
-3. Create a zone file that points to the web location of the profile token file
-
-```jsx
-"account": [
- {
- "@type": "Account",
- "service": "twitter",
- "identifier": "naval",
- "proofType": "http",
- "proofUrl": "https://twitter.com/naval/status/12345678901234567890"
- }
-]
-```
-
-## Create a profile
-
-```jsx
-const profileOfNaval = {
- '@context': 'http://schema.org/',
- '@type': 'Person',
- name: 'Naval Ravikant',
- description: 'Co-founder of AngelList',
-};
-```
-
-## Sign a profile as a single token
-
-```jsx
-import { wrapProfileToken, Person } from '@stacks/profiles';
-
-const privateKey = 'e546ba96ee34220287d0c177418011addf8d71b32fb81ae8e33a1d7510fa5d0d01';
-
-const person = new Person(profileOfNaval);
-const token = person.toToken(privateKey);
-const tokenFile = [wrapProfileToken(token)];
-```
-
-## Verify an individual token
-
-```jsx
-import { verifyProfileToken } from '@stacks/profiles';
-
-try {
- const decodedToken = verifyProfileToken(tokenFile[0].token, publicKey);
-} catch (e) {
- console.log(e);
-}
-```
-
-## Recover a profile from a token file
-
-```jsx
-const recoveredProfile = Person.fromToken(tokenFile, publicKey);
-```
-
-## Validate profile schema
-
-```jsx
-const validationResults = Person.validateSchema(recoveredProfile);
-```
-
-### Transaction signing
-
-TBD: info on transaction signing protocol
diff --git a/src/pages/build-apps/tutorials/todos.md b/src/pages/build-apps/tutorials/todos.md
index f249f413..7dd0d880 100644
--- a/src/pages/build-apps/tutorials/todos.md
+++ b/src/pages/build-apps/tutorials/todos.md
@@ -69,10 +69,9 @@ You should see the app's landing page:
### Step 1: Choose **Get started** to start onboarding into the app.
-The app displays a standardized introductory modal using
-Stacks Connect.
+The app displays a standardized introductory modal using the `@stacks/connect` library.
-![The Stacks Connect Modal](/images/todos/get-started.png)
+![Modal displayed by showConnect function](/images/todos/get-started.png)
This modal is displayed using the `authenticate` function exported by the `src/auth.js` module, which organizes all Stacks resources needed for authentication in the app:
@@ -109,7 +108,7 @@ export function getPerson() {
}
```
-The `authenticate` function implements the `showConnect` function imported from the `@stacks/connect` library.
+The `authenticate` function implements the `showConnect` function imported from the `connect` package of Stacks.js.
`showConnect` triggers the display of a modal that initiates the authentication process for users, one in which they'll authenticate with a _Secret Key_ that's used to encrypt their private data.