@antseed/node 0.2.152 → 0.2.154

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 (125) hide show
  1. package/dist/buyer-identity-context.d.ts +2 -0
  2. package/dist/buyer-identity-context.d.ts.map +1 -1
  3. package/dist/buyer-identity-context.js +1 -0
  4. package/dist/buyer-identity-context.js.map +1 -1
  5. package/dist/discovery/announcer.d.ts +2 -0
  6. package/dist/discovery/announcer.d.ts.map +1 -1
  7. package/dist/discovery/announcer.js +11 -9
  8. package/dist/discovery/announcer.js.map +1 -1
  9. package/dist/health/gas-health-monitor.d.ts +19 -0
  10. package/dist/health/gas-health-monitor.d.ts.map +1 -1
  11. package/dist/health/gas-health-monitor.js +21 -0
  12. package/dist/health/gas-health-monitor.js.map +1 -1
  13. package/dist/health/model-health-checker.d.ts +52 -0
  14. package/dist/health/model-health-checker.d.ts.map +1 -1
  15. package/dist/health/model-health-checker.js +139 -7
  16. package/dist/health/model-health-checker.js.map +1 -1
  17. package/dist/health/seller-events.d.ts +24 -0
  18. package/dist/health/seller-events.d.ts.map +1 -0
  19. package/dist/health/seller-events.js +71 -0
  20. package/dist/health/seller-events.js.map +1 -0
  21. package/dist/health/upstream-credit.d.ts +8 -0
  22. package/dist/health/upstream-credit.d.ts.map +1 -0
  23. package/dist/health/upstream-credit.js +22 -0
  24. package/dist/health/upstream-credit.js.map +1 -0
  25. package/dist/index.d.ts +13 -3
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +7 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/interfaces/seller-provider.d.ts +4 -1
  30. package/dist/interfaces/seller-provider.d.ts.map +1 -1
  31. package/dist/metering/index.d.ts +1 -1
  32. package/dist/metering/index.d.ts.map +1 -1
  33. package/dist/metering/index.js.map +1 -1
  34. package/dist/metering/seller-session-tracker.d.ts +7 -0
  35. package/dist/metering/seller-session-tracker.d.ts.map +1 -1
  36. package/dist/metering/seller-session-tracker.js +29 -0
  37. package/dist/metering/seller-session-tracker.js.map +1 -1
  38. package/dist/metering/storage.d.ts +146 -6
  39. package/dist/metering/storage.d.ts.map +1 -1
  40. package/dist/metering/storage.js +209 -14
  41. package/dist/metering/storage.js.map +1 -1
  42. package/dist/node.d.ts +44 -0
  43. package/dist/node.d.ts.map +1 -1
  44. package/dist/node.js +122 -11
  45. package/dist/node.js.map +1 -1
  46. package/dist/payments/channel-store.d.ts +10 -0
  47. package/dist/payments/channel-store.d.ts.map +1 -1
  48. package/dist/payments/channel-store.js +17 -0
  49. package/dist/payments/channel-store.js.map +1 -1
  50. package/dist/payments/evm/seller-pools-client.d.ts +9 -0
  51. package/dist/payments/evm/seller-pools-client.d.ts.map +1 -1
  52. package/dist/payments/evm/seller-pools-client.js +23 -0
  53. package/dist/payments/evm/seller-pools-client.js.map +1 -1
  54. package/dist/payments/free-tier-delegation.d.ts +65 -0
  55. package/dist/payments/free-tier-delegation.d.ts.map +1 -0
  56. package/dist/payments/free-tier-delegation.js +145 -0
  57. package/dist/payments/free-tier-delegation.js.map +1 -0
  58. package/dist/payments/free-tier-program.d.ts +97 -0
  59. package/dist/payments/free-tier-program.d.ts.map +1 -0
  60. package/dist/payments/free-tier-program.js +267 -0
  61. package/dist/payments/free-tier-program.js.map +1 -0
  62. package/dist/payments/free-tier-stake-resolver.d.ts +79 -0
  63. package/dist/payments/free-tier-stake-resolver.d.ts.map +1 -0
  64. package/dist/payments/free-tier-stake-resolver.js +152 -0
  65. package/dist/payments/free-tier-stake-resolver.js.map +1 -0
  66. package/dist/payments/free-tier-stake.d.ts +101 -0
  67. package/dist/payments/free-tier-stake.d.ts.map +1 -0
  68. package/dist/payments/free-tier-stake.js +116 -0
  69. package/dist/payments/free-tier-stake.js.map +1 -0
  70. package/dist/payments/index.d.ts +7 -1
  71. package/dist/payments/index.d.ts.map +1 -1
  72. package/dist/payments/index.js +3 -0
  73. package/dist/payments/index.js.map +1 -1
  74. package/dist/payments/seller-free-tier-limiter.d.ts +124 -6
  75. package/dist/payments/seller-free-tier-limiter.d.ts.map +1 -1
  76. package/dist/payments/seller-free-tier-limiter.js +342 -32
  77. package/dist/payments/seller-free-tier-limiter.js.map +1 -1
  78. package/dist/payments/seller-free-usage-manager.d.ts.map +1 -1
  79. package/dist/payments/seller-free-usage-manager.js +5 -1
  80. package/dist/payments/seller-free-usage-manager.js.map +1 -1
  81. package/dist/seller-request-handler.d.ts.map +1 -1
  82. package/dist/seller-request-handler.js +113 -19
  83. package/dist/seller-request-handler.js.map +1 -1
  84. package/dist/storage/migrate.d.ts +6 -0
  85. package/dist/storage/migrate.d.ts.map +1 -1
  86. package/dist/storage/migrate.js +11 -0
  87. package/dist/storage/migrate.js.map +1 -1
  88. package/dist/storage/migrations/metering/004_add_free_tier_staked_usage.d.ts +3 -0
  89. package/dist/storage/migrations/metering/004_add_free_tier_staked_usage.d.ts.map +1 -0
  90. package/dist/storage/migrations/metering/004_add_free_tier_staked_usage.js +21 -0
  91. package/dist/storage/migrations/metering/004_add_free_tier_staked_usage.js.map +1 -0
  92. package/dist/storage/migrations/metering/005_add_free_tier_scope.d.ts +8 -0
  93. package/dist/storage/migrations/metering/005_add_free_tier_scope.d.ts.map +1 -0
  94. package/dist/storage/migrations/metering/005_add_free_tier_scope.js +23 -0
  95. package/dist/storage/migrations/metering/005_add_free_tier_scope.js.map +1 -0
  96. package/dist/storage/migrations/metering/006_add_event_service.d.ts +4 -0
  97. package/dist/storage/migrations/metering/006_add_event_service.d.ts.map +1 -0
  98. package/dist/storage/migrations/metering/006_add_event_service.js +11 -0
  99. package/dist/storage/migrations/metering/006_add_event_service.js.map +1 -0
  100. package/dist/storage/migrations/metering/007_add_event_detail.d.ts +4 -0
  101. package/dist/storage/migrations/metering/007_add_event_detail.d.ts.map +1 -0
  102. package/dist/storage/migrations/metering/007_add_event_detail.js +12 -0
  103. package/dist/storage/migrations/metering/007_add_event_detail.js.map +1 -0
  104. package/dist/storage/migrations/metering/008_add_event_request_id.d.ts +4 -0
  105. package/dist/storage/migrations/metering/008_add_event_request_id.d.ts.map +1 -0
  106. package/dist/storage/migrations/metering/008_add_event_request_id.js +10 -0
  107. package/dist/storage/migrations/metering/008_add_event_request_id.js.map +1 -0
  108. package/dist/storage/migrations/metering/009_index_receipts_by_event.d.ts +4 -0
  109. package/dist/storage/migrations/metering/009_index_receipts_by_event.d.ts.map +1 -0
  110. package/dist/storage/migrations/metering/009_index_receipts_by_event.js +9 -0
  111. package/dist/storage/migrations/metering/009_index_receipts_by_event.js.map +1 -0
  112. package/dist/storage/migrations/metering/010_repair_free_tier_usage.d.ts +8 -0
  113. package/dist/storage/migrations/metering/010_repair_free_tier_usage.d.ts.map +1 -0
  114. package/dist/storage/migrations/metering/010_repair_free_tier_usage.js +35 -0
  115. package/dist/storage/migrations/metering/010_repair_free_tier_usage.js.map +1 -0
  116. package/dist/storage/migrations/metering/index.d.ts.map +1 -1
  117. package/dist/storage/migrations/metering/index.js +8 -1
  118. package/dist/storage/migrations/metering/index.js.map +1 -1
  119. package/dist/types/metering.d.ts +8 -0
  120. package/dist/types/metering.d.ts.map +1 -1
  121. package/dist/utils/file-lock.d.ts +12 -0
  122. package/dist/utils/file-lock.d.ts.map +1 -0
  123. package/dist/utils/file-lock.js +58 -0
  124. package/dist/utils/file-lock.js.map +1 -0
  125. package/package.json +11 -3
