@antseed/node 0.1.0 → 0.1.1
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/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/seller-provider.d.ts +13 -1
- package/dist/interfaces/seller-provider.d.ts.map +1 -1
- package/dist/node.d.ts +13 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +123 -15
- package/dist/node.js.map +1 -1
- package/dist/proxy/proxy-mux.d.ts +3 -1
- package/dist/proxy/proxy-mux.d.ts.map +1 -1
- package/dist/proxy/proxy-mux.js +9 -5
- package/dist/proxy/proxy-mux.js.map +1 -1
- package/dist/types/http.d.ts +1 -0
- package/dist/types/http.d.ts.map +1 -1
- package/dist/types/http.js +1 -1
- package/dist/types/http.js.map +1 -1
- package/package.json +14 -10
- package/contracts/AntseedEscrow.sol +0 -310
- package/contracts/MockUSDC.sol +0 -64
- package/contracts/README.md +0 -102
- package/src/config/encryption.test.ts +0 -49
- package/src/config/encryption.ts +0 -53
- package/src/config/plugin-config-manager.test.ts +0 -92
- package/src/config/plugin-config-manager.ts +0 -153
- package/src/config/plugin-loader.ts +0 -90
- package/src/discovery/announcer.ts +0 -169
- package/src/discovery/bootstrap.ts +0 -57
- package/src/discovery/default-metadata-resolver.ts +0 -18
- package/src/discovery/dht-health.ts +0 -136
- package/src/discovery/dht-node.ts +0 -191
- package/src/discovery/http-metadata-resolver.ts +0 -47
- package/src/discovery/index.ts +0 -15
- package/src/discovery/metadata-codec.ts +0 -453
- package/src/discovery/metadata-resolver.ts +0 -7
- package/src/discovery/metadata-server.ts +0 -73
- package/src/discovery/metadata-validator.ts +0 -172
- package/src/discovery/peer-lookup.ts +0 -122
- package/src/discovery/peer-metadata.ts +0 -34
- package/src/discovery/peer-selector.ts +0 -134
- package/src/discovery/profile-manager.ts +0 -131
- package/src/discovery/profile-search.ts +0 -100
- package/src/discovery/reputation-verifier.ts +0 -54
- package/src/index.ts +0 -61
- package/src/interfaces/buyer-router.ts +0 -21
- package/src/interfaces/plugin.ts +0 -36
- package/src/interfaces/seller-provider.ts +0 -81
- package/src/metering/index.ts +0 -6
- package/src/metering/receipt-generator.ts +0 -105
- package/src/metering/receipt-verifier.ts +0 -102
- package/src/metering/session-tracker.ts +0 -145
- package/src/metering/storage.ts +0 -600
- package/src/metering/token-counter.ts +0 -127
- package/src/metering/usage-aggregator.ts +0 -236
- package/src/node.ts +0 -1698
- package/src/p2p/connection-auth.ts +0 -152
- package/src/p2p/connection-manager.ts +0 -916
- package/src/p2p/handshake.ts +0 -162
- package/src/p2p/ice-config.ts +0 -59
- package/src/p2p/identity.ts +0 -110
- package/src/p2p/index.ts +0 -11
- package/src/p2p/keepalive.ts +0 -118
- package/src/p2p/message-protocol.ts +0 -171
- package/src/p2p/nat-traversal.ts +0 -169
- package/src/p2p/payment-codec.ts +0 -165
- package/src/p2p/payment-mux.ts +0 -153
- package/src/p2p/reconnect.ts +0 -117
- package/src/payments/balance-manager.ts +0 -77
- package/src/payments/buyer-payment-manager.ts +0 -414
- package/src/payments/disputes.ts +0 -72
- package/src/payments/evm/escrow-client.ts +0 -263
- package/src/payments/evm/keypair.ts +0 -31
- package/src/payments/evm/signatures.ts +0 -103
- package/src/payments/evm/wallet.ts +0 -42
- package/src/payments/index.ts +0 -50
- package/src/payments/settlement.ts +0 -40
- package/src/payments/types.ts +0 -79
- package/src/proxy/index.ts +0 -3
- package/src/proxy/provider-detection.ts +0 -78
- package/src/proxy/proxy-mux.ts +0 -173
- package/src/proxy/request-codec.ts +0 -294
- package/src/reputation/index.ts +0 -6
- package/src/reputation/rating-manager.ts +0 -118
- package/src/reputation/report-manager.ts +0 -91
- package/src/reputation/trust-engine.ts +0 -120
- package/src/reputation/trust-score.ts +0 -74
- package/src/reputation/uptime-tracker.ts +0 -155
- package/src/routing/default-router.ts +0 -75
- package/src/types/bittorrent-dht.d.ts +0 -19
- package/src/types/buyer.ts +0 -37
- package/src/types/capability.ts +0 -34
- package/src/types/connection.ts +0 -29
- package/src/types/http.ts +0 -20
- package/src/types/index.ts +0 -14
- package/src/types/metering.ts +0 -175
- package/src/types/nat-api.d.ts +0 -29
- package/src/types/peer-profile.ts +0 -25
- package/src/types/peer.ts +0 -62
- package/src/types/plugin-config.ts +0 -31
- package/src/types/protocol.ts +0 -162
- package/src/types/provider.ts +0 -40
- package/src/types/rating.ts +0 -23
- package/src/types/report.ts +0 -30
- package/src/types/seller.ts +0 -38
- package/src/types/staking.ts +0 -23
- package/src/utils/debug.ts +0 -30
- package/src/utils/hex.ts +0 -14
- package/tests/balance-manager.test.ts +0 -156
- package/tests/bootstrap.test.ts +0 -108
- package/tests/buyer-payment-manager.test.ts +0 -358
- package/tests/connection-auth.test.ts +0 -87
- package/tests/default-router.test.ts +0 -148
- package/tests/evm-keypair.test.ts +0 -173
- package/tests/identity.test.ts +0 -133
- package/tests/message-protocol.test.ts +0 -212
- package/tests/metadata-codec.test.ts +0 -165
- package/tests/metadata-validator.test.ts +0 -261
- package/tests/metering-storage.test.ts +0 -244
- package/tests/payment-codec.test.ts +0 -95
- package/tests/payment-mux.test.ts +0 -191
- package/tests/peer-selector.test.ts +0 -184
- package/tests/provider-detection.test.ts +0 -107
- package/tests/proxy-mux-security.test.ts +0 -38
- package/tests/receipt.test.ts +0 -215
- package/tests/reputation-integration.test.ts +0 -195
- package/tests/request-codec.test.ts +0 -144
- package/tests/token-counter.test.ts +0 -122
- package/tsconfig.json +0 -9
- package/vitest.config.ts +0 -7
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
export interface DHTHealthSnapshot {
|
|
2
|
-
nodeCount: number;
|
|
3
|
-
totalLookups: number;
|
|
4
|
-
successfulLookups: number;
|
|
5
|
-
failedLookups: number;
|
|
6
|
-
totalAnnounces: number;
|
|
7
|
-
successfulAnnounces: number;
|
|
8
|
-
failedAnnounces: number;
|
|
9
|
-
averageLookupLatencyMs: number;
|
|
10
|
-
isHealthy: boolean;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface HealthThresholds {
|
|
14
|
-
minNodeCount: number;
|
|
15
|
-
minLookupSuccessRate: number;
|
|
16
|
-
maxAvgLookupLatencyMs: number;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const DEFAULT_HEALTH_THRESHOLDS: HealthThresholds = {
|
|
20
|
-
minNodeCount: 5,
|
|
21
|
-
minLookupSuccessRate: 0.3,
|
|
22
|
-
maxAvgLookupLatencyMs: 15000,
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export class DHTHealthMonitor {
|
|
26
|
-
private readonly thresholds: HealthThresholds;
|
|
27
|
-
private readonly getNodeCount: () => number;
|
|
28
|
-
private _totalLookups = 0;
|
|
29
|
-
private _successfulLookups = 0;
|
|
30
|
-
private _failedLookups = 0;
|
|
31
|
-
private _totalAnnounces = 0;
|
|
32
|
-
private _successfulAnnounces = 0;
|
|
33
|
-
private _failedAnnounces = 0;
|
|
34
|
-
private readonly latencySamples: number[] = [];
|
|
35
|
-
private static readonly MAX_LATENCY_SAMPLES = 100;
|
|
36
|
-
|
|
37
|
-
constructor(
|
|
38
|
-
getNodeCount: () => number,
|
|
39
|
-
thresholds: HealthThresholds = DEFAULT_HEALTH_THRESHOLDS
|
|
40
|
-
) {
|
|
41
|
-
this.getNodeCount = getNodeCount;
|
|
42
|
-
this.thresholds = thresholds;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
recordLookup(success: boolean, latencyMs: number): void {
|
|
46
|
-
this._totalLookups++;
|
|
47
|
-
if (success) {
|
|
48
|
-
this._successfulLookups++;
|
|
49
|
-
} else {
|
|
50
|
-
this._failedLookups++;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
this.latencySamples.push(latencyMs);
|
|
54
|
-
if (this.latencySamples.length > DHTHealthMonitor.MAX_LATENCY_SAMPLES) {
|
|
55
|
-
this.latencySamples.shift();
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
recordAnnounce(success: boolean): void {
|
|
60
|
-
this._totalAnnounces++;
|
|
61
|
-
if (success) {
|
|
62
|
-
this._successfulAnnounces++;
|
|
63
|
-
} else {
|
|
64
|
-
this._failedAnnounces++;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
getSnapshot(): DHTHealthSnapshot {
|
|
69
|
-
const nodeCount = this.getNodeCount();
|
|
70
|
-
const averageLookupLatencyMs = this.computeAverageLatency();
|
|
71
|
-
const healthy = this.evaluateHealth(nodeCount, averageLookupLatencyMs);
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
nodeCount,
|
|
75
|
-
totalLookups: this._totalLookups,
|
|
76
|
-
successfulLookups: this._successfulLookups,
|
|
77
|
-
failedLookups: this._failedLookups,
|
|
78
|
-
totalAnnounces: this._totalAnnounces,
|
|
79
|
-
successfulAnnounces: this._successfulAnnounces,
|
|
80
|
-
failedAnnounces: this._failedAnnounces,
|
|
81
|
-
averageLookupLatencyMs,
|
|
82
|
-
isHealthy: healthy,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
isHealthy(): boolean {
|
|
87
|
-
const nodeCount = this.getNodeCount();
|
|
88
|
-
const averageLookupLatencyMs = this.computeAverageLatency();
|
|
89
|
-
return this.evaluateHealth(nodeCount, averageLookupLatencyMs);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
reset(): void {
|
|
93
|
-
this._totalLookups = 0;
|
|
94
|
-
this._successfulLookups = 0;
|
|
95
|
-
this._failedLookups = 0;
|
|
96
|
-
this._totalAnnounces = 0;
|
|
97
|
-
this._successfulAnnounces = 0;
|
|
98
|
-
this._failedAnnounces = 0;
|
|
99
|
-
this.latencySamples.length = 0;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
private computeAverageLatency(): number {
|
|
103
|
-
if (this.latencySamples.length === 0) {
|
|
104
|
-
return 0;
|
|
105
|
-
}
|
|
106
|
-
const sum = this.latencySamples.reduce((a, b) => a + b, 0);
|
|
107
|
-
return sum / this.latencySamples.length;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
private evaluateHealth(
|
|
111
|
-
nodeCount: number,
|
|
112
|
-
averageLookupLatencyMs: number
|
|
113
|
-
): boolean {
|
|
114
|
-
// Must have minimum node count
|
|
115
|
-
if (nodeCount < this.thresholds.minNodeCount) {
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Check lookup success rate (only if we have 5+ lookups)
|
|
120
|
-
if (this._totalLookups >= 5) {
|
|
121
|
-
const successRate = this._successfulLookups / this._totalLookups;
|
|
122
|
-
if (successRate < this.thresholds.minLookupSuccessRate) {
|
|
123
|
-
return false;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Check average latency (only if we have 5+ samples)
|
|
128
|
-
if (this.latencySamples.length >= 5) {
|
|
129
|
-
if (averageLookupLatencyMs > this.thresholds.maxAvgLookupLatencyMs) {
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return true;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import DHT from "bittorrent-dht";
|
|
2
|
-
import { createHash } from "node:crypto";
|
|
3
|
-
import { EventEmitter } from "node:events";
|
|
4
|
-
import type { PeerId } from "../types/peer.js";
|
|
5
|
-
import { OFFICIAL_BOOTSTRAP_NODES, toBootstrapConfig } from "./bootstrap.js";
|
|
6
|
-
|
|
7
|
-
export interface DHTNodeConfig {
|
|
8
|
-
peerId: PeerId;
|
|
9
|
-
port: number;
|
|
10
|
-
bootstrapNodes: Array<{ host: string; port: number }>;
|
|
11
|
-
reannounceIntervalMs: number;
|
|
12
|
-
operationTimeoutMs: number;
|
|
13
|
-
/** Allow private/loopback IPs in lookup results. Default: false. Set true for local testing. */
|
|
14
|
-
allowPrivateIPs?: boolean;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const DEFAULT_DHT_CONFIG: Omit<DHTNodeConfig, "peerId"> = {
|
|
18
|
-
port: 6881,
|
|
19
|
-
bootstrapNodes: toBootstrapConfig(OFFICIAL_BOOTSTRAP_NODES),
|
|
20
|
-
reannounceIntervalMs: 15 * 60 * 1000,
|
|
21
|
-
operationTimeoutMs: 10_000,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
function isPublicIP(host: string): boolean {
|
|
25
|
-
if (host === "localhost" || host === "::1") return false;
|
|
26
|
-
const parts = host.split(".");
|
|
27
|
-
if (parts.length !== 4) return false;
|
|
28
|
-
const [a, b] = parts.map(Number);
|
|
29
|
-
if (a === 127) return false; // loopback
|
|
30
|
-
if (a === 10) return false; // 10.0.0.0/8
|
|
31
|
-
if (a === 172 && b !== undefined && b >= 16 && b <= 31) return false; // 172.16.0.0/12
|
|
32
|
-
if (a === 192 && b === 168) return false; // 192.168.0.0/16
|
|
33
|
-
if (a === 169 && b === 254) return false; // link-local
|
|
34
|
-
if (a === 0) return false;
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function topicToInfoHash(topic: string): Buffer {
|
|
39
|
-
return createHash("sha1").update(topic).digest();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function providerTopic(providerName: string): string {
|
|
43
|
-
return "antseed:" + providerName.toLowerCase();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function capabilityTopic(capability: string, name?: string): string {
|
|
47
|
-
const base = "antseed:" + capability.toLowerCase();
|
|
48
|
-
return name ? base + ":" + name.toLowerCase() : base;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export class DHTNode {
|
|
52
|
-
private readonly config: DHTNodeConfig;
|
|
53
|
-
private dht: DHT | null = null;
|
|
54
|
-
public readonly events: EventEmitter = new EventEmitter();
|
|
55
|
-
|
|
56
|
-
constructor(config: DHTNodeConfig) {
|
|
57
|
-
this.config = config;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async start(): Promise<void> {
|
|
61
|
-
return new Promise<void>((resolve, reject) => {
|
|
62
|
-
this.dht = new DHT({
|
|
63
|
-
bootstrap: this.config.bootstrapNodes.map(
|
|
64
|
-
(n) => `${n.host}:${n.port}`
|
|
65
|
-
),
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
const timeout = setTimeout(() => {
|
|
69
|
-
// Resolve even on timeout — the DHT may still work with partial bootstrap.
|
|
70
|
-
// This prevents hanging when public bootstrap nodes are unreachable.
|
|
71
|
-
cleanup();
|
|
72
|
-
this.events.emit("ready");
|
|
73
|
-
resolve();
|
|
74
|
-
}, this.config.operationTimeoutMs);
|
|
75
|
-
|
|
76
|
-
let settled = false;
|
|
77
|
-
const cleanup = (): void => {
|
|
78
|
-
if (settled) return;
|
|
79
|
-
settled = true;
|
|
80
|
-
clearTimeout(timeout);
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
this.dht.listen(this.config.port, () => {
|
|
84
|
-
// Socket is bound; now wait for DHT bootstrap to complete.
|
|
85
|
-
// The 'ready' event fires when the routing table has been populated.
|
|
86
|
-
this.dht!.on("ready", () => {
|
|
87
|
-
cleanup();
|
|
88
|
-
this.events.emit("ready");
|
|
89
|
-
resolve();
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
this.dht.on("error", (err: Error) => {
|
|
94
|
-
cleanup();
|
|
95
|
-
reject(err);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
async stop(): Promise<void> {
|
|
101
|
-
return new Promise<void>((resolve) => {
|
|
102
|
-
if (!this.dht) {
|
|
103
|
-
resolve();
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
this.dht.destroy(() => {
|
|
107
|
-
this.dht = null;
|
|
108
|
-
resolve();
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async announce(infoHash: Buffer, port: number): Promise<void> {
|
|
114
|
-
return new Promise<void>((resolve, reject) => {
|
|
115
|
-
if (!this.dht) {
|
|
116
|
-
reject(new Error("DHT not started"));
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const timeout = setTimeout(() => {
|
|
121
|
-
reject(new Error("Announce timeout"));
|
|
122
|
-
}, this.config.operationTimeoutMs);
|
|
123
|
-
|
|
124
|
-
this.dht.announce(infoHash, port, (err?: Error) => {
|
|
125
|
-
clearTimeout(timeout);
|
|
126
|
-
if (err) {
|
|
127
|
-
reject(err);
|
|
128
|
-
} else {
|
|
129
|
-
resolve();
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
async lookup(infoHash: Buffer): Promise<Array<{ host: string; port: number }>> {
|
|
136
|
-
return new Promise<Array<{ host: string; port: number }>>((resolve) => {
|
|
137
|
-
if (!this.dht) {
|
|
138
|
-
resolve([]);
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const peers: Array<{ host: string; port: number }> = [];
|
|
143
|
-
let done = false;
|
|
144
|
-
|
|
145
|
-
const onPeer = (peer: { host: string; port: number }, hash: Buffer): void => {
|
|
146
|
-
if (hash.equals(infoHash)) {
|
|
147
|
-
if (peer.port < 1 || peer.port > 65535) return;
|
|
148
|
-
if (!this.config.allowPrivateIPs && !isPublicIP(peer.host)) return;
|
|
149
|
-
peers.push({ host: peer.host, port: peer.port });
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
const finish = (): void => {
|
|
154
|
-
if (done) return;
|
|
155
|
-
done = true;
|
|
156
|
-
clearTimeout(timeout);
|
|
157
|
-
this.dht?.off("peer", onPeer);
|
|
158
|
-
resolve(peers);
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
this.dht.on("peer", onPeer);
|
|
162
|
-
|
|
163
|
-
const timeout = setTimeout(() => {
|
|
164
|
-
finish();
|
|
165
|
-
}, this.config.operationTimeoutMs);
|
|
166
|
-
|
|
167
|
-
this.dht.lookup(infoHash, () => {
|
|
168
|
-
finish();
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
getNodeCount(): number {
|
|
174
|
-
if (!this.dht) {
|
|
175
|
-
return 0;
|
|
176
|
-
}
|
|
177
|
-
return this.dht.nodes.toArray().length;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
getPort(): number {
|
|
181
|
-
if (!this.dht) {
|
|
182
|
-
return this.config.port;
|
|
183
|
-
}
|
|
184
|
-
try {
|
|
185
|
-
const addr = this.dht.address();
|
|
186
|
-
return addr?.port ?? this.config.port;
|
|
187
|
-
} catch {
|
|
188
|
-
return this.config.port;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { PeerEndpoint, MetadataResolver } from './metadata-resolver.js';
|
|
2
|
-
import type { PeerMetadata } from './peer-metadata.js';
|
|
3
|
-
import { debugWarn } from '../utils/debug.js';
|
|
4
|
-
|
|
5
|
-
export interface HttpMetadataResolverConfig {
|
|
6
|
-
/** Timeout in ms for each metadata fetch. Default: 5000 */
|
|
7
|
-
timeoutMs?: number;
|
|
8
|
-
/** Port offset from the signaling port to the metadata HTTP port. Default: 0 (same port) */
|
|
9
|
-
metadataPortOffset?: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export class HttpMetadataResolver implements MetadataResolver {
|
|
13
|
-
private readonly timeoutMs: number;
|
|
14
|
-
private readonly metadataPortOffset: number;
|
|
15
|
-
|
|
16
|
-
constructor(config?: HttpMetadataResolverConfig) {
|
|
17
|
-
this.timeoutMs = config?.timeoutMs ?? 5000;
|
|
18
|
-
this.metadataPortOffset = config?.metadataPortOffset ?? 0;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async resolve(peer: PeerEndpoint): Promise<PeerMetadata | null> {
|
|
22
|
-
const metadataPort = peer.port + this.metadataPortOffset;
|
|
23
|
-
const url = `http://${peer.host}:${metadataPort}/metadata`;
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
const controller = new AbortController();
|
|
27
|
-
const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
28
|
-
|
|
29
|
-
const response = await fetch(url, { signal: controller.signal });
|
|
30
|
-
clearTimeout(timeout);
|
|
31
|
-
|
|
32
|
-
if (!response.ok) {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return (await response.json()) as PeerMetadata;
|
|
37
|
-
} catch (err) {
|
|
38
|
-
const reason = err instanceof DOMException && err.name === 'AbortError'
|
|
39
|
-
? 'timeout'
|
|
40
|
-
: err instanceof SyntaxError
|
|
41
|
-
? 'invalid JSON'
|
|
42
|
-
: 'network error';
|
|
43
|
-
debugWarn(`[MetadataResolver] Failed to resolve ${url}: ${reason}`);
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
package/src/discovery/index.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export { DHTNode, DEFAULT_DHT_CONFIG, topicToInfoHash, providerTopic, type DHTNodeConfig } from './dht-node.js';
|
|
2
|
-
export { PeerAnnouncer, type AnnouncerConfig } from './announcer.js';
|
|
3
|
-
export { PeerLookup, DEFAULT_LOOKUP_CONFIG, type LookupConfig, type LookupResult } from './peer-lookup.js';
|
|
4
|
-
export { scorePeer, rankPeers, selectBestPeer, selectDiversePeers, DEFAULT_SCORING_WEIGHTS, type ScoringWeights, type PeerCandidate, type ScoredPeer } from './peer-selector.js';
|
|
5
|
-
export { OFFICIAL_BOOTSTRAP_NODES, parseBootstrapList, mergeBootstrapNodes, toBootstrapConfig, type BootstrapNode } from './bootstrap.js';
|
|
6
|
-
export { encodeMetadata, encodeMetadataForSigning, decodeMetadata } from './metadata-codec.js';
|
|
7
|
-
export { validateMetadata, MAX_METADATA_SIZE, MAX_PROVIDERS, type ValidationError } from './metadata-validator.js';
|
|
8
|
-
export { METADATA_VERSION, type PeerMetadata, type ProviderAnnouncement } from './peer-metadata.js';
|
|
9
|
-
export { type MetadataResolver, type PeerEndpoint } from './metadata-resolver.js';
|
|
10
|
-
export { DefaultMetadataResolver } from './default-metadata-resolver.js';
|
|
11
|
-
export { HttpMetadataResolver, type HttpMetadataResolverConfig } from './http-metadata-resolver.js';
|
|
12
|
-
export { DHTHealthMonitor, DEFAULT_HEALTH_THRESHOLDS, type DHTHealthSnapshot, type HealthThresholds } from './dht-health.js';
|
|
13
|
-
export { ProfileManager, type ProfileManagerConfig } from './profile-manager.js';
|
|
14
|
-
export { ProfileSearchIndex, type ProfileSearchQuery, type ProfileSearchResult } from './profile-search.js';
|
|
15
|
-
export { verifyReputation, type ReputationVerification } from './reputation-verifier.js';
|