内容
# Daxie
**人工智能的以太坊钱包。** 一个以智能体为优先的以太坊CLI钱包,使用Go编写,内置MCP服务器。非交互式标志/环境变量/stdin,`--json`无处不在,确定性的退出代码,密封的支出限制防护措施,以及一个一核心/两个前端的架构,使得CLI和MCP服务器遍历**完全相同**的钱包逻辑——以及**完全相同**的防护措施。
[](https://github.com/daxchain-io/daxie/actions/workflows/ci.yml)
[](https://github.com/daxchain-io/daxie/actions/workflows/release.yml)
[](https://go.dev/)
[](LICENSE)
> **状态:v1 — 稳定。** CLI界面、JSON模式、退出代码、MCP工具集、配置模式和磁盘状态格式已冻结并受语义版本保护(参见[版本控制](#版本控制))。v1中的托管是一个**加密的本地密钥库,位于一个操作系统信任域内**(与代理相同的uid)。该边界被诚实声明 - 参见[安全模型](#安全模型)和v2签名守护进程路径。使用测试网络和小额主网浮动资产进行评估。
---
## 什么是Daxie?
大多数以太坊工具假设终端上有一个人类确认每个操作。Daxie颠倒了这一点:它是为**自主代理**设计的,用于持有账户和在**操作员设置的限制内**转移资金,而代理无法提高这些限制。由此产生了两个设计选择:
- **一核心,两前端。** 一个单一的`internal/service`包拥有每个用例(构建交易,评估策略,签名,广播,等待)。 **CLI**(`internal/cli`)和**MCP服务器**(`internal/mcpserver`)是该核心的薄适配器。没有第二个签名路径需要审计:CLI可以做的事情,代理可以通过MCP做 - 而且*两者*都不能绕过防护措施,因为防护措施位于*下方*两个前端,位于一个签名检查点内。
- **两密码,两权限级别。** **密钥库密码**解锁签名(代理可能持有它)。 **管理员密码**授权策略更改(代理*永远*不持有它)。一个完全被劫持的代理可以花费到限制 - 它不能更改限制,改变允许列表,改变别名的意思,或读取密钥。
代理需要的一切都是非交互的:标志,`DAXIE_*`环境变量,stdin用于秘密,每个命令的`--json`输出,以及一个小的稳定退出代码集。
---
## 安装
四种支持的安装路径。**在运行前请验证**(参见[docs/install.md](docs/install.md)中的下载-验证-运行配方和cosign签名验证)。
> 浮动安装渠道 - Homebrew,`curl | sh` `/releases/latest` URL,`:latest`和`:1.0` Docker标签,以及`go install` with `@latest` — 跟踪**稳定**渠道:它们解析为最新的稳定版本,预发布版本从不移动它们。在生产环境中固定确切的版本或镜像摘要。
### Homebrew(macOS / Linux)
```sh
brew install --cask daxchain-io/tap/daxie
```
### curl | sh(Linux / macOS)
```sh
curl -fsSL https://github.com/daxchain-io/daxie/releases/latest/download/install.sh | sh
```
### 容器镜像(GHCR)
```sh
VERSION=1.1.0
docker pull "ghcr.io/daxchain-io/images/daxie:${VERSION}"
docker run --rm "ghcr.io/daxchain-io/images/daxie:${VERSION}" version
```
### go install
```sh
go install github.com/daxchain-io/daxie/cmd/daxie@latest
```
---
## 快速入门
在[docs/quickstart.md](docs/quickstart.md)中有完整的演练。 60秒版本,在Sepolia上:
```sh
# 1. 创建钱包(仅显示助记词一次;加密密钥库密码)。
daxie wallet create treasury
daxie account use treasury/0 # 使其成为默认账户
# 2. 选择网络 + 端点。
daxie network use sepolia
daxie rpc add sepolia-default --network sepolia --url https://rpc.sepolia.org
# 3. 检查余额(只读;无需策略)。
daxie balance --json
# 4. 设置防护措施。 这需要管理员密码,而不是密钥库密码。
daxie policy set --max-tx 0.1eth --max-day 0.5eth
daxie policy allow 0xRecipient... # 允许列表目的地(或联系人/固定的ENS)
# 5. 发送 - 在签名之前强制执行策略。
daxie tx send --to 0xRecipient... --amount 0.05 --wait --json --yes
# 6. 通过MCP(stdio)将相同的钱包提供给AI代理。
daxie mcp serve
```
退出代码是稳定的并且可以被代理分支使用 - 大多数情况下你会分支使用的代码:`0` ok,`3` 策略拒绝,`5` 资金不足,`6` 网络,`7` 已恢复,`8` 超时待处理 **或** 密封违规,`9` 计数冲突(nonce/替换)。
---
## 代理 / MCP 故事
`daxie mcp serve` 通过 **stdio** (v1传输;流式HTTP在v1.1中无需重构)向任何MCP客户端(Claude,自主代理,自定义工具)公开钱包。握手报告钱包版本,因此代理可以确定它正在与哪个版本进行通信,而无需调用shell。
- **31种工具**,每种工具对应一个*操作*(一个`send`涵盖ETH / ERC-20 / ERC-721 / ERC-1155;一个`contract_send`涵盖任何非标准ABI)。工具列表和JSON模式在[docs/agents.md](docs/agents.md)和`daxie mcp tools`中。
- **模式从CLI绑定使用的相同Go结构体派生**,因此CLI和MCP永远不会漂移。 一个JSON输出合约,两个传输。
- **相同的防护措施绑定两个前端。** `policy.Reserve`在可以访问的单个签名方法内部运行。 使用CLI设置策略一次;每个MCP `send` / `token_approve` / `contract_send`都会根据它进行检查。
- **MCP表面故意变窄。** 它可以在**策略范围内**移动资金和读取所有内容;它**不能**导出密钥,创建/导入钱包,改变策略或添加注册别名(别名伪造边界)。 那些是操作员专有的,带外操作。 完整的排除列表在[docs/agents.md](docs/agents.md)。
```sh
# 示例MCP客户端启动器(一个受信任的外壳固定env +路径):
DAXIE_PASSPHRASE_FILE=/run/secrets/daxie-pass \
daxie mcp serve
```
---
## 命令界面
名词/动词树。 每个命令都有一个人类形式 **和** `--json`,一个非交互路径,和文档化的退出代码。 权威合约是[docs/cli-spec.md](docs/cli-spec.md)。
| 名词 | 动词 |
|---|---|
| `wallet` | `create` · `import` · `list` · `show` · `rename` · `export` · `delete` |
| `account` | `derive` · `alias` · `unalias` · `import` · `use` · `list` · `show` · `export` · `delete` |
| `keystore` | `change-passphrase` · `info` |
| `balance` | (ETH / `--token` / `--all`;原始地址或ENS参数) |
| `tx` | `send` · `status` · `wait` · `list` · `speedup` · `cancel`(RBF)· `abandon` |
| `gas` | (基准费用+慢/正常/快速建议) |
| `token` | `info` · `add` · `rename` · `list` · `remove` · `approve` · `allowance` · `revoke` |
| `nft` | `add` · `alias` · `aliases` · `list` · `show` · `send` |
| `contract` | `add` · `list` · `show` · `remove` · `call` · `send` · `logs` · `encode` · `decode` |
| `sign` / `verify` | `sign message` · `sign typed` · `verify`(EIP-191 / EIP-712) |
| `ens` | `resolve` · `reverse` |
| `receive` | (区块直到入站资金确认; `--new`发票地址) |
| `contacts` | `add` · `list` · `show` · `remove` |
| `network` | `list` · `add` · `use` · `show` · `remove` |
| `rpc` | `add` · `list` · `show` · `use` · `test` · `rename` · `remove` |
| `policy` | `show` · `set` · `allow` · `deny` · `verify` · `check` · `counters` · `pin` · `reset` · `change-admin-passphrase` · `typed allow/remove` · `contract allow/remove` |
| `mcp` | `serve` · `tools` |
| 实用工具 | `version` · `completion` · `config get/set/list` · `convert` |
**退出代码(稳定):** `0` ok · `1` 内部 · `2` 用法 · `3` 策略拒绝 ·
`4` 认证(密码)· `5` 资金不足 · `6` 网络 · `7` 已恢复 ·
`8` 超时待处理 / 密封 · `9` 交易冲突(nonce/替换)· `10`
未找到 / 只读挂载 · `11` 状态目录问题 · `12` 完整性触发。
---
## 安全模型
Daxie的安全目标是一句话:*一个完全被劫持的代理持有密钥库密码不能通过Daxie(a)提取密钥材料,(b)超出操作员设置的策略,或(c)更改该策略 - 而一个拥有磁盘但没有密码的窃贼什么也得不到。* 完整的威胁模型是[docs/design.md §8](docs/design.md);面向操作员的总结是[docs/security.md](docs/security.md)。
控件,简而言之:
- **两密码。** 密钥库密码 = 签名(代理可能持有它)。 管理员密码 = 策略突变 + 策略密封(仅限操作员,从不托管在代理主机上)。 它们是独立的(不同的盐和scrypt参数),因此密钥库秘密对伪造策略一无所知。
- **Ed25519密封策略 + 固定的锚点。** 策略文件带有单独的Ed25519密封。 代理主机仅持有**公有验证密钥**(在配置类中,直接读取,从不通过Viper/env/flag),因此它可以*验证*每次签名操作,但*永远不能*伪造。 被篡改或删除的策略会关闭(退出8)。
- **滚动24小时支出限制。** 每笔交易和每天的上限,包含gas,跨账户和网络聚合在持久计数器上,重启后存活(重置计数器会重新加宽窗口,因此它在损坏时关闭,而不是归零)。
- **目的地允许列表 + ENS/联系人固定。** 发送仅发送到允许的目的地;允许列表ENS名称存储名称**和**解析地址,并且后续重新指向被拒绝(`pin_drift`)直到重新允许。
- **数据分类器。** `contract send`在签名之前解码4字节选择器:识别的支出等效项(`approve`/`transfer`/`setApprovalForAll`/`permit`)击中与类型命令相同的允许列表 +无限确认仪式,而未识别的选择器在激活策略时默认为拒绝。 通用名词不能击败类型名词。
- **签名供应链。** 发布包含SHA256校验和cosign **无长期密钥**签名(Rekor透明日志,无长期密钥),SBOM和SLSA提供;OCI镜像是distroless/static,非root,digest cosign签名。
### 诚实的残留量(非隐藏)
v1做了一个范围声明。 两个残留量影响最大:
- **R1 — 主机妥协(关键)。** 任意代码执行为代理的uid可以读取密钥库文件 **和**与其共存的密码,然后在Daxie外部离线解密。 没有进程设计阻止在一个信任域内阻止它。 这是 **v2签名守护进程**的主要动机,它将密钥移出真正的权限边界(代理然后仅持有可撤销的凭证;密钥导出不是API)。
- **R2 — 相同域计数器/状态篡改(高)。** 代理端进程写入支出计数器且不包含任何秘密来密封它们,因此在相同信任域内它们是**可篡改的证据**,而非**证明**。 在Kubernetes上,策略 **anchor** 存在于只读的ConfigMap中,这在结构上关闭了策略文件交换变体结构计数器 **连续性**在重新指向状态目录后仍然存在。 **由v2 守护进程关闭。**
完整的排名残留表(R1-R10,每个映射到它们是否由v2守护进程关闭)是[docs/security.md](docs/security.md)和[docs/design.md §8.6](docs/design.md).
---
## 四个状态类
Daxie将其磁盘数据分为四个类别,以便容器部署可以每个类别使用正确的耐用性和可写性。这是[部署清单](docs/deploy/)的骨干。
| 类别 | 覆盖变量 | 内容 | K8s 挂载 |
|---|---|---|---|
| **config** | `DAXIE_CONFIG` | `config.toml`(网络、RPC端点,gas/tx默认值)+ `policy-anchor.json`(密封验证密钥 - 直接读取,从不通过Viper) | **只读ConfigMap** |
| **keystore** | `DAXIE_KEYSTORE` | `keystore.json`,`meta.json`,`wallets/<uuid>.json`,`accounts/UTC--...`,`index.lock` | 秘密/外部秘密同步或PVC(运行时只读) |
| **state** | `DAXIE_STATE_DIR` (+ `DAXIE_REGISTRY_DIR`) | 交易日志 + 非随机数,密封的`policy.json` + **耐用支出计数器**,代币/NFT/联系人注册表 | **PVC(必须持久)** |
| **cache** | `DAXIE_CACHE_DIR` | ENS / 元数据 / 费率历史缓存(可重建) | emptyDir / tmpfs |
测试:*config* 由操作员提供且从不被签名操作写入;*keystore* 携带备份中的密钥材料;*state* 由代理的运行时作业写入且**必须在重启后存活**;*cache* 是可丢弃的。
---
## 从源代码构建
需要 **Go 1.26+** 。所有构建都是纯Go(`CGO_ENABLED=0`)。
```sh
CGO_ENABLED=0 go build -o daxie ./cmd/daxie
```
发布管道(`goreleaser`)构建六个目标(darwin/linux/windows ×
amd64/arm64),可重现(`-trimpath`,提交固定的`mod_timestamp`,无
时钟输入)。要验证完整的管道而无需发布:
```sh
goreleaser release --snapshot --clean --skip=sbom,sign
```
---
## 文档
| 文档 | 内容 |
|---|---|
| [docs/quickstart.md](docs/quickstart.md) | 首次钱包,策略启动,Sepolia发送,代理/MCP流程 |
| [docs/install.md](docs/install.md) | 每个安装路径的深入解析 + 验证配方 + `--uninstall` |
| [docs/configuration.md](docs/configuration.md) | `config.toml`,`DAXIE_*`环境变量,四个状态类别 |
| [docs/agents.md](docs/agents.md) | 部署Daxie到代理后面:MCP,工具表面,无人值守的秘密 |
| [docs/security.md](docs/security.md) | 面向操作员的威胁模型 + 分级残留量 |
| [docs/deploy/](docs/deploy/) | Docker Compose + Kubernetes 清单(Helm图表在v1.1中提供) |
| [docs/cli-spec.md](docs/cli-spec.md) | 权威命令/标志/退出代码合约 |
| [docs/design.md](docs/design.md) | 规范设计(法律) |
| [docs/requirements.md](docs/requirements.md) | 需求 |
| [CHANGELOG.md](CHANGELOG.md) | 发布历史 |
架构一句话: **一个核心(`internal/service`),两个薄前端(`internal/cli`,`internal/mcpserver`),每个都位于相同的线路合约(`internal/domain`)之上。** 前端从不导入提供者;提供者从不导入核心;`domain`不导入任何内部内容。 这由`internal/arch_test.go`和`depguard` linter强制执行,而不是通过约定。
---
## 版本控制
SemVer 2.0.0,扁平`v*`标签,从`main`发布。 **公共API** semver保护:命令树和标志,JSON输出模式,文档化的退出代码,MCP工具名称/模式,配置文件模式,`DAXIE_*`环境变量名称和磁盘状态格式。渠道:`stable` = `vX.Y.Z`;`beta`/`rc` = `vX.Y.Z-beta.N` / `-rc.N`。Homebrew,`:latest`和`:X.Y` Docker标签,以及`/releases/latest` 跟踪**稳定** - 预发布版本从不移动浮动标签。在生产环境中使用确切的版本或镜像摘要。
## 贡献
Daxie是出于透明度公开的源代码,目前由维护者领导开发。参见[CONTRIBUTING.md](CONTRIBUTING.md)了解当前的贡献政策。
每个同意的更改必须保持绿色:3个OS矩阵的单元测试,anvil集成套件,`goreleaser build --snapshot`适用于所有六个目标,golangci-lint(包括depguard前端/叶子矩阵),`internal/arch_test.go`中的架构防护,以及运行未修改的`docs/demos/mNN.sh`演练。 [docs/design.md](docs/design.md)中的设计是源头。
## 安全
通过[SECURITY.md](SECURITY.md)中的流程报告疑似漏洞。不要在公共问题中发布漏洞详细信息,钱包材料或实时资金复制品。
## 风险通知
Daxie在Apache License 2.0下提供,不带任何保证或法律要求的责任。Daxie签署并广播区块链交易,这可能不可逆转,并可能导致资金损失。
用户在使用真实资产的Daxie之前,应审查配置,策略,密钥,RPC端点,交易详情和适用法律。使用测试网络和小额余额进行评估。
## 许可
[Apache License 版本2.0](LICENSE)。