Skip to content

Latest commit

History

163 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Engram

Decentralized AI Memory Layer on Bittensor

Permanent, content-addressed semantic memory for AI — store text, images, and PDFs with cryptographic proofs. No central authority, no AWS, no single point of failure.

CILicense: MITPython 3.10+PyPIBittensorStatusDashboardMobileAkashContributions WelcomeRoadmapTests


What is Engram?

Engram is a Bittensor subnet that turns text, images, and documents into permanently stored, content-addressed memories. Every piece of knowledge gets a deterministic CID derived from its embedding — the same content always maps to the same identifier, regardless of which miner stores it.

  • Content-addressedv1::a3f2b1... uniquely identifies an embedding, not a location
  • Decentralized — replicated across competing miners on Bittensor subnet 450
  • Permanent — binary files (images, PDFs) pinned to Arweave across the full stack (SDK, miner, web)
  • Private — X25519 hybrid encryption with differential privacy noise on stored embeddings; namespace isolation enforced at every endpoint
  • Incentivized — miners earn TAO for provably storing and serving vectors
  • Verifiable — Merkle commitment over full memory corpus + HMAC challenge-response proofs
  • Mobile — mine from your phone via managed Akash Network nodes, pay per hour with USDC on Base

Why does this matter? Every RAG system today relies on a single-vendor vector database (Pinecone, Weaviate, pgvector). Engram replaces that single point of failure with a cryptographically incentivized network — the same model a CDN uses to distribute content, applied to AI memory.

 store("The transformer architecture changed everything.")
│
▼
┌───────────────────────────────┐
│ CID: v1::a3f2b1c4d5e6f7... │
│ Embedding: [0.02, -0.14, ...]│
│ Stored on: miners 3, 7, 11 │
└───────────────────────────────┘
│
query("how does attention work?")
│
▼
┌───────────────────────────────┐
│ score: 0.9821 cid: v1::a3f │
│ score: 0.8744 cid: v1::b2e │
│ score: 0.8291 cid: v1::c1d │
└───────────────────────────────┘

Live Network

PropertyValue
NetworkBittensor Testnet
Subnet UID450
Embedding modelall-MiniLM-L6-v2 (384d, local)
Vector indexQdrant (persistent WAL)
Proof typeHMAC-SHA256 challenge-response
Blob storageArweave (pay-once permanent)
Dashboardtheengram.space
Playgroundtheengram.space/playground

Quick Start

Install

pip install engram-subnet

For PDF ingestion or Arweave uploads, install the optional extras:

pip install "engram-subnet[pdf]"# PDF ingestion via ingest_document()
pip install "engram-subnet[arweave]"# Arweave permanent storage upload
pip install "engram-subnet[media]"# Both PDF + Arweave

Or from source:

git clone https://github.com/Dipraise1/Engram.git
cd Engram
pip install -e .

Python SDK

fromengram.sdkimportEngramClientclient=EngramClient("https://api.theengram.space")
# Store text — returns a permanent CIDcid=client.ingest("The transformer architecture changed everything.")
print(cid) # v1::a3f2b1...# Semantic searchresults=client.query("how does attention work?", top_k=5)
forrinresults:
print(f"{r['score']:.4f}{r['cid']}")
# Batch ingest from JSONLcids=client.batch_ingest_file("data/corpus.jsonl")

CLI

engram ingest "Some important knowledge"
engram ingest --file corpus.jsonl
engram query "what is self-attention?"
engram status # local store info
engram status --live --netuid 450 # live metagraph + miner health

Storing Files (Playground)

Open theengram.space/playground to store content from your browser — no wallet or API key needed:

TabWhat happens
TextEmbedded with all-MiniLM-L6-v2, stored on miners
ImageDescribed by Grok Vision, uploaded to Arweave, embedding stored on miners
PDFText extracted, uploaded to Arweave, embedding stored on miners

Every stored item gets a CID you can share. Retrieve it at theengram.space/cid/<YOUR_CID>.

Two-CID Architecture

Images and PDFs get two identifiers:

engram_cid = v1::sha256(embedding + metadata) ← semantic address for search
content_cid = sha256:sha256(raw_bytes) ← content address for retrieval
arweave_tx = <Arweave transaction ID> ← permanent off-chain blob

Arweave Integration (full stack)

Arweave storage is now wired through the entire subnet — not just the web frontend. Set ARWEAVE_KEY (JWK JSON) in the miner or SDK environment and raw media is automatically uploaded before vectorization. The arweave_tx_id and arweave_url are stored in vector metadata.

