@reppo/cli 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/api/public.d.ts +12 -0
- package/dist/api/public.d.ts.map +1 -0
- package/dist/api/public.js +66 -0
- package/dist/api/public.js.map +1 -0
- package/dist/bin.js +5 -1
- package/dist/bin.js.map +1 -1
- package/dist/commands/list/datanets.d.ts +10 -0
- package/dist/commands/list/datanets.d.ts.map +1 -0
- package/dist/commands/list/datanets.js +144 -0
- package/dist/commands/list/datanets.js.map +1 -0
- package/dist/commands/list/pods.d.ts +16 -0
- package/dist/commands/list/pods.d.ts.map +1 -0
- package/dist/commands/list/pods.js +237 -0
- package/dist/commands/list/pods.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,6 +47,11 @@ Errors **always** emit JSON on stderr regardless of mode, with a stable `code` f
|
|
|
47
47
|
- `reppo query datanet <datanetId> [--for <addr>]` — validity + REPPO access fee, optionally check access for an address
|
|
48
48
|
- `reppo query emissions-due` — list unclaimed REPPO emissions across all pods owned by the configured wallet (uses platform API)
|
|
49
49
|
|
|
50
|
+
### List
|
|
51
|
+
|
|
52
|
+
- `reppo list datanets [--status ACTIVE|ALL] [--token-symbol <sym>] [--limit <n>]` — list all datanets on the platform (public endpoint, no auth required)
|
|
53
|
+
- `reppo list pods [--include-emissions] [--limit <n>]` — list pods owned by the configured wallet (uses platform API)
|
|
54
|
+
|
|
50
55
|
### Write
|
|
51
56
|
|
|
52
57
|
- `reppo vote --pod <id> --subnet <id> --like|--dislike` — cast an on-chain vote
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const DEFAULT_PUBLIC_API_URL = "https://reppo.ai";
|
|
2
|
+
/**
|
|
3
|
+
* Unauthenticated GET against the Reppo public API. Returns parsed JSON
|
|
4
|
+
* or throws `PUBLIC_API_*` on transport / non-2xx / parse failures.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors the error-shape conventions of `platformGet` in `platform.ts`:
|
|
7
|
+
* - PUBLIC_API_UNREACHABLE — network error (fetch threw)
|
|
8
|
+
* - PUBLIC_API_ERROR — non-2xx HTTP response
|
|
9
|
+
* - PUBLIC_API_INVALID_RESPONSE — 2xx but body wasn't JSON
|
|
10
|
+
*/
|
|
11
|
+
export declare function publicGet<T>(baseUrl: string | undefined, path: string): Promise<T>;
|
|
12
|
+
//# sourceMappingURL=public.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/api/public.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AAEzD;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CA+BxF"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reppo public API helpers (reppo.ai).
|
|
3
|
+
*
|
|
4
|
+
* Unauthenticated read-only endpoints exposed by the Reppo dashboard,
|
|
5
|
+
* distinct from the wallet-authed platform API at api.reppo.xyz. No
|
|
6
|
+
* Bearer token, no signature — just `fetch`.
|
|
7
|
+
*
|
|
8
|
+
* Kept separate from `src/api/platform.ts` so callers can't accidentally
|
|
9
|
+
* route a public-API request through `platformGet`, which requires a
|
|
10
|
+
* session token.
|
|
11
|
+
*
|
|
12
|
+
* Base URL resolution:
|
|
13
|
+
* 1. explicit `baseUrl` arg (caller-supplied / env override)
|
|
14
|
+
* 2. DEFAULT_PUBLIC_API_URL
|
|
15
|
+
*
|
|
16
|
+
* The `REPPO_PUBLIC_API_URL` env override is read at the call site, not
|
|
17
|
+
* threaded through `config/load.ts`, to keep the config plumbing scope
|
|
18
|
+
* minimal for now.
|
|
19
|
+
*/
|
|
20
|
+
import { cliError } from '../output/format.js';
|
|
21
|
+
export const DEFAULT_PUBLIC_API_URL = 'https://reppo.ai';
|
|
22
|
+
/**
|
|
23
|
+
* Unauthenticated GET against the Reppo public API. Returns parsed JSON
|
|
24
|
+
* or throws `PUBLIC_API_*` on transport / non-2xx / parse failures.
|
|
25
|
+
*
|
|
26
|
+
* Mirrors the error-shape conventions of `platformGet` in `platform.ts`:
|
|
27
|
+
* - PUBLIC_API_UNREACHABLE — network error (fetch threw)
|
|
28
|
+
* - PUBLIC_API_ERROR — non-2xx HTTP response
|
|
29
|
+
* - PUBLIC_API_INVALID_RESPONSE — 2xx but body wasn't JSON
|
|
30
|
+
*/
|
|
31
|
+
export async function publicGet(baseUrl, path) {
|
|
32
|
+
const resolved = (baseUrl ?? DEFAULT_PUBLIC_API_URL).replace(/\/+$/, '');
|
|
33
|
+
const url = `${resolved}${path}`;
|
|
34
|
+
let response;
|
|
35
|
+
try {
|
|
36
|
+
response = await fetch(url);
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
throw cliError('PUBLIC_API_UNREACHABLE', `Could not reach ${url}: ${e.message}.`, 'Check your internet connection. If reppo.ai is down, try again in a few minutes.');
|
|
40
|
+
}
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
const body = await safeJson(response);
|
|
43
|
+
throw cliError('PUBLIC_API_ERROR', `${path} returned HTTP ${response.status}: ${pickErr(body) ?? 'no body'}.`);
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
return (await response.json());
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
throw cliError('PUBLIC_API_INVALID_RESPONSE', `${path} returned 200 but the body was not valid JSON: ${e.message}.`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// ── Internal helpers ───────────────────────────────────────────────────
|
|
53
|
+
async function safeJson(resp) {
|
|
54
|
+
try {
|
|
55
|
+
return (await resp.json());
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function pickErr(body) {
|
|
62
|
+
if (!body)
|
|
63
|
+
return undefined;
|
|
64
|
+
return (body.error ?? body.message ?? body.detail);
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=public.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../src/api/public.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,MAAM,CAAC,MAAM,sBAAsB,GAAG,kBAAkB,CAAC;AAEzD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,OAA2B,EAAE,IAAY;IAC1E,MAAM,QAAQ,GAAG,CAAC,OAAO,IAAI,sBAAsB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACzE,MAAM,GAAG,GAAG,GAAG,QAAQ,GAAG,IAAI,EAAE,CAAC;IAEjC,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,QAAQ,CACZ,wBAAwB,EACxB,mBAAmB,GAAG,KAAM,CAAW,CAAC,OAAO,GAAG,EAClD,kFAAkF,CACnF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,QAAQ,CACZ,kBAAkB,EAClB,GAAG,IAAI,kBAAkB,QAAQ,CAAC,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,SAAS,GAAG,CAC3E,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;IACtC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,QAAQ,CACZ,6BAA6B,EAC7B,GAAG,IAAI,kDAAmD,CAAW,CAAC,OAAO,GAAG,CACjF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,0EAA0E;AAE1E,KAAK,UAAU,QAAQ,CAAC,IAAc;IACpC,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAA4B,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,IAAoC;IACnD,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAuB,CAAC;AAC3E,CAAC"}
|
package/dist/bin.js
CHANGED
|
@@ -8,6 +8,8 @@ import { AuthCommand } from './commands/auth.js';
|
|
|
8
8
|
import { ClaimEmissionsCommand } from './commands/claim-emissions.js';
|
|
9
9
|
import { ExtendLockCommand } from './commands/extend-lock.js';
|
|
10
10
|
import { GrantAccessCommand } from './commands/grant-access.js';
|
|
11
|
+
import { ListDatanetsCommand } from './commands/list/datanets.js';
|
|
12
|
+
import { ListPodsCommand } from './commands/list/pods.js';
|
|
11
13
|
import { LockCommand } from './commands/lock.js';
|
|
12
14
|
import { MintPodCommand } from './commands/mint-pod.js';
|
|
13
15
|
import { QueryBalanceCommand } from './commands/query/balance.js';
|
|
@@ -21,7 +23,7 @@ import { VoteCommand } from './commands/vote.js';
|
|
|
21
23
|
const cli = new Cli({
|
|
22
24
|
binaryLabel: 'Reppo CLI',
|
|
23
25
|
binaryName: 'reppo',
|
|
24
|
-
binaryVersion: '0.1.
|
|
26
|
+
binaryVersion: '0.1.1',
|
|
25
27
|
enableCapture: false,
|
|
26
28
|
});
|
|
27
29
|
cli.register(Builtins.HelpCommand);
|
|
@@ -30,6 +32,8 @@ cli.register(AuthCommand);
|
|
|
30
32
|
cli.register(ClaimEmissionsCommand);
|
|
31
33
|
cli.register(ExtendLockCommand);
|
|
32
34
|
cli.register(GrantAccessCommand);
|
|
35
|
+
cli.register(ListDatanetsCommand);
|
|
36
|
+
cli.register(ListPodsCommand);
|
|
33
37
|
cli.register(LockCommand);
|
|
34
38
|
cli.register(MintPodCommand);
|
|
35
39
|
cli.register(QueryBalanceCommand);
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;GAGG;AACH,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC;IAClB,WAAW,EAAE,WAAW;IACxB,UAAU,EAAE,OAAO;IACnB,aAAa,EAAE,OAAO;IACtB,aAAa,EAAE,KAAK;CACrB,CAAC,CAAC;AAEH,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACnC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;AAEtC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC1B,GAAG,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC;AACpC,GAAG,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AAChC,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;AACjC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC1B,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;AAC7B,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;AAClC,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;AAClC,GAAG,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;AACvC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;AAC9B,GAAG,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC;AACtC,GAAG,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;AACnC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;AAC5B,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAE1B,kCAAkC;AAClC,uEAAuE;AACvE,uDAAuD;AAEvD,mEAAmE;AACnE,mEAAmE;AACnE,kEAAkE;AAClE,8BAA8B;AAC9B,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C,IAAI,CAAC;IACH,MAAM,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,IAAI,CAAC;QACH,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;KAC1D,CAAC,CAAC;AACL,CAAC"}
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseCommand } from '../_base.js';
|
|
2
|
+
export declare class ListDatanetsCommand extends BaseCommand {
|
|
3
|
+
static paths: string[][];
|
|
4
|
+
static usage: import("clipanion").Usage;
|
|
5
|
+
status: string;
|
|
6
|
+
tokenSymbol: string | undefined;
|
|
7
|
+
limit: string | undefined;
|
|
8
|
+
execute(): Promise<number>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=datanets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datanets.d.ts","sourceRoot":"","sources":["../../../src/commands/list/datanets.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAkD1C,qBAAa,mBAAoB,SAAQ,WAAW;IAClD,OAAgB,KAAK,aAA0B;IAE/C,OAAgB,KAAK,4BAclB;IAEH,MAAM,SAEH;IAEH,WAAW,qBAER;IAEH,KAAK,qBAEF;IAEG,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAoEjC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `reppo list datanets` — list active datanets on the Reppo platform.
|
|
3
|
+
*
|
|
4
|
+
* Hits the UNAUTHENTICATED public endpoint at
|
|
5
|
+
* https://reppo.ai/api/v1/public/subnets. No private key, no Bearer
|
|
6
|
+
* token. Distinct host from `cfg.apiUrl` (api.reppo.xyz, wallet-authed).
|
|
7
|
+
*
|
|
8
|
+
* "Datanet" is the user-facing name; the platform API still uses the
|
|
9
|
+
* legacy "subnet" terminology in field names. The CLI surface translates.
|
|
10
|
+
*
|
|
11
|
+
* Output is a compact list shape — full descriptions, thumbnails, and
|
|
12
|
+
* onboarding text live in `query datanet <id>` instead so this view
|
|
13
|
+
* stays scannable for agents.
|
|
14
|
+
*
|
|
15
|
+
* Numeric platform fields (accessFeeREPPO, emissionsPerEpochREPPO,
|
|
16
|
+
* upVoteVolume, downVoteVolume) arrive as JSON numbers; they're emitted
|
|
17
|
+
* as strings here so downstream agents can BigInt-parse them without
|
|
18
|
+
* losing precision.
|
|
19
|
+
*/
|
|
20
|
+
import { Option } from 'clipanion';
|
|
21
|
+
import { BaseCommand } from '../_base.js';
|
|
22
|
+
import { cliError, emit } from '../../output/format.js';
|
|
23
|
+
import { publicGet, DEFAULT_PUBLIC_API_URL } from '../../api/public.js';
|
|
24
|
+
const VALID_STATUSES = ['ACTIVE', 'ALL'];
|
|
25
|
+
export class ListDatanetsCommand extends BaseCommand {
|
|
26
|
+
static paths = [['list', 'datanets']];
|
|
27
|
+
static usage = BaseCommand.Usage({
|
|
28
|
+
description: 'List active datanets on the Reppo platform (public, unauthenticated).',
|
|
29
|
+
examples: [
|
|
30
|
+
['List all active datanets',
|
|
31
|
+
'reppo list datanets'],
|
|
32
|
+
['Include scheduled-for-deletion rows too',
|
|
33
|
+
'reppo list datanets --status ALL'],
|
|
34
|
+
['Only datanets paid in REPPO',
|
|
35
|
+
'reppo list datanets --token-symbol REPPO'],
|
|
36
|
+
['Limit to first 5 rows',
|
|
37
|
+
'reppo list datanets --limit 5'],
|
|
38
|
+
['JSON output for agents',
|
|
39
|
+
'reppo list datanets --json'],
|
|
40
|
+
],
|
|
41
|
+
});
|
|
42
|
+
status = Option.String('--status', 'ACTIVE', {
|
|
43
|
+
description: 'Filter by status. ACTIVE (default) shows live datanets; ALL includes scheduled-for-deletion.',
|
|
44
|
+
});
|
|
45
|
+
tokenSymbol = Option.String('--token-symbol', {
|
|
46
|
+
description: 'Filter by native token symbol (case-insensitive), e.g. REPPO or USDC.',
|
|
47
|
+
});
|
|
48
|
+
limit = Option.String('--limit', {
|
|
49
|
+
description: 'Maximum number of rows to return after filtering.',
|
|
50
|
+
});
|
|
51
|
+
async execute() {
|
|
52
|
+
try {
|
|
53
|
+
const cfg = this.loadConfig();
|
|
54
|
+
// Validate --status.
|
|
55
|
+
const statusUpper = this.status.toUpperCase();
|
|
56
|
+
if (!isStatusFilter(statusUpper)) {
|
|
57
|
+
throw cliError('INVALID_STATUS', `--status must be one of ${VALID_STATUSES.join(', ')}; got "${this.status}".`);
|
|
58
|
+
}
|
|
59
|
+
// Validate --limit if present (positive integer).
|
|
60
|
+
let limitN;
|
|
61
|
+
if (this.limit !== undefined) {
|
|
62
|
+
if (!/^\d+$/.test(this.limit)) {
|
|
63
|
+
throw cliError('INVALID_LIMIT', `--limit must be a non-negative integer; got "${this.limit}".`);
|
|
64
|
+
}
|
|
65
|
+
limitN = Number.parseInt(this.limit, 10);
|
|
66
|
+
}
|
|
67
|
+
// Resolve env override at call site (per spec — not in loadConfig).
|
|
68
|
+
const baseUrl = process.env.REPPO_PUBLIC_API_URL ?? DEFAULT_PUBLIC_API_URL;
|
|
69
|
+
const resp = await publicGet(baseUrl, '/api/v1/public/subnets');
|
|
70
|
+
const raw = resp.data?.subnets ?? resp.subnets ?? [];
|
|
71
|
+
// Filter: status, token-symbol.
|
|
72
|
+
const symbolNeedle = this.tokenSymbol?.toLowerCase();
|
|
73
|
+
const filtered = raw.filter((s) => {
|
|
74
|
+
if (statusUpper === 'ACTIVE' && (s.status ?? '').toUpperCase() !== 'ACTIVE')
|
|
75
|
+
return false;
|
|
76
|
+
if (symbolNeedle && (s.nativeTokenSymbol ?? '').toLowerCase() !== symbolNeedle)
|
|
77
|
+
return false;
|
|
78
|
+
return true;
|
|
79
|
+
});
|
|
80
|
+
const limited = limitN !== undefined ? filtered.slice(0, limitN) : filtered;
|
|
81
|
+
const datanets = limited.map(toRow);
|
|
82
|
+
const result = {
|
|
83
|
+
network: cfg.network,
|
|
84
|
+
datanets,
|
|
85
|
+
count: datanets.length,
|
|
86
|
+
};
|
|
87
|
+
const lines = [
|
|
88
|
+
`Network: ${cfg.network}`,
|
|
89
|
+
`Datanets: ${datanets.length}${this.tokenSymbol ? ` (token=${this.tokenSymbol})` : ''}${statusUpper !== 'ACTIVE' ? ` (status=${statusUpper})` : ''}`,
|
|
90
|
+
``,
|
|
91
|
+
];
|
|
92
|
+
if (datanets.length === 0) {
|
|
93
|
+
lines.push('(no datanets matched)');
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
for (const d of datanets) {
|
|
97
|
+
lines.push(` #${d.id.padEnd(4)} ${d.name} [${d.status}] fee=${d.accessFeeREPPO} REPPO token=${d.nativeToken.symbol}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
emit(result, lines);
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
this.handleError(err);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function isStatusFilter(v) {
|
|
109
|
+
return VALID_STATUSES.includes(v);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Convert a JSON number/string from the platform into a string suitable
|
|
113
|
+
* for downstream BigInt parsing. Non-numeric or missing values render
|
|
114
|
+
* as "0" rather than "NaN" or "undefined" so the output shape stays
|
|
115
|
+
* consistent.
|
|
116
|
+
*/
|
|
117
|
+
function numericToString(v) {
|
|
118
|
+
if (v === undefined || v === null)
|
|
119
|
+
return '0';
|
|
120
|
+
if (typeof v === 'number') {
|
|
121
|
+
if (!Number.isFinite(v))
|
|
122
|
+
return '0';
|
|
123
|
+
return Math.trunc(v).toString();
|
|
124
|
+
}
|
|
125
|
+
const s = v.trim();
|
|
126
|
+
return s === '' ? '0' : s;
|
|
127
|
+
}
|
|
128
|
+
function toRow(s) {
|
|
129
|
+
return {
|
|
130
|
+
id: s.tokenId ?? '',
|
|
131
|
+
name: s.subnetName ?? '',
|
|
132
|
+
status: s.status ?? 'UNKNOWN',
|
|
133
|
+
accessFeeREPPO: numericToString(s.accessFeeREPPO),
|
|
134
|
+
emissionsPerEpochREPPO: numericToString(s.emissionsPerEpochREPPO),
|
|
135
|
+
nativeToken: {
|
|
136
|
+
address: s.nativeTokenAddress ?? '',
|
|
137
|
+
symbol: s.nativeTokenSymbol ?? '',
|
|
138
|
+
decimals: typeof s.nativeTokenDecimals === 'number' ? s.nativeTokenDecimals : 0,
|
|
139
|
+
},
|
|
140
|
+
upVoteVolume: numericToString(s.upVoteVolume),
|
|
141
|
+
downVoteVolume: numericToString(s.downVoteVolume),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=datanets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datanets.js","sourceRoot":"","sources":["../../../src/commands/list/datanets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseCommand } from '../_base.js';
|
|
2
|
+
export declare class ListPodsCommand extends BaseCommand {
|
|
3
|
+
static paths: string[][];
|
|
4
|
+
static usage: import("clipanion").Usage;
|
|
5
|
+
includeEmissions: boolean;
|
|
6
|
+
limit: string | undefined;
|
|
7
|
+
execute(): Promise<number>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Parse a non-negative wei-amount from the platform API. Same semantics
|
|
11
|
+
* as `query/emissions-due.ts`'s parseWei — duplicated rather than imported
|
|
12
|
+
* because that file's parseWei isn't part of a stable shared utility yet,
|
|
13
|
+
* and refactoring it out is a separate concern.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseWei(v: string | number | undefined | null): bigint;
|
|
16
|
+
//# sourceMappingURL=pods.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pods.d.ts","sourceRoot":"","sources":["../../../src/commands/list/pods.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA4C1C,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,OAAgB,KAAK,aAAsB;IAE3C,OAAgB,KAAK,4BAYlB;IAEH,gBAAgB,UAEb;IAEH,KAAK,qBAAwF;IAEvF,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAkLjC;AAiBD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAKtE"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `reppo list pods` — list pods owned by the authenticated wallet.
|
|
3
|
+
*
|
|
4
|
+
* Hits the platform API `GET /pods` on `cfg.apiUrl` (mainnet defaults to
|
|
5
|
+
* https://api.reppo.xyz). The platform API only returns pods for the
|
|
6
|
+
* authenticated wallet — there is NO `?owner=0xOther` query param, so
|
|
7
|
+
* "list someone else's pods" is intentionally out of scope (it would
|
|
8
|
+
* require an event scan or a new platform endpoint that doesn't exist
|
|
9
|
+
* yet). Switching wallets requires switching REPPO_PRIVATE_KEY.
|
|
10
|
+
*
|
|
11
|
+
* Optional `--include-emissions` follows up with `GET /pods/{podId}/emissions`
|
|
12
|
+
* per pod (matches the `query emissions-due` shape) and appends a per-pod
|
|
13
|
+
* `unclaimedEmissionsREPPO` plus a top-level `totalUnclaimedREPPO`. Off by
|
|
14
|
+
* default because it's N+1 against the platform.
|
|
15
|
+
*
|
|
16
|
+
* Auth: auto-acquires a platform session token via getOrRefreshSession,
|
|
17
|
+
* same flow as `reppo auth` / `reppo query emissions-due`. Requires
|
|
18
|
+
* REPPO_PRIVATE_KEY. Testnet without REPPO_API_URL surfaces
|
|
19
|
+
* PLATFORM_API_NOT_CONFIGURED via requireApiUrl inside getOrRefreshSession.
|
|
20
|
+
*/
|
|
21
|
+
import { Option } from 'clipanion';
|
|
22
|
+
import { formatUnits } from 'viem';
|
|
23
|
+
import { BaseCommand } from '../_base.js';
|
|
24
|
+
import { cliError, emit } from '../../output/format.js';
|
|
25
|
+
import { getOrRefreshSession, platformGet } from '../../api/platform.js';
|
|
26
|
+
export class ListPodsCommand extends BaseCommand {
|
|
27
|
+
static paths = [['list', 'pods']];
|
|
28
|
+
static usage = BaseCommand.Usage({
|
|
29
|
+
description: 'List pods owned by the authenticated wallet (REPPO_PRIVATE_KEY).',
|
|
30
|
+
examples: [
|
|
31
|
+
['List my pods',
|
|
32
|
+
'reppo list pods'],
|
|
33
|
+
['JSON output for an agent loop',
|
|
34
|
+
'reppo list pods --json'],
|
|
35
|
+
['Include unclaimed emissions per pod (N+1 — slower)',
|
|
36
|
+
'reppo list pods --include-emissions'],
|
|
37
|
+
['Cap at 5 rows',
|
|
38
|
+
'reppo list pods --limit 5'],
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
includeEmissions = Option.Boolean('--include-emissions', false, {
|
|
42
|
+
description: 'Also fetch unclaimed emissions per pod (N+1 against platform; off by default)',
|
|
43
|
+
});
|
|
44
|
+
limit = Option.String('--limit', { description: 'Max rows to return (default: unlimited)' });
|
|
45
|
+
async execute() {
|
|
46
|
+
try {
|
|
47
|
+
const cfg = this.loadConfig();
|
|
48
|
+
const pk = cfg.privateKey;
|
|
49
|
+
if (!pk) {
|
|
50
|
+
throw cliError('MISSING_PRIVATE_KEY', 'No signing key available.', 'Set REPPO_PRIVATE_KEY in env. The platform API requires a wallet signature to enumerate pods.');
|
|
51
|
+
}
|
|
52
|
+
// Parse --limit up front so a bad value fails before any network call.
|
|
53
|
+
let limit;
|
|
54
|
+
if (this.limit !== undefined) {
|
|
55
|
+
const n = Number(this.limit);
|
|
56
|
+
if (!Number.isInteger(n) || n < 0) {
|
|
57
|
+
throw cliError('INVALID_LIMIT', `--limit must be a non-negative integer; got "${this.limit}".`);
|
|
58
|
+
}
|
|
59
|
+
limit = n;
|
|
60
|
+
}
|
|
61
|
+
// Auto-acquire/refresh the session token. Same flow `reppo auth` runs.
|
|
62
|
+
// requireApiUrl inside getOrRefreshSession surfaces PLATFORM_API_NOT_CONFIGURED
|
|
63
|
+
// for testnet without REPPO_API_URL.
|
|
64
|
+
const session = await getOrRefreshSession(cfg.network, cfg.apiUrl, pk);
|
|
65
|
+
const podsResp = await platformGet(cfg.apiUrl, '/pods', session.accessToken);
|
|
66
|
+
const rawPods = podsResp.data?.pods ?? podsResp.pods ?? [];
|
|
67
|
+
// Normalize: pick podId from `id` or `podId`, drop anything without one.
|
|
68
|
+
const normalized = rawPods
|
|
69
|
+
.map((p) => {
|
|
70
|
+
const podId = (p.id ?? p.podId)?.toString();
|
|
71
|
+
if (!podId)
|
|
72
|
+
return null;
|
|
73
|
+
const out = { podId };
|
|
74
|
+
if (p.subnetId !== undefined && p.subnetId !== null)
|
|
75
|
+
out.subnetId = p.subnetId.toString();
|
|
76
|
+
if (p.mintedAt)
|
|
77
|
+
out.mintedAt = p.mintedAt;
|
|
78
|
+
else if (p.createdAt)
|
|
79
|
+
out.mintedAt = p.createdAt;
|
|
80
|
+
if (p.mintHash)
|
|
81
|
+
out.mintHash = p.mintHash;
|
|
82
|
+
if (p.basescanUrl)
|
|
83
|
+
out.basescanUrl = p.basescanUrl;
|
|
84
|
+
return out;
|
|
85
|
+
})
|
|
86
|
+
.filter((p) => p !== null);
|
|
87
|
+
const truncated = limit !== undefined ? normalized.slice(0, limit) : normalized;
|
|
88
|
+
if (truncated.length === 0) {
|
|
89
|
+
const result = {
|
|
90
|
+
address: session.walletAddress,
|
|
91
|
+
network: cfg.network,
|
|
92
|
+
pods: [],
|
|
93
|
+
count: 0,
|
|
94
|
+
};
|
|
95
|
+
emit(result, [
|
|
96
|
+
`Wallet: ${session.walletAddress}`,
|
|
97
|
+
`Network: ${cfg.network}`,
|
|
98
|
+
`No pods owned by this wallet.`,
|
|
99
|
+
`(Mint a pod with \`reppo mint-pod\` first.)`,
|
|
100
|
+
]);
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
let emissionsByPod;
|
|
104
|
+
if (this.includeEmissions) {
|
|
105
|
+
emissionsByPod = new Map();
|
|
106
|
+
const fetched = await batchedPromiseAll(truncated, 10, async (p) => {
|
|
107
|
+
try {
|
|
108
|
+
const r = await platformGet(cfg.apiUrl, `/pods/${encodeURIComponent(p.podId)}/emissions`, session.accessToken);
|
|
109
|
+
const data = r.data ?? r;
|
|
110
|
+
// Prefer the API-provided `totalClaimable` aggregate; fall back
|
|
111
|
+
// to summing unclaimed epochs only if it's absent.
|
|
112
|
+
let unclaimed = parseWei(data.totalClaimable);
|
|
113
|
+
if (unclaimed === 0n && data.epochs) {
|
|
114
|
+
for (const e of data.epochs) {
|
|
115
|
+
if (!e.claimed)
|
|
116
|
+
unclaimed += parseWei(e.amount);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return { podId: p.podId, unclaimedREPPO: unclaimed };
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
const err = e;
|
|
123
|
+
return {
|
|
124
|
+
podId: p.podId,
|
|
125
|
+
unclaimedREPPO: 0n,
|
|
126
|
+
error: {
|
|
127
|
+
code: err.code ?? 'PLATFORM_API_ERROR',
|
|
128
|
+
message: err.message ?? String(e),
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
for (const f of fetched) {
|
|
134
|
+
emissionsByPod.set(f.podId, f.error
|
|
135
|
+
? { unclaimedREPPO: f.unclaimedREPPO, error: f.error }
|
|
136
|
+
: { unclaimedREPPO: f.unclaimedREPPO });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const pods = truncated.map((p) => {
|
|
140
|
+
const base = { podId: p.podId };
|
|
141
|
+
if (p.subnetId !== undefined)
|
|
142
|
+
base.subnetId = p.subnetId;
|
|
143
|
+
if (p.mintedAt !== undefined)
|
|
144
|
+
base.mintedAt = p.mintedAt;
|
|
145
|
+
if (p.mintHash !== undefined)
|
|
146
|
+
base.mintHash = p.mintHash;
|
|
147
|
+
if (p.basescanUrl !== undefined)
|
|
148
|
+
base.basescanUrl = p.basescanUrl;
|
|
149
|
+
if (emissionsByPod) {
|
|
150
|
+
const e = emissionsByPod.get(p.podId);
|
|
151
|
+
if (e) {
|
|
152
|
+
base.unclaimedEmissionsREPPO = {
|
|
153
|
+
raw: e.unclaimedREPPO.toString(),
|
|
154
|
+
formatted: formatUnits(e.unclaimedREPPO, 18),
|
|
155
|
+
};
|
|
156
|
+
if (e.error)
|
|
157
|
+
base.emissionsError = e.error;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return base;
|
|
161
|
+
});
|
|
162
|
+
const totalUnclaimed = emissionsByPod
|
|
163
|
+
? Array.from(emissionsByPod.values()).reduce((acc, e) => acc + e.unclaimedREPPO, 0n)
|
|
164
|
+
: undefined;
|
|
165
|
+
const result = {
|
|
166
|
+
address: session.walletAddress,
|
|
167
|
+
network: cfg.network,
|
|
168
|
+
pods,
|
|
169
|
+
count: pods.length,
|
|
170
|
+
};
|
|
171
|
+
if (totalUnclaimed !== undefined) {
|
|
172
|
+
result.totalUnclaimedREPPO = {
|
|
173
|
+
raw: totalUnclaimed.toString(),
|
|
174
|
+
formatted: formatUnits(totalUnclaimed, 18),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
const lines = [
|
|
178
|
+
`Wallet: ${session.walletAddress}`,
|
|
179
|
+
`Network: ${cfg.network}`,
|
|
180
|
+
`Pods: ${pods.length}${limit !== undefined && normalized.length > pods.length ? ` (of ${normalized.length}; limited)` : ''}`,
|
|
181
|
+
];
|
|
182
|
+
if (totalUnclaimed !== undefined) {
|
|
183
|
+
lines.push(`Total unclaimed: ${formatUnits(totalUnclaimed, 18)} REPPO`);
|
|
184
|
+
}
|
|
185
|
+
lines.push(``);
|
|
186
|
+
for (const p of pods) {
|
|
187
|
+
const subnet = p.subnetId !== undefined ? ` subnet=${p.subnetId}` : '';
|
|
188
|
+
let emissionsLine = '';
|
|
189
|
+
if (emissionsByPod) {
|
|
190
|
+
const e = emissionsByPod.get(p.podId);
|
|
191
|
+
if (e?.error) {
|
|
192
|
+
emissionsLine = ` (emissions: ✗ ${e.error.code})`;
|
|
193
|
+
}
|
|
194
|
+
else if (e) {
|
|
195
|
+
emissionsLine = ` ${formatUnits(e.unclaimedREPPO, 18)} REPPO unclaimed`;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
lines.push(` pod ${p.podId}${subnet}${emissionsLine}`);
|
|
199
|
+
}
|
|
200
|
+
emit(result, lines);
|
|
201
|
+
return 0;
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
this.handleError(err);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/** Promise.all with concurrency cap. Mirrors the emissions-due helper. */
|
|
209
|
+
async function batchedPromiseAll(items, concurrency, fn) {
|
|
210
|
+
const out = [];
|
|
211
|
+
for (let i = 0; i < items.length; i += concurrency) {
|
|
212
|
+
const batch = items.slice(i, i + concurrency);
|
|
213
|
+
const results = await Promise.all(batch.map(fn));
|
|
214
|
+
out.push(...results);
|
|
215
|
+
}
|
|
216
|
+
return out;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Parse a non-negative wei-amount from the platform API. Same semantics
|
|
220
|
+
* as `query/emissions-due.ts`'s parseWei — duplicated rather than imported
|
|
221
|
+
* because that file's parseWei isn't part of a stable shared utility yet,
|
|
222
|
+
* and refactoring it out is a separate concern.
|
|
223
|
+
*/
|
|
224
|
+
export function parseWei(v) {
|
|
225
|
+
if (v === undefined || v === null)
|
|
226
|
+
return 0n;
|
|
227
|
+
const s = typeof v === 'number' ? Math.trunc(v).toString() : v.toString().trim();
|
|
228
|
+
if (!/^\d+$/.test(s))
|
|
229
|
+
return 0n;
|
|
230
|
+
try {
|
|
231
|
+
return BigInt(s);
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
return 0n;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=pods.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pods.js","sourceRoot":"","sources":["../../../src/commands/list/pods.ts"],"names":[],"mappings":"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"}
|