@akta/dao-cli 0.1.1 → 0.1.2
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.
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akta/dao-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Read-only CLI and TUI for querying Akita DAO state on Algorand",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"start": "bun run src/index.ts",
|
|
11
|
-
"typecheck": "tsc --noEmit"
|
|
11
|
+
"typecheck": "tsc --noEmit",
|
|
12
|
+
"style-screenshots": "bun run scripts/style-screenshots.ts"
|
|
12
13
|
},
|
|
13
14
|
"dependencies": {
|
|
14
15
|
"@akta/sdk": "0.0.1",
|
package/src/commands/state.ts
CHANGED
|
@@ -9,13 +9,32 @@ import {
|
|
|
9
9
|
formatBigInt,
|
|
10
10
|
daoStateLabel,
|
|
11
11
|
resolveAppName,
|
|
12
|
+
getAppName,
|
|
12
13
|
colorState,
|
|
13
14
|
} from "../formatting";
|
|
14
15
|
|
|
15
16
|
export async function stateCommand(dao: AkitaDaoSDK, network: AkitaNetwork, json: boolean): Promise<void> {
|
|
16
17
|
const state = await dao.getGlobalState();
|
|
17
18
|
|
|
18
|
-
if (json)
|
|
19
|
+
if (json) {
|
|
20
|
+
let pluginProposalSettings: { plugin: bigint; pluginName: string; account: string; fee: bigint; power: bigint; duration: bigint; participation: bigint; approval: bigint }[] = [];
|
|
21
|
+
try {
|
|
22
|
+
const pluginsMap = await dao.client.state.box.plugins.getMap();
|
|
23
|
+
pluginProposalSettings = [...pluginsMap.entries()].map(([key, ps]) => ({
|
|
24
|
+
plugin: key.plugin,
|
|
25
|
+
pluginName: (getAppName(key.plugin, network) ?? key.plugin.toString()).replace(/ Plugin$/, ""),
|
|
26
|
+
account: key.escrow || "Main",
|
|
27
|
+
fee: ps.fee,
|
|
28
|
+
power: ps.power,
|
|
29
|
+
duration: ps.duration,
|
|
30
|
+
participation: ps.participation,
|
|
31
|
+
approval: ps.approval,
|
|
32
|
+
}));
|
|
33
|
+
} catch {
|
|
34
|
+
// Box may be empty or inaccessible
|
|
35
|
+
}
|
|
36
|
+
return printJson({ ...state, pluginProposalSettings });
|
|
37
|
+
}
|
|
19
38
|
|
|
20
39
|
header("Core Settings");
|
|
21
40
|
printKV([
|
|
@@ -38,6 +57,7 @@ export async function stateCommand(dao: AkitaDaoSDK, network: AkitaNetwork, json
|
|
|
38
57
|
printAppLists(state, network);
|
|
39
58
|
printFees(state);
|
|
40
59
|
printProposalSettings(state);
|
|
60
|
+
await printPluginProposalSettings(dao, network);
|
|
41
61
|
printRevenueSplits(state, network);
|
|
42
62
|
}
|
|
43
63
|
|
|
@@ -152,6 +172,31 @@ function printProposalSettings(state: Partial<AkitaDaoGlobalState>): void {
|
|
|
152
172
|
printColumns(["Category", "Fee", "Power", "Duration", "Participation", "Approval"], rows);
|
|
153
173
|
}
|
|
154
174
|
|
|
175
|
+
async function printPluginProposalSettings(dao: AkitaDaoSDK, network: AkitaNetwork): Promise<void> {
|
|
176
|
+
let pluginsMap: Map<{ plugin: bigint; escrow: string }, { fee: bigint; power: bigint; duration: bigint; participation: bigint; approval: bigint }>;
|
|
177
|
+
try {
|
|
178
|
+
pluginsMap = await dao.client.state.box.plugins.getMap();
|
|
179
|
+
} catch {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (pluginsMap.size === 0) return;
|
|
183
|
+
|
|
184
|
+
header("Plugin Proposal Settings");
|
|
185
|
+
const rows = [...pluginsMap.entries()].map(([key, ps]) => {
|
|
186
|
+
const name = (getAppName(key.plugin, network) ?? key.plugin.toString()).replace(/ Plugin$/, "");
|
|
187
|
+
return [
|
|
188
|
+
name,
|
|
189
|
+
key.escrow || "Main",
|
|
190
|
+
formatMicroAlgo(ps.fee),
|
|
191
|
+
formatBigInt(ps.power),
|
|
192
|
+
formatDuration(ps.duration),
|
|
193
|
+
formatBasisPoints(ps.participation),
|
|
194
|
+
formatBasisPoints(ps.approval),
|
|
195
|
+
];
|
|
196
|
+
});
|
|
197
|
+
printColumns(["Plugin", "Account", "Fee", "Power", "Duration", "Participation", "Approval"], rows);
|
|
198
|
+
}
|
|
199
|
+
|
|
155
200
|
function printRevenueSplits(state: Partial<AkitaDaoGlobalState>, network: AkitaNetwork): void {
|
|
156
201
|
if (!state.revenueSplits || state.revenueSplits.length === 0) return;
|
|
157
202
|
|
package/src/tui/views/dao.ts
CHANGED
|
@@ -16,6 +16,9 @@ import {
|
|
|
16
16
|
} from "../../formatting";
|
|
17
17
|
import { renderPanel, renderPanelGrid, splitWidth } from "../panels";
|
|
18
18
|
import type { LoadResult, View, ViewContext } from "../types";
|
|
19
|
+
import type { AkitaDaoSDK } from "@akta/sdk/dao";
|
|
20
|
+
|
|
21
|
+
type PluginsMap = Awaited<ReturnType<AkitaDaoSDK["client"]["state"]["box"]["plugins"]["getMap"]>>;
|
|
19
22
|
|
|
20
23
|
export const daoView: View = {
|
|
21
24
|
async load(ctx: ViewContext): Promise<LoadResult> {
|
|
@@ -23,6 +26,15 @@ export const daoView: View = {
|
|
|
23
26
|
const state = await dao.getGlobalState();
|
|
24
27
|
const ids = getNetworkAppIds(network);
|
|
25
28
|
|
|
29
|
+
// Fetch per-plugin proposal settings from box storage
|
|
30
|
+
let pluginsMap: PluginsMap | null = null;
|
|
31
|
+
try {
|
|
32
|
+
pluginsMap = await dao.client.state.box.plugins.getMap();
|
|
33
|
+
if (pluginsMap.size === 0) pluginsMap = null;
|
|
34
|
+
} catch {
|
|
35
|
+
// Box may be empty or inaccessible
|
|
36
|
+
}
|
|
37
|
+
|
|
26
38
|
// Fetch supply data for AKTA & BONES
|
|
27
39
|
let aktaSupply: SupplyInfo | null = null;
|
|
28
40
|
let bonesSupply: SupplyInfo | null = null;
|
|
@@ -54,11 +66,11 @@ export const daoView: View = {
|
|
|
54
66
|
}
|
|
55
67
|
|
|
56
68
|
// Build structured data for JSON mode
|
|
57
|
-
const data = buildDaoData(state, network, ids, dao.appId, aktaSupply, bonesSupply);
|
|
69
|
+
const data = buildDaoData(state, network, ids, dao.appId, aktaSupply, bonesSupply, pluginsMap);
|
|
58
70
|
|
|
59
71
|
let lines: string[];
|
|
60
72
|
if (width < 80) {
|
|
61
|
-
lines = renderSingleColumn(state, network, ids, width, aktaSupply, bonesSupply);
|
|
73
|
+
lines = renderSingleColumn(state, network, ids, width, aktaSupply, bonesSupply, pluginsMap);
|
|
62
74
|
} else {
|
|
63
75
|
const gridRows: string[][][] = [];
|
|
64
76
|
|
|
@@ -108,11 +120,16 @@ export const daoView: View = {
|
|
|
108
120
|
? renderPanel(appLines, { title: "App IDs", width: appW })
|
|
109
121
|
: renderPanel([" No app ID data"], { title: "App IDs", width: appW });
|
|
110
122
|
|
|
111
|
-
// Stack Proposal Settings + Revenue Splits into one right column
|
|
123
|
+
// Stack Proposal Settings + Plugin Proposal Settings + Revenue Splits into one right column
|
|
112
124
|
const rightPanels: string[] = [];
|
|
113
125
|
if (proposalLines.length > 0) {
|
|
114
126
|
rightPanels.push(...renderPanel(proposalLines, { title: "Proposal Settings", width: rightPanelW }));
|
|
115
127
|
}
|
|
128
|
+
const pluginPsLines = renderPluginProposalSettings(pluginsMap, network);
|
|
129
|
+
if (pluginPsLines.length > 0) {
|
|
130
|
+
if (rightPanels.length > 0) rightPanels.push("");
|
|
131
|
+
rightPanels.push(...renderPanel(pluginPsLines, { title: "Plugin Proposal Settings", width: rightPanelW }));
|
|
132
|
+
}
|
|
116
133
|
if (revLines.length > 0) {
|
|
117
134
|
if (rightPanels.length > 0) rightPanels.push("");
|
|
118
135
|
rightPanels.push(...renderPanel(revLines, { title: "Revenue Splits", width: rightPanelW }));
|
|
@@ -140,6 +157,7 @@ function renderSingleColumn(
|
|
|
140
157
|
width: number,
|
|
141
158
|
aktaSupply: SupplyInfo | null,
|
|
142
159
|
bonesSupply: SupplyInfo | null,
|
|
160
|
+
pluginsMap: PluginsMap | null,
|
|
143
161
|
): string[] {
|
|
144
162
|
const lines: string[] = [""];
|
|
145
163
|
|
|
@@ -173,6 +191,12 @@ function renderSingleColumn(
|
|
|
173
191
|
lines.push(...renderPanel(proposalLines, { title: "Proposal Settings", width }));
|
|
174
192
|
}
|
|
175
193
|
|
|
194
|
+
const pluginPsLines = renderPluginProposalSettings(pluginsMap, network);
|
|
195
|
+
if (pluginPsLines.length > 0) {
|
|
196
|
+
lines.push("");
|
|
197
|
+
lines.push(...renderPanel(pluginPsLines, { title: "Plugin Proposal Settings", width }));
|
|
198
|
+
}
|
|
199
|
+
|
|
176
200
|
const revLines = renderRevenueSplits(state, network, width - 4);
|
|
177
201
|
if (revLines.length > 0) {
|
|
178
202
|
lines.push("");
|
|
@@ -191,6 +215,7 @@ function buildDaoData(
|
|
|
191
215
|
appId: bigint,
|
|
192
216
|
aktaSupply: SupplyInfo | null,
|
|
193
217
|
bonesSupply: SupplyInfo | null,
|
|
218
|
+
pluginsMap: PluginsMap | null,
|
|
194
219
|
) {
|
|
195
220
|
// App ID lists
|
|
196
221
|
const appSections: [string, Record<string, bigint> | undefined][] = [
|
|
@@ -255,6 +280,16 @@ function buildDaoData(
|
|
|
255
280
|
tokenSupply,
|
|
256
281
|
apps,
|
|
257
282
|
proposalSettings,
|
|
283
|
+
pluginProposalSettings: pluginsMap ? [...pluginsMap.entries()].map(([key, ps]) => ({
|
|
284
|
+
plugin: key.plugin,
|
|
285
|
+
pluginName: (getAppName(key.plugin, network) ?? key.plugin.toString()).replace(/ Plugin$/, ""),
|
|
286
|
+
account: key.escrow || "Main",
|
|
287
|
+
fee: ps.fee,
|
|
288
|
+
power: ps.power,
|
|
289
|
+
duration: ps.duration,
|
|
290
|
+
participation: ps.participation,
|
|
291
|
+
approval: ps.approval,
|
|
292
|
+
})) : [],
|
|
258
293
|
revenueSplits,
|
|
259
294
|
};
|
|
260
295
|
}
|
|
@@ -312,6 +347,25 @@ function renderProposalSettings(state: Partial<AkitaDaoGlobalState>): string[] {
|
|
|
312
347
|
return renderColumns(["Cat", "Fee", "Pwr", "Dur", "Part", "Appr"], rows);
|
|
313
348
|
}
|
|
314
349
|
|
|
350
|
+
function renderPluginProposalSettings(pluginsMap: PluginsMap | null, network: AkitaNetwork): string[] {
|
|
351
|
+
if (!pluginsMap || pluginsMap.size === 0) return [];
|
|
352
|
+
|
|
353
|
+
const rows = [...pluginsMap.entries()].map(([key, ps]) => {
|
|
354
|
+
const name = (getAppName(key.plugin, network) ?? key.plugin.toString()).replace(/ Plugin$/, "");
|
|
355
|
+
return [
|
|
356
|
+
name,
|
|
357
|
+
key.escrow || "Main",
|
|
358
|
+
formatMicroAlgo(ps.fee),
|
|
359
|
+
formatBigInt(ps.power),
|
|
360
|
+
formatDuration(ps.duration),
|
|
361
|
+
inlineBar(ps.participation),
|
|
362
|
+
inlineBar(ps.approval),
|
|
363
|
+
];
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
return renderColumns(["Plugin", "Account", "Fee", "Pwr", "Dur", "Part", "Appr"], rows);
|
|
367
|
+
}
|
|
368
|
+
|
|
315
369
|
const SPLIT_COLORS = theme.splitColors;
|
|
316
370
|
|
|
317
371
|
function renderRevenueSplits(state: Partial<AkitaDaoGlobalState>, network: AkitaNetwork, barWidth: number): string[] {
|
|
@@ -376,7 +430,7 @@ function renderRevenueSplits(state: Partial<AkitaDaoGlobalState>, network: Akita
|
|
|
376
430
|
|
|
377
431
|
// ── Inline bar for basis-point percentages ─────────────────────
|
|
378
432
|
|
|
379
|
-
const INLINE_BAR_WIDTH =
|
|
433
|
+
const INLINE_BAR_WIDTH = 10;
|
|
380
434
|
|
|
381
435
|
function inlineBar(bp: bigint): string {
|
|
382
436
|
const pct = Number(bp) / 1000;
|