Akk525/memora
GitHub: Akk525/memora
面向自主 Agent 的可验证执行溯源基础设施,通过双签名和链上锚定实现执行记录的事后审计与确定性重放。
Stars: 2 | Forks: 0
# Memora Sentinel
# Auth secrets(生成方式:openssl rand -hex 32)
MEMORA_WRITE_SECRET=
MEMORA_SERVICE_HMAC_SECRET=
MEMORA_KEK=<64-char hex>
```
```
# 部署 registry contract(仅一次)
pnpm contracts:deploy
# 应用 Supabase migrations(00001 → 00021,按顺序)
# 将 supabase/migrations/ 中的每个文件粘贴到你的 Supabase SQL Editor 中
# 启动 key-broker (:3000) 和 indexer (:3001)
pnpm dev
# 可选:启动 gateway (:8787) — 生产环境中推荐的 SDK target
pnpm --filter @memora/gateway start
# 启动 web console
cd apps/web && cp .env.example .env.local
# 有关 GitHub/Google OAuth 配置,请参见 docs/SUPABASE_AUTH_SETUP.md
pnpm dev
```
完整的分步指南请见 [docs/LOCAL_SETUP.md](docs/LOCAL_SETUP.md)。
## 生产环境部署(Railway)
托管技术栈:
| 对外服务 | URL | 角色 |
|---------|-----|------|
| Web 控制台 | `https://getmemora.dev` | OAuth、工作区、凭证、驾驶舱 |
| 公共 API | `https://api.getmemora.dev` | SDK `baseUrl` — 仅 gateway |
从 monorepo 根目录部署**五个服务**:`web`、`gateway`、`indexer`、`key-broker`、`agent-runtime`(可选)。构建命令、健康检查和环境变量配置请见 [docs/RAILWAY.md](docs/RAILWAY.md)。
**SDK 使用者**只需要 `baseUrl` + 每个 Agent 对应的 API key。Indexer 和 key-broker 作为私有服务隐藏在 gateway 之后。
## 演示模式(无实时基础设施)
使用预置的金库测试数据运行 Web 控制台 — 无需 Supabase、indexer 或 Hedera 连接:
```
cd apps/web
MEMORA_CONSOLE_DEMO=1 pnpm dev
```
可在 `http://localhost:3000` 体验完整的驾驶舱、重放检查器和金库演示。
## 测试
```
# 单元测试 + 集成测试(所有 packages)
pnpm test
# 按 package 划分
pnpm --filter @memora/shared exec vitest run # 98 TypeScript tests
pnpm --filter @smritheon/memora-core exec vitest run # 50 TypeScript tests
pnpm --filter @memora/gateway exec vitest run # 44 TypeScript tests
pnpm --filter @memora/key-broker exec vitest run # 42 TypeScript tests
pnpm --filter @memora/indexer exec vitest run # 58 TypeScript tests
pnpm contracts:test # 80 Solidity tests (Hardhat)
# E2E(web console)— 186 个测试,无需实时 infra
cd apps/web
pnpm test:e2e
```
E2E 测试涵盖:导航、驾驶舱、重放、身份、账本、配置、故障可见性、金库演示、策略执行和文档页面。所有 186 个测试均通过模拟的 API 路由和演示数据运行通过 — 无需连接到实时的 Hedera 或 Supabase。
## Web 控制台
`apps/web` — 位于 [getmemora.dev](https://getmemora.dev) 的操作溯源接口。通过 Supabase 进行 GitHub/Google OAuth;工作区用于划分 Agent 和 API key。
| 路由 | 用途 |
|-------|---------|
| `/auth/login` | OAuth 登录 (GitHub / Google) |
| `/app/workspaces/new` | 首次运行的工作区创建 |
| `/app/cockpit` | 实时执行流 — HCS 排序、提交路径徽章、内联验证 |
| `/app/replay` | 执行追踪查看器 — 血统、签名状态、签名者有效性、父链 |
| `/app/identities` | Agent 注册表 — 凭证、SDK 代码片段 |
| `/app/policies` | 操作治理 — 针对 Agent 的策略配置 |
| `/app/ledger` | 溯源记录 — 产物检查、哈希验证 |
| `/app/config` | 服务健康状态(gateway、indexer、key-broker)、部署模式 |
| `/docs` | SDK 文档 |
## 仓库结构
```
packages/
shared/ Canonical types, crypto primitives, signing helpers @memora/shared
contracts/ MemoraRegistry.sol — Hardhat, Solidity 0.8.20 @memora/contracts
gateway/ Public API edge /v1/* → indexer + key-broker @memora/gateway
indexer/ Write API + HCS subscriber + contract listener @memora/indexer
key-broker/ AES key custody, challenge/response auth @memora/key-broker
cli/ write | query | read | verify | replay verify @memora/cli
sdk/ Published client SDK @smritheon/memora-core
apps/
web/ Next.js console (OAuth, workspaces, cockpit) (Next.js 14)
agent-runtime/ Reference agent worker
supabase/
migrations/ 00001–00021 in order, never skip, never reorder
docs/
LOCAL_SETUP.md Full local dev stack guide
RAILWAY.md Railway deploy (web, gateway, indexer, key-broker)
SUPABASE_AUTH_SETUP.md OAuth provider config for web console
SDK.md SDK API reference
ROADMAP.md Future work
```
## 安全模型
### 信封加密
```
payload
↓ AES-256-GCM (random IV per write)
ciphertext → Supabase Storage (default) or IPFS/Pinata
AES key
↓ wrapped with KEK (MEMORA_KEK, AES-256)
wrapped key → key-broker (challenge/response: owner or delegate wallet signs nonce)
```
仅凭数据库遭到入侵无法解密 payload。获取明文需要:密文**以及**来自 key-broker 的、由 KEK 解包的 AES 密钥。
### 威胁模型
| 威胁 | 缓解措施 |
|--------|-----------|
| 伪造的执行记录 | 双重签名 VERIFIED 提交;链上 `ecrecover` |
| 过期 delegate 的滥用 | 有时间限制的 `DelegatePolicy.expiresAt`;提交上限 |
| Payload 篡改 | SHA-256 摘要提交至 HCS + 注册表 |
| 开放的 HCS 主题注入 | 订阅者中的 operator 签名验证 |
| 数据库被入侵 | 信封加密的 AES 密钥;独立的 KEK |
| 签名者欺骗 | 链上 `agentSigners` 注册表带有时间窗口 |
| 血统嫁接 | 重放中的父哈希链验证 |
| API key 被入侵 | Agent 级别作用域;Web 控制台中经 KEK 加密的原始密钥 |
| 对密钥注册的重放攻击 | indexer→key-broker 之间使用带时间戳和 nonce 的 HMAC-SHA256 |
### 各组件被入侵后的爆炸半径
| 被入侵的组件 | 能伪造签名 | 能解密 payload | 能损坏索引 |
|-------------|---------------|---------------------|-------------------|
| 仅 Operator 密钥 | 仅能伪造 Operator 签名。无法伪造 Agent 签名。 | 否 | 否 |
| Agent 签名密钥 | 仅能伪造 Agent 签名。仍需 Operator 接受。 | 否 | 否 |
| 仅 KEK | 否 | 是(在有 Supabase 访问权限的情况下) | 否 |
| Supabase 服务密钥 | 否 | 否 | 是 |
## 环境变量
针对单个服务的 Railway 配置请参阅 [docs/RAILWAY.md](docs/RAILWAY.md)。完整列表请参阅 `.env.example`。摘要:
| 变量 | 服务 | 用途 |
|----------|---------|---------|
| `HEDERA_OPERATOR_ID | Indexer | 用于 HCS + EVM 的 Hedera 账户 |
| `HEDERA_OPERATOR_KEY` | Indexer | 64 字符的十六进制 ECDSA 私钥 |
| `HEDERA_EVM_RPC_URL` | Indexer, Key-broker | Hedera EVM JSON-RPC endpoint |
| `HCS_TOPIC_ID` | Indexer | HCS 主题 (`0.0.XXXXX`) |
| `MEMORA_REGISTRY_CONTRACT_ID` | Indexer, Key-broker | 已部署的 `MemoraRegistry` 地址 |
| `MEMORA_WRITE_SECRET` | Indexer | Operator 级别的写入授权 |
| `MEMORA_SERVICE_HMAC_SECRET` | Indexer, Key-broker | 用于 `/keys/register` 的 S2S HMAC 认证(首选) |
| `MEMORA_KEY_REGISTER_SECRET` | Indexer, Key-broker | 密钥注册的 Bearer 回退方案 |
| `MEMORA_KEK` | Key-broker | 64 字符十六进制 AES-256 密钥加密密钥 |
| `KEY_BROKER_BASE_URL` | Indexer | 内部 key-broker URL |
| `SUPABASE_URL` | Indexer, Key-broker, Web | Supabase 项目 URL |
| `SUPABASE_SERVICE_ROLE_KEY` | Indexer, Key-broker, Web | Service role(服务端) |
| `PINATA_JWT` | Indexer | IPFS pinning(仅在 `MEMORA_STORAGE_PROVIDER=ipfs` 时需要) |
| `MEMORA_INDEXER_URL` | Gateway | 内部 indexer URL |
| `MEMORA_KEY_BROKER_URL` | Gateway | 内部 key-broker URL |
| `MEMORA_GATEWAY_URL` | Web | 服务端 gateway URL(健康检查、批次刷新) |
| `NEXT_PUBLIC_GATEWAY_URL` | Web | SDK 代码片段中的公共 gateway URL |
| `NEXT_PUBLIC_SUPABASE_URL` | Web | 用于浏览器认证的 Supabase URL |
| `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Web | 用于 OAuth 的 Supabase anon key |
| `MEMORA_BASE_URL` | SDK, Agent-runtime | Gateway 公共 URL |
| `MEMORA_API_KEY` / 每个 Agent 的密钥 | SDK, Agent-runtime | 写入时的 `Authorization: Bearer` |
| `MEMORA_CONSOLE_DEMO` | Web | `1` → 演示模式(无实时基础设施) |
| `MEMORA_INTEGRITY_BACKEND` | Indexer | `enterprise` \| `hedera` — 如未设置则自动检测 |
## 当前局限性
这些是已知的尚未实现的缺失功能:
- **TEE Quote 验证在链下进行** — `commitMemoryTEE()` 在链上锚定 attestation quote 的 SHA-256 哈希,并强制执行双重 ecrecover。Quote 内容(AMD SEV / Intel TDX enclave 度量)由 indexer 在链下验证。链上完整 Quote 验证尚未实现;如果 indexer 被破坏,可能会锚定无效的 quote 哈希。真正的硬件级 attestation 的 runtime 完整性需要完成链上 quote 验证。
- **用于 KEK 的外部 HSM / KMS** — key-broker 从进程环境中读取 `MEMORA_KEK`。需要 HSM 级别密钥保护的生产环境使用场景需要外部 KMS(AWS KMS、HashiCorp Vault)。丢失 `MEMORA_KEK` 将永久销毁所有已包装的 payload 密钥。
- **HCS submit-key 强制执行** — HCS topic 默认是开放的。第三方消息注入的威胁在订阅者中通过 Operator ECDSA 签名验证来缓解,而不是在接入时阻止。设置 `HEDERA_HCS_SUBMIT_KEY` 以锁定 topic。
- **链上摘要重建** — registry 合约存储 `bytes32 eventDigest`,但不会从 payload 字段中重新推导它。摘要内容仅由 CLI replay verifier 在链下验证。
- **分布式限流** — gateway 的限流 bucket 基于每个进程存储在内存中。水平扩展需要共享状态(Redis、Upstash)。
- **确定性 runtime 重放** — Memora 记录的是 Agent *确实*运行了以及*它签署了什么*,而不是*它运行得是否正确或诚实*。
## 路线图
### 已在开发预览版中交付
- ✓ 所有写入 endpoint 上的基于 Agent 的 API key 认证
- ✓ 使用 KEK 进行 AES-256-GCM 密钥包装
- ✓ HMAC-SHA256 服务间认证 (indexer → key-broker)
- ✓ 持久化挑战存储(基于 Supabase,可安全重启)
- ✓ Gateway 限流(内存中,基于单进程)
- ✓ 托管云 (`api.getmemora.dev` + `getmemora.dev`)
- ✓ Merkle 批次溯源 (`commitBatchRoot`)
- ✓ IntegrityBackend 抽象(企业版 / hedera 可插拔)
- ✓ 持久化的重放验证结果
- ✓ TEE 提交路径 — `commitMemoryTEE()`、`strictTeeRequired`、quote 哈希锚定、链下 quote 验证、CLI 重放支持 (`MemoryCommittedV4`)
### 未来工作
- **链上 TEE quote 验证** — 在合约中直接提供 AMD SEV / Intel TDX enclave 度量的密码学证明(目前由 indexer 在链下验证)
- **用于 KEK 的外部 KMS** — HashiCorp Vault、AWS KMS 或类似服务
- **合约升级路径** — 用于 `MemoraRegistry` 的 UUPS 或透明代理
- **用户拥有的 Agent 密钥** — 独立于 operator 的链上 Agent 所有权
- **HCS submit-key 工具** — 配置和轮换 topic submit key
- **链上摘要重建** — 合约强制执行的 `eventDigest` 验证
- **仅追加的签名者策略日志** — 消除重放中链下事件重建的需要
- **Base L2 后端** — 实现 `IntegrityBackend` 的 `integrity/base.ts`(工厂用例已连接)
- **HCS 重建工具** — 从 HCS + 合约事件重建 Supabase 索引
- **主网支持** — 目前所有基础设施均针对 Hedera testnet
## 贡献
Memora Sentinel 是基于 Apache 2.0 的开源项目。欢迎贡献。
1. Fork 仓库并从 `main` 切出分支。
2. 阅读仓库根目录下的 `CLAUDE.md` — 架构不变量和阶段检查清单。
3. 运行 `pnpm test` — 所有 292 个 TypeScript 单元测试和 80 个 Solidity 测试必须通过。
4. 对于 Web 更改:`cd apps/web && pnpm test:e2e` — 所有 186 个 Playwright 测试必须通过。
5. 接口更改必须是**原子的**:在一次提交中更新 `@memora/shared` 类型、所有消费者和测试。不完整的更改会破坏 `main`。
完整的流程和当前的高影响区域请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。
**安全披露:** 请勿针对漏洞开启公开的 issue。请联系邮箱:akuniyil@purdue.edu
## 技术栈
TypeScript · Next.js 14 · Node.js ≥ 20 · Hedera HCS · Hedera EVM · Solidity 0.8.20 · ethers.js · Supabase · IPFS / Pinata · Playwright · AES-256-GCM · ECDSA / EIP-191
## 许可证
版权所有 2026 Aditya Kuniyil Kattil
基于 Apache License, Version 2.0 授权。详见 [LICENSE](LICENSE)。
**面向自主系统的可验证执行溯源基础设施。**
[](LICENSE)
[](https://www.npmjs.com/package/@smritheon/memora-core)
[](#tests)
[](#tests)
[](#tests)
[](#dev-preview-state)
## 这是什么
Memora Sentinel 回答了一个操作性问题:
**执行了什么,谁授权了它,以及执行历史能否被独立验证?**
不是通过声明 —— 而是通过可重放、双签、哈希链式的执行记录,锚定在防篡改的序列上。溯源后端是可插拔的:Hedera HCS + EVM(在 testnet 上运行),或者是自托管的仅追加日志(无需区块链)。
**何时使用 Memora:**
| 场景 | 使用 Memora? |
|-----------|-------------|
| 自主 Agent 转移资金或做出具有现实后果的决策 | 是 |
| 你需要在事后准确审计模型做了什么 | 是 |
| 你想证明 Agent 在执行时持有了有效的签名密钥 | 是 |
| 你需要对 Agent 决策进行完全确定性的重放 | 是 |
| 你正在构建一个简单的聊天机器人 | 否 |
| 你已经有了足够的不可变审计日志 | 否 |
## 开发预览版状态
这是一个开源的开发者预览版。核心后端是生产级别的,并经过了全面测试。Web 控制台功能正常,但部分 UI 流程尚未完成。
| 组件 | 状态 |
|-----------|--------|
| SDK (`@smritheon/memora-core`) | 稳定 — 已发布至 npm |
| Gateway (`/v1/*`) | 稳定 — 已在 `api.getmemora.dev` 上线 |
| Indexer + key-broker | 稳定 — 已部署在 Railway 上 |
| 合约 (`MemoraRegistry`) | 稳定 — 已部署在 Hedera testnet 上 |
| VERIFIED 提交路径 (双重 `ecrecover`) | 稳定 |
| Merkle 批次溯源 | 稳定 |
| Web 控制台 — 驾驶舱、账本、重放 | 功能正常 |
| Web 控制台 — 签名者治理 UI | 占位符(按钮不可用) |
| CLI 重放验证器 | 稳定 |
| API 和 Supabase schema | 在 v1.0 之前可能会演进 |
## 架构
**六层架构,均可替换:**
```
┌────────────────────────────────────────────────────────────┐
│ 1. Your runtime LangGraph · Temporal · CrewAI · custom │
│ (unchanged call sites — SDK wraps, not replaces) │
├────────────────────────────────────────────────────────────┤
│ 2. SDK @smritheon/memora-core │
│ agentId + apiKey + baseUrl → gateway │
├────────────────────────────────────────────────────────────┤
│ 3. Gateway /v1/* — auth check, rate limit, │
│ audit log, proxy to indexer + key-broker │
├────────────────────────────────────────────────────────────┤
│ 4. Indexer write path · HCS publisher │
│ Key-broker AES key custody · challenge/response │
├────────────────────────────────────────────────────────────┤
│ 5. Provenance Hedera HCS + EVM (full_on_chain) │
│ backend Hedera HCS only (anchored) │
│ Internal Merkle (enterprise) │
├────────────────────────────────────────────────────────────┤
│ 6. Web console OAuth workspaces · cockpit · replay │
│ getmemora.dev │
└────────────────────────────────────────────────────────────┘
```
## 执行流程
每个 VERIFIED 事件都包含:
- **Agent 签名** — 基于原始 SHA-256 摘要的 EIP-191,Agent ECDSA 密钥
- **Operator 连署** — 相同的规范摘要,Operator ECDSA 密钥
- **HCS 序列** — 来自 Hedera Consensus Service 的全局有序、防篡改时间戳
- **链上 ecrecover** — `MemoraRegistry.commitMemoryVerified()` 验证两个签名;触发 `MemoryCommittedV3`。TEE 提交使用 `commitMemoryTEE()` 并额外锚定证明 Quote 的哈希;触发 `MemoryCommittedV4`。
## 提交路径
| 路径 | 合约方法 | 链上强制执行 |
|------|-----------------|----------------------|
| `TEE` | `commitMemoryTEE()` | 对 operator + agent 均进行 `ecrecover`。TEE Quote 哈希锚定在链上。Quote 内容由 indexer 在链下验证。触发 `MemoryCommittedV4`。 |
| `VERIFIED` | `commitMemoryVerified()` | 对 operator + agent 均进行 `ecrecover`。针对 high-s 可延展性的防护。触发 `MemoryCommittedV3`。 |
| `ATTESTED` | `commitMemoryAttested()` | 签名者地址存储在链上,无 `ecrecover`。可通过链下重放进行验证。触发 `MemoryCommittedV2`。 |
| `LEGACY` | `commitMemory()` | 无。如果为 Agent 启用了严格的 attestation 模式或严格的 TEE 模式,则会回滚。 |
Indexer 会根据存在的签名和 TEE 字段,自动选择优先级为 `TEE → VERIFIED → ATTESTED → LEGACY` 的提交路径。
基于 Agent 的严格模式标志强制要求最低提交路径:
- `strictAttestationRequired` — 拒绝 `LEGACY` 提交;至少要求 `ATTESTED`。
- `strictTeeRequired` — 拒绝所有非 TEE 提交路径;要求使用 `commitMemoryTEE()`。
## 信任模型
Memora **不是无信任(trustless)的**。它对自身能证明什么非常明确。
**密码学可验证:**
- 基于事件摘要的 Operator ECDSA 签名
- 基于 Agent 特定摘要的 Agent ECDSA 签名
- 事件发生时的签名者注册表成员身份(链上注册表;有时间限制)
- Payload 哈希完整性(SHA-256 已提交至 HCS + 注册表)
- 仅追加序列排序
- 重放血统连续性(父哈希链)
- Merkle 批次包含证明(阶段 6)
**基础设施信任(非密码学可验证):**
- Runtime 完整性 — Agent 代码的正确性是被断言的,而非被证明的
- KEK 保管 — key-broker 从进程环境读取 `MEMORA_KEK`(而非 HSM)
- Supabase 索引 — 可查询的元数据;遭到破坏可能会损坏索引,但无法伪造签名或解密 payload
- 明文执行语义 — Agent *打算*做什么
有关完整的安全架构,请参阅 [TRUST_MODEL.md](TRUST_MODEL.md)。
## 金库演示
标准演示:一个自主金库 Agent 管理着 1000 万美元的基金再平衡。每一次工具调用都会被签名、记录并且可以重放。
```
Treasury Sentinel Fund I — $10,000,000 AUM
Positions: USDC 50% ETH 28% BTC 15% SOL 7%
Target: USDC 40% ETH 30% BTC 20% SOL 10%
```
**干净运行(13 个 VERIFIED 事件):**
```
1001 run_started
1002 tool_called → fetch_positions
1003 tool_result → 4 assets, $10M AUM 124ms
1004 tool_called → evaluate_risk
1005 tool_result → risk: medium, USDC overweight 89ms
1006 tool_called → simulate_rebalance
1007 tool_result → 4 trades, Δ$1,000,000 156ms
1008 tool_called → policy_check
1009 tool_result → APPROVED: movement 10% < 20% limit 34ms
1010 tool_called → execute_rebalance
1011 tool_result → 4 trades settled 892ms
1012 settlement_confirmed → $1,000,000 moved
1013 run_completed → 1.34s total
```
全部 13 个事件:VERIFIED 提交路径,双重签名,HCS 排序。
**策略拦截(35% 的移动超过了 20% 的阈值):**
```
2009 tool_result → BLOCKED: movement 35% > 20% limit [ATTESTED]
2010 policy_violated → MAX_SINGLE_MOVEMENT_PCT [ATTESTED]
2011 run_failed → approval_required [ATTESTED]
```
## 重放验证
```
pnpm --filter @memora/cli -- replay verify --memory mem_tr_013
```
```
EXECUTION TRACE: treasury-rebal-20260531
──────────────────────────────────────────
✓ contract_tx_hash present
✓ HCS sequence recorded seq: 1001 → 1013
✓ event_id format valid
✓ operator ECDSA signature valid
✓ parent hash-chain continuity
✓ agent countersignature valid
✓ commit path: VERIFIED (from tx receipt — MemoryCommittedV3)
✓ signer timeline valid (from AgentSignerUpdated events, not current state)
✓ payload hash consistent
```
步骤 8(签名者时间线)从历史 `AgentSignerUpdated` 合约事件中重建签名者有效性,而不是通过 `isAgentSignerValid()` 的当前状态。在事件发生后注册的密钥不能使其追溯生效。
## SDK 快速入门
```
npm install @smritheon/memora-core
```
**托管版 — 仅需 agentId + apiKey:**
```
import { Memora } from "@smritheon/memora-core";
const memora = new Memora({
agentId: process.env.MEMORA_AGENT_ID, // from console → Identities → Credentials
apiKey: process.env.MEMORA_API_KEY, // per-agent key from console
// Self-hosted: add baseUrl: process.env.MEMORA_BASE_URL
});
// Structured trace with named events
const decision = await memora.trace("treasury-rebalance", async (trace) => {
await trace.event("input_received", { totalAum, positions });
const rebalance = await existingWorkflow(positions);
await trace.event("decision_made", { trades: rebalance.trades });
return rebalance;
});
// Wrap any existing function — call site is identical
const analyseRisk = memora.wrap("risk-analysis", existingAnalyser);
const result = await analyseRisk(portfolio);
// Individual tool recording
const transfer = memora.tool("transfer_funds", async (args) => bankTransfer(args));
```
**直接写入(底层,自托管):**
```
import { MemoraClient } from "@smritheon/memora-core";
const client = new MemoraClient({
indexerBaseUrl: "https://api.getmemora.dev", // or your gateway URL
keyBrokerBaseUrl: "https://api.getmemora.dev",
writeSecret: process.env.MEMORA_API_KEY,
v1Routes: true,
});
const receipt = await client.write({
agentId: "ops-agent-01",
contentType: "application/json",
content: { event_type: "task_completed", result: { status: "ok" } },
lineage: {
mission_id: "mission_abc",
event_type: "task_completed",
parent_ids: ["prev_event_id"],
actor_type: "agent",
},
});
// receipt: { memory_id, payload_hash, hcs_sequence, contract_tx_hash }
```
完整的 API 参考请见 [docs/SDK.md](docs/SDK.md)。
## 部署模式
区块链是**可选的**。溯源后端是三个基元(`submit()`、`verify()`、`getOrdering()`)的可插拔实现。
| 模式 | 后端 (`MEMORA_INTEGRITY_BACKEND`) | 需要链 | 用例 |
|------|--------------------------------------|----------------|----------|
| `enterprise` | `enterprise` — Merkle root 仅存于 Supabase | 否 | 本地开发、气隙隔离、受监管环境 |
| `anchored` | `hedera` — HCS 有序锚定 | 是 (Hedera) | 外部时间戳,无 EVM 花费 |
| `full_on_chain` | `hedera` + 合约锚定 | 是 (Hedera EVM) | 最高级别的 attestation,在 testnet 上运行 |
完整性后端独立于存储后端(`MEMORA_STORAGE_PROVIDER`)。无论选择哪种完整性后端,信任模型和重放语义都**完全相同** —— 区别仅在于排序证明存放的位置。
## 本地设置(全栈)
**前置条件:** Node.js ≥ 20,pnpm 9,Hedera testnet 账户,Supabase 项目。
```
git clone https://github.com/Akk525/memora.git
cd memora
pnpm install
cp .env.example .env
```
编辑 `.env`:
```
# Hedera testnet
HEDERA_OPERATOR_ID=0.0.xxxxx
HEDERA_OPERATOR_KEY=<64-char hex ECDSA private key>
HEDERA_EVM_RPC_URL=https://testnet.hashio.io/api
# 部署合约后:
HCS_TOPIC_ID=0.0.xxxxx
MEMORA_REGISTRY_CONTRACT_ID=0x...
# Supabase
SUPABASE_URL=https://YOUR_PROJECT.supabase.co
SUPABASE_SERVICE_ROLE_KEY=标签:Hedera, Solidity, TypeScript, 区块链, 可验证执行, 安全插件, 暗色界面, 溯源审计, 自动化攻击, 自治代理, 防篡改日志