Skip to main content
ALL CHAINS

Working with Hive Storage

Hive provides per-user sandboxed storage (MongoDB + IPFS) authenticated via DID. For conceptual background — architecture, vault model, provider choice, backup/migration, and trust model — see the Hive Storage overview.

Prerequisites: Node.js 18+, a published Elastos DID (user + app instance), and a Hive Node URL.

SDK Installation

npm install @elastosfoundation/hive-js-sdk @elastosfoundation/did-js-sdk

Initialize the resolver

Before AppContext.build, call AppContext.setupResolver:

import { AppContext } from "@elastosfoundation/hive-js-sdk";

AppContext.setupResolver("https://api.elastos.io/eid", "./did-cache");
Hive requires AppContext.setupResolver

Relying only on DIDBackend.initialize can leave Hive's context without its resolver flag and throw DIDResolverNotSetupException.

Authentication

Hive uses DID-based challenge-response auth (see the full flow). Implement getAuthorization() in your AppContextProvider:

import { AppContext } from "@elastosfoundation/hive-js-sdk";
import { DIDStore, DIDDocument } from "@elastosfoundation/did-js-sdk";

class HiveAuthHelper {
private appContext: AppContext;

constructor(
private userDid: string,
private appDid: string,
private didStore: DIDStore,
private storepass: string
) {
this.appContext = AppContext.build({
getLocalDataDir: () => "/path/to/hive-data",
getAppInstanceDocument: async () => {
return await this.didStore.loadDid(this.appDid);
},
getAuthorization: async (jwtToken: string) => {
const appDoc = await this.didStore.loadDid(this.appDid);
return await appDoc.signJWT(
{ token: jwtToken },
this.storepass
);
},
}, this.userDid);
}

getContext(): AppContext {
return this.appContext;
}
}
info

Your application DID must be published to the EID chain before authenticating. See the DID Integration guide.

Open a vault

import { Vault } from "@elastosfoundation/hive-js-sdk";

const vault = new Vault(appContext, "https://your-hive-node.example.com");

const database = vault.getDatabaseService();
const files = vault.getFilesService();
const scripting = vault.getScriptingService();

Subscribe to a vault

If the user has not subscribed on this node yet:

import { VaultSubscription } from "@elastosfoundation/hive-js-sdk";

const vaultSubscription = new VaultSubscription(appContext, "https://your-hive-node.example.com");
await vaultSubscription.subscribe();

Database Operations (MongoDB)

const db = vault.getDatabaseService();

await db.createCollection("notes");

const result = await db.insertOne("notes", {
title: "Meeting Notes",
content: "Discussion about Elastos integration",
tags: ["elastos", "development"],
createdAt: new Date().toISOString(),
});

await db.insertMany("notes", [
{ title: "Note 1", content: "Content 1", createdAt: new Date().toISOString() },
{ title: "Note 2", content: "Content 2", createdAt: new Date().toISOString() },
]);

const notes = await db.findMany("notes", {
filter: { tags: { $in: ["elastos"] } },
sort: { createdAt: -1 },
limit: 10,
});

const note = await db.findOne("notes", {
filter: { _id: result.insertedId },
});

await db.updateOne("notes", {
filter: { _id: result.insertedId },
update: { $set: { content: "Updated content" } },
});

await db.deleteOne("notes", {
filter: { _id: result.insertedId },
});

const count = await db.countDocuments("notes", {
filter: { tags: { $in: ["elastos"] } },
});

File Operations (IPFS)

const files = vault.getFilesService();

// Upload
const content = Buffer.from("Hello, Elastos!");
await files.upload("documents/hello.txt", content);

// Upload from stream
const stream = fs.createReadStream("/local/path/to/file.pdf");
await files.upload("documents/report.pdf", stream);

// Download
const downloaded = await files.download("documents/hello.txt");

// List directory
const listing = await files.list("documents/");
for (const entry of listing) {
console.log(`${entry.name} - ${entry.size} bytes`);
}

// Metadata
const props = await files.stat("documents/hello.txt");

// Delete
await files.delete("documents/hello.txt");

// Move / rename
await files.move("documents/report.pdf", "archive/report-2024.pdf");

// IPFS hash
const hash = await files.hash("documents/report.pdf");

Scripting Service

Scripts let vault owners expose controlled access to data for other DIDs. On registerScript, parameter order is: scriptName, executable, optional condition, allowAnonymousUser, allowAnonymousApp.

import { ScriptingService, Condition, Executable, FindExecutable } from "@elastosfoundation/hive-js-sdk";

const scripting = vault.getScriptingService();

// Public script — anyone can call
await scripting.registerScript(
"get_public_profile",
new Executable("find", {
collection: "profile",
filter: { public: true },
}),
null,
false
);

// Restricted script — only approved DIDs
await scripting.registerScript(
"get_private_notes",
new Executable("find", {
collection: "notes",
filter: { sharedWith: "$caller_did" },
}),
new Condition("verify_caller", {
type: "queryHasResults",
collection: "allowed_callers",
filter: { did: "$caller_did" },
}),
false
);

// Call a script from another DID
const result = await callerScripting.callScript(
"get_public_profile",
{},
ownerDid,
appDid
);

Security

  • Data is not end-to-end encrypted by default. Encrypt sensitive fields client-side before insertOne / upload.
  • Self-host a Hive Node for full data sovereignty. See the trust model.

Pricing

Hive vault storage is paid via an ESC smart contract. Pricing is set by individual node operators:

const response = await fetch("https://your-hive-node/api/v2/payment/plans");
const plans = await response.json();

References