@meddleware/dao-ui 0.1.7 → 0.1.8

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 ADDED
@@ -0,0 +1,94 @@
1
+ # @meddleware/dao-ui
2
+
3
+ The **Meddleware DAO console** — a standalone Vue 3 SPA (and embeddable library) that surfaces the
4
+ platform's on-chain state on Sui: treasury balance, commission policy, the community access gates the
5
+ treasury controls, and a live feed of access-gate activity.
6
+
7
+ Deployed at `sui-dao.meddleware.co.uk` and also embedded inline in the tools hub
8
+ (`sui.meddleware.co.uk`) as the default view.
9
+
10
+ ## What it shows
11
+
12
+ The console is **read-only today** — no wallet connection is required to view any data. It reads
13
+ directly from Sui via a bare RPC client. Five tabs:
14
+
15
+ | Tab | Content |
16
+ | --- | --- |
17
+ | **Overview** | Treasury balance + commission rate, platform activity counters (active gates, accesses minted/consumed), and a recent-activity feed. |
18
+ | **Treasury** | Commission rate (bps), current SUI balance, treasury address, and the table of **Community Gates** the treasury controls (name, price, object id). |
19
+ | **Proposals** | Fundraising / governance proposals. **Placeholder** until the `vault_dao` on-chain module ships — shows an empty state today (see [Roadmap](#roadmap)). |
20
+ | **Governance** | Platform parameters (commission rate, the on-chain 10% / 1000-bps hard cap, treasury address) and an **Admin Actions** panel that detects whether the connected wallet holds a `PlatformAdminCap`. Controls light up only for cap holders (implementation pending). |
21
+ | **History** | Paginated on-chain event log (access sold / used / burned) with explorer links per address and transaction. |
22
+
23
+ ## How gate discovery works
24
+
25
+ Gates are discovered by **`AdminCap` ownership**, not by events:
26
+
27
+ 1. Read the treasury address from the `PlatformConfig` shared object.
28
+ 2. List `access_gate::AdminCap` objects owned by the treasury.
29
+ 3. Fetch each `Gate` shared object referenced by its `AdminCap.gate_id`.
30
+
31
+ This is deliberately **resilient to event pruning** — testnet fullnodes prune old events (including
32
+ the one-time `GateCreatedEvent`) after ~3 months, so event-based gate counting is unreliable. The
33
+ `AdminCap`→`Gate` path always reflects live on-chain reality. See
34
+ [`src/composables/useGates.ts`](src/composables/useGates.ts).
35
+
36
+ ## Commission model
37
+
38
+ Commission is charged on every NFT access purchase and enforced on-chain by the `access_gate`
39
+ package: `commission_bps / 10000 × price` routes to the treasury; the remainder goes to the gate
40
+ operator. `commission_bps` is read live from `PlatformConfig`; the on-chain hard cap is 1000 bps
41
+ (10%).
42
+
43
+ ## Configure (build-time `VITE_*`)
44
+
45
+ All values have working testnet defaults; override per network for mainnet.
46
+
47
+ | Var | Meaning |
48
+ | --- | --- |
49
+ | `VITE_NETWORK` | `testnet` (default) or `mainnet` |
50
+ | `VITE_RPC_TESTNET` / `VITE_RPC_MAINNET` | Sui RPC URL override |
51
+ | `VITE_ACCESS_GATE_PACKAGE_ID_{NET}` | Published `access_gate` package id (governs which events/objects are queried) |
52
+ | `VITE_PLATFORM_CONFIG_ID_{NET}` | `PlatformConfig` shared-object id (commission + treasury) |
53
+
54
+ Mainnet package/config ids are empty until deployment; set them via the `_MAINNET` vars — no code
55
+ change required.
56
+
57
+ ## Develop
58
+
59
+ ```sh
60
+ npm install
61
+ npm run dev # vite dev server
62
+ npm run type-check # vue-tsc --noEmit
63
+ npm test # vitest
64
+ ```
65
+
66
+ ## Build
67
+
68
+ ```sh
69
+ npm run build # vue-tsc + vite → dist/
70
+ docker build -t dao-ui .
71
+ ```
72
+
73
+ ## Use as a library
74
+
75
+ The package exports the core view so the dashboard (or any host) can render it inline against a
76
+ shared wallet:
77
+
78
+ ```ts
79
+ import { DaoView } from '@meddleware/dao-ui'
80
+ ```
81
+
82
+ `DaoView` imports its own scoped stylesheet (`styles/qt.css`), so no consumer needs to import dao-ui
83
+ CSS separately. See [CLAUDE.md](CLAUDE.md) for the dual app+library architecture.
84
+
85
+ ## Roadmap
86
+
87
+ - **`vault_dao` on-chain module** — proposals and governance are stubbed
88
+ ([`src/composables/useProposals.ts`](src/composables/useProposals.ts) returns an empty list; the
89
+ Governance admin panel detects the cap but has no actions yet). When `vault_dao` ships, the
90
+ `Proposal` type and composable return shapes are kept stable so the UI wiring is unchanged.
91
+
92
+ ## License
93
+
94
+ BSD Zero Clause License (`0BSD`). See [LICENSE](LICENSE).
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@meddleware/dao-ui",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
+ "homepage": "https://docs.meddleware.co.uk/blockchain/sui/dao/",
4
5
  "description": "Meddleware DAO console — treasury overview, proposals, and governance on Sui.",
5
6
  "author": "Meddleware <dev@meddleware.co.uk>",
6
7
  "license": "0BSD",
package/src/App.vue CHANGED
@@ -6,6 +6,7 @@ import { NETWORK } from './config.js'
6
6
  import DaoView from './DaoView.vue'
7
7
 
8
8
  const { mode, set } = useColorMode('dark')
9
+ const DOCS_URL = import.meta.env.VITE_DOCS_URL || 'https://docs.meddleware.co.uk/blockchain/sui/dao/'
9
10
  </script>
10
11
 
11
12
  <template>
@@ -22,7 +23,7 @@ const { mode, set } = useColorMode('dark')
22
23
 
23
24
  <DaoView style="flex: 1; min-height: 0" />
24
25
 
25
- <AppFooter />
26
+ <AppFooter :docs-url="DOCS_URL" />
26
27
  </div>
27
28
  </template>
28
29
 
@@ -1,4 +1,6 @@
1
1
  <script setup lang="ts">
2
+ // Formats a MIST bigint as human SUI (4 dp, trimming trailing zeros below that),
3
+ // rendering "—" for null. Display-only; never source-of-truth for accounting.
2
4
  defineProps<{
3
5
  mist: bigint | null
4
6
  symbol?: string
@@ -1,4 +1,6 @@
1
1
  <script setup lang="ts">
2
+ // Scrollable table shell with a `head` slot (header cells) and default slot (rows).
3
+ // Renders the `empty` message when no rows are provided.
2
4
  defineProps<{ empty?: string }>()
3
5
 
4
6
  const slots = defineSlots<{
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ // Titled content panel — the console's basic surface primitive. Optional heading + default slot.
2
3
  defineProps<{ title?: string }>()
3
4
  </script>
4
5
 
@@ -1,4 +1,6 @@
1
1
  <script setup lang="ts">
2
+ // Renders one fundraising/governance proposal: status badge, progress toward target,
3
+ // and epochs-left. The Contribute button is disabled until the vault_dao module ships.
2
4
  import { computed } from 'vue'
3
5
  import type { Proposal } from '../composables/useProposals.js'
4
6
 
@@ -1,4 +1,6 @@
1
1
  <script setup lang="ts">
2
+ // Bottom status bar: network + health dot (error-driven), current epoch, and a
3
+ // relative "refreshed Ns ago" timestamp. Purely presentational.
2
4
  import { computed } from 'vue'
3
5
  import { NETWORK } from '../config.js'
4
6
 
@@ -1,4 +1,6 @@
1
1
  <script setup lang="ts">
2
+ // Bespoke raised-tab navigation for the console (v-model + typed tabs). Deliberately
3
+ // distinct from the shared @meddleware/ui tab styling — the desktop-app look is intentional.
2
4
  export interface Tab {
3
5
  id: string
4
6
  label: string
@@ -1,3 +1,6 @@
1
+ // Reads the PlatformConfig shared object once on mount and exposes the treasury
2
+ // address + commission rate (bps). Source of truth for the commission model and for
3
+ // whose AdminCaps the gate discovery (useGates) looks up.
1
4
  import { ref, onMounted } from 'vue'
2
5
  import { getSuiClient } from '../wallet.js'
3
6
  import { CONFIG_ID } from '../config.js'
@@ -1,3 +1,5 @@
1
+ // Reads the SUI balance of the treasury address. Reactive to the address getter so it
2
+ // refetches when usePlatformConfig resolves; clears to null while the address is unknown.
1
3
  import { ref, watch } from 'vue'
2
4
  import { getSuiClient } from '../wallet.js'
3
5
 
package/src/config.ts CHANGED
@@ -1,3 +1,6 @@
1
+ // Build-time configuration. All chain ids are read from VITE_* env with working
2
+ // testnet defaults; mainnet ids stay empty until deployment (set the _MAINNET vars —
3
+ // no code change needed). PACKAGE_ID / CONFIG_ID / RPC_URL resolve to the active network.
1
4
  export type Network = 'testnet' | 'mainnet'
2
5
 
3
6
  export const NETWORK: Network = (import.meta.env.VITE_NETWORK as Network) || 'testnet'
package/src/index.ts CHANGED
@@ -1 +1,3 @@
1
+ // Library entry point. Hosts (e.g. the dashboard) import DaoView to render the DAO
2
+ // console inline against a shared wallet. DaoView self-imports its scoped qt.css.
1
3
  export { default as DaoView } from './DaoView.vue'
package/src/main.ts CHANGED
@@ -1,3 +1,6 @@
1
+ // Standalone SPA bootstrap. Loads the design-token + ui base stylesheets and the
2
+ // console's qt.css, then mounts the App shell. (The library path — src/index.ts —
3
+ // bypasses this and relies on DaoView's own scoped qt.css import instead.)
1
4
  import '@meddleware/design-tokens/tokens.css'
2
5
  import '@meddleware/ui/base.css'
3
6
  import './styles/qt.css'
@@ -1,4 +1,6 @@
1
1
  <script setup lang="ts">
2
+ // History tab: paginated on-chain access-gate event log (sold / used / burned) with
3
+ // per-row explorer links. Data comes from useDaoEvents (pruning-tolerant, merged feed).
2
4
  import { ref, computed } from 'vue'
3
5
  import DataTable from '../components/DataTable.vue'
4
6
  import { useDaoEvents } from '../composables/useDaoEvents.js'
@@ -1,4 +1,6 @@
1
1
  <script setup lang="ts">
2
+ // Overview tab: treasury balance + commission, platform activity counters (active gates,
3
+ // accesses minted/consumed derived from the event feed), and a recent-activity list.
2
4
  import { computed } from 'vue'
3
5
  import Panel from '../components/Panel.vue'
4
6
  import AmountCell from '../components/AmountCell.vue'
@@ -1,4 +1,6 @@
1
1
  <script setup lang="ts">
2
+ // Proposals tab. Lists proposals via useProposals (currently a stub returning []),
3
+ // showing an empty state until the on-chain vault_dao module lands.
2
4
  import ProposalRow from '../components/ProposalRow.vue'
3
5
  import { useProposals } from '../composables/useProposals.js'
4
6
  import { useEpoch } from '../composables/useEpoch.js'
@@ -1,4 +1,6 @@
1
1
  <script setup lang="ts">
2
+ // Treasury tab: commission rate + live SUI balance + treasury address, plus the table
3
+ // of Community Gates the treasury controls (discovered via AdminCap ownership).
2
4
  import { computed } from 'vue'
3
5
  import Panel from '../components/Panel.vue'
4
6
  import AmountCell from '../components/AmountCell.vue'