Observed since 20 Oct, 17:40 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Persistent, verifiable memory for AI agents — backed by 0G Storage (KV + Log) and 0G Chain

Persistent, verifiable memory for AI agents — backed by 0G Storage (KV + Log layers) and 0G Chain.
Agents built with this SDK remember clients, context, and history across sessions — from any machine, without a database.
npm install 0g-memory-sdk
AI agents forget everything when a session ends. Context lives in RAM, databases owned by third parties, or not at all. There is no cryptographic proof that stored data was not modified.
0g-memory-sdk gives any agent three primitives that run entirely on the 0G decentralized network:
| Method | What it does |
|---|---|
remember(key, value) | Writes permanently to 0G Log (immutable, Merkle-provable) and registers a key → rootHash pointer in 0G KV so it is retrievable from any machine |
recall(key) | Resolves the key via the KV index, fetches the value from the Log layer |
archive(record) | Writes typed business records and returns a StorageScan URL as a verifiable on-chain proof |
Because the key index lives on 0G — not on disk — any agent instance with the same private key and agentId gets full memory across machines, restarts, and serverless deployments.
import { ZeroGMemory, deriveAgentId } from '0g-memory-sdk';
const { agentId } = deriveAgentId('my-agent', process.env.PRIVATE_KEY!);
const memory = new ZeroGMemory({
agentId,
privateKey: process.env.PRIVATE_KEY!,
rpcUrl: 'https://evmrpc-testnet.0g.ai',
indexerRpc: 'https://indexer-storage-testnet-standard.0g.ai',
});
// Store something
const rootHash = await memory.remember('user:alice', { plan: 'pro', credits: 42 });
// Retrieve later — from any machine
const data = await memory.recall('user:alice');
// → { plan: 'pro', credits: 42 }
// Or retrieve immediately by root hash (before KV index settles on-chain)
const same = await memory.recallByHash(rootHash);
Testnet tokens: Get OG from the 0G faucet to pay for storage transactions.
new ZeroGMemory(config)const memory = new ZeroGMemory({
agentId: string, // unique agent identifier — use deriveAgentId()
privateKey: string, // wallet private key, pays for 0G storage txs
rpcUrl: string, // 0G chain RPC endpoint
indexerRpc: string, // 0G storage indexer endpoint
});
ChainMemory is exported as an alias of ZeroGMemory for backward compatibility.
memory.remember(key, value) → Promise<string>Writes value to the 0G Log layer (permanent, content-addressed) and fires a concurrent KV write to register key → rootHash in the distributed index. Returns the root hash.
const rootHash = await memory.remember('session:xyz', {
messages: [...],
summary: 'User asked about pricing.',
});
The KV index write settles within a few 0G blocks. Use recallByHash(rootHash) for same-request access before it settles.
memory.recall(key) → Promise<unknown | null>Looks up key in the 0G KV index, then fetches the value from the Log layer. Returns null if the key was never written or the KV index has not yet settled.
Falls back automatically to the legacy local-file index (.chainmemory/) for data written by earlier SDK versions, and migrates those entries to KV on first access.
const context = await memory.recall('session:xyz');
if (context) {
// resume where the agent left off
}
memory.recallByHash(rootHash) → Promise<unknown | null>Fetches a value directly from the 0G Log layer by its root hash, bypassing the KV index entirely. Use this immediately after remember() when you cannot wait for the index to settle.
const rootHash = await memory.remember('key', data);
const same = await memory.recallByHash(rootHash); // always consistent
memory.archive(record) → Promise<{ rootHash, storageScanUrl }>Writes a typed, permanent record to the 0G Log layer. Returns the content-address root hash and a StorageScan explorer URL that anyone can use to verify the data was not modified.
const { rootHash, storageScanUrl } = await memory.archive({
type: 'invoice', // 'invoice' | 'payment' | 'interaction' | 'custom'
data: invoice,
});
console.log(storageScanUrl);
// https://storagescan-newton.0g.ai/tx/0xabc...
memory.updateClientContext(clientName, context) → Promise<string>Convenience wrapper that normalises clientName to a key (client:<name>) and calls remember(). Designed for agents that serve multiple clients and need per-client persistent state. Returns the root hash.
const rootHash = await memory.updateClientContext('Alice Johnson', {
totalInvoiced: 4200,
invoiceCount: 3,
lastJobDescription: 'Frontend redesign — 40 hrs at $120/hr',
});
// Recall in a future session:
const alice = await memory.recall('client:alice_johnson');
deriveAgentId(name, privateKey) → AgentIdentityDerives a deterministic, collision-resistant agent ID from a human-readable name and a wallet private key. Format: <name>:<first-8-hex-chars-of-address>.
import { deriveAgentId } from '0g-memory-sdk';
const { agentId, walletAddress } = deriveAgentId('billing-agent', process.env.PRIVATE_KEY!);
// agentId: "billing-agent:a3f8c201"
// walletAddress: "0xA3F8..."
isValidAgentId(agentId) → booleanValidates that a string matches the <name>:<8-hex-chars> format.
| Field | Description | Testnet value |
|---|---|---|
agentId | Unique agent identifier | deriveAgentId('my-agent', privateKey).agentId |
privateKey | Wallet private key — pays gas and storage fees | Your Galileo testnet key |
rpcUrl | 0G chain JSON-RPC endpoint | https://evmrpc-testnet.0g.ai |
indexerRpc | 0G storage indexer endpoint | https://indexer-storage-testnet-standard.0g.ai |
async function chat(sessionId: string, userMessage: string) {
const history = (await memory.recall(`session:${sessionId}`)) as Message[] ?? [];
const reply = await llm.complete([
...history,
{ role: 'user', content: userMessage },
]);
await memory.remember(`session:${sessionId}`, [
...history,
{ role: 'user', content: userMessage },
{ role: 'assistant', content: reply },
]);
return reply;
}
async function greet(clientName: string) {
const ctx = await memory.recall(`client:${clientName.toLowerCase()}`);
return ctx
? `Welcome back — you've invoiced $${ctx.totalInvoiced} across ${ctx.invoiceCount} jobs.`
: `Welcome! Let's set up your first invoice.`;
}
const { rootHash, storageScanUrl } = await memory.archive({
type: 'invoice',
data: { id: 'INV-042', client: 'Acme Corp', total: 6000, currency: 'USD' },
});
// Share storageScanUrl — anyone can verify the invoice was not tampered with
import { ZeroGMemory, deriveAgentId } from '0g-memory-sdk';
const { agentId } = deriveAgentId('langchain-agent', process.env.PRIVATE_KEY!);
const memory = new ZeroGMemory({ agentId, privateKey: ..., rpcUrl: ..., indexerRpc: ... });
// Use as a custom memory store
const loadMemory = async (key: string) => memory.recall(key);
const saveMemory = async (key: string, value: unknown) => memory.remember(key, value);
| Pattern | Consistency | When to use |
|---|---|---|
remember() → recallByHash() | Immediate | Same request, same session |
remember() → recall() | Eventual (few blocks, ~seconds) | Cross-session, cross-machine |
archive() | Write-once, permanent | Invoices, audit trails, proof records |
recall() automatically falls back to the local .chainmemory/ index for data written by older SDK versions and migrates those entries to the KV layer transparently.
AgentBill is the reference implementation — an autonomous invoicing agent built with this SDK on the full 0G stack:
recall() / updateClientContext()archive(), root hash returned as proofSource: github.com/anbusan19/0g-memory
MIT
Download counts and popularity will appear here as the collector receives them.
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 17:40 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:7899134f8dd49dd41843a06e4113638b933fb57fed6b5ef6887bad9a7a430a0f