@reppo/cli 0.1.0

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 (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +84 -0
  3. package/dist/api/platform.d.ts +39 -0
  4. package/dist/api/platform.d.ts.map +1 -0
  5. package/dist/api/platform.js +148 -0
  6. package/dist/api/platform.js.map +1 -0
  7. package/dist/bin.d.ts +3 -0
  8. package/dist/bin.d.ts.map +1 -0
  9. package/dist/bin.js +60 -0
  10. package/dist/bin.js.map +1 -0
  11. package/dist/chain/abis.d.ts +576 -0
  12. package/dist/chain/abis.d.ts.map +1 -0
  13. package/dist/chain/abis.js +66 -0
  14. package/dist/chain/abis.js.map +1 -0
  15. package/dist/chain/addresses.d.ts +27 -0
  16. package/dist/chain/addresses.d.ts.map +1 -0
  17. package/dist/chain/addresses.js +39 -0
  18. package/dist/chain/addresses.js.map +1 -0
  19. package/dist/chain/clients.d.ts +46 -0
  20. package/dist/chain/clients.d.ts.map +1 -0
  21. package/dist/chain/clients.js +48 -0
  22. package/dist/chain/clients.js.map +1 -0
  23. package/dist/chain/contracts.d.ts +28 -0
  24. package/dist/chain/contracts.d.ts.map +1 -0
  25. package/dist/chain/contracts.js +70 -0
  26. package/dist/chain/contracts.js.map +1 -0
  27. package/dist/chain/errors.d.ts +14 -0
  28. package/dist/chain/errors.d.ts.map +1 -0
  29. package/dist/chain/errors.js +72 -0
  30. package/dist/chain/errors.js.map +1 -0
  31. package/dist/commands/_base.d.ts +19 -0
  32. package/dist/commands/_base.d.ts.map +1 -0
  33. package/dist/commands/_base.js +40 -0
  34. package/dist/commands/_base.js.map +1 -0
  35. package/dist/commands/auth.d.ts +9 -0
  36. package/dist/commands/auth.d.ts.map +1 -0
  37. package/dist/commands/auth.js +93 -0
  38. package/dist/commands/auth.js.map +1 -0
  39. package/dist/commands/claim-emissions.d.ts +11 -0
  40. package/dist/commands/claim-emissions.d.ts.map +1 -0
  41. package/dist/commands/claim-emissions.js +192 -0
  42. package/dist/commands/claim-emissions.js.map +1 -0
  43. package/dist/commands/extend-lock.d.ts +11 -0
  44. package/dist/commands/extend-lock.d.ts.map +1 -0
  45. package/dist/commands/extend-lock.js +196 -0
  46. package/dist/commands/extend-lock.js.map +1 -0
  47. package/dist/commands/grant-access.d.ts +11 -0
  48. package/dist/commands/grant-access.d.ts.map +1 -0
  49. package/dist/commands/grant-access.js +191 -0
  50. package/dist/commands/grant-access.js.map +1 -0
  51. package/dist/commands/lock.d.ts +11 -0
  52. package/dist/commands/lock.d.ts.map +1 -0
  53. package/dist/commands/lock.js +192 -0
  54. package/dist/commands/lock.js.map +1 -0
  55. package/dist/commands/mint-pod.d.ts +15 -0
  56. package/dist/commands/mint-pod.d.ts.map +1 -0
  57. package/dist/commands/mint-pod.js +286 -0
  58. package/dist/commands/mint-pod.js.map +1 -0
  59. package/dist/commands/query/balance.d.ts +9 -0
  60. package/dist/commands/query/balance.d.ts.map +1 -0
  61. package/dist/commands/query/balance.js +91 -0
  62. package/dist/commands/query/balance.js.map +1 -0
  63. package/dist/commands/query/datanet.d.ts +10 -0
  64. package/dist/commands/query/datanet.d.ts.map +1 -0
  65. package/dist/commands/query/datanet.js +128 -0
  66. package/dist/commands/query/datanet.js.map +1 -0
  67. package/dist/commands/query/emissions-due.d.ts +18 -0
  68. package/dist/commands/query/emissions-due.d.ts.map +1 -0
  69. package/dist/commands/query/emissions-due.js +170 -0
  70. package/dist/commands/query/emissions-due.js.map +1 -0
  71. package/dist/commands/query/pod.d.ts +8 -0
  72. package/dist/commands/query/pod.d.ts.map +1 -0
  73. package/dist/commands/query/pod.js +88 -0
  74. package/dist/commands/query/pod.js.map +1 -0
  75. package/dist/commands/query/voting-power.d.ts +9 -0
  76. package/dist/commands/query/voting-power.d.ts.map +1 -0
  77. package/dist/commands/query/voting-power.js +82 -0
  78. package/dist/commands/query/voting-power.js.map +1 -0
  79. package/dist/commands/register-agent.d.ts +9 -0
  80. package/dist/commands/register-agent.d.ts.map +1 -0
  81. package/dist/commands/register-agent.js +115 -0
  82. package/dist/commands/register-agent.js.map +1 -0
  83. package/dist/commands/unlock.d.ts +11 -0
  84. package/dist/commands/unlock.d.ts.map +1 -0
  85. package/dist/commands/unlock.js +181 -0
  86. package/dist/commands/unlock.js.map +1 -0
  87. package/dist/commands/vote.d.ts +13 -0
  88. package/dist/commands/vote.d.ts.map +1 -0
  89. package/dist/commands/vote.js +174 -0
  90. package/dist/commands/vote.js.map +1 -0
  91. package/dist/config/load.d.ts +19 -0
  92. package/dist/config/load.d.ts.map +1 -0
  93. package/dist/config/load.js +66 -0
  94. package/dist/config/load.js.map +1 -0
  95. package/dist/output/format.d.ts +43 -0
  96. package/dist/output/format.d.ts.map +1 -0
  97. package/dist/output/format.js +58 -0
  98. package/dist/output/format.js.map +1 -0
  99. package/dist/state/db.d.ts +47 -0
  100. package/dist/state/db.d.ts.map +1 -0
  101. package/dist/state/db.js +169 -0
  102. package/dist/state/db.js.map +1 -0
  103. package/dist/state/idempotency.d.ts +66 -0
  104. package/dist/state/idempotency.d.ts.map +1 -0
  105. package/dist/state/idempotency.js +173 -0
  106. package/dist/state/idempotency.js.map +1 -0
  107. package/package.json +63 -0
@@ -0,0 +1,91 @@
1
+ /**
2
+ * `reppo query balance [address]` — show ETH + REPPO + veREPPO + USDC
3
+ * balances for an address. Defaults to the address derived from
4
+ * REPPO_PRIVATE_KEY if no address is given.
5
+ *
6
+ * Token contracts that are TBD on the current network (e.g. mainnet
7
+ * veReppo today) emit `{ unavailable: "<reason>" }` instead of a
8
+ * misleading 0 — so an agent can tell "user has nothing" apart from
9
+ * "the CLI doesn't know where to look".
10
+ */
11
+ import { Option } from 'clipanion';
12
+ import { formatUnits, isAddress } from 'viem';
13
+ import { privateKeyToAddress } from 'viem/accounts';
14
+ import { BaseCommand } from '../_base.js';
15
+ import { cliError, emit } from '../../output/format.js';
16
+ import { createReadClient } from '../../chain/clients.js';
17
+ import { tryReppoToken, tryUsdcToken, tryVeReppo } from '../../chain/contracts.js';
18
+ function unavailable(label, network) {
19
+ return { unavailable: `${label} address not configured for ${network}.` };
20
+ }
21
+ export class QueryBalanceCommand extends BaseCommand {
22
+ static paths = [['query', 'balance']];
23
+ static usage = BaseCommand.Usage({
24
+ description: 'Show on-chain balances (ETH, REPPO, veREPPO, USDC) for an address.',
25
+ examples: [
26
+ ['Query the wallet derived from REPPO_PRIVATE_KEY', 'reppo query balance'],
27
+ ['Query a specific address', 'reppo query balance 0x726c…E31d'],
28
+ ['JSON output', 'reppo query balance --json'],
29
+ ],
30
+ });
31
+ address = Option.String({ required: false });
32
+ async execute() {
33
+ try {
34
+ const cfg = this.loadConfig();
35
+ const addr = this.resolveAddress(cfg.privateKey);
36
+ const client = createReadClient({ network: cfg.network, ...(cfg.rpcUrl ? { rpcUrl: cfg.rpcUrl } : {}) });
37
+ const eth = await client.getBalance({ address: addr });
38
+ const reppoContract = tryReppoToken(cfg.network);
39
+ const reppo = reppoContract
40
+ ? await client.readContract({ ...reppoContract, functionName: 'balanceOf', args: [addr] })
41
+ .then((v) => ({ raw: v.toString(), formatted: formatUnits(v, 18) }))
42
+ : unavailable('REPPO token', cfg.network);
43
+ const veReppoContract = tryVeReppo(cfg.network);
44
+ const veReppo = veReppoContract
45
+ ? await client.readContract({ ...veReppoContract, functionName: 'votingPowerOf', args: [addr] })
46
+ .then((v) => ({ raw: v.toString(), formatted: formatUnits(v, 18) }))
47
+ : unavailable('veReppo', cfg.network);
48
+ const usdcContract = tryUsdcToken(cfg.network);
49
+ const usdc = usdcContract
50
+ ? await client.readContract({ ...usdcContract, functionName: 'balanceOf', args: [addr] })
51
+ .then((v) => ({ raw: v.toString(), formatted: formatUnits(v, 6) }))
52
+ : unavailable('USDC', cfg.network);
53
+ const result = {
54
+ address: addr,
55
+ network: cfg.network,
56
+ balances: {
57
+ eth: { raw: eth.toString(), formatted: formatUnits(eth, 18) },
58
+ reppo,
59
+ veReppo,
60
+ usdc,
61
+ },
62
+ };
63
+ const fmt = (b) => 'unavailable' in b ? `(unavailable: ${b.unavailable})` : b.formatted;
64
+ emit(result, [
65
+ `Address: ${addr}`,
66
+ `Network: ${cfg.network}`,
67
+ `ETH: ${formatUnits(eth, 18)}`,
68
+ `REPPO: ${fmt(reppo)}`,
69
+ `veREPPO: ${fmt(veReppo)}`,
70
+ `USDC: ${fmt(usdc)}`,
71
+ ]);
72
+ return 0;
73
+ }
74
+ catch (err) {
75
+ this.handleError(err);
76
+ }
77
+ }
78
+ resolveAddress(pk) {
79
+ if (this.address) {
80
+ if (!isAddress(this.address)) {
81
+ throw cliError('INVALID_ADDRESS', `Invalid address: ${this.address}`);
82
+ }
83
+ return this.address;
84
+ }
85
+ if (!pk) {
86
+ throw cliError('MISSING_ADDRESS', 'No address provided and REPPO_PRIVATE_KEY not set.', 'Pass an address argument or set REPPO_PRIVATE_KEY in env.');
87
+ }
88
+ return privateKeyToAddress(pk);
89
+ }
90
+ }
91
+ //# sourceMappingURL=balance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.js","sourceRoot":"","sources":["../../../src/commands/query/balance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../_base.js';
2
+ export declare class QueryDatanetCommand extends BaseCommand {
3
+ static paths: string[][];
4
+ static usage: import("clipanion").Usage;
5
+ datanet: string;
6
+ for_: string | undefined;
7
+ execute(): Promise<number>;
8
+ private resolveCallerAddress;
9
+ }
10
+ //# sourceMappingURL=datanet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datanet.d.ts","sourceRoot":"","sources":["../../../src/commands/query/datanet.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAW1C,qBAAa,mBAAoB,SAAQ,WAAW;IAClD,OAAgB,KAAK,aAA0B;IAE/C,OAAgB,KAAK,4BAUlB;IAEH,OAAO,SAAqC;IAC5C,IAAI,qBAA+H;IAE7H,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAoFhC,OAAO,CAAC,oBAAoB;CAU7B"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * `reppo query datanet <datanetId> [--for <address>]` — show whether a
3
+ * datanet exists, its REPPO access fee, and (optionally) whether a given
4
+ * address has access.
5
+ *
6
+ * "Datanet" is Reppo's user-facing term; on-chain the same concept is
7
+ * called a "subnet" (SubnetManager, validSubnet, hasSubnetAccess). The
8
+ * CLI uses the user-facing term at its surface and translates internally.
9
+ *
10
+ * Resolution order for the access check:
11
+ * 1. --for <addr> (explicit, no key needed)
12
+ * 2. REPPO_PRIVATE_KEY (derived from env)
13
+ * 3. neither set → callerAccess omitted from output
14
+ *
15
+ * If subnet manager is TBD on the chosen network (mainnet today), every
16
+ * field emits `{ unavailable: "<reason>" }` rather than a misleading
17
+ * default.
18
+ */
19
+ import { Option } from 'clipanion';
20
+ import { formatUnits, isAddress } from 'viem';
21
+ import { privateKeyToAddress } from 'viem/accounts';
22
+ import { BaseCommand } from '../_base.js';
23
+ import { cliError, emit } from '../../output/format.js';
24
+ import { createReadClient } from '../../chain/clients.js';
25
+ import { trySubnetManager } from '../../chain/contracts.js';
26
+ function unavailable(reason) {
27
+ return { unavailable: reason };
28
+ }
29
+ export class QueryDatanetCommand extends BaseCommand {
30
+ static paths = [['query', 'datanet']];
31
+ static usage = BaseCommand.Usage({
32
+ description: 'Show datanet validity, REPPO access fee, and (optionally) whether an address has access.',
33
+ examples: [
34
+ ['Inspect datanet 19',
35
+ 'reppo query datanet 19'],
36
+ ['Check whether a specific address has access',
37
+ 'reppo query datanet 19 --for 0x726c…E31d'],
38
+ ['JSON output for an agent',
39
+ 'reppo query datanet 19 --json'],
40
+ ],
41
+ });
42
+ datanet = Option.String({ required: true });
43
+ for_ = Option.String('--for', { description: 'Address to check access for (defaults to address derived from REPPO_PRIVATE_KEY)' });
44
+ async execute() {
45
+ try {
46
+ const cfg = this.loadConfig();
47
+ let datanetId;
48
+ try {
49
+ datanetId = BigInt(this.datanet);
50
+ }
51
+ catch {
52
+ throw cliError('INVALID_DATANET_ID', `Datanet id must be a non-negative integer; got "${this.datanet}".`);
53
+ }
54
+ const client = createReadClient({ network: cfg.network, ...(cfg.rpcUrl ? { rpcUrl: cfg.rpcUrl } : {}) });
55
+ const sm = trySubnetManager(cfg.network);
56
+ if (!sm) {
57
+ const reason = `Datanet manager address not configured for ${cfg.network}.`;
58
+ emit({
59
+ datanetId: datanetId.toString(),
60
+ network: cfg.network,
61
+ valid: unavailable(reason),
62
+ accessFeeREPPO: unavailable(reason),
63
+ }, [
64
+ `Datanet: ${datanetId}`,
65
+ `Network: ${cfg.network}`,
66
+ `(unavailable: ${reason})`,
67
+ ]);
68
+ return 0;
69
+ }
70
+ // On-chain function names use the legacy "subnet" naming; CLI surface uses datanet.
71
+ const valid = await client.readContract({ ...sm, functionName: 'validSubnet', args: [datanetId] });
72
+ // Skip the fee read on invalid datanets — getAccessFeeREPPO is likely
73
+ // to revert (or return 0) for non-existent datanets, and either way
74
+ // the answer is "no fee because there is no datanet", not "fee is 0".
75
+ const accessFeeREPPO = valid
76
+ ? await client.readContract({ ...sm, functionName: 'getAccessFeeREPPO', args: [datanetId] })
77
+ .then((v) => ({ raw: v.toString(), formatted: formatUnits(v, 18) }))
78
+ : unavailable('datanet does not exist');
79
+ // Optional caller-access check.
80
+ const callerAddr = this.resolveCallerAddress(cfg.privateKey);
81
+ const callerAccess = callerAddr && valid
82
+ ? {
83
+ address: callerAddr,
84
+ hasAccess: await client.readContract({
85
+ ...sm, functionName: 'hasSubnetAccess', args: [datanetId, callerAddr],
86
+ }),
87
+ }
88
+ : undefined;
89
+ const result = {
90
+ datanetId: datanetId.toString(),
91
+ network: cfg.network,
92
+ valid,
93
+ accessFeeREPPO,
94
+ ...(callerAccess ? { callerAccess } : {}),
95
+ };
96
+ const feeFmt = 'unavailable' in accessFeeREPPO
97
+ ? `(unavailable: ${accessFeeREPPO.unavailable})`
98
+ : `${accessFeeREPPO.formatted} REPPO`;
99
+ const lines = [
100
+ `Datanet: ${datanetId}`,
101
+ `Network: ${cfg.network}`,
102
+ `Valid: ${valid}`,
103
+ `Access fee: ${feeFmt}`,
104
+ ];
105
+ if (callerAccess) {
106
+ lines.push(`Caller: ${callerAccess.address}`);
107
+ lines.push(`Caller access: ${callerAccess.hasAccess}`);
108
+ }
109
+ emit(result, lines);
110
+ return 0;
111
+ }
112
+ catch (err) {
113
+ this.handleError(err);
114
+ }
115
+ }
116
+ resolveCallerAddress(pk) {
117
+ if (this.for_) {
118
+ if (!isAddress(this.for_)) {
119
+ throw cliError('INVALID_ADDRESS', `Invalid --for address: ${this.for_}`);
120
+ }
121
+ return this.for_;
122
+ }
123
+ if (pk)
124
+ return privateKeyToAddress(pk);
125
+ return undefined;
126
+ }
127
+ }
128
+ //# sourceMappingURL=datanet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datanet.js","sourceRoot":"","sources":["../../../src/commands/query/datanet.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { BaseCommand } from '../_base.js';
2
+ export declare class QueryEmissionsDueCommand extends BaseCommand {
3
+ static paths: string[][];
4
+ static usage: import("clipanion").Usage;
5
+ execute(): Promise<number>;
6
+ }
7
+ /**
8
+ * Parse a non-negative wei-amount returned by the platform API. Accepts
9
+ * both string decimal ("1500000000000000000") and JS number forms; falls
10
+ * back to 0n on anything unparseable so a single malformed pod entry
11
+ * doesn't crash the whole command. `BigInt()` throws SyntaxError on
12
+ * floats, scientific notation, and non-digit chars — guarded here so we
13
+ * surface a clean 0 rather than an opaque INTERNAL_ERROR. Negatives are
14
+ * also rejected (claimable emissions are always non-negative) so a buggy
15
+ * API response can't drag totalDueREPPO below zero.
16
+ */
17
+ export declare function parseWei(v: string | number | undefined): bigint;
18
+ //# sourceMappingURL=emissions-due.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emissions-due.d.ts","sourceRoot":"","sources":["../../../src/commands/query/emissions-due.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAuC1C,qBAAa,wBAAyB,SAAQ,WAAW;IACvD,OAAgB,KAAK,aAAgC;IAErD,OAAgB,KAAK,4BAQlB;IAEG,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAwHjC;AAiBD;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAK/D"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * `reppo query emissions-due` — list all unclaimed REPPO emissions
3
+ * across the caller's pods.
4
+ *
5
+ * Goes through the platform API at api.reppo.xyz because pods are not
6
+ * enumerable on-chain (PodManager doesn't expose tokenOfOwnerByIndex).
7
+ * The platform API's `GET /pods` returns the caller's owned pods; for
8
+ * each pod we follow up with `GET /pods/{podId}/emissions` to get the
9
+ * per-epoch breakdown.
10
+ *
11
+ * Auth: this command auto-acquires a platform session token (via the
12
+ * same flow as `reppo auth`), refreshing if expired. The user must
13
+ * have set REPPO_PRIVATE_KEY — the platform API requires a wallet
14
+ * signature to sign in.
15
+ *
16
+ * Output schema:
17
+ * { walletAddress, totalDueREPPO: { raw, formatted },
18
+ * byPod: [{ podId, currentEpoch, totalDue: {raw, formatted},
19
+ * epochs: [{ epoch, amount, claimed }, ...] }, ...] }
20
+ *
21
+ * No optional [address] argument — the platform API only returns pods
22
+ * for the authenticated wallet. Switching wallets requires switching
23
+ * REPPO_PRIVATE_KEY.
24
+ */
25
+ import { formatUnits } from 'viem';
26
+ import { BaseCommand } from '../_base.js';
27
+ import { cliError, emit } from '../../output/format.js';
28
+ import { getOrRefreshSession, platformGet } from '../../api/platform.js';
29
+ export class QueryEmissionsDueCommand extends BaseCommand {
30
+ static paths = [['query', 'emissions-due']];
31
+ static usage = BaseCommand.Usage({
32
+ description: 'List unclaimed REPPO emissions across all pods owned by the configured wallet.',
33
+ examples: [
34
+ ['List emissions due',
35
+ 'reppo query emissions-due'],
36
+ ['JSON output for an agent loop',
37
+ 'reppo query emissions-due --json'],
38
+ ],
39
+ });
40
+ async execute() {
41
+ try {
42
+ const cfg = this.loadConfig();
43
+ const pk = cfg.privateKey;
44
+ if (!pk) {
45
+ 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.');
46
+ }
47
+ // Auto-acquire/refresh the session token. Same flow `reppo auth` runs.
48
+ const session = await getOrRefreshSession(cfg.network, cfg.apiUrl, pk);
49
+ // Step 1: list the caller's pods.
50
+ const podsResp = await platformGet(cfg.apiUrl, '/pods', session.accessToken);
51
+ const pods = podsResp.data?.pods ?? podsResp.pods ?? [];
52
+ if (pods.length === 0) {
53
+ const result = {
54
+ walletAddress: session.walletAddress,
55
+ totalDueREPPO: { raw: '0', formatted: '0' },
56
+ byPod: [],
57
+ };
58
+ emit(result, [
59
+ `No pods owned by ${session.walletAddress}.`,
60
+ `(Mint a pod with \`reppo mint-pod\` first.)`,
61
+ ]);
62
+ return 0;
63
+ }
64
+ // Step 2: per-pod emissions, in parallel. Cap fan-out at 10 to be
65
+ // gentle on the platform; if more pods exist, batch sequentially.
66
+ const podIds = pods
67
+ .map((p) => (p.id ?? p.podId)?.toString())
68
+ .filter((id) => id !== undefined && id !== '');
69
+ const breakdowns = await batchedPromiseAll(podIds, 10, async (podId) => {
70
+ try {
71
+ const r = await platformGet(cfg.apiUrl, `/pods/${encodeURIComponent(podId)}/emissions`, session.accessToken);
72
+ const data = r.data ?? r;
73
+ return {
74
+ ok: true,
75
+ podId,
76
+ currentEpoch: data.currentEpoch?.toString() ?? null,
77
+ totalClaimable: parseWei(data.totalClaimable),
78
+ epochs: (data.epochs ?? []).map((e) => ({
79
+ epoch: e.epoch?.toString() ?? null,
80
+ amount: e.amount?.toString() ?? '0',
81
+ claimed: !!e.claimed,
82
+ })),
83
+ moreEpochsAvailable: !!data.moreEpochsAvailable,
84
+ };
85
+ }
86
+ catch (e) {
87
+ const err = e;
88
+ return {
89
+ ok: false,
90
+ podId,
91
+ error: {
92
+ code: err.code ?? 'PLATFORM_API_ERROR',
93
+ message: err.message ?? String(e),
94
+ },
95
+ };
96
+ }
97
+ });
98
+ const totalDue = breakdowns.reduce((acc, b) => (b.ok ? acc + b.totalClaimable : acc), 0n);
99
+ const failedCount = breakdowns.filter((b) => !b.ok).length;
100
+ const result = {
101
+ walletAddress: session.walletAddress,
102
+ totalDueREPPO: { raw: totalDue.toString(), formatted: formatUnits(totalDue, 18) },
103
+ byPod: breakdowns.map((b) => b.ok
104
+ ? {
105
+ podId: b.podId,
106
+ currentEpoch: b.currentEpoch,
107
+ totalDue: { raw: b.totalClaimable.toString(), formatted: formatUnits(b.totalClaimable, 18) },
108
+ epochs: b.epochs,
109
+ moreEpochsAvailable: b.moreEpochsAvailable,
110
+ }
111
+ : { podId: b.podId, error: b.error }),
112
+ };
113
+ const lines = [
114
+ `Wallet: ${session.walletAddress}`,
115
+ `Pods: ${pods.length}${failedCount > 0 ? ` (${failedCount} failed to fetch — see byPod[].error)` : ''}`,
116
+ `Total claimable: ${formatUnits(totalDue, 18)} REPPO`,
117
+ ``,
118
+ ];
119
+ for (const b of breakdowns) {
120
+ if (!b.ok) {
121
+ lines.push(` pod ${b.podId}: ✗ ${b.error.code} — ${b.error.message}`);
122
+ continue;
123
+ }
124
+ const claimable = formatUnits(b.totalClaimable, 18);
125
+ const claimed = b.epochs.filter((e) => e.claimed).length;
126
+ const open = b.epochs.length - claimed;
127
+ lines.push(` pod ${b.podId}: ${claimable} REPPO due across ${open} unclaimed epoch${open === 1 ? '' : 's'}${b.moreEpochsAvailable ? ' (more available — re-run after claiming)' : ''}`);
128
+ }
129
+ emit(result, lines);
130
+ return 0;
131
+ }
132
+ catch (err) {
133
+ this.handleError(err);
134
+ }
135
+ }
136
+ }
137
+ /** Promise.all but with a concurrency cap. Avoids slamming the platform. */
138
+ async function batchedPromiseAll(items, concurrency, fn) {
139
+ const out = [];
140
+ for (let i = 0; i < items.length; i += concurrency) {
141
+ const batch = items.slice(i, i + concurrency);
142
+ const results = await Promise.all(batch.map(fn));
143
+ out.push(...results);
144
+ }
145
+ return out;
146
+ }
147
+ /**
148
+ * Parse a non-negative wei-amount returned by the platform API. Accepts
149
+ * both string decimal ("1500000000000000000") and JS number forms; falls
150
+ * back to 0n on anything unparseable so a single malformed pod entry
151
+ * doesn't crash the whole command. `BigInt()` throws SyntaxError on
152
+ * floats, scientific notation, and non-digit chars — guarded here so we
153
+ * surface a clean 0 rather than an opaque INTERNAL_ERROR. Negatives are
154
+ * also rejected (claimable emissions are always non-negative) so a buggy
155
+ * API response can't drag totalDueREPPO below zero.
156
+ */
157
+ export function parseWei(v) {
158
+ if (v === undefined || v === null)
159
+ return 0n;
160
+ const s = typeof v === 'number' ? Math.trunc(v).toString() : v.toString().trim();
161
+ if (!/^\d+$/.test(s))
162
+ return 0n;
163
+ try {
164
+ return BigInt(s);
165
+ }
166
+ catch {
167
+ return 0n;
168
+ }
169
+ }
170
+ //# sourceMappingURL=emissions-due.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emissions-due.js","sourceRoot":"","sources":["../../../src/commands/query/emissions-due.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { BaseCommand } from '../_base.js';
2
+ export declare class QueryPodCommand extends BaseCommand {
3
+ static paths: string[][];
4
+ static usage: import("clipanion").Usage;
5
+ pod: string;
6
+ execute(): Promise<number>;
7
+ }
8
+ //# sourceMappingURL=pod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pod.d.ts","sourceRoot":"","sources":["../../../src/commands/query/pod.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK1C,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,OAAgB,KAAK,aAAsB;IAE3C,OAAgB,KAAK,4BAQlB;IAEH,GAAG,SAAqC;IAElC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CA6DjC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * `reppo query pod <podId>` — show whether a pod exists and who owns it.
3
+ *
4
+ * The PodManager is an ERC-721 — `ownerOf(tokenId)` reverts on non-
5
+ * existent tokens (per the spec). We render `{ exists: false, owner: null }`
6
+ * for any revert from that call. RPC errors *also* show up that way; for
7
+ * an alpha read command that's an acceptable trade-off versus introspecting
8
+ * the revert reason. (Real bugs surface as RPC errors elsewhere.)
9
+ *
10
+ * The mainnet PodManager and testnet PodManager (forked variant) share the
11
+ * `ownerOf` selector, so this command works on both networks via
12
+ * `tryPodManager(network)` — viem pairs the right ABI with the right
13
+ * address automatically.
14
+ */
15
+ import { Option } from 'clipanion';
16
+ import { BaseCommand } from '../_base.js';
17
+ import { cliError, emit } from '../../output/format.js';
18
+ import { createReadClient } from '../../chain/clients.js';
19
+ import { tryPodManager } from '../../chain/contracts.js';
20
+ export class QueryPodCommand extends BaseCommand {
21
+ static paths = [['query', 'pod']];
22
+ static usage = BaseCommand.Usage({
23
+ description: 'Show pod existence and ownership.',
24
+ examples: [
25
+ ['Inspect pod 34',
26
+ 'reppo query pod 34'],
27
+ ['JSON output for an agent',
28
+ 'reppo query pod 34 --json'],
29
+ ],
30
+ });
31
+ pod = Option.String({ required: true });
32
+ async execute() {
33
+ try {
34
+ const cfg = this.loadConfig();
35
+ let podId;
36
+ try {
37
+ podId = BigInt(this.pod);
38
+ }
39
+ catch {
40
+ throw cliError('INVALID_POD_ID', `Pod id must be a non-negative integer; got "${this.pod}".`);
41
+ }
42
+ const client = createReadClient({ network: cfg.network, ...(cfg.rpcUrl ? { rpcUrl: cfg.rpcUrl } : {}) });
43
+ const pm = tryPodManager(cfg.network);
44
+ if (!pm) {
45
+ const reason = `PodManager address not configured for ${cfg.network}.`;
46
+ emit({
47
+ podId: podId.toString(),
48
+ network: cfg.network,
49
+ exists: { unavailable: reason },
50
+ owner: { unavailable: reason },
51
+ }, [
52
+ `Pod: ${podId}`,
53
+ `Network: ${cfg.network}`,
54
+ `(unavailable: ${reason})`,
55
+ ]);
56
+ return 0;
57
+ }
58
+ let owner = null;
59
+ let exists = false;
60
+ try {
61
+ owner = await client.readContract({ ...pm, functionName: 'ownerOf', args: [podId] });
62
+ exists = true;
63
+ }
64
+ catch {
65
+ // ownerOf reverts on non-existent tokens (ERC-721 spec). We
66
+ // intentionally don't decodeRevert here — the answer the user
67
+ // wants is "does this pod exist?", not the revert reason.
68
+ }
69
+ const result = {
70
+ podId: podId.toString(),
71
+ network: cfg.network,
72
+ exists,
73
+ owner,
74
+ };
75
+ emit(result, [
76
+ `Pod: ${podId}`,
77
+ `Network: ${cfg.network}`,
78
+ `Exists: ${exists}`,
79
+ `Owner: ${owner ?? '(none — pod does not exist)'}`,
80
+ ]);
81
+ return 0;
82
+ }
83
+ catch (err) {
84
+ this.handleError(err);
85
+ }
86
+ }
87
+ }
88
+ //# sourceMappingURL=pod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pod.js","sourceRoot":"","sources":["../../../src/commands/query/pod.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { BaseCommand } from '../_base.js';
2
+ export declare class QueryVotingPowerCommand extends BaseCommand {
3
+ static paths: string[][];
4
+ static usage: import("clipanion").Usage;
5
+ address: string | undefined;
6
+ execute(): Promise<number>;
7
+ private resolveAddress;
8
+ }
9
+ //# sourceMappingURL=voting-power.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voting-power.d.ts","sourceRoot":"","sources":["../../../src/commands/query/voting-power.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAe1C,qBAAa,uBAAwB,SAAQ,WAAW;IACtD,OAAgB,KAAK,aAA+B;IAEpD,OAAgB,KAAK,4BAOlB;IAEH,OAAO,qBAAsC;IAEvC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAuChC,OAAO,CAAC,cAAc;CAgBvB"}