importosos.environ["ARWEAVE_KEY"] ='{"kty":"RSA",...}'# your JWK walletclient=EngramClient("https://api.theengram.space")
# Raw image bytes uploaded to Arweave, description embedded on minerresult=client.ingest_image("photo.jpg", xai_api_key="xai-...")
print(result["arweave_url"]) # https://arweave.net/<tx_id># PDF bytes archived on Arweave, text embedded on minerresult=client.ingest_pdf("paper.pdf")
print(result["arweave_tx_id"])
# Page HTML archived on Arweave, text extracted and embeddedresult=client.ingest_url("https://arxiv.org/abs/1706.03762")

For private namespaces, raw bytes are encrypted with your X25519 public key before upload so Arweave gateway operators cannot read the content.

Privacy & Security

ProtectionMechanismATLASStatus
Private namespace encryptionX25519 ECDH + HKDF + AES-256-GCM per message
Vector inversion resistanceGaussian DP noise on stored embeddings (ε=3.0)AML.T0024
Encrypted media on Arweaveencrypt_raw() before upload for private clientsAML.T0035
Namespace auth — no key on wiresr25519 signed challenge replaces namespace_keyAML.T0043
Flag-stripping downgradenamespace + hotkey covered by sig — stripping invalidates itAML.T0043
TLS on miner endpointshttps://api.theengram.space terminates TLS before port 8091passive sniff
Namespace trust tierssr25519 attestation + on-chain stake tiersAML.T0010
Anti-sybilStake-weighted trust + slash thresholdAML.T0016
Compromised miner reads queriesThreshold decryption (K-of-N)AML.T0010🔲 planned
Timing / access-pattern leakUniform response paddingAML.T0036🔲 planned

Namespace auth — when a keypair is set on the client, the raw key never leaves the machine. The client signs engram-ns:{namespace}:{timestamp_ms} with its sr25519 hotkey; the miner verifies the signature and stores the hotkey as the namespace owner. Legacy namespace_key still works for backward compatibility.

# Secure namespace auth (keypair-based)importbittensorasbtwallet=bt.wallet(name="my_wallet")
client=EngramClient("https://api.theengram.space", keypair=wallet.hotkey, namespace="my-ns")
cid=client.ingest("private data") # sig challenge sent — key never on wire# Legacy (still works, deprecated)client=EngramClient("https://api.theengram.space", namespace="my-ns", namespace_key="secret")

Configure DP noise: DP_EPSILON=3.0 (default). Set to none to disable.
SDK clients should use https://api.theengram.space as MINER_API_URL to get TLS.


Framework Integrations

# LangChainfromengram.sdk.langchainimportEngramVectorStorestore=EngramVectorStore(miner_url="https://api.theengram.space", embeddings=your_embeddings)
retriever=store.as_retriever(search_kwargs={"k": 5})
# LlamaIndexfromengram.sdk.llama_indeximportEngramVectorStorestore=EngramVectorStore(miner_url="https://api.theengram.space")
index=VectorStoreIndex.from_documents(
documents,
storage_context=StorageContext.from_defaults(vector_store=store)
)

Mine from Your Phone

No server required. The Engram mobile app lets you mine on Akash Network (decentralised cloud) and pay per hour with USDC — your private key never leaves your phone.

App Store / Play Store → Generate keypair → Pick tier → Pay → Mining starts in ~3 min
TiervCPURAMPrice
Lite12 GB~$0.10/hr
Standard24 GB~$0.20/hr
Pro48 GB~$0.36/hr

How it works: your phone is the identity and payment layer (sr25519 keypair + x402 USDC on Base). A managed miner node on Akash does the actual compute — query embedding, vector storage, Bittensor proofs. The cloud node handles all on-chain Bittensor signing; your private key is never sent anywhere.

Full guide: docs/cloud-mining.md


Running a Miner (self-hosted)

On Windows? Use the one-script Docker setup — no Python/Rust install needed: see docs/miner-windows.md.

# Create wallet
btcli wallet new_coldkey --wallet.name engram
btcli wallet new_hotkey --wallet.name engram --wallet.hotkey miner
# Register on subnet (testnet)
btcli subnet register --netuid 450 --wallet.name engram --wallet.hotkey miner --subtensor.network test# Configure
cp .env.example .env.miner
# Set: WALLET_NAME, WALLET_HOTKEY, NETUID=450, SUBTENSOR_NETWORK=test# Start
ENV_FILE=.env.miner python neurons/miner.py

Or with Docker (builds the local-embedder image that matches the validator):

ENGRAM_WALLET_DIR="$HOME/.bittensor" \
docker compose -f docker-compose.windows.yml up -d --build miner

The compose file is named windows but works on Linux/macOS too. It mounts your wallet from $HOME/.bittensor, persists the FAISS index, and exposes port 8091.

Optional env vars:

VariableDefaultDescription
ARWEAVE_KEYJWK wallet JSON; enables Arweave media archival
DP_EPSILON3.0DP noise for private namespace embeddings (none to disable)
REQUIRE_HOTKEY_SIGfalseReject unsigned requests

Full guide: docs/miner.md


Running a Validator

