Memora Core SDK — Developer Guide
This guide describes how to integrate @smritheon/memora-core into applications and agents. Memora provides verifiable long-term memory: encrypted payloads on IPFS, ordered commitments on Hedera Consensus Service (HCS), and registry-based access control on Hedera EVM. The SDK operates in cloud mode: your process calls a Memora indexer and key broker over HTTPS; it does not hold operator keys for the network.
Audience: Application developers and agent runtime authors who need to write, query, decrypt, and integrity-check memories without implementing the full protocol stack.
Overview
| Capability | Description |
|---|---|
| Write | Submit a structured payload; the indexer encrypts, pins ciphertext, commits to HCS, and updates the registry. |
| Query | List memory references for an agent and optional task scope. |
| Read | Owner or delegate proves identity via wallet signature; key broker releases the decryption key; SDK verifies payload_hash. |
| Verify | Check indexer metadata and on-chain reference integrity without decrypting. |
The SDK is configuration-only: pass base URLs explicitly. It does not read process.env.
Hosted Memora endpoints: Public indexer and key broker base URLs operated by Memora will be published when they are generally available. Until then, use URLs from your own deployment, your infrastructure provider, or your operator.
Architecture (high level)
The following illustrates how the SDK fits relative to Hedera and off-chain services:
┌─────────────┐ HTTPS ┌──────────────────┐
│ Your app │ ──────────────►│ Memora indexer │
│ MemoraClient│ │ (REST: /write, │
└──────┬──────┘ │ /memories, …) │
│ └────────┬─────────┘
│ │
│ challenge / keys │ IPFS (ciphertext)
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Key broker │ │ HCS + EVM │
│ (registry │◄── on-chain ───►│ registry │
│ checks) │ │ (Hedera) │
└──────────────┘ └──────────────┘For protocol fields, hashing rules, and message schemas, see the Memora Core specification (source repository).
Related Hedera documentation:
- Hedera documentation — consensus, smart contracts, and network concepts.
- Hedera Consensus Service — ordered, timestamped message streams.
Prerequisites
- Node.js 18 or later (recommended LTS).
- Running Memora services: an indexer and key broker reachable over HTTPS (self-hosted, operator-provided, or—when announced—Memora-hosted URLs).
- Read path: a wallet (or signing provider) whose address is the owner or a delegate of the agent on the Memora registry contract.
Install
npm install @smritheon/memora-corepnpm add @smritheon/memora-corePackage registry: npmjs.com/package/@smritheon/memora-core.
Configure the client
Instantiate MemoraClient with the base URLs of your indexer and key broker. Optionally set an IPFS gateway used when fetching ciphertext during read.
Memora-hosted indexer and key broker URLs are coming soon; substitute your own origins in the examples below until those are published.
| Option | Required | Description |
|---|---|---|
indexerBaseUrl | Yes | Origin of the indexer API (no trailing slash required). |
keyBrokerBaseUrl | Yes | Origin of the key broker API. |
ipfsGatewayUrl | No | Gateway prefix for CID resolution (default: Pinata public gateway). |
import { MemoraClient } from "@smritheon/memora-core";
const client = new MemoraClient({
indexerBaseUrl: "https://indexer.example.com",
keyBrokerBaseUrl: "https://keys.example.com",
ipfsGatewayUrl: "https://gateway.pinata.cloud/ipfs/",
});Write memory
write sends a JSON payload to the indexer (POST /write). The indexer canonicalizes and hashes the plaintext, encrypts it, stores the bundle on IPFS, records the commitment, and returns a receipt.
Required fields: agentId, contentType, content.
Optional fields: tags, taskId, access, lineage (execution graph metadata for v0.2).
const receipt = await client.write({
agentId: "0x…", // or your agent identifier as registered
contentType: "application/json",
content: {
summary: "Planning session",
decisions: ["Ship v0.2 lineage", "Document SDK"],
},
tags: ["planning", "sdk"],
taskId: "mission_01",
});
console.log(receipt.memory_id);
console.log(receipt.cid_ciphertext);
console.log(receipt.payload_hash);
console.log(receipt.contract_tx_hash);Receipt fields:
| Field | Meaning |
|---|---|
memory_id | Stable identifier for the memory commitment. |
cid_ciphertext | IPFS content identifier for the encrypted bundle. |
payload_hash | SHA-256 (hex) of canonical plaintext prior to encryption. |
hcs_topic_id | HCS topic used for the ordered commit. |
contract_tx_hash | EVM transaction associating the memory with the registry. |
Query memories
query calls GET /memories with optional agent_id, task_id, limit, and offset.
const refs = await client.query({
agentId: "0x…",
taskId: "mission_01",
limit: 50,
offset: 0,
});
for (const ref of refs) {
console.log(ref.memory_id, ref.payload_hash);
}Read and decrypt
read loads the memory reference from the indexer, fetches ciphertext from IPFS, completes the key-broker challenge with signMessage, decrypts, and verifies that the decrypted bytes hash to payload_hash.
Parameters:
memoryId— from a write receipt or query result.signMessage(message: string) => Promise<string>— typicallywalletClient.signMessageor equivalent.requesterAddress— checksummed or lowercase hex address of the signer.
const payload = await client.read(
receipt.memory_id,
(message) => wallet.signMessage({ message }),
wallet.address,
);
console.log(payload.contentType, payload.content);Note: If the signer is not the owner or an authorized delegate, the key broker returns an error and read fails.
Verify integrity
verify checks indexer metadata and presence of an on-chain transaction hash. It does not download IPFS ciphertext or contact the key broker. Optionally pass an expected payload_hash to compare against the stored reference.
const { valid, reason } = await client.verify(receipt.memory_id);
if (!valid) {
console.error("Verification failed:", reason);
}
const withHash = await client.verify(
receipt.memory_id,
receipt.payload_hash,
);Execution lineage (optional)
For v0.2, you may attach lineage metadata to a write for missions, parent/child memory links, and tooling provenance. When lineage is set, the client sets memora_version according to the shared package default for lineage-capable payloads.
await client.write({
agentId: "0x…",
contentType: "application/json",
content: { step: "tool_result", outputRef: "…" },
lineage: {
event_type: "tool_call",
mission_id: "mission_01",
parent_ids: ["0xabc…"],
tool_ref: "web_search_v1",
actor_type: "agent",
actor_id: "0x…",
},
});Error handling
The SDK throws Error with a message derived from HTTP responses when:
- Configuration is invalid (missing base URLs).
- Write or query requests fail (non-OK status).
- IPFS fetch fails or returns malformed JSON.
- Key broker challenge or key release is denied.
- Decrypted plaintext does not match
payload_hash.
Inspect err.message in application logs. For read failures after decryption, the error may include computedHash and expectedHash on the error object for debugging.
REST surface (reference)
The client uses these indexer routes (relative to indexerBaseUrl):
| Method | Path | Used by |
|---|---|---|
POST | /write | write |
GET | /memories | query |
GET | /memory/:memoryId | read, verify |
Key broker routes (relative to keyBrokerBaseUrl):
| Method | Path | Used by |
|---|---|---|
GET | /challenge?memory_id=&requester= | read |
POST | /keys | read |
Exact request and response bodies are defined in SPEC.md.
Local development
To run indexer and key broker against Hedera testnet and a local database, follow the main repository README and docs/RAILWAY.md (deployment). Point MemoraClient at your dev origins (for example http://localhost:3001 and http://localhost:3000).
Exported types
The package exports MemoraClient, MemoraClientConfig, WriteOptions, WriteReceipt, WriteLineageOptions, VerifyResult, and shared encryption types used by advanced integrators. TypeScript definitions ship with the package.
Related documentation
| Resource | Description |
|---|---|
| npm: @smritheon/memora-core | Package releases and install. |
| Protocol specification (SPEC.md) | Schemas, hashing, and verification flow. |
| Missions and on-chain model | How task_id, lineage, and missions relate to HCS and the registry. |
| Memora repository (GitHub) | Source, issues, and full stack setup. |
| Hedera docs | Network and service fundamentals. |
Monorepo docs/SDK-MEMORA-CORE.md | This guide in source form (for clones and review). |
