@ -17,7 +17,7 @@ Authentication provides a way for users to identify themselves to an app while r
Users who register for your app can subsequently authenticate to any other app with support for the [Blockchain Naming System](/build-apps/references/bns) and vice versa.
See [the Todos app tutorial](/build-apps/tutorials/todos) for a concrete example of this functionality in practice.
[See the Todos app tutorial](/build-apps/tutorials/todos) for a concrete example of this functionality in practice.
@ -15,199 +15,145 @@ This guide explains how to save and retrieve data for users with [Gaia](/build-a
Data storage provides a way for users to save both public and private data off-chain while retaining complete control over it.
Storing data off of the blockchain ensures that apps can provide users with high performance and high availability for data reads and writes without the involvement of centralized parties that could comprise their privacy or accessibility.
Storing data off the Stacks blockchain ensures that apps can provide users with high performance and high availability for data reads and writes without the involvement of centralized parties that could compromise their privacy or accessibility.
See [the Todos app tutorial](/build-apps/tutorials/todos) for a concrete example of this functionality in practice.
[See the Todos app tutorial](/build-apps/tutorials/todos) for a concrete example of this functionality in practice.
## Authentication
## Initiate session
TODO: Add indicator that authentication guide should be followed first
Users must authenticate to an app before the `storage` package will work to save or retrieve data on their behalf.
## How data is stored
[See the authentication guide](/build-apps/guides/authentication) before proceeding to integrate the following data storage capabilities in cases where `userSession.isUserSignedIn()` returns `true`.
Gaia storage is a key-value store.
## Save data for session user
## Creating a file
Gaia serves as a key-value store in which data is saved and retrieved as files to and from Gaia hubs owned by, or managed for, users.
Use the [Storage.putFile](https://blockstack.github.io/stacks.js/classes/storage.html#putfile) method:
The default Gaia hub for users who authenticate to apps with [the Stacks Wallet](https://blockstack.org/wallet) is run by Hiro PBC at `https://gaia.blockstack.org/`. It supports files up to 25 megabytes in size.
// hello.txt exists now, and has the contents "hello world"
});
```
-> We recommend breaking data instances greater than 25 MB into several files, saving them individually, and recomposing them on retrieval.
## Creating an encrypted file
These files can comprise any type of data such as text, image, video or binary.
Use the [Storage.putFile](https://blockstack.github.io/stacks.js/classes/storage.html#putfile) method and
pass `encrypt: true` within the options object. See the [`PutFileOptions` type definition here](https://blockstack.github.io/stacks.js/interfaces/putfileoptions.html#encrypt)
Files are often saved as strings that represent stringified JSON objects and contain a variety of properties for a particular model.
```tsx
const userSession = new UserSession();
To save a file, first instantiate a `storage` object using the `userSession` object for an authenticated user. Then proceed to call its `putFile` method with relevant parameters:
const options: PutFileOptions = {
encrypt: true,
};
```js
import { AppConfig, UserSession } from '@stacks/connect';
The `options` parameter object contains an `encrypt` property that when set to `true` indicates that the data should be encrypted with the user's app private key before saved to their Gaia hub. All data will be encrypted as such by default if the `encrypt` property or the `options` object itself is omitted entirely.
Use the [Storage.getFile](https://blockstack.github.io/stacks.js/classes/storage.html#getfile) method and pass
`decrypt: true` within the options object. See the [`GetFileOptions` type definition here](https://blockstack.github.io/stacks.js/interfaces/getfileoptions.html#decrypt)
If the `encrypt` property is set to `false`, the data will be saved completely unencrypted and available to everyone online with public access to the user's Gaia hub.
```tsx
const userSession = new UserSession();
const storage = new Storage({ userSession });
Whereas saving privately encrypted data is possible for all authenticated apps with the [`store_write`](https://blockstack.github.io/stacks.js/enums/authscope.html#store_write) scope, the user must have previously granted the [`publish_data`](https://blockstack.github.io/stacks.js/enums/authscope.html#publish_data) scope as well during authentication for the app to save publicly unencrypted data.
const options: GetFileOptions = {
decrypt: true,
};
-> Note that you'll need to save an entirely new string of modified data using `putFile` with the same `fileName` every time you want to update a record. There is no separate update method.
// Handle any execution that uses decrypted fileData
});
```
## Delete a file
Note how the `decrypt` property in the `options` object here should implement the same boolean value as used for `encrypt` initially upon saving the data with `putFile`. The `decrypt` property will default to `true` if omitted.
Use the [`UserSession.deleteFile`](https://blockstack.github.io/stacks.js/classes/storage.html#deletefile) from the application's data store.
Encrypted files need `decrypt` set to `true` so the app knows to decrypt the data with the user's app private key before made available in the callback here as `fileData`.
```jsx
const userSession = new UserSession();
const storage = new Storage({ userSession });
storage.deleteFile('hello.txt').then(() => {
// hello.txt is now removed.
});
```
## Get data for other user
## Write-to and Read-from URL Guarantees
Apps can also retrieve public data saved by users other than the one with the active session, granted those users have registered usernames via the [Blockchain Naming System](/build-apps/references/bns).
Gaia is built on a driver model that supports many storage services. So, with
very few lines of code, you can interact with providers on Amazon S3, Dropbox,
and so forth. The simple `getFile()` and `putFile()` interfaces are kept simple
because Stacks assumes and wants to encourage a community of
open-source-data-management libraries.
Simply indicate the username of such a user in the `options` object:
The performance and simplicity-oriented guarantee of the Gaia specification is
that when an application submits a write-to
`https://myhub.service.org/store/foo/bar` URL, the application is guaranteed to
be able to read from the `https://myreads.com/foo/bar` URL. Note that, while the
prefix in the write-to url (for example,`myhub.service.org/store`) and the read-from URL
(`https://myreads.com`) are different, the `foo/bar` suffixes are the same.
```js
import { AppConfig, UserSession } from '@stacks/connect';
import { Storage } from '@stacks/storage';
By default, `putFile()` encrypts information while `getFile()` decrypts it by default. Data stored in an
encrypted format means only the user that stored it can view it. For applications that want other users to
view data, the application should set the `encrypt` option to `false`. And, corresponding, the `decrypt`
option on `getFile()` should also be `false`.
const appConfig = new AppConfig(['store_write', 'publish_data']);
const userSession = new UserSession({ appConfig });
const storage = new Storage({ userSession });
Consistent, identical suffixes allow an application to know _exactly_ where a
written file can be read from, given the read prefix. The Gaia service defines a `hub_info` endpoint to obtain
that read prefix:
let fileName = 'car.json';
```bash
GET /hub_info/
```
The endpoint returns a JSON object with a `read_url_prefix`, for example, if my service returns:
This `getFile` call will retrieve data found at the given `fileName` path from the storage bucket of the Gaia hub that maps to the user who registered the given `username` and this particular app as hosted at the current domain.
The application is guaranteed that the profile is written with `putFile()` this request address:
Set an additional `app` property within `options` to retrieve data for a user as saved by an app hosted at a separate domain:
// Handle any execution after file has been deleted
});
```
This data is public and unencrypted. The same works for encrypted data. Only the holder of the private key used for encryption would be able to decrypt the data.
-> Apps can save and delete data only for the active session user.
@ -17,7 +17,7 @@ Transaction signing provides a way for users execute [Clarity smart contracts](/
Users can sign transactions that exchange fungible or non-fungible tokens with upfront guarantees while retaining complete control over their digital assets.
See [the public registry tutorial](/build-apps/tutorials/public-registry) for a concrete example of this functionality in practice.
[See the public registry tutorial](/build-apps/tutorials/public-registry) for a concrete example of this functionality in practice.