@antseed/cli 0.1.149 → 0.1.151
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/README.md +38 -19
- package/dist/cli/commands/buyer/activity.d.ts +3 -0
- package/dist/cli/commands/buyer/activity.d.ts.map +1 -0
- package/dist/cli/commands/buyer/activity.js +555 -0
- package/dist/cli/commands/buyer/activity.js.map +1 -0
- package/dist/cli/commands/buyer/daemon.d.ts +13 -0
- package/dist/cli/commands/buyer/daemon.d.ts.map +1 -0
- package/dist/cli/commands/buyer/daemon.js +39 -0
- package/dist/cli/commands/buyer/daemon.js.map +1 -0
- package/dist/cli/commands/buyer/deposit.d.ts +8 -0
- package/dist/cli/commands/buyer/deposit.d.ts.map +1 -1
- package/dist/cli/commands/buyer/deposit.js +338 -25
- package/dist/cli/commands/buyer/deposit.js.map +1 -1
- package/dist/cli/commands/buyer/index.d.ts.map +1 -1
- package/dist/cli/commands/buyer/index.js +2 -0
- package/dist/cli/commands/buyer/index.js.map +1 -1
- package/dist/cli/commands/buyer/start.d.ts.map +1 -1
- package/dist/cli/commands/buyer/start.js +44 -2
- package/dist/cli/commands/buyer/start.js.map +1 -1
- package/dist/cli/commands/buyer/sweep.d.ts.map +1 -1
- package/dist/cli/commands/buyer/sweep.js +17 -17
- package/dist/cli/commands/buyer/sweep.js.map +1 -1
- package/dist/cli/commands/payments.d.ts.map +1 -1
- package/dist/cli/commands/payments.js +29 -34
- package/dist/cli/commands/payments.js.map +1 -1
- package/dist/cli/commands/seller/start.d.ts.map +1 -1
- package/dist/cli/commands/seller/start.js +4 -1
- package/dist/cli/commands/seller/start.js.map +1 -1
- package/dist/cli/commands/seller/start.test.js +15 -0
- package/dist/cli/commands/seller/start.test.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +1 -0
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +2 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/loader.test.js +18 -0
- package/dist/config/loader.test.js.map +1 -1
- package/dist/config/types.d.ts +7 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/generated/baked-defaults.d.ts +15 -0
- package/dist/generated/baked-defaults.d.ts.map +1 -0
- package/dist/generated/baked-defaults.js +15 -0
- package/dist/generated/baked-defaults.js.map +1 -0
- package/dist/plugins/manager.d.ts +1 -0
- package/dist/plugins/manager.d.ts.map +1 -1
- package/dist/plugins/manager.js +15 -4
- package/dist/plugins/manager.js.map +1 -1
- package/dist/plugins/manager.test.d.ts +2 -0
- package/dist/plugins/manager.test.d.ts.map +1 -0
- package/dist/plugins/manager.test.js +15 -0
- package/dist/plugins/manager.test.js.map +1 -0
- package/dist/proxy/buyer-proxy.d.ts +12 -1
- package/dist/proxy/buyer-proxy.d.ts.map +1 -1
- package/dist/proxy/buyer-proxy.js +75 -2
- package/dist/proxy/buyer-proxy.js.map +1 -1
- package/dist/proxy/buyer-proxy.test.js +96 -7
- package/dist/proxy/buyer-proxy.test.js.map +1 -1
- package/dist/proxy/deposit-watcher.d.ts +125 -0
- package/dist/proxy/deposit-watcher.d.ts.map +1 -0
- package/dist/proxy/deposit-watcher.js +306 -0
- package/dist/proxy/deposit-watcher.js.map +1 -0
- package/dist/proxy/deposit-watcher.test.d.ts +2 -0
- package/dist/proxy/deposit-watcher.test.d.ts.map +1 -0
- package/dist/proxy/deposit-watcher.test.js +173 -0
- package/dist/proxy/deposit-watcher.test.js.map +1 -0
- package/dist/proxy/request-utils.js +4 -3
- package/dist/proxy/request-utils.js.map +1 -1
- package/package.json +6 -5
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { getServiceMetadataId } from '@antseed/node';
|
|
5
|
+
import { canonicalModelKey } from '@antseed/node/model-identity';
|
|
6
|
+
import { getGlobalOptions } from '../types.js';
|
|
7
|
+
import { BAKED_COMPARABLE_PRICES_URL } from '../../../generated/baked-defaults.js';
|
|
8
|
+
import { loadConfig } from '../../../config/loader.js';
|
|
9
|
+
import { loadCryptoContext, createChannelsClient, createDepositsClient, createEmissionsClient, requireCryptoConfig, formatAnts, formatUsdc, } from '../../payment-utils.js';
|
|
10
|
+
import { ChannelsClient } from '@antseed/node';
|
|
11
|
+
import { daemonJson } from './daemon.js';
|
|
12
|
+
import { pastEpochs } from '../emissions.js';
|
|
13
|
+
const HISTORY_WINDOWS = [7, 30, 90];
|
|
14
|
+
/**
|
|
15
|
+
* Endpoint serving comparable retail prices for the Saved tile, in the
|
|
16
|
+
* OpenRouter-compatible models schema:
|
|
17
|
+
* `{ data: [{ id, name, pricing: { prompt, completion, input_cache_read } }] }`
|
|
18
|
+
* with prices in USD per token (e.g. set it to OpenRouter's models endpoint).
|
|
19
|
+
* Release builds bake a default via scripts/bake-comparable-prices-url.mjs;
|
|
20
|
+
* with neither env nor baked value, the savings baseline is off. Setting the
|
|
21
|
+
* env to an empty string disables a baked default.
|
|
22
|
+
*/
|
|
23
|
+
const COMPARABLE_PRICES_URL_ENV = 'ANTSEED_COMPARABLE_PRICES_URL';
|
|
24
|
+
const COMPARABLE_PRICES_TIMEOUT_MS = 8_000;
|
|
25
|
+
const CHART_WIDTH = 24;
|
|
26
|
+
const ONCHAIN_READ_CONCURRENCY = 8;
|
|
27
|
+
const MAX_CHANNEL_ROWS = 12;
|
|
28
|
+
function str(raw, key, fallback = '0') {
|
|
29
|
+
const value = raw[key];
|
|
30
|
+
return typeof value === 'string' && value ? value : fallback;
|
|
31
|
+
}
|
|
32
|
+
function num(raw, key) {
|
|
33
|
+
const value = raw[key];
|
|
34
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : 0;
|
|
35
|
+
}
|
|
36
|
+
function normalizeChannelRow(entry) {
|
|
37
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry))
|
|
38
|
+
return null;
|
|
39
|
+
const raw = entry;
|
|
40
|
+
const channelId = str(raw, 'channelId', '') || str(raw, 'sessionId', '');
|
|
41
|
+
if (!channelId)
|
|
42
|
+
return null;
|
|
43
|
+
return {
|
|
44
|
+
channelId,
|
|
45
|
+
peerId: str(raw, 'peerId', ''),
|
|
46
|
+
seller: str(raw, 'seller', ''),
|
|
47
|
+
buyer: str(raw, 'buyer', ''),
|
|
48
|
+
sellerDisplayName: typeof raw['sellerDisplayName'] === 'string' && raw['sellerDisplayName'] ? raw['sellerDisplayName'] : null,
|
|
49
|
+
cumulativeSigned: str(raw, 'cumulativeSigned'),
|
|
50
|
+
reservedAt: num(raw, 'reservedAt'),
|
|
51
|
+
updatedAt: num(raw, 'updatedAt'),
|
|
52
|
+
status: str(raw, 'status', 'unknown'),
|
|
53
|
+
requestCount: num(raw, 'requestCount'),
|
|
54
|
+
// Daemon channel rows name cumulative input tokens `tokensDelivered`
|
|
55
|
+
// (BuyerChannelSummary in @antseed/node).
|
|
56
|
+
inputTokens: str(raw, 'tokensDelivered'),
|
|
57
|
+
outputTokens: str(raw, 'outputTokens'),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function normalizeUsageTotals(value) {
|
|
61
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
62
|
+
return null;
|
|
63
|
+
const raw = value;
|
|
64
|
+
const services = Array.isArray(raw['services'])
|
|
65
|
+
? raw['services'].flatMap((entry) => {
|
|
66
|
+
if (!entry || typeof entry !== 'object')
|
|
67
|
+
return [];
|
|
68
|
+
const service = entry;
|
|
69
|
+
const serviceIdHash = str(service, 'serviceIdHash', '');
|
|
70
|
+
if (!serviceIdHash)
|
|
71
|
+
return [];
|
|
72
|
+
return [{
|
|
73
|
+
serviceIdHash,
|
|
74
|
+
amountUsdc: str(service, 'amountUsdc'),
|
|
75
|
+
inputTokens: str(service, 'inputTokens'),
|
|
76
|
+
cachedInputTokens: str(service, 'cachedInputTokens'),
|
|
77
|
+
outputTokens: str(service, 'outputTokens'),
|
|
78
|
+
requestCount: num(service, 'requestCount'),
|
|
79
|
+
}];
|
|
80
|
+
})
|
|
81
|
+
: [];
|
|
82
|
+
return {
|
|
83
|
+
totalRequests: num(raw, 'totalRequests'),
|
|
84
|
+
totalInputTokens: str(raw, 'totalInputTokens'),
|
|
85
|
+
totalOutputTokens: str(raw, 'totalOutputTokens'),
|
|
86
|
+
totalSettlements: num(raw, 'totalSettlements'),
|
|
87
|
+
uniqueSellers: num(raw, 'uniqueSellers'),
|
|
88
|
+
activeChannels: num(raw, 'activeChannels'),
|
|
89
|
+
services,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function safeBigInt(value) {
|
|
93
|
+
try {
|
|
94
|
+
const parsed = BigInt(value || '0');
|
|
95
|
+
return parsed >= 0n ? parsed : 0n;
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return 0n;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function utcDayStartSeconds(timestampMs) {
|
|
102
|
+
return Math.floor(timestampMs / 86_400_000) * 86_400;
|
|
103
|
+
}
|
|
104
|
+
function buildSpendHistory(channels, days, nowMs = Date.now()) {
|
|
105
|
+
const cutoffSeconds = utcDayStartSeconds(nowMs) - ((days - 1) * 86_400);
|
|
106
|
+
const byDayStart = new Map();
|
|
107
|
+
for (const channel of channels) {
|
|
108
|
+
const timestampMs = channel.updatedAt || channel.reservedAt;
|
|
109
|
+
if (!Number.isFinite(timestampMs) || timestampMs <= 0)
|
|
110
|
+
continue;
|
|
111
|
+
const dayStart = utcDayStartSeconds(timestampMs);
|
|
112
|
+
if (dayStart < cutoffSeconds)
|
|
113
|
+
continue;
|
|
114
|
+
const spent = safeBigInt(channel.cumulativeSigned);
|
|
115
|
+
const tokens = safeBigInt(channel.inputTokens) + safeBigInt(channel.outputTokens);
|
|
116
|
+
if (spent === 0n && tokens === 0n && channel.requestCount === 0)
|
|
117
|
+
continue;
|
|
118
|
+
const previous = byDayStart.get(dayStart);
|
|
119
|
+
byDayStart.set(dayStart, {
|
|
120
|
+
day: new Date(dayStart * 1000).toISOString().slice(0, 10),
|
|
121
|
+
dayStart,
|
|
122
|
+
spentUsdc: (previous?.spentUsdc ?? 0n) + spent,
|
|
123
|
+
tokens: (previous?.tokens ?? 0n) + tokens,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return [...byDayStart.values()].sort((left, right) => left.dayStart - right.dayStart);
|
|
127
|
+
}
|
|
128
|
+
function comparablePricesUrl() {
|
|
129
|
+
const raw = process.env[COMPARABLE_PRICES_URL_ENV];
|
|
130
|
+
if (raw !== undefined) {
|
|
131
|
+
// A set-but-empty env explicitly disables a baked release default.
|
|
132
|
+
return raw.trim() || null;
|
|
133
|
+
}
|
|
134
|
+
return BAKED_COMPARABLE_PRICES_URL;
|
|
135
|
+
}
|
|
136
|
+
async function fetchComparableRetailPrices() {
|
|
137
|
+
const url = comparablePricesUrl();
|
|
138
|
+
if (!url)
|
|
139
|
+
return null;
|
|
140
|
+
try {
|
|
141
|
+
const res = await fetch(url, { signal: AbortSignal.timeout(COMPARABLE_PRICES_TIMEOUT_MS) });
|
|
142
|
+
if (!res.ok)
|
|
143
|
+
return null;
|
|
144
|
+
const body = await res.json();
|
|
145
|
+
if (!Array.isArray(body?.data))
|
|
146
|
+
return null;
|
|
147
|
+
const perMillion = (pricePerToken) => {
|
|
148
|
+
const numeric = Number(pricePerToken);
|
|
149
|
+
return Number.isFinite(numeric) && numeric > 0 ? numeric * 1_000_000 : null;
|
|
150
|
+
};
|
|
151
|
+
const map = new Map();
|
|
152
|
+
for (const model of body.data) {
|
|
153
|
+
const price = {
|
|
154
|
+
input: perMillion(model.pricing?.prompt),
|
|
155
|
+
output: perMillion(model.pricing?.completion),
|
|
156
|
+
cachedInput: perMillion(model.pricing?.input_cache_read),
|
|
157
|
+
};
|
|
158
|
+
if (price.input === null && price.output === null)
|
|
159
|
+
continue;
|
|
160
|
+
for (const rawName of [model.id, model.name]) {
|
|
161
|
+
if (typeof rawName !== 'string' || !rawName.trim())
|
|
162
|
+
continue;
|
|
163
|
+
const key = canonicalModelKey(rawName);
|
|
164
|
+
if (key && !map.has(key))
|
|
165
|
+
map.set(key, price);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return map.size > 0 ? map : null;
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Usage attributes spend per keccak256(serviceName); hashing is one-way, so
|
|
176
|
+
* rebuild the reverse map from every service name the buyer has seen
|
|
177
|
+
* advertised in buyer.state.json.
|
|
178
|
+
*/
|
|
179
|
+
async function resolveServiceNames(dataDir, hashes) {
|
|
180
|
+
const resolved = new Map();
|
|
181
|
+
const wanted = new Set(hashes.map((hash) => hash.toLowerCase()));
|
|
182
|
+
try {
|
|
183
|
+
const raw = await readFile(join(dataDir, 'buyer.state.json'), 'utf-8');
|
|
184
|
+
const parsed = JSON.parse(raw);
|
|
185
|
+
for (const peer of parsed.discoveredPeers ?? []) {
|
|
186
|
+
if (!Array.isArray(peer?.services))
|
|
187
|
+
continue;
|
|
188
|
+
for (const service of peer.services) {
|
|
189
|
+
if (typeof service !== 'string' || !service.trim())
|
|
190
|
+
continue;
|
|
191
|
+
try {
|
|
192
|
+
const hash = getServiceMetadataId(service.trim()).toLowerCase();
|
|
193
|
+
if (wanted.has(hash))
|
|
194
|
+
resolved.set(hash, service.trim());
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
// hashing never throws for plain strings — belt and braces
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
// no buyer state yet — nothing resolves, savings shows as unavailable
|
|
204
|
+
}
|
|
205
|
+
return resolved;
|
|
206
|
+
}
|
|
207
|
+
function computeMeasuredSavings(services, names, referenceMap) {
|
|
208
|
+
let actualUsd = 0;
|
|
209
|
+
let baselineUsd = 0;
|
|
210
|
+
let matchedServices = 0;
|
|
211
|
+
const tokens = (value) => {
|
|
212
|
+
const numeric = Number(value);
|
|
213
|
+
return Number.isFinite(numeric) && numeric >= 0 ? numeric : 0;
|
|
214
|
+
};
|
|
215
|
+
for (const service of services) {
|
|
216
|
+
const name = names.get(service.serviceIdHash.toLowerCase());
|
|
217
|
+
if (!name)
|
|
218
|
+
continue;
|
|
219
|
+
const ref = referenceMap.get(canonicalModelKey(name));
|
|
220
|
+
if (!ref || (ref.input === null && ref.output === null))
|
|
221
|
+
continue;
|
|
222
|
+
// Buyer-side inputTokens are total logical input (fresh + cached).
|
|
223
|
+
const totalInput = tokens(service.inputTokens);
|
|
224
|
+
const cached = Math.min(tokens(service.cachedInputTokens), totalInput);
|
|
225
|
+
const freshInput = totalInput - cached;
|
|
226
|
+
const output = tokens(service.outputTokens);
|
|
227
|
+
if (totalInput === 0 && output === 0)
|
|
228
|
+
continue;
|
|
229
|
+
const inputPrice = ref.input ?? 0;
|
|
230
|
+
const cachedPrice = ref.cachedInput ?? inputPrice;
|
|
231
|
+
const outputPrice = ref.output ?? 0;
|
|
232
|
+
const serviceBaseline = (freshInput * inputPrice + cached * cachedPrice + output * outputPrice) / 1_000_000;
|
|
233
|
+
if (serviceBaseline <= 0)
|
|
234
|
+
continue;
|
|
235
|
+
baselineUsd += serviceBaseline;
|
|
236
|
+
actualUsd += tokens(service.amountUsdc) / 1_000_000;
|
|
237
|
+
matchedServices += 1;
|
|
238
|
+
}
|
|
239
|
+
if (matchedServices === 0 || baselineUsd <= 0)
|
|
240
|
+
return null;
|
|
241
|
+
const pct = Math.round(Math.max(0, Math.min(1, 1 - actualUsd / baselineUsd)) * 100);
|
|
242
|
+
return { pct, actualUsd, baselineUsd, matchedServices };
|
|
243
|
+
}
|
|
244
|
+
// ─── Formatting ───
|
|
245
|
+
function formatCompactTokens(total) {
|
|
246
|
+
const value = Number(total);
|
|
247
|
+
if (value >= 1e9)
|
|
248
|
+
return `${(value / 1e9).toFixed(1)}B`;
|
|
249
|
+
if (value >= 1e6)
|
|
250
|
+
return `${(value / 1e6).toFixed(1)}M`;
|
|
251
|
+
if (value >= 1e3)
|
|
252
|
+
return `${(value / 1e3).toFixed(1)}k`;
|
|
253
|
+
return total.toString();
|
|
254
|
+
}
|
|
255
|
+
function formatUsd(baseUnits) {
|
|
256
|
+
const whole = baseUnits / 1000000n;
|
|
257
|
+
const cents = (baseUnits % 1000000n) / 10000n;
|
|
258
|
+
return `$${whole}.${cents.toString().padStart(2, '0')}`;
|
|
259
|
+
}
|
|
260
|
+
function formatSavedUsd(usd) {
|
|
261
|
+
if (!Number.isFinite(usd) || usd <= 0)
|
|
262
|
+
return '$0';
|
|
263
|
+
if (usd < 0.01)
|
|
264
|
+
return '<$0.01';
|
|
265
|
+
if (usd >= 1000)
|
|
266
|
+
return `$${(usd / 1000).toFixed(1)}k`;
|
|
267
|
+
return `$${usd.toFixed(2)}`;
|
|
268
|
+
}
|
|
269
|
+
function isCurrentChannelStatus(status) {
|
|
270
|
+
return status === 'active' || status === 'open' || status === 'closing' || status === 'withdrawable';
|
|
271
|
+
}
|
|
272
|
+
function sumBigints(values) {
|
|
273
|
+
let total = 0n;
|
|
274
|
+
for (const value of values)
|
|
275
|
+
total += typeof value === 'bigint' ? value : safeBigInt(value);
|
|
276
|
+
return total;
|
|
277
|
+
}
|
|
278
|
+
async function runInBatches(items, batchSize, task) {
|
|
279
|
+
for (let index = 0; index < items.length; index += batchSize) {
|
|
280
|
+
await Promise.allSettled(items.slice(index, index + batchSize).map(task));
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// ─── On-chain reads (each degrades to null/empty on failure) ───
|
|
284
|
+
async function fetchDepositsBalance(config, address) {
|
|
285
|
+
try {
|
|
286
|
+
return await createDepositsClient(config).getBuyerBalance(address);
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
async function fetchClaimableRewards(config, address) {
|
|
293
|
+
try {
|
|
294
|
+
const emissionsClient = createEmissionsClient(config);
|
|
295
|
+
const epochInfo = await emissionsClient.getEpochInfo();
|
|
296
|
+
const pending = await emissionsClient.pendingEmissions(address, pastEpochs(epochInfo.epoch));
|
|
297
|
+
return { pendingAnts: pending.buyer, epoch: epochInfo.epoch };
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
return null; // no emissions contract on this chain / RPC unreachable
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
async function readOnChainChannelState(config, rows) {
|
|
304
|
+
const state = { locked: new Map(), status: new Map() };
|
|
305
|
+
try {
|
|
306
|
+
const crypto = requireCryptoConfig(config);
|
|
307
|
+
const channelsClient = createChannelsClient(config);
|
|
308
|
+
// Channels with a delegated seller live behind the seller's facade
|
|
309
|
+
// contract (the row's `seller` is the contract, e.g. DiemStakingProxy) —
|
|
310
|
+
// ChannelsClient probes `channelsAddress()` on it to find the underlying
|
|
311
|
+
// channels deployment.
|
|
312
|
+
const facadeClients = new Map();
|
|
313
|
+
const facadeClientFor = (seller) => {
|
|
314
|
+
const key = seller.toLowerCase();
|
|
315
|
+
let client = facadeClients.get(key);
|
|
316
|
+
if (!client) {
|
|
317
|
+
client = new ChannelsClient({
|
|
318
|
+
rpcUrl: crypto.rpcUrl,
|
|
319
|
+
...(crypto.fallbackRpcUrls && crypto.fallbackRpcUrls.length > 0 ? { fallbackRpcUrls: crypto.fallbackRpcUrls } : {}),
|
|
320
|
+
contractAddress: seller,
|
|
321
|
+
evmChainId: crypto.evmChainId,
|
|
322
|
+
});
|
|
323
|
+
facadeClients.set(key, client);
|
|
324
|
+
}
|
|
325
|
+
return client;
|
|
326
|
+
};
|
|
327
|
+
await runInBatches(rows, ONCHAIN_READ_CONCURRENCY, async (row) => {
|
|
328
|
+
let info = await channelsClient.getSession(row.channelId);
|
|
329
|
+
if (info.status === 0 && /^0x[0-9a-fA-F]{40}$/.test(row.seller)) {
|
|
330
|
+
info = await facadeClientFor(row.seller).getSession(row.channelId).catch(() => info);
|
|
331
|
+
}
|
|
332
|
+
// Record status 0 too: a successful read with no record anywhere means
|
|
333
|
+
// the seller never landed reserve() on-chain (or the channel predates a
|
|
334
|
+
// Channels redeployment) — distinct from a failed read, where nothing
|
|
335
|
+
// is recorded and the amount stays genuinely unknown.
|
|
336
|
+
state.status.set(row.channelId, { status: info.status, closeRequestedAt: Number(info.closeRequestedAt) });
|
|
337
|
+
if (info.status === 0)
|
|
338
|
+
return;
|
|
339
|
+
if (info.status !== 1)
|
|
340
|
+
return; // settled/timed-out: nothing is held any more
|
|
341
|
+
const deposit = BigInt(info.deposit.toString());
|
|
342
|
+
const settled = BigInt(info.settled.toString());
|
|
343
|
+
const signed = safeBigInt(row.cumulativeSigned);
|
|
344
|
+
const spent = signed > settled ? signed : settled;
|
|
345
|
+
state.locked.set(row.channelId, {
|
|
346
|
+
reserve: deposit > settled ? deposit - settled : 0n,
|
|
347
|
+
recoverable: deposit > spent ? deposit - spent : 0n,
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
// chain unreachable — channel rows render without locked amounts
|
|
353
|
+
}
|
|
354
|
+
return state;
|
|
355
|
+
}
|
|
356
|
+
// ─── Command ───
|
|
357
|
+
export function registerBuyerActivityCommand(buyerCmd) {
|
|
358
|
+
buyerCmd
|
|
359
|
+
.command('activity')
|
|
360
|
+
.description('Activity summary: tokens, spending history, measured savings, active channels, and claimable ANTS rewards')
|
|
361
|
+
.option('--days <n>', `Spending window in days (${HISTORY_WINDOWS.join(', ')})`, '7')
|
|
362
|
+
.option('--json', 'Output JSON')
|
|
363
|
+
.action(async (options) => {
|
|
364
|
+
const globalOpts = getGlobalOptions(buyerCmd);
|
|
365
|
+
const config = await loadConfig(globalOpts.config);
|
|
366
|
+
const days = HISTORY_WINDOWS.includes(Number(options.days)) ? Number(options.days) : 7;
|
|
367
|
+
const proxyPort = config.buyer.proxyPort;
|
|
368
|
+
const [channelsBody, usageBody] = await Promise.all([
|
|
369
|
+
daemonJson(proxyPort, '/_antseed/channels?all=1'),
|
|
370
|
+
daemonJson(proxyPort, '/_antseed/buyer-usage'),
|
|
371
|
+
]);
|
|
372
|
+
if (!channelsBody || !usageBody) {
|
|
373
|
+
console.error(chalk.red(`No buyer connection reachable on port ${proxyPort}.`));
|
|
374
|
+
console.error(chalk.dim('Activity is served by the running connection — start it with `antseed buyer start`.'));
|
|
375
|
+
process.exit(1);
|
|
376
|
+
}
|
|
377
|
+
const channels = Array.isArray(channelsBody['channels'])
|
|
378
|
+
? channelsBody['channels'].map(normalizeChannelRow).filter((row) => row !== null)
|
|
379
|
+
: [];
|
|
380
|
+
const usage = normalizeUsageTotals(usageBody['totals']);
|
|
381
|
+
// The daemon may run with a different key than the local identity.key
|
|
382
|
+
// (the desktop injects its managed key via ANTSEED_IDENTITY_HEX), so
|
|
383
|
+
// take the buyer address from the daemon's own channel rows and only
|
|
384
|
+
// fall back to the local identity when there are none.
|
|
385
|
+
const address = channels.find((row) => row.buyer)?.buyer
|
|
386
|
+
?? (await loadCryptoContext(globalOpts.dataDir)).address;
|
|
387
|
+
// Savings baseline, balances, rewards, and on-chain channel state in
|
|
388
|
+
// parallel; each degrades to "unavailable" on its own without failing
|
|
389
|
+
// the summary.
|
|
390
|
+
const currentChannels = channels.filter((row) => isCurrentChannelStatus(row.status));
|
|
391
|
+
const [referenceMap, serviceNames, deposits, rewards, onChain] = await Promise.all([
|
|
392
|
+
fetchComparableRetailPrices(),
|
|
393
|
+
resolveServiceNames(globalOpts.dataDir, (usage?.services ?? []).map((s) => s.serviceIdHash)),
|
|
394
|
+
fetchDepositsBalance(config, address),
|
|
395
|
+
fetchClaimableRewards(config, address),
|
|
396
|
+
readOnChainChannelState(config, currentChannels),
|
|
397
|
+
]);
|
|
398
|
+
const locked = onChain.locked;
|
|
399
|
+
const onChainStatus = onChain.status;
|
|
400
|
+
const savings = usage && referenceMap
|
|
401
|
+
? computeMeasuredSavings(usage.services, serviceNames, referenceMap)
|
|
402
|
+
: null;
|
|
403
|
+
const history = buildSpendHistory(channels, days);
|
|
404
|
+
const totalSpent = sumBigints(channels.map((row) => row.cumulativeSigned));
|
|
405
|
+
const totalTokens = usage
|
|
406
|
+
? safeBigInt(usage.totalInputTokens) + safeBigInt(usage.totalOutputTokens)
|
|
407
|
+
: sumBigints(channels.flatMap((row) => [row.inputTokens, row.outputTokens]));
|
|
408
|
+
const windowSpent = sumBigints(history.map((day) => day.spentUsdc));
|
|
409
|
+
const windowTokens = sumBigints(history.map((day) => day.tokens));
|
|
410
|
+
// The chain is the authority on liveness: locally-"active" rows whose
|
|
411
|
+
// on-chain record says settled/timed-out are history, not active. Among
|
|
412
|
+
// live rows, keep those whose reserve is still held (or unknown) — a
|
|
413
|
+
// fully signed-away channel shows "no funds locked" but stays closable.
|
|
414
|
+
const effectiveStatus = (row) => {
|
|
415
|
+
const chain = onChainStatus.get(row.channelId);
|
|
416
|
+
if (!chain)
|
|
417
|
+
return row.status;
|
|
418
|
+
if (chain.status === 2)
|
|
419
|
+
return 'settled';
|
|
420
|
+
if (chain.status === 3)
|
|
421
|
+
return 'timedout';
|
|
422
|
+
if (chain.status === 1 && chain.closeRequestedAt > 0)
|
|
423
|
+
return 'closing';
|
|
424
|
+
return row.status;
|
|
425
|
+
};
|
|
426
|
+
// Confirmed no-record rows (the seller never landed reserve()) hold no
|
|
427
|
+
// funds and have nothing to close — they are local bookkeeping, not
|
|
428
|
+
// activity, so they are counted but not listed.
|
|
429
|
+
const currentByChain = currentChannels.filter((row) => isCurrentChannelStatus(effectiveStatus(row)));
|
|
430
|
+
const unreservedCount = currentByChain
|
|
431
|
+
.filter((row) => onChainStatus.get(row.channelId)?.status === 0)
|
|
432
|
+
.length;
|
|
433
|
+
const activeRows = currentByChain
|
|
434
|
+
.filter((row) => onChainStatus.get(row.channelId)?.status !== 0)
|
|
435
|
+
.filter((row) => !locked.has(row.channelId) || locked.get(row.channelId).reserve > 0n)
|
|
436
|
+
.sort((left, right) => {
|
|
437
|
+
const leftLocked = locked.get(left.channelId)?.recoverable ?? -1n;
|
|
438
|
+
const rightLocked = locked.get(right.channelId)?.recoverable ?? -1n;
|
|
439
|
+
if (leftLocked !== rightLocked)
|
|
440
|
+
return rightLocked > leftLocked ? 1 : -1;
|
|
441
|
+
return (right.reservedAt || 0) - (left.reservedAt || 0);
|
|
442
|
+
});
|
|
443
|
+
if (options.json) {
|
|
444
|
+
console.log(JSON.stringify({
|
|
445
|
+
usage,
|
|
446
|
+
totals: { tokens: totalTokens.toString(), spentUsdcBaseUnits: totalSpent.toString() },
|
|
447
|
+
savings,
|
|
448
|
+
spending: {
|
|
449
|
+
days,
|
|
450
|
+
spentUsdcBaseUnits: windowSpent.toString(),
|
|
451
|
+
tokens: windowTokens.toString(),
|
|
452
|
+
byDay: history.map((day) => ({ day: day.day, spentUsdcBaseUnits: day.spentUsdc.toString(), tokens: day.tokens.toString() })),
|
|
453
|
+
},
|
|
454
|
+
channels: activeRows.map((row) => ({
|
|
455
|
+
...row,
|
|
456
|
+
status: effectiveStatus(row),
|
|
457
|
+
lockedBaseUnits: locked.get(row.channelId)?.recoverable.toString() ?? null,
|
|
458
|
+
onChainReserveBaseUnits: locked.get(row.channelId)?.reserve.toString() ?? null,
|
|
459
|
+
onChainStatus: onChainStatus.get(row.channelId)?.status ?? null,
|
|
460
|
+
})),
|
|
461
|
+
unreservedChannels: unreservedCount,
|
|
462
|
+
deposits: deposits
|
|
463
|
+
? { available: deposits.available.toString(), reserved: deposits.reserved.toString() }
|
|
464
|
+
: null,
|
|
465
|
+
rewards: rewards
|
|
466
|
+
? { pendingAntsBaseUnits: rewards.pendingAnts.toString(), pendingAnts: formatAnts(rewards.pendingAnts), epoch: rewards.epoch }
|
|
467
|
+
: null,
|
|
468
|
+
}, null, 2));
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
console.log('');
|
|
472
|
+
console.log(chalk.bold('Activity'));
|
|
473
|
+
console.log('');
|
|
474
|
+
let savedLabel;
|
|
475
|
+
if (savings) {
|
|
476
|
+
savedLabel = `${formatSavedUsd(savings.baselineUsd - savings.actualUsd)} (${savings.pct}% vs retail, ${savings.matchedServices} matched model${savings.matchedServices === 1 ? '' : 's'})`;
|
|
477
|
+
}
|
|
478
|
+
else if ((usage?.totalRequests ?? 0) === 0) {
|
|
479
|
+
savedLabel = '$0';
|
|
480
|
+
}
|
|
481
|
+
else if (!comparablePricesUrl()) {
|
|
482
|
+
savedLabel = chalk.dim(`off — set ${COMPARABLE_PRICES_URL_ENV} to a retail-prices models API`);
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
savedLabel = chalk.dim('unavailable');
|
|
486
|
+
}
|
|
487
|
+
console.log(` Tokens ${chalk.bold(formatCompactTokens(totalTokens))} · Spent ${chalk.bold(formatUsd(totalSpent))} · Saved ${chalk.bold(savedLabel)}`);
|
|
488
|
+
console.log('');
|
|
489
|
+
console.log(chalk.bold(`Spending — last ${days} days`) + chalk.dim(` ${formatCompactTokens(windowTokens)} tokens · ${formatUsd(windowSpent)}`));
|
|
490
|
+
if (history.length === 0) {
|
|
491
|
+
console.log(chalk.dim(' No spending in this window.'));
|
|
492
|
+
}
|
|
493
|
+
else {
|
|
494
|
+
const maxSpent = history.reduce((max, day) => (day.spentUsdc > max ? day.spentUsdc : max), 1n);
|
|
495
|
+
for (const day of history) {
|
|
496
|
+
const width = Number((day.spentUsdc * BigInt(CHART_WIDTH)) / maxSpent);
|
|
497
|
+
const bar = '█'.repeat(Math.max(day.spentUsdc > 0n ? 1 : 0, width));
|
|
498
|
+
console.log(` ${day.day} ${chalk.green(bar.padEnd(CHART_WIDTH))} ${formatUsd(day.spentUsdc)}`);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
console.log('');
|
|
502
|
+
const totalLocked = sumBigints([...locked.values()].map((entry) => entry.recoverable));
|
|
503
|
+
console.log(chalk.bold('Active channels') + chalk.dim(locked.size > 0 ? ` ${formatUsd(totalLocked)} locked` : ''));
|
|
504
|
+
if (unreservedCount > 0) {
|
|
505
|
+
console.log(chalk.dim(` (${unreservedCount} locally-tracked channel${unreservedCount === 1 ? '' : 's'} with no on-chain record hidden — nothing is locked for them)`));
|
|
506
|
+
}
|
|
507
|
+
if (activeRows.length === 0) {
|
|
508
|
+
console.log(chalk.dim(' No active channels.'));
|
|
509
|
+
}
|
|
510
|
+
else {
|
|
511
|
+
for (const row of activeRows.slice(0, MAX_CHANNEL_ROWS)) {
|
|
512
|
+
const name = row.sellerDisplayName ?? `${row.seller.slice(0, 8)}…${row.seller.slice(-4)}`;
|
|
513
|
+
const entry = locked.get(row.channelId);
|
|
514
|
+
let lockedAmount;
|
|
515
|
+
if (!entry) {
|
|
516
|
+
lockedAmount = chalk.dim('locked amount unavailable');
|
|
517
|
+
}
|
|
518
|
+
else if (entry.recoverable === 0n) {
|
|
519
|
+
lockedAmount = chalk.dim('no funds locked');
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
lockedAmount = `${formatUsd(entry.recoverable)} locked`;
|
|
523
|
+
}
|
|
524
|
+
console.log(` ${name.padEnd(24)} ${effectiveStatus(row).padEnd(12)} ${lockedAmount}`);
|
|
525
|
+
console.log(chalk.dim(` ${row.channelId}`));
|
|
526
|
+
}
|
|
527
|
+
if (activeRows.length > MAX_CHANNEL_ROWS) {
|
|
528
|
+
console.log(chalk.dim(` … ${activeRows.length - MAX_CHANNEL_ROWS} more — see \`antseed buyer channels\``));
|
|
529
|
+
}
|
|
530
|
+
console.log('');
|
|
531
|
+
console.log(chalk.dim(' Close a channel with `antseed buyer channels close <channelId>` — asks the seller to settle and release the remainder instantly.'));
|
|
532
|
+
console.log(chalk.dim(' If the seller is unreachable, `antseed buyer channels request-close <channelId>` starts an on-chain close; after the'));
|
|
533
|
+
console.log(chalk.dim(' 15-minute grace period, `antseed buyer channels withdraw <channelId>` reclaims the remaining locked funds.'));
|
|
534
|
+
}
|
|
535
|
+
console.log('');
|
|
536
|
+
if (rewards) {
|
|
537
|
+
console.log(chalk.bold('Rewards') + chalk.dim(` epoch ${rewards.epoch}`));
|
|
538
|
+
if (rewards.pendingAnts > 0n) {
|
|
539
|
+
console.log(` ${chalk.green(`${formatAnts(rewards.pendingAnts)} ANTS`)} available to claim — run \`${chalk.bold('antseed buyer emissions claim')}\``);
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
console.log(chalk.dim(' No ANTS available to claim yet.'));
|
|
543
|
+
}
|
|
544
|
+
console.log('');
|
|
545
|
+
}
|
|
546
|
+
if (deposits) {
|
|
547
|
+
console.log(chalk.dim(`Deposits: ${formatUsdc(deposits.available)} USDC available · ${formatUsdc(deposits.reserved)} USDC reserved`));
|
|
548
|
+
}
|
|
549
|
+
if (usage) {
|
|
550
|
+
console.log(chalk.dim(`Lifetime: ${usage.totalRequests} requests · ${usage.uniqueSellers} sellers · ${usage.totalSettlements} settlements`));
|
|
551
|
+
}
|
|
552
|
+
console.log('');
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
//# sourceMappingURL=activity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity.js","sourceRoot":"","sources":["../../../../src/cli/commands/buyer/activity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Shared HTTP helpers for the running buyer daemon's control plane. */
|
|
2
|
+
import type { DepositWatcherStatus } from '../../../proxy/deposit-watcher.js';
|
|
3
|
+
/** Fetch against the local buyer daemon; null when nothing is listening. */
|
|
4
|
+
export declare function daemonFetch(port: number, path: string, init?: RequestInit, timeoutMs?: number): Promise<Response | null>;
|
|
5
|
+
/** GET a control-plane endpoint as a JSON object; null on any failure. */
|
|
6
|
+
export declare function daemonJson(port: number, path: string, timeoutMs?: number): Promise<Record<string, unknown> | null>;
|
|
7
|
+
export interface DaemonDepositsStatus {
|
|
8
|
+
watcher: boolean;
|
|
9
|
+
status: DepositWatcherStatus | null;
|
|
10
|
+
}
|
|
11
|
+
export declare function daemonDepositsStatus(port: number): Promise<DaemonDepositsStatus | null>;
|
|
12
|
+
export declare function daemonSetWatchMode(port: number, mode: 'active' | 'background'): Promise<boolean>;
|
|
13
|
+
//# sourceMappingURL=daemon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/buyer/daemon.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AAE7E,4EAA4E;AAC5E,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,WAAW,EAClB,SAAS,SAAS,GACjB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAS1B;AAED,0EAA0E;AAC1E,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,SAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAKvH;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAA;CACpC;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAO7F;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAQtG"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** Fetch against the local buyer daemon; null when nothing is listening. */
|
|
2
|
+
export async function daemonFetch(port, path, init, timeoutMs = 10_000) {
|
|
3
|
+
try {
|
|
4
|
+
return await fetch(`http://127.0.0.1:${port}${path}`, {
|
|
5
|
+
...init,
|
|
6
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** GET a control-plane endpoint as a JSON object; null on any failure. */
|
|
14
|
+
export async function daemonJson(port, path, timeoutMs = 5_000) {
|
|
15
|
+
const res = await daemonFetch(port, path, undefined, timeoutMs);
|
|
16
|
+
if (!res?.ok)
|
|
17
|
+
return null;
|
|
18
|
+
const body = await res.json().catch(() => null);
|
|
19
|
+
return body && typeof body === 'object' && !Array.isArray(body) ? body : null;
|
|
20
|
+
}
|
|
21
|
+
export async function daemonDepositsStatus(port) {
|
|
22
|
+
const body = await daemonJson(port, '/_antseed/deposits/status', 2_000);
|
|
23
|
+
if (!body || body['ok'] !== true)
|
|
24
|
+
return null;
|
|
25
|
+
return {
|
|
26
|
+
watcher: body['watcher'] === true,
|
|
27
|
+
status: (body['status'] ?? null),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export async function daemonSetWatchMode(port, mode) {
|
|
31
|
+
const res = await daemonFetch(port, '/_antseed/deposits/watch', {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: { 'content-type': 'application/json' },
|
|
34
|
+
body: JSON.stringify({ mode }),
|
|
35
|
+
}, 5_000);
|
|
36
|
+
const body = await res?.json().catch(() => null);
|
|
37
|
+
return body?.ok === true;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=daemon.js.map
|