@bolloon/bolloon-agent 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -0
- package/dist/agents/agent-lang.js +101 -0
- package/dist/agents/agent-manifest-protocol.js +4 -0
- package/dist/agents/chain/transfer-classify.js +99 -0
- package/dist/agents/chain/transfer-index.js +354 -0
- package/dist/agents/gateway-group.js +44 -3
- package/dist/agents/identity/address-binding.js +613 -0
- package/dist/agents/network-pulse.js +706 -27
- package/dist/agents/pi-sdk.js +101 -8
- package/dist/agents/workflow-pivot-loop.js +3 -1
- package/dist/agents/x402/direct-payment.js +689 -0
- package/dist/agents/x402/order-identity.js +408 -0
- package/dist/agents/x402/paid-info-store.js +17 -0
- package/dist/agents/x402/seller-signing.js +614 -0
- package/dist/agents/x402/seller-summary.js +398 -0
- package/dist/cli/identity-command.js +327 -2
- package/dist/cli/protocol-envelope.js +4 -0
- package/dist/cli/update-commands.js +41 -25
- package/dist/cli/x402-buyer-command.js +463 -0
- package/dist/cli/x402-seller-command.js +289 -0
- package/dist/cli-entry.js +21 -5
- package/dist/efficode/compress.js +78 -0
- package/dist/efficode/crc32.js +38 -0
- package/dist/efficode/did.js +66 -0
- package/dist/efficode/index.js +24 -0
- package/dist/efficode/lz77.js +170 -0
- package/dist/efficode/negotiate.js +187 -0
- package/dist/efficode/ops.js +87 -0
- package/dist/efficode/packet.js +271 -0
- package/dist/efficode/types.js +45 -0
- package/dist/electron-build/agents/agent-manifest-protocol.js +4 -0
- package/dist/electron-build/agents/agent-manifest-protocol.js.map +1 -1
- package/dist/electron-build/agents/chain/transfer-classify.js +106 -0
- package/dist/electron-build/agents/chain/transfer-classify.js.map +1 -0
- package/dist/electron-build/agents/chain/transfer-index.js +400 -0
- package/dist/electron-build/agents/chain/transfer-index.js.map +1 -0
- package/dist/electron-build/agents/identity/address-binding.js +672 -0
- package/dist/electron-build/agents/identity/address-binding.js.map +1 -0
- package/dist/electron-build/agents/network-pulse.js +714 -28
- package/dist/electron-build/agents/network-pulse.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk.js +102 -8
- package/dist/electron-build/agents/pi-sdk.js.map +1 -1
- package/dist/electron-build/agents/workflow-pivot-loop.js +3 -1
- package/dist/electron-build/agents/workflow-pivot-loop.js.map +1 -1
- package/dist/electron-build/agents/x402/direct-payment.js +744 -0
- package/dist/electron-build/agents/x402/direct-payment.js.map +1 -0
- package/dist/electron-build/agents/x402/order-identity.js +458 -0
- package/dist/electron-build/agents/x402/order-identity.js.map +1 -0
- package/dist/electron-build/agents/x402/paid-info-protocol.js.map +1 -1
- package/dist/electron-build/agents/x402/paid-info-store.js +18 -0
- package/dist/electron-build/agents/x402/paid-info-store.js.map +1 -1
- package/dist/electron-build/agents/x402/seller-signing.js +682 -0
- package/dist/electron-build/agents/x402/seller-signing.js.map +1 -0
- package/dist/electron-build/llm/pi-ai.js +685 -48
- package/dist/electron-build/llm/pi-ai.js.map +1 -1
- package/dist/electron-build/utils/auto-update.js +2 -2
- package/dist/electron-build/utils/auto-update.js.map +1 -1
- package/dist/electron-build/utils/runtime-bootstrap.js +1 -1
- package/dist/electron-build/utils/runtime-bootstrap.js.map +1 -1
- package/dist/electron-build/utils/update-manager.js +3 -3
- package/dist/electron-build/utils/update-manager.js.map +1 -1
- package/dist/electron-build/utils/version-identity.js +1 -1
- package/dist/electron-build/utils/version-identity.js.map +1 -1
- package/dist/electron-build/web/routes-x402-info.js +28 -1
- package/dist/electron-build/web/routes-x402-info.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/llm/pi-ai.js +666 -47
- package/dist/utils/auto-update.js +2 -2
- package/dist/utils/runtime-bootstrap.js +1 -1
- package/dist/utils/update-health.js +2 -2
- package/dist/utils/update-manager.js +3 -3
- package/dist/utils/version-identity.js +1 -1
- package/dist/web/bolloon-web.json +3 -3
- package/dist/web/mobile.js +64 -0
- package/dist/web/routes-x402-info.js +28 -1
- package/dist/web/sw.js +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* efficode/packet - 包封装 (帧结构 + CRC32 尾段 + 严格解析)
|
|
3
|
+
*
|
|
4
|
+
* 布局 (照规范):
|
|
5
|
+
* [Header 2B] | [DID 验证段 32B] | [指令段 动态] | [数据块 动态] | [CRC32 4B]
|
|
6
|
+
*
|
|
7
|
+
* Header 2B:
|
|
8
|
+
* byte0: version(高 4 位) | mode(低 4 位) mode: 0=compact · 1=text
|
|
9
|
+
* byte1: flags bit0=有 DID 段 · bit1=有指令段 · bit2=有数据块
|
|
10
|
+
* bit3=数据块已压缩 · bit4..7=保留 (必须 0)
|
|
11
|
+
*
|
|
12
|
+
* 指令段: [varint opLen][opBytes] opBytes 见 ops.ts 的逐条形状
|
|
13
|
+
* 数据块: [varint dataLen][dataBytes] dataBytes[0] = 压缩算法 id (见 compress.ts)
|
|
14
|
+
*
|
|
15
|
+
* 两条硬纪律 (变异 M1/M2 就是拆这两条, 门必须变红):
|
|
16
|
+
* ① 解析必须**逐段自描述**: 长度对不上就报截断, 不许"能解多少解多少";
|
|
17
|
+
* ② 尾段 CRC32 覆盖 CRC 之前的**全部**字节, 对不上就报 CRC_MISMATCH,
|
|
18
|
+
* 绝不放行"内容看着像就收下"。
|
|
19
|
+
*
|
|
20
|
+
* 诚实边界:
|
|
21
|
+
* - "DID 段 32B" 在规范里是固定段; 参考实现允许省略 (省 32B), 省略时 flags 如实写 0,
|
|
22
|
+
* 解码端按 flags 解, **不假设**段存在;
|
|
23
|
+
* - CRC32 只防传输损坏, **不是**防篡改 (无密钥)。防篡改要真签名 —— 规范中, 见 did.ts 注释。
|
|
24
|
+
*/
|
|
25
|
+
import { crc32Bytes, readCrc32Bytes, crc32 } from './crc32.js';
|
|
26
|
+
import { DID_SEGMENT_BYTES, EfficodeError, EFFICODE_VERSION, CRC_BYTES, MIN_PACKET_BYTES } from './types.js';
|
|
27
|
+
import { compressBlock, decompressBlock, pickAlgo } from './compress.js';
|
|
28
|
+
import { decodeDidSegment, didDigestString, encodeDidSegment } from './did.js';
|
|
29
|
+
import { instructionsToSymbolic, opByCode, opBySymbol, symbolicToInstructions } from './ops.js';
|
|
30
|
+
const MODE_TO_NUM = { compact: 0, text: 1 };
|
|
31
|
+
const NUM_TO_MODE = { 0: 'compact', 1: 'text' };
|
|
32
|
+
const F_HAS_DID = 1 << 0;
|
|
33
|
+
const F_HAS_OP = 1 << 1;
|
|
34
|
+
const F_HAS_DATA = 1 << 2;
|
|
35
|
+
const F_COMPRESSED = 1 << 3;
|
|
36
|
+
const FLAG_RESERVED = 0xf0;
|
|
37
|
+
function writeVarint(out, n) {
|
|
38
|
+
let v = n >>> 0;
|
|
39
|
+
while (v >= 0x80) {
|
|
40
|
+
out.push((v & 0x7f) | 0x80);
|
|
41
|
+
v >>>= 7;
|
|
42
|
+
}
|
|
43
|
+
out.push(v & 0xff);
|
|
44
|
+
}
|
|
45
|
+
function readVarint(buf, pos) {
|
|
46
|
+
let value = 0;
|
|
47
|
+
let shift = 0;
|
|
48
|
+
let i = pos;
|
|
49
|
+
for (;;) {
|
|
50
|
+
if (i >= buf.length)
|
|
51
|
+
throw new EfficodeError('EFFICODE_TRUNCATED', 'varint 未读完就到底', i);
|
|
52
|
+
const b = buf[i++];
|
|
53
|
+
value |= (b & 0x7f) << shift;
|
|
54
|
+
if ((b & 0x80) === 0)
|
|
55
|
+
break;
|
|
56
|
+
shift += 7;
|
|
57
|
+
if (shift > 28)
|
|
58
|
+
throw new EfficodeError('EFFICODE_TRUNCATED', 'varint 超过 32 位上限', i);
|
|
59
|
+
}
|
|
60
|
+
return { value: value >>> 0, next: i };
|
|
61
|
+
}
|
|
62
|
+
/** 指令序列 → 指令段字节 (不含外层 varint 长度) */
|
|
63
|
+
function encodeInstructions(instructions) {
|
|
64
|
+
const out = [];
|
|
65
|
+
for (const ins of instructions) {
|
|
66
|
+
const def = opBySymbol(ins.op);
|
|
67
|
+
out.push(def.code);
|
|
68
|
+
const payload = def.hasPayload ? Buffer.from(String(ins.value ?? ''), 'utf-8') : Buffer.alloc(0);
|
|
69
|
+
if (!def.hasPayload && (ins.value ?? '') !== '') {
|
|
70
|
+
throw new EfficodeError('EFFICODE_UNKNOWN_OPCODE', `控制指令 ${def.symbol} 不接受载荷`);
|
|
71
|
+
}
|
|
72
|
+
writeVarint(out, payload.length);
|
|
73
|
+
for (const b of payload)
|
|
74
|
+
out.push(b);
|
|
75
|
+
}
|
|
76
|
+
return Uint8Array.from(out);
|
|
77
|
+
}
|
|
78
|
+
/** 指令段字节 → 指令序列 (严格: 未知 opcode / 截断都抛) */
|
|
79
|
+
function decodeInstructions(buf) {
|
|
80
|
+
const out = [];
|
|
81
|
+
let pos = 0;
|
|
82
|
+
while (pos < buf.length) {
|
|
83
|
+
const code = buf[pos];
|
|
84
|
+
const def = opByCode(code, pos); // 未知 opcode → 抛 (变异 M1 拆掉这里 → 门变红)
|
|
85
|
+
pos += 1;
|
|
86
|
+
const len = readVarint(buf, pos);
|
|
87
|
+
pos = len.next;
|
|
88
|
+
if (def.hasPayload) {
|
|
89
|
+
if (pos + len.value > buf.length) {
|
|
90
|
+
throw new EfficodeError('EFFICODE_TRUNCATED', `指令 ${def.symbol} 声明 ${len.value}B 载荷但只剩 ${buf.length - pos}B`, pos);
|
|
91
|
+
}
|
|
92
|
+
out.push({ op: def.symbol, value: Buffer.from(buf.subarray(pos, pos + len.value)).toString('utf-8') });
|
|
93
|
+
pos += len.value;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
if (len.value !== 0) {
|
|
97
|
+
throw new EfficodeError('EFFICODE_UNKNOWN_OPCODE', `控制指令 ${def.symbol} 声明了 ${len.value}B 载荷`, pos);
|
|
98
|
+
}
|
|
99
|
+
out.push({ op: def.symbol });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
/** 打包 (总是产出二进制; mode 记在 header 里) */
|
|
105
|
+
export function buildPacket(msg) {
|
|
106
|
+
const mode = msg.mode ?? 'compact';
|
|
107
|
+
if (!(mode in MODE_TO_NUM)) {
|
|
108
|
+
// 语音/声波模式等未实现模式 = 显式拒绝, 不静默降级
|
|
109
|
+
throw new EfficodeError('EFFICODE_MODE_NOT_IMPLEMENTED', `模式 ${String(mode)} 未实现 (只有 compact/text)`);
|
|
110
|
+
}
|
|
111
|
+
const instructions = msg.instructions ?? [];
|
|
112
|
+
if (!instructions.length)
|
|
113
|
+
throw new EfficodeError('EFFICODE_BAD_FLAGS', '指令段不能为空 (至少一条指令)');
|
|
114
|
+
const hasDid = typeof msg.from === 'string' && msg.from.length > 0;
|
|
115
|
+
const didSeg = hasDid ? encodeDidSegment(msg.from) : null;
|
|
116
|
+
if (didSeg && didSeg.length !== DID_SEGMENT_BYTES) {
|
|
117
|
+
throw new EfficodeError('EFFICODE_DID_SEGMENT_BAD', `DID 段长度异常 ${didSeg.length}B`);
|
|
118
|
+
}
|
|
119
|
+
const opBytes = encodeInstructions(instructions);
|
|
120
|
+
const rawData = Buffer.from(msg.data ?? '', 'utf-8');
|
|
121
|
+
const algo = msg.compression ?? pickAlgo(new Uint8Array(rawData));
|
|
122
|
+
const dataBlock = rawData.length > 0 ? compressBlock(new Uint8Array(rawData), algo) : new Uint8Array(0);
|
|
123
|
+
let flags = F_HAS_OP;
|
|
124
|
+
if (didSeg)
|
|
125
|
+
flags |= F_HAS_DID;
|
|
126
|
+
if (dataBlock.length > 0)
|
|
127
|
+
flags |= F_HAS_DATA;
|
|
128
|
+
if (dataBlock.length > 0 && algo !== 'none')
|
|
129
|
+
flags |= F_COMPRESSED;
|
|
130
|
+
const out = [];
|
|
131
|
+
out.push(((EFFICODE_VERSION & 0xf) << 4) | (MODE_TO_NUM[mode] & 0xf));
|
|
132
|
+
out.push(flags);
|
|
133
|
+
if (didSeg)
|
|
134
|
+
for (const b of didSeg)
|
|
135
|
+
out.push(b);
|
|
136
|
+
writeVarint(out, opBytes.length);
|
|
137
|
+
for (const b of opBytes)
|
|
138
|
+
out.push(b);
|
|
139
|
+
if (dataBlock.length > 0) {
|
|
140
|
+
writeVarint(out, dataBlock.length);
|
|
141
|
+
for (const b of dataBlock)
|
|
142
|
+
out.push(b);
|
|
143
|
+
}
|
|
144
|
+
const head = Uint8Array.from(out);
|
|
145
|
+
const crc = crc32Bytes(head);
|
|
146
|
+
const packet = new Uint8Array(head.length + CRC_BYTES);
|
|
147
|
+
packet.set(head, 0);
|
|
148
|
+
packet.set(crc, head.length);
|
|
149
|
+
return packet;
|
|
150
|
+
}
|
|
151
|
+
/** 编码成要上网的形态: text 模式 → Base64 串; compact 模式 → 二进制 */
|
|
152
|
+
export function encodePacket(msg) {
|
|
153
|
+
const packet = buildPacket(msg);
|
|
154
|
+
const mode = msg.mode ?? 'compact';
|
|
155
|
+
return mode === 'text' ? Buffer.from(packet).toString('base64') : packet;
|
|
156
|
+
}
|
|
157
|
+
/** 解析 (严格)。入参可以是二进制包或 text 模式的 Base64 串 */
|
|
158
|
+
export function parsePacket(input) {
|
|
159
|
+
let mode;
|
|
160
|
+
let buf;
|
|
161
|
+
if (typeof input === 'string') {
|
|
162
|
+
mode = 'text';
|
|
163
|
+
const cleaned = input.trim();
|
|
164
|
+
if (!/^[A-Za-z0-9+/]+={0,2}$/.test(cleaned) || cleaned.length % 4 !== 0) {
|
|
165
|
+
throw new EfficodeError('EFFICODE_BAD_BASE64', '文本模式载荷不是合法 Base64');
|
|
166
|
+
}
|
|
167
|
+
buf = new Uint8Array(Buffer.from(cleaned, 'base64'));
|
|
168
|
+
if (buf.length === 0)
|
|
169
|
+
throw new EfficodeError('EFFICODE_BAD_BASE64', 'Base64 解出 0 字节');
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
mode = 'compact';
|
|
173
|
+
buf = input;
|
|
174
|
+
}
|
|
175
|
+
if (buf.length < MIN_PACKET_BYTES) {
|
|
176
|
+
throw new EfficodeError('EFFICODE_TOO_SHORT', `包 ${buf.length}B < 最短合法 ${MIN_PACKET_BYTES}B`);
|
|
177
|
+
}
|
|
178
|
+
const version = (buf[0] >> 4) & 0xf;
|
|
179
|
+
if (version !== EFFICODE_VERSION) {
|
|
180
|
+
throw new EfficodeError('EFFICODE_BAD_VERSION', `包版本 ${version} 不被支持 (本实现只认 ${EFFICODE_VERSION})`, 0);
|
|
181
|
+
}
|
|
182
|
+
const modeNum = buf[0] & 0xf;
|
|
183
|
+
const declaredMode = NUM_TO_MODE[modeNum];
|
|
184
|
+
if (!declaredMode)
|
|
185
|
+
throw new EfficodeError('EFFICODE_BAD_MODE', `未知模式 id=${modeNum}`, 0);
|
|
186
|
+
if (declaredMode !== mode) {
|
|
187
|
+
throw new EfficodeError('EFFICODE_BAD_MODE', `传输形态(${mode})与包头声明(${declaredMode})不一致`, 0);
|
|
188
|
+
}
|
|
189
|
+
const flags = buf[1];
|
|
190
|
+
if ((flags & FLAG_RESERVED) !== 0) {
|
|
191
|
+
throw new EfficodeError('EFFICODE_BAD_FLAGS', `flags 保留位被置位: 0x${flags.toString(16)}`, 1);
|
|
192
|
+
}
|
|
193
|
+
let pos = 2;
|
|
194
|
+
let didDigest = null;
|
|
195
|
+
let didSegmentHex = null;
|
|
196
|
+
if (flags & F_HAS_DID) {
|
|
197
|
+
if (pos + DID_SEGMENT_BYTES > buf.length) {
|
|
198
|
+
throw new EfficodeError('EFFICODE_TRUNCATED', `声明有 DID 段但只剩 ${buf.length - pos}B`, pos);
|
|
199
|
+
}
|
|
200
|
+
const seg = buf.subarray(pos, pos + DID_SEGMENT_BYTES);
|
|
201
|
+
const parsed = decodeDidSegment(seg); // algo 未知 → 抛
|
|
202
|
+
didDigest = didDigestString(parsed);
|
|
203
|
+
didSegmentHex = Buffer.from(seg).toString('hex');
|
|
204
|
+
pos += DID_SEGMENT_BYTES;
|
|
205
|
+
}
|
|
206
|
+
let instructions = [];
|
|
207
|
+
if (flags & F_HAS_OP) {
|
|
208
|
+
const opLen = readVarint(buf, pos);
|
|
209
|
+
pos = opLen.next;
|
|
210
|
+
if (pos + opLen.value > buf.length) {
|
|
211
|
+
throw new EfficodeError('EFFICODE_TRUNCATED', `指令段声明 ${opLen.value}B 但只剩 ${buf.length - pos}B`, pos);
|
|
212
|
+
}
|
|
213
|
+
instructions = decodeInstructions(buf.subarray(pos, pos + opLen.value));
|
|
214
|
+
pos += opLen.value;
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
throw new EfficodeError('EFFICODE_BAD_FLAGS', 'flags 声明无指令段 —— 本实现不接受无指令的包', 1);
|
|
218
|
+
}
|
|
219
|
+
let data = '';
|
|
220
|
+
let compression = 'none';
|
|
221
|
+
let rawDataBytes = 0;
|
|
222
|
+
if (flags & F_HAS_DATA) {
|
|
223
|
+
const dataLen = readVarint(buf, pos);
|
|
224
|
+
pos = dataLen.next;
|
|
225
|
+
if (pos + dataLen.value > buf.length) {
|
|
226
|
+
throw new EfficodeError('EFFICODE_TRUNCATED', `数据块声明 ${dataLen.value}B 但只剩 ${buf.length - pos}B`, pos);
|
|
227
|
+
}
|
|
228
|
+
const block = buf.subarray(pos, pos + dataLen.value);
|
|
229
|
+
const un = decompressBlock(block);
|
|
230
|
+
compression = un.algo;
|
|
231
|
+
rawDataBytes = un.data.length;
|
|
232
|
+
data = Buffer.from(un.data).toString('utf-8');
|
|
233
|
+
pos += dataLen.value;
|
|
234
|
+
}
|
|
235
|
+
const expectCrcAt = buf.length - CRC_BYTES;
|
|
236
|
+
if (pos !== expectCrcAt) {
|
|
237
|
+
throw new EfficodeError('EFFICODE_TRAILING_BYTES', `解析在 ${pos}B 结束, 但 CRC 段在 ${expectCrcAt}B —— 中间有 ${expectCrcAt - pos}B 垃圾`, pos);
|
|
238
|
+
}
|
|
239
|
+
const head = buf.subarray(0, expectCrcAt);
|
|
240
|
+
const want = readCrc32Bytes(buf, expectCrcAt);
|
|
241
|
+
const got = crc32(head);
|
|
242
|
+
if (want !== got) {
|
|
243
|
+
throw new EfficodeError('EFFICODE_CRC_MISMATCH', `CRC32 不符: 包内 0x${want.toString(16)}, 实算 0x${got.toString(16)}`, expectCrcAt);
|
|
244
|
+
}
|
|
245
|
+
return {
|
|
246
|
+
mode: declaredMode,
|
|
247
|
+
didDigest,
|
|
248
|
+
didSegmentHex,
|
|
249
|
+
instructions,
|
|
250
|
+
data,
|
|
251
|
+
compression,
|
|
252
|
+
bytes: buf.length,
|
|
253
|
+
rawDataBytes,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
/** 便捷: 包 → 语义消息 (保留符号化形态, 供文本模式/调试面读取) */
|
|
257
|
+
export function packetToMessage(input) {
|
|
258
|
+
const p = parsePacket(input);
|
|
259
|
+
return {
|
|
260
|
+
instructions: p.instructions,
|
|
261
|
+
data: p.data || undefined,
|
|
262
|
+
mode: p.mode,
|
|
263
|
+
compression: p.compression,
|
|
264
|
+
bytes: p.bytes,
|
|
265
|
+
symbolic: instructionsToSymbolic(p.instructions),
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
/** 从符号化文本造一条消息 (调试/文本模式入口) */
|
|
269
|
+
export function messageFromSymbolic(text, data) {
|
|
270
|
+
return { instructions: symbolicToInstructions(text), data, mode: 'compact' };
|
|
271
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* efficode/types - Efficode 参考实现的公共类型
|
|
3
|
+
*
|
|
4
|
+
* 设计口径 (照 leo 给的规范, 不自行发明新协议):
|
|
5
|
+
* - 符号化指令集 + 前缀表达式: @DID: 身份 · #DATA: 数据 · #REQ: 请求 · !ACK/!SEND/!END 控制
|
|
6
|
+
* - 两种模式: 文本模式 (调试/低带宽, 可 Base64) 与 二进制模式 (默认, 高密度)
|
|
7
|
+
* - 自解压数据块: 数据块自带轻量解码规则 (压缩算法 id + 原始长度), 接收方按规则直接展开
|
|
8
|
+
* - 包结构: [Header 2B] | [DID 验证段 32B] | [指令段 动态] | [数据块 动态] | [CRC32 4B]
|
|
9
|
+
*
|
|
10
|
+
* 诚实标注 (都写进 docs/wiki/efficode.md, 不在这里当已验证结论):
|
|
11
|
+
* - 本文件是**参考实现**: 能真编真解、逐字节回环、畸形包报错;
|
|
12
|
+
* - 语音/声波模式 (ggwave 类) **未实现** —— 只留 `mode` 枚举里的保留位, 编码时显式拒绝;
|
|
13
|
+
* - 链上签名验证 / ECC 临时会话密钥 **规范中** —— 本实现只做 DID 摘要段, 不做签名;
|
|
14
|
+
* - 压缩率/信息密度这类宣传数字一律按**实测**写, 见 scripts/verify-efficode.ts 的真测输出。
|
|
15
|
+
*/
|
|
16
|
+
export const COMPRESSION_IDS = {
|
|
17
|
+
none: 0,
|
|
18
|
+
lz77: 1,
|
|
19
|
+
deflate: 2,
|
|
20
|
+
};
|
|
21
|
+
export const COMPRESSION_BY_ID = {
|
|
22
|
+
0: 'none',
|
|
23
|
+
1: 'lz77',
|
|
24
|
+
2: 'deflate',
|
|
25
|
+
};
|
|
26
|
+
/** 包版本 (Header 高 4 位) */
|
|
27
|
+
export const EFFICODE_VERSION = 1;
|
|
28
|
+
/** DID 段固定长度 (字节) —— 照规范: 32B */
|
|
29
|
+
export const DID_SEGMENT_BYTES = 32;
|
|
30
|
+
/** CRC32 尾段固定长度 (字节) */
|
|
31
|
+
export const CRC_BYTES = 4;
|
|
32
|
+
/** 最短合法包 = Header 2 + 无 DID 段 + 指令段最少 (varint 长度 1 + 一条控制指令 2) + 无数据块 + CRC 4 = 9B
|
|
33
|
+
* (DID 段 32B 是**可选**省略的, 所以不放进来; 带 DID 的包应 ≥ 41B, 由 flags 驱动逐段校验而不是靠这个下限) */
|
|
34
|
+
export const MIN_PACKET_BYTES = 2 + 1 + 2 + CRC_BYTES;
|
|
35
|
+
export class EfficodeError extends Error {
|
|
36
|
+
code;
|
|
37
|
+
/** 出错位置 (字节偏移); 拿不到时为 -1 */
|
|
38
|
+
offset;
|
|
39
|
+
constructor(code, message, offset = -1) {
|
|
40
|
+
super(`${code}: ${message}${offset >= 0 ? ` (offset=${offset})` : ''}`);
|
|
41
|
+
this.name = 'EfficodeError';
|
|
42
|
+
this.code = code;
|
|
43
|
+
this.offset = offset;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -104,6 +104,10 @@ function setLocalManifest(m) {
|
|
|
104
104
|
localManifest.exportments = [];
|
|
105
105
|
if (!('sciences' in m))
|
|
106
106
|
localManifest.sciences = [];
|
|
107
|
+
// 2026-09-28: 交流语言声明同规矩 —— 不给就显式清空, 免得旧的 efficode 声明在对端已经不支持时还留着.
|
|
108
|
+
// (老 manifest 语义不变: 没有 supportedLangs = 没声明 = 自然语言)
|
|
109
|
+
if (!('supportedLangs' in m))
|
|
110
|
+
localManifest.supportedLangs = [];
|
|
107
111
|
// 2026-09-18: 网络脉冲 (只记公开统计; 不落 DID/正文; 统计失败绝不影响主路径)
|
|
108
112
|
try {
|
|
109
113
|
const did = String(localManifest.ownerPublicKey || '');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-manifest-protocol.js","sourceRoot":"","sources":["../../../src/agents/agent-manifest-protocol.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"agent-manifest-protocol.js","sourceRoot":"","sources":["../../../src/agents/agent-manifest-protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* transfer-classify.ts — 转账索引的**纯**部分 (类型 + 分类 + 折算 + 汇总)
|
|
4
|
+
* =========================================================================
|
|
5
|
+
* 为什么单独一个文件: 这两半的**加载代价**完全不同 ——
|
|
6
|
+
* · 本文件: 零依赖 (不 import ethers / 不发 RPC / 不读盘) ⇒ 公开页/快照构建可以**静态**引入;
|
|
7
|
+
* · `transfer-index.ts`: 要 JSON-RPC provider (ethers) 与文件系统 ⇒ 只在**同步**路径上加载。
|
|
8
|
+
* 把纯函数放在这里, network-pulse 才不必为了 `formatUnits` 把 ethers 拖进网页进程。
|
|
9
|
+
*
|
|
10
|
+
* 分类口径 (leo 2026-09-29 实测拍板; **不许**只按"USDC 转到该地址"计数):
|
|
11
|
+
* · `escrow_settlement` from == escrow 合约 → 「escrow 退款/释放」(实测块 51685757 / 51686009
|
|
12
|
+
* 两笔 +0.001 与那两笔 Disputed→Refunded **逐块对应**) —— 钱退回, **不是收入**;
|
|
13
|
+
* · `self_transfer` from ∈ 自己地址集 (可配 ownAddresses) → 「转入(非销售)」;
|
|
14
|
+
* · `external_payment` 其余 → 「外部付款」(与卖方端点台账对上的加标「经 x402 流程」);
|
|
15
|
+
* · `outbound` 关注地址**付出** → 不进「链上转入」计数。
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.TRANSFER_ADDRESS_RE = exports.USDC_BY_CHAIN = exports.ERC20_TRANSFER_TOPIC = exports.TRANSFER_INDEX_SCHEMA_VERSION = void 0;
|
|
19
|
+
exports.formatUnits = formatUnits;
|
|
20
|
+
exports.classifyTransfer = classifyTransfer;
|
|
21
|
+
exports.summarizeTransfers = summarizeTransfers;
|
|
22
|
+
exports.TRANSFER_INDEX_SCHEMA_VERSION = 1;
|
|
23
|
+
/** Transfer(address indexed from, address indexed to, uint256 value) 的 topic0 */
|
|
24
|
+
exports.ERC20_TRANSFER_TOPIC = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';
|
|
25
|
+
/** Base 主网 USDC (缺省 token; 也可由 chain.json 的 tokenAddress / env 覆盖) */
|
|
26
|
+
exports.USDC_BY_CHAIN = {
|
|
27
|
+
8453: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',
|
|
28
|
+
84532: '0x036cbd53842c5426634e7929541ec2318f3dcf7e',
|
|
29
|
+
};
|
|
30
|
+
/** 0x + 40 位十六进制 (地址形状; 与 explorer.ts 的同一套尺子) */
|
|
31
|
+
exports.TRANSFER_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
|
|
32
|
+
/** 原子单位 → 十进制字符串 (纯整数运算, 不经过浮点; 去掉末尾多余的 0) */
|
|
33
|
+
function formatUnits(atomic, decimals) {
|
|
34
|
+
const v = BigInt(typeof atomic === 'bigint' ? atomic : (String(atomic || '0').trim() || '0'));
|
|
35
|
+
const neg = v < 0n;
|
|
36
|
+
const abs = neg ? -v : v;
|
|
37
|
+
const d = Math.max(0, Math.floor(decimals));
|
|
38
|
+
const base = 10n ** BigInt(d);
|
|
39
|
+
const whole = (abs / base).toString();
|
|
40
|
+
const frac = (abs % base).toString().padStart(d, '0').replace(/0+$/, '');
|
|
41
|
+
const out = frac ? `${whole}.${frac}` : whole;
|
|
42
|
+
return neg ? `-${out}` : out;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 一条转账的**分类** (纯函数: 输入事实 + 配置, 输出分类)。
|
|
46
|
+
* 为什么在**读**的时候算而不是写索引时算: 分类规则 / 自己地址集是会变的
|
|
47
|
+
* (把 0xb4cb8009… 认成"自己钱包"之前, 它只是一个外部地址) ⇒ 历史行必须能被重新分类,
|
|
48
|
+
* 而不是把当时的判断固化进索引。索引里只存**链上事实** (from/to/value/块号)。
|
|
49
|
+
*/
|
|
50
|
+
function classifyTransfer(e, cfg) {
|
|
51
|
+
const from = String(e.from || '').toLowerCase();
|
|
52
|
+
const to = String(e.to || '').toLowerCase();
|
|
53
|
+
const watch = new Set((cfg.watchAddresses || []).map((a) => String(a).toLowerCase()));
|
|
54
|
+
if (e.direction === 'out' || (watch.has(from) && !watch.has(to)))
|
|
55
|
+
return 'outbound';
|
|
56
|
+
const escrow = String(cfg.escrowAddress || '').toLowerCase();
|
|
57
|
+
if (escrow && from === escrow)
|
|
58
|
+
return 'escrow_settlement';
|
|
59
|
+
if ((cfg.ownAddresses || []).map((a) => String(a).toLowerCase()).includes(from))
|
|
60
|
+
return 'self_transfer';
|
|
61
|
+
return 'external_payment';
|
|
62
|
+
}
|
|
63
|
+
/** 已落盘转账索引 → 汇总 (纯函数; 不发网络、不读配置以外的东西) */
|
|
64
|
+
function summarizeTransfers(state, cfg) {
|
|
65
|
+
const live = (state.entries || []).filter((e) => !e.suspect);
|
|
66
|
+
const by_class = { escrow_settlement: 0, self_transfer: 0, external_payment: 0 };
|
|
67
|
+
const by_class_atomic = { escrow_settlement: '0', self_transfer: '0', external_payment: '0' };
|
|
68
|
+
let inbound = 0, inboundAtomic = 0n, outbound = 0, outboundAtomic = 0n, pending = 0;
|
|
69
|
+
for (const e of live) {
|
|
70
|
+
if (e.finality === 'observed')
|
|
71
|
+
pending++;
|
|
72
|
+
const v = BigInt(e.value || '0');
|
|
73
|
+
if (e.direction === 'out') {
|
|
74
|
+
outbound++;
|
|
75
|
+
outboundAtomic += v;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
inbound++;
|
|
79
|
+
inboundAtomic += v;
|
|
80
|
+
const c = classifyTransfer(e, cfg);
|
|
81
|
+
if (c !== 'outbound') {
|
|
82
|
+
by_class[c]++;
|
|
83
|
+
by_class_atomic[c] = (BigInt(by_class_atomic[c]) + v).toString();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const decimals = Number.isInteger(state.tokenDecimals) ? state.tokenDecimals : (cfg.tokenDecimals ?? 6);
|
|
87
|
+
return {
|
|
88
|
+
configured: cfg.enabled !== false && !!((state.watchAddresses || cfg.watchAddresses || []).length),
|
|
89
|
+
reason: cfg.reason || '',
|
|
90
|
+
entries: live.length,
|
|
91
|
+
suspects: (state.entries || []).length - live.length,
|
|
92
|
+
inbound, inbound_atomic: inboundAtomic.toString(), inbound_display: formatUnits(inboundAtomic, decimals),
|
|
93
|
+
by_class, by_class_atomic,
|
|
94
|
+
outbound, outbound_atomic: outboundAtomic.toString(),
|
|
95
|
+
token_symbol: state.tokenSymbol || cfg.tokenSymbol || '',
|
|
96
|
+
token_decimals: decimals,
|
|
97
|
+
watch_addresses_count: (state.watchAddresses || cfg.watchAddresses || []).length,
|
|
98
|
+
own_addresses_count: (cfg.ownAddresses || []).length,
|
|
99
|
+
from_block: state.fromBlock,
|
|
100
|
+
last_synced_block: state.lastSyncedBlock,
|
|
101
|
+
last_synced_at: state.lastSyncedAt,
|
|
102
|
+
head_block: state.headBlock,
|
|
103
|
+
pending_observation: pending,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=transfer-classify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transfer-classify.js","sourceRoot":"","sources":["../../../../src/agents/chain/transfer-classify.ts"],"names":[],"mappings":"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"}
|