btcli subnet register --netuid 450 --wallet.name engram --wallet.hotkey validator --subtensor.network test
cp .env.example .env.validator
# Set: WALLET_NAME, WALLET_HOTKEY, NETUID=450, SUBTENSOR_NETWORK=test
ENV_FILE=.env.validator python neurons/validator.py

Full guide: docs/validator.md


Scoring

composite_score = 0.50 × recall@10
+ 0.30 × latency_score (1.0 at ≤100ms, 0.0 at ≥500ms)
+ 0.20 × proof_success_rate

Validators score miners every 120 seconds. Miners with proof success rate below 50% receive weight 0.


Architecture

 Your app / AI agent
│
│ pip install engram-subnet
▼
┌───────────────────────────────────────────────────────────────┐
│ EngramClient · LangChain adapter · LlamaIndex adapter │
│ (signed requests · optional X25519 encryption) │
└───────────────────────┬───────────────────────────────────────┘
│ HTTP (ingest / query / challenge)
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Miner 1 │ │ Miner 2 │ │ Miner N │
│ Qdrant HNSW │ │ Qdrant HNSW │ │ Qdrant HNSW │ Akash /
│ embedder │ │ embedder │ │ embedder │ self-hosted
│ engram-core │ │ engram-core │ │ engram-core │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
└─────────────────┼──────────────────┘
│
┌────────▼─────────┐
│ Validator │
│ • recall@10 │
│ • HMAC challenge │
│ • set TAO weights│
└────────┬─────────┘
│ weight_commit_hash
┌────────▼─────────┐
│ Bittensor Chain │
│ metagraph · TAO │
└──────────────────┘
┌──────────────────────────────────────────┐
│ engram-core (Rust / PyO3) │
│ • deterministic CID generation │
│ • HMAC-SHA256 storage proofs │
│ • Merkle commitment over full corpus │
└──────────────────────────────────────────┘
┌──────────────────────────────────────────┐
│ Arweave │
│ images · PDFs · encrypted private blobs │
│ pay-once · permanent · publicly indexed │
└──────────────────────────────────────────┘
┌──────────────────────────────────────────┐
│ engram-web (Next.js · theengram.space) │
│ playground · memory browser · dashboard │
└──────────────────────────────────────────┘

Repository Structure

engram/
├── engram/ # Python package
│ ├── miner/ # Ingest (+ DP noise), query, embedder, store, rate limiter
│ ├── validator/ # Scoring, challenge, weight setting
│ ├── sdk/ # Client (+ Arweave), LangChain, LlamaIndex, encryption
│ ├── storage/ # arweave.py — permanent media upload (Python layer)
│ ├── cloud/ # Cloud mining layer
│ │ ├── session.py # CloudMiningSession lifecycle + registry
│ │ ├── x402.py # x402/Dexter Cash payment gate
│ │ ├── akash.py # Akash Network deployment client
│ │ └── akash_sdl.py # SDL manifest generator (lite/standard/pro)
│ └── protocol.py # Synapse types (IngestSynapse, QuerySynapse)
├── engram-core/ # Rust core — CID generation, HMAC proofs, Merkle commitment
├── engram-web/ # Next.js frontend (theengram.space, Vercel)
│ ├── app/playground/ # Text / Image / PDF ingest UI
│ ├── app/memory/ # Memory search + AI chat
│ ├── app/cid/[id]/ # CID lookup + Arweave proof view
│ └── app/api/ # Next.js API routes → miner proxy
├── mobile/ # React Native app (mine from phone)
│ ├── App.tsx # Root navigator (Dashboard / Start / Wallet)
│ └── src/
│ ├── screens/ # DashboardScreen, StartMiningScreen, WalletScreen
│ └── services/ # gateway.ts, keystore.ts, payment.ts
├── neurons/ # miner.py, validator.py, cloud_gateway.py
├── Dockerfile # Miner image for Akash deployment
├── tests/ # pytest suite (219 passing, all CI green)
└── docs/ # Architecture, SDK, CLI, protocol, cloud-mining

Documentation

GuideDescription
docs/architecture.mdSystem design, data flows, Arweave integration
docs/miner.mdMiner setup, configuration, systemd, Docker
docs/validator.mdValidator setup and scoring loop
docs/sdk.mdPython SDK full reference
docs/cli.mdCLI command reference
docs/protocol.mdWire protocol, CID spec, Merkle proofs, scoring
docs/cloud-mining.mdMine from your phone via Akash + x402 payments
FUNDING.mdFunding priorities, sponsorship areas, and support paths
CONTRIBUTING.mdContributor workflow and high-impact collaboration areas

Tests

pytest tests/ -q
cargo test --manifest-path engram-core/Cargo.toml --no-default-features

Links


2026 — Permanent semantic memory for AI. Mine from anywhere.

About

Decentralized vector database on Bittensor — content-addressed semantic memory for AI

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages