@f2a/network 0.1.2 → 0.2.0

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.
Files changed (226) hide show
  1. package/README.md +278 -63
  2. package/dist/cli/commands.d.ts.map +1 -1
  3. package/dist/cli/commands.js +29 -2
  4. package/dist/cli/commands.js.map +1 -1
  5. package/dist/cli/config.d.ts +176 -0
  6. package/dist/cli/config.d.ts.map +1 -0
  7. package/dist/cli/config.js +386 -0
  8. package/dist/cli/config.js.map +1 -0
  9. package/dist/cli/daemon.d.ts +54 -0
  10. package/dist/cli/daemon.d.ts.map +1 -0
  11. package/dist/cli/daemon.js +572 -0
  12. package/dist/cli/daemon.js.map +1 -0
  13. package/dist/cli/index.js +90 -16
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cli/init.d.ts +13 -0
  16. package/dist/cli/init.d.ts.map +1 -0
  17. package/dist/cli/init.js +352 -0
  18. package/dist/cli/init.js.map +1 -0
  19. package/dist/core/e2ee-crypto.d.ts +127 -1
  20. package/dist/core/e2ee-crypto.d.ts.map +1 -1
  21. package/dist/core/e2ee-crypto.js +446 -12
  22. package/dist/core/e2ee-crypto.js.map +1 -1
  23. package/dist/core/f2a.d.ts +2 -1
  24. package/dist/core/f2a.d.ts.map +1 -1
  25. package/dist/core/f2a.js +6 -2
  26. package/dist/core/f2a.js.map +1 -1
  27. package/dist/core/identity/encrypted-key-store.d.ts +19 -0
  28. package/dist/core/identity/encrypted-key-store.d.ts.map +1 -0
  29. package/dist/core/identity/encrypted-key-store.js +72 -0
  30. package/dist/core/identity/encrypted-key-store.js.map +1 -0
  31. package/dist/core/identity/identity-manager.d.ts +133 -0
  32. package/dist/core/identity/identity-manager.d.ts.map +1 -0
  33. package/dist/core/identity/identity-manager.js +454 -0
  34. package/dist/core/identity/identity-manager.js.map +1 -0
  35. package/dist/core/identity/index.d.ts +8 -0
  36. package/dist/core/identity/index.d.ts.map +1 -0
  37. package/dist/core/identity/index.js +7 -0
  38. package/dist/core/identity/index.js.map +1 -0
  39. package/dist/core/identity/types.d.ts +70 -0
  40. package/dist/core/identity/types.d.ts.map +1 -0
  41. package/dist/core/identity/types.js +17 -0
  42. package/dist/core/identity/types.js.map +1 -0
  43. package/dist/core/p2p-network.d.ts +26 -0
  44. package/dist/core/p2p-network.d.ts.map +1 -1
  45. package/dist/core/p2p-network.js +434 -105
  46. package/dist/core/p2p-network.js.map +1 -1
  47. package/dist/core/reputation-security.d.ts +15 -0
  48. package/dist/core/reputation-security.d.ts.map +1 -1
  49. package/dist/core/reputation-security.js +73 -3
  50. package/dist/core/reputation-security.js.map +1 -1
  51. package/dist/core/reputation.d.ts +129 -4
  52. package/dist/core/reputation.d.ts.map +1 -1
  53. package/dist/core/reputation.js +294 -1
  54. package/dist/core/reputation.js.map +1 -1
  55. package/dist/core/review-committee.d.ts +2 -2
  56. package/dist/core/review-committee.d.ts.map +1 -1
  57. package/dist/core/review-committee.js +17 -0
  58. package/dist/core/review-committee.js.map +1 -1
  59. package/dist/daemon/control-server.d.ts.map +1 -1
  60. package/dist/daemon/control-server.js +44 -1
  61. package/dist/daemon/control-server.js.map +1 -1
  62. package/dist/daemon/webhook.d.ts +3 -0
  63. package/dist/daemon/webhook.d.ts.map +1 -1
  64. package/dist/daemon/webhook.js +318 -6
  65. package/dist/daemon/webhook.js.map +1 -1
  66. package/dist/index.d.ts +3 -3
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +7 -3
  69. package/dist/index.js.map +1 -1
  70. package/dist/types/index.d.ts +4 -0
  71. package/dist/types/index.d.ts.map +1 -1
  72. package/dist/types/index.js.map +1 -1
  73. package/dist/types/result.d.ts +1 -1
  74. package/dist/types/result.d.ts.map +1 -1
  75. package/dist/types/result.js.map +1 -1
  76. package/dist/utils/crypto-utils.d.ts +17 -0
  77. package/dist/utils/crypto-utils.d.ts.map +1 -0
  78. package/dist/utils/crypto-utils.js +28 -0
  79. package/dist/utils/crypto-utils.js.map +1 -0
  80. package/dist/utils/logger.d.ts +1 -0
  81. package/dist/utils/logger.d.ts.map +1 -1
  82. package/dist/utils/logger.js +9 -3
  83. package/dist/utils/logger.js.map +1 -1
  84. package/dist/utils/rate-limiter.d.ts.map +1 -1
  85. package/dist/utils/rate-limiter.js +3 -1
  86. package/dist/utils/rate-limiter.js.map +1 -1
  87. package/dist/utils/signature.d.ts +47 -1
  88. package/dist/utils/signature.d.ts.map +1 -1
  89. package/dist/utils/signature.js +166 -11
  90. package/dist/utils/signature.js.map +1 -1
  91. package/package.json +9 -1
  92. package/.github/workflows/ci.yml +0 -113
  93. package/.github/workflows/publish.yml +0 -60
  94. package/MONOREPO.md +0 -58
  95. package/SKILL.md +0 -137
  96. package/dist/adapters/openclaw.d.ts +0 -103
  97. package/dist/adapters/openclaw.d.ts.map +0 -1
  98. package/dist/adapters/openclaw.js +0 -297
  99. package/dist/adapters/openclaw.js.map +0 -1
  100. package/dist/core/connection-manager.d.ts +0 -80
  101. package/dist/core/connection-manager.d.ts.map +0 -1
  102. package/dist/core/connection-manager.js +0 -235
  103. package/dist/core/connection-manager.js.map +0 -1
  104. package/dist/core/connection-manager.test.d.ts +0 -2
  105. package/dist/core/connection-manager.test.d.ts.map +0 -1
  106. package/dist/core/connection-manager.test.js +0 -52
  107. package/dist/core/connection-manager.test.js.map +0 -1
  108. package/dist/core/identity.d.ts +0 -47
  109. package/dist/core/identity.d.ts.map +0 -1
  110. package/dist/core/identity.js +0 -130
  111. package/dist/core/identity.js.map +0 -1
  112. package/dist/core/identity.test.d.ts +0 -2
  113. package/dist/core/identity.test.d.ts.map +0 -1
  114. package/dist/core/identity.test.js +0 -43
  115. package/dist/core/identity.test.js.map +0 -1
  116. package/dist/core/serverless.d.ts +0 -155
  117. package/dist/core/serverless.d.ts.map +0 -1
  118. package/dist/core/serverless.js +0 -615
  119. package/dist/core/serverless.js.map +0 -1
  120. package/dist/daemon/webhook.test.d.ts +0 -2
  121. package/dist/daemon/webhook.test.d.ts.map +0 -1
  122. package/dist/daemon/webhook.test.js +0 -24
  123. package/dist/daemon/webhook.test.js.map +0 -1
  124. package/dist/protocol/messages.d.ts +0 -739
  125. package/dist/protocol/messages.d.ts.map +0 -1
  126. package/dist/protocol/messages.js +0 -188
  127. package/dist/protocol/messages.js.map +0 -1
  128. package/dist/protocol/messages.test.d.ts +0 -2
  129. package/dist/protocol/messages.test.d.ts.map +0 -1
  130. package/dist/protocol/messages.test.js +0 -55
  131. package/dist/protocol/messages.test.js.map +0 -1
  132. package/docs/F2A-PROTOCOL.md +0 -61
  133. package/docs/MOBILE_BOOTSTRAP_DESIGN.md +0 -126
  134. package/docs/a2a-lessons.md +0 -316
  135. package/docs/middleware-guide.md +0 -448
  136. package/docs/readme-update-checklist.md +0 -90
  137. package/docs/reputation-guide.md +0 -396
  138. package/docs/rfcs/001-reputation-system.md +0 -712
  139. package/docs/security-design.md +0 -247
  140. package/install.sh +0 -231
  141. package/packages/openclaw-adapter/README.md +0 -510
  142. package/packages/openclaw-adapter/openclaw.plugin.json +0 -106
  143. package/packages/openclaw-adapter/package.json +0 -40
  144. package/packages/openclaw-adapter/src/announcement-queue.test.ts +0 -449
  145. package/packages/openclaw-adapter/src/announcement-queue.ts +0 -403
  146. package/packages/openclaw-adapter/src/capability-detector.test.ts +0 -99
  147. package/packages/openclaw-adapter/src/capability-detector.ts +0 -183
  148. package/packages/openclaw-adapter/src/claim-handlers.test.ts +0 -974
  149. package/packages/openclaw-adapter/src/claim-handlers.ts +0 -482
  150. package/packages/openclaw-adapter/src/connector.business.test.ts +0 -583
  151. package/packages/openclaw-adapter/src/connector.ts +0 -795
  152. package/packages/openclaw-adapter/src/index.test.ts +0 -82
  153. package/packages/openclaw-adapter/src/index.ts +0 -18
  154. package/packages/openclaw-adapter/src/integration.e2e.test.ts +0 -829
  155. package/packages/openclaw-adapter/src/logger.ts +0 -51
  156. package/packages/openclaw-adapter/src/network-client.test.ts +0 -266
  157. package/packages/openclaw-adapter/src/network-client.ts +0 -251
  158. package/packages/openclaw-adapter/src/network-recovery.test.ts +0 -465
  159. package/packages/openclaw-adapter/src/node-manager.test.ts +0 -136
  160. package/packages/openclaw-adapter/src/node-manager.ts +0 -429
  161. package/packages/openclaw-adapter/src/plugin.test.ts +0 -439
  162. package/packages/openclaw-adapter/src/plugin.ts +0 -104
  163. package/packages/openclaw-adapter/src/reputation.test.ts +0 -221
  164. package/packages/openclaw-adapter/src/reputation.ts +0 -368
  165. package/packages/openclaw-adapter/src/task-guard.test.ts +0 -502
  166. package/packages/openclaw-adapter/src/task-guard.ts +0 -860
  167. package/packages/openclaw-adapter/src/task-queue.concurrency.test.ts +0 -462
  168. package/packages/openclaw-adapter/src/task-queue.edge-cases.test.ts +0 -284
  169. package/packages/openclaw-adapter/src/task-queue.persistence.test.ts +0 -408
  170. package/packages/openclaw-adapter/src/task-queue.ts +0 -668
  171. package/packages/openclaw-adapter/src/tool-handlers.test.ts +0 -906
  172. package/packages/openclaw-adapter/src/tool-handlers.ts +0 -574
  173. package/packages/openclaw-adapter/src/types.ts +0 -361
  174. package/packages/openclaw-adapter/src/webhook-pusher.test.ts +0 -188
  175. package/packages/openclaw-adapter/src/webhook-pusher.ts +0 -220
  176. package/packages/openclaw-adapter/src/webhook-server.test.ts +0 -580
  177. package/packages/openclaw-adapter/src/webhook-server.ts +0 -202
  178. package/packages/openclaw-adapter/tsconfig.json +0 -20
  179. package/src/cli/commands.test.ts +0 -157
  180. package/src/cli/commands.ts +0 -129
  181. package/src/cli/index.test.ts +0 -77
  182. package/src/cli/index.ts +0 -234
  183. package/src/core/autonomous-economy.test.ts +0 -291
  184. package/src/core/autonomous-economy.ts +0 -428
  185. package/src/core/e2ee-crypto.test.ts +0 -125
  186. package/src/core/e2ee-crypto.ts +0 -246
  187. package/src/core/f2a.test.ts +0 -269
  188. package/src/core/f2a.ts +0 -618
  189. package/src/core/p2p-network.test.ts +0 -199
  190. package/src/core/p2p-network.ts +0 -1432
  191. package/src/core/reputation-security.test.ts +0 -403
  192. package/src/core/reputation-security.ts +0 -562
  193. package/src/core/reputation.test.ts +0 -260
  194. package/src/core/reputation.ts +0 -576
  195. package/src/core/review-committee.test.ts +0 -380
  196. package/src/core/review-committee.ts +0 -401
  197. package/src/core/token-manager.test.ts +0 -133
  198. package/src/core/token-manager.ts +0 -140
  199. package/src/daemon/control-server.test.ts +0 -216
  200. package/src/daemon/control-server.ts +0 -292
  201. package/src/daemon/index.test.ts +0 -85
  202. package/src/daemon/index.ts +0 -89
  203. package/src/daemon/main.ts +0 -44
  204. package/src/daemon/start.ts +0 -29
  205. package/src/daemon/webhook.test.ts +0 -68
  206. package/src/daemon/webhook.ts +0 -105
  207. package/src/index.test.ts +0 -436
  208. package/src/index.ts +0 -72
  209. package/src/types/index.test.ts +0 -87
  210. package/src/types/index.ts +0 -341
  211. package/src/types/result.ts +0 -68
  212. package/src/utils/benchmark.ts +0 -237
  213. package/src/utils/logger.ts +0 -331
  214. package/src/utils/middleware.ts +0 -229
  215. package/src/utils/rate-limiter.ts +0 -207
  216. package/src/utils/signature.ts +0 -136
  217. package/src/utils/validation.ts +0 -186
  218. package/tests/docker/Dockerfile.node +0 -23
  219. package/tests/docker/Dockerfile.runner +0 -18
  220. package/tests/docker/docker-compose.test.yml +0 -73
  221. package/tests/integration/message-passing.test.ts +0 -109
  222. package/tests/integration/multi-node.test.ts +0 -92
  223. package/tests/integration/p2p-connection.test.ts +0 -83
  224. package/tests/integration/test-config.ts +0 -32
  225. package/tsconfig.json +0 -21
  226. package/vitest.config.ts +0 -26
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * F2A Daemon 入口
4
- */
5
-
6
- import { F2ADaemon } from './index.js';
7
-
8
- // 解析引导节点地址
9
- const bootstrapPeers = process.env.BOOTSTRAP_PEERS
10
- ? process.env.BOOTSTRAP_PEERS.split(',')
11
- : undefined;
12
-
13
- // P2P 端口(默认 0 = 随机分配)
14
- const p2pPort = parseInt(process.env.F2A_P2P_PORT || '0');
15
-
16
- const daemon = new F2ADaemon({
17
- controlPort: parseInt(process.env.F2A_CONTROL_PORT || '9001'),
18
- network: {
19
- listenPort: p2pPort,
20
- bootstrapPeers,
21
- },
22
- });
23
-
24
- // 处理信号
25
- process.on('SIGINT', async () => {
26
- console.log('[Daemon] Received SIGINT, shutting down...');
27
- await daemon.stop();
28
- process.exit(0);
29
- });
30
-
31
- process.on('SIGTERM', async () => {
32
- console.log('[Daemon] Received SIGTERM, shutting down...');
33
- await daemon.stop();
34
- process.exit(0);
35
- });
36
-
37
- // 启动
38
- daemon.start().catch((error) => {
39
- console.error('[Daemon] Failed to start:', error instanceof Error ? error.message : String(error));
40
- if (error instanceof Error && error.stack) {
41
- console.error('[Daemon] Stack trace:', error.stack);
42
- }
43
- process.exit(1);
44
- });
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * F2A Daemon 入口
4
- */
5
-
6
- import { F2ADaemon } from './index.js';
7
-
8
- const daemon = new F2ADaemon({
9
- controlPort: parseInt(process.env.F2A_CONTROL_PORT || '9001'),
10
- });
11
-
12
- // 处理信号
13
- process.on('SIGINT', async () => {
14
- console.log('[Daemon] Received SIGINT, shutting down...');
15
- await daemon.stop();
16
- process.exit(0);
17
- });
18
-
19
- process.on('SIGTERM', async () => {
20
- console.log('[Daemon] Received SIGTERM, shutting down...');
21
- await daemon.stop();
22
- process.exit(0);
23
- });
24
-
25
- // 启动
26
- daemon.start().catch((error) => {
27
- console.error('[Daemon] Failed to start:', error);
28
- process.exit(1);
29
- });
@@ -1,68 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
- import { WebhookService } from './webhook.js';
3
-
4
- describe('WebhookService', () => {
5
- let service: WebhookService;
6
-
7
- beforeEach(() => {
8
- service = new WebhookService({
9
- url: 'http://localhost:8080/hooks',
10
- token: 'test-token'
11
- });
12
- });
13
-
14
- describe('constructor', () => {
15
- it('should create service with default options', () => {
16
- const defaultService = new WebhookService({
17
- url: 'http://localhost:8080/hooks',
18
- token: 'test-token'
19
- });
20
- expect(defaultService).toBeDefined();
21
- });
22
-
23
- it('should create service with custom options', () => {
24
- const customService = new WebhookService({
25
- url: 'http://localhost:8080/hooks',
26
- token: 'test-token',
27
- timeout: 10000,
28
- retries: 5,
29
- retryDelay: 2000
30
- });
31
- expect(customService).toBeDefined();
32
- });
33
- });
34
-
35
- describe('send', () => {
36
- it('should skip notification when token not set', async () => {
37
- const noTokenService = new WebhookService({
38
- url: 'http://localhost:8080/hooks',
39
- token: ''
40
- });
41
-
42
- const result = await noTokenService.send({ message: 'test' });
43
- expect(result.success).toBe(false);
44
- expect(result.error).toBe('Token not set');
45
- });
46
-
47
- it('should send notification with default options', async () => {
48
- // This would make actual HTTP request in real scenario
49
- // For unit test, we just verify it doesn't throw
50
- const result = await service.send({ message: 'test' });
51
- // Result depends on network
52
- });
53
-
54
- it('should send notification with custom options', async () => {
55
- const result = await service.send({
56
- message: 'test message',
57
- name: 'Test Agent',
58
- wakeMode: 'now',
59
- deliver: true
60
- });
61
- });
62
-
63
- it('should handle network errors with retries', async () => {
64
- // Mock would be needed to test retry logic
65
- const result = await service.send({ message: 'test' });
66
- });
67
- });
68
- });
@@ -1,105 +0,0 @@
1
- /**
2
- * Webhook 通知服务
3
- */
4
-
5
- import { request, RequestOptions } from 'https';
6
- import { request as httpRequest } from 'http';
7
- import { WebhookConfig } from '../types/index.js';
8
-
9
- export interface WebhookNotification {
10
- message: string;
11
- name?: string;
12
- wakeMode?: 'now' | 'next-heartbeat';
13
- deliver?: boolean;
14
- }
15
-
16
- export class WebhookService {
17
- private config: WebhookConfig;
18
-
19
- constructor(config: WebhookConfig) {
20
- this.config = {
21
- timeout: 5000,
22
- retries: 3,
23
- retryDelay: 1000,
24
- ...config
25
- };
26
- }
27
-
28
- /**
29
- * 发送通知
30
- */
31
- async send(notification: WebhookNotification): Promise<{ success: boolean; error?: string }> {
32
- if (!this.config.token) {
33
- console.log('[Webhook] Token not set, skipping notification');
34
- return { success: false, error: 'Token not set' };
35
- }
36
-
37
- const payload = JSON.stringify({
38
- message: notification.message,
39
- name: notification.name || 'F2A',
40
- wakeMode: notification.wakeMode || 'now',
41
- deliver: notification.deliver !== false
42
- });
43
-
44
- for (let attempt = 1; attempt <= this.config.retries!; attempt++) {
45
- try {
46
- await this.sendRequest(payload);
47
- console.log(`[Webhook] Notification sent (attempt ${attempt})`);
48
- return { success: true };
49
- } catch (err) {
50
- const message = err instanceof Error ? err.message : String(err);
51
- console.log(`[Webhook] Attempt ${attempt} failed: ${message}`);
52
-
53
- if (attempt < this.config.retries!) {
54
- await this.delay(this.config.retryDelay!);
55
- }
56
- }
57
- }
58
-
59
- return { success: false, error: 'All retries failed' };
60
- }
61
-
62
- /**
63
- * 发送 HTTP 请求
64
- */
65
- private sendRequest(payload: string): Promise<void> {
66
- return new Promise((resolve, reject) => {
67
- const isHttps = this.config.url.startsWith('https');
68
- const client = isHttps ? request : httpRequest;
69
-
70
- const options: RequestOptions = {
71
- method: 'POST',
72
- headers: {
73
- 'Authorization': `Bearer ${this.config.token}`,
74
- 'Content-Type': 'application/json',
75
- 'Content-Length': Buffer.byteLength(payload)
76
- },
77
- timeout: this.config.timeout
78
- };
79
-
80
- const req = client(this.config.url, options, (res) => {
81
- if (res.statusCode === 200 || res.statusCode === 202) {
82
- resolve();
83
- } else {
84
- reject(new Error(`HTTP ${res.statusCode}`));
85
- }
86
- });
87
-
88
- req.on('error', reject);
89
- req.on('timeout', () => {
90
- req.destroy();
91
- reject(new Error('Timeout'));
92
- });
93
-
94
- req.write(payload);
95
- req.end();
96
- });
97
- }
98
-
99
- /**
100
- * 延迟
101
- */
102
- private delay(ms: number): Promise<void> {
103
- return new Promise(resolve => setTimeout(resolve, ms));
104
- }
105
- }
package/src/index.test.ts DELETED
@@ -1,436 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { randomUUID } from 'crypto';
3
- import {
4
- // 核心 P2P 网络
5
- F2A,
6
- P2PNetwork,
7
- TokenManager,
8
- E2EECrypto,
9
- // 信誉系统
10
- ReputationManager,
11
- REPUTATION_TIERS,
12
- ReviewCommittee,
13
- AutonomousEconomy,
14
- // 信誉安全机制
15
- ChainSignatureManager,
16
- InvitationManager,
17
- ChallengeManager,
18
- // 工具模块
19
- Logger,
20
- RateLimiter,
21
- RequestSigner,
22
- createMessageSizeLimitMiddleware,
23
- createMessageTypeFilterMiddleware,
24
- // 类型
25
- type ReputationLevel,
26
- type MiddlewareContext,
27
- // 版本号
28
- VERSION,
29
- } from './index.js';
30
-
31
- // ============================================================================
32
- // 业务场景 1: SDK 导出完整性验证
33
- // 确保用户可以通过 SDK 正确导入所有需要的模块
34
- // ============================================================================
35
- describe('SDK Exports - 用户使用场景', () => {
36
- describe('场景 1.1: 用户创建 F2A 节点', () => {
37
- it('应该能导入 F2A 主类并创建实例', () => {
38
- expect(F2A).toBeDefined();
39
- expect(typeof F2A.create).toBe('function');
40
- });
41
-
42
- it('应该能导入 P2PNetwork 用于底层网络操作', () => {
43
- expect(P2PNetwork).toBeDefined();
44
- expect(typeof P2PNetwork).toBe('function');
45
- });
46
- });
47
-
48
- describe('场景 1.2: 用户配置安全机制', () => {
49
- it('应该能导入 TokenManager 进行认证管理', () => {
50
- expect(TokenManager).toBeDefined();
51
- });
52
-
53
- it('应该能导入 E2EECrypto 进行加密通信', () => {
54
- expect(E2EECrypto).toBeDefined();
55
- });
56
-
57
- it('应该能导入 RequestSigner 进行请求签名', () => {
58
- expect(RequestSigner).toBeDefined();
59
- });
60
- });
61
-
62
- describe('场景 1.3: 用户实现信誉系统', () => {
63
- it('应该能导入 ReputationManager 和等级配置', () => {
64
- expect(ReputationManager).toBeDefined();
65
- expect(REPUTATION_TIERS).toBeDefined();
66
- expect(REPUTATION_TIERS.length).toBe(5); // 5个等级
67
- });
68
-
69
- it('REPUTATION_TIERS 应该包含完整的业务等级定义', () => {
70
- const levels: ReputationLevel[] = ['restricted', 'novice', 'participant', 'contributor', 'core'];
71
- REPUTATION_TIERS.forEach((tier, index) => {
72
- expect(tier.level).toBe(levels[index]);
73
- expect(tier.permissions).toHaveProperty('canPublish');
74
- expect(tier.permissions).toHaveProperty('canExecute');
75
- expect(tier.permissions).toHaveProperty('canReview');
76
- expect(tier.permissions).toHaveProperty('publishPriority');
77
- expect(tier.permissions).toHaveProperty('publishDiscount');
78
- });
79
- });
80
-
81
- it('应该能导入 ReviewCommittee 进行任务评审', () => {
82
- expect(ReviewCommittee).toBeDefined();
83
- });
84
-
85
- it('应该能导入 AutonomousEconomy 进行经济系统管理', () => {
86
- expect(AutonomousEconomy).toBeDefined();
87
- });
88
- });
89
-
90
- describe('场景 1.4: 用户配置网络安全', () => {
91
- it('应该能导入 ChainSignatureManager 进行链式签名', () => {
92
- expect(ChainSignatureManager).toBeDefined();
93
- });
94
-
95
- it('应该能导入 InvitationManager 管理节点邀请', () => {
96
- expect(InvitationManager).toBeDefined();
97
- });
98
-
99
- it('应该能导入 ChallengeManager 进行节点挑战验证', () => {
100
- expect(ChallengeManager).toBeDefined();
101
- });
102
- });
103
-
104
- describe('场景 1.5: 用户配置基础设施', () => {
105
- it('应该能导入 Logger 进行日志记录', () => {
106
- expect(Logger).toBeDefined();
107
- });
108
-
109
- it('应该能导入 RateLimiter 进行速率限制', () => {
110
- expect(RateLimiter).toBeDefined();
111
- });
112
-
113
- it('应该能导入中间件工厂函数', () => {
114
- expect(createMessageSizeLimitMiddleware).toBeDefined();
115
- expect(createMessageTypeFilterMiddleware).toBeDefined();
116
- });
117
- });
118
- });
119
-
120
- // ============================================================================
121
- // 业务场景 2: 真实业务功能验证
122
- // 测试模块在真实业务场景中的工作能力
123
- // ============================================================================
124
- describe('SDK Integration - 真实业务场景', () => {
125
- describe('场景 2.1: 信誉管理业务流程', () => {
126
- it('应该能获取新节点的初始信誉分(默认70分)', () => {
127
- const reputationManager = new ReputationManager();
128
- const peerId = 'peer-' + Date.now() + '-' + Math.random();
129
- const initialRep = reputationManager.getReputation(peerId);
130
- expect(initialRep.score).toBe(70); // 默认初始分是70
131
- expect(initialRep.level).toBe('contributor'); // 70分对应contributor等级
132
- });
133
-
134
- it('应该能记录任务成功并改变信誉分', () => {
135
- // 使用自定义配置创建新的管理器,避免状态污染
136
- const reputationManager = new ReputationManager({
137
- initialScore: 50,
138
- alpha: 0.3,
139
- minScore: 0,
140
- maxScore: 100,
141
- maxHistory: 100,
142
- });
143
- const peerId = 'peer-' + randomUUID();
144
-
145
- // 先获取初始状态(会创建条目,分数为50)
146
- const initialRep = reputationManager.getReputation(peerId);
147
- expect(initialRep.score).toBe(50);
148
- // 记录初始历史长度(getReputation 会创建 'initial' 记录)
149
- const initialHistoryLength = initialRep.history.length;
150
-
151
- // 记录成功,delta=10
152
- reputationManager.recordSuccess(peerId, 'task-1', 10);
153
- const updatedRep = reputationManager.getReputation(peerId);
154
-
155
- // EWMA 算法: newScore = 0.3 * (50 + 10) + 0.7 * 50 = 53
156
- // 验证分数确实增加了
157
- expect(updatedRep.score).toBe(53);
158
- expect(updatedRep.score).toBeGreaterThan(50);
159
-
160
- // 验证历史记录增加了
161
- expect(updatedRep.history.length).toBe(initialHistoryLength + 1);
162
- expect(updatedRep.history[updatedRep.history.length - 1].type).toBe('task_success');
163
- });
164
-
165
- it('应该能根据信誉分判断权限', () => {
166
- const reputationManager = new ReputationManager();
167
- const peerId = 'peer-' + Date.now() + '-' + Math.random();
168
- // 默认70分为 contributor 等级,拥有所有权限
169
- expect(reputationManager.hasPermission(peerId, 'publish')).toBe(true);
170
- expect(reputationManager.hasPermission(peerId, 'execute')).toBe(true);
171
- expect(reputationManager.hasPermission(peerId, 'review')).toBe(true);
172
- });
173
-
174
- it('应该能获取信誉等级', () => {
175
- const reputationManager = new ReputationManager();
176
- const tier = reputationManager.getTier(75);
177
- expect(tier.level).toBe('contributor');
178
- expect(tier.permissions.canPublish).toBe(true);
179
- });
180
-
181
- it('应该能记录任务失败并改变信誉分', () => {
182
- // 使用自定义配置创建新的管理器,避免状态污染
183
- const reputationManager = new ReputationManager({
184
- initialScore: 50,
185
- alpha: 0.3,
186
- minScore: 0,
187
- maxScore: 100,
188
- maxHistory: 100,
189
- });
190
- const peerId = 'peer-' + randomUUID();
191
-
192
- // 使用默认的 delta (-20) 或传入负数
193
- reputationManager.recordFailure(peerId, 'task-fail', 'timeout');
194
- const updatedRep = reputationManager.getReputation(peerId);
195
- // 默认 delta 为 -20,EWMA: newScore = 0.3 * (50 - 20) + 0.7 * 50 = 44
196
- expect(updatedRep.score).toBeLessThan(50);
197
- });
198
-
199
- it('应该能获取发布优先级和折扣(根据实际等级)', () => {
200
- const reputationManager = new ReputationManager();
201
- const peerId = 'peer-' + Date.now() + '-' + Math.random();
202
- // 默认70分为 contributor 等级,优先级为3,折扣90%
203
- expect(reputationManager.getPublishPriority(peerId)).toBe(3);
204
- expect(reputationManager.getPublishDiscount(peerId)).toBe(0.9);
205
- });
206
-
207
- it('应该能获取高信誉节点列表', () => {
208
- const reputationManager = new ReputationManager();
209
- const peerA = 'peer-a-' + Date.now() + '-' + Math.random();
210
- const peerB = 'peer-b-' + Date.now() + '-' + Math.random();
211
-
212
- // 提升 peerA 的信誉
213
- reputationManager.recordSuccess(peerA, 'task-1', 20);
214
- reputationManager.recordSuccess(peerA, 'task-2', 20);
215
-
216
- // peerB 保持默认
217
-
218
- const highRepNodes = reputationManager.getHighReputationNodes(80);
219
- const highRepPeerIds = highRepNodes.map(n => n.peerId);
220
- expect(highRepPeerIds).toContain(peerA);
221
- });
222
- });
223
-
224
- describe('场景 2.2: 速率限制业务流程', () => {
225
- let rateLimiter: RateLimiter;
226
-
227
- beforeEach(() => {
228
- rateLimiter = new RateLimiter({ windowMs: 1000, maxRequests: 3 });
229
- });
230
-
231
- afterEach(() => {
232
- rateLimiter.stop();
233
- });
234
-
235
- it('应该允许在限制内的请求', () => {
236
- const clientId = 'client-' + Date.now() + '-' + Math.random();
237
- expect(rateLimiter.allowRequest(clientId)).toBe(true);
238
- expect(rateLimiter.allowRequest(clientId)).toBe(true);
239
- expect(rateLimiter.allowRequest(clientId)).toBe(true);
240
- });
241
-
242
- it('应该拒绝超出限制的请求', () => {
243
- const clientId = 'client-' + Date.now() + '-' + Math.random();
244
- rateLimiter.allowRequest(clientId);
245
- rateLimiter.allowRequest(clientId);
246
- rateLimiter.allowRequest(clientId);
247
- expect(rateLimiter.allowRequest(clientId)).toBe(false);
248
- });
249
-
250
- it('应该能查询剩余令牌数', () => {
251
- const clientId = 'client-' + Date.now() + '-' + Math.random();
252
- expect(rateLimiter.getRemainingTokens(clientId)).toBe(3);
253
- rateLimiter.allowRequest(clientId);
254
- expect(rateLimiter.getRemainingTokens(clientId)).toBe(2);
255
- });
256
-
257
- it('应该能重置限制', () => {
258
- const clientId = 'client-' + Date.now() + '-' + Math.random();
259
- rateLimiter.allowRequest(clientId);
260
- rateLimiter.allowRequest(clientId);
261
- rateLimiter.allowRequest(clientId);
262
- expect(rateLimiter.allowRequest(clientId)).toBe(false);
263
-
264
- rateLimiter.reset(clientId);
265
- expect(rateLimiter.allowRequest(clientId)).toBe(true);
266
- });
267
- });
268
-
269
- describe('场景 2.3: 请求签名业务流程', () => {
270
- it('应该能签名和验证请求', () => {
271
- const signer = new RequestSigner({ secretKey: 'my-secret-key' });
272
- const payload = JSON.stringify({ action: 'publish', data: 'test' });
273
-
274
- const signedMessage = signer.sign(payload);
275
- expect(signedMessage).toBeDefined();
276
- expect(signedMessage.signature).toBeDefined();
277
- expect(signedMessage.timestamp).toBeDefined();
278
- expect(signedMessage.nonce).toBeDefined();
279
-
280
- const result = signer.verify(signedMessage);
281
- expect(result.valid).toBe(true);
282
- });
283
-
284
- it('应该拒绝篡改后的请求', () => {
285
- const signer = new RequestSigner({ secretKey: 'my-secret-key' });
286
- const payload = JSON.stringify({ action: 'publish', data: 'test' });
287
- const signedMessage = signer.sign(payload);
288
-
289
- // 篡改 payload
290
- signedMessage.payload = JSON.stringify({ action: 'publish', data: 'tampered' });
291
- const result = signer.verify(signedMessage);
292
- expect(result.valid).toBe(false);
293
- });
294
- });
295
-
296
- describe('场景 2.4: 日志记录业务流程', () => {
297
- it('应该能创建带组件标识的日志记录器', () => {
298
- const logger = new Logger({ component: 'TestService' });
299
- expect(logger).toBeInstanceOf(Logger);
300
-
301
- // 验证日志方法存在且可调用
302
- expect(() => logger.info('test message')).not.toThrow();
303
- expect(() => logger.error('error message')).not.toThrow();
304
- expect(() => logger.warn('warning message')).not.toThrow();
305
- expect(() => logger.debug('debug message')).not.toThrow();
306
- });
307
- });
308
-
309
- describe('场景 2.5: 中间件业务流程', () => {
310
- it('消息大小限制中间件应该能拦截大消息', async () => {
311
- const middleware = createMessageSizeLimitMiddleware(100);
312
- const context: MiddlewareContext = {
313
- message: {
314
- id: 'msg-1',
315
- type: 'task',
316
- payload: { data: 'x'.repeat(200) }, // 大消息
317
- timestamp: Date.now(),
318
- },
319
- peerId: 'peer-1',
320
- metadata: new Map(),
321
- };
322
-
323
- const result = await middleware.process(context);
324
- expect(result.action).toBe('drop');
325
- });
326
-
327
- it('消息类型过滤中间件应该能过滤不允许的类型', async () => {
328
- const middleware = createMessageTypeFilterMiddleware(['task', 'response']);
329
- const context: MiddlewareContext = {
330
- message: {
331
- id: 'msg-2',
332
- type: 'unknown-type',
333
- payload: {},
334
- timestamp: Date.now(),
335
- },
336
- peerId: 'peer-1',
337
- metadata: new Map(),
338
- };
339
-
340
- const result = await middleware.process(context);
341
- expect(result.action).toBe('drop');
342
- });
343
-
344
- it('允许的消息应该继续处理', async () => {
345
- const middleware = createMessageTypeFilterMiddleware(['task', 'response']);
346
- const context: MiddlewareContext = {
347
- message: {
348
- id: 'msg-3',
349
- type: 'task',
350
- payload: {},
351
- timestamp: Date.now(),
352
- },
353
- peerId: 'peer-1',
354
- metadata: new Map(),
355
- };
356
-
357
- const result = await middleware.process(context);
358
- expect(result.action).toBe('continue');
359
- });
360
- });
361
-
362
- describe('场景 2.6: 评审委员会业务流程', () => {
363
- it('应该能创建评审委员会', () => {
364
- const reputationManager = new ReputationManager();
365
- const committee = new ReviewCommittee({
366
- reputationManager,
367
- minReviewers: 2,
368
- maxReviewers: 5,
369
- reviewTimeout: 5000,
370
- });
371
-
372
- expect(committee).toBeInstanceOf(ReviewCommittee);
373
- });
374
- });
375
-
376
- describe('场景 2.7: 自治经济系统业务流程', () => {
377
- it('应该能创建经济系统', () => {
378
- const reputationManager = new ReputationManager();
379
- const economy = new AutonomousEconomy({
380
- reputationManager,
381
- baseTaskCost: 10,
382
- complexityMultiplier: 1.5,
383
- });
384
-
385
- expect(economy).toBeInstanceOf(AutonomousEconomy);
386
- });
387
- });
388
-
389
- describe('场景 2.8: 邀请管理业务流程', () => {
390
- it('应该能创建邀请管理器', () => {
391
- const reputationManager = new ReputationManager();
392
- const invitationManager = new InvitationManager({
393
- reputationManager,
394
- minInviterReputation: 60,
395
- });
396
-
397
- expect(invitationManager).toBeInstanceOf(InvitationManager);
398
- });
399
- });
400
-
401
- describe('场景 2.9: 挑战管理业务流程', () => {
402
- it('应该能创建挑战管理器', () => {
403
- const reputationManager = new ReputationManager();
404
- const challengeManager = new ChallengeManager({
405
- reputationManager,
406
- });
407
-
408
- expect(challengeManager).toBeInstanceOf(ChallengeManager);
409
- });
410
- });
411
-
412
- describe('场景 2.10: 链式签名业务流程', () => {
413
- it('应该能创建链式签名管理器', () => {
414
- const signatureManager = new ChainSignatureManager();
415
- expect(signatureManager).toBeInstanceOf(ChainSignatureManager);
416
- });
417
- });
418
- });
419
-
420
- // ============================================================================
421
- // 业务场景 3: 版本和兼容性
422
- // ============================================================================
423
- describe('SDK Version - 版本管理', () => {
424
- it('应该导出有效的语义化版本号', () => {
425
- expect(VERSION).toBeDefined();
426
- expect(typeof VERSION).toBe('string');
427
- expect(VERSION).toMatch(/^\d+\.\d+\.\d+$/);
428
- });
429
-
430
- it('版本号应该符合当前发布版本', () => {
431
- const [major, minor, patch] = VERSION.split('.').map(Number);
432
- expect(major).toBeGreaterThanOrEqual(1);
433
- expect(minor).toBeGreaterThanOrEqual(0);
434
- expect(patch).toBeGreaterThanOrEqual(0);
435
- });
436
- });