diff --git a/src/utils/FeatureCards.js b/src/utils/FeatureCards.js
new file mode 100644
index 0000000..6dc2ec4
--- /dev/null
+++ b/src/utils/FeatureCards.js
@@ -0,0 +1,23 @@
+export const QuickStartFeatures = [
+ {
+ title: 'SecretVault & SecretDataAnalytics',
+ description:
+ 'Build a secure password manager via SecretVault and SecretDataAnalytics',
+ icon: '🔐',
+ href: './build/secretVault-secretData/overview',
+ },
+ {
+ title: 'SecretLLM',
+ description: 'Coming Soon',
+ icon: '💻',
+ disabled: true,
+ href: './start-building',
+ },
+ {
+ title: 'SecretSigning',
+ description: 'Coming Soon',
+ icon: '🔑',
+ disabled: true,
+ href: './community-and-support',
+ },
+];
From a3c22053f3168114a64dc87df573a72b2b8ce06b Mon Sep 17 00:00:00 2001
From: crypblizz <45455218+crypblizz8@users.noreply.github.com>
Date: Tue, 14 Jan 2025 11:51:19 +0100
Subject: [PATCH 05/30] chore: rewording
---
docs/quickstart.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx
index c8c9420..ca8b8ca 100644
--- a/docs/quickstart.mdx
+++ b/docs/quickstart.mdx
@@ -11,6 +11,6 @@ import { QuickStartFeatures } from '@site/src/utils/FeatureCards';
You can get started by building one of these Nillion products:
-If you are looking for other quickstarts, please refer to [Blind Modules](./build/blind-modules.md)
+If you are looking for older quickstarts, please refer to [Blind Modules](./build/blind-modules.md)
From 3cce10f5e19813bb0283bb7e71c1d1001b011a7b Mon Sep 17 00:00:00 2001
From: crypblizz <45455218+crypblizz8@users.noreply.github.com>
Date: Tue, 14 Jan 2025 14:18:57 +0100
Subject: [PATCH 06/30] chore: docCardList
---
docs/js-client-hooks.md | 8 +++++---
docs/js-client.md | 2 +-
docs/nada-lang.md | 2 +-
docs/nada-libraries.md | 2 +-
docs/nillion-client.md | 2 +-
docs/python-client.md | 2 +-
sidebars.js | 15 ---------------
7 files changed, 10 insertions(+), 23 deletions(-)
diff --git a/docs/js-client-hooks.md b/docs/js-client-hooks.md
index 5fbd495..40e237f 100644
--- a/docs/js-client-hooks.md
+++ b/docs/js-client-hooks.md
@@ -1,12 +1,14 @@
import DocCardList from '@theme/DocCardList';
# Hooks
+
Hooks are functions that help you easily read/write into Nillion network and interact with Nada Programs. Our [examples/nextjs](https://github.com/NillionNetwork/client-ts/tree/main/examples-nextjs) have all of these as components to better understand how to interact with them.
To best understand how Nillion functions, it provides two main focuses:
+
1. Storage of [values](./js-client-hooks-values.md) and retrieving them
-2. Blind [computation](./js-client-hooks-compute.md) powered by MPC with Nada Programs.
+2. Blind [computation](./js-client-hooks-compute.md) powered by MPC with Nada Programs.
-[Permissions](./js-client-hooks-permissions.md) are added on top of the network to allow/restrict who can interact with the storage and compute.
+[Permissions](./js-client-hooks-permissions.md) are added on top of the network to allow/restrict who can interact with the storage and compute.
-
\ No newline at end of file
+
diff --git a/docs/js-client.md b/docs/js-client.md
index acef406..addb509 100644
--- a/docs/js-client.md
+++ b/docs/js-client.md
@@ -124,4 +124,4 @@ Now you can interact with the Nillion devnet and use the React hooks to do vario
And once you are ready for testnet, you can follow these [testnet instructions.](./quickstart-testnet.md)
-
+
diff --git a/docs/nada-lang.md b/docs/nada-lang.md
index b95eca4..7207fad 100644
--- a/docs/nada-lang.md
+++ b/docs/nada-lang.md
@@ -18,4 +18,4 @@ The Nada language is:
## Nada Language Components
-
+
diff --git a/docs/nada-libraries.md b/docs/nada-libraries.md
index 0a7f7a4..d16b977 100644
--- a/docs/nada-libraries.md
+++ b/docs/nada-libraries.md
@@ -20,4 +20,4 @@ The Nillion Network leverages [Nada](/nada-lang) for defining programs. We are d
- AI Modules: Provides a PyTorch-like interface to create ML models in Nada by stacking pre-built common components, with the option to create custom components.
- Importing Model State: Easily import an exported model state from the Nillion network for use in a Nada program.
-
+
diff --git a/docs/nillion-client.md b/docs/nillion-client.md
index f386527..77b73c2 100644
--- a/docs/nillion-client.md
+++ b/docs/nillion-client.md
@@ -4,7 +4,7 @@ import DocCardList from '@theme/DocCardList';
There are 3 Nillion Clients - a Python, JavaScript, and CLI Client. Each Nillion Client provides APIs that you can use for generating user and node keys, and managing programs, secrets, and permissions on the Nillion Network.
-
+
### NillionClient
diff --git a/docs/python-client.md b/docs/python-client.md
index f9479d3..8dfbd5d 100644
--- a/docs/python-client.md
+++ b/docs/python-client.md
@@ -4,4 +4,4 @@ import TabItem from '@theme/TabItem';
# Python Client
-
+
diff --git a/sidebars.js b/sidebars.js
index 4b124fc..0d954a3 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -45,13 +45,6 @@ const sidebars = {
id: 'build/secretLLM/overview',
},
items: [],
- // items: [
- // {
- // type: 'doc',
- // label: 'Overview',
- // id: 'build/secretLLM/overview',
- // },
- // ],
},
{
type: 'category',
@@ -61,14 +54,6 @@ const sidebars = {
id: 'build/secretSigning/overview',
},
items: [],
-
- // items: [
- // {
- // type: 'doc',
- // label: 'Overview',
- // id: 'build/secretVault-secretData/overview',
- // },
- // ],
},
'build/blind-modules',
{
From 759b7b7aa95c06cbcf99be066c9c49b58f79b91d Mon Sep 17 00:00:00 2001
From: crypblizz <45455218+crypblizz8@users.noreply.github.com>
Date: Tue, 14 Jan 2025 14:23:20 +0100
Subject: [PATCH 07/30] chore: test sidebar casing
---
sidebars.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sidebars.js b/sidebars.js
index 0d954a3..61673b1 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -42,7 +42,7 @@ const sidebars = {
label: 'SecretLLM',
link: {
type: 'doc',
- id: 'build/secretLLM/overview',
+ id: 'build/secretLlm/overview',
},
items: [],
},
From 21d6f2975337386a4c2c22a9258123bb7896f30e Mon Sep 17 00:00:00 2001
From: Steph <91382964+oceans404@users.noreply.github.com>
Date: Tue, 14 Jan 2025 09:05:17 -0800
Subject: [PATCH 08/30] Update quickstart.mdx
---
docs/quickstart.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx
index ca8b8ca..9d0aef3 100644
--- a/docs/quickstart.mdx
+++ b/docs/quickstart.mdx
@@ -9,7 +9,7 @@ import { QuickStartFeatures } from '@site/src/utils/FeatureCards';
# Quickstart
-You can get started by building one of these Nillion products:
+You can get started by building with one of these Nillion products:
If you are looking for older quickstarts, please refer to [Blind Modules](./build/blind-modules.md)
From 9098a8223a3fa5e4a11b407a8ab5069e24f78112 Mon Sep 17 00:00:00 2001
From: crypblizz <45455218+crypblizz8@users.noreply.github.com>
Date: Wed, 15 Jan 2025 13:57:31 +0100
Subject: [PATCH 09/30] chore: edits
---
docusaurus.config.js | 2 +-
src/pages/index.js | 2 +-
src/utils/FeatureCards.js | 10 +++++-----
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/docusaurus.config.js b/docusaurus.config.js
index 858e060..7d65970 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -109,7 +109,7 @@ const config = {
{
type: 'doc',
position: 'left',
- docId: 'start-building',
+ docId: 'quickstart',
label: 'Build',
},
// {
diff --git a/src/pages/index.js b/src/pages/index.js
index 65ef6c2..d2c8c63 100644
--- a/src/pages/index.js
+++ b/src/pages/index.js
@@ -59,7 +59,7 @@ function FeaturesSection() {
description:
'Start building on Nillion with one of our developer quickstart guides. Create fullstack Python and JavaScript applications with Nada.',
icon: '👷',
- href: './start-building',
+ href: './quickstart',
},
{
title: 'Community',
diff --git a/src/utils/FeatureCards.js b/src/utils/FeatureCards.js
index 6dc2ec4..9f7b22c 100644
--- a/src/utils/FeatureCards.js
+++ b/src/utils/FeatureCards.js
@@ -1,20 +1,20 @@
export const QuickStartFeatures = [
{
- title: 'SecretVault & SecretDataAnalytics',
+ title: 'Build a secure password manager',
description:
- 'Build a secure password manager via SecretVault and SecretDataAnalytics',
+ 'Read and write to an encrypted database via SecretVault and SecretDataAnalytics',
icon: '🔐',
href: './build/secretVault-secretData/overview',
},
{
- title: 'SecretLLM',
+ title: 'Build a private AI chat app',
description: 'Coming Soon',
- icon: '💻',
+ icon: '💬',
disabled: true,
href: './start-building',
},
{
- title: 'SecretSigning',
+ title: 'Build a private AI agent',
description: 'Coming Soon',
icon: '🔑',
disabled: true,
From dfe56c8e477facac7471bc535d5198e6853a3a28 Mon Sep 17 00:00:00 2001
From: crypblizz <45455218+crypblizz8@users.noreply.github.com>
Date: Wed, 15 Jan 2025 14:01:54 +0100
Subject: [PATCH 10/30] chore: port over sv-sd files
---
docs/build/secretVault-secretData/overview.md | 0
.../encryption.md | 39 +++
.../generate-tokens.md | 124 ++++++++
.../overview.md | 50 ++++
.../upload-retrieve.md | 281 ++++++++++++++++++
sidebars.js | 10 +-
static/img/nildb_diagram.png | Bin 0 -> 75111 bytes
7 files changed, 496 insertions(+), 8 deletions(-)
delete mode 100644 docs/build/secretVault-secretData/overview.md
create mode 100644 docs/build/secretVault-secretDataAnalytics/encryption.md
create mode 100644 docs/build/secretVault-secretDataAnalytics/generate-tokens.md
create mode 100644 docs/build/secretVault-secretDataAnalytics/overview.md
create mode 100644 docs/build/secretVault-secretDataAnalytics/upload-retrieve.md
create mode 100644 static/img/nildb_diagram.png
diff --git a/docs/build/secretVault-secretData/overview.md b/docs/build/secretVault-secretData/overview.md
deleted file mode 100644
index e69de29..0000000
diff --git a/docs/build/secretVault-secretDataAnalytics/encryption.md b/docs/build/secretVault-secretDataAnalytics/encryption.md
new file mode 100644
index 0000000..d45c997
--- /dev/null
+++ b/docs/build/secretVault-secretDataAnalytics/encryption.md
@@ -0,0 +1,39 @@
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# Encryption with nilQL
+
+1. To apply encryption to your data, they are to be secret shared across your selected nodes.
+2. This is to be done with **nilQL**, a library for working with encrypted data within nilDB queries and replies, available in [Python](https://pypi.org/project/nilql/#description) and [TypeScript](https://www.npmjs.com/package/@nillion/nilql).
+3. You can find an example on using nilQL to encrypt/decrypt data below
+
+
+
+ ```
+ pip install nilql
+ ```
+
+
+ ```
+ pnpm install @nillion/nilql
+ ```
+
+
+
+
+
+
+```python reference showGithubLink
+https://github.com/NillionNetwork/nil-examples/blob/main/nildb/secretvault_python/encryption.py
+```
+
+
+
+
+```tsx reference showGithubLink
+https://github.com/NillionNetwork/nil-examples/blob/main/nildb/secretvault_nextjs/app/lib/encryption.ts
+```
+
+
+
+
diff --git a/docs/build/secretVault-secretDataAnalytics/generate-tokens.md b/docs/build/secretVault-secretDataAnalytics/generate-tokens.md
new file mode 100644
index 0000000..ec92b18
--- /dev/null
+++ b/docs/build/secretVault-secretDataAnalytics/generate-tokens.md
@@ -0,0 +1,124 @@
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# Generating API tokens
+
+1. In order to access the endpoints of SecretVault/SecretDataAnalytics, you will require a set of Bearer tokens for authorization - one for each node in your setup.
+2. Those can be generated programmatically using the information from your Credentials and Cluster Config
+3. Specifically you'll be able to generate them with just the following information using the code below:
+ - Your private key
+ - Your DID
+ - The target node's DID
+
+
+
+
+```python
+# generate.py
+# pip install "PyJWT[crypto]" ecdsa
+
+import jwt
+import time
+from ecdsa import SigningKey, SECP256k1
+
+def create_jwt(secret_key: str = None,
+ org_did: str = None,
+ node_ids: list = None,
+ ttl: int = 3600) -> list:
+ """
+ Create JWTs signed with ES256K for multiple node_ids
+ """
+
+ # Convert the secret key from hex to bytes
+ private_key = bytes.fromhex(secret_key)
+ signer = SigningKey.from_string(private_key, curve=SECP256k1)
+
+ tokens = []
+ for node_id in node_ids:
+ # Create payload for each node_id
+ payload = {
+ "iss": org_did,
+ "aud": node_id,
+ "exp": int(time.time()) + ttl
+ }
+
+ # Create and sign the JWT
+ token = jwt.encode(
+ payload,
+ signer.to_pem(),
+ algorithm="ES256K"
+ )
+ tokens.append(token)
+ print(f"Generated JWT for {node_id}: {token}")
+
+ return tokens
+
+# # Replace secret_key with secret Key
+# # Replace org_did with DID for organization
+# # Replace node_ids with the Node DIDs
+if __name__ == "__main__":
+ secret_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ org_did = "did:nil:testnet:nillionXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ node_ids = [
+ "did:nil:testnet:nillionXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+ "did:nil:testnet:nillionXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+ "did:nil:testnet:nillionXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ ]
+ create_jwt(secret_key, org_did, node_ids)
+```
+
+
+
+
+```JavaScript
+// generate.js
+// npm install did-jwt
+// run it via node (node generate.js)
+
+const { createJWT, ES256KSigner } = require('did-jwt');
+const { Buffer } = require('buffer');
+
+// Creating the JWT Token
+async function createJwt(secretKey, orgDid, nodeIds, ttl = 3600) {
+ // Create signer from private key
+ const signer = ES256KSigner(Buffer.from(secretKey, 'hex'));
+ const tokens = [];
+
+ for (const nodeId of nodeIds) {
+ const payload = {
+ iss: orgDid,
+ aud: nodeId,
+ exp: Math.floor(Date.now() / 1000) + ttl
+ };
+
+ const token = await createJWT(payload, { issuer: orgDid, signer });
+ tokens.push(token);
+ console.log(`Generated JWT for ${nodeId}: ${token}`);
+ }
+
+ return tokens;
+}
+
+// Example usage
+async function main() {
+ const secretKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
+ const orgDid = "did:nil:testnet:nillionXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
+ const nodeIds = [
+ "did:nil:testnet:nillionXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+ "did:nil:testnet:nillionXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+ "did:nil:testnet:nillionXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ ];
+
+ await createJwt(secretKey, orgDid, nodeIds);
+}
+
+if (require.main === module) {
+ main().catch(console.error);
+}
+
+module.exports = { createJwt };
+```
+
+
+
+
diff --git a/docs/build/secretVault-secretDataAnalytics/overview.md b/docs/build/secretVault-secretDataAnalytics/overview.md
new file mode 100644
index 0000000..fff9e87
--- /dev/null
+++ b/docs/build/secretVault-secretDataAnalytics/overview.md
@@ -0,0 +1,50 @@
+# Overview
+
+Securely store your data with **SecretVault** + run secure queries and computations on them with **SecretDataAnalytics**.
+
+- **SecretVault**: Use Nillion's encryption libraries to secret share your data across our decentralised network of nodes to store and retrieve it using Nillion's easy to use RESTful API
+- **SecretDataAnalytics**: Run encrypted queries across your data stored in the SecretVault using our easy to use RESTful API, with Nillion's decryption libraries to reconstruct the result.
+
+![alt text](/img/nildb_diagram.png)
+
+:::info
+The API page will be integrated into the documentation page shortly.
+:::
+
+# Getting Started
+
+Let's get started with SecretVault and SecretDataAnalytics in a few steps!
+
+To make it easier for you, we have a publicly available shared organization with a pre-defined schema and queries that anyone can use to securely store and then query some test data. This is accessible here with an OpenAPI Swagger interface for `/data/create` and `/data/read`.
+
+`queries/execute` is for more advanced cross-schema queries.
+
+# Access
+
+:::info
+
+If you are on this page, you can skip this step.
+:::
+
+In order to use SecretVault/SecretDataAnalytics with your own schemas and queries, please fill in this form.
+
+Our requirements are to:
+
+- Provide details on how you're planning to use them and your goals.
+- Provide detailed representation of the schemas and queries you'll need in JSON schema format. Please make sure they are valid by using tools like [JSON Schema Validator](https://www.jsonschemavalidator.net/).
+
+You will hear back from us if your applications is approved or feedback is required, and you can then proceed with registering.
+
+# Self-Registering
+
+1. After your application is approved, you will receive a link from us to self-register your org
+2. Here you'll be able to choose a name for your org and select the SecretVault/SecretDataAnalytics nodes that you'd like to deploy to.
+3. You will receive and be prompted to securely store your newly created **Credentials** in the form of:
+ - A DID (Decentralized Identifier)
+ - A private/public keypair
+4. Please note that you are solely responsible for keeping your credentials safe and available. We will not be able to retrieve/regenerate them for you, and you will very likely not be able to access your data without these.
+5. You will also get a **Cluster Config** describing the nodes that you picked in the form of each nodes:
+ - URL
+ - DID (Decentralized Identifier)
+ - Public key
+6. At this stage you should forward us your new DID (from your Credentials), so we can move ahead with registering your schemas and queries as you described them in your application. You can review them using the GET `/schemas` and GET `/queries` endpoints (detailed information in the API Reference page).
diff --git a/docs/build/secretVault-secretDataAnalytics/upload-retrieve.md b/docs/build/secretVault-secretDataAnalytics/upload-retrieve.md
new file mode 100644
index 0000000..d2177e1
--- /dev/null
+++ b/docs/build/secretVault-secretDataAnalytics/upload-retrieve.md
@@ -0,0 +1,281 @@
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+# Uploading & Querying Data
+
+1. The two main operations for a user are:
+ - Uploading / Reading Data (SecretVault)
+ - Running Queries on the Data (SecretDataAnalytics)
+2. To achieve these, we are to communicate with all the nodes in use by the org via REST API endpoints, using the previously generated Bearer tokens for authentication.
+3. An org can always retrieve information on all their schemas and queries using the GET `/schemas` and GET `/queries` endpoints (detailed information in the API Reference page).
+4. Below are a couple simple examples on using the POST `/data/create` and POST `/data/read` endpoints. The format of these requests, and especially for uploading data, must match the JSON schema definition of the target schema. We also have this extended for POST `queries/execute` for more complex schemas.
+
+:::info
+You’ll have to provide an `_id` field of UUIDv4 type for all newly created records. All records are also getting internal `_created` and `_updated` fields automatically assigned and filled that can be used on queries.
+:::
+
+
+
+
+```python
+# nildbapi.py
+import requests
+import json
+from typing import Dict, List, Optional
+
+class NilDBAPI:
+ def __init__(self, node_config: Dict):
+ self.nodes = node_config
+
+ def create_credential(self, node_name: str, credential_data: Dict) -> bool:
+ """Create a credential entry in the specified node."""
+ try:
+ node = self.nodes[node_name]
+ headers = {
+ 'Authorization': f'Bearer {node["jwt"]}',
+ 'Content-Type': 'application/json'
+ }
+
+ payload = {
+ "schema": credential_data["schema"],
+ "data": [credential_data["data"]]
+ }
+
+ response = requests.post(
+ f"{node['url']}/data/create",
+ headers=headers,
+ json=payload
+ )
+
+ return response.status_code == 200
+ except Exception as e:
+ print(f"Error creating credential in {node_name}: {str(e)}")
+ return False
+
+ def read_credentials(self, node_name: str, schema: str, service: Optional[str] = None) -> List[Dict]:
+ """Read credentials from the specified node."""
+ try:
+ node = self.nodes[node_name]
+ headers = {
+ 'Authorization': f'Bearer {node["jwt"]}',
+ 'Content-Type': 'application/json'
+ }
+
+ payload = {
+ "schema": schema,
+ "filter": {"service": service} if service else {}
+ }
+
+ response = requests.post(
+ f"{node['url']}/data/read",
+ headers=headers,
+ json=payload
+ )
+
+ if response.status_code == 200:
+ return response.json().get("data", [])
+ else:
+ raise Exception(f"HTTP error! status: {response.status}")
+ except Exception as e:
+ print(f"Error reading credentials from {node_name}: {str(e)}")
+ return []
+
+ def read_credentials_advanced(self, node_name: str, schema: str, service: Optional[str] = None) -> List[Dict]:
+ """Read credentials from the specified node with advanced filtering."""
+ try:
+ node = self.nodes[node_name]
+ headers = {
+ 'Authorization': f'Bearer {node["jwt"]}',
+ 'Content-Type': 'application/json'
+ }
+
+ payload = {
+ "schema": schema,
+ "filter": {"service": service} if service else {}
+ }
+
+ response = requests.post(
+ f"{node['url']}/queries/execute",
+ headers=headers,
+ json=payload
+ )
+
+ if response.status_code == 200:
+ return response.json().get("data", [])
+ return []
+ except Exception as e:
+ print(f"Error reading credentials from {node_name}: {str(e)}")
+ return []
+
+```
+
+
+
+
+```TypeScript
+// lib/nildb.ts
+import { NODE_CONFIG, NUM_NODES, SCHEMA_ID } from './config';
+
+export type NodeName = keyof typeof NODE_CONFIG;
+
+export interface Credential {
+ _id: string;
+ username: string;
+ password: string;
+ service: string;
+}
+
+interface CredentialPayload {
+ schema: string;
+ data: Credential;
+}
+
+interface NodeResponse {
+ data?: T;
+ error?: string;
+}
+
+export const createNilDBAPI = (config = NODE_CONFIG) => {
+ const uploadCredential = async (
+ nodeName: NodeName,
+ credentialData: CredentialPayload
+ ): Promise => {
+ const node = config[nodeName];
+
+ try {
+ const response = await fetch(`${node.url}/data/create`, {
+ method: 'POST',
+ headers: {
+ Authorization: `Bearer ${node.jwt}`,
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ schema: credentialData.schema,
+ data: [credentialData.data],
+ }),
+ });
+
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+
+ return true;
+ } catch (error) {
+ console.error(`Error creating credential in ${String(nodeName)}:`, error);
+ return false;
+ }
+ };
+
+ const retrieveCredentials = async (
+ nodeName: NodeName,
+ schema: string,
+ service?: string
+ ): Promise => {
+ const node = config[nodeName];
+
+ try {
+ const response = await fetch(`${node.url}/data/read`, {
+ method: 'POST',
+ headers: {
+ Authorization: `Bearer ${node.jwt}`,
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ schema,
+ filter: service ? { service } : {},
+ }),
+ });
+
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+
+ const result = (await response.json()) as NodeResponse;
+ return result.data || [];
+ } catch (error) {
+ console.error(`Error reading credentials from ${nodeName}:`, error);
+ return [];
+ }
+ };
+
+ const retrieveCredentialsAdvanced = async (
+ nodeName: NodeName,
+ query: string,
+ service?: string
+ ): Promise => {
+ const node = config[nodeName];
+
+ try {
+ const response = await fetch(`${node.url}/queries/execute`, {
+ method: 'POST',
+ headers: {
+ Authorization: `Bearer ${node.jwt}`,
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ id: query,
+ variables: {
+ service: service,
+ },
+ }),
+ });
+
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+
+ const result = (await response.json()) as NodeResponse;
+ return result.data || [];
+ } catch (error) {
+ console.error(`Error reading advanced credentials from ${nodeName}:`, error);
+ return [];
+ }
+ };
+
+ return {
+ uploadCredential,
+ retrieveCredentials,
+ retrieveCredentialsAdvanced,
+ config,
+ NUM_NODES,
+ SCHEMA_ID,
+ } as const;
+};
+
+export type NilDB = ReturnType;
+
+
+```
+
+
+
+
+```JSON
+// Single-node example API requests
+
+// POST /data/create
+// Authorization: Bearer XXXXXXX
+{
+ "schema": "6aa651af-7762-4aaa-9089-82f8eab16774",
+ "data": [
+ {
+ "_id": "490421b2-2efb-496a-9e77-2064d5928887",
+ "username": "my_username",
+ "password": "oTsOsg+XMaA=", //encrypted share
+ "service": "github"
+ }
+ ]
+}
+
+// POST /queries/execute
+// Authorization: Bearer XXXXXXX
+{
+ "id": "dfcee886-231d-4a9d-9bdd-857f74a72669",
+ "variables": {
+ "service": "github"
+ }
+}
+```
+
+
+
diff --git a/sidebars.js b/sidebars.js
index 61673b1..7961130 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -27,15 +27,9 @@ const sidebars = {
label: 'SecretVault & SecretData',
link: {
type: 'doc',
- id: 'build/secretVault-secretData/overview',
+ id: 'build/secretVault-secretDataAnalytics/overview',
},
- items: [
- {
- type: 'doc',
- label: 'Overview',
- id: 'build/secretVault-secretData/overview',
- },
- ],
+ items: [],
},
{
type: 'category',
diff --git a/static/img/nildb_diagram.png b/static/img/nildb_diagram.png
new file mode 100644
index 0000000000000000000000000000000000000000..e204a4f85980311f526f97c2dd13665d175782ce
GIT binary patch
literal 75111
zcmeFZby$>Z*ESAH;{XbXG)PLSbPFRONOw2VAT2{l3rI;xmvnbC(jd|?bW6ifL&xvN
zy`T5n&%5{g9=|`nzrN$)I3{4Ox#zmpwXU_!^IU5PR*;hfVUb`VAt8aJ-n>>qLPFz4
zLPB1|Km-1Qwy5$13F(211sJR#1qM?oIM}_jur@_PdJ`P0j;^8H`#4owNeTn+)5n;h
zB&w%$A7k*ekT%8fVk1#7=(_yVjU
0Hii
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
n_t%#^LwzkyV+?osSD9he0(LJm=
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