@twinsearth/agent-universe 2.3.6 → 2.5.6

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/index.js CHANGED
@@ -1,71 +1,7 @@
1
- // index.js
2
- // Agent Universe(智能体宇宙)主入口
1
+ // Agent Universe - 智能体宇宙
3
2
  // 群众化的 AGI 路线,去中心化的智能体共享 & 开源网络
3
+ //
4
+ // 根入口:re-export js/ 完整 SDK 实现。
5
+ // 另有 Rust 核心库 gsn-core(cd gsn-core && cargo build)与 Python SDK (aip-sdk-py)。
4
6
 
5
- const { Keypair } = require('./lib/keychain');
6
- const { AgentCard, Task, TaskStatus } = require('./lib/models');
7
- const { MemoryDHT, ShardedIndex, shardOf } = require('./lib/dht');
8
- const { AgentMarket, Bid, Reputation, MIN_STAKE } = require('./lib/market');
9
- const { McpHttpClient, McpError, MCP_PROTOCOL_VERSION } = require('./lib/mcp');
10
- const aca = require('./lib/aca');
11
-
12
- const version = '2.3.6';
13
-
14
- /**
15
- * AgentUniverse 门面:聚合身份、网络、市场能力
16
- */
17
- class AgentUniverse {
18
- constructor() {
19
- this.identity = Keypair.generate();
20
- this.dht = new MemoryDHT();
21
- this.market = new AgentMarket();
22
- }
23
-
24
- get did() {
25
- return this.identity.did;
26
- }
27
-
28
- /** 注册一张 AgentCard 到本地网络 */
29
- register(card) {
30
- this.dht.put(card.did, card);
31
- return card;
32
- }
33
-
34
- /** 发现某能力的 Agent */
35
- discover(capability) {
36
- return this.market.discoverBySkill(capability);
37
- }
38
- }
39
-
40
- module.exports = {
41
- version,
42
- AgentUniverse,
43
- Keypair,
44
- AgentCard,
45
- Task,
46
- TaskStatus,
47
- MemoryDHT,
48
- ShardedIndex,
49
- shardOf,
50
- AgentMarket,
51
- Bid,
52
- Reputation,
53
- MIN_STAKE,
54
- // MCP
55
- McpHttpClient,
56
- McpError,
57
- MCP_PROTOCOL_VERSION,
58
- // ACA(跨语言对齐身份与协议对象)
59
- AipIdentity: aca.AipIdentity,
60
- buildManifest: aca.buildManifest,
61
- buildEnvelope: aca.buildEnvelope,
62
- buildMessage: aca.buildMessage,
63
- buildReceipt: aca.buildReceipt,
64
- handshakeMessage: aca.handshakeMessage,
65
- proposalMessage: aca.proposalMessage,
66
- receiptMessage: aca.receiptMessage,
67
- verifyManifest: aca.verifyManifest,
68
- verifyMessage: aca.verifyMessage,
69
- verifyReceipt: aca.verifyReceipt,
70
- verifyReceiptResult: aca.verifyReceiptResult,
71
- };
7
+ module.exports = require('./js');
package/js/index.d.ts ADDED
@@ -0,0 +1,209 @@
1
+ // Type definitions for @twinsearth/agent-universe
2
+
3
+ export const version: string;
4
+ export const MIN_STAKE: number;
5
+
6
+ export class Keypair {
7
+ publicKey: string;
8
+ privateKey: string;
9
+ did: string;
10
+ static generate(): Keypair;
11
+ sign(message: string | Buffer): string;
12
+ verify(message: string | Buffer, signatureHex: string): boolean;
13
+ }
14
+
15
+ export class AgentCard {
16
+ did: string;
17
+ name: string;
18
+ capabilities: string[];
19
+ skills: string[];
20
+ version: string;
21
+ stake: number;
22
+ reputation: number;
23
+ static new(opts: { did: string; name: string }): AgentCard;
24
+ withCapability(cap: string): this;
25
+ withSkill(skill: string): this;
26
+ hasCapability(cap: string): boolean;
27
+ }
28
+
29
+ export const TaskStatus: Record<string, string>;
30
+
31
+ export class Task {
32
+ taskId: string;
33
+ goal: string;
34
+ status: string;
35
+ assignee: string | null;
36
+ history: string[];
37
+ constructor(taskId: string, goal: string);
38
+ assign(did: string): this;
39
+ start(): this;
40
+ complete(): this;
41
+ verify(passed: boolean): this;
42
+ settle(): this;
43
+ readonly isTerminal: boolean;
44
+ }
45
+
46
+ export class MemoryDHT {
47
+ put(key: string, value: unknown): void;
48
+ get(key: string): unknown;
49
+ has(key: string): boolean;
50
+ remove(key: string): boolean;
51
+ readonly size: number;
52
+ }
53
+
54
+ export class ShardedIndex {
55
+ constructor(numShards?: number);
56
+ put(key: string, value: unknown): number;
57
+ get(key: string): unknown;
58
+ has(key: string): boolean;
59
+ remove(key: string): boolean;
60
+ readonly size: number;
61
+ distribution(): number[];
62
+ }
63
+
64
+ export function shardOf(key: string, numShards: number): number;
65
+
66
+ export class Bid {
67
+ agentId: string;
68
+ price: number;
69
+ }
70
+
71
+ export class Reputation {
72
+ quality: number;
73
+ speed: number;
74
+ honesty: number;
75
+ availability: number;
76
+ overall(): number;
77
+ }
78
+
79
+ export class AgentMarket {
80
+ agents: Map<string, unknown>;
81
+ tasks: Map<string, Task>;
82
+ deposit(account: string, amount: number): void;
83
+ balance(account: string): number;
84
+ registerAgent(card: AgentCard, stake: number): boolean;
85
+ publishTask(taskId: string, goal: string, budget: number, requester: string): Task;
86
+ submitBid(taskId: string, agentId: string, price: number): boolean;
87
+ matchTask(taskId: string): Bid;
88
+ completeTask(taskId: string, passed?: boolean): Task;
89
+ settle(taskId: string): { paid: number; reason: string };
90
+ slash(agentId: string, amount: number, reason: string): unknown;
91
+ discoverBySkill(skill: string): AgentCard[];
92
+ leaderboard(limit?: number): unknown[];
93
+ conservationCheck(totalDeposits: number): {
94
+ conserved: boolean;
95
+ balanceSum: number;
96
+ totalSlashed: number;
97
+ expected: number;
98
+ };
99
+ }
100
+
101
+ export class AgentUniverse {
102
+ identity: Keypair;
103
+ dht: MemoryDHT;
104
+ market: AgentMarket;
105
+ readonly did: string;
106
+ register(card: AgentCard): AgentCard;
107
+ discover(capability: string): AgentCard[];
108
+ }
109
+
110
+ // ── MCP ──
111
+ export const MCP_PROTOCOL_VERSION: string;
112
+
113
+ export class McpError extends Error {
114
+ code: number;
115
+ }
116
+
117
+ export class McpHttpClient {
118
+ initialized: boolean;
119
+ constructor(baseUrl?: string, path?: string, timeout?: number);
120
+ initialize(): Promise<{
121
+ protocolVersion: string;
122
+ serverInfo: { name: string; version: string };
123
+ }>;
124
+ ping(): Promise<boolean>;
125
+ listTools(): Promise<
126
+ Array<{
127
+ name: string;
128
+ description?: string;
129
+ inputSchema: Record<string, unknown>;
130
+ }>
131
+ >;
132
+ callTool(
133
+ name: string,
134
+ args?: Record<string, unknown>
135
+ ): Promise<{ content: Array<{ type: string; text: string }>; isError?: boolean }>;
136
+ }
137
+
138
+ // ── ACA ──
139
+ export class AipIdentity {
140
+ did: string;
141
+ readonly publicKey: Buffer;
142
+ static generate(): AipIdentity;
143
+ static fromSeed(seed: Buffer | Uint8Array): AipIdentity;
144
+ signObject(obj: Record<string, unknown>): string;
145
+ signInto(obj: Record<string, unknown>): Record<string, unknown>;
146
+ static verifyObject(obj: Record<string, unknown>, rawPub: Buffer): boolean;
147
+ }
148
+
149
+ export function buildManifest(
150
+ identity: AipIdentity,
151
+ name: string,
152
+ capabilities: string[],
153
+ opts?: Record<string, unknown>
154
+ ): Record<string, unknown>;
155
+
156
+ export function buildEnvelope(
157
+ requesterDid: string,
158
+ capability: string,
159
+ outputSpec: string,
160
+ opts?: Record<string, unknown>
161
+ ): Record<string, unknown>;
162
+
163
+ export function buildMessage(
164
+ identity: AipIdentity,
165
+ msgType: string,
166
+ toDid: string,
167
+ payload: unknown
168
+ ): Record<string, unknown>;
169
+
170
+ export function buildReceipt(
171
+ identity: AipIdentity,
172
+ taskId: string,
173
+ result: Buffer,
174
+ opts?: Record<string, unknown>
175
+ ): Record<string, unknown>;
176
+
177
+ export function handshakeMessage(
178
+ identity: AipIdentity,
179
+ manifest: Record<string, unknown>
180
+ ): Record<string, unknown>;
181
+
182
+ export function proposalMessage(
183
+ identity: AipIdentity,
184
+ toDid: string,
185
+ envelope: Record<string, unknown>
186
+ ): Record<string, unknown>;
187
+
188
+ export function receiptMessage(
189
+ identity: AipIdentity,
190
+ toDid: string,
191
+ receipt: Record<string, unknown>
192
+ ): Record<string, unknown>;
193
+
194
+ export function verifyManifest(
195
+ manifest: Record<string, unknown>,
196
+ rawPub: Buffer
197
+ ): boolean;
198
+ export function verifyMessage(
199
+ message: Record<string, unknown>,
200
+ rawPub: Buffer
201
+ ): boolean;
202
+ export function verifyReceipt(
203
+ receipt: Record<string, unknown>,
204
+ rawPub: Buffer
205
+ ): boolean;
206
+ export function verifyReceiptResult(
207
+ receipt: Record<string, unknown>,
208
+ result: Buffer
209
+ ): boolean;
package/js/index.js ADDED
@@ -0,0 +1,71 @@
1
+ // index.js
2
+ // Agent Universe(智能体宇宙)主入口
3
+ // 群众化的 AGI 路线,去中心化的智能体共享 & 开源网络
4
+
5
+ const { Keypair } = require('./lib/keychain');
6
+ const { AgentCard, Task, TaskStatus } = require('./lib/models');
7
+ const { MemoryDHT, ShardedIndex, shardOf } = require('./lib/dht');
8
+ const { AgentMarket, Bid, Reputation, MIN_STAKE } = require('./lib/market');
9
+ const { McpHttpClient, McpError, MCP_PROTOCOL_VERSION } = require('./lib/mcp');
10
+ const aca = require('./lib/aca');
11
+
12
+ const version = '2.5.6';
13
+
14
+ /**
15
+ * AgentUniverse 门面:聚合身份、网络、市场能力
16
+ */
17
+ class AgentUniverse {
18
+ constructor() {
19
+ this.identity = Keypair.generate();
20
+ this.dht = new MemoryDHT();
21
+ this.market = new AgentMarket();
22
+ }
23
+
24
+ get did() {
25
+ return this.identity.did;
26
+ }
27
+
28
+ /** 注册一张 AgentCard 到本地网络 */
29
+ register(card) {
30
+ this.dht.put(card.did, card);
31
+ return card;
32
+ }
33
+
34
+ /** 发现某能力的 Agent */
35
+ discover(capability) {
36
+ return this.market.discoverBySkill(capability);
37
+ }
38
+ }
39
+
40
+ module.exports = {
41
+ version,
42
+ AgentUniverse,
43
+ Keypair,
44
+ AgentCard,
45
+ Task,
46
+ TaskStatus,
47
+ MemoryDHT,
48
+ ShardedIndex,
49
+ shardOf,
50
+ AgentMarket,
51
+ Bid,
52
+ Reputation,
53
+ MIN_STAKE,
54
+ // MCP
55
+ McpHttpClient,
56
+ McpError,
57
+ MCP_PROTOCOL_VERSION,
58
+ // ACA(跨语言对齐身份与协议对象)
59
+ AipIdentity: aca.AipIdentity,
60
+ buildManifest: aca.buildManifest,
61
+ buildEnvelope: aca.buildEnvelope,
62
+ buildMessage: aca.buildMessage,
63
+ buildReceipt: aca.buildReceipt,
64
+ handshakeMessage: aca.handshakeMessage,
65
+ proposalMessage: aca.proposalMessage,
66
+ receiptMessage: aca.receiptMessage,
67
+ verifyManifest: aca.verifyManifest,
68
+ verifyMessage: aca.verifyMessage,
69
+ verifyReceipt: aca.verifyReceipt,
70
+ verifyReceiptResult: aca.verifyReceiptResult,
71
+ };
@@ -129,7 +129,7 @@ function buildManifest(identity, name, capabilities, opts = {}) {
129
129
  const manifest = {
130
130
  did: identity.did,
131
131
  name,
132
- version: opts.version || '2.3.6',
132
+ version: opts.version || '2.5.6',
133
133
  capabilities: [...capabilities],
134
134
  endpoints: opts.endpoints || [],
135
135
  hardware: {
@@ -60,7 +60,7 @@ class McpHttpClient {
60
60
  method: 'initialize',
61
61
  params: {
62
62
  protocolVersion: MCP_PROTOCOL_VERSION,
63
- clientInfo: { name: 'agent-universe-js', version: '2.3.6' },
63
+ clientInfo: { name: 'agent-universe-js', version: '2.5.6' },
64
64
  capabilities: {},
65
65
  },
66
66
  });
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@twinsearth/agent-universe",
3
+ "version": "2.5.6",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "@twinsearth/agent-universe",
9
+ "version": "2.5.6",
10
+ "license": "MIT",
11
+ "engines": {
12
+ "node": ">=18"
13
+ }
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@twinsearth/agent-universe",
3
+ "version": "2.5.6",
4
+ "description": "Agent Universe - 群众化的 AGI 路线,去中心化的智能体共享 & 开源网络。使命:让科技造福全人类!",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "scripts": {
8
+ "test": "node test/test.js"
9
+ },
10
+ "keywords": [
11
+ "agi",
12
+ "agent",
13
+ "p2p",
14
+ "decentralized",
15
+ "swarm",
16
+ "dht",
17
+ "mcp",
18
+ "a2a",
19
+ "agent-market"
20
+ ],
21
+ "author": "TwinsEarth",
22
+ "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/TwinsEarth/agent-universe.git",
26
+ "directory": "js"
27
+ },
28
+ "homepage": "https://github.com/TwinsEarth/agent-universe#readme",
29
+ "bugs": {
30
+ "url": "https://github.com/TwinsEarth/agent-universe/issues"
31
+ },
32
+ "publishConfig": {
33
+ "registry": "https://registry.npmjs.org/"
34
+ },
35
+ "engines": {
36
+ "node": ">=18"
37
+ },
38
+ "files": [
39
+ "index.js",
40
+ "index.d.ts",
41
+ "lib"
42
+ ]
43
+ }
@@ -0,0 +1,224 @@
1
+ // test/test.js
2
+ // Agent Universe JS SDK 测试(8 项)
3
+
4
+ const assert = require('node:assert');
5
+ const {
6
+ version,
7
+ AgentUniverse,
8
+ Keypair,
9
+ AgentCard,
10
+ Task,
11
+ TaskStatus,
12
+ MemoryDHT,
13
+ ShardedIndex,
14
+ shardOf,
15
+ AgentMarket,
16
+ MIN_STAKE,
17
+ AipIdentity,
18
+ buildManifest,
19
+ buildEnvelope,
20
+ proposalMessage,
21
+ buildReceipt,
22
+ verifyManifest,
23
+ verifyMessage,
24
+ verifyReceipt,
25
+ verifyReceiptResult,
26
+ } = require('../index');
27
+
28
+ let passed = 0;
29
+ function test(name, fn) {
30
+ try {
31
+ fn();
32
+ passed++;
33
+ console.log(` ✓ ${name}`);
34
+ } catch (e) {
35
+ console.error(` ✗ ${name}`);
36
+ console.error(` ${e.message}`);
37
+ process.exitCode = 1;
38
+ }
39
+ }
40
+
41
+ console.log('Agent Universe JS SDK 测试\n');
42
+
43
+ // 1. 版本号
44
+ test('版本号为 2.5.6', () => {
45
+ assert.strictEqual(version, '2.5.6');
46
+ });
47
+
48
+ // 2. 密钥对 + DID + 签名验证
49
+ test('Keypair 生成 DID 且签名可验证', () => {
50
+ const kp = Keypair.generate();
51
+ assert.ok(kp.did.startsWith('did:au:'), 'DID 前缀');
52
+ assert.strictEqual(kp.did.length, 'did:au:'.length + 32);
53
+ const msg = 'hello agent universe';
54
+ const sig = kp.sign(msg);
55
+ assert.ok(kp.verify(msg, sig), '签名验证通过');
56
+ assert.ok(!kp.verify('tampered', sig), '篡改消息验证失败');
57
+ });
58
+
59
+ // 3. AgentCard
60
+ test('AgentCard 能力与技能', () => {
61
+ const card = AgentCard.new({ did: 'did:au:abc', name: 'writer' })
62
+ .withCapability('writing')
63
+ .withSkill('translation');
64
+ assert.ok(card.hasCapability('writing'));
65
+ assert.deepStrictEqual(card.toJSON().skills, ['translation']);
66
+ });
67
+
68
+ // 4. Task 状态机
69
+ test('Task 状态机合法流转且拒绝非法转移', () => {
70
+ const t = new Task('t1', 'write doc');
71
+ t.transition(TaskStatus.OPEN);
72
+ t.assign('did:au:worker');
73
+ t.start();
74
+ t.complete();
75
+ t.verify(true);
76
+ t.settle();
77
+ assert.strictEqual(t.status, TaskStatus.SETTLED);
78
+ assert.ok(t.isTerminal);
79
+
80
+ const t2 = new Task('t2', 'bad');
81
+ assert.throws(() => t2.start(), /非法状态转移/);
82
+ });
83
+
84
+ // 5. MemoryDHT
85
+ test('MemoryDHT 存取与前缀查找', () => {
86
+ const dht = new MemoryDHT();
87
+ dht.put('/aip/agent/1', { name: 'a' });
88
+ dht.put('/aip/agent/2', { name: 'b' });
89
+ assert.strictEqual(dht.size, 2);
90
+ assert.strictEqual(dht.get('/aip/agent/1').name, 'a');
91
+ assert.strictEqual(dht.findByPrefix('/aip/agent').length, 2);
92
+ });
93
+
94
+ // 6. ShardedIndex 分片
95
+ test('ShardedIndex 分片落盘且分片号合法', () => {
96
+ const idx = new ShardedIndex(16);
97
+ for (let i = 0; i < 100; i++) {
98
+ const s = idx.put(`key-${i}`, i);
99
+ assert.ok(s >= 0 && s < 16);
100
+ }
101
+ assert.strictEqual(idx.size, 100);
102
+ assert.strictEqual(shardOf('key-0', 16), shardOf('key-0', 16));
103
+ // 分布:100 key 到 16 片,不应有大片为空(概率性,至少覆盖 8 片)
104
+ const nonEmpty = idx.distribution().filter((n) => n > 0).length;
105
+ assert.ok(nonEmpty >= 8, `非空分片 ${nonEmpty} >= 8`);
106
+ });
107
+
108
+ // 7. AgentMarket 端到端 + 守恒
109
+ test('AgentMarket 端到端:注册→发布→投标→匹配→完成→结算→守恒', () => {
110
+ const market = new AgentMarket();
111
+ const owner = 'did:au:owner';
112
+ const requester = 'did:au:requester';
113
+
114
+ // 充值(owner 质押 100,requester 预算 50)
115
+ market.deposit(owner, 100);
116
+ market.deposit(requester, 50);
117
+ const totalDeposits = 150;
118
+
119
+ const card = AgentCard.new({ did: owner, name: 'worker' })
120
+ .withSkill('writing');
121
+ market.registerAgent(card, MIN_STAKE);
122
+
123
+ market.publishTask('task-1', 'write an article', 50, requester);
124
+ market.submitBid('task-1', owner, 40);
125
+ const winner = market.matchTask('task-1');
126
+ assert.strictEqual(winner.agentId, owner);
127
+
128
+ market.completeTask('task-1', true);
129
+ const result = market.settle('task-1');
130
+ assert.strictEqual(result.paid, 40);
131
+
132
+ // 重复结算短路
133
+ const again = market.settle('task-1');
134
+ assert.strictEqual(again.reason, 'already_paid');
135
+
136
+ // 守恒:无罚没,总余额 = 总充值
137
+ const check = market.conservationCheck(totalDeposits);
138
+ assert.ok(check.conserved, `守恒: ${JSON.stringify(check)}`);
139
+ });
140
+
141
+ // 8. 罚没守恒
142
+ test('罚没后守恒:总余额 = 总充值 − 罚没', () => {
143
+ const market = new AgentMarket();
144
+ const owner = 'did:au:bad';
145
+ market.deposit(owner, 200);
146
+ const card = AgentCard.new({ did: owner, name: 'bad' });
147
+ market.registerAgent(card, MIN_STAKE); // 质押 100
148
+
149
+ const slashResult = market.slash(owner, 60, 'fraud');
150
+ assert.strictEqual(slashResult.slashed, 60);
151
+
152
+ const check = market.conservationCheck(200);
153
+ assert.ok(check.conserved, `罚没守恒: ${JSON.stringify(check)}`);
154
+ assert.strictEqual(check.balanceSum, 140);
155
+ });
156
+
157
+ // 9. AipIdentity DID 与签名往返
158
+ test('AipIdentity 生成 did:aip 且签名可验证', () => {
159
+ const id = AipIdentity.generate();
160
+ assert.ok(id.did.startsWith('did:aip:'), 'DID 前缀');
161
+ assert.strictEqual(id.publicKey.length, 32, '原始公钥 32 字节');
162
+ const obj = { did: id.did, name: 't' };
163
+ id.signInto(obj);
164
+ assert.ok(AipIdentity.verifyObject(obj, id.publicKey), '验签通过');
165
+ const tampered = { ...obj, name: 'x' };
166
+ assert.ok(!AipIdentity.verifyObject(tampered, id.publicKey), '篡改拒绝');
167
+ });
168
+
169
+ // 10. 跨语言基准(与 Rust/Python 固定种子一致)
170
+ test('AipIdentity.fromSeed 复算 Rust/Python 基准', () => {
171
+ const id = AipIdentity.fromSeed(Buffer.alloc(32, 1));
172
+ assert.strictEqual(
173
+ id.publicKey.toString('hex'),
174
+ '8a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c'
175
+ );
176
+ assert.strictEqual(id.did, 'did:aip:34750f98bd59fcfc');
177
+ const obj = {
178
+ did: id.did,
179
+ name: 'CrossLang',
180
+ capabilities: ['text-generation', 'mcp'],
181
+ stake: 100,
182
+ };
183
+ const sig = id.signObject(obj);
184
+ assert.strictEqual(
185
+ sig,
186
+ 'e14d3f9e8204ea185ea4ba32a8117f262095ab9dac1352e1a7964ce36d3355c288dd6804ffa7daeb5f6eba9f30428f52702a75fd3efbb6a62555a7f24665da0e'
187
+ );
188
+ });
189
+
190
+ // 11. ACA manifest/message 构造与验签
191
+ test('ACA manifest 与 proposal message 可验签、篡改拒绝', () => {
192
+ const owner = AipIdentity.generate();
193
+ const peer = AipIdentity.generate();
194
+ const manifest = buildManifest(owner, 'Agent1', ['text-generation'], {
195
+ stake: 100,
196
+ mcpToolCount: 3,
197
+ });
198
+ assert.ok(verifyManifest(manifest, owner.publicKey));
199
+ assert.ok(!verifyManifest({ ...manifest, name: 'Fake' }, owner.publicKey));
200
+
201
+ const envelope = buildEnvelope(owner.did, 'text-generation', 'out', {
202
+ budget: 10,
203
+ });
204
+ const message = proposalMessage(owner, peer.did, envelope);
205
+ assert.ok(verifyMessage(message, owner.publicKey));
206
+ assert.ok(!verifyMessage(message, peer.publicKey), '他人公钥拒绝');
207
+ });
208
+
209
+ // 12. Receipt 签名与结果哈希
210
+ test('ACA receipt 签名、结果哈希正反例', () => {
211
+ const owner = AipIdentity.generate();
212
+ const result = Buffer.from('hello result');
213
+ const receipt = buildReceipt(owner, 'task-1', result);
214
+ assert.ok(verifyReceipt(receipt, owner.publicKey));
215
+ assert.ok(verifyReceiptResult(receipt, result));
216
+ assert.ok(!verifyReceiptResult(receipt, Buffer.from('other')));
217
+ });
218
+
219
+ console.log(`\n${passed} 项测试通过`);
220
+ if (process.exitCode === 1) {
221
+ console.error('存在失败测试');
222
+ } else {
223
+ console.log('全部通过');
224
+ }