package/dist/node.js CHANGED
@@ -6,6 +6,7 @@ import { computeTrustScore } from './reputation/trust-score.js';
6
6
  import { TrustSignalsClient } from './payments/evm/trust-signals-client.js';
7
7
  import { loadOrCreateIdentity } from "./p2p/identity.js";
8
8
  import { peerIdToAddress } from "./types/peer.js";
9
+ import { isFreeUnitBillingModel } from "./billing/unit.js";
9
10
  import { MeteringStorage } from "./metering/storage.js";
10
11
  import { ResourceOwnershipStore } from "./resources/resource-ownership-store.js";
11
12
  import { ReceiptGenerator } from "./metering/receipt-generator.js";
@@ -14,7 +15,7 @@ import { ConnectionState } from "./types/connection.js";
14
15
  import { DHTNode, DEFAULT_DHT_CONFIG, SUBNET_COUNT, } from "./discovery/dht-node.js";
15
16
  import { toBootstrapConfig, OFFICIAL_BOOTSTRAP_NODES, mergeBootstrapNodes } from "./discovery/bootstrap.js";
16
17
  import { ConnectionManager, } from "./p2p/connection-manager.js";
17
- import { PeerAnnouncer, } from "./discovery/announcer.js";
18
+ import { PeerAnnouncer, builtinPeerCapabilities, } from "./discovery/announcer.js";
18
19
  import { verifyPeerMetadataDomains } from "./discovery/domain-verification.js";
