-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add Nillion Storage APIs docs for ethglobal hackathon
- Loading branch information
Showing
3 changed files
with
526 additions
and
656 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
# Nillion Storage APIs | ||
|
||
The Nillion Storage APIs provide a simple HTTP interface for storing and retrieving secrets on the Nillion Network Testnet, with built-in management of store IDs and secret names. | ||
|
||
:::info | ||
The Storage APIs are suitable for quick hackathon projects. If you need lower-level control or want to handle store ID management yourself, check out our [Python Client](/python-client) for backend applications and [Javascript Client](https://github.com/NillionNetwork/client-ts) for frontend applications. | ||
::: | ||
|
||
## Overview | ||
|
||
The Nillion Storage APIs make it easy to quickly bootstrap a hackathon project that securely stores and retrieves secret data from the Nillion Network Testnet. APIs include built-in management of store IDs (locations of your secrets on Nillion) and abstract away Testnet payments. You can use Nillion Storage APIs to: | ||
|
||
- Create an app id | ||
- Store 2 types of secrets (numbers and strings/blobs) | ||
- Customize secret permissions: grant retrieve, update, delete, and compute permissions to specific User IDs when storing secrets | ||
- List all store IDs and names of secrets for your app id | ||
- Retrieve secret values from Nillion using their store IDs | ||
|
||
## Storage APIs Quickstart | ||
|
||
This guide shows how to store secrets, list all store IDs and secret names for your app, and retrieve secrets using the Nillion Storage APIs. | ||
|
||
### Prerequisites | ||
|
||
All you need is a way to make HTTP requests. The examples below use `curl` and JavaScript. You can explore and test all API endpoints directly from the [Nillion Storage API Reference](https://nillion-storage-apis-v0.onrender.com/docs). | ||
|
||
### Step 0: Register Your App | ||
|
||
First run the following command from your terminal to register a new app: | ||
|
||
```bash | ||
curl -X POST https://nillion-storage-apis-v0.onrender.com/api/apps/register | ||
``` | ||
|
||
This returns an `app_id` to track the store IDs for your secrets. Save the `app_id` from the response. This is your app's unique identifier. | ||
|
||
### 1. [Optional] Check Your User ID | ||
|
||
Check the deterministic user ID generated by your user seed using POST `/api/user`. You can share this user ID with others so they can give you permissions to retrieve their secrets. | ||
|
||
:::warning | ||
Never share user seeds - they're like private keys! Only share user_ids. | ||
::: | ||
|
||
```javascript | ||
const USER_SEED = 'user_123'; // your seed generates a deterministic nillion user id | ||
const API_BASE = 'https://nillion-storage-apis-v0.onrender.com'; | ||
|
||
// 1. Check your deterministic user ID | ||
console.log('Checking user ID generated by your seed...'); | ||
const user = await fetch(`${API_BASE}/api/user`, { | ||
method: 'POST', | ||
headers: { 'Content-Type': 'application/json' }, | ||
body: JSON.stringify({ | ||
nillion_seed: USER_SEED, | ||
}), | ||
}).then((res) => res.json()); | ||
console.log('Your User ID:', user.nillion_user_id); | ||
``` | ||
|
||
### 2. Store a Secret Number | ||
|
||
Store a number secret using POST `/api/apps/{app_id}/secrets`. The empty permissions arrays mean only the storing user has access. | ||
|
||
**Make sure to update the `APP_ID` below with your app_id from step 0 before running the code:** | ||
|
||
```javascript | ||
const APP_ID = 'INSERT_YOUR_APP_ID_HERE'; | ||
const USER_SEED = 'user_123'; // your seed generates a deterministic nillion user id | ||
const API_BASE = 'https://nillion-storage-apis-v0.onrender.com'; | ||
|
||
// 2. Store first secret (number) | ||
console.log('\nStoring first secret...'); | ||
const storeResult1 = await fetch(`${API_BASE}/api/apps/${APP_ID}/secrets`, { | ||
method: 'POST', | ||
headers: { 'Content-Type': 'application/json' }, | ||
body: JSON.stringify({ | ||
secret: { | ||
nillion_seed: USER_SEED, | ||
secret_value: 16, | ||
secret_name: 'my_secret_number', | ||
}, | ||
permissions: { | ||
retrieve: [], | ||
update: [], | ||
delete: [], | ||
compute: {}, | ||
}, | ||
}), | ||
}).then((res) => res.json()); | ||
console.log('First secret stored at:', storeResult1); | ||
``` | ||
|
||
### 3. Store a Secret String | ||
|
||
Store a string/blob secret using the same endpoint. | ||
|
||
**Make sure to update the `APP_ID` below with your app_id from step 0 before running the code:** | ||
|
||
```javascript | ||
const APP_ID = 'INSERT_YOUR_APP_ID_HERE'; | ||
const USER_SEED = 'user_123'; // your seed generates a deterministic nillion user id | ||
const API_BASE = 'https://nillion-storage-apis-v0.onrender.com'; | ||
|
||
// 3. Store second secret (string/blob) | ||
console.log('\nStoring second secret...'); | ||
const storeResult2 = await fetch(`${API_BASE}/api/apps/${APP_ID}/secrets`, { | ||
method: 'POST', | ||
headers: { 'Content-Type': 'application/json' }, | ||
body: JSON.stringify({ | ||
secret: { | ||
nillion_seed: USER_SEED, | ||
secret_value: 'gm!', | ||
secret_name: 'my_secret_blob', | ||
}, | ||
permissions: { | ||
retrieve: [], | ||
update: [], | ||
delete: [], | ||
compute: {}, | ||
}, | ||
}), | ||
}).then((res) => res.json()); | ||
console.log('Second secret stored at:', storeResult2); | ||
``` | ||
|
||
### 4. List Store IDs | ||
|
||
Get all store IDs for your app using GET `/api/apps/{app_id}/store_ids` to find your secrets. | ||
|
||
**Make sure to update the `APP_ID` below with your app_id from step 0 before running the code:** | ||
|
||
```javascript | ||
const APP_ID = 'INSERT_YOUR_APP_ID_HERE'; | ||
const USER_SEED = 'user_123'; // your seed generates a deterministic nillion user id | ||
const API_BASE = 'https://nillion-storage-apis-v0.onrender.com'; | ||
|
||
// 4. List store IDs | ||
const storeIds = await fetch(`${API_BASE}/api/apps/${APP_ID}/store_ids`) | ||
.then((res) => res.json()) | ||
.then((data) => data.store_ids); | ||
console.log('Store IDs:', storeIds); | ||
``` | ||
|
||
### 5. Retrieve Secrets | ||
|
||
Get each secret's value using GET `/api/secret/retrieve/{store_id}` with the correct secret name and user seed. | ||
|
||
**Make sure to update the `APP_ID` below with your app_id from step 0 before running the code:** | ||
|
||
```javascript | ||
const APP_ID = 'INSERT_YOUR_APP_ID_HERE'; | ||
const USER_SEED = 'user_123'; // your seed generates a deterministic nillion user id | ||
const API_BASE = 'https://nillion-storage-apis-v0.onrender.com'; | ||
const storeIds = await fetch(`${API_BASE}/api/apps/${APP_ID}/store_ids`) | ||
.then((res) => res.json()) | ||
.then((data) => data.store_ids); | ||
|
||
// 5. Retrieve both secrets using the store IDs we just created | ||
console.log('\nRetrieving secrets...'); | ||
const secret1 = await fetch( | ||
`${API_BASE}/api/secret/retrieve/${storeIds[0].store_id}?retrieve_as_nillion_user_seed=${USER_SEED}&secret_name=${storeIds[0].secret_name}` | ||
).then((res) => res.json()); | ||
console.log('First secret retrieved:', secret1); | ||
|
||
const secret2 = await fetch( | ||
`${API_BASE}/api/secret/retrieve/${storeIds[1].store_id}?retrieve_as_nillion_user_seed=${USER_SEED}&secret_name=${storeIds[1].secret_name}` | ||
).then((res) => res.json()); | ||
console.log('Second secret retrieved:', secret2); | ||
``` | ||
|
||
## Quickstart Complete Code | ||
|
||
**Make sure to update the `APP_ID` below with your app_id from step 0 before running the code:** | ||
|
||
```javascript reference showGithubLink | ||
https://github.com/oceans404/nillion-storage-apis-v0/blob/main/Quickstart.md?plain=1#L48-L131 | ||
``` | ||
|
||
## How to Share Secrets with Other Users | ||
|
||
### Store with Permissions | ||
|
||
To give another user access to your secrets, include their user_id in the permissions arrays when storing. | ||
|
||
**Make sure to update the `APP_ID` below with your app_id from step 0 before running the code:** | ||
|
||
```javascript | ||
const APP_ID = 'INSERT_YOUR_APP_ID_HERE'; | ||
const USER_SEED = 'user_123'; // your seed generates a deterministic nillion user id | ||
const API_BASE = 'https://nillion-storage-apis-v0.onrender.com'; | ||
|
||
// Example using a "test" user seed - your friend should use their own unique seed in production | ||
const friend_user_id = | ||
'63P5NjU6a2zkjJqengfuDuwMUF9Yu3ogrrqMPNjidc4ogfcvefDchZgRNNJQg9T3WKiyZ4L7kF4zGwFurpxCo5bP'; | ||
|
||
const storeResultForFriend = await fetch( | ||
`${API_BASE}/api/apps/${APP_ID}/secrets`, | ||
{ | ||
method: 'POST', | ||
headers: { 'Content-Type': 'application/json' }, | ||
body: JSON.stringify({ | ||
secret: { | ||
nillion_seed: USER_SEED, | ||
secret_value: 'secret message to my friend!', | ||
secret_name: 'message_to_friend', | ||
}, | ||
permissions: { | ||
retrieve: [friend_user_id], // give friend retrieve permission | ||
update: [], | ||
delete: [], | ||
compute: {}, | ||
}, | ||
}), | ||
} | ||
).then((res) => res.json()); | ||
console.log('Secret stored for friend:', storeResultForFriend); | ||
``` | ||
|
||
### Retrieve with Permissions | ||
|
||
If you tell your friend the store id, that friend can then retrieve the secret using their seed: | ||
|
||
**Make sure to update the `store_id` below before running the code:** | ||
|
||
```javascript | ||
const store_id = 'store_id_from_above'; | ||
const API_BASE = 'https://nillion-storage-apis-v0.onrender.com'; | ||
const friend_user_seed = 'test'; // friends should use their own unique seed | ||
|
||
const secret = await fetch( | ||
`${API_BASE}/api/secret/retrieve/${store_id}?retrieve_as_nillion_user_seed=${friend_user_seed}&secret_name=message_to_friend` | ||
).then((res) => res.json()); | ||
console.log('Secret retrieved by friend:', secret); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.