@antseed/node 0.2.93 → 0.2.95
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/buyer-request-handler.d.ts +4 -1
- package/dist/buyer-request-handler.d.ts.map +1 -1
- package/dist/buyer-request-handler.js +83 -4
- package/dist/buyer-request-handler.js.map +1 -1
- package/dist/discovery/http-metadata-resolver.d.ts +7 -0
- package/dist/discovery/http-metadata-resolver.d.ts.map +1 -1
- package/dist/discovery/http-metadata-resolver.js +16 -3
- package/dist/discovery/http-metadata-resolver.js.map +1 -1
- package/dist/discovery/index.d.ts +1 -0
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +1 -0
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/verification-links.d.ts +16 -0
- package/dist/discovery/verification-links.d.ts.map +1 -0
- package/dist/discovery/verification-links.js +71 -0
- package/dist/discovery/verification-links.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +25 -2
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +247 -21
- package/dist/node.js.map +1 -1
- package/dist/p2p/payment-codec.d.ts +9 -1
- package/dist/p2p/payment-codec.d.ts.map +1 -1
- package/dist/p2p/payment-codec.js +67 -0
- package/dist/p2p/payment-codec.js.map +1 -1
- package/dist/p2p/payment-mux.d.ts +13 -1
- package/dist/p2p/payment-mux.d.ts.map +1 -1
- package/dist/p2p/payment-mux.js +44 -0
- package/dist/p2p/payment-mux.js.map +1 -1
- package/dist/payments/buyer-free-usage-manager.d.ts +39 -0
- package/dist/payments/buyer-free-usage-manager.d.ts.map +1 -0
- package/dist/payments/buyer-free-usage-manager.js +280 -0
- package/dist/payments/buyer-free-usage-manager.js.map +1 -0
- package/dist/payments/buyer-payment-manager.d.ts +2 -4
- package/dist/payments/buyer-payment-manager.d.ts.map +1 -1
- package/dist/payments/buyer-payment-manager.js +34 -110
- package/dist/payments/buyer-payment-manager.js.map +1 -1
- package/dist/payments/buyer-payment-negotiator.d.ts +6 -2
- package/dist/payments/buyer-payment-negotiator.d.ts.map +1 -1
- package/dist/payments/buyer-payment-negotiator.js +41 -13
- package/dist/payments/buyer-payment-negotiator.js.map +1 -1
- package/dist/payments/chain-config.d.ts +3 -2
- package/dist/payments/chain-config.d.ts.map +1 -1
- package/dist/payments/chain-config.js +4 -4
- package/dist/payments/chain-config.js.map +1 -1
- package/dist/payments/channel-session-state.d.ts +2 -1
- package/dist/payments/channel-session-state.d.ts.map +1 -1
- package/dist/payments/channel-session-state.js +4 -3
- package/dist/payments/channel-session-state.js.map +1 -1
- package/dist/payments/channel-store.d.ts +31 -15
- package/dist/payments/channel-store.d.ts.map +1 -1
- package/dist/payments/channel-store.js +74 -35
- package/dist/payments/channel-store.js.map +1 -1
- package/dist/payments/channel-usage-accounting.d.ts +18 -0
- package/dist/payments/channel-usage-accounting.d.ts.map +1 -0
- package/dist/payments/channel-usage-accounting.js +66 -0
- package/dist/payments/channel-usage-accounting.js.map +1 -0
- package/dist/payments/evm/free-usage-client.d.ts +34 -0
- package/dist/payments/evm/free-usage-client.d.ts.map +1 -0
- package/dist/payments/evm/free-usage-client.js +61 -0
- package/dist/payments/evm/free-usage-client.js.map +1 -0
- package/dist/payments/evm/signatures.d.ts +70 -0
- package/dist/payments/evm/signatures.d.ts.map +1 -1
- package/dist/payments/evm/signatures.js +89 -0
- package/dist/payments/evm/signatures.js.map +1 -1
- package/dist/payments/index.d.ts +10 -6
- package/dist/payments/index.d.ts.map +1 -1
- package/dist/payments/index.js +7 -4
- package/dist/payments/index.js.map +1 -1
- package/dist/payments/seller-free-usage-manager.d.ts +44 -0
- package/dist/payments/seller-free-usage-manager.d.ts.map +1 -0
- package/dist/payments/seller-free-usage-manager.js +350 -0
- package/dist/payments/seller-free-usage-manager.js.map +1 -0
- package/dist/payments/seller-payment-manager.d.ts.map +1 -1
- package/dist/payments/seller-payment-manager.js +21 -20
- package/dist/payments/seller-payment-manager.js.map +1 -1
- package/dist/payments/types.d.ts +2 -0
- package/dist/payments/types.d.ts.map +1 -1
- package/dist/reputation/on-chain-reputation.d.ts +35 -3
- package/dist/reputation/on-chain-reputation.d.ts.map +1 -1
- package/dist/reputation/on-chain-reputation.js +87 -7
- package/dist/reputation/on-chain-reputation.js.map +1 -1
- package/dist/seller-request-handler.d.ts +2 -0
- package/dist/seller-request-handler.d.ts.map +1 -1
- package/dist/seller-request-handler.js +8 -0
- package/dist/seller-request-handler.js.map +1 -1
- package/dist/storage/migrations/channels/004_add_channel_kind.d.ts +3 -0
- package/dist/storage/migrations/channels/004_add_channel_kind.d.ts.map +1 -0
- package/dist/storage/migrations/channels/004_add_channel_kind.js +16 -0
- package/dist/storage/migrations/channels/004_add_channel_kind.js.map +1 -0
- package/dist/storage/migrations/channels/index.d.ts.map +1 -1
- package/dist/storage/migrations/channels/index.js +2 -1
- package/dist/storage/migrations/channels/index.js.map +1 -1
- package/dist/types/peer.d.ts +15 -1
- package/dist/types/peer.d.ts.map +1 -1
- package/dist/types/peer.js.map +1 -1
- package/dist/types/protocol.d.ts +47 -0
- package/dist/types/protocol.d.ts.map +1 -1
- package/dist/types/protocol.js +4 -0
- package/dist/types/protocol.js.map +1 -1
- package/dist/verification/samples.js +1 -1
- package/dist/verification/samples.js.map +1 -1
- package/package.json +1 -1
package/dist/node.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { type SellerContractConfig } from "./discovery/announcer.js";
|
|
|
9
9
|
import type { PeerVerifications } from "./discovery/peer-metadata.js";
|
|
10
10
|
import type { Provider, ProviderStreamCallbacks } from "./interfaces/seller-provider.js";
|
|
11
11
|
import type { Router } from "./interfaces/buyer-router.js";
|
|
12
|
-
import { type PaymentConfig, type PaymentMethod } from "./payments/index.js";
|
|
12
|
+
import { type PaymentConfig, type PaymentMethod, FreeUsageClient, BuyerFreeUsageManager, SellerFreeUsageManager } from "./payments/index.js";
|
|
13
13
|
import { BuyerPaymentManager, type BuyerPaymentConfig } from "./payments/buyer-payment-manager.js";
|
|
14
14
|
import { BuyerPaymentNegotiator } from "./payments/buyer-payment-negotiator.js";
|
|
15
15
|
import { IdentityClient } from "./payments/evm/identity-client.js";
|
|
@@ -44,6 +44,8 @@ export interface NodePaymentsConfig {
|
|
|
44
44
|
depositsAddress?: string;
|
|
45
45
|
/** Deployed AntseedChannels contract address */
|
|
46
46
|
channelsAddress?: string;
|
|
47
|
+
/** Optional deployed AntseedFreeUsage contract address */
|
|
48
|
+
freeUsageAddress?: string;
|
|
47
49
|
/** USDC token contract address */
|
|
48
50
|
usdcAddress?: string;
|
|
49
51
|
/** ERC-8004 IdentityRegistry contract address */
|
|
@@ -68,7 +70,7 @@ export interface NodePaymentsConfig {
|
|
|
68
70
|
maxReserveAmountUsdc?: string;
|
|
69
71
|
}
|
|
70
72
|
export interface NodeVerificationConfig {
|
|
71
|
-
/** Random sample rate for storing full buyer request/response evidence. Default: 0.
|
|
73
|
+
/** Random sample rate for storing full buyer request/response evidence. Default: 0.005. */
|
|
72
74
|
sampleRate?: number;
|
|
73
75
|
/** Maximum combined encoded request + response bytes per sample. Default: 16 MiB. */
|
|
74
76
|
maxSampleBytes?: number;
|
|
@@ -155,6 +157,9 @@ export declare class AntseedNode extends EventEmitter {
|
|
|
155
157
|
private _balanceManager;
|
|
156
158
|
private _depositsClient;
|
|
157
159
|
private _channelsClient;
|
|
160
|
+
private _freeUsageClient;
|
|
161
|
+
private _buyerFreeUsageManager;
|
|
162
|
+
private _sellerFreeUsageManager;
|
|
158
163
|
private _stakingClient;
|
|
159
164
|
private _sellerAddressResolver;
|
|
160
165
|
private _identityClient;
|
|
@@ -186,6 +191,10 @@ export declare class AntseedNode extends EventEmitter {
|
|
|
186
191
|
private _backgroundPeerDiscoveryPromise;
|
|
187
192
|
/** Serializes non-blocking on-chain enrichment for incrementally discovered peers. */
|
|
188
193
|
private _partialPeerEnrichmentChain;
|
|
194
|
+
/** Serializes non-blocking external claim verification for discovered peers. */
|
|
195
|
+
private _externalVerificationChain;
|
|
196
|
+
private _externalVerificationCache;
|
|
197
|
+
private _externalVerificationInFlight;
|
|
189
198
|
constructor(config: NodeConfig);
|
|
190
199
|
get peerId(): string | null;
|
|
191
200
|
get identity(): Identity | null;
|
|
@@ -202,6 +211,12 @@ export declare class AntseedNode extends EventEmitter {
|
|
|
202
211
|
get signalingPort(): number;
|
|
203
212
|
/** ERC-8004 IdentityRegistry client (null if not configured). */
|
|
204
213
|
get identityClient(): IdentityClient | null;
|
|
214
|
+
/** AntseedFreeUsage client (null if not configured). */
|
|
215
|
+
get freeUsageClient(): FreeUsageClient | null;
|
|
216
|
+
/** Buyer-side free usage manager (null if free usage is not configured). */
|
|
217
|
+
get buyerFreeUsageManager(): BuyerFreeUsageManager | null;
|
|
218
|
+
/** Seller-side free usage manager (null if free usage is not configured). */
|
|
219
|
+
get sellerFreeUsageManager(): SellerFreeUsageManager | null;
|
|
205
220
|
/** Current connection state for a peer if a connection exists, otherwise null. */
|
|
206
221
|
getPeerConnectionState(peerId: PeerId): ConnectionState | null;
|
|
207
222
|
/**
|
|
@@ -218,6 +233,11 @@ export declare class AntseedNode extends EventEmitter {
|
|
|
218
233
|
startBackgroundPeerDiscoverySweep(): void;
|
|
219
234
|
private _startBackgroundPeerDiscoverySweep;
|
|
220
235
|
private _queuePartialPeerEnrichment;
|
|
236
|
+
private _attachCachedExternalVerificationResults;
|
|
237
|
+
private _queueExternalVerification;
|
|
238
|
+
private _verifyExternalClaimsForPeers;
|
|
239
|
+
private _verifyExternalClaimsForPeer;
|
|
240
|
+
private _externalVerificationClaimsKey;
|
|
221
241
|
/**
|
|
222
242
|
* Look up a single peer by its peerId via the per-peer DHT topic.
|
|
223
243
|
* Much cheaper and more deterministic than walking the wildcard topic:
|
|
@@ -334,5 +354,8 @@ export declare class AntseedNode extends EventEmitter {
|
|
|
334
354
|
private _getOrCreateVerificationMux;
|
|
335
355
|
private _resolvePublicAddress;
|
|
336
356
|
private _lookupResultToPeerInfo;
|
|
357
|
+
private _warnIfFreeUsageMeteringUnavailable;
|
|
358
|
+
private _hasFreePricedService;
|
|
359
|
+
private _isZeroPricing;
|
|
337
360
|
}
|
|
338
361
|
//# sourceMappingURL=node.d.ts.map
|
package/dist/node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
|
package/dist/node.js
CHANGED
|
@@ -11,6 +11,8 @@ import { DHTNode, DEFAULT_DHT_CONFIG, SUBNET_COUNT, } from "./discovery/dht-node
|
|
|
11
11
|
import { toBootstrapConfig, OFFICIAL_BOOTSTRAP_NODES, mergeBootstrapNodes } from "./discovery/bootstrap.js";
|
|
12
12
|
import { ConnectionManager, } from "./p2p/connection-manager.js";
|
|
13
13
|
import { PeerAnnouncer, } from "./discovery/announcer.js";
|
|
14
|
+
import { verifyPeerMetadataDomains } from "./discovery/domain-verification.js";
|
|
15
|
+
import { verifyPeerMetadataGithub } from "./discovery/github-verification.js";
|
|
14
16
|
import { PeerLookup, DEFAULT_LOOKUP_CONFIG, } from "./discovery/peer-lookup.js";
|
|
15
17
|
import { HttpMetadataResolver } from "./discovery/http-metadata-resolver.js";
|
|
16
18
|
import { ProxyMux } from "./proxy/proxy-mux.js";
|
|
@@ -23,7 +25,7 @@ import { KeepaliveManager, buildPongPayload } from "./p2p/keepalive.js";
|
|
|
23
25
|
import { MessageType } from "./types/protocol.js";
|
|
24
26
|
import { NatTraversal } from "./p2p/nat-traversal.js";
|
|
25
27
|
import { signUtf8 } from "./p2p/identity.js";
|
|
26
|
-
import { BalanceManager, DepositsClient, ChannelsClient, StakingClient, ChannelStore, CHANNEL_STATUS, } from "./payments/index.js";
|
|
28
|
+
import { BalanceManager, DepositsClient, ChannelsClient, FreeUsageClient, BuyerFreeUsageManager, SellerFreeUsageManager, StakingClient, ChannelStore, CHANNEL_ROLE, CHANNEL_STATUS, } from "./payments/index.js";
|
|
27
29
|
import { debugLog, debugWarn } from "./utils/debug.js";
|
|
28
30
|
import { parsePublicAddress } from "./discovery/public-address.js";
|
|
29
31
|
import { BuyerPaymentManager } from "./payments/buyer-payment-manager.js";
|
|
@@ -34,7 +36,7 @@ import { SellerPaymentManager } from "./payments/seller-payment-manager.js";
|
|
|
34
36
|
import { IdentityClient } from "./payments/evm/identity-client.js";
|
|
35
37
|
import { SellerRequestHandler } from "./seller-request-handler.js";
|
|
36
38
|
import { BuyerRequestHandler, } from "./buyer-request-handler.js";
|
|
37
|
-
import { buildSybilContext, computeOnChainScore, computeOnChainSybilRisk, computeOnChainTrust, } from "./reputation/on-chain-reputation.js";
|
|
39
|
+
import { buildSybilContext, computeOnChainScore, computeOnChainScoreWithRisk, computeOnChainSybilRisk, computeOnChainTrust, } from "./reputation/on-chain-reputation.js";
|
|
38
40
|
const EMPTY_BUYER_USAGE = {
|
|
39
41
|
totalRequests: 0,
|
|
40
42
|
totalInputTokens: '0',
|
|
@@ -44,6 +46,7 @@ const EMPTY_BUYER_USAGE = {
|
|
|
44
46
|
activeChannels: 0,
|
|
45
47
|
channels: [],
|
|
46
48
|
};
|
|
49
|
+
const EXTERNAL_VERIFICATION_RESULT_TTL_MS = 15 * 60_000;
|
|
47
50
|
export class AntseedNode extends EventEmitter {
|
|
48
51
|
_config;
|
|
49
52
|
_identity = null;
|
|
@@ -63,6 +66,9 @@ export class AntseedNode extends EventEmitter {
|
|
|
63
66
|
_balanceManager = null;
|
|
64
67
|
_depositsClient = null;
|
|
65
68
|
_channelsClient = null;
|
|
69
|
+
_freeUsageClient = null;
|
|
70
|
+
_buyerFreeUsageManager = null;
|
|
71
|
+
_sellerFreeUsageManager = null;
|
|
66
72
|
_stakingClient = null;
|
|
67
73
|
_sellerAddressResolver = null;
|
|
68
74
|
_identityClient = null;
|
|
@@ -94,6 +100,10 @@ export class AntseedNode extends EventEmitter {
|
|
|
94
100
|
_backgroundPeerDiscoveryPromise = null;
|
|
95
101
|
/** Serializes non-blocking on-chain enrichment for incrementally discovered peers. */
|
|
96
102
|
_partialPeerEnrichmentChain = Promise.resolve();
|
|
103
|
+
/** Serializes non-blocking external claim verification for discovered peers. */
|
|
104
|
+
_externalVerificationChain = Promise.resolve();
|
|
105
|
+
_externalVerificationCache = new Map();
|
|
106
|
+
_externalVerificationInFlight = new Set();
|
|
97
107
|
constructor(config) {
|
|
98
108
|
super();
|
|
99
109
|
this._config = config;
|
|
@@ -133,6 +143,18 @@ export class AntseedNode extends EventEmitter {
|
|
|
133
143
|
get identityClient() {
|
|
134
144
|
return this._identityClient;
|
|
135
145
|
}
|
|
146
|
+
/** AntseedFreeUsage client (null if not configured). */
|
|
147
|
+
get freeUsageClient() {
|
|
148
|
+
return this._freeUsageClient;
|
|
149
|
+
}
|
|
150
|
+
/** Buyer-side free usage manager (null if free usage is not configured). */
|
|
151
|
+
get buyerFreeUsageManager() {
|
|
152
|
+
return this._buyerFreeUsageManager;
|
|
153
|
+
}
|
|
154
|
+
/** Seller-side free usage manager (null if free usage is not configured). */
|
|
155
|
+
get sellerFreeUsageManager() {
|
|
156
|
+
return this._sellerFreeUsageManager;
|
|
157
|
+
}
|
|
136
158
|
/** Current connection state for a peer if a connection exists, otherwise null. */
|
|
137
159
|
getPeerConnectionState(peerId) {
|
|
138
160
|
return this._connectionManager?.getConnection(peerId)?.state ?? null;
|
|
@@ -187,6 +209,9 @@ export class AntseedNode extends EventEmitter {
|
|
|
187
209
|
if (this._buyerNegotiator) {
|
|
188
210
|
this._buyerNegotiator.cleanup();
|
|
189
211
|
}
|
|
212
|
+
if (this._sellerFreeUsageManager) {
|
|
213
|
+
await this._sellerFreeUsageManager.flushAllPendingRecords();
|
|
214
|
+
}
|
|
190
215
|
if (this._sessionTracker) {
|
|
191
216
|
await this._sessionTracker.finalizeAllSessions("node-stop");
|
|
192
217
|
this._sessionTracker.clearTimers();
|
|
@@ -274,6 +299,9 @@ export class AntseedNode extends EventEmitter {
|
|
|
274
299
|
this._balanceManager = null;
|
|
275
300
|
this._depositsClient = null;
|
|
276
301
|
this._channelsClient = null;
|
|
302
|
+
this._freeUsageClient = null;
|
|
303
|
+
this._buyerFreeUsageManager = null;
|
|
304
|
+
this._sellerFreeUsageManager = null;
|
|
277
305
|
this._stakingClient = null;
|
|
278
306
|
this._identityClient = null;
|
|
279
307
|
this._sellerAddressResolver = null;
|
|
@@ -316,6 +344,8 @@ export class AntseedNode extends EventEmitter {
|
|
|
316
344
|
}
|
|
317
345
|
}
|
|
318
346
|
const filtered = service ? peers.filter((p) => peerOffersService(p, service)) : peers;
|
|
347
|
+
this._attachCachedExternalVerificationResults(filtered);
|
|
348
|
+
this._queueExternalVerification(filtered);
|
|
319
349
|
// On-chain enrichment runs after the metadata filter so we don't waste
|
|
320
350
|
// RPC calls on peers we'll discard.
|
|
321
351
|
await this._enrichPeersWithOnChainStats(filtered);
|
|
@@ -351,7 +381,9 @@ export class AntseedNode extends EventEmitter {
|
|
|
351
381
|
debugLog(`[Node] Background DHT partial ${context.phase}`
|
|
352
382
|
+ `${context.subnet !== undefined ? ` ${context.subnet}/${SUBNET_COUNT - 1}` : ""}`
|
|
353
383
|
+ ` emitted ${peers.length} peer(s) from ${context.endpointCount} endpoint(s)`);
|
|
384
|
+
this._attachCachedExternalVerificationResults(peers);
|
|
354
385
|
this.emit("peers:discovered", peers);
|
|
386
|
+
this._queueExternalVerification(peers);
|
|
355
387
|
this._queuePartialPeerEnrichment(peers);
|
|
356
388
|
});
|
|
357
389
|
debugLog(`[Node] Background DHT sweep returned ${results.length} result(s)`);
|
|
@@ -388,6 +420,124 @@ export class AntseedNode extends EventEmitter {
|
|
|
388
420
|
debugWarn(`[Node] Background DHT partial on-chain enrichment failed: ${err instanceof Error ? err.message : err}`);
|
|
389
421
|
});
|
|
390
422
|
}
|
|
423
|
+
_attachCachedExternalVerificationResults(peers) {
|
|
424
|
+
const nowMs = Date.now();
|
|
425
|
+
for (const peer of peers) {
|
|
426
|
+
const claimsKey = this._externalVerificationClaimsKey(peer);
|
|
427
|
+
if (!claimsKey)
|
|
428
|
+
continue;
|
|
429
|
+
const cached = this._externalVerificationCache.get(peer.peerId);
|
|
430
|
+
if (cached
|
|
431
|
+
&& cached.claimsKey === claimsKey
|
|
432
|
+
&& nowMs - cached.checkedAtMs < EXTERNAL_VERIFICATION_RESULT_TTL_MS) {
|
|
433
|
+
peer.verificationResults = cached.results;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
_queueExternalVerification(peers) {
|
|
438
|
+
const queued = [];
|
|
439
|
+
const nowMs = Date.now();
|
|
440
|
+
for (const peer of peers) {
|
|
441
|
+
const claimsKey = this._externalVerificationClaimsKey(peer);
|
|
442
|
+
if (!claimsKey)
|
|
443
|
+
continue;
|
|
444
|
+
const cacheKey = `${peer.peerId}:${claimsKey}`;
|
|
445
|
+
if (this._externalVerificationInFlight.has(cacheKey))
|
|
446
|
+
continue;
|
|
447
|
+
const cached = this._externalVerificationCache.get(peer.peerId);
|
|
448
|
+
if (cached
|
|
449
|
+
&& cached.claimsKey === claimsKey
|
|
450
|
+
&& nowMs - cached.checkedAtMs < EXTERNAL_VERIFICATION_RESULT_TTL_MS) {
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
this._externalVerificationInFlight.add(cacheKey);
|
|
454
|
+
queued.push({ ...peer });
|
|
455
|
+
}
|
|
456
|
+
if (queued.length === 0)
|
|
457
|
+
return;
|
|
458
|
+
this._externalVerificationChain = this._externalVerificationChain.then(async () => {
|
|
459
|
+
if (!this._started)
|
|
460
|
+
return;
|
|
461
|
+
const verifiedPeers = await this._verifyExternalClaimsForPeers(queued);
|
|
462
|
+
if (!this._started || verifiedPeers.length === 0)
|
|
463
|
+
return;
|
|
464
|
+
debugLog(`[Node] External verification emitted ${verifiedPeers.length} peer update(s)`);
|
|
465
|
+
this.emit("peers:discovered", verifiedPeers);
|
|
466
|
+
}).catch((err) => {
|
|
467
|
+
debugWarn(`[Node] External verification failed: ${err instanceof Error ? err.message : err}`);
|
|
468
|
+
}).finally(() => {
|
|
469
|
+
for (const peer of queued) {
|
|
470
|
+
const claimsKey = this._externalVerificationClaimsKey(peer);
|
|
471
|
+
if (claimsKey) {
|
|
472
|
+
this._externalVerificationInFlight.delete(`${peer.peerId}:${claimsKey}`);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
async _verifyExternalClaimsForPeers(peers) {
|
|
478
|
+
const queue = peers.slice();
|
|
479
|
+
const verifiedPeers = [];
|
|
480
|
+
const EXTERNAL_VERIFICATION_CONCURRENCY = 2;
|
|
481
|
+
const workers = Array.from({ length: Math.min(EXTERNAL_VERIFICATION_CONCURRENCY, queue.length) }, async () => {
|
|
482
|
+
for (;;) {
|
|
483
|
+
const peer = queue.shift();
|
|
484
|
+
if (!peer)
|
|
485
|
+
return;
|
|
486
|
+
const verified = await this._verifyExternalClaimsForPeer(peer);
|
|
487
|
+
if (verified) {
|
|
488
|
+
verifiedPeers.push(verified);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
await Promise.all(workers);
|
|
493
|
+
return verifiedPeers;
|
|
494
|
+
}
|
|
495
|
+
async _verifyExternalClaimsForPeer(peer) {
|
|
496
|
+
const metadata = peer.metadata;
|
|
497
|
+
const claimsKey = this._externalVerificationClaimsKey(peer);
|
|
498
|
+
if (!metadata || !claimsKey)
|
|
499
|
+
return null;
|
|
500
|
+
try {
|
|
501
|
+
const [domains, github] = await Promise.all([
|
|
502
|
+
verifyPeerMetadataDomains(metadata),
|
|
503
|
+
verifyPeerMetadataGithub(metadata),
|
|
504
|
+
]);
|
|
505
|
+
const checkedAtMs = Date.now();
|
|
506
|
+
const allResults = [...domains, ...github];
|
|
507
|
+
const results = {
|
|
508
|
+
verified: allResults.length > 0 && allResults.every((result) => result.verified),
|
|
509
|
+
checkedAtMs,
|
|
510
|
+
domains,
|
|
511
|
+
github,
|
|
512
|
+
};
|
|
513
|
+
this._externalVerificationCache.set(peer.peerId, {
|
|
514
|
+
claimsKey,
|
|
515
|
+
checkedAtMs,
|
|
516
|
+
results,
|
|
517
|
+
});
|
|
518
|
+
const verifiedPeer = { ...peer, verificationResults: results };
|
|
519
|
+
const risk = typeof verifiedPeer.onChainSybilRisk === 'number'
|
|
520
|
+
? verifiedPeer.onChainSybilRisk
|
|
521
|
+
: 0;
|
|
522
|
+
verifiedPeer.onChainReputationScore = computeOnChainScoreWithRisk(verifiedPeer, risk) ?? verifiedPeer.onChainReputationScore;
|
|
523
|
+
return verifiedPeer;
|
|
524
|
+
}
|
|
525
|
+
catch (err) {
|
|
526
|
+
debugWarn(`[Node] External verification failed for ${peer.peerId.slice(0, 12)}...: ${err instanceof Error ? err.message : err}`);
|
|
527
|
+
return null;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
_externalVerificationClaimsKey(peer) {
|
|
531
|
+
const verifications = peer.metadata?.verifications;
|
|
532
|
+
const domainCount = verifications?.domains?.length ?? 0;
|
|
533
|
+
const githubCount = verifications?.github?.length ?? 0;
|
|
534
|
+
if (domainCount + githubCount === 0)
|
|
535
|
+
return null;
|
|
536
|
+
return JSON.stringify({
|
|
537
|
+
domains: verifications?.domains ?? [],
|
|
538
|
+
github: verifications?.github ?? [],
|
|
539
|
+
});
|
|
540
|
+
}
|
|
391
541
|
/**
|
|
392
542
|
* Look up a single peer by its peerId via the per-peer DHT topic.
|
|
393
543
|
* Much cheaper and more deterministic than walking the wildcard topic:
|
|
@@ -424,6 +574,8 @@ export class AntseedNode extends EventEmitter {
|
|
|
424
574
|
// served metadata matches the id; pick the freshest by timestamp.
|
|
425
575
|
const best = results.reduce((acc, r) => r.metadata.timestamp > acc.metadata.timestamp ? r : acc);
|
|
426
576
|
const peer = this._lookupResultToPeerInfo(best);
|
|
577
|
+
this._attachCachedExternalVerificationResults([peer]);
|
|
578
|
+
this._queueExternalVerification([peer]);
|
|
427
579
|
await this._enrichPeersWithOnChainStats([peer]);
|
|
428
580
|
return peer;
|
|
429
581
|
}
|
|
@@ -542,14 +694,14 @@ export class AntseedNode extends EventEmitter {
|
|
|
542
694
|
getMeteringStatsByPeer(sellerPeerId) {
|
|
543
695
|
const buyerAddress = this._identity?.wallet.address ?? null;
|
|
544
696
|
const channel = (buyerAddress != null)
|
|
545
|
-
? (this._channelStore?.getActiveChannelByPeerAndBuyer(sellerPeerId,
|
|
546
|
-
?? this._channelStore?.getLatestChannelByPeerAndBuyer(sellerPeerId,
|
|
547
|
-
: (this._channelStore?.getActiveChannelByPeer(sellerPeerId,
|
|
548
|
-
?? this._channelStore?.getLatestChannel(sellerPeerId,
|
|
697
|
+
? (this._channelStore?.getActiveChannelByPeerAndBuyer(sellerPeerId, CHANNEL_ROLE.BUYER, buyerAddress)
|
|
698
|
+
?? this._channelStore?.getLatestChannelByPeerAndBuyer(sellerPeerId, CHANNEL_ROLE.BUYER, buyerAddress))
|
|
699
|
+
: (this._channelStore?.getActiveChannelByPeer(sellerPeerId, CHANNEL_ROLE.BUYER)
|
|
700
|
+
?? this._channelStore?.getLatestChannel(sellerPeerId, CHANNEL_ROLE.BUYER))
|
|
549
701
|
?? null;
|
|
550
702
|
const lifetime = (buyerAddress != null)
|
|
551
|
-
? this._channelStore?.getTotalsByPeerAndBuyer(sellerPeerId,
|
|
552
|
-
: this._channelStore?.getTotalsByPeer(sellerPeerId,
|
|
703
|
+
? this._channelStore?.getTotalsByPeerAndBuyer(sellerPeerId, CHANNEL_ROLE.BUYER, buyerAddress)
|
|
704
|
+
: this._channelStore?.getTotalsByPeer(sellerPeerId, CHANNEL_ROLE.BUYER)
|
|
553
705
|
?? null;
|
|
554
706
|
const liveTotals = this._buyerPaymentManager?.getResponseTokenTotals(sellerPeerId);
|
|
555
707
|
const inputTokens = (liveTotals != null) ? liveTotals.input
|
|
@@ -593,7 +745,7 @@ export class AntseedNode extends EventEmitter {
|
|
|
593
745
|
const buyerAddress = this._identity?.wallet.address ?? null;
|
|
594
746
|
if (!buyerAddress || !this._channelStore)
|
|
595
747
|
return [];
|
|
596
|
-
const stored = this._channelStore.getActiveChannelsByBuyer(
|
|
748
|
+
const stored = this._channelStore.getActiveChannelsByBuyer(CHANNEL_ROLE.BUYER, buyerAddress);
|
|
597
749
|
return stored.map((c) => {
|
|
598
750
|
const liveReserve = this._buyerPaymentManager?.getReserveCeiling(c.peerId);
|
|
599
751
|
const reserveMax = (liveReserve != null && liveReserve > 0n)
|
|
@@ -779,6 +931,8 @@ export class AntseedNode extends EventEmitter {
|
|
|
779
931
|
this._decoders.delete(peerId);
|
|
780
932
|
// Clean up buyer-side payment state on disconnect
|
|
781
933
|
this._buyerNegotiator?.onPeerDisconnect(peerId);
|
|
934
|
+
this._buyerFreeUsageManager?.onPeerDisconnect(peerId);
|
|
935
|
+
this._sellerFreeUsageManager?.onPeerDisconnect(peerId);
|
|
782
936
|
// Handle buyer disconnect (seller side)
|
|
783
937
|
if (this._sellerPaymentManager) {
|
|
784
938
|
this._sellerPaymentManager.onBuyerDisconnect(peerId);
|
|
@@ -838,6 +992,7 @@ export class AntseedNode extends EventEmitter {
|
|
|
838
992
|
onSessionFinalized: (info) => this.emit("session:finalized", info),
|
|
839
993
|
});
|
|
840
994
|
await this._initializePayments(dataDir);
|
|
995
|
+
this._warnIfFreeUsageMeteringUnavailable();
|
|
841
996
|
// Wire idle session events to on-chain settlement
|
|
842
997
|
if (this._sellerPaymentManager) {
|
|
843
998
|
const spm = this._sellerPaymentManager;
|
|
@@ -932,6 +1087,7 @@ export class AntseedNode extends EventEmitter {
|
|
|
932
1087
|
identity,
|
|
933
1088
|
providers: this._providers,
|
|
934
1089
|
sellerPaymentManager: this._sellerPaymentManager,
|
|
1090
|
+
sellerFreeUsageManager: this._sellerFreeUsageManager,
|
|
935
1091
|
sessionTracker: this._sessionTracker,
|
|
936
1092
|
channelsClient: this._channelsClient,
|
|
937
1093
|
announcer: this._announcer,
|
|
@@ -1010,7 +1166,7 @@ export class AntseedNode extends EventEmitter {
|
|
|
1010
1166
|
this._buyerPaymentManager = new BuyerPaymentManager(identity, buyerPaymentConfig, this._channelStore, this._sellerAddressResolver ?? undefined);
|
|
1011
1167
|
debugLog(`[Node] Buyer payment manager initialized (wallet=${identity.wallet.address.slice(0, 10)}... chainId=${buyerPaymentConfig.chainId} deposits=${buyerPaymentConfig.depositsContractAddress.slice(0, 10)}...)`);
|
|
1012
1168
|
// Create negotiator that wraps the BPM with 402 handling and per-request auth
|
|
1013
|
-
this._buyerNegotiator = new BuyerPaymentNegotiator(identity, this._buyerPaymentManager, this._depositsClient, this._channelsClient, this._channelStore, {}, this, this._sellerAddressResolver ?? undefined);
|
|
1169
|
+
this._buyerNegotiator = new BuyerPaymentNegotiator(identity, this._buyerPaymentManager, this._depositsClient, this._channelsClient, this._channelStore, {}, this, this._sellerAddressResolver ?? undefined, this._buyerFreeUsageManager);
|
|
1014
1170
|
debugLog(`[Node] Buyer payment negotiator initialized`);
|
|
1015
1171
|
}
|
|
1016
1172
|
}
|
|
@@ -1022,6 +1178,7 @@ export class AntseedNode extends EventEmitter {
|
|
|
1022
1178
|
}, {
|
|
1023
1179
|
localPeerId: identity.peerId,
|
|
1024
1180
|
negotiator: this._buyerNegotiator,
|
|
1181
|
+
freeUsageManager: this._buyerFreeUsageManager,
|
|
1025
1182
|
verificationStorage: this._verificationStorage,
|
|
1026
1183
|
verificationSampler: this._verificationSampler,
|
|
1027
1184
|
getConnection: (peer) => this._getOrCreateConnection(peer),
|
|
@@ -1057,6 +1214,23 @@ export class AntseedNode extends EventEmitter {
|
|
|
1057
1214
|
debugWarn(`[Node] SpendingAuth rejected — SellerPaymentManager not configured`);
|
|
1058
1215
|
});
|
|
1059
1216
|
}
|
|
1217
|
+
if (this._sellerFreeUsageManager) {
|
|
1218
|
+
const freeUsage = this._sellerFreeUsageManager;
|
|
1219
|
+
paymentMux.onFreeUsageOpen((payload) => {
|
|
1220
|
+
freeUsage.handleOpen(buyerPeerId, payload, paymentMux);
|
|
1221
|
+
});
|
|
1222
|
+
paymentMux.onFreeUsageAuth((payload) => {
|
|
1223
|
+
freeUsage.handleAuth(buyerPeerId, payload, paymentMux);
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
else {
|
|
1227
|
+
paymentMux.onFreeUsageOpen(() => {
|
|
1228
|
+
debugWarn(`[Node] FreeUsageOpen ignored — SellerFreeUsageManager not configured`);
|
|
1229
|
+
});
|
|
1230
|
+
paymentMux.onFreeUsageAuth(() => {
|
|
1231
|
+
debugWarn(`[Node] FreeUsageAuth ignored — SellerFreeUsageManager not configured`);
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1060
1234
|
this._paymentMuxes.set(buyerPeerId, paymentMux);
|
|
1061
1235
|
this._verificationMuxes.set(buyerPeerId, verificationMux);
|
|
1062
1236
|
const { mux } = this._sellerHandler.handleConnection(conn, buyerPeerId, paymentMux, verificationMux);
|
|
@@ -1070,6 +1244,17 @@ export class AntseedNode extends EventEmitter {
|
|
|
1070
1244
|
return;
|
|
1071
1245
|
}
|
|
1072
1246
|
const fallbackRpcUrls = payments.fallbackRpcUrls;
|
|
1247
|
+
const paymentsDir = join(dataDir, "payments");
|
|
1248
|
+
// Shared store for paid and free channel accounting.
|
|
1249
|
+
if (!this._channelStore) {
|
|
1250
|
+
try {
|
|
1251
|
+
this._channelStore = new ChannelStore(paymentsDir);
|
|
1252
|
+
debugLog("[Node] ChannelStore initialized");
|
|
1253
|
+
}
|
|
1254
|
+
catch (err) {
|
|
1255
|
+
debugWarn(`[Node] ChannelStore unavailable: ${err instanceof Error ? err.message : err}`);
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1073
1258
|
// Initialize DepositsClient
|
|
1074
1259
|
if (payments.rpcUrl && payments.depositsAddress && payments.usdcAddress) {
|
|
1075
1260
|
this._depositsClient = new DepositsClient({
|
|
@@ -1115,6 +1300,32 @@ export class AntseedNode extends EventEmitter {
|
|
|
1115
1300
|
});
|
|
1116
1301
|
debugLog(`[Node] SellerAddressResolver initialized`);
|
|
1117
1302
|
}
|
|
1303
|
+
// Initialize FreeUsageClient
|
|
1304
|
+
if (payments.rpcUrl && payments.freeUsageAddress) {
|
|
1305
|
+
this._freeUsageClient = new FreeUsageClient({
|
|
1306
|
+
rpcUrl: payments.rpcUrl,
|
|
1307
|
+
...(fallbackRpcUrls ? { fallbackRpcUrls } : {}),
|
|
1308
|
+
contractAddress: payments.freeUsageAddress,
|
|
1309
|
+
...(payments.chainId ? { evmChainId: payments.chainId } : {}),
|
|
1310
|
+
});
|
|
1311
|
+
debugLog(`[Node] FreeUsageClient initialized (contract=${payments.freeUsageAddress.slice(0, 10)}...)`);
|
|
1312
|
+
if (this._identity) {
|
|
1313
|
+
const freeUsageConfig = {
|
|
1314
|
+
rpcUrl: payments.rpcUrl,
|
|
1315
|
+
...(fallbackRpcUrls ? { fallbackRpcUrls } : {}),
|
|
1316
|
+
freeUsageContractAddress: payments.freeUsageAddress,
|
|
1317
|
+
chainId: payments.chainId ?? 8453,
|
|
1318
|
+
};
|
|
1319
|
+
this._buyerFreeUsageManager = new BuyerFreeUsageManager(this._identity, {
|
|
1320
|
+
chainId: freeUsageConfig.chainId,
|
|
1321
|
+
freeUsageContractAddress: freeUsageConfig.freeUsageContractAddress,
|
|
1322
|
+
defaultAuthDurationSecs: payments.defaultAuthDurationSecs ?? 900,
|
|
1323
|
+
}, this._sellerAddressResolver ?? undefined, this._channelStore ?? undefined);
|
|
1324
|
+
if (this._config.role === 'seller') {
|
|
1325
|
+
this._sellerFreeUsageManager = new SellerFreeUsageManager(this._identity, freeUsageConfig);
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1118
1329
|
// Initialize StakingClient
|
|
1119
1330
|
if (payments.rpcUrl && payments.stakingAddress && payments.usdcAddress) {
|
|
1120
1331
|
this._stakingClient = new StakingClient({
|
|
@@ -1136,17 +1347,6 @@ export class AntseedNode extends EventEmitter {
|
|
|
1136
1347
|
});
|
|
1137
1348
|
debugLog(`[Node] IdentityClient initialized (contract=${payments.identityRegistryAddress.slice(0, 10)}...)`);
|
|
1138
1349
|
}
|
|
1139
|
-
// Initialize ChannelStore for persistent payment channels (shared instance)
|
|
1140
|
-
const paymentsDir = join(dataDir, "payments");
|
|
1141
|
-
if (!this._channelStore) {
|
|
1142
|
-
try {
|
|
1143
|
-
this._channelStore = new ChannelStore(paymentsDir);
|
|
1144
|
-
debugLog("[Node] ChannelStore initialized");
|
|
1145
|
-
}
|
|
1146
|
-
catch (err) {
|
|
1147
|
-
debugWarn(`[Node] ChannelStore unavailable: ${err instanceof Error ? err.message : err}`);
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
1350
|
// Initialize SellerPaymentManager for seller role
|
|
1151
1351
|
if (this._config.role === 'seller' && this._identity && this._channelStore &&
|
|
1152
1352
|
payments.rpcUrl && payments.channelsAddress) {
|
|
@@ -1404,6 +1604,32 @@ export class AntseedNode extends EventEmitter {
|
|
|
1404
1604
|
onChainGhostCount: result.metadata.onChainGhostCount,
|
|
1405
1605
|
};
|
|
1406
1606
|
}
|
|
1607
|
+
_warnIfFreeUsageMeteringUnavailable() {
|
|
1608
|
+
if (this._sellerFreeUsageManager || !this._hasFreePricedService())
|
|
1609
|
+
return;
|
|
1610
|
+
const missingAddress = !this._config.payments?.freeUsageAddress;
|
|
1611
|
+
debugWarn(`[Node] Zero-priced service advertised but AntseedFreeUsage is not configured` +
|
|
1612
|
+
`${missingAddress ? ' (payments.freeUsageAddress missing)' : ''}. ` +
|
|
1613
|
+
`Free requests will be served without on-chain usage proofs.`);
|
|
1614
|
+
}
|
|
1615
|
+
_hasFreePricedService() {
|
|
1616
|
+
for (const provider of this._providers) {
|
|
1617
|
+
if (provider.services.length === 0 && this._isZeroPricing(provider.pricing.defaults))
|
|
1618
|
+
return true;
|
|
1619
|
+
for (const service of provider.services) {
|
|
1620
|
+
const servicePricing = provider.pricing.services?.[service] ?? provider.pricing.defaults;
|
|
1621
|
+
if (this._isZeroPricing(servicePricing))
|
|
1622
|
+
return true;
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
return false;
|
|
1626
|
+
}
|
|
1627
|
+
_isZeroPricing(pricing) {
|
|
1628
|
+
const cachedPrice = pricing.cachedInputUsdPerMillion ?? pricing.inputUsdPerMillion;
|
|
1629
|
+
return pricing.inputUsdPerMillion === 0
|
|
1630
|
+
&& pricing.outputUsdPerMillion === 0
|
|
1631
|
+
&& cachedPrice === 0;
|
|
1632
|
+
}
|
|
1407
1633
|
}
|
|
1408
1634
|
function parsePeerAddress(address) {
|
|
1409
1635
|
const parts = address.split(":");
|