@antseed/node 0.1.0 → 0.1.2

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 (140) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +7 -5
  3. package/dist/discovery/http-metadata-resolver.d.ts +6 -0
  4. package/dist/discovery/http-metadata-resolver.d.ts.map +1 -1
  5. package/dist/discovery/http-metadata-resolver.js +32 -4
  6. package/dist/discovery/http-metadata-resolver.js.map +1 -1
  7. package/dist/discovery/peer-lookup.d.ts +1 -0
  8. package/dist/discovery/peer-lookup.d.ts.map +1 -1
  9. package/dist/discovery/peer-lookup.js +10 -25
  10. package/dist/discovery/peer-lookup.js.map +1 -1
  11. package/dist/index.d.ts +2 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +1 -1
  14. package/dist/index.js.map +1 -1
  15. package/dist/interfaces/seller-provider.d.ts +13 -1
  16. package/dist/interfaces/seller-provider.d.ts.map +1 -1
  17. package/dist/node.d.ts +13 -3
  18. package/dist/node.d.ts.map +1 -1
  19. package/dist/node.js +146 -21
  20. package/dist/node.js.map +1 -1
  21. package/dist/proxy/proxy-mux.d.ts +3 -1
  22. package/dist/proxy/proxy-mux.d.ts.map +1 -1
  23. package/dist/proxy/proxy-mux.js +9 -5
  24. package/dist/proxy/proxy-mux.js.map +1 -1
  25. package/dist/types/http.d.ts +1 -0
  26. package/dist/types/http.d.ts.map +1 -1
  27. package/dist/types/http.js +1 -1
  28. package/dist/types/http.js.map +1 -1
  29. package/package.json +14 -10
  30. package/contracts/AntseedEscrow.sol +0 -310
  31. package/contracts/MockUSDC.sol +0 -64
  32. package/contracts/README.md +0 -102
  33. package/src/config/encryption.test.ts +0 -49
  34. package/src/config/encryption.ts +0 -53
  35. package/src/config/plugin-config-manager.test.ts +0 -92
  36. package/src/config/plugin-config-manager.ts +0 -153
  37. package/src/config/plugin-loader.ts +0 -90
  38. package/src/discovery/announcer.ts +0 -169
  39. package/src/discovery/bootstrap.ts +0 -57
  40. package/src/discovery/default-metadata-resolver.ts +0 -18
  41. package/src/discovery/dht-health.ts +0 -136
  42. package/src/discovery/dht-node.ts +0 -191
  43. package/src/discovery/http-metadata-resolver.ts +0 -47
  44. package/src/discovery/index.ts +0 -15
  45. package/src/discovery/metadata-codec.ts +0 -453
  46. package/src/discovery/metadata-resolver.ts +0 -7
  47. package/src/discovery/metadata-server.ts +0 -73
  48. package/src/discovery/metadata-validator.ts +0 -172
  49. package/src/discovery/peer-lookup.ts +0 -122
  50. package/src/discovery/peer-metadata.ts +0 -34
  51. package/src/discovery/peer-selector.ts +0 -134
  52. package/src/discovery/profile-manager.ts +0 -131
  53. package/src/discovery/profile-search.ts +0 -100
  54. package/src/discovery/reputation-verifier.ts +0 -54
  55. package/src/index.ts +0 -61
  56. package/src/interfaces/buyer-router.ts +0 -21
  57. package/src/interfaces/plugin.ts +0 -36
  58. package/src/interfaces/seller-provider.ts +0 -81
  59. package/src/metering/index.ts +0 -6
  60. package/src/metering/receipt-generator.ts +0 -105
  61. package/src/metering/receipt-verifier.ts +0 -102
  62. package/src/metering/session-tracker.ts +0 -145
  63. package/src/metering/storage.ts +0 -600
  64. package/src/metering/token-counter.ts +0 -127
  65. package/src/metering/usage-aggregator.ts +0 -236
  66. package/src/node.ts +0 -1698
  67. package/src/p2p/connection-auth.ts +0 -152
  68. package/src/p2p/connection-manager.ts +0 -916
  69. package/src/p2p/handshake.ts +0 -162
  70. package/src/p2p/ice-config.ts +0 -59
  71. package/src/p2p/identity.ts +0 -110
  72. package/src/p2p/index.ts +0 -11
  73. package/src/p2p/keepalive.ts +0 -118
  74. package/src/p2p/message-protocol.ts +0 -171
  75. package/src/p2p/nat-traversal.ts +0 -169
  76. package/src/p2p/payment-codec.ts +0 -165
  77. package/src/p2p/payment-mux.ts +0 -153
  78. package/src/p2p/reconnect.ts +0 -117
  79. package/src/payments/balance-manager.ts +0 -77
  80. package/src/payments/buyer-payment-manager.ts +0 -414
  81. package/src/payments/disputes.ts +0 -72
  82. package/src/payments/evm/escrow-client.ts +0 -263
  83. package/src/payments/evm/keypair.ts +0 -31
  84. package/src/payments/evm/signatures.ts +0 -103
  85. package/src/payments/evm/wallet.ts +0 -42
  86. package/src/payments/index.ts +0 -50
  87. package/src/payments/settlement.ts +0 -40
  88. package/src/payments/types.ts +0 -79
  89. package/src/proxy/index.ts +0 -3
  90. package/src/proxy/provider-detection.ts +0 -78
  91. package/src/proxy/proxy-mux.ts +0 -173
  92. package/src/proxy/request-codec.ts +0 -294
  93. package/src/reputation/index.ts +0 -6
  94. package/src/reputation/rating-manager.ts +0 -118
  95. package/src/reputation/report-manager.ts +0 -91
  96. package/src/reputation/trust-engine.ts +0 -120
  97. package/src/reputation/trust-score.ts +0 -74
  98. package/src/reputation/uptime-tracker.ts +0 -155
  99. package/src/routing/default-router.ts +0 -75
  100. package/src/types/bittorrent-dht.d.ts +0 -19
  101. package/src/types/buyer.ts +0 -37
  102. package/src/types/capability.ts +0 -34
  103. package/src/types/connection.ts +0 -29
  104. package/src/types/http.ts +0 -20
  105. package/src/types/index.ts +0 -14
  106. package/src/types/metering.ts +0 -175
  107. package/src/types/nat-api.d.ts +0 -29
  108. package/src/types/peer-profile.ts +0 -25
  109. package/src/types/peer.ts +0 -62
  110. package/src/types/plugin-config.ts +0 -31
  111. package/src/types/protocol.ts +0 -162
  112. package/src/types/provider.ts +0 -40
  113. package/src/types/rating.ts +0 -23
  114. package/src/types/report.ts +0 -30
  115. package/src/types/seller.ts +0 -38
  116. package/src/types/staking.ts +0 -23
  117. package/src/utils/debug.ts +0 -30
  118. package/src/utils/hex.ts +0 -14
  119. package/tests/balance-manager.test.ts +0 -156
  120. package/tests/bootstrap.test.ts +0 -108
  121. package/tests/buyer-payment-manager.test.ts +0 -358
  122. package/tests/connection-auth.test.ts +0 -87
  123. package/tests/default-router.test.ts +0 -148
  124. package/tests/evm-keypair.test.ts +0 -173
  125. package/tests/identity.test.ts +0 -133
  126. package/tests/message-protocol.test.ts +0 -212
  127. package/tests/metadata-codec.test.ts +0 -165
  128. package/tests/metadata-validator.test.ts +0 -261
  129. package/tests/metering-storage.test.ts +0 -244
  130. package/tests/payment-codec.test.ts +0 -95
  131. package/tests/payment-mux.test.ts +0 -191
  132. package/tests/peer-selector.test.ts +0 -184
  133. package/tests/provider-detection.test.ts +0 -107
  134. package/tests/proxy-mux-security.test.ts +0 -38
  135. package/tests/receipt.test.ts +0 -215
  136. package/tests/reputation-integration.test.ts +0 -195
  137. package/tests/request-codec.test.ts +0 -144
  138. package/tests/token-counter.test.ts +0 -122
  139. package/tsconfig.json +0 -9
  140. package/vitest.config.ts +0 -7
@@ -1,173 +0,0 @@
1
- import { MessageType, type FramedMessage } from "../types/protocol.js";
2
- import type { PeerConnection } from "../p2p/connection-manager.js";
3
- import { encodeFrame } from "../p2p/message-protocol.js";
4
- import {
5
- encodeHttpRequest,
6
- decodeHttpRequest,
7
- encodeHttpResponse,
8
- decodeHttpResponse,
9
- encodeHttpResponseChunk,
10
- decodeHttpResponseChunk,
11
- } from "./request-codec.js";
12
- import type {
13
- SerializedHttpRequest,
14
- SerializedHttpResponse,
15
- SerializedHttpResponseChunk,
16
- } from "../types/http.js";
17
-
18
- type ResponseHandler = (response: SerializedHttpResponse) => void;
19
- type ChunkHandler = (chunk: SerializedHttpResponseChunk) => void;
20
- type RequestHandler = (request: SerializedHttpRequest) => void | Promise<void>;
21
-
22
- /**
23
- * Request/response multiplexer over DataChannel.
24
- * Handles both buyer-side and seller-side proxy communication.
25
- */
26
- export class ProxyMux {
27
- private readonly _connection: PeerConnection;
28
- private _messageIdCounter = 0;
29
-
30
- // Buyer side: pending requests awaiting responses
31
- private readonly _responseHandlers = new Map<string, ResponseHandler>();
32
- private readonly _chunkHandlers = new Map<string, ChunkHandler>();
33
-
34
- // Seller side: handler for incoming proxy requests
35
- private _requestHandler: RequestHandler | null = null;
36
-
37
- constructor(connection: PeerConnection) {
38
- this._connection = connection;
39
- }
40
-
41
- /** Buyer side: send a proxy request and register response/chunk handlers. */
42
- sendProxyRequest(
43
- request: SerializedHttpRequest,
44
- onResponse: ResponseHandler,
45
- onChunk: ChunkHandler
46
- ): void {
47
- this._responseHandlers.set(request.requestId, onResponse);
48
- this._chunkHandlers.set(request.requestId, onChunk);
49
-
50
- const payload = encodeHttpRequest(request);
51
- const frame = encodeFrame({
52
- type: MessageType.HttpRequest,
53
- messageId: this._nextMessageId(),
54
- payload,
55
- });
56
-
57
- this._connection.send(frame);
58
- }
59
-
60
- /** Buyer side: cancel handlers for an in-flight request. */
61
- cancelProxyRequest(requestId: string): void {
62
- this._responseHandlers.delete(requestId);
63
- this._chunkHandlers.delete(requestId);
64
- }
65
-
66
- /** Seller side: register a handler for incoming proxy requests. */
67
- onProxyRequest(handler: RequestHandler): void {
68
- this._requestHandler = handler;
69
- }
70
-
71
- /** Seller side: send a complete proxy response. */
72
- sendProxyResponse(response: SerializedHttpResponse): void {
73
- const payload = encodeHttpResponse(response);
74
- const frame = encodeFrame({
75
- type: MessageType.HttpResponse,
76
- messageId: this._nextMessageId(),
77
- payload,
78
- });
79
-
80
- this._connection.send(frame);
81
- }
82
-
83
- /** Seller side: send a proxy response chunk. */
84
- sendProxyChunk(chunk: SerializedHttpResponseChunk): void {
85
- const type = chunk.done
86
- ? MessageType.HttpResponseEnd
87
- : MessageType.HttpResponseChunk;
88
-
89
- const payload = encodeHttpResponseChunk(chunk);
90
- const frame = encodeFrame({
91
- type,
92
- messageId: this._nextMessageId(),
93
- payload,
94
- });
95
-
96
- this._connection.send(frame);
97
- }
98
-
99
- /** Route an incoming frame to the correct handler based on message type. */
100
- async handleFrame(frame: FramedMessage): Promise<void> {
101
- try {
102
- switch (frame.type) {
103
- case MessageType.HttpRequest: {
104
- // Seller side: incoming request from buyer
105
- if (this._requestHandler) {
106
- const request = decodeHttpRequest(frame.payload);
107
- await this._requestHandler(request);
108
- }
109
- break;
110
- }
111
- case MessageType.HttpResponse: {
112
- // Buyer side: complete response from seller
113
- const response = decodeHttpResponse(frame.payload);
114
- const handler = this._responseHandlers.get(response.requestId);
115
- if (handler) {
116
- this._responseHandlers.delete(response.requestId);
117
- this._chunkHandlers.delete(response.requestId);
118
- handler(response);
119
- }
120
- break;
121
- }
122
- case MessageType.HttpResponseChunk: {
123
- // Buyer side: streaming chunk from seller
124
- const chunk = decodeHttpResponseChunk(frame.payload);
125
- const chunkHandler = this._chunkHandlers.get(chunk.requestId);
126
- if (chunkHandler) {
127
- chunkHandler(chunk);
128
- }
129
- break;
130
- }
131
- case MessageType.HttpResponseEnd: {
132
- // Buyer side: final chunk (done=true) from seller
133
- const endChunk = decodeHttpResponseChunk(frame.payload);
134
- const endHandler = this._chunkHandlers.get(endChunk.requestId);
135
- if (endHandler) {
136
- endHandler(endChunk);
137
- this._responseHandlers.delete(endChunk.requestId);
138
- this._chunkHandlers.delete(endChunk.requestId);
139
- }
140
- break;
141
- }
142
- case MessageType.HttpResponseError: {
143
- // Buyer side: error response from seller
144
- const errorResponse = decodeHttpResponse(frame.payload);
145
- const errorHandler = this._responseHandlers.get(errorResponse.requestId);
146
- if (errorHandler) {
147
- this._responseHandlers.delete(errorResponse.requestId);
148
- this._chunkHandlers.delete(errorResponse.requestId);
149
- errorHandler(errorResponse);
150
- }
151
- break;
152
- }
153
- default:
154
- // Unknown message type — ignore
155
- break;
156
- }
157
- } catch (err) {
158
- const message = err instanceof Error ? err.message : String(err);
159
- throw new Error(`Failed to handle proxy frame type ${frame.type}: ${message}`);
160
- }
161
- }
162
-
163
- /** Number of in-flight requests (buyer side). */
164
- activeRequestCount(): number {
165
- return this._responseHandlers.size;
166
- }
167
-
168
- private _nextMessageId(): number {
169
- const id = this._messageIdCounter;
170
- this._messageIdCounter = (this._messageIdCounter + 1) & 0xFFFFFFFF;
171
- return id;
172
- }
173
- }
@@ -1,294 +0,0 @@
1
- import type {
2
- SerializedHttpRequest,
3
- SerializedHttpResponse,
4
- SerializedHttpResponseChunk,
5
- } from "../types/http.js";
6
-
7
- const encoder = new TextEncoder();
8
- const decoder = new TextDecoder();
9
-
10
- /**
11
- * Encode an HTTP request into binary format:
12
- * [requestIdLen:2][requestId:N][methodLen:1][method:N][pathLen:2][path:N]
13
- * [headerCount:2][for each header: keyLen:2, key:N, valLen:2, val:N]
14
- * [bodyLen:4][body:N]
15
- */
16
- export function encodeHttpRequest(req: SerializedHttpRequest): Uint8Array {
17
- const requestIdBytes = encoder.encode(req.requestId);
18
- const methodBytes = encoder.encode(req.method);
19
- const pathBytes = encoder.encode(req.path);
20
-
21
- const headerEntries = Object.entries(req.headers);
22
- const encodedHeaders: Array<{ key: Uint8Array; val: Uint8Array }> = [];
23
- let headersSize = 0;
24
- for (const [key, val] of headerEntries) {
25
- const keyBytes = encoder.encode(key);
26
- const valBytes = encoder.encode(val);
27
- encodedHeaders.push({ key: keyBytes, val: valBytes });
28
- headersSize += 2 + keyBytes.length + 2 + valBytes.length;
29
- }
30
-
31
- const totalSize =
32
- 2 + requestIdBytes.length +
33
- 1 + methodBytes.length +
34
- 2 + pathBytes.length +
35
- 2 + headersSize +
36
- 4 + req.body.length;
37
-
38
- const buf = new Uint8Array(totalSize);
39
- const view = new DataView(buf.buffer);
40
- let offset = 0;
41
-
42
- // requestId
43
- view.setUint16(offset, requestIdBytes.length);
44
- offset += 2;
45
- buf.set(requestIdBytes, offset);
46
- offset += requestIdBytes.length;
47
-
48
- // method
49
- view.setUint8(offset, methodBytes.length);
50
- offset += 1;
51
- buf.set(methodBytes, offset);
52
- offset += methodBytes.length;
53
-
54
- // path
55
- view.setUint16(offset, pathBytes.length);
56
- offset += 2;
57
- buf.set(pathBytes, offset);
58
- offset += pathBytes.length;
59
-
60
- // headers
61
- view.setUint16(offset, headerEntries.length);
62
- offset += 2;
63
- for (const { key, val } of encodedHeaders) {
64
- view.setUint16(offset, key.length);
65
- offset += 2;
66
- buf.set(key, offset);
67
- offset += key.length;
68
- view.setUint16(offset, val.length);
69
- offset += 2;
70
- buf.set(val, offset);
71
- offset += val.length;
72
- }
73
-
74
- // body
75
- view.setUint32(offset, req.body.length);
76
- offset += 4;
77
- buf.set(req.body, offset);
78
-
79
- return buf;
80
- }
81
-
82
- /**
83
- * Decode binary data into a SerializedHttpRequest.
84
- */
85
- export function decodeHttpRequest(data: Uint8Array): SerializedHttpRequest {
86
- const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
87
- let offset = 0;
88
-
89
- // requestId
90
- const requestIdLen = view.getUint16(offset);
91
- offset += 2;
92
- const requestId = decoder.decode(data.slice(offset, offset + requestIdLen));
93
- offset += requestIdLen;
94
-
95
- // method
96
- const methodLen = view.getUint8(offset);
97
- offset += 1;
98
- const method = decoder.decode(data.slice(offset, offset + methodLen));
99
- offset += methodLen;
100
-
101
- // path
102
- const pathLen = view.getUint16(offset);
103
- offset += 2;
104
- const path = decoder.decode(data.slice(offset, offset + pathLen));
105
- offset += pathLen;
106
-
107
- // headers
108
- const headerCount = view.getUint16(offset);
109
- offset += 2;
110
- const headers: Record<string, string> = {};
111
- for (let i = 0; i < headerCount; i++) {
112
- const keyLen = view.getUint16(offset);
113
- offset += 2;
114
- const key = decoder.decode(data.slice(offset, offset + keyLen));
115
- offset += keyLen;
116
- const valLen = view.getUint16(offset);
117
- offset += 2;
118
- const val = decoder.decode(data.slice(offset, offset + valLen));
119
- offset += valLen;
120
- headers[key] = val;
121
- }
122
-
123
- // body
124
- const bodyLen = view.getUint32(offset);
125
- offset += 4;
126
- const body = data.slice(offset, offset + bodyLen);
127
-
128
- return { requestId, method, path, headers, body };
129
- }
130
-
131
- /**
132
- * Encode an HTTP response into binary format:
133
- * [requestIdLen:2][requestId:N][statusCode:2]
134
- * [headerCount:2][for each header: keyLen:2, key:N, valLen:2, val:N]
135
- * [bodyLen:4][body:N]
136
- */
137
- export function encodeHttpResponse(resp: SerializedHttpResponse): Uint8Array {
138
- const requestIdBytes = encoder.encode(resp.requestId);
139
-
140
- const headerEntries = Object.entries(resp.headers);
141
- const encodedHeaders: Array<{ key: Uint8Array; val: Uint8Array }> = [];
142
- let headersSize = 0;
143
- for (const [key, val] of headerEntries) {
144
- const keyBytes = encoder.encode(key);
145
- const valBytes = encoder.encode(val);
146
- encodedHeaders.push({ key: keyBytes, val: valBytes });
147
- headersSize += 2 + keyBytes.length + 2 + valBytes.length;
148
- }
149
-
150
- const totalSize =
151
- 2 + requestIdBytes.length +
152
- 2 +
153
- 2 + headersSize +
154
- 4 + resp.body.length;
155
-
156
- const buf = new Uint8Array(totalSize);
157
- const view = new DataView(buf.buffer);
158
- let offset = 0;
159
-
160
- // requestId
161
- view.setUint16(offset, requestIdBytes.length);
162
- offset += 2;
163
- buf.set(requestIdBytes, offset);
164
- offset += requestIdBytes.length;
165
-
166
- // statusCode
167
- view.setUint16(offset, resp.statusCode);
168
- offset += 2;
169
-
170
- // headers
171
- view.setUint16(offset, headerEntries.length);
172
- offset += 2;
173
- for (const { key, val } of encodedHeaders) {
174
- view.setUint16(offset, key.length);
175
- offset += 2;
176
- buf.set(key, offset);
177
- offset += key.length;
178
- view.setUint16(offset, val.length);
179
- offset += 2;
180
- buf.set(val, offset);
181
- offset += val.length;
182
- }
183
-
184
- // body
185
- view.setUint32(offset, resp.body.length);
186
- offset += 4;
187
- buf.set(resp.body, offset);
188
-
189
- return buf;
190
- }
191
-
192
- /**
193
- * Decode binary data into a SerializedHttpResponse.
194
- */
195
- export function decodeHttpResponse(data: Uint8Array): SerializedHttpResponse {
196
- const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
197
- let offset = 0;
198
-
199
- // requestId
200
- const requestIdLen = view.getUint16(offset);
201
- offset += 2;
202
- const requestId = decoder.decode(data.slice(offset, offset + requestIdLen));
203
- offset += requestIdLen;
204
-
205
- // statusCode
206
- const statusCode = view.getUint16(offset);
207
- offset += 2;
208
-
209
- // headers
210
- const headerCount = view.getUint16(offset);
211
- offset += 2;
212
- const headers: Record<string, string> = {};
213
- for (let i = 0; i < headerCount; i++) {
214
- const keyLen = view.getUint16(offset);
215
- offset += 2;
216
- const key = decoder.decode(data.slice(offset, offset + keyLen));
217
- offset += keyLen;
218
- const valLen = view.getUint16(offset);
219
- offset += 2;
220
- const val = decoder.decode(data.slice(offset, offset + valLen));
221
- offset += valLen;
222
- headers[key] = val;
223
- }
224
-
225
- // body
226
- const bodyLen = view.getUint32(offset);
227
- offset += 4;
228
- const body = data.slice(offset, offset + bodyLen);
229
-
230
- return { requestId, statusCode, headers, body };
231
- }
232
-
233
- /**
234
- * Encode an HTTP response chunk into binary format:
235
- * [requestIdLen:2][requestId:N][done:1][dataLen:4][data:N]
236
- */
237
- export function encodeHttpResponseChunk(
238
- chunk: SerializedHttpResponseChunk
239
- ): Uint8Array {
240
- const requestIdBytes = encoder.encode(chunk.requestId);
241
-
242
- const totalSize =
243
- 2 + requestIdBytes.length +
244
- 1 +
245
- 4 + chunk.data.length;
246
-
247
- const buf = new Uint8Array(totalSize);
248
- const view = new DataView(buf.buffer);
249
- let offset = 0;
250
-
251
- // requestId
252
- view.setUint16(offset, requestIdBytes.length);
253
- offset += 2;
254
- buf.set(requestIdBytes, offset);
255
- offset += requestIdBytes.length;
256
-
257
- // done
258
- view.setUint8(offset, chunk.done ? 1 : 0);
259
- offset += 1;
260
-
261
- // data
262
- view.setUint32(offset, chunk.data.length);
263
- offset += 4;
264
- buf.set(chunk.data, offset);
265
-
266
- return buf;
267
- }
268
-
269
- /**
270
- * Decode binary data into a SerializedHttpResponseChunk.
271
- */
272
- export function decodeHttpResponseChunk(
273
- data: Uint8Array
274
- ): SerializedHttpResponseChunk {
275
- const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
276
- let offset = 0;
277
-
278
- // requestId
279
- const requestIdLen = view.getUint16(offset);
280
- offset += 2;
281
- const requestId = decoder.decode(data.slice(offset, offset + requestIdLen));
282
- offset += requestIdLen;
283
-
284
- // done
285
- const done = view.getUint8(offset) === 1;
286
- offset += 1;
287
-
288
- // data
289
- const dataLen = view.getUint32(offset);
290
- offset += 4;
291
- const chunkData = data.slice(offset, offset + dataLen);
292
-
293
- return { requestId, data: chunkData, done };
294
- }
@@ -1,6 +0,0 @@
1
- export { computeTrustScore, DEFAULT_TRUST_WEIGHTS, DEFAULT_COMPONENTS } from './trust-score.js';
2
- export type { TrustScore, TrustComponents } from './trust-score.js';
3
- export { TrustScoreEngine, type TrustEngineConfig } from './trust-engine.js';
4
- export { UptimeTracker, type UptimeTrackerConfig, type UptimeWindow, type PeerUptimeRecord } from './uptime-tracker.js';
5
- export { ReportManager, type ReportManagerConfig } from './report-manager.js';
6
- export { RatingManager, type RatingManagerConfig } from './rating-manager.js';
@@ -1,118 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { readFile, writeFile, mkdir } from 'node:fs/promises';
3
- import { join } from 'node:path';
4
- import type { PeerId } from '../types/peer.js';
5
- import type { PeerRating, RatingDimension, AggregateRating } from '../types/rating.js';
6
- import type { Identity } from '../p2p/identity.js';
7
- import { signData } from '../p2p/identity.js';
8
- import { bytesToHex } from '../utils/hex.js';
9
-
10
- const HALF_LIFE_MS = 90 * 24 * 60 * 60 * 1000; // 90 days
11
- const DIMENSIONS: RatingDimension[] = ['quality', 'speed', 'reliability', 'value', 'overall'];
12
-
13
- export interface RatingManagerConfig {
14
- configDir: string;
15
- identity?: Identity;
16
- }
17
-
18
- export class RatingManager {
19
- private readonly configDir: string;
20
- private readonly identity: Identity | undefined;
21
- private ratings: PeerRating[] = [];
22
-
23
- constructor(config: RatingManagerConfig) {
24
- this.configDir = config.configDir;
25
- this.identity = config.identity;
26
- }
27
-
28
- async submitRating(
29
- targetPeerId: PeerId,
30
- sessionId: string,
31
- dimensions: Record<RatingDimension, 1 | 2 | 3 | 4 | 5>,
32
- comment?: string,
33
- ): Promise<PeerRating> {
34
- if (!this.identity) throw new Error('Identity required to submit ratings');
35
-
36
- const rating: PeerRating = {
37
- ratingId: randomUUID(),
38
- raterPeerId: this.identity.peerId as PeerId,
39
- targetPeerId,
40
- sessionId,
41
- dimensions,
42
- comment,
43
- timestamp: Date.now(),
44
- signature: '',
45
- };
46
-
47
- const dataToSign = `${rating.ratingId}:${rating.raterPeerId}:${rating.targetPeerId}:${rating.sessionId}:${rating.timestamp}`;
48
- const sig = await signData(this.identity.privateKey, new TextEncoder().encode(dataToSign));
49
- rating.signature = bytesToHex(sig);
50
-
51
- this.ratings.push(rating);
52
- await this.save();
53
- return rating;
54
- }
55
-
56
- getAggregateRating(peerId: PeerId): AggregateRating {
57
- const peerRatings = this.ratings.filter(r => r.targetPeerId === peerId);
58
- const now = Date.now();
59
-
60
- const weightedSums: Record<string, number> = Object.fromEntries(DIMENSIONS.map(d => [d, 0]));
61
- let totalWeight = 0;
62
-
63
- for (const rating of peerRatings) {
64
- // Exponential decay weight
65
- const age = now - rating.timestamp;
66
- const weight = Math.pow(0.5, age / HALF_LIFE_MS);
67
- totalWeight += weight;
68
-
69
- for (const dim of DIMENSIONS) {
70
- weightedSums[dim]! += rating.dimensions[dim] * weight;
71
- }
72
- }
73
-
74
- const averageByDimension = {} as Record<RatingDimension, number>;
75
- for (const dim of DIMENSIONS) {
76
- averageByDimension[dim] = totalWeight > 0
77
- ? Math.round((weightedSums[dim]! / totalWeight) * 100) / 100
78
- : 0;
79
- }
80
-
81
- const overallAverage = totalWeight > 0
82
- ? Math.round((DIMENSIONS.reduce((sum, dim) => sum + averageByDimension[dim], 0) / DIMENSIONS.length) * 100) / 100
83
- : 0;
84
-
85
- return {
86
- peerId,
87
- averageByDimension,
88
- overallAverage,
89
- totalRatings: peerRatings.length,
90
- lastUpdated: now,
91
- };
92
- }
93
-
94
- getRatingsFor(peerId: PeerId): PeerRating[] {
95
- return this.ratings.filter(r => r.targetPeerId === peerId);
96
- }
97
-
98
- getMyRatings(): PeerRating[] {
99
- if (!this.identity) return [];
100
- return this.ratings.filter(r => r.raterPeerId === this.identity!.peerId);
101
- }
102
-
103
- async save(): Promise<void> {
104
- await mkdir(this.configDir, { recursive: true });
105
- const filePath = join(this.configDir, 'ratings.json');
106
- await writeFile(filePath, JSON.stringify(this.ratings, null, 2), 'utf-8');
107
- }
108
-
109
- async load(): Promise<void> {
110
- const filePath = join(this.configDir, 'ratings.json');
111
- try {
112
- const raw = await readFile(filePath, 'utf-8');
113
- this.ratings = JSON.parse(raw) as PeerRating[];
114
- } catch {
115
- this.ratings = [];
116
- }
117
- }
118
- }
@@ -1,91 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { readFile, writeFile, mkdir } from 'node:fs/promises';
3
- import { join } from 'node:path';
4
- import type { PeerId } from '../types/peer.js';
5
- import type { PeerReport, ReportReason, ReportEvidence } from '../types/report.js';
6
- import type { Identity } from '../p2p/identity.js';
7
- import { signData } from '../p2p/identity.js';
8
- import { bytesToHex } from '../utils/hex.js';
9
-
10
- export interface ReportManagerConfig {
11
- configDir: string;
12
- identity?: Identity;
13
- }
14
-
15
- export class ReportManager {
16
- private readonly configDir: string;
17
- private readonly identity: Identity | undefined;
18
- private reports: PeerReport[] = [];
19
-
20
- constructor(config: ReportManagerConfig) {
21
- this.configDir = config.configDir;
22
- this.identity = config.identity;
23
- }
24
-
25
- async submitReport(
26
- targetPeerId: PeerId,
27
- reason: ReportReason,
28
- evidence: ReportEvidence[],
29
- sessionId?: string,
30
- ): Promise<PeerReport> {
31
- if (!this.identity) throw new Error('Identity required to submit reports');
32
-
33
- const report: PeerReport = {
34
- reportId: randomUUID(),
35
- reporterPeerId: this.identity.peerId as PeerId,
36
- targetPeerId,
37
- reason,
38
- evidence,
39
- sessionId,
40
- timestamp: Date.now(),
41
- status: 'pending',
42
- signature: '',
43
- };
44
-
45
- // Sign the report
46
- const dataToSign = `${report.reportId}:${report.reporterPeerId}:${report.targetPeerId}:${report.reason}:${report.timestamp}`;
47
- const sig = await signData(this.identity.privateKey, new TextEncoder().encode(dataToSign));
48
- report.signature = bytesToHex(sig);
49
-
50
- this.reports.push(report);
51
- await this.save();
52
- return report;
53
- }
54
-
55
- getReportsAgainst(peerId: PeerId): PeerReport[] {
56
- return this.reports.filter(r => r.targetPeerId === peerId);
57
- }
58
-
59
- getMyReports(): PeerReport[] {
60
- if (!this.identity) return [];
61
- return this.reports.filter(r => r.reporterPeerId === this.identity!.peerId);
62
- }
63
-
64
- getReport(reportId: string): PeerReport | null {
65
- return this.reports.find(r => r.reportId === reportId) ?? null;
66
- }
67
-
68
- updateReportStatus(reportId: string, status: PeerReport['status']): void {
69
- const report = this.reports.find(r => r.reportId === reportId);
70
- if (report) {
71
- report.status = status;
72
- }
73
- }
74
-
75
- async save(): Promise<void> {
76
- const dir = join(this.configDir, 'reports');
77
- await mkdir(dir, { recursive: true });
78
- const filePath = join(dir, 'reports.json');
79
- await writeFile(filePath, JSON.stringify(this.reports, null, 2), 'utf-8');
80
- }
81
-
82
- async load(): Promise<void> {
83
- const filePath = join(this.configDir, 'reports', 'reports.json');
84
- try {
85
- const raw = await readFile(filePath, 'utf-8');
86
- this.reports = JSON.parse(raw) as PeerReport[];
87
- } catch {
88
- this.reports = [];
89
- }
90
- }
91
- }