19
20
  import { verifyPeerMetadataGithub } from "./discovery/github-verification.js";
20
21
  import { PeerLookup, DEFAULT_LOOKUP_CONFIG, } from "./discovery/peer-lookup.js";
@@ -36,11 +37,15 @@ import { signUtf8 } from "./p2p/identity.js";
36
37
  import { BalanceManager, DepositsClient, ChannelsClient, FreeUsageClient, BuyerFreeUsageManager, SellerFreeUsageManager, SellerFreeTierLimiter, StakingClient, ChannelStore, CHANNEL_KIND, CHANNEL_ROLE, CHANNEL_STATUS, } from "./payments/index.js";
37
38
  import { debugLog, debugWarn } from "./utils/debug.js";
38
39
  import { parsePublicAddress } from "./discovery/public-address.js";
40
+ import { MAX_PEER_CAPABILITIES } from "./discovery/metadata-validator.js";
39
41
  import { sanitizePeerDisplayName } from "./discovery/display-name.js";
40
42
  import { BuyerPaymentManager } from "./payments/buyer-payment-manager.js";
41
43
  import { BuyerPaymentNegotiator } from "./payments/buyer-payment-negotiator.js";
42
44
  import { RpcHealthMonitor } from "./payments/rpc-health.js";
43
45
  import { SellerAddressResolver } from "./discovery/seller-address-resolver.js";
46
+ import { SellerPoolsClient } from "./payments/evm/seller-pools-client.js";
47
+ import { FreeTierStakeResolver } from "./payments/free-tier-stake-resolver.js";
48
+ import { encodeFreeTierDelegationsHeader } from "./payments/free-tier-delegation.js";
44
49
  import { Contract as EthersContract } from "ethers";
45
50
  import { SellerPaymentManager } from "./payments/seller-payment-manager.js";
46
51
  import { IdentityClient } from "./payments/evm/identity-client.js";
@@ -154,6 +159,8 @@ export class AntseedNode extends EventEmitter {
154
159
  _buyerIdentities = new Map();
155
160
  /** Seller-side deposit-sweep relayer (initialized when configured + enabled). */
156
161
  _depositRelayer = null;
162
+ /** Settles or closes a buyer's channel when its metering session goes idle; removed on stop. */
163
+ _settleOnIdle = null;
157
164
  /** Seller-side request handler (provider matching, execution, load tracking). */
158
165
  _sellerHandler = null;
159
166
  /** Buyer-side payment manager (initialized when buyer has payment config). */
@@ -328,7 +335,7 @@ export class AntseedNode extends EventEmitter {
328
335
  }
329
336
  const dataDir = this._config.dataDir ?? join(homedir(), ".antseed");
330
337
  // Load or create identity
331
- this._identity = await loadOrCreateIdentity(this._config.identityStore ?? dataDir);
338
+ this._identity = this._config.identity ?? await loadOrCreateIdentity(this._config.identityStore ?? dataDir);
332
339
  debugLog(`[Node] Identity loaded: ${this._identity.peerId.slice(0, 12)}...`);
333
340
  // Determine bootstrap nodes — merge official + any user-configured nodes unless
334
341
  // noOfficialBootstrap is set (e.g. isolated local testing).
@@ -336,11 +343,22 @@ export class AntseedNode extends EventEmitter {
336
343
  ? (this._config.bootstrapNodes ?? [])
337
344
  : mergeBootstrapNodes(OFFICIAL_BOOTSTRAP_NODES, this._config.bootstrapNodes ?? []));
338
345
  debugLog(`[Node] Starting as ${this._config.role} with ${bootstrapNodes.length} bootstrap node(s)`);
339
- if (this._config.role === "seller") {
340
- await this._startSeller(bootstrapNodes);
346
+ try {
347
+ if (this._config.role === "seller") {
348
+ await this._startSeller(bootstrapNodes);
349
+ }
350
+ else {
351
+ await this._startBuyer(bootstrapNodes);
352
+ }
341
353
  }
342
- else {
343
- await this._startBuyer(bootstrapNodes);
354
+ catch (error) {
355
+ // A start that fails partway (say the DHT after the payment store and
356
+ // RPC monitor) releases what it opened, so a retry starts clean.
357
+ this._started = true;
358
+ await this.stop().catch((err) => {
359
+ debugWarn(`[Node] Cleanup after a failed start failed: ${err instanceof Error ? err.message : err}`);
360
+ });
361
+ throw error;
344
362
  }
345
363
  this._started = true;
346
364
  debugLog(`[Node] Started successfully`);
@@ -485,6 +503,12 @@ export class AntseedNode extends EventEmitter {
485
503
  this._buyerHandler = null;
486
504
  this._backgroundPeerDiscoveryPromise = null;
487
505
  this._sellerPaymentManager = null;
506
+ if (this._settleOnIdle) {
507
+ this.off("session:finalized", this._settleOnIdle);
508
+ this._settleOnIdle = null;
509
+ }
510
+ this._depositRelayer = null;
511
+ this._advertisingPausedReason = null;
488
512
  this._sessionTracker = null;
489
513
  this._started = false;
490
514
  this.emit("stopped");
@@ -1231,6 +1255,7 @@ export class AntseedNode extends EventEmitter {
1231
1255
  },
1232
1256
  maxUploadBodyBytes: this._config.maxUploadBodyBytes,
1233
1257
  requireSecureTransport: this._config.requireSecureTransport,
1258
+ freeTierDelegationsHeader: () => this._freeTierDelegationsHeader(identity.wallet.address),
1234
1259
  shared: {
1235
1260
  channelStore: this._channelStore,
1236
1261
  depositsClient: this._depositsClient,
@@ -1454,12 +1479,16 @@ export class AntseedNode extends EventEmitter {
1454
1479
  this._sellerFreeTierLimiter = this._config.freeTier
1455
1480
  ? new SellerFreeTierLimiter(this._config.freeTier, this._metering)
1456
1481
  : null;
1482
+ const offered = this._offeredServicesByPrice();
1483
+ this._sellerFreeTierLimiter?.setPaidServices(offered.paid);
1484
+ this._sellerFreeTierLimiter?.setFreeServices(offered.free);
1457
1485
  await this._initializePayments(dataDir);
1458
1486
  this._warnIfFreeUsageMeteringUnavailable();
1487
+ this._initializeFreeTierStakeResolver(identity);
1459
1488
  // Wire idle session events to on-chain settlement
1460
1489
  if (this._sellerPaymentManager) {
1461
1490
  const spm = this._sellerPaymentManager;
1462
- this.on("session:finalized", (info) => {
1491
+ this._settleOnIdle = (info) => {
1463
1492
  if (info.reason === "idle-settle") {
1464
1493
  debugLog(`[Node] Idle settle for buyer ${info.buyerPeerId.slice(0, 12)}... — settling channel (keeping open)`);
1465
1494
  void spm.settleSession(info.buyerPeerId, { settleOnly: true });
@@ -1468,7 +1497,8 @@ export class AntseedNode extends EventEmitter {
1468
1497
  debugLog(`[Node] Idle timeout for buyer ${info.buyerPeerId.slice(0, 12)}... — closing channel`);
1469
1498
  void spm.settleSession(info.buyerPeerId, { cleanupOnFailure: true });
1470
1499
  }
1471
- });
1500
+ };
1501
+ this.on("session:finalized", this._settleOnIdle);
1472
1502
  }
1473
1503
  // Start DHT
1474
1504
  this._dht = new DHTNode(this._createDHTConfig(dhtPort, bootstrapNodes));
@@ -1506,10 +1536,12 @@ export class AntseedNode extends EventEmitter {
1506
1536
  }
1507
1537
  // Set up announcer for providers
1508
1538
  if (this._providers.length > 0) {
1509
- const extraCapabilities = [
1539
+ const baseCapabilities = [
1510
1540
  ...(this._connectionManager.supportsWebRtc ? [CONNECTION_CAPABILITY_WEBRTC_V1] : []),
1511
1541
  ...(this._config.capabilities ?? []),
1512
1542
  ];
1543
+ const usedCapabilities = builtinPeerCapabilities(this._depositRelayer !== null).length + baseCapabilities.length;
1544
+ const extraCapabilities = [...baseCapabilities, ...this._freeTierCapabilities(usedCapabilities)];
1513
1545
  const announcerConfig = {
1514
1546
  identity,
1515
1547
  dht: this._dht,
@@ -1666,6 +1698,7 @@ export class AntseedNode extends EventEmitter {
1666
1698
  getMux: (peerId, conn) => this._getOrCreateMux(peerId, conn),
1667
1699
  getVerificationMux: (peerId, conn) => this._getOrCreateVerificationMux(peerId, conn),
1668
1700
  registerPaymentMux: (peerId, pmux) => this._paymentMuxes.set(peerId, pmux),
1701
+ freeTierDelegationsHeader: () => this._freeTierDelegationsHeader(identity.wallet.address),
1669
1702
  });
1670
1703
  debugLog(`[Node] Buyer ready — DHT running on port ${this._dht.getPort()}`);
1671
1704
  }
@@ -1841,7 +1874,7 @@ export class AntseedNode extends EventEmitter {
1841
1874
  sellerContracts.set(sellerContract, contract);
1842
1875
  }
1843
1876
  else {
1844
- contract = new EthersContract(sellerContract, isOperatorAbi, channelsClientRef.provider);
1877
+ contract = new EthersContract(sellerContract, isOperatorAbi, payments.readProvider ?? channelsClientRef.provider);
1845
1878
  if (sellerContracts.size >= SELLER_CONTRACTS_MAX) {
1846
1879
  const oldest = sellerContracts.keys().next().value;
1847
1880
  if (oldest !== undefined)
@@ -1894,7 +1927,7 @@ export class AntseedNode extends EventEmitter {
1894
1927
  debugLog(`[Node] StakingClient initialized (contract=${payments.stakingAddress.slice(0, 10)}...)`);
1895
1928
  }
1896
1929
  if (this._channelsClient && payments.stakingAddress && payments.channelsAddress) {
1897
- this._trustSignalsClient = new TrustSignalsClient(this._channelsClient.provider, {
1930
+ this._trustSignalsClient = new TrustSignalsClient(payments.readProvider ?? this._channelsClient.provider, {
1898
1931
  sellerRegistry: payments.stakingAddress,
1899
1932
  channels: payments.channelsAddress,
1900
1933
  ...(payments.sellerPoolsAddress ? { sellerPools: payments.sellerPoolsAddress } : {}),
@@ -2294,6 +2327,84 @@ export class AntseedNode extends EventEmitter {
2294
2327
  onChainGhostCount: result.metadata.onChainGhostCount,
2295
2328
  };
2296
2329
  }
2330
+ /** Replace the buyer's free-tier delegations; later requests send the new set. */
2331
+ setFreeTierDelegations(delegations) {
2332
+ this._config.freeTierDelegations = [...delegations];
2333
+ }
2334
+ /** Header value carrying the unexpired delegations to `buyerAddress`, or null when there are none. */
2335
+ _freeTierDelegationsHeader(buyerAddress) {
2336
+ const nowSeconds = Date.now() / 1000;
2337
+ const delegations = (this._config.freeTierDelegations ?? []).filter((delegation) => delegation.buyer.toLowerCase() === buyerAddress.toLowerCase() && delegation.expiresAt > nowSeconds);
2338
+ return delegations.length > 0 ? encodeFreeTierDelegationsHeader(delegations) : null;
2339
+ }
2340
+ /**
2341
+ * Back staked free-tier tiers with on-chain reads: the positions of the
2342
+ * buyer and of every staker that signed a delegation to it in this seller's
2343
+ * pool. Without the seller pools contract every buyer keeps the base limits
2344
+ * and no tiers are advertised.
2345
+ */
2346
+ /**
2347
+ * Free-tier programs to advertise within what is left of the peer
2348
+ * capability limit. Programs that do not fit are still enforced; buyers
2349
+ * learn them from the seller's refusals instead.
2350
+ */
2351
+ /**
2352
+ * Offered services by whether some provider charges for them (tokens or any
2353
+ * priced unit-billing model), as the request handler decides it. A paid
2354
+ * service's allowance never admits a free-usage channel; the free ones decide admission.
2355
+ */
2356
+ _offeredServicesByPrice() {
2357
+ const paid = new Set();
2358
+ const offered = new Set();
2359
+ for (const provider of this._providers) {
2360
+ for (const service of provider.services) {
2361
+ offered.add(service);
2362
+ const pricing = provider.pricing.services?.[service] ?? provider.pricing.defaults;
2363
+ const tokenPriced = pricing.inputUsdPerMillion > 0 || pricing.outputUsdPerMillion > 0 || (pricing.cachedInputUsdPerMillion ?? 0) > 0;
2364
+ const unitPriced = Object.values(provider.serviceUnitBillingModels?.[service] ?? {})
2365
+ .some((model) => model !== undefined && !isFreeUnitBillingModel(model));
2366
+ if (tokenPriced || unitPriced)
2367
+ paid.add(service);
2368
+ }
2369
+ }
2370
+ return { paid: [...paid], free: [...offered].filter((service) => !paid.has(service)) };
2371
+ }
2372
+ _freeTierCapabilities(usedCapabilities) {
2373
+ const limiter = this._sellerFreeTierLimiter;
2374
+ if (!limiter)
2375
+ return [];
2376
+ const capabilities = limiter.capabilities(MAX_PEER_CAPABILITIES - usedCapabilities);
2377
+ if (capabilities.length < limiter.capabilities().length) {
2378
+ debugWarn(`[Node] Not every free-tier program fits in peer metadata (${MAX_PEER_CAPABILITIES} capabilities max); ` +
2379
+ `the rest are enforced but not advertised`);
2380
+ }
2381
+ return capabilities;
2382
+ }
2383
+ _initializeFreeTierStakeResolver(identity) {
2384
+ const limiter = this._sellerFreeTierLimiter;
2385
+ const payments = this._config.payments;
2386
+ if (!limiter || !limiter.hasStakeTiers)
2387
+ return;
2388
+ if (!payments?.rpcUrl || !payments.sellerPoolsAddress) {
2389
+ debugLog("[Node] Staked free-tier tiers disabled: seller pools contract not configured");
2390
+ return;
2391
+ }
2392
+ const sellerPools = new SellerPoolsClient({
2393
+ rpcUrl: payments.rpcUrl,
2394
+ ...(payments.fallbackRpcUrls ? { fallbackRpcUrls: payments.fallbackRpcUrls } : {}),
2395
+ contractAddress: payments.sellerPoolsAddress,
2396
+ // Only stake writes use the token; the free tier only reads.
2397
+ antsTokenAddress: "0x0000000000000000000000000000000000000000",
2398
+ ...(payments.chainId ? { evmChainId: payments.chainId } : {}),
2399
+ });
2400
+ const sellerAddress = this._config.sellerContract?.sellerContract ?? identity.wallet.address;
2401
+ limiter.setStakeResolver(new FreeTierStakeResolver({
2402
+ sellerAgentId: () => sellerPools.agentIdForSeller(sellerAddress),
2403
+ currentEpoch: () => sellerPools.currentEpoch(),
2404
+ stakerPositions: (staker, agentId, epoch) => sellerPools.stakerPositionsInPool(staker, agentId, epoch),
2405
+ }), payments.chainId ?? 8453);
2406
+ debugLog(`[Node] Staked free-tier tiers enabled (pools=${payments.sellerPoolsAddress.slice(0, 10)}...)`);
2407
+ }
2297
2408
  _warnIfFreeUsageMeteringUnavailable() {
2298
2409
  if (this._sellerFreeUsageManager || !this._hasFreePricedService())
2299
2410
  return;