Skip to content

Commit 8ff8717

Browse files
authored
feat(chain-adapter): EVM 和 BIP39 链适配器 (#132)
* feat(chain-adapter): add EVM and BIP39 adapters - Add EVM adapter for Ethereum/BSC chains - IdentityService, AssetService, TransactionService, ChainService - Balance queries via walletapi - Transaction signing placeholder (not yet implemented) - Add BIP39 adapter for Bitcoin/Tron chains - Similar structure to EVM adapter - Chain-specific fee estimates and confirmations - Update use-send.ts error messages - Show chain type name for unsupported chains - Prepare for future EVM/BIP39 transfer implementation - Register all adapters in setupAdapters() * docs: add testnet integration guide - Add new chapter: 08-测试篇/06-测试网络 - Document public testnets: Sepolia, BSC Testnet, Nile, Signet - Include RPC endpoints, faucets, and explorer links - Add testnet-chains.json config file - Update white-book index * feat(chain-adapter): complete EVM transaction signing with PublicNode RPC - Use standard Ethereum JSON-RPC instead of custom REST API - Implement proper secp256k1 signature parsing with recovery bit - Add PublicNode as unified RPC provider for all chains (ETH/BSC/Tron/BTC) - Update testnet documentation with PublicNode endpoints * feat(chain-adapter): add Tron adapter with PublicNode API - Add dedicated Tron chain type and adapter - Implement TronIdentityService with address derivation and signing - Implement TronAssetService for TRX balance queries - Implement TronChainService for block info and health checks - Implement TronTransactionService for transaction building/signing/broadcasting - Update ChainConfigTypeSchema to include 'tron' type - Update schema.test.ts for new chain type distribution * feat(chain-adapter): add Bitcoin adapter with mempool.space API - Add BitcoinIdentityService with BIP84 address derivation (P2WPKH) - Add BitcoinAssetService for balance and UTXO queries - Add BitcoinChainService for block info and fee estimates - Add BitcoinTransactionService for transaction building - Implement custom bech32 encoding/decoding - Note: Full transaction signing requires specialized library * refactor(bitcoin): use @scure/base and viem standard libraries - Replace custom bech32/base58 implementation with @scure/base - Add viem for future EVM improvements - Simplify Bitcoin address validation using standard library * feat(use-send): integrate Web3 chain adapters for EVM/Tron/Bitcoin - Add use-send.web3.ts with transfer/fee/validation functions - Update use-send.ts to route EVM/Tron/Bitcoin transfers through adapters - Support address validation using chain adapter identity service - Support fee estimation using chain adapter transaction service * docs/test: add Web3 adapter documentation and unit tests - Add white-book documentation explaining API choices (mempool.space vs PublicNode for Bitcoin) - Add unit tests for EVM, Bitcoin, and Tron adapters - Update testnet documentation with Bitcoin API comparison table
1 parent 7aef4e8 commit 8ff8717

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+3859
-14
lines changed
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# Web3 链适配器实现
2+
3+
> 本文档描述 EVM、Tron、Bitcoin 链适配器的实现细节。
4+
5+
## 概述
6+
7+
Web3 适配器为非 Bioforest 链提供统一接口,包括:
8+
9+
| 链类型 | 适配器 | API 端点 | 签名状态 |
10+
|-------|--------|---------|---------|
11+
| EVM (ETH/BSC) | `EvmAdapter` | PublicNode JSON-RPC | ✅ 完整 |
12+
| Tron | `TronAdapter` | PublicNode HTTP API | ✅ 完整 |
13+
| Bitcoin | `BitcoinAdapter` | mempool.space REST | ⚠️ 部分 |
14+
15+
## 目录结构
16+
17+
```
18+
src/services/chain-adapter/
19+
├── evm/
20+
│ ├── adapter.ts # 主适配器
21+
│ ├── identity-service.ts # 地址验证
22+
│ ├── asset-service.ts # 余额查询
23+
│ ├── chain-service.ts # 链信息、Gas 价格
24+
│ ├── transaction-service.ts # 交易构建、签名、广播
25+
│ └── types.ts
26+
├── tron/
27+
│ ├── adapter.ts
28+
│ ├── identity-service.ts # Base58Check 地址
29+
│ ├── asset-service.ts # TRX 余额
30+
│ ├── chain-service.ts # 带宽/能量
31+
│ ├── transaction-service.ts
32+
│ └── types.ts
33+
├── bitcoin/
34+
│ ├── adapter.ts
35+
│ ├── identity-service.ts # Bech32/Base58 地址
36+
│ ├── asset-service.ts # UTXO 余额
37+
│ ├── chain-service.ts # 费率估算
38+
│ ├── transaction-service.ts # UTXO 选择
39+
│ └── types.ts
40+
└── index.ts # 适配器注册
41+
```
42+
43+
## EVM 适配器
44+
45+
### 地址派生
46+
47+
使用 BIP44 路径 `m/44'/60'/0'/0/index`
48+
49+
```typescript
50+
import { HDKey } from '@scure/bip32'
51+
import { keccak_256 } from '@noble/hashes/sha3.js'
52+
53+
async deriveAddress(seed: Uint8Array, index = 0): Promise<Address> {
54+
const hdKey = HDKey.fromMasterSeed(seed)
55+
const derived = hdKey.derive(`m/44'/60'/0'/0/${index}`)
56+
const pubKey = secp256k1.getPublicKey(derived.privateKey!, false)
57+
const hash = keccak_256(pubKey.slice(1))
58+
return '0x' + bytesToHex(hash.slice(-20))
59+
}
60+
```
61+
62+
### 交易签名
63+
64+
使用 RLP 编码和 EIP-155 签名:
65+
66+
```typescript
67+
// 1. 构建交易数据
68+
const txData = {
69+
nonce: await this.rpc('eth_getTransactionCount', [from, 'pending']),
70+
gasPrice: await this.rpc('eth_gasPrice'),
71+
gasLimit: '0x5208', // 21000 for simple transfer
72+
to, value, data: '0x',
73+
chainId: this.evmChainId,
74+
}
75+
76+
// 2. RLP 编码(EIP-155 预签名)
77+
const rawTx = this.rlpEncode([nonce, gasPrice, gasLimit, to, value, data, chainId, '0x', '0x'])
78+
79+
// 3. 签名
80+
const msgHash = keccak_256(hexToBytes(rawTx.slice(2)))
81+
const sig = secp256k1.sign(msgHash, privateKey, { format: 'recovered' })
82+
const v = chainId * 2 + 35 + sig.recovery
83+
84+
// 4. 编码签名交易
85+
const signedRaw = this.rlpEncode([nonce, gasPrice, gasLimit, to, value, data, v, r, s])
86+
```
87+
88+
### API 调用
89+
90+
使用标准 Ethereum JSON-RPC:
91+
92+
```typescript
93+
private async rpc<T>(method: string, params: unknown[] = []): Promise<T> {
94+
const response = await fetch(this.rpcUrl, {
95+
method: 'POST',
96+
headers: { 'Content-Type': 'application/json' },
97+
body: JSON.stringify({ jsonrpc: '2.0', id: Date.now(), method, params }),
98+
})
99+
const json = await response.json()
100+
return json.result
101+
}
102+
```
103+
104+
## Tron 适配器
105+
106+
### 地址格式
107+
108+
Tron 使用 Base58Check 编码,前缀 `0x41`
109+
110+
```typescript
111+
// 公钥 → 地址
112+
const pubKeyHash = keccak_256(pubKey.slice(1)).slice(-20)
113+
const payload = new Uint8Array([0x41, ...pubKeyHash])
114+
const checksum = sha256(sha256(payload)).slice(0, 4)
115+
return base58.encode([...payload, ...checksum]) // 以 'T' 开头
116+
```
117+
118+
### 交易流程
119+
120+
1. **创建交易**:调用 `/wallet/createtransaction`
121+
2. **签名**:对 `txID`(已是 hash)进行 secp256k1 签名
122+
3. **广播**:调用 `/wallet/broadcasttransaction`
123+
124+
```typescript
125+
// 创建交易
126+
const rawTx = await this.api('/wallet/createtransaction', {
127+
owner_address: hexAddress,
128+
to_address: toHexAddress,
129+
amount: Number(amount.raw),
130+
})
131+
132+
// 签名(Tron 的 txID 已经是 hash)
133+
const sig = secp256k1.sign(hexToBytes(rawTx.txID), privateKey, { format: 'recovered' })
134+
135+
// 广播
136+
await this.api('/wallet/broadcasttransaction', { ...rawTx, signature: [bytesToHex(sig)] })
137+
```
138+
139+
## Bitcoin 适配器
140+
141+
### 地址类型支持
142+
143+
| 类型 | 前缀 | BIP 路径 | 编码 |
144+
|-----|------|---------|------|
145+
| P2WPKH (SegWit) | bc1q | m/84'/0'/0'/0/x | Bech32 |
146+
| P2TR (Taproot) | bc1p | m/86'/0'/0'/0/x | Bech32m |
147+
| P2PKH (Legacy) | 1 | m/44'/0'/0'/0/x | Base58Check |
148+
149+
默认使用 P2WPKH (Native SegWit):
150+
151+
```typescript
152+
import { bech32 } from '@scure/base'
153+
154+
async deriveAddress(seed: Uint8Array, index = 0): Promise<Address> {
155+
const hdKey = HDKey.fromMasterSeed(seed)
156+
const derived = hdKey.derive(`m/84'/0'/0'/0/${index}`)
157+
const pubKeyHash = ripemd160(sha256(derived.publicKey!))
158+
const words = bech32.toWords(pubKeyHash)
159+
return bech32.encode('bc', [0, ...words])
160+
}
161+
```
162+
163+
### UTXO 查询
164+
165+
使用 mempool.space API:
166+
167+
```typescript
168+
// 获取 UTXO 列表
169+
const utxos = await this.api<BitcoinUtxo[]>(`/address/${address}/utxo`)
170+
171+
// 计算余额
172+
const info = await this.api<BitcoinAddressInfo>(`/address/${address}`)
173+
const balance = info.chain_stats.funded_txo_sum - info.chain_stats.spent_txo_sum
174+
```
175+
176+
### 交易签名限制
177+
178+
Bitcoin 交易签名比 EVM/Tron 复杂,需要:
179+
180+
1. UTXO 选择算法
181+
2. 为每个输入构建 sighash
182+
3. 签名每个输入
183+
4. 构建完整的 witness 数据
184+
185+
**当前状态**:余额查询、UTXO 列表、交易历史已实现。完整签名需要集成 `bitcoinjs-lib` 或类似库。
186+
187+
## 依赖库
188+
189+
| 库 | 用途 |
190+
|---|------|
191+
| `@noble/curves` | secp256k1 签名 |
192+
| `@noble/hashes` | sha256, keccak256, ripemd160 |
193+
| `@scure/bip32` | HD 密钥派生 |
194+
| `@scure/bip39` | 助记词处理 |
195+
| `@scure/base` | bech32, base58 编码 |
196+
| `viem` | EVM 工具(可选,用于进一步简化)|
197+
198+
## 测试
199+
200+
```bash
201+
# 运行适配器测试
202+
pnpm test -- --testPathPattern="chain-adapter"
203+
```
204+
205+
## 相关文档
206+
207+
- [链配置管理](../07-链配置管理/index.md)
208+
- [测试网络](../../08-测试篇/06-测试网络/index.md)
209+
- [ITransactionService](../ITransactionService.md)

0 commit comments

Comments
 (0)