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");
AppContext.setupResolverRelying 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;
}
}
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
- Elastos.Hive.JS.SDK
- Elastos.Hive.Node
- Hive JS SDK guide — focused SDK reference
- Hive Storage overview — concepts, architecture, trust model