# Realms

What is Realms?

**Realms** is a sophisticated, fully on-chain platform designed to simplify and enhance the management of decentralized autonomous organizations (DAOs) on the Solana blockchain.\
\
Whether overseeing a simple multisig wallet or a large-scale protocol worth billions, Realms provides a comprehensive set of tools to support your community's growth and governance.

<figure><img src="/files/0UqZsh6SkGShza9dO3Gp" alt=""><figcaption></figcaption></figure>

### How can I use Realms?

For a user to use Realms in his full capacity there are three main components: DAOs, proposals, and votes. Each DAO is filled with proposals and a treasury linked to it which all proposals get voted.

Users can then generate proposals and vote within their newly generated DAO. Council token holders can establish rules for proposal creation and voting by setting specific configurations.

For instance, users may need to hold a minimum of 1 or 1 million tokens to create proposals depending on the DAO parameters.


# What is a DAO

At its simplest, a decentralized autonomous organization (DAO) is a community with a shared bank account

Members of the **DAO** make decisions in a **transparent** and **decentralized** fashion, with smart contracts executing these decisions.

For instance, a member can create a proposal suggesting an investment of the treasury or a program upgrade. The **DAO** members then come together to vote on the proposal. If a predefined quorum votes for the proposal to pass, the proposal is accepted and executed by a smart contract.

As a result, the **DAO** structure provides a “flat” organizational structure. Each **DAO** member has a voice in the community and the opportunity to drive the direction of the organization.

## DAO Landing Page <a href="#dao-landing-page" id="dao-landing-page"></a>

Users when landing in their preferred DAO page will be able to see straight away:

* **DAO Stats**
* **Members**
* **Settings** (DAO Config)
* **DAO Wallets & Assets** (Treasury)
* **Programs** (Programs that involve dApp and Realms interactions)
* **Proposals**

Users who have their Solana wallet connected will be able to see their **governance power** where they can **Deposit**, **Withdraw**, **Delegate** and **Lock Tokens**.

## Where to find them? <a href="#where-to-find-them" id="where-to-find-them"></a>

DAOs are displayed upon visiting Realms and can primarily be filtered by the **search bar** and searching for the DAO you wish to visit.\
\
**Custom domain names** for spaces are also supported (bonkedao.com).

<div data-with-frame="true"><img src="/files/EpMtcLTg75HbBZZ8ATK5" alt=""></div>

## Proposal Filtering & Sorting <a href="#proposal-filtering--sorting" id="proposal-filtering--sorting"></a>

Users can go through all of DAO proposals and turn on/off **specific filters** to them, including **completed**, **canceled**, and **defeated** proposals.

<div data-with-frame="true"><img src="/files/FUmZDkQyYRw3DdbpYVHV" alt=""></div>


# Features

Set of features available in Realms

<table data-view="cards"><thead><tr><th align="center"></th><th align="center"></th><th data-hidden data-type="image">Cover image (dark)</th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-type="image">Cover image (dark)</th><th data-hidden data-type="image">Cover image (dark)</th><th data-hidden data-type="image">Cover image (dark)</th><th data-hidden data-type="image">Cover image (dark)</th><th data-hidden data-type="image">Cover image (dark)</th><th data-hidden data-type="image">Cover image (dark)</th><th data-hidden data-card-cover-dark data-type="image">Cover image (dark)</th></tr></thead><tbody><tr><td align="center"><strong>User-Friendly Interface</strong></td><td align="center">Create and configure your DAO with ease, thanks to Realms creation wizard setup process.</td><td><a href="/files/SzBFgiiH8bNEz68PlNPa">/files/SzBFgiiH8bNEz68PlNPa</a></td><td><a href="/files/Hovbb3jD34wGTIY03V14">/files/Hovbb3jD34wGTIY03V14</a></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td align="center"><strong>Customizable Framework</strong></td><td align="center">Adapt the DAO structure to fit various needs, including NFT communities, token-based DAOs and multi-sigs.</td><td></td><td><a href="/files/u8yY9ZmHEDlwXn0ENYHH">/files/u8yY9ZmHEDlwXn0ENYHH</a></td><td></td><td></td><td></td><td></td><td></td><td><a href="/files/UPCF5vJS3uGznzKs5QPe">/files/UPCF5vJS3uGznzKs5QPe</a></td><td></td></tr><tr><td align="center"><strong>Quorum and Thresholds</strong></td><td align="center">Set specific voting quorums and approval thresholds.</td><td></td><td><a href="/files/ju5o4TrxNRTE9RhLLEcf">/files/ju5o4TrxNRTE9RhLLEcf</a></td><td></td><td></td><td></td><td></td><td></td><td></td><td><a href="/files/XyiRYjiAK2193HvUZX1i">/files/XyiRYjiAK2193HvUZX1i</a></td></tr><tr><td align="center"><strong>Proposal and Voting Validation</strong></td><td align="center">Utilize Civic Pass to validate who can create a proposal or cast a vote.</td><td></td><td><a href="/files/dJ88i3SDJ4FUN6rcUW7I">/files/dJ88i3SDJ4FUN6rcUW7I</a></td><td></td><td></td><td><a href="/files/ed8Sv8Y8zWoKH2xoSTnQ">/files/ed8Sv8Y8zWoKH2xoSTnQ</a></td><td></td><td></td><td></td><td></td></tr><tr><td align="center"><strong>DAO Activity Notifications</strong></td><td align="center">Use Dialect to receive notifications of new proposals.</td><td></td><td><a href="/files/nHlruG1khK0nWHJ7kCzB">/files/nHlruG1khK0nWHJ7kCzB</a></td><td></td><td><a href="/files/S3CKEi9jTF86vCou4Gkk">/files/S3CKEi9jTF86vCou4Gkk</a></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td align="center"><strong>Custom Branding</strong></td><td align="center">DAOs can have their own branding, color schemes and domain name.</td><td></td><td><a href="/files/pQdSAJG1ojKBAx9w0Ouv">/files/pQdSAJG1ojKBAx9w0Ouv</a></td><td><a href="/files/vgBM3FdKBCQv2Iekwcoh">/files/vgBM3FdKBCQv2Iekwcoh</a></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td align="center"><strong>SPL Governance Integration</strong></td><td align="center">Realms acts as the frontend for SPL Governance, providing a versatile and standardized approach to DAO management on Solana.</td><td></td><td><a href="/files/3idvoHIlKXSqzL6U7yGo">/files/3idvoHIlKXSqzL6U7yGo</a></td><td></td><td></td><td></td><td><a href="/files/143U1urPyo8zowLzscom">/files/143U1urPyo8zowLzscom</a></td><td></td><td></td><td></td></tr><tr><td align="center"><strong>Open-source</strong></td><td align="center">Realms powers <a href="https://github.com/Mythic-Project/governance-ui">open-source</a> DAO management on Solana as the frontend for SPL Governance, built for flexibility and consistency.</td><td></td><td><a href="/files/v68vojwL9ZEB1RgCpI0P">/files/v68vojwL9ZEB1RgCpI0P</a></td><td></td><td></td><td></td><td></td><td><a href="/files/w1yfWUmOldAPpxCbduND">/files/w1yfWUmOldAPpxCbduND</a></td><td></td><td></td></tr></tbody></table>


# Safety

Learn more about security on Realms

{% file src="/files/YmtIGKoAopodk0AZ2Nto" %}

<table data-card-size="large" data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-type="image">Cover image (dark)</th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-cover-dark data-type="image">Cover image (dark)</th></tr></thead><tbody><tr><td align="center">Ottersec</td><td><a href="/files/U0oImqNV1nSd1tokFOzh">/files/U0oImqNV1nSd1tokFOzh</a></td><td><a href="/files/oACGKyr1tyw5APatPv8j">/files/oACGKyr1tyw5APatPv8j</a></td><td></td></tr><tr><td align="center">Sec3</td><td><a href="/files/7KaaOAcGO56CtkUWYvO1">/files/7KaaOAcGO56CtkUWYvO1</a></td><td><a href="/files/SYtAzl68Mp4i7L4JcJGn">/files/SYtAzl68Mp4i7L4JcJGn</a></td><td></td></tr><tr><td align="center">Neodyme</td><td><a href="/files/W9SdjWXmyiXlinXJRiuH">/files/W9SdjWXmyiXlinXJRiuH</a></td><td><a href="/files/xS7JTIFNvbffDiLKyBrU">/files/xS7JTIFNvbffDiLKyBrU</a></td><td></td></tr><tr><td align="center">Accretion</td><td></td><td><a href="/files/FgwBlFIoKNxuW52Iy7Fv">/files/FgwBlFIoKNxuW52Iy7Fv</a></td><td><a href="/files/hAQ7kkcna7bDqp3vnNVw">/files/hAQ7kkcna7bDqp3vnNVw</a></td></tr></tbody></table>


# Costs

Platform fees & Network fees

## Detailed Breakdown <a href="#detailed-breakdown" id="detailed-breakdown"></a>

| Component                  | Estimated Cost | Description                                                      |
| -------------------------- | -------------- | ---------------------------------------------------------------- |
| **DAO Creation**           | \~2 SOL\*      | Creates the main DAO governance structure                        |
| **Metadata**               | \~0.5 SOL\*º   | Sets up DAO metadata and configuration                           |
| **Treasury Accounts**      | \~0.2 SOL\*    | Sets up token and SOL treasury wallets                           |
| **Voter Account**          | \~0.1 SOL\*    | Creates voter weight and delegation accounts                     |
| **Delegation Hub Profile** | \~0.1 SOL\*    | Creates a public delegate profile visible on the DAO’s main page |

\*Plus standard Solana network transaction fees.\
ºMetadata set up is free during DAO creation.

**Costs may vary based on:**

* Network congestion and priority fees
* Additional token accounts needed
* Complex governance configurations
* Custom plugin integrations

### Ongoing Operation Costs <a href="#ongoing-operation-costs" id="ongoing-operation-costs"></a>

{% hint style="success" %}
Realms does **not charge any additional fees** for platform usage.
{% endhint %}

All ongoing operations only incur **standard Solana network transaction fees**.

#### Network Transaction Fees <a href="#network-transaction-fees" id="network-transaction-fees"></a>

* **Voting**: \
  **SPL** \~ 0.0015 SOL\
  **NFT** \~ 0.00167 SOL (Reclaimable)
* **Proposal Creation**: min \~ 0.0020 SOL\
  *(costs scale depending on the size of the proposal plus instructions attached.)*


# Glossary

List of words related to governance

#### DAO (Decentralized Autonomous Organization) <a href="#dao-decentralized-autonomous-organization" id="dao-decentralized-autonomous-organization"></a>

A **decentralized organization** that operates based on rules encoded as smart contracts on a blockchain. DAOs are governed by their members through a **transparent voting process**.

#### Proposal <a href="#proposal" id="proposal"></a>

A **formal suggestion** or plan put forward for consideration by the members of a DAO. Proposals can include changes to the DAO's operations, **allocation of funds**, or changes to the **governance structure**.

#### Multisig <a href="#multisig" id="multisig"></a>

A **security mechanism** requiring multiple signatures to authorize a transaction. This adds a layer of security by preventing a **single point of failure**.

#### Council

A **council** is a selected group of trusted members or representatives responsible for overseeing key decisions, managing proposals, or acting as a check on community governance.&#x20;

#### Treasury <a href="#treasury" id="treasury"></a>

The **collective funds** or assets managed by a DAO. The treasury is often used to fund projects, pay contributors, and support the operations of the DAO.

### Governance Mechanics <a href="#governance-mechanics" id="governance-mechanics"></a>

#### Quorum <a href="#quorum" id="quorum"></a>

The **percentage of votes** required for a proposal to pass. This threshold can be set to ensure that a proposal has **sufficient support** from the community before being enacted.

#### Delegation <a href="#delegation" id="delegation"></a>

The process of **assigning voting power** to another member of the DAO. Delegation allows members to entrust their voting rights to someone they believe will **represent their interests**.

#### Vesting <a href="#vesting" id="vesting"></a>

The process by which tokens are **gradually released** to their recipients over time. Vesting schedules are used to incentivize **long-term commitment** and participation in the DAO.

### Technical Terms <a href="#technical-terms" id="technical-terms"></a>

#### On-Chain Governance <a href="#on-chain-governance" id="on-chain-governance"></a>

A governance system where all processes and decisions are **recorded and executed** on the blockchain. On-chain governance ensures **transparency** and **immutability** of the decision-making process.

#### Lockup Period <a href="#lockup-period" id="lockup-period"></a>

A **predetermined period** during which tokens cannot be sold or transferred. Lockup periods are often used to prevent **market manipulation** and ensure **long-term commitment**.


# Sowellian Governance

By utilizing a novel betting mechanism, organizations can align decisions and outcomes with "skin in the game"

{% file src="/files/Fo0vPIo3RjF1xHOrf5OR" %}

## Sowellian Governance

Drawing inspiration from Robin Hanson's Futarchy model, Sowellian Governance separates governance into two distinct layers to align incentives with outcomes.

#### 1. Strategy Layer: Vote on Values

**Voters decide top-level values and objectives.**\
Organizations vote on their Key Performance Indicators (KPIs), proposal settings, asset flows, and executive elections. This establishes the **"Rules of the Game."**

#### 2. Tactics Layer: Bet on Methods

**Bettors determine the best methods** to achieve objectives through a market-based mechanism.\
Proposals are supported or opposed through betting, with payouts determined by outcomes.

### Core Principles

These principles guide the governance architecture. Each maps directly to a specific mechanism within the system.

#### 1. Pay for Mistakes

Those who make decisions must pay for mistakes.

**Mechanism**: All signaling is done through betting. If an idea secures the most bets, it is implemented. Upon evaluation, the bet is resolved financially.

#### 2. Vote on Values

Every organization has KPIs and proposals must target them.

**Mechanism**: Proposals must target specific KPIs. Organizations vote to select which KPIs are valid, ensuring focus and alignment.

#### 3. Proposing with Purpose

Proposers compete to surface valuable ideas; bettors compete to support them.

**Mechanism**: Time-Weighted Staking: The earlier a bet is placed, the higher the potential reward. This incentivizes proposers to share good ideas quickly.

#### 4. Bet on Beliefs

Voters stake once to express belief.

**Mechanism**: To ensure skin in the game, the bet is locked until the outcome is evaluated. Results matter and impact those that make the decision.

#### 5. Sustainable Change

Change should always leave the organization better off.

**Mechanism**: Every proposal generates revenue for the treasury via a Proposal Bond (for missing quorum) or a 1% Rake from losing bets.

### Voting on Values

Decentralized organizations are often plagued by obtuse policies and perverse incentives. Sowellian Governance establishes the "Rules of the Game" first through standard voting.

#### KPIs (The Target)

What outcomes can proposals target?

* Objective: On-chain or externally verifiable
* Time-bounded: Clear start and end points
* Quantifiable: Binary or numeric (e.g., "+10% user growth in 3 months")

#### Proposal Settings (The Rules)

The criteria required to pass a proposal

* Betting duration
* Evaluation timeline
* Bond amounts
* Quorum thresholds

#### Asset Flows (The Budget)

How assets are utilized between elections

* Allowances and Grants
* Redemptions/Dissolutions
* Taxes and Protocol Fees

#### Elections (The Executive)

Who has authority for tactical decisions?

* Executive branch or committee
* Decisions that cannot be automated
* Elected group authority

### The Execution Cycle

Once values are set, the organization moves into the operational cycle. Here's how proposals flow from idea to outcome.

#### 1. Proposing with Purpose

Anyone can create a proposal by selecting a targeted KPI, describing the idea, and submitting a Proposal Bond.

* Select the KPI you are targeting
* Describe your proposal idea
* Submit the Proposal Bond (fixed amount)

**The Check**: If the proposal does not meet the required Quorum, the bond is forfeited to the treasury. This prevents spam.

#### 2. Betting on Beliefs

Once live, the community places bets to support (**YES**) or oppose (**NO**) the idea.

* Lock-up: Bets cannot be withdrawn
* Multi-bet: Participants can increase position during betting window
* Incentive: Payouts are time-weighted

Contentious proposals offer high returns for winners; highly supported proposals offer high returns for contrarians who turn out to be right.

#### 3. Observing Outcomes

Outcomes are measured by an Oracle, a 'source of truth' or an elected group if no data feed exists.

* Success: The KPI was met. YES bettors win
* Failure: The KPI was not met. NO bettors win
* The Rake: 1% of losing side's pot goes to Treasury

Payouts are calculated based on the amount bet and how long the bet was held; paid immediately after outcome confirmation.

#### Pass/Fail Criteria

**PASS**\
If **YES Bets > NO Bets** at the end of the window. The proposal moves to execution and evaluation.

**FAIL**\
If **NO Bets > YES Bets**. The proposal is rejected, and all bets are returned (no loss of capital, merely opportunity cost).

**No Quorum**\
Bond forfeited to treasury.

### Visualizing the Workflow

The complete lifecycle of a proposal from creation to resolution.

#### Phase 1: Proposing

* Select KPI target
* Describe proposal
* Submit bond

#### Phase 2: Betting

* YES bets = Support
* NO bets = Oppose
* Bets locked until eval

**Decision**

* YES > NO → Proposal passes
* NO > YES → Proposal fails, bets returned
* No Quorum → Bond forfeited to treasury

#### Phase 3: Observing

* Oracle measures KPI
* Winners get losers' stake
* 1% rake to treasury

### Payout Illustrations

Understanding how payouts work based on time-weighted stakes. Earlier bets receive higher rewards, incentivizing early conviction.

#### If YES Wins

Scenario: 90% YES / 10% NO: Proposal passes

Losing Pool (after 1% rake): $9,900

Total Weighted YES Stake: 90,800

| Role              | Stake ($)  | Time Weight | Weighted Stake | Profit Share ($) | Profit % | Final Value ($) |
| ----------------- | ---------- | ----------- | -------------- | ---------------- | -------- | --------------- |
| Proposer          | 1,000      | 1.5×        | 1,500          | +163.4           | 16.3%    | 1,163.4         |
| Early Bettor      | 30,000     | 1.3×        | 39,000         | +4,252           | 14.2%    | 34,252          |
| Mid Window Bettor | 30,000     | 1.0×        | 30,000         | +3,270.9         | 10.9%    | 33,270.9        |
| Late Bettor       | 29,000     | 0.7×        | 20,300         | +2,213.7         | 7.6%     | 31,213.7        |
| **TOTAL**         | **90,000** | -           | **90,800**     | **+9,900**       | -        | **99,900**      |

### Case Studies

To illustrate the flexibility of Sowellian Governance, we apply the model to two distinct entities with different goals and contexts.

#### The Trading Group

**Decentralized Hedge Fund**

Treasury: $1M\
KPI: Treasury Value Increases

**Configuration**

* Proposal Settings: 1-day betting; 1-week evaluation. Bond: 1% of Quorum
* Quorum: 1% of Treasury Value ($10k in bets required)
* Asset Flows: Executive team receives 5% of profit

**The Proposal**

"Exchange 10% of USD Treasury into Bitcoin"

**The Bet**

Bond posted: $1,000. Betting ensues.

**The Outcome**

Proposal passes (90% YES). Bitcoin is bought.

**Resolution**

One week later: Bitcoin price dropped. The KPI (Increase Treasury Value) failed.\
The NO bettors win the YES bettors' money.

#### The Fishing Village

**Community Governance**

Treasury: 10,000 Gold Coins\
KPI: Increase Population\
Population: 1,000

**Configuration**

* Proposal Settings: 1-week betting; 1-year evaluation. Bond: 10 Coins
* Quorum: 10% of Treasury Value + 10% Citizen Participation
* Asset Flows: Tribe manages 20% of treasury. 30% Fish Sales Tax

**The Proposal**

"Lower fish tax for families of 5 or more"

**The Bet**

Bond posted: 10 Coins. High contention (55% YES / 45% NO).

**The Outcome**

Proposal passes. Tax break enacted.

**Resolution**

One year later: Census shows 25% population growth.\
The YES bettors win the NO bettors' money.

### References & Further Reading

The intellectual foundations of Sowellian Governance draw from these key works.

**Thomas Sowell**

* *The Vision of the Anointed:* A critique of political decision-making by those who bear no consequences for their errors.
* *Knowledge and Decisions:* An exploration of how knowledge is dispersed throughout society and how decisions should be made accordingly.

**Robin Hanson**

* *Futarchy: Vote Values, But Bet Beliefs*: The foundational paper on using prediction markets for governance decisions.
* *The Age of Em*: A look at future governance structures and economic organization.


# Sowellian: How It Works

## Sowellian: How It Works

Sowellian is a prediction market governance plugin for SPL Governance. It transforms traditional governance proposals into betting markets where participants stake tokens on the outcome of proposals, combining financial incentives with governance participation.

### Overview

Instead of simply voting "Yes" or "No" on a proposal, Sowellian creates a **bet** tied to each proposal. Participants stake tokens on their predicted outcome, and when the bet is resolved, winners earn from the losing pool. This creates a "skin in the game" dynamic that incentivizes informed participation and honest signal expression.

**Program ID:** `sowEL1Rtn3p479rg34gW7mVPeCNY58Es5rkLpFsCJAW`

### Core Concepts

#### Bet

A Bet is the central account that ties a prediction market to an SPL Governance proposal. It tracks:

* The associated proposal
* Total tokens staked on Yes vs No
* The bet's lifecycle state (Active, Settled, Resolved)
* The seed used for PDA derivation
* The owner (proposer) who created it

#### Vote Receipt

When a participant places a bet (casts a Sowellian vote), a **Vote Receipt** is created. This receipt:

* Records the voter's position (Yes or No)
* Records the amount staked
* Becomes the `governing_token_owner` for a dedicated Voter Weight Record
* Is used to claim winnings after resolution

#### Registrar

The Registrar configures the Sowellian plugin for a specific Realm. It stores:

* The linked Realm and governing token mint
* The governance account
* The treasury address (for fee collection)
* The realm authority

### Lifecycle

#### 1. Create a Bet

When a proposal is created, a bet is created alongside it:

```
create_bet(seed, name, description_link, proposal_seed, amount)
```

The proposer provides an initial stake and defines the bet parameters. A proposal is automatically created in SPL Governance tied to this bet.

#### 2. Cast Sowellian Votes

Participants stake tokens on their predicted outcome:

```
cast_sowellian_vote(vote_seed, is_yes, amount)
```

* `is_yes: true` - Betting the proposal will pass
* `is_yes: false` - Betting the proposal will fail
* `amount` - Number of tokens to stake

Tokens are transferred to the bet vault (an Associated Token Account controlled by the bet PDA).

Each vote creates:

1. A **Vote Receipt** PDA: `['vote-receipt', bet, vote_seed]`
2. A **Voter Weight Record** PDA for the receipt, allowing the governance program to recognize the vote

The Sowellian plugin simultaneously casts the governance vote through CPI (Cross-Program Invocation) to the SPL Governance program.

#### 3. Settle the Bet

After the governance vote concludes, anyone can settle the bet:

```
settle_bet()
```

Settlement:

* Locks in all staked amounts
* Prevents further betting
* The proposal owner's receipt is created
* A treasury cut is taken from the pool

#### 4. Resolve the Bet

The realm authority resolves the bet with the actual outcome:

```
resolve_bet(outcome: BetOutcome)  // Yes, No, or Void
```

Resolution:

* Sets the winning side
* Takes a 1% treasury cut from the total pool
* Marks the bet as resolved

#### 5. Claim Winnings

Winners claim their share of the losing pool:

```
claim_bet(vote_seed)
```

Winnings are distributed proportionally based on each winner's stake relative to the total winning pool.

### Fee Structure

| Fee                   | Percentage | Description                                     |
| --------------------- | ---------- | ----------------------------------------------- |
| Proposer Profit Share | 15%        | Portion of profits allocated to the bet creator |
| Voter Profit Share    | 5%         | Additional share for governance voters          |
| Bet Loss Rake         | 1%         | Treasury cut from the total pool on resolution  |

### Bet Weight Multiplier

Sowellian applies a weight multiplier to bets based on the participant's position in the betting order, divided into 10 buckets:

```typescript
const SOWELLIAN_WEIGHT_ARRAY = [
  1, 1.2, 1.4, 1.6, 1.8, 2, 2.2, 2.4, 2.5, 2.5,
];
```

The multiplier ranges from 1x (first bucket) to 2.5x (last buckets). A participant's bucket is determined by their position relative to the total number of bettors.

### PDA Addresses

| Account             | Seeds                                                                |
| ------------------- | -------------------------------------------------------------------- |
| Registrar           | `['registrar', realm, governing_token_mint]`                         |
| Bet                 | `['bet', seed]`                                                      |
| Vote Receipt        | `['vote-receipt', bet, vote_seed]`                                   |
| Voter Weight Record | `['voter-weight-record', realm, governing_token_mint, vote_receipt]` |
| Bet Vault           | ATA of the bet PDA for the governing token mint                      |

### Integration with SPL Governance

Sowellian works as a governance plugin by:

1. **Registering as a voter weight addin** on the Realm through `SetRealmConfig`
2. **Creating VoterWeightRecords** for each bet participant (keyed to their vote receipt, not their wallet directly)
3. **Casting governance votes via CPI** when a Sowellian vote is placed
4. The governance program reads the Sowellian-managed VoterWeightRecords to determine voting power

This means every Sowellian bet simultaneously functions as a governance vote, bridging prediction markets with on-chain governance execution.

### Helper Functions

```typescript
import {
  getBetAddress,
  getRegistrarAddress,
  getVoteReceiptAddress,
  getSowellianVoterWeightRecordAddress,
  SOWELLIAN_PLUGIN_PROGRAM_ID,
} from './sowellian/constants';

// Derive the bet PDA
const betAddress = getBetAddress(seed);

// Derive the registrar PDA
const registrarAddress = getRegistrarAddress(realm, governingTokenMint);

// Derive vote receipt PDA
const receiptAddress = getVoteReceiptAddress(bet, voteSeed);

// Derive voter weight record PDA
const vwrAddress = getSowellianVoterWeightRecordAddress(
  realm, governingTokenMint, governingTokenOwner
);
```


# Island Capital Proposals

Proposals are how DAOs make decisions, this guide shows you how to create Sowellian proposals.

{% columns fullWidth="false" %}
{% column %}

## Token Votes

There are two scheduled token votes:

* **At start**
* **At midway**

During token votes:

* **No open bets**
* **No new trades**
* **Island Capital is paused**
  {% endcolumn %}

{% column %}

## Voted Parameters

* **Proposal threshold**: 0.1% of Treasury
* **Proposer bond**: 0.1% of Treasury
* **Sowellian Quorum**: 1% of Treasury

### Links

* **DAO**: [Link](https://v2.realms.today/sowellian/BrSjisqNyzfQY6MtcaW6JcNkDGNyC7vani47RTa54QNQ)
* **X**: <https://x.com/@islanddao>
  {% endcolumn %}
  {% endcolumns %}

{% embed url="<https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjcBkwIHRLHkf9D1lm834%2Fuploads%2FSaBPk2KnImoSQ1La3Ja9%2Fcursorful-video-1769809210606.mp4?alt=media&token=b95a9822-6031-41ba-b52b-bbd1e76dd29d>" %}
How to create a Sowellian proposal on Island Capital
{% endembed %}

## **What is Island Capital Buying?**

Simply click to create a **Bet** and choose an asset that you wish to allocate to using **Jupiter Limit Orders**.

## **How Long?**

* Vote duration: 48 hours
* Max evaluation period: Up to 2 weeks

## **What is the Size?**

Trade sizes:

* **5–10% of Treasury**: Take Profit at ±10%
* **0–5% of Treasury**: No SL / TP

## **Incentives**

* 15% of profits allocated to proposers
* 5% of profits allocated to voters
* 1% loser rake allocated to IslandDAO Treasury


# V2 Interface

Complete guide to navigating the Realms V2 interface

## Overview <a href="#overview" id="overview"></a>

You most likely use the web-based UI as the primary point of interaction with the SPL Governance program. Therefore, we will conclude this article with a brief overview of the discussed concepts in the context of the UI.

### Creating a Realm <a href="#creating-a-realm" id="creating-a-realm"></a>

**Quick Start**: Navigate to [**v2.realms.today**](https://v2.realms.today/) to see existing realms and create your own DAO.

When you navigate to the Realms homepage, you can browse the list of existing realms. Clicking the **Create DAO** button presents you with three specialized options:

* **NFT Community DAO** — Voting power comes from NFT ownership using voter weight plugins
* **Community Token DAO** — Community-driven DAOs with both council and community enabled
* **Multi-Signature Wallet** — Creates a Realm where only the council votes (community disabled)

Each option provides a walkthrough wizard with predefined default parameters and customizable settings specific to that DAO type.

{% hint style="success" %}
**Configuration Changes**: When a Realm is created, configuration changes are made through **proposals,** the standard way to modify Realm and Governance settings.
{% endhint %}

## Key Interface Components <a href="#key-interface-components" id="key-interface-components"></a>

{% hint style="info" %}
**Navigation Tip**: The following sections cover the essential UI components you'll interact with when managing your DAO.
{% endhint %}

#### My governance power <a href="#my-governance-power" id="my-governance-power"></a>

After connecting their wallet, users can deposit tokens into a DAO to manage their voting power, veToken lockers, and delegation, depending on the DAO’s setup.

#### Settings <a href="#params" id="params"></a>

This section shows the settings of the **DAO** and allows for changes through the creation wizard. The user can change the configuration of the **DAO** (stored in **`RealmConfigAccount`**) in the top right corner by clicking on **Create Proposal** → **Add Instruction** → **DAO Config.**\
\
All **Governance** instances are listed below, and the voting settings can be changed by clicking on the **DAO Config** button. *(Through the Create Proposal Wizard)*\
\
It is also includes a list of **Governance** instances, including **Accounts**, where the user can list all related accounts to the Governance.\
\
The **Accounts** lists the **native treasury** wallet, ATA token wallets managed by the governance, and program accounts or a mint, if available.

<div data-with-frame="true"><img src="/files/zB8lgERIclO5N9AjBOMH" alt="DAO Settings Interface"></div>

#### DAO Wallets <a href="#dao-wallets" id="dao-wallets"></a>

This section provides a different perspective on the **`governance`** accounts. \
\
The list below the button represents the addresses of the **`native treasury`** wallets (every **`governance`** has one).&#x20;

<div data-with-frame="true"><img src="/files/Yx5tCM8P4Y1VTLSrYX5S" alt="DAO Treasury Accounts"></div>

#### Programs <a href="#programs" id="programs"></a>

This section allows the user to manage the **`upgrade authority`** of programs and do code upgrades. \
\
The **`new program`** button creates a new program type **`governance`** (see d*ifferent types of governances*) and takes over management power for the program.

<div data-with-frame="true"><figure><img src="/files/BeD69c1WJjSJyXENvRQY" alt=""><figcaption><p>DAO Owned Programs</p></figcaption></figure></div>

#### New proposal <a href="#new-proposal" id="new-proposal"></a>

The last section we will touch on is the **`new proposal`** screen.&#x20;

Here, the user can create a new proposal that can be chosen from a list of common proposals (such as council removal, transfer, etc.) or pass a base64-encoded transaction as a proposal.&#x20;

At **`Preview transaction`** button, the user can check the instruction by simulating it.&#x20;

The switch **`vote by council`** defines if the proposal will be created as a council or community proposal (a council proposal is voted on only by the council and vice versa).&#x20;

The **`create proposal`** button then creates a new proposal that is eventually listed on the main DAO page.


# DAO Creation Wizard


# Community Token DAO

A Community Token DAO is the most common type of DAO where governance power comes from holding governance tokens. Members vote on proposals proportional to their token holdings.

## Creating a Community Token DAO <a href="#creating-a-community-token-dao" id="creating-a-community-token-dao"></a>

Community Token DAOs are ideal for projects with a **distributed token economy** where governance should be **proportional to stake**.

## Prerequisites <a href="#prerequisites" id="prerequisites"></a>

Before creating your Community Token DAO:

* **Solana wallet** with at least **2 SOL (or 2.5 SOL for initial DAO metadata)** + network fees
* **Governance token** already created (or create through [**daoszn.fun**](https://www.daoszn.fun/launchpad/))
* **Basic understanding** of DAO governance concepts

{% stepper %}
{% step %}

### Start DAO Creation <a href="#step-1---start-dao-creation" id="step-1---start-dao-creation"></a>

Navigate to [**Realms**](https://v2.realms.today/) and click **Create DAO**, then select **Community Token DAO**.
{% endstep %}

{% step %}

### Governance Token Setup <a href="#step-2---basic-information" id="step-2---basic-information"></a>

Initial DAO setup requires an existing token for it to be created, alternative solution is to create a token through [daoszn.fun](https://daoszn.fun)
{% endstep %}

{% step %}

### Basic Information <a href="#step-2---basic-information" id="step-2---basic-information"></a>

Enter your DAO's basic information:

* **DAO Name**: Choose a clear, descriptive name
* **DAO Description**: Explain your DAO's purpose and goals
* **DAO Image**: 1mb Max 512x512px
* **DAO Banner**: 2mb Max 1200x400px
* **Category**: DeFi, Social, Web3, NFT, Gaming, Legal, Other
* **Socials Links**: Website, Twitter, Discord
  {% endstep %}

{% step %}

#### Council Setup <a href="#step-5---council-setup-optional" id="step-5---council-setup-optional"></a>

Decide if you want a council:

* **Council Size**: Number of council members
  {% endstep %}

{% step %}

### Review Settings <a href="#step-7---review-settings" id="step-7---review-settings"></a>

Review all your DAO configuration before deployment:

* Verify all parameters are correct
* Check token supply and voting thresholds
* Ensure treasury settings are appropriate
  {% endstep %}

{% step %}

### Advanced Configuration (Optional) <a href="#step-4---voting-configuration" id="step-4---voting-configuration"></a>

Custom set up voting parameters:

* **Proposal Threshold**: Tokens required to create proposals
* **Max Voting Time**: How long members have to vote
* **Cool-off Period**: Duration after the voting ends during which the vote can only be removed or voted *NO*
* **Approval Quorum**: Percentage of total supply needed to pass proposals
* **Treasury**: Amount of initial treasuries upon creation
  {% endstep %}
  {% endstepper %}

{% hint style="warning" %}
**Security Considerations**: Always test your DAO configuration with small amounts first and double-check all parameters.
{% endhint %}


# NFT Community DAO

An NFT Community DAO uses NFT ownership as the basis for governance participation. Each NFT typically represents one vote, creating a membership-based governance model.

## Creating an NFT Community DAO <a href="#creating-an-nft-community-dao" id="creating-an-nft-community-dao"></a>

NFT DAOs are perfect for communities built around **NFT collections**, where NFT holders make decisions about the collection's future.

## Prerequisites <a href="#prerequisites" id="prerequisites"></a>

Before creating your NFT Community DAO:

* **Solana wallet** with at least **2 SOL (or 2.5 SOL for initial DAO metadata)** + network fees
* **NFT Collection** already created and distributed
* **Collection metadata** and verification details

{% stepper %}
{% step %}

### Start NFT DAO Creation <a href="#step-1---start-nft-dao-creation" id="step-1---start-nft-dao-creation"></a>

Navigate to [**Realms**](https://v2.realms.today/) and click **Create DAO**, then select **NFT DAO**.
{% endstep %}

{% step %}

### NFT Collection Setup <a href="#step-3---nft-collection-setup" id="step-3---nft-collection-setup"></a>

Configure your NFT collection for governance:

* **Collection Address**: The verified collection identifier
* **Collection Name**: Display name for your collection
* **Voting Weight**: Usually 1 vote per NFT

|              ✅ Supported             |                   ❌ Not Supported                  |
| :----------------------------------: | :------------------------------------------------: |
| Metaplex Non-Fungible Standard (NFT) | Metaplex Programmable Non-Fungible Standard (pNFT) |
|         Metaplex Core (CORE)         |              Metaplex Hybrid (MPL-404)             |
|             {% endstep %}            |                                                    |

{% step %}

### DAO Information <a href="#step-2---dao-information" id="step-2---dao-information"></a>

Enter your NFT DAO's details:

* **DAO Name**: Should relate to your NFT collection
* **DAO Description**: Explain your DAO's purpose and goals
* **DAO Image**: 1mb Max 512x512px
* **DAO Banner**: 2mb Max 1200x400px
* **Category**: DeFi, Social, Web3, NFT, Gaming, Legal, Other
* **Socials Links**: Website, Twitter, Discord
  {% endstep %}

{% step %}

### Council Setup

Decide the size of your council:

* **Council Size**: Number of council members
  {% endstep %}

{% step %}

### Review Settings <a href="#step-7---review-settings" id="step-7---review-settings"></a>

Review all your DAO configuration before deployment:

* Verify all parameters are correct
* Check token supply and voting thresholds
* Ensure treasury settings are appropriate
  {% endstep %}

{% step %}

### Advanced Configuration (Optional) <a href="#step-4---voting-configuration" id="step-4---voting-configuration"></a>

Custom set up voting parameters:

* **Proposal Threshold**: Tokens required to create proposals
* **Max Voting Time**: How long members have to vote
* **Cool-off Period**: Duration after the voting ends during which the vote can only be removed or voted *NO*
* **Approval Quorum**: Percentage of total supply needed to pass proposals
* **Treasury**: Amount of initial treasuries upon creation
  {% endstep %}
  {% endstepper %}

{% hint style="warning" %}
**Security Considerations**: Always test your DAO configuration with small amounts first and double-check all parameters.
{% endhint %}


# Multi-Signature DAO (Multi-sig)

A Multi-Signature DAO operates like a traditional multi-sig wallet but with additional governance features. It's perfect for small teams or organizations that need shared control over assets and decis

## Creating a Multi-Signature DAO <a href="#creating-a-multi-signature-dao" id="creating-a-multi-signature-dao"></a>

Multi-sig DAOs are ideal for **small teams**, **treasuries**, or situations where you need a specific group of **trusted individuals** to approve all decisions.

### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

Before creating your Multi-Signature DAO:

* **Solana wallet** with at least **2 SOL (or 2.5 SOL for initial DAO metadata)** + network fees
* **List of signers** with their wallet addresses
* **Clear agreement** on signing thresholds and responsibilities

{% stepper %}
{% step %}

### Start Multi-Sig Creation <a href="#step-1---start-multi-sig-creation" id="step-1---start-multi-sig-creation"></a>

Navigate to [**Realms**](https://v2.realms.today/) and click **Create DAO**, then select **Create Multisig**.
{% endstep %}

{% step %}

### Basic Configuration <a href="#step-2---basic-configuration" id="step-2---basic-configuration"></a>

Enter your multi-sig DAO details:

* **DAO Name**: Choose a descriptive name for your organization
* **Description**: Explain the purpose and scope of the multi-sig
* **DAO Image**: 1mb Max 512x512px
* **DAO Banner**: 2mb Max 1200x400px
* **Category**: DeFi, Social, Web3, NFT, Gaming, Legal, Other
* **Socials Links**: Website, Twitter, Discord
  {% endstep %}

{% step %}

### Signer Setup <a href="#step-3---signer-setup" id="step-3---signer-setup"></a>

Add the wallet addresses that will be signers:

* **Primary Signers**: Core team members who can approve transactions
* **Verification**: Double-check all wallet addresses are correct
  {% endstep %}

{% step %}

### Review Settings <a href="#step-7---review-settings" id="step-7---review-settings"></a>

Review all your DAO configuration before deployment:

* Verify all parameters are correct
* Ensure treasury settings are appropriate
  {% endstep %}

{% step %}

### Advanced Configuration (Optional) <a href="#step-4---voting-configuration" id="step-4---voting-configuration"></a>

Custom set up voting parameters:

* **Max Voting Time**: How long members have to vote
* **Cool-off Period**: Duration after the voting ends during which the vote can only be removed or voted *NO*
* **Approval Quorum**: Percentage of total supply needed to pass proposals
* **Treasury**: Amount of initial treasuries upon creation
  {% endstep %}
  {% endstepper %}

{% hint style="danger" %}
**Critical**: Losing access to enough signer wallets can permanently lock your multi-sig.\
\
Always maintain secure backups and recovery procedures.
{% endhint %}

{% hint style="warning" %}
**Security Note**: Never store all signing keys in the same location or with the same person.\
\
Distribute risk across multiple trusted parties.
{% endhint %}


# Configurations

After a DAO is created, users that detain governance tokens or council tokens can change the DAO configuration.

## DAO configuration

For safe measures against DAO attacks make sure you DAO configuration has a **high minimum of governance tokens** for it to be altered.

### Initial Config Visualisation <a href="#initial-config-visualisation" id="initial-config-visualisation"></a>

{% hint style="success" %}
**Jito** will be used below for example purposes. After a DAO is deployed the configuration of a DAO can be found in **Settings**.
{% endhint %}

Upon opening **Settings** you will find the DAO main addresses, configuration & governances (treasuries).

<div data-with-frame="true"><img src="/files/lzzAIDGz8tHfY7xeWPRj" alt="DAO Settings Page"></div>

### Addresses <a href="#parameters" id="parameters"></a>

In the addresses section users are able to see:

* **Realm/ Pubkey**: Address of the DAO
* **Realm Authority 'x DAO Treasury'**: Realm authority, usually set to one of the DAO wallets, the authority controls DAO configuration.
* **Owner 'Governance Program'**: spl-governance instance used by the DAO.
* **Community Mint**: Address of the chosen governance token.
* **Council Mint**: Address of the council token.

### Governance (Treasuries) <a href="#governance-treasuries" id="governance-treasuries"></a>

In the governances section users are able to see the DAO treasury/ treasuries and their parameters, accounts & statistics.

For every treasury created an authority is also given for each.

### Advanced Parameters/ Config <a href="#config" id="config"></a>

In the advanced parameters/ config section users are able to see:

* **Community max vote weight source**: Percentage of the token supply considered for quorum or absolute number of the token supply or set number by the DAO.
* **Min community tokens to create governance**: Amount of tokens needed to change the DAO Config
* **Use community voter weight add-in**: Indicates whether voter weight governance plugin is used by the DAO.
* **Use max community voter weight add-in**: Indicates whether max voter weight governance plugin is used by the DAO.

{% hint style="info" %}
For **Multisig DAOs** without the community governance token, this value is irrelevant and it's defaulted to disabled value.
{% endhint %}

### Config Modification <a href="#config-modification" id="config-modification"></a>

Only users with sufficient governance tokens can propose configuration changes to maintain DAO security.

#### Prerequisites for Config Changes <a href="#prerequisites-for-config-changes" id="prerequisites-for-config-changes"></a>

Before modifying DAO configuration, ensure you have:

* Sufficient governance tokens to meet the minimum proposal threshold
* Understanding of the proposed changes and their impact
* Community consensus or discussion around the modification

{% stepper %}
{% step %}

#### Access DAO Configuration

Navigate to your DAO create proposal wizard section and move forward to DAO config and review the current configuration settings.<br>

1. Create Proposal
2. Proposal Details
3. Select Governance Wallet (Main)
4. Add Instruction
5. DAO Config
   {% endstep %}

{% step %}

#### Select Configuration Type <a href="#step-2---select-configuration-type" id="step-2---select-configuration-type"></a>

Click on **"Change Config"** to start proposing configuration changes.

Choose the type of configuration you want to modify:

**How would you like to configure your community token**: Liquid, Disabled, Membership

* Liquid - Maybe be bought, sold, or transferred.
* Disabled - This removes voting & managing power for token owners.
* Membership - Cannot be traded or transferred, but can be revoked by the DAO.

**Do you want the community to be able to manage this DAO**: Anyone with the alloted amount of governance power can edit non security-related information without a proposal.

**What is the minimum amount of governance power needed to manage this DAO?**: A user will need at least this much governance power to manage and edit information for this DAO.

**What type of governance structure do you want your DAO's community to use**: Default, VSR, NFT, Civic, QV, Custom

* Default - Governance is based on token ownership
* VSR - Locked tokens (veTokens)
* NFT - Voting enabled and weighted based on NFTs owned
* Civic - Governance based on Civic verification
* QV - Quadratic voting
* Custom - Add a custom program ID for governance structure

{% hint style="danger" %}
QV & Civic plugins are disabled at the moment, if you wish to pursue them please reach out!
{% endhint %}

**How would you like to configure your council token**: Liquid, Disabled, Membership

* Liquid - Maybe be bought, sold, or transferred.
* Disabled - This removes voting & managing power for token owners.
* Membership - Cannot be traded or transferred, but can be revoked by the DAO.

**What Type of community maximum voter weight do you want to use?**: This determines the maximum voter weight used to calculate voting thresholds. Updating this option requires you to know the maximum supply of your governance token.

* Supply Fraction
* Absolute
  {% endstep %}
  {% endstepper %}

{% hint style="warning" %}
**Security Note**: Always set conservative thresholds to prevent governance attacks. Higher minimum token requirements provide better security against malicious proposals.
{% endhint %}


# Features


# Proposals

Proposals are how DAOs make decisions, this guide shows you how to create, manage, and vote on them.

Proposals are the **foundation of DAO governance**, enabling community members to suggest changes, allocate resources, and make collective decisions. This guide covers everything you need to know about **creating**, **managing**, and **voting** on proposals.

## Creating a Proposal <a href="#creating-a-proposal" id="creating-a-proposal"></a>

{% stepper %}
{% step %}

### Access Proposal Creation

Navigate through the DAO page and click **Create Proposal**.
{% endstep %}

{% step %}

### Configure Proposal Details <a href="#step-3---configure-proposal-details" id="step-3---configure-proposal-details"></a>

Fill in the proposal information:

* **Title**: Clear, descriptive proposal name
* **Description**: Detailed explanation of the proposal

#### Choose Proposal Type <a href="#step-2---choose-proposal-type" id="step-2---choose-proposal-type"></a>

Select the appropriate proposal type based on your intended action:

* **Executable:** Executable proposals are proposals that contain on-chain instructions, which can be executed once the proposal reaches quorum and further more a finalized state.
* **Non-Executable:** These proposals are mostly used for signal voting/ multi-choice sentiment within the DAO.

<div data-with-frame="true"><figure><img src="/files/85HCcRncPE0sfLdFdxj4" alt=""><figcaption><p>Proposal Details</p></figcaption></figure></div>
{% endstep %}

{% step %}

### Add [Instructions](/realms-v2/features/instructions) (Executable) <a href="#step-4---add-instructions-executable" id="step-4---add-instructions-executable"></a>

For executable proposals, you can select instructions from the current list such as:

* **Treasury Transfers**: Specify recipient addresses and amounts
* **Configuration Changes**: Define new parameter values
* **DeFi Actions**: Staking, swaps & lending

Select the appropriate proposal type based on your intended action:

* **Community Vote:** Community Token holders will be able to vote.
* **Council Vote:** Vote is restricted only to Council token holders.
  {% endstep %}

{% step %}

### Add Multi-Choice Options (Non-Executable)

For non-executable proposals, you can select what type of multi-choice should the proposal be:

* **Single Selection**
* **Multiple Selection**

{% hint style="warning" %}
Non-executable proposals are limited to a maximum of 10 entries.
{% endhint %}

<div data-with-frame="true"><figure><img src="/files/9ezevFQ6R8nD24lHOcuE" alt=""><figcaption><p>Non-executable: Multi-Choice Options</p></figcaption></figure></div>
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Proposals are the primary mechanism for DAO evolution and decision-making. Active participation in the proposal process is essential for effective governance.
{% endhint %}

{% hint style="warning" %}
Always verify proposal instructions carefully, especially for treasury transfers. Approved proposals with incorrect instructions cannot be reversed.
{% endhint %}


# Instructions

Instructions are executable actions attached to proposals. When a proposal is approved, its instructions are executed on-chain.

## What are Instructions? <a href="#what-are-instructions" id="what-are-instructions"></a>

Instructions define **what happens** when a proposal passes. A proposal without instructions is purely signaling, it doesn't execute any on-chain action.

### Adding Instructions to a Proposal <a href="#adding-instructions-to-a-proposal" id="adding-instructions-to-a-proposal"></a>

{% stepper %}
{% step %}

#### Create a Proposal

Navigate to your DAO and click **Create Proposal**.
{% endstep %}

{% step %}

#### Fill Proposal Details <a href="#step-2---fill-proposal-details" id="step-2---fill-proposal-details"></a>

Add a title and description explaining the purpose.
{% endstep %}

{% step %}

#### Add Instruction <a href="#step-3---add-instruction" id="step-3---add-instruction"></a>

Click **Add Instruction** and select the instruction type you need.
{% endstep %}

{% step %}

#### Submit <a href="#step-5---submit" id="step-5---submit"></a>

Review and submit the proposal for voting.
{% endstep %}
{% endstepper %}

### Instruction Types <a href="#instruction-types" id="instruction-types"></a>

#### Common Instructions <a href="#treasury-instructions" id="treasury-instructions"></a>

| Instruction              | Description                                 |
| ------------------------ | ------------------------------------------- |
| **Transfer Tokens**      | Send tokens from treasury to a recipient    |
| **Create Token Account** | Create a new token account for the treasury |
| **Burn Tokens**          | Burn tokens from treasury                   |
| **Update Metadata**      | Add or update DAO Metadata                  |

#### Treasury/ DeFi Instructions <a href="#token-instructions" id="token-instructions"></a>

| Instruction                              | Description                                                                         |
| ---------------------------------------- | ----------------------------------------------------------------------------------- |
| **DeFi Lending**                         | Earn yield on treasury assets by depositing on [Save Finance](https://save.finance) |
| **Staking (Stake, Deactivate, Unstake)** | Stake SOL from the treasury to a validator                                          |
| **Token22 Fees**                         | Claim fees from token22 token account                                               |

#### Streaming Instructions <a href="#streaming-instructions" id="streaming-instructions"></a>

| Instruction            | Description                                   |
| ---------------------- | --------------------------------------------- |
| **Create Stream**      | Set up token streaming to a recipient         |
| **Cancel Stream**      | Stop an active stream                         |
| **Lock Tokens**        | Locks token until a specific date             |
| **Cancel Lock Tokens** | Cancel an active token lock from the treasury |

#### Custom Instructions <a href="#custom-instructions" id="custom-instructions"></a>

| Instruction            | Description                                   |
| ---------------------- | --------------------------------------------- |
| **Base64 Instruction** | Execute any instruction using raw base64 data |
| **Empty Instruction**  | Signaling proposal with no execution          |

Use Base64 instructions for advanced use cases or protocols not yet integrated into the UI.

#### Governance Instructions <a href="#governance-instructions" id="governance-instructions"></a>

| Instruction                   | Description                  |
| ----------------------------- | ---------------------------- |
| **Set Governance Config**     | Modify DAO voting parameters |
| **Set Realm Authority**       | Change the realm authority   |
| **Set Realm Config**          | Update realm configuration   |
| **Add/Remove Council Member** | Manage council membership    |

#### Program Instructions <a href="#protocol-integrations" id="protocol-integrations"></a>

| Instruction               | Description                                 |
| ------------------------- | ------------------------------------------- |
| **Upgrade Program**       | Deploy a new version of a DAO-owned program |
| **Set Upgrade Authority** | Transfer program upgrade authority          |
| **Close Program Buffer**  | Clean up unused program buffers             |

### Multiple Instructions <a href="#multiple-instructions" id="multiple-instructions"></a>

A single proposal can contain multiple instructions. They execute in order when the proposal is approved.

Common multi-instruction patterns:

* Create token account → Transfer tokens
* Multiple treasury transfers in one proposal

### Instruction Hold-up Time <a href="#instruction-hold-up-time" id="instruction-hold-up-time"></a>

Each instruction can have a **hold-up time** a delay between approval and execution. This gives the community time to react before irreversible actions occur.

### Executing Instructions <a href="#executing-instructions" id="executing-instructions"></a>

After a proposal passes:

1. Wait for any hold-up time to expire
2. Click **Execute** on each instruction
3. Confirm the transaction

Anyone can execute approved instructions once the hold-up time passes. Instructions must be executed before they expire.

For developers wanting to add custom protocol instructions, please reach out.


# Delegation

Delegation allows governance token holders to assign their voting power to trusted community members, enabling more active participation in DAO governance while maintaining democratic principles.

## How Delegation Works <a href="#how-delegation-works" id="how-delegation-works"></a>

When you delegate your tokens:

1. **Voting Power Transfer**: Your governance tokens' voting power is assigned to your chosen delegate
2. **Token Ownership**: You retain full ownership of your tokens
3. **Flexible Management**: You can change or revoke delegation at any time

### Delegating Your Voting Power <a href="#delegating-your-voting-power" id="delegating-your-voting-power"></a>

{% stepper %}
{% step %}

#### Access Delegation Interface

Navigate to the **My governance view** section in your DAO interface.
{% endstep %}

{% step %}

#### Choose a Delegate <a href="#step-2---choose-a-delegate" id="step-2---choose-a-delegate"></a>

Check your current delegation status and available voting power or select a community member to delegate your voting power to. Consider:

You can only delegate to **1 wallet**.

{% hint style="warning" %}
Split delegation is not supported yet.&#x20;
{% endhint %}

* **Track Record**: Review their voting history and DAO participation
* **Alignment**: Ensure their values align with your preferences
* **Activity Level**: Choose active participants who regularly vote
  {% endstep %}

{% step %}

#### Managing Your Delegations <a href="#step-3---managing-your-delegations" id="step-3---managing-your-delegations"></a>

Users can also check the delegation they are receiving from different addresses.

<div data-with-frame="true"><figure><img src="/files/2CpfE4q6BBQ6tKvVufHU" alt=""><figcaption><p>User Governance View</p></figcaption></figure></div>

{% hint style="success" %}
Delegation enhances DAO governance by enabling broader participation while leveraging community expertise.\
\
It's a powerful tool for creating more effective and representative decision-making processes.
{% endhint %}

{% hint style="warning" %}
Choose your delegates carefully. While delegation is reversible, poor delegate choices can impact important DAO decisions during the delegation period.
{% endhint %}
{% endstep %}
{% endstepper %}

### DAO Delegation Hub

*(soon)*


# Treasury

A treasury account is a shared wallet that holds assets owned by a DAO.

## Treasury Account <a href="#treasury-account" id="treasury-account"></a>

Each **DAO** can have any number of treasury accounts holding different assets (**SPL & Token22**).\
\
Anybody can deposit tokens into treasury accounts but only **DAO members** can approve withdrawals through **treasury transfer proposals**.

<div data-with-frame="true"><figure><img src="/files/HD7y5MHtffiP8GcbhKT1" alt=""><figcaption><p>DAO Treasury Page</p></figcaption></figure></div>

### Treasury Governance Settings <a href="#settings---treasury-governance-settings" id="settings---treasury-governance-settings"></a>

* **Min community tokens to create a proposal** — The minimal amount of the **DAO** community governance tokens a member of the DAO has to own to be allowed to propose transfers from the treasury.
* **Min instruction hold up time (days)** — The minimal number of days before you can transfer funds from the treasury after a vote on the transfer proposal is approved.

{% hint style="success" %}
The delay for treasuries is usually set to **0** to allow transfers of the assets immediately after they are approved.
{% endhint %}

* **Max voting time (days)** — The maximum number of days the **DAO** can vote on the treasury proposals. If consensus is not reached by the end of the voting time, the proposal is defeated.
* **Yes vote threshold (%)** — The Yes vote threshold defines the number of Approve votes required to approve a transfer from a treasury account. For example, if there are 10 members in the **DAO** and the Yes threshold is set to **60%**, then at least **6 members** must approve any transfers from the treasury.


# Streaming

Streaming allows continuous, time-based token transfers instead of one-time payments. Both users and DAOs can create streams to distribute tokens gradually over a set period.

## User Streaming <a href="#user-streaming" id="user-streaming"></a>

User streaming enables individuals to set up continuous token flows to recipients.

Access user streaming at [stream.realms.today](https://stream.realms.today/)

## Creating a User Stream <a href="#creating-a-user-stream" id="creating-a-user-stream"></a>

{% stepper %}
{% step %}

### Access Streaming

Navigate to [stream.realms.today](https://stream.realms.today/)

and connect your wallet.
{% endstep %}

{% step %}

### Configure Stream <a href="#step-2---configure-stream" id="step-2---configure-stream"></a>

Set up your stream parameters:

* **Recipient**: The wallet address receiving the stream
* **Token**: The token to stream (SOL, USDC, etc.)
* **Amount**: Total amount to be streamed
* **Duration**: Time period for the stream (days, weeks, months)
* **Start Date**: When the stream begins
  {% endstep %}

{% step %}

### Fund and Start <a href="#step-3---fund-and-start" id="step-3---fund-and-start"></a>

Deposit the tokens and activate the stream.
{% endstep %}
{% endstepper %}

### Managing Your Streams <a href="#managing-your-streams" id="managing-your-streams"></a>

* **View Active Streams**: Monitor ongoing streams and remaining balances
* **Cancel Stream**: Stop the stream and reclaim remaining tokens
* **Withdraw**: Recipients can withdraw accumulated tokens at any time

## DAO Streaming <a href="#dao-streaming" id="dao-streaming"></a>

DAO streaming enables governance-controlled token distribution for grants, salaries, vesting, and other recurring payments.

* **User Side**: View and manage your incoming DAO payments at [v2.realms.today/my-payments](https://v2.realms.today/my-payments)
* **DAO Side**: Create and manage streams through DAO instructions

#### Use Cases <a href="#use-cases" id="use-cases"></a>

* **Contributor Payments**: Pay team members over time
* **Grant Distribution**: Stream funds to grant recipients
* **Token Vesting**: Distribute vested tokens to stakeholders
* **Partnership Deals**: Gradual payments for long-term agreements

### Creating a DAO Stream <a href="#creating-a-dao-stream" id="creating-a-dao-stream"></a>

{% stepper %}
{% step %}

### Step 1 - Create Proposal

Submit a proposal to create a new stream from the DAO treasury.
{% endstep %}

{% step %}

#### Define Parameters <a href="#step-2---define-parameters" id="step-2---define-parameters"></a>

Specify stream details in the proposal:

* **Recipient Address**: Who receives the stream
* **Treasury Account**: Source of funds
* **Token and Amount**: What and how much to stream
* **Schedule**: Duration and start time
  {% endstep %}

{% step %}

#### Community Vote <a href="#step-3---community-vote" id="step-3---community-vote"></a>

DAO members vote on the streaming proposal.
{% endstep %}

{% step %}

#### Execution <a href="#step-4---execution" id="step-4---execution"></a>

If approved, the stream is created and starts automatically.
{% endstep %}
{% endstepper %}

### Managing DAO Streams <a href="#managing-dao-streams" id="managing-dao-streams"></a>

* **View All Streams**: See active streams from the treasury
* **Cancel via Proposal**: Stop a stream through governance vote
* **Modify Streams**: Change parameters through new proposals

DAO streams can only be created, modified, or cancelled through governance proposals.

### Stream Details <a href="#stream-details" id="stream-details"></a>

#### How Tokens Accumulate <a href="#how-tokens-accumulate" id="how-tokens-accumulate"></a>

Tokens accumulate linearly over time. For example, a 30-day stream of 3000 USDC releases 100 USDC per day.

#### Withdrawal <a href="#withdrawal" id="withdrawal"></a>

* Recipients can withdraw accumulated tokens anytime
* No need to wait until stream completion
* Partial withdrawals are supported

#### Cancellation <a href="#cancellation" id="cancellation"></a>

When a stream is cancelled:

* Recipient keeps already-streamed tokens
* Remaining tokens return to the sender (user or DAO treasury)

{% hint style="warning" %}
Always ensure sufficient token balance in the source account for the entire stream duration.
{% endhint %}


# Programs

DAO owned programs are Solana programs (smart contracts) where the upgrade authority is transferred to the DAO's governance.

## What are DAO Owned Programs? <a href="#what-are-dao-owned-programs" id="what-are-dao-owned-programs"></a>

When a program's upgrade authority is owned by a DAO:

* **Community Control**: The DAO members vote on all program upgrades
* **Decentralized Governance**: No single person can modify the program
* **Transparent Changes**: All updates happen through proposals visible to everyone
* **Security**: Prevents unauthorized modifications

<div data-with-frame="true"><figure><img src="/files/Hfo7JJLRnb6JNvtzIBGI" alt=""><figcaption></figcaption></figure></div>

### Program Upgrade Authority <a href="#program-upgrade-authority" id="program-upgrade-authority"></a>

On Solana, every deployed program has an **upgrade authority** - the wallet address that can deploy new versions of the program.

When this authority is transferred to a DAO's governance address, the program becomes DAO-controlled.

#### Making Changes <a href="#making-changes" id="making-changes"></a>

To upgrade or modify a DAO-owned program:

1. **Create a Proposal**: Submit a proposal with the program upgrade instruction
2. **Community Vote**: DAO members vote on the proposed changes
3. **Execution**: If approved, the upgrade is executed through governance
4. **Deployment**: The new program version is deployed on-chain

#### Common Use Cases <a href="#common-use-cases" id="common-use-cases"></a>

* **Protocol Upgrades**: Add new features or fix bugs in DAO protocols
* **Parameter Changes**: Update program configuration and settings
* **Security Patches**: Deploy critical security fixes through governance
* **Feature Additions**: Introduce new functionality voted on by the community

### Upgrading a DAO Owned Program <a href="#upgrading-a-dao-owned-program" id="upgrading-a-dao-owned-program"></a>

To upgrade a program owned by your DAO, you need to create a proposal with a custom instruction that includes:

* **Program ID**: The address of the program to upgrade
* **Buffer Address**: The address containing the new program code
* **Upgrade Instruction**: The specific upgrade command

Program upgrades are irreversible once executed. Always test thoroughly on devnet before proposing mainnet upgrades.

### Transferring Upgrade Authority to DAO <a href="#transferring-upgrade-authority-to-dao" id="transferring-upgrade-authority-to-dao"></a>

If you're a program developer wanting to transfer control to a DAO:

1. Deploy your program with your wallet as the upgrade authority
2. Test the program thoroughly
3. Create a proposal to transfer the upgrade authority
4. Execute the transfer instruction to the DAO's governance address

Once transferred, you'll need to go through the governance process to make any future changes. Make sure the program is production-ready before the transfer.


# Metadata

This guide shows you how to update your DAO’s logo, banner, and social links on Realms to build recognition and trust.

## DAO Metadata Overview

Managing the **DAO's visual identity** and social links is crucial for building recognition and trust within the community. This guide will walk you through the process of updating your **DAO's logo/banner and social links** through **on-chain metadata** using the Realms platform.

Whether you're setting up your DAO's identity for the first time or **refreshing your existing branding**, these steps will help you make these changes effectively and securely.

<div data-with-frame="true"><figure><img src="/files/WPtCktuAXP4psAPCeBVq" alt=""><figcaption><p>Jito DAO DAO Page</p></figcaption></figure></div>

#### **Prerequisites:**

* **Minimum community/council tokens** to create a proposal
* **Prepared logo and banner images**, (1mb max 512x512px for logo & 2mb max 1200x400px for banner)
* **Basic understanding** of proposal creation

The following steps will guide you through the entire process, from accessing the metadata interface to executing the final proposal.

#### Step 1 - Visit the DAO page <a href="#step-1---visit-the-dao-page" id="step-1---visit-the-dao-page"></a>

1. Click the **Add Metadata** button. *(Should be a little pencil icon in the top right corner of the DAO banner, only visible for users that match the min. governance power)*\
   \
   ***Alternative:** Find the Metadata instruction through the **Create Proposal** button.*

#### Step 2 - Fill the metadata <a href="#step-2---fill-the-metadata" id="step-2---fill-the-metadata"></a>

Realms allows DAOs to configure a variety of metadata fields to improve discoverability and presentation:

* **Display Name:** the primary name shown for the DAO
* **Description:** a short summary of the DAO’s purpose or mission
* **Logo:** main visual identity graphic
* **Banner:** header visual for DAO profile pages
* **Category:** classification to help users find similar DAOs\
  *(DeFi, Social, Web3, NFT, Gaming, Legal, Other)*
* **Social Links:** external links for community and communication\
  *(Website, Twitter/X, Discord)*

#### Step 3 - Review the metadata <a href="#step-3---review-the-metadata" id="step-3---review-the-metadata"></a>

* Once you have entered the desired fields, **verify all the details** on the Review page.
* Make sure that the images are **loading on this page.**
* Choose whether you want to create the through a **Community** or a **Multi-sig** proposal.

#### Step 4 - Sign the Transactions <a href="#step-4---sign-the-transactions" id="step-4---sign-the-transactions"></a>

* The wallet pop-up will ask you to sign 4-8 transactions depending upon the metadata configured.

#### Step 5 - Pass the proposal <a href="#step-5---pass-the-proposal" id="step-5---pass-the-proposal"></a>

* Once the transactions are confirmed, you can visit the DAO and pass the metadata proposal.
* After the proposal is executed, the metadata will reflect on Realms after few brief moments.

<br>


# Council

A council is a selected group of trusted members or representatives responsible for overseeing key decisions, managing proposals, or acting as a check on community governance.

## What is a DAO Council? <a href="#what-is-a-dao-council" id="what-is-a-dao-council"></a>

A DAO council is a group of **elected** or **appointed members** who have special privileges and responsibilities within the organization. They often play a crucial role in **governance**, **decision-making**, and **day-to-day operations** of the DAO.

### Adding or Removing Council Members <a href="#adding-council-members" id="adding-council-members"></a>

{% stepper %}
{% step %}

#### Accessing Members

1. Navigate to the Members section of your DAO's interface and browse through the Multi-sig member tab.
2. Ensure you have the necessary permissions to propose new members.
   {% endstep %}

{% step %}

#### Initiating New Member Addition or Initiating Member Removal <a href="#step-2---initiating-new-member-addition" id="step-2---initiating-new-member-addition"></a>

1. Click the **Add/Remove** button in the members panel to start the process of adding a new member or initiating a member removal.
   {% endstep %}

{% step %}

#### Proposing a New Member/ Removal of a Member <a href="#step-3---proposing-a-new-member" id="step-3---proposing-a-new-member"></a>

1. Enter the new member's **wallet address** in the provided form.
2. Click the **Create Proposal** button to create a proposal for adding the new member. *(Via Community or Council vote)*

{% hint style="info" %}
The proposal form **auto-fills** with default values through step 1 & 2. You can override these if needed, but it's not required.
{% endhint %}

{% hint style="warning" %}
**Voter Weight**: This determines the new member's voting power within the DAO. A weight of 1 equals one vote. Consider carefully as this affects the balance of power in the DAO
{% endhint %}
{% endstep %}
{% endstepper %}


# Veto

Veto allows DAOs to configure a secondary rejection mechanism where proposals can be blocked if a sufficient number of members vote against them, even if the approval threshold was met.

## What is Veto? <a href="#what-is-veto" id="what-is-veto"></a>

Veto is a governance safeguard that enables:

* **Community Veto**: Community token holders can block proposals
* **Council Veto**: Council members can block proposals
* **Quorum-based Rejection**: Proposals are vetoed when rejection votes meet the configured quorum

This provides an additional layer of protection against proposals that may have passed the approval threshold but face strong opposition.

## Veto Configuration <a href="#veto-configuration" id="veto-configuration"></a>

DAOs can configure veto settings separately for both community and council governance.

### Community Veto Settings <a href="#community-veto-settings" id="community-veto-settings"></a>

* **Veto Quorum (%)**: The percentage of community voting power required to veto a proposal
* **Enable/Disable**: Toggle community veto capability on or off

### Council Veto Settings <a href="#council-veto-settings" id="council-veto-settings"></a>

* **Veto Quorum (%)**: The percentage of council members required to veto a proposal
* **Enable/Disable**: Toggle council veto capability on or off

### Setting Up Veto <a href="#setting-up-veto" id="setting-up-veto"></a>

{% stepper %}
{% step %}

#### Access DAO Configuration

Navigate to your DAO's **Settings** section to view current governance settings.
{% endstep %}

{% step %}

#### Create Configuration Proposal <a href="#step-2---create-configuration-proposal" id="step-2---create-configuration-proposal"></a>

Create a proposal to modify the DAO configuration and enable veto settings.

* Create Proposal
* Edit Wallet Rules
* Advanced Community Settings/ Advanced Multisig Settings
* Enable/ Disable
  {% endstep %}

{% step %}

#### Configure Veto Parameters <a href="#step-3---configure-veto-parameters" id="step-3---configure-veto-parameters"></a>

Set the veto quorum for community and/or council:

* **Community Veto Quorum**: Percentage of community tokens needed to veto
* **Council Veto Quorum**: Percentage of council votes needed to veto
  {% endstep %}

{% step %}

#### Submit and Vote <a href="#step-4---submit-and-vote" id="step-4---submit-and-vote"></a>

Submit the configuration proposal for community/council approval.
{% endstep %}

{% step %}

#### Execute Changes <a href="#step-5---execute-changes" id="step-5---execute-changes"></a>

Once approved, execute the proposal to apply the new veto settings.
{% endstep %}
{% endstepper %}

## How Veto Works <a href="#how-veto-works" id="how-veto-works"></a>

### During Voting <a href="#during-voting" id="during-voting"></a>

1. Members vote **Yes**, **No**, or **Veto (If enabled)** on a proposal
2. **Veto** votes count toward the veto quorum
3. If veto quorum is reached, the proposal is blocked regardless of approval votes

### Veto Outcome <a href="#veto-outcome" id="veto-outcome"></a>

* **Vetoed**: Proposal blocked when rejection votes meet veto quorum
* **Passed**: Proposal approved if it meets approval threshold without triggering veto
* **Failed**: Proposal fails to meet approval threshold


# Profile

The User Profile is your personal space within the DAO ecosystem, where you can manage your identity, view your participation, and customize your presence.

## Profile Overview <a href="#profile-overview" id="profile-overview"></a>

Your user profile serves as your identity card Realms. It displays essential information about your DAO participation and helps other members recognize and connect with you.

<div data-with-frame="true"><figure><img src="/files/FA0NelWat9eJ5OyUtgMF" alt=""><figcaption><p>User Profile Overview</p></figcaption></figure></div>

### Profile Structure <a href="#profile-structure" id="profile-structure"></a>

{% stepper %}
{% step %}

### Header Section

The header contains your primary identification information:

* **Profile Picture**
* **Display Name**
* **Wallet Address**
* **Social Links (Github/ Twitter)**
* **Bio Description**
  {% endstep %}

{% step %}

### Stats Section

This section displays your:

* **Followers**
* **Proposals**
* **Total Votes**
* **DAOs Joined**
  {% endstep %}

{% step %}

### Activity Statistics

Track your participation metrics:

* **Proposals Created**
* **Votes Cast**
* **Delegations&#x20;*****(Soon)***
  {% endstep %}

{% step %}

#### Achievements <a href="#id-6-badges--achievements-optional" id="id-6-badges--achievements-optional"></a>

soon
{% endstep %}
{% endstepper %}


# Leaderboard

The Realms Leaderboard tracks individual user activity and engagement, determining eligibility for Realms token allocation. Reputation before rewards.

Check your rank at [v2.realms.today/leaderboard](https://v2.realms.today/leaderboard).

## How It Works <a href="#how-it-works" id="how-it-works"></a>

The leaderboard reflects how you actually use Realms:

* **Which organizations you join**
* **Your votes and proposals**
* **How consistently you show up**

Realms tokens go to participants, not spectators.

### Earning Points <a href="#earning-points" id="earning-points"></a>

Increase your score by actively using Realms:

| Activity              | Description                                           |
| --------------------- | ----------------------------------------------------- |
| **Profiles**          | Create and maintain your Realms profile               |
| **DAO Participation** | Joining DAOs, Voting on proposals, creating proposals |
| **Consistency**       | Regular engagement over time                          |

### Getting Started <a href="#getting-started" id="getting-started"></a>

1. **Create your profile** at [v2.realms.today](https://v2.realms.today)
2. **Join DAOs** you believe in
3. **Vote** on proposals that matter
4. **Be consistent** in your participation

The more actively and consistently you participate in DAO governance, the higher your leaderboard ranking.

{% hint style="success" %}
Signal before distribution. Start participating now to build your reputation ahead of token allocation.
{% endhint %}


# Integrate Realms

Integrate Realms Into Your Stack

## Integrate Realms Into Your Stack

This guide covers how to integrate SPL Governance (Realms) into your application, whether you're building a DeFi protocol, NFT project, or any on-chain application that needs decentralized decision-making.

### Integration Approaches

#### 1. Use Realms as Your Upgrade Authority

The simplest integration: let your DAO control program upgrades.

```bash
# Transfer program upgrade authority to your DAO wallet
solana program set-upgrade-authority <PROGRAM_ID> \
  --new-upgrade-authority <DAO_WALLET_ADDRESS>
```

The DAO Wallet is the native treasury PDA derived from your Governance account. Once transferred, all program upgrades must go through a governance vote.

#### 2. Use the DAO Wallet as Admin Authority

If your program has admin/authority accounts, point them to the DAO Wallet:

```rust
// In your program's initialize instruction
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
    let config = &mut ctx.accounts.config;
    config.authority = dao_wallet_address; // DAO controls this program
    Ok(())
}
```

Any instruction in your program that requires this authority can now only be executed through a governance proposal.

#### 3. SDK Integration

**Install**

```bash
npm install @realms-today/spl-governance @solana/web3.js
```

**Read Governance Data**

```typescript
import {
  getRealm,
  getGovernance,
  getProposal,
  getTokenOwnerRecord,
  getAllGovernances,
  getAllProposals,
  getVoteRecordsByVoter,
  GOVERNANCE_PROGRAM_ID,
} from '@realms-today/spl-governance';

// Fetch realm info
const realm = await getRealm(connection, realmAddress);
console.log('Realm:', realm.account.name);
console.log('Community Mint:', realm.account.communityMint.toBase58());

// Fetch all governances
const governances = await getAllGovernances(connection, programId, realmAddress);

// Fetch proposals for a governance
const proposals = await getAllProposals(connection, programId, governanceAddress);

// Check a user's voting power
const tokenOwnerRecord = await getTokenOwnerRecord(connection, torAddress);
console.log('Voting power:', tokenOwnerRecord.account.governingTokenDepositAmount.toString());
```

**Create Governance Actions**

The SDK uses a builder pattern where all instruction-building functions are prefixed with `with` and push instructions onto a `TransactionInstruction[]` array:

```typescript
import {
  withCreateProposal,
  withInsertTransaction,
  withSignOffProposal,
  withCastVote,
  withExecuteTransaction,
  VoteType,
  Vote,
} from '@realms-today/spl-governance';
import { TransactionInstruction } from '@solana/web3.js';

// Full proposal lifecycle
const instructions: TransactionInstruction[] = [];

const proposalAddress = await withCreateProposal(instructions, /* ... */);
const txAddress = await withInsertTransaction(instructions, /* ... */);
withSignOffProposal(instructions, /* ... */);
// ... voting period ...
const voteRecord = await withCastVote(instructions, /* ... */);
// ... after vote succeeds + hold_up_time ...
await withExecuteTransaction(instructions, /* ... */);
```

#### 4. Embed Governance in Your dApp

Display governance data within your own frontend:

```typescript
// Fetch and display active proposals
async function getActiveProposals(realmAddress: PublicKey) {
  const governances = await getAllGovernances(connection, programId, realmAddress);

  const allProposals = [];
  for (const gov of governances) {
    const proposals = await getAllProposals(connection, programId, gov.pubkey);
    allProposals.push(...proposals.flat());
  }

  return allProposals
    .filter(p => p.account.state === ProposalState.Voting)
    .sort((a, b) =>
      b.account.votingAt.toNumber() - a.account.votingAt.toNumber()
    );
}
```

#### 5. Plugin Integration

If your protocol has a custom token model (staking, locking, etc.), build a governance plugin so your token holders can vote with their staked/locked tokens. See Create a Custom Plugin for details.

### Architecture Patterns

#### Pattern A: Governance-Controlled Protocol

```
┌──────────────┐    vote    ┌──────────────┐   execute   ┌──────────────┐
│  Token Holder │ ────────► │  SPL         │ ──────────► │  Your        │
│  Community    │           │  Governance  │             │  Protocol    │
└──────────────┘           └──────────────┘             └──────────────┘
                                  │
                                  ▼
                           ┌──────────────┐
                           │  DAO Wallet   │
                           │  (Treasury)   │
                           └──────────────┘
```

#### Pattern B: Multi-Governance Setup

Create multiple governances within a single realm for different security tiers:

```typescript
import { GovernanceConfig, VoteThreshold, VoteThresholdType, VoteTipping } from '@realms-today/spl-governance';

// High-security governance (e.g., program upgrades)
const highSecConfig = new GovernanceConfig({
  communityVoteThreshold: new VoteThreshold({ type: VoteThresholdType.YesVotePercentage, value: 80 }),
  baseVotingTime: 7 * 24 * 3600,           // 7 days
  minInstructionHoldUpTime: 3 * 24 * 3600,  // 3 day delay
  /* ... other required fields */
});

// Low-security governance (e.g., parameter tweaks)
const lowSecConfig = new GovernanceConfig({
  communityVoteThreshold: new VoteThreshold({ type: VoteThresholdType.YesVotePercentage, value: 50 }),
  baseVotingTime: 2 * 24 * 3600,            // 2 days
  minInstructionHoldUpTime: 0,
  /* ... other required fields */
});
```

#### Pattern C: Council + Community Hybrid

Use a council for quick decisions and community for major changes:

```typescript
import { withCreateRealm, MintMaxVoteWeightSource } from '@realms-today/spl-governance';

const instructions: TransactionInstruction[] = [];

const realmAddress = await withCreateRealm(
  instructions,
  programId,
  programVersion,
  'My DAO',
  realmAuthority,
  communityMint,     // large community
  payer,
  councilMint,       // small council (e.g., core team)
  MintMaxVoteWeightSource.FULL_SUPPLY_FRACTION,
  new BN(1),
);

// Council governance: fast, low threshold
// Community governance: slow, high threshold
```

### Deployment Models

#### Shared Instance (Quick Start)

Use the public governance program instance:

```typescript
const GOVERNANCE_PROGRAM_ID = new PublicKey('GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw');
```

#### Own Instance (Maximum Control)

Deploy your own instance for full sovereignty:

```bash
# Build the program
cargo build-sbf --manifest-path governance/program/Cargo.toml

# Deploy
solana program deploy target/deploy/spl_governance.so

# Transfer upgrade authority to your DAO
solana program set-upgrade-authority <PROGRAM_ID> \
  --new-upgrade-authority <DAO_WALLET>
```

This way your DAO governs its own governance program - no external party can change the rules.

### SPL Token 2022 Support

SPL Governance v3.1.2 supports Token-2022 (Token Extensions) for both community and council mints. Pass the appropriate `GoverningTokenConfigAccountArgs` with the token type when creating the realm:

```typescript
import {
  withCreateRealm,
  MintMaxVoteWeightSource,
  GoverningTokenConfigAccountArgs,
  GoverningTokenType,
} from '@realms-today/spl-governance';

const instructions: TransactionInstruction[] = [];

const realmAddress = await withCreateRealm(
  instructions,
  programId,
  programVersion,
  'My Token-2022 DAO',
  realmAuthority,
  communityMint2022,
  payer,
  councilMint,
  MintMaxVoteWeightSource.FULL_SUPPLY_FRACTION,
  new BN(1),
  // Community token config (Token-2022)
  new GoverningTokenConfigAccountArgs({
    voterWeightAddin: undefined,
    maxVoterWeightAddin: undefined,
    tokenType: GoverningTokenType.Liquid,
  }),
  // Council token config (standard SPL Token)
  new GoverningTokenConfigAccountArgs({
    voterWeightAddin: undefined,
    maxVoterWeightAddin: undefined,
    tokenType: GoverningTokenType.Liquid,
  }),
);
```


# AI Agents & Realms

AI agents can be powerful participants in DAO governance. They can monitor proposals, analyze voting patterns, automate routine governance tasks, and even act as delegates

## AI Agents and Realms

AI agents can be powerful participants in DAO governance. They can monitor proposals, analyze voting patterns, automate routine governance tasks, and even act as delegates. This guide covers how to integrate AI agents into Realms-based DAOs.

### Use Cases

#### 1. Proposal Monitoring and Analysis

An AI agent can watch for new proposals and provide automated analysis:

* Summarize proposal content and linked discussions
* Assess risk of proposed on-chain transactions
* Flag proposals that modify critical parameters
* Alert stakeholders about upcoming vote deadlines

#### 2. Automated Voting (Delegate Agent)

SPL Governance supports delegation. A token owner can delegate their voting power to another address, which can be controlled by an AI agent:

```typescript
import { withSetGovernanceDelegate } from '@realms-today/spl-governance';
import { TransactionInstruction } from '@solana/web3.js';

// Delegate voting power to the agent's wallet
const instructions: TransactionInstruction[] = [];

await withSetGovernanceDelegate(
  instructions,
  programId,
  programVersion,           // e.g. 3
  realmAddress,
  governingTokenMint,
  tokenOwnerWallet,         // token owner
  tokenOwnerWallet,         // governance authority (current authority)
  agentWalletAddress,       // the AI agent's wallet
);
```

Once delegated, the agent can cast votes on behalf of the token owner:

```typescript
import { withCastVote, Vote, YesNoVote } from '@realms-today/spl-governance';

const voteIxs: TransactionInstruction[] = [];

await withCastVote(
  voteIxs,
  programId,
  programVersion,
  realmAddress,
  governanceAddress,
  proposalAddress,
  proposalOwnerRecordAddress,
  delegatorTokenOwnerRecordAddress,
  agentWalletAddress,       // agent signs as delegate
  governingTokenMint,
  Vote.fromYesNoVote(YesNoVote.Yes),
  agentWalletAddress,       // payer
  voterWeightRecord,
  maxVoterWeightRecord,
);
```

#### 3. Proposal Creation Agent

An agent can create proposals programmatically based on triggers:

* Scheduled treasury distributions
* Automated parameter adjustments based on on-chain metrics
* Emergency proposals when security thresholds are breached

#### 4. Transaction Execution Bot

After a proposal passes and the hold-up time elapses, execution is permissionless. An AI agent can monitor for executable proposals and trigger them:

```typescript
import { withExecuteTransaction } from '@realms-today/spl-governance';

// Anyone can execute - no special permissions needed
const executeIxs: TransactionInstruction[] = [];

await withExecuteTransaction(
  executeIxs,
  programId,
  programVersion,
  governanceAddress,
  proposalAddress,
  proposalTransactionAddress,
  transactionInstructions,  // InstructionData[] from the ProposalTransaction
);
```

#### 5. Governance Analytics Agent

Build an agent that provides ongoing governance health metrics:

* Voter participation rates
* Proposal success/failure ratios
* Treasury balance monitoring
* Token holder concentration analysis

### Architecture Pattern

A typical AI agent integration follows this pattern:

```
┌─────────────────────┐
│   AI Agent Service   │
│  (Off-chain server)  │
├─────────────────────┤
│  - LLM for analysis │
│  - Decision logic    │
│  - Scheduling        │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│   Agent Wallet       │
│  (Solana Keypair)    │
├─────────────────────┤
│  - Signs transactions│
│  - Holds SOL for fees│
│  - Delegated voting  │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│  SPL Governance      │
│  (On-chain program)  │
├─────────────────────┤
│  - Cast votes        │
│  - Create proposals  │
│  - Execute txs       │
└─────────────────────┘
```

### Implementation Guide

#### 1. Set Up the Agent Wallet

```typescript
import { Keypair, Connection } from '@solana/web3.js';

// Generate or load the agent's keypair
const agentKeypair = Keypair.fromSecretKey(
  Buffer.from(process.env.AGENT_PRIVATE_KEY, 'base64')
);

const connection = new Connection(process.env.RPC_URL);
```

#### 2. Monitor Proposals

Poll for new proposals or use WebSocket subscriptions:

```typescript
import { getAllProposals, ProposalState } from '@realms-today/spl-governance';

async function monitorProposals(governanceAddress: PublicKey) {
  const proposals = await getAllProposals(
    connection,
    programId,
    governanceAddress,
  );

  const activeProposals = proposals.flat().filter(
    p => p.account.state === ProposalState.Voting
  );

  for (const proposal of activeProposals) {
    await analyzeAndVote(proposal);
  }
}
```

#### 3. Analyze and Decide

Feed proposal data to your AI model for analysis:

```typescript
async function analyzeAndVote(proposal) {
  // Fetch proposal details and description
  const description = await fetchProposalDescription(proposal.account.descriptionLink);

  // Fetch proposed transactions
  const transactions = await getProposalTransactions(proposal.pubkey);

  // AI analysis
  const analysis = await aiModel.analyze({
    name: proposal.account.name,
    description,
    transactions: transactions.map(formatTransaction),
    governanceConfig: await getGovernanceConfig(proposal.account.governance),
  });

  // Decision
  if (analysis.shouldVote) {
    await submitVote(proposal, analysis.vote);
  }
}
```

#### 4. Submit Votes

```typescript
async function submitVote(proposal, voteDecision: Vote) {
  const instructions: TransactionInstruction[] = [];

  await withCastVote(
    instructions,
    programId,
    programVersion,
    realmAddress,
    proposal.account.governance,
    proposal.pubkey,
    proposalOwnerRecord,
    agentTokenOwnerRecord,
    agentKeypair.publicKey,
    governingTokenMint,
    voteDecision,
    agentKeypair.publicKey,
  );

  const tx = new Transaction().add(...instructions);
  await sendAndConfirmTransaction(connection, tx, [agentKeypair]);
}
```

### Security Considerations

* **Key Management**: Store agent private keys securely (HSM, KMS, or encrypted vault). Never hardcode keys.
* **Spending Limits**: Use a dedicated wallet with limited SOL for fees. The agent should not hold governance tokens directly - use delegation instead.
* **Delegation Revocation**: Token owners can revoke delegation at any time by calling `setGovernanceDelegate` with `None`.
* **Audit Trail**: Log all agent decisions and the reasoning behind them for transparency.
* **Rate Limiting**: Implement rate limits to prevent the agent from taking too many actions in a short period.
* **Human Override**: Always maintain the ability for human governance participants to override agent decisions through delegation revocation.

### Existing Integrations

AI agents can be combined with existing governance plugins:

* **VSR + AI Agent**: Agent votes with time-locked token power
* **NFT Voter + AI Agent**: Agent manages NFT-based governance participation
* **Sowellian + AI Agent**: Agent participates in prediction market governance bets

The delegation mechanism is the key enabler. Since any wallet can be a delegate, AI agents naturally fit into the existing governance model without requiring any protocol changes.


# Plugins V2

*soon*


# Plugins V1


# Voter Weight Plugin

## What is a Voter Weight Plugin? <a href="#what-is-a-voter-weight-plugin" id="what-is-a-voter-weight-plugin"></a>

Realms is designed to be ***modular***, allowing for the addition of ***plugins*** that can modify the voter weight of members in a DAO.\
\
By default, the voter weight of a member is equal to the number of tokens they hold.\
\
However, if a DAO enables a plugin, the voter weight of a member can be modified.

Example plugins are:

* **Quadratic Voting**: The voter weight of a member is proportional to the square root of the number of tokens they hold.
* **Voter Stake Registry**: A voter's weight can be increased by locking tokens.
* **NFT**: The voter weight of a member is proportional to the number and type of NFTs they hold.

## How to Create a Voter Weight Plugin <a href="#how-to-create-a-voter-weight-plugin" id="how-to-create-a-voter-weight-plugin"></a>

There are two parts to creating a voter weight plugin:

1. The on-chain program
2. The JS/TS client

Plugins are stored in the [Governance Program Library](https://github.com/Mythic-Project/governance-program-library), where you can see example plugins.

{% stepper %}
{% step %}

### The Plugin Program

The plugin program is a Solana program that modifies the voter weight of a member.

It defines the following main account types:

1. The **`Registrar`**

This associates a plugin with a realm, and stores any configuration data that this plugin uses.

2. The Voter Weight Record (VWR)

This is a record that stores the voter weight of a member according to this plugin. It is updated before each vote and passed in as the voter weight to the voting instruction.

The SPL-Governance program checks that the program ID of the VWR matches the expected program ID for the governance, as well as checking that it is up to date.

3. The Maximum Voter Weight Record (Max VWR) (Optional)

This record is used in the case where the plugin does not just modify a single voter's weight, but also the total maximum votes of a realm. An example is an NFT DAO where the total maximum votes depends on the number and type of all NFTs in a collection.

#### **Sample Registrar Account**

{% code fullWidth="false" %}

```rust
pub struct Registrar {
    /// spl-governance program the Realm belongs to
    pub governance_program_id: Pubkey,
 
    /// Realm of the Registrar
    pub realm: Pubkey,
 
    /// Governing token mint the Registrar is for
    /// It can either be the Community or the Council mint of the Realm
    pub governing_token_mint: Pubkey,
 
    /// If the plugin is one in a sequence, this is the previous plugin program ID
    /// If set, then update_voter_weight_record will expect a voter_weight_record owned by this program
    pub previous_voter_weight_plugin_program_id: Option<Pubkey>,
    
    /// ...add your configuration here
 
    /// Reserved for future upgrades
    pub reserved: [u8; 128],
}
```

{% endcode %}

#### **Voter Weight Record**

The structure of a Voter Weight record is fixed by the SPL-Governance program.\
\
See [here](https://github.com/Mythic-Project/solana-program-library/blob/master/governance/addin-api/src/voter_weight.rs) for its structure.

#### **Instructions**

Your program is expected to have instructions to create and update the voter weight record.

These will be called by your JS/TS client.
{% endstep %}

{% step %}

### The JS/TS Client <a href="#part-2---the-jsts-client" id="part-2---the-jsts-client"></a>

The JS/TS client is a JS plugin for the Realms UI, allowing the UI to interact with your plugin program at voting time, and when a user joins a DAO.

The client must implement the [Client interface](https://github.com/Mythic-Project/governance-program-library/blob/master/src/common/Client.ts) in governance-program-library.

The client provides implementations for

* creating and updating voter weights and max voter weights,
* creating and configuring registrars, and
* calculating the current voter weight
  {% endstep %}
  {% endstepper %}

## Integrating with Realms <a href="#integrating-with-realms" id="integrating-with-realms"></a>

Once you have a program and client, you can integrate your plugin with Realms as follows:

1. Import it into [Governance UI](https://github.com/Mythic-Project/governance-ui)
2. Register it in [VoterWeightPlugins/clients/index.ts](https://github.com/Mythic-Project/governance-ui/blob/master/VoterWeightPlugins/clients/index.ts)
3. List it in [VotingStructureSelector/index.tsx](https://github.com/Mythic-Project/governance-ui/blob/master/hub/components/EditRealmConfig/VotingStructureSelector/index.tsx) and [constants/plugins.ts](https://github.com/Mythic-Project/governance-ui/blob/master/constants/plugins.ts) to ensure it appears in the list of plugins when editing a DAO.
4. Define any optional UI components as needed.

The typical place where you will need to add dedicated UI components for your plugin is the "**Voter Weight card**", which shows the user what their voting power is, and how it is calculated.

If your plugin does not need any dedicated UI to show voting power, the "Vanilla" voting power UI will be used.

The vanilla voting power UI will:

* assume the user can "deposit" tokens into the DAO
* show the votes simply using the plugin's calculatedVoteWeight without explanation

This is a reasonable placeholder for some plugins, but to make life easier for users, plugin developers may want to add their own.

To add your own:

* add your plugin name to `pluginsWithDedicatedVotingPowerUI` in [VotingPowerCards.tsx](https://github.com/Mythic-Project/governance-ui/blob/master/components/GovernancePower/Power/VotingPowerCards.tsx)
* register your UI component inside `CardForPlugin` in the same file

## Voter Weight Plugin Chaining <a href="#voter-weight-plugin-chaining" id="voter-weight-plugin-chaining"></a>

Realms supports chaining of voter weight plugins. This means that a voter's weight can be modified by multiple plugins in order.

Plugins are structured like a linked-list, where each plugin registrar has a reference to the previous plugin program ID. The final plugin program ID is registered against the governance on the realm.

When a voter weight is calculated, the Realms UI will call the `update_voter_weight_record` instruction on each plugin in order. The resultant voter weight record account should have the program ID of the final plugin program ID, and this will be checked by the SPL-Governance program.

To support plugin chaining in your plugin:

* Ensure that your plugin registrar has a `previous_voter_weight_plugin_program_id` field
* Ensure that your `update_voter_weight_record` instruction includes an `input_voter_weight_record` account
* Verify that the `input_voter_weight_record` account has the program ID that matches the `previous_voter_weight_plugin_program_id` field

For examples of chainable plugins, see the Civic Pass and Quadratic plugins in the [Governance Program Library](https://github.com/Mythic-Project/governance-program-library).

## Supporting Chaining in the UI <a href="#supporting-chaining-in-the-ui" id="supporting-chaining-in-the-ui"></a>

There is relatively little specific logic required to support plugin chaining when adding your plugin to the UI.

The Realms code will automatically wire up your plugin with others in the chain, as long as your plugin client provides a Registrar account that contains a `previousVoterWeightPluginProgramId` property.

If `previousVoterWeightPluginProgramId` is found, then Realms will pass in an input VWR belonging to that plugin to your plugin's `updateVoterWeightRecord` instruction and `calculateVoterWeight` function.

**Example**

Here is an example of a plugin registrar that supports chaining (using Anchor):

```rust
export interface Registrar {
  governanceProgramId: PublicKey;
  realm: PublicKey;
  governingTokenMint: PublicKey;
  previousVoterWeightPluginProgramId?: PublicKey;
  // ...any other plugin-specific configuration
}
 
class MyPluginClient extends Client<typeof IDL> {
    //...other functions
    getRegistrarAccount(realm: PublicKey, mint: PublicKey) {
        const { registrar } = this.getRegistrarPDA(
            realm,
            mint,
        );
        return this.program.account.registrar.fetchNullable(
            registrar
        )
    }
 
    async calculateVoterWeight(voter: PublicKey, realm: PublicKey, mint: PublicKey, inputVoterWeight: BN): Promise<BN | null> {
        const registrar = await this.getRegistrarAccount(realm, mint);
 
        // This part varies depending on your plugin
        const voteWeight = applyMyPluginFunction(registrar, inputVoterWeight);
        
        return voteWeight;
    }
}
```

## **Input Weights of First Plugin**

The first plugin in the chain will receive the user's raw token balance as the input weight (or the token supply of the governance mint in the case of max voter weight plugins).

This may or may not be relevant to your plugin, so you may choose to ignore it. An example would be the NFT plugin, which uses the user's NFTs to calculate their voting power, and does not use their token balance, and the NFT collection details are defined in the plugin registrar.

If you are ignoring the input voter weight, you may not want to prompt the user to deposit their governance tokens (since doing so has no effect on their voting power). In this case, set the `requiresInputVoterWeight` property to false. Set it explicitly to true to prompt the user to deposit their tokens.

{% hint style="info" %}
**Note:** \
\
This toggle has no effect on the on-chain logic - the plugin will still receive the input voter weight. It is purely a UI convenience.
{% endhint %}

<br>


# V1 Voter Stake Registry Plugin

VSR is a governance plugin implementing the veToken semantics. If a DAO uses the plugin (or any other plugin) then there are additional plugin instructions required to vote on a proposal.

{% hint style="success" %}
This guide has screenshots and text used by the [**PsyOptions DAO**](https://twitter.com/PsyOptions) on their docs explanation about VSR, for any additional help or in-depth questions visit our [**Discord**](https://discord.gg/6UZHcNJFr8)!
{% endhint %}

## What is VSR? <a href="#what-is-vsr" id="what-is-vsr"></a>

By establishing a **Voter Stake Registry** for your **DAO** in [**Realms**](https://realms.today/), you can empower contributors, investors, and advisors to engage in governance while their tokens are in the vesting process.\
\
This not only fosters alignment and active participation in the **DAO**, but also ensures that every action is traceable on the chain!

## Setting up VSR for Your DAO <a href="#setting-up-vsr-for-your-dao" id="setting-up-vsr-for-your-dao"></a>

Deploy your own instance of the **Voter Stake Registry** to the **DAO**. Deploying your own is safest because it cannot be upgrade by some other authority, whether that authority is a person or another DAO.

This step is optional, but is the safest route to go!

{% stepper %}
{% step %}

### Registrar

Create a Registrar by passing in the governance program ID, and the community token mint. Registrars are uniquely constrained (via PDA usage) by those two parameters.\
\
Using the SPL Governance UI today will default to the community owned VSR instance.

Create a Registrar by passing in the governance program ID, and the community token mint. Registrars are uniquely constrained (via PDA usage) by those two parameters.

Using the SPL Governance UI today will default to the community owned VSR instance.

Use **`ConfigureVotingMint`** to add a token to the Registrar and set it’s vote weight. This instruction is where a lot of magic happens and ***needs to be carefully paid attention to!***

{% hint style="info" %}
**Consider this -** Should the vote weight be relative to the community token that is tied to the Registrar?
{% endhint %}

{% hint style="warning" %}
Remaining accounts must be all the token mints that have registered as voting mints, ***including the newly registered one.***
{% endhint %}
{% endstep %}

{% step %}

### ConfigureVotingMint Parameters <a href="#step-2----configurevotingmint-parameters" id="step-2----configurevotingmint-parameters"></a>

* **idx:** index of the rate to be set. There is an array of `VotingMintConfig`s, and the idx references the index that the corresponding config is or should be placed. When adding a new one it should be the next index.
* **digit\_shift:** the amount of digits to shift the native token amount. If set to positive number, the base is shifted to left. E.g. if set to then 100 tokens will give 1000 voting power. If set to -1 then 100 voting power will become 10.
* **baseline\_vote\_weight\_scaled\_factor:** this simply means how much voting power will the user receive for simply depositing the tokens. Let's say, if set at 1. The user will receive 1 vote for every token deposited. If you don't wanna give voting power to users for simply depositing the tokens, you can set it to 0. Vote weight factor for all funds in vault, in 1/1e9 units. So 1e9 means 1!
* **max\_extra\_lockup\_vote\_weight\_scaled\_factor:** this is the max voting power a user will receive for locking the tokens. Let' say, if set to 2, a user will receive 2x the deposited tokens if they lock it for the max duration. Max extra weight for lockups, in 1/1e9 units. So 1e9 means no matter how long a lock up period is the voting weight can never exceed this factor.
* **lockup\_saturation\_secs:** this is the duration for which the user has to keep the tokens locked to receive the voting power. A user can lock tokens for lesser period and will receive proportionate tokens. This is a factor that dampens the lock up vote power boost until this has passed. If this max boost power is 1e9 (factoring in the scale factor it's 1), then this value does not matter.
* **grant\_authority:** The authority that can grant the additional vote weight. This should be a governance authority.

{% hint style="success" %}
**voting\_power** = baseline\_vote\_weight + min(lockup\_time\_remaining / lockup\_saturation\_secs, 1) \* max\_extra\_lockup\_vote\_weight
{% endhint %}
{% endstep %}

{% step %}

### Realm Config <a href="#step-3----realm-config" id="step-3----realm-config"></a>

Enable the voter weight plugin by calling the **`SetRealmConfig`** instruction on the SPL Governance program used or use the Realms UI to setup the change it for you.

**Option 1**:

Use the Realm Config proposal, and put the voter stake registry program ID as the community vote plugin.

**Option 2**:

Go to your DAO page, then `Params` → `Config` → `Change Config` → `What type of governance structure do you want your DAO's community to use?` → `VSR`

After doing these steps press continue and fill out the title and description for your DAO to know about the change.
{% endstep %}
{% endstepper %}

## How to Lock Your Own Tokens <a href="#how-to-lock-your-own-tokens" id="how-to-lock-your-own-tokens"></a>

Brief guide onto how to lock your tokens after **VSR** is enable for the **DAO** in case.

{% stepper %}
{% step %}

### Deposit

Go to view your account on [**Realms**](https://realms.today/).

Deposit your tokens.

Click "**View**" in the right hand corner of the "**Your Account**" section of the page. (See the image under step 1.)

To lock your tokens, click "**Lock Tokens**".
{% endstep %}

{% step %}

### Lockup Type Selection <a href="#step-2---lockup-type-selection" id="step-2---lockup-type-selection"></a>

Select the "**Lockup Type**", the amount of tokens to lock, and the duration of the lockup.

There are three lockup types: "**Cliff**", "**Constant**" and "**Vested**".

* **Cliff** - The cliff lockup sets a date in the future and your lockup tokens and governance power will be decaying when approaching that fixed date and you will get back your tokens that you deposited back then.
* **Constant** - With constant lockup your lockup your tokens basically and hence voting power never decays, if you set it to 2 years now it's going to be still 2 years a year from now, in other words there is no fixed end date of the lockup.
* **Vested** - With vested lockup type you are able to choose between monthly and daily where you will get to claim your tokens daily/monthly while your governance power decays.

You may have heard the term "**Cliff**" before when discussing investor, or team token lockup schedules.
{% endstep %}

{% step %}

### Lock <a href="#step-3---lock" id="step-3---lock"></a>

After setting your lockup schedule, and clicking "**Lock Tokens**" you will now be able to see information regarding your lockups from the Account page.
{% endstep %}
{% endstepper %}

## How to Propose Issuing Locked Tokens <a href="#how-to-propose-issuing-locked-tokens" id="how-to-propose-issuing-locked-tokens"></a>

Brief guide onto how to propose issuing locked tokens after **VSR** is enable for the **DAO** in case.

{% stepper %}
{% step %}

### Create Proposal

Head to your **DAO** page on [**Realms**](https://realms.today/).

Select "**New Proposal**".

Input a Title and Description for your proposal.
{% endstep %}

{% step %}

### Transaction Type <a href="#step-2---transaction-type" id="step-2---transaction-type"></a>

Select the Transaction type. In this case, you will select **Grant.**

Select the "**Lock up kind**".

Fill out the rest of the relevant information such as the **start date**, **end date**, **wallet address** and the **amount**.
{% endstep %}

{% step %}

### Create the Proposal <a href="#step-3---create-the-proposal" id="step-3---create-the-proposal"></a>

If the proposal is **passed**, the recipient must **execute the transaction**!
{% endstep %}
{% endstepper %}

## How to Propose Clawing Back Granted Tokens <a href="#how-to-propose-clawing-back-granted-tokens" id="how-to-propose-clawing-back-granted-tokens"></a>

Brief guide onto how to propose clawing back granted tokens after **VSR** is enable for the **DAO** in case.

{% stepper %}
{% step %}

### Create Proposal

Head to your **DAO** page on [**Realms**](https://realms.today/).

Select "**New Proposal**".

Input a Title and Description for your proposal.
{% endstep %}

{% step %}

### Transaction Type <a href="#step-2---transaction-type-1" id="step-2---transaction-type-1"></a>

Select the Transaction type. In this case, you will select **Clawback.**

* Fill out the clawback information.
  * **Voter:** The Solana wallet address that received the Grant.
  * **Deposit:** A single voter could receive multiple Grants. Selecting this determines which Grant the proposal would clawback.
  * **Clawback Destination:** The Treasury Account the clawed back tokens should go into.
    {% endstep %}

{% step %}

### Create the Proposal <a href="#step-3---create-the-proposal-1" id="step-3---create-the-proposal-1"></a>

{% hint style="warning" %}
If you try to **clawback** tokens that have voted on an active proposal the tokens will be transferred back to the treasury, the vote will stay, but the user will no longer have the voting power.
{% endhint %}
{% endstep %}
{% endstepper %}


# V1 NFT Plugin

Configure NFT Voting Plugin and Enable NFT Voting Plugin

{% hint style="info" %}
This page is a continuation and copy of the original [NFT Community DAO Setup](https://docs.realms.today/setup/daonft)
{% endhint %}

**NFT Community DAO** is a **DAO** where NFTs are used as the governance token. Any DAO can enable NFT voting through the `Plug & Play` mechanism of [**`spl-governance`**](https://github.com/Mythic-Project/solana-program-library/blob/master/governance/README.md).

In order to enable NFT governance for a DAO the [**`NFT voting plugin`**](https://github.com/Mythic-Project/governance-program-library) has to be enabled for the **DAO**.

The NFT voting plugin grants governance power to NFTs based on the [**Metaplex Certified Collection**](https://www.metaplex.com/posts/certified-collections) they belong to.

{% hint style="info" %}
**Metaplex** supports certified collections from **version 1.1** of the standard.\
\
NFTs minted with the older Metadata standard must be upgraded first to the **latest version** before they can be used for governance.
{% endhint %}

In the most basic scenario each NFT gives its owner **1 vote**. The owner can have multiple NFTs and vote with all of them at once.

A **DAO** can also use more advanced scenarios where multiple collections with different voting power are used. This way a multi tier governance structure can be created where different NFTs can represent different membership levels.

Only NFTs with **certified collection** on their metadata can participate in governance.

{% hint style="danger" %}
Beware the **authority** of the collection can certify and uncertify NFTs for the collection.\
\
It means it has the **ultimate power** to decide who can and can't vote in the **DAO**. It's recommended for the **authority** to be transferred to the **DAO**.
{% endhint %}

{% stepper %}
{% step %}

### Create DAO

If you already have your DAO created, you can skip this section. However, please take note of the DAO parameters needed for the setup and adjust your DAO configuration accordingly. To create the NFT Community DAO, use the Bespoke DAO Wizard with the following parameters:

* **`Min community tokens to create proposal`**: Set to 1 to allow each NFT holder to create new governances. If a more restrictive setup is required, the min threshold can be set to a higher value accordingly.
* **`Custom program Id`**: Use the default instance of **`spl-governance`** or an instance with a minimum **version of v2.2.4**.

spl-governance program version must be equal or higher than **v2.2.4** for the NFT plugin to work correctly.

If the plugin is enabled for **older versions** it can result in irreversible deadlock of the **DAO**.

* **`Council`**: Setup a DAO with the council.

It's recommended to always set up the council as a Multisig for the initial DAO members. The members would be able to moderate the DAO governance process at its inception and prevent irreversible actions like setting impossible quorums or defending the DAO from governance attacks. After successful decentralization, the council can be removed through a proposal​.
{% endstep %}

{% step %}

#### Configure NFT Voting Plugin <a href="#step-2---configure-nft-voting-plugin" id="step-2---configure-nft-voting-plugin"></a>

To configure the NFT Plugin, a proposal with the following 3 instructions must be created:

* Create NFT plugin registrar.
* Create NFT plugin max voter weight.
* Configure NFT plugin collection.

The NFT collection configuration instruction must be added for every NFT collection which should be allowed to participate in governance of the **DAO**. Each NFT collection has the following parameters:

* **`Collection size`**: The number of certified NFTs in the collection. The size of the collection is used to calculate the maximum voter weight and voting quorum levels.
* **`Collection weight`**: The relative voting weight of the NFTs from the collection.
* **`Collection`**: The Id of the NFT collection which should be used for governance​.

The **collection ID** can be found on the NFT explorer view. For example for [Dean's List](https://explorer.solana.com/address/B5DeZ7s9FLmSMMftwFNtbSWKACW7EjHDh4caYV3oFKks) NFT the collection id is **`5FusHaKEKjfKsmQwXNrhFcFABGGxu7iYCdbvyVSRe3Ri`**
{% endstep %}

{% step %}

#### Enable NFT Voting Plugin <a href="#step-3---enable-nft-voting-plugin" id="step-3---enable-nft-voting-plugin"></a>

Once the NFT voting plugin configuration proposal is voted on and all instructions executed, the DAO can enable NFT governance through a **`DAO Config Change`** proposal.

From the **DAO** parameters page, select **`Change Config`** option or create a **`Proposal`** directly.

And then set the **DAO** configuration parameters.

Both **`Community voter weight addin`** and **`Community max voter weight addin`** parameters should be set to the NFT Voting Plugin Program Id:

**`GnftV5kLjd67tvHpNGyodwWveEKivz3ZWvvE3Z4xi2iw`**
{% endstep %}

{% step %}

#### Voting with NFTs <a href="#step-4---voting-with-nfts" id="step-4---voting-with-nfts"></a>

Once the proposal to enable the NFT Voting Plugin for the **DAO** is executed, any owner of an NFT from the configured collection can participate in the **DAO** governance.

The NFTs eligible for governance are displayed in the account view.
{% endstep %}
{% endstepper %}


# V1 Quadratic Voting

## What is Quadratic Voting? <a href="#what-is-quadratic-voting" id="what-is-quadratic-voting"></a>

**Quadratic Voting (QV)** is a voting mechanism that ascribes a "cost" to a vote, allowing:

* voters to express the intensity of their preferences across a range of issues
* the tempering of the influence of wealthy voters, by increasing the cost of additional votes

The Quadratic Voting Plugin in Realms implements the latter feature by making the voting power of a member proportional to the square root of the number of tokens they hold.

This has the effect of increasing the voting power of minority voters compared to large token holders, increasing alignment and encouraging voter participation.

## What is Sybil Resistance? <a href="#what-is-sybil-resistance" id="what-is-sybil-resistance"></a>

One challenge to Quadratic Voting is the potential for a single voter to create multiple accounts, split their tokens between them, and vote multiple times.

This is known as a **Sybil Attack**.

To mitigate this in Realms, the [Civic Pass Plugin](https://docs.realms.today/civic) is also used, to ensure that each voter is a unique individual.

This means that Quadratic Voting DAOs in Realms require voters to have a Civic Pass. For more details, see [civic.com](https://civic.com/).

## Creating a QV DAO from Scratch <a href="#creating-a-qv-dao-from-scratch" id="creating-a-qv-dao-from-scratch"></a>

{% stepper %}
{% step %}

### **Select Community DAO**

Choose the **Community Token DAO** option from the **Create DAO** page.
{% endstep %}

{% step %}

### **Select Quadratic**

In the **Community Token** section, select **Advanced Options**, and then select **Quadratic**.

Note: It is possible here to configure the Quadratic Voting plugin. We recommend keeping the default settings. To learn about the configuration options, see below.
{% endstep %}

{% step %}
**Create DAO**

Proceed through the other steps of the DAO and create it.
{% endstep %}
{% endstepper %}

## Adapting an existing DAO to use QV <a href="#adapting-an-existing-dao-to-use-qv" id="adapting-an-existing-dao-to-use-qv"></a>

{% hint style="danger" %}
The **spl-governance** program version must be equal or higher than **v2.2.6** for the **QV** plugin to work correctly.\
\
If the plugin is enabled for **older versions** it can result in **irreversible deadlock** of the **DAO**.
{% endhint %}

{% stepper %}
{% step %}

### Add Civic Pass Plugin

Select the **Params** button and choose **Change config**.

Select **Civic** as the governance structure

Leave the pass type as the default.
{% endstep %}

{% step %}

### Add QV Plugin <a href="#step-2---add-qv-plugin" id="step-2---add-qv-plugin"></a>

Once again, select the **Params** button and choose **Change config**.

This time, select **Quadratic** as the governance structure, and enable the **Chain this plugin with the Civic Plugin?** option.

Leave the coefficients as the default.

Click **Continue**, **Create Proposal** and vote on the resultant proposal.

Once the proposal has passed, execute it.

You have now converted the DAO to use Quadratic Voting!
{% endstep %}
{% endstepper %}

## Advanced Configuration <a href="#advanced-configuration" id="advanced-configuration"></a>

### Coefficients <a href="#coefficients" id="coefficients"></a>

The QV plugin uses the following formula for calculating the voting power of a member:

ax+bx+cax​+bx+c

$$
a\sqrt{x}+bx+c
$$

The coefficients `a`, `b`, and `c` can be configured by the DAO creator, but are set as default to 1,0,0 respectively(\*), which has the effect of making the voting power of a member equal to the square root of the number of tokens they hold.

* The `a` coefficient in fact depends on the number of decimal places of the token, and is formally calculated as  $$\sqrt{10^\textrm{ tokenDecimals}}$$

Setting the coefficients to different values can have the effect of making the voting power of a member more or less sensitive to the number of tokens they hold. For extreme examples:

* Setting `a` and `c` to 0 and `b` to 1 would make the voting power of a member equal to the number of tokens they hold.
* Setting `a` and `b` to 0 and `c` to 1 would make the voting power of a member equal to 1, regardless of the number of tokens they hold, resulting in a one-person one-vote system.

## Civic Pass <a href="#civic-pass" id="civic-pass"></a>

The choice of Civic Pass type can be configured by the DAO creator, and can be set to any of the available Civic Pass types. However, it is worth noting that not all Civic Passes are suitable for sybil resistance. Therefore it is recommended to use the default Civic Pass type to secure your DAO.

## Circulating Token Supply Factor <a href="#circulating-token-supply-factor" id="circulating-token-supply-factor"></a>

When configuring your DAO, you have the option to set the circulating token supply to a percentage of the total token supply.

This allows a DAO to configure its maximum voter weight, which, in a quadratic voting DAO, is based on the token distribution and is typically less than the total token supply.

This is particularly useful if you know the upper limit will not exceed a fixed value.

For example, if 25% of the total supply is held by a single entity, that votes in a block, then you can set the circulating supply factor to 75% + the square root of the number of tokens held by the entity.

## Approval Quorum <a href="#approval-quorum" id="approval-quorum"></a>

The approval quorum is the amount of votes required for a proposal to pass. It is set as a percentage of the circulating voter weight. Combined with the circulating total supply factor, this allows a DAO to configure the amount of votes needed for a proposal to pass, and adapt it over time.

This value should be used when the max voter weight is not known, or varies frequently.


# API

The Realms API provides HTTP endpoints for querying DAO data, proposals, members, and more

## Realms API

> **API Access**: The Realms API is available under a gated access plan. To get an API key and learn about available tiers, please contact the Realms team at the channels listed below.

### Getting Access

API access is managed through plans that determine rate limits and available endpoints. To request access:

1. Visit the Realms platform
2. Contact the team through the official channels (see below)
3. Receive your API key and plan details

### Base URL

```
NEXT_PUBLIC_REALMS_API_URL=<provided upon access>
```

### Available Endpoints

#### DAOs

**List all DAOs**

```
GET /api/v1/daos
```

Returns a paginated list of all Realms (DAOs) registered on the platform.

**Get a specific DAO**

```
GET /api/v1/daos/:realmPk
```

Returns detailed information about a specific DAO including governance configuration, token mints, and metadata.

**Create a DAO**

```
POST /api/v1/daos/create
```

Programmatic DAO creation through the API.

#### User Data

**Get user profile**

```
GET /api/v1/user/:walletPk
```

Returns a user's governance participation data including DAOs they are members of, voting history, and delegation information.

#### Leaderboard

```
GET /api/v1/leaderboard
```

Returns ranked DAO and governance participation data.

### On-Chain Data Access (No API Key Required)

You can always query SPL Governance data directly from the Solana blockchain without an API key using `getProgramAccounts` or an indexer:

#### Direct RPC Queries

```typescript
import { Connection, PublicKey } from '@solana/web3.js';
import { getRealm, getAllGovernances, getAllProposals } from '@realms-today/spl-governance';

const connection = new Connection('https://api.mainnet-beta.solana.com');
const programId = new PublicKey('GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw');

// Fetch a realm
const realm = await getRealm(connection, realmAddress);

// Fetch all governances for a realm
const governances = await getAllGovernances(connection, programId, realmAddress);

// Fetch all proposals for a governance
const proposals = await getAllProposals(connection, programId, governanceAddress);
```

#### Account Types You Can Query

| Account Type        | PDA Seeds                                               | Description                   |
| ------------------- | ------------------------------------------------------- | ----------------------------- |
| Realm               | `['governance', name]`                                  | Top-level DAO entity          |
| Governance          | `['account-governance', realm, governed_account]`       | Voting rules + treasury link  |
| Proposal            | `['governance', governance, token_mint, proposal_seed]` | A specific vote               |
| TokenOwnerRecord    | `['governance', realm, token_mint, token_owner]`        | Voter's deposit record        |
| VoteRecord          | `['governance', proposal, token_owner_record]`          | Individual vote               |
| NativeTreasury      | `['native-treasury', governance]`                       | The DAO wallet (SOL)          |
| ProposalTransaction | `['governance', proposal, option_index, index]`         | Executable instructions       |
| SignatoryRecord     | `['governance', proposal, signatory]`                   | Proposal sign-off             |
| RealmConfig         | `['realm-config', realm]`                               | Realm configuration + plugins |

### Contact

To inquire about API access plans, integrations, or partnerships:

* Discord: [Realms](https://discord.gg/VsPbrK2hJk)
* Documentation: [docs.realms.today](https://docs.realms.today)


# SDK

Explore the Realms SDK

{% hint style="info" %}

### IDL <a href="#idl" id="idl"></a>

* **SPL Governance IDL SDK**: <https://www.npmjs.com/package/governance-idl-sdk>
* **Source Code**: <https://github.com/Mythic-Project/governance-sdk>
  {% endhint %}

{% hint style="info" %}

### Legacy <a href="#legacy" id="legacy"></a>

* **SPL Governance SDK**: <https://www.npmjs.com/package/@solana/spl-governance>
* **Source Code**: <https://github.com/Mythic-Project/oyster/tree/main/packages/governance-sdk>
  {% endhint %}


# SDK DAO Creation

Create a DAO using the SDK

## Create a DAO Using the SDK

This guide walks you through creating a fully functional DAO (Realm) on Solana using the `@realms-today/spl-governance` TypeScript SDK or the Rust program SDK.

### Prerequisites

* A community token mint (SPL Token or Token-2022)
* An optional council token mint
* A funded wallet for paying transaction fees

### TypeScript SDK

Install the SDK:

```bash
npm install @realms-today/spl-governance @solana/web3.js
```

> **Note:** The SDK uses a builder pattern. All instruction-building functions are prefixed with `with` and take a `TransactionInstruction[]` array as their first argument. Instructions are pushed onto this array. Many functions also require a `programVersion` parameter (use `3` for v3.1.2).

#### Step 1: Create a Realm

A Realm is the top-level DAO entity. It ties together a community token, an optional council token, and all governance structures.

```typescript
import {
  withCreateRealm,
  MintMaxVoteWeightSource,
} from '@realms-today/spl-governance';
import {
  Connection,
  Keypair,
  PublicKey,
  sendAndConfirmTransaction,
  Transaction,
  TransactionInstruction,
} from '@solana/web3.js';
import BN from 'bn.js';

const connection = new Connection('https://api.mainnet-beta.solana.com');
const payer = Keypair.fromSecretKey(/* your key */);

const communityMint = new PublicKey('YOUR_COMMUNITY_TOKEN_MINT');
const councilMint = new PublicKey('YOUR_COUNCIL_TOKEN_MINT'); // optional

// You can use the default shared instance or deploy your own
const programId = new PublicKey('GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw');
const programVersion = 3;

const realmName = 'My DAO';

const instructions: TransactionInstruction[] = [];

const realmAddress = await withCreateRealm(
  instructions,
  programId,
  programVersion,
  realmName,
  payer.publicKey,          // realm authority
  communityMint,
  payer.publicKey,          // payer
  councilMint,              // optional council mint (undefined if none)
  MintMaxVoteWeightSource.FULL_SUPPLY_FRACTION,
  new BN(1),                // min community weight to create governance
);

const tx = new Transaction().add(...instructions);
await sendAndConfirmTransaction(connection, tx, [payer]);
```

#### Step 2: Deposit Governing Tokens

Members deposit tokens to gain voting power:

```typescript
import { withDepositGoverningTokens } from '@realms-today/spl-governance';

const depositIxs: TransactionInstruction[] = [];

const tokenOwnerRecordAddress = await withDepositGoverningTokens(
  depositIxs,
  programId,
  programVersion,
  realmAddress,
  tokenSourceAccount,       // your token account
  communityMint,
  voterWalletAddress,       // token owner
  voterWalletAddress,       // source authority
  payer.publicKey,
  new BN(1_000_000),        // amount to deposit
);
```

#### Step 3: Create a Governance

A Governance defines the voting rules for a set of proposals. Each Governance has an associated DAO Wallet (native treasury) that can hold SOL and control assets.

```typescript
import {
  withCreateGovernance,
  GovernanceConfig,
  VoteThreshold,
  VoteThresholdType,
  VoteTipping,
} from '@realms-today/spl-governance';

const config = new GovernanceConfig({
  communityVoteThreshold: new VoteThreshold({
    type: VoteThresholdType.YesVotePercentage,
    value: 60,
  }),
  minCommunityTokensToCreateProposal: new BN(1_000_000),
  minInstructionHoldUpTime: 0,            // seconds before execution
  baseVotingTime: 3 * 24 * 60 * 60,      // 3 days in seconds
  communityVoteTipping: VoteTipping.Strict,
  councilVoteThreshold: new VoteThreshold({
    type: VoteThresholdType.YesVotePercentage,
    value: 60,
  }),
  councilVetoVoteThreshold: new VoteThreshold({
    type: VoteThresholdType.YesVotePercentage,
    value: 50,
  }),
  minCouncilTokensToCreateProposal: new BN(1),
  councilVoteTipping: VoteTipping.Early,
  communityVetoVoteThreshold: new VoteThreshold({
    type: VoteThresholdType.Disabled,
  }),
  votingCoolOffTime: 0,
  depositExemptProposalCount: 10,
});

const govIxs: TransactionInstruction[] = [];

const governanceAddress = await withCreateGovernance(
  govIxs,
  programId,
  programVersion,
  realmAddress,
  undefined,                // governed account (undefined = auto-generated)
  config,
  tokenOwnerRecordAddress,
  payer.publicKey,
  payer.publicKey,          // create authority
);
```

#### Step 4: Create the Native Treasury (DAO Wallet)

```typescript
import { withCreateNativeTreasury } from '@realms-today/spl-governance';

const treasuryIxs: TransactionInstruction[] = [];

const treasuryAddress = await withCreateNativeTreasury(
  treasuryIxs,
  programId,
  programVersion,
  governanceAddress,
  payer.publicKey,
);
```

#### Step 5: Create a Proposal

```typescript
import { withCreateProposal, VoteType } from '@realms-today/spl-governance';

const proposalSeed = Keypair.generate().publicKey;

const proposalIxs: TransactionInstruction[] = [];

const proposalAddress = await withCreateProposal(
  proposalIxs,
  programId,
  programVersion,
  realmAddress,
  governanceAddress,
  tokenOwnerRecordAddress,
  'Fund Developer Grant',     // name
  'https://forum.example.com/proposal-1',  // description link
  communityMint,
  payer.publicKey,            // governance authority
  undefined,                  // proposal index
  VoteType.SINGLE_CHOICE,
  ['Approve'],
  true,                       // use deny option
  payer.publicKey,            // payer
  undefined,                  // voter weight record
  proposalSeed,
);
```

#### Step 6: Cast a Vote

```typescript
import { withCastVote, Vote, YesNoVote } from '@realms-today/spl-governance';

const voteIxs: TransactionInstruction[] = [];

const voteRecordAddress = await withCastVote(
  voteIxs,
  programId,
  programVersion,
  realmAddress,
  governanceAddress,
  proposalAddress,
  proposalOwnerRecordAddress,
  voterTokenOwnerRecordAddress,
  voterWalletAddress,         // governance authority
  communityMint,
  Vote.fromYesNoVote(YesNoVote.Yes),
  payer.publicKey,
);
```

### Rust SDK

The Rust SDK provides the same functions as helper methods in the `instruction.rs` module:

```rust
use spl_governance::instruction::*;

// Create realm
let ix = create_realm(
    &program_id,
    &realm_authority,
    &community_token_mint,
    &payer,
    Some(council_token_mint),
    None, None,
    "My DAO".to_string(),
    1, // min_community_weight_to_create_governance
    MintMaxVoterWeightSource::FullSupplyFraction(10_000_000_000),
    false, false,
);
```

All instruction constructors follow the same pattern: they accept account pubkeys and args, compute the necessary PDAs internally, and return a ready-to-send `Instruction`.

### Program Instances

| Instance        | Program ID                                     | Notes                               |
| --------------- | ---------------------------------------------- | ----------------------------------- |
| Default mainnet | `GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw` | Shared, community governed          |
| Test instance   | `GTesTBiEWE32WHXXE2S4XbZvA5CrEc4xs6ZgRe895dP`  | For testing DAOs                    |
| Custom instance | Deploy your own                                | Full control, DAO-governed upgrades |

### Governance Configuration Reference

| Parameter                            | Description                                                |
| ------------------------------------ | ---------------------------------------------------------- |
| `communityVoteThreshold`             | Percentage of Yes votes needed (e.g., 60%)                 |
| `minCommunityTokensToCreateProposal` | Minimum tokens to create a proposal                        |
| `minInstructionHoldUpTime`           | Delay (seconds) before execution after vote                |
| `baseVotingTime`                     | Duration (seconds) the voting period lasts                 |
| `communityVoteTipping`               | `Strict` / `Early` / `Disabled` - when vote auto-completes |
| `councilVoteThreshold`               | Council vote percentage threshold                          |
| `councilVetoVoteThreshold`           | Council veto threshold                                     |
| `communityVetoVoteThreshold`         | Community veto threshold                                   |
| `votingCoolOffTime`                  | Cool-off period where only Deny/Veto votes are allowed     |
| `depositExemptProposalCount`         | Number of active proposals before deposit is required      |


# Custom Instruction

How to create a custom instruction to be executed via Realms

## Create a Custom Instruction

SPL Governance proposals can execute arbitrary on-chain instructions once a vote succeeds. This is the core mechanism that makes DAOs powerful: any instruction that can be called by a Solana program can be governed by a vote.

### How Proposal Transactions Work

A Proposal can contain multiple **ProposalTransactions**, each with multiple instructions. After a successful vote, anyone can trigger execution once the `hold_up_time` has elapsed. The instructions are signed by the Governance PDA (specifically the DAO Wallet), giving them authority over any assets the DAO controls.

#### Two Transaction Types

SPL Governance v3.1.2 supports two types of proposal transactions:

1. **Legacy Transactions** (`InsertTransaction`) - The original format using `InstructionData`
2. **Versioned Transactions** (`InsertVersionedTransaction`) - New in v3.1.2, supports Address Lookup Tables and larger transactions

### Creating a Legacy Proposal Transaction

#### InstructionData Format

Each instruction in a proposal transaction is encoded as:

```rust
pub struct InstructionData {
    /// Target program ID
    pub program_id: Pubkey,
    /// Account metadata for the instruction
    pub accounts: Vec<AccountMetaData>,
    /// Instruction data bytes
    pub data: Vec<u8>,
}

pub struct AccountMetaData {
    pub pubkey: Pubkey,
    pub is_signer: bool,
    pub is_writable: bool,
}
```

#### Step-by-Step: Adding an Instruction to a Proposal

**1. Create the proposal:**

```rust
let proposal_seed = Pubkey::new_unique();

let create_proposal_ix = create_proposal(
    &governance_program_id,
    &governance,
    &proposal_owner_record,
    &governance_authority,
    &payer,
    None, // voter_weight_record
    &realm,
    "Transfer 100 SOL to Developer".to_string(),
    "https://forum.example.com/proposal-42".to_string(),
    &governing_token_mint,
    VoteType::SingleChoice,
    vec!["Approve".to_string()],
    true, // use_deny_option
    &proposal_seed,
);
```

**2. Insert a transaction with your custom instruction:**

```rust
// Example: Transfer SOL from the DAO treasury
let transfer_ix = system_instruction::transfer(
    &dao_wallet,      // source: the DAO's native treasury
    &recipient,       // destination
    100_000_000_000,  // 100 SOL in lamports
);

let instruction_data = vec![InstructionData {
    program_id: system_program::id(),
    accounts: transfer_ix.accounts.iter().map(|a| AccountMetaData {
        pubkey: a.pubkey,
        is_signer: a.is_signer,
        is_writable: a.is_writable,
    }).collect(),
    data: transfer_ix.data,
}];

let insert_tx_ix = insert_transaction(
    &governance_program_id,
    &governance,
    &proposal,
    &token_owner_record,
    &governance_authority,
    &payer,
    0,              // option_index (first option)
    0,              // transaction_index
    0,              // hold_up_time in seconds (0 = execute immediately after vote)
    instruction_data,
);
```

**3. Sign off the proposal to begin voting:**

```rust
let sign_off_ix = sign_off_proposal(
    &governance_program_id,
    &realm,
    &governance,
    &proposal,
    &governance_authority,
    Some(&proposal_owner_record),
);
```

### Creating Versioned Transactions (v3.1.2)

For larger instructions or when you need Address Lookup Tables, use versioned transactions:

#### Direct Insert (Small Transactions)

```rust
let insert_vtx_ix = insert_versioned_transaction(
    &governance_program_id,
    &governance,
    &proposal,
    &token_owner_record,
    &governance_authority,
    &payer,
    0,  // option_index
    0,  // ephemeral_signers count
    0,  // transaction_index
    transaction_message_bytes, // serialized VersionedMessage
);
```

#### Buffered Insert (Large Transactions)

For transactions that exceed the Solana transaction size limit, use the buffer mechanism:

```rust
// 1. Create a buffer
let create_buffer_ix = create_transaction_buffer(
    &governance_program_id,
    &governance,
    &proposal,
    &token_owner_record,
    &governance_authority,
    &payer,
    0, // buffer_index
    final_buffer_hash, // SHA-256 of the complete message
    final_buffer_size,
    initial_chunk, // first chunk of bytes
);

// 2. Extend the buffer with remaining chunks
let extend_buffer_ix = extend_transaction_buffer(
    &governance_program_id,
    &governance,
    &proposal,
    &payer,
    0, // buffer_index
    next_chunk, // next chunk of bytes
);

// 3. Insert the versioned transaction from the completed buffer
let insert_from_buffer_ix = insert_versioned_transaction_from_buffer(
    &governance_program_id,
    &governance,
    &proposal,
    &token_owner_record,
    &governance_authority,
    &payer,
    0, // option_index
    0, // ephemeral_signers
    0, // transaction_index
    0, // buffer_index
);
```

### Common Custom Instruction Patterns

#### Program Upgrade

The most common governance action - upgrading a program:

```rust
let upgrade_ix = bpf_loader_upgradeable::upgrade(
    &program_id_to_upgrade,
    &buffer_address,
    &dao_wallet,  // upgrade authority = DAO wallet
    &payer,
);
```

#### Token Transfer from Treasury

```rust
let transfer_ix = spl_token::instruction::transfer(
    &spl_token::id(),
    &dao_token_account,
    &recipient_token_account,
    &dao_wallet,  // authority = DAO wallet
    &[],
    amount,
)?;
```

#### Mint Tokens

```rust
let mint_ix = spl_token::instruction::mint_to(
    &spl_token::id(),
    &governed_mint,
    &destination_account,
    &dao_wallet,  // mint authority = DAO wallet
    &[],
    amount,
)?;
```

#### Call Any Program

You can create instructions for any program. The key insight is that the Governance PDA (DAO Wallet) acts as a signer, so it can authorize any action where it holds authority:

```rust
// Generic pattern for calling any program
let custom_ix = Instruction {
    program_id: target_program_id,
    accounts: vec![
        AccountMeta::new(dao_wallet, true),  // DAO wallet as signer
        // ... other accounts as needed
    ],
    data: your_instruction_data,
};
```

### Important Notes

* **DAO Wallet vs Governance PDA**: Always use the DAO Wallet (native treasury) as the authority over assets. It is a PDA with no data, derived from the Governance account, and owned by the System program. It behaves like a regular wallet.
* **hold\_up\_time**: Set this to add a delay between vote completion and execution. This gives the community time to react to controversial proposals.
* **Multiple transactions per option**: A proposal option can have multiple transactions that execute independently.
* **Execution is permissionless**: Once the vote passes and hold-up time elapses, anyone can trigger execution.


# Custom Plugin

How to create a custom plugin and attach it to Realms

## Create a Custom Plugin

SPL Governance uses an open/close plugin architecture that allows you to customize how voting power is determined. Instead of the default "deposit tokens = voting power" model, you can build plugins that implement any custom logic: NFT voting, token locking, staking, quadratic voting, prediction markets, and more.

### How Plugins Work

Plugins (also called "addins") are standalone Solana programs that integrate with SPL Governance through two standardized interfaces:

1. **VoterWeightRecord** - Provides individual voter weight to the governance program
2. **MaxVoterWeightRecord** - Provides the maximum possible voter weight for quorum calculations

When a Realm is configured with a plugin, the governance program reads the `VoterWeightRecord` account instead of using deposited token amounts for voting power. This means your plugin has full control over how voting power is computed.

### The VoterWeightRecord Interface

Your plugin must create and maintain `VoterWeightRecord` accounts that conform to this structure:

```rust
pub struct VoterWeightRecord {
    /// Discriminator: sha256("account:VoterWeightRecord")[..8]
    pub account_discriminator: [u8; 8],

    /// The Realm this record belongs to
    pub realm: Pubkey,

    /// The governing token mint (community or council)
    pub governing_token_mint: Pubkey,

    /// The voter's wallet address
    pub governing_token_owner: Pubkey,

    /// The computed voter weight
    pub voter_weight: u64,

    /// Optional: slot when this weight expires (None = never expires)
    pub voter_weight_expiry: Option<Slot>,

    /// Optional: the specific governance action this weight applies to
    pub weight_action: Option<VoterWeightAction>,

    /// Optional: the target account for the action (e.g., a specific Proposal)
    pub weight_action_target: Option<Pubkey>,

    pub reserved: [u8; 8],
}
```

The `VoterWeightAction` enum defines which governance actions the weight applies to:

```rust
pub enum VoterWeightAction {
    CastVote,          // Voting on a proposal
    CommentProposal,   // Commenting on a proposal
    CreateGovernance,  // Creating a new governance
    CreateProposal,    // Creating a new proposal
    SignOffProposal,   // Signing off a proposal
}
```

### The MaxVoterWeightRecord Interface

If your plugin needs to define the maximum possible voting weight (used for quorum calculations), implement:

```rust
pub struct MaxVoterWeightRecord {
    /// Discriminator: sha256("account:MaxVoterWeightRecord")[..8]
    pub account_discriminator: [u8; 8],

    pub realm: Pubkey,
    pub governing_token_mint: Pubkey,

    /// The maximum voter weight
    pub max_voter_weight: u64,

    /// Optional expiry slot
    pub max_voter_weight_expiry: Option<Slot>,

    pub reserved: [u8; 8],
}
```

### Building Your Plugin: Step by Step

#### 1. Create the On-Chain Program

Your plugin is a standard Solana program (Anchor or native). It must:

* Store voter weight data in `VoterWeightRecord` accounts with the correct discriminator
* Provide an instruction to update/refresh the voter weight (commonly called `UpdateVoterWeightRecord`)
* Optionally provide a `MaxVoterWeightRecord` if your model needs custom quorum logic

**Recommended structure using Anchor:**

```
my-plugin/
  programs/
    my-plugin/
      src/
        lib.rs          # Program entrypoint
        instructions/
          create_registrar.rs
          create_voter_weight_record.rs
          update_voter_weight_record.rs
        state/
          registrar.rs   # Plugin config per realm
          voter.rs       # Per-voter state
```

A **Registrar** account is a common pattern: it stores the plugin configuration for a specific Realm (e.g., which token mints are accepted, locking parameters, etc.).

#### 2. Key Instructions to Implement

**CreateRegistrar** - Initialize plugin config for a realm:

* Seeds: `['registrar', realm, governing_token_mint]`
* Stores: realm reference, governing token mint, custom config

**CreateVoterWeightRecord** - Create a voter's weight record:

* Seeds: `['voter-weight-record', realm, governing_token_mint, governing_token_owner]`
* Initialize with proper discriminator

**UpdateVoterWeightRecord** - Refresh the voter's weight before governance actions:

* Read your custom state (deposits, locks, NFTs, etc.)
* Compute the weight
* Write it to the `VoterWeightRecord` with the current slot as expiry
* This instruction is called in the same transaction as the governance action

#### 3. Register the Plugin with a Realm

Use `SetRealmConfig` to attach your plugin to a Realm:

```rust
set_realm_config(
    program_id,
    realm,
    realm_authority,
    council_token_mint,
    payer,
    Some(GoverningTokenConfigAccountArgs {
        voter_weight_addin: Some(your_plugin_program_id),
        max_voter_weight_addin: None, // or Some(your_program_id)
        token_type: GoverningTokenType::Liquid,
    }),
    None, // council config
    min_community_weight_to_create_governance,
    community_mint_max_voter_weight_source,
)
```

#### 4. Build the UI Client

If you want your plugin to work with the Realms UI, implement the `VotePlugin` TypeScript interface:

```typescript
export interface VotePlugin {
  showDepositModal: boolean;

  initPlugin(
    rpcEndpoint: string,
    programId: string,
    voter: string,
    realm: string,
    mint: string,
    delegates: string[],
    inputWeightProgramId?: string
  ): Promise<VotePlugin>;

  getVoterWeight(tokenOwnerRecord?: string): Promise<VoteWeight>;

  getDepositInstructions(amount: BN): Promise<PluginInstructions>;
  getWithdrawInstructions(amount: BN, tokenOwnerRecord: string): Promise<PluginInstructions>;

  getDepositMessage(): DepositMessage | null;
  getPluginDepositMint(): string | null;
  getDepositedTokenAmount(): BN | null;

  getUpdateVoterWeightInstructions(
    tokenOwnerRecord?: string,
    actionTarget?: string,
    action?: VoterWeightAction,
    governance?: string,
    proposal?: string
  ): Promise<UpdateInstructions>;
}
```

See the Custom UI Integration guide for details on integrating with the Realms UI.

### Existing Plugin Examples

These plugins are live on mainnet and serve as reference implementations:

| Plugin                     | Description                                  | Program ID                                     |
| -------------------------- | -------------------------------------------- | ---------------------------------------------- |
| VSR (Voter Stake Registry) | Token locking with time-weighted multipliers | `vsr2nfGVNHmSY8uxoBGqq8AQbwz3JwaEaHqGbsTPXqQ`  |
| Bio VSR                    | Bio variant of Voter Stake Registry          | `bioU1oVcFscZa2KwxexVREBVBuRtMBUNdFoGPUSsPnf`  |
| Epicentral VSR             | Epicentral Labs staking-based voting         | `epciLwfT8DePi1ch5FKXvLmwHBknXV9EL42yGqrZPEy`  |
| NFT Voter                  | Vote with NFTs from specific collections     | `GnftV5kLjd67tvHpNGyodwWveEKivz3ZWvvE3Z4xi2iw` |
| Token Voter                | Vote based on token holdings                 | `HA99cuBQCCzZu1zuHN2qBxo2FBo1cxNLwKkdt6Prhy8v` |
| Bonk                       | Bonk token voting                            | `BonKNRsdWbRFkjPRNXfMqGNq5GShqdT2RGKZZ7Pn1LR`  |
| Token Haver                | Vote based on token ownership (haver)        | `HavrKkk4L3mpEgPRD4GZ3RBvE3qLiKrK2xPam8ojDhPg` |
| Gateway                    | Civic Pass identity verification gate        | `GgathUhdrCWRHowoRKACjgWhYHfxCEdBi5ViqYN6HVxk` |
| Quadratic                  | Quadratic voting power distribution          | `quadCSapU8nTdLg73KHDnmdxKnJQsh7GUbu5tZfnRRr`  |
| Pyth                       | Pyth staking-based voting                    | `pytS9TjG1qyAZypk7n8rw8gfW9sUaqqYyMhJQ4E7JCQ`  |
| Drift                      | Drift protocol staking voting                | `dVoTE1AJqkZVoE1mPbWcqYPmEEvAUBksHY2NiM2UJQe`  |
| Parcl                      | Parcl governance voting                      | `parCLFza3XxuMnoR8M2LhCXMKP7dSaaUvqjXbKre9UT`  |
| Sowellian                  | Prediction market governance                 | `sowEL1Rtn3p479rg34gW7mVPeCNY58Es5rkLpFsCJAW`  |
| Core Voter                 | Vote with Metaplex Core NFTs                 | `cNFTHBQuERFVrbmks1UzqFQPBHzquRmoLbmgpHBbczF`  |

### Testing Your Plugin

The `governance/addin-mock` directory in the SPL Governance repo contains a mock addin program that can be used as a starting point and for testing:

```rust
pub enum VoterWeightAddinInstruction {
    SetupVoterWeightRecord {
        voter_weight: u64,
        voter_weight_expiry: Option<Slot>,
        weight_action: Option<VoterWeightAction>,
        weight_action_target: Option<Pubkey>,
    },
    SetupMaxVoterWeightRecord {
        max_voter_weight: u64,
        max_voter_weight_expiry: Option<Slot>,
    },
}
```

Use it in integration tests to simulate custom voting weights without deploying a full plugin.

### Plugin Chaining

Plugins can be chained by configuring one plugin to read the `VoterWeightRecord` produced by another as its input. The `VotePlugin` interface supports this via the optional `inputWeightProgramId` parameter in `initPlugin`. For example, a Gateway plugin can wrap a VSR plugin to require identity verification on top of token-locked voting power. In this setup, VSR computes the base voter weight, and Gateway reads that weight and gates it behind a Civic Pass check before producing the final `VoterWeightRecord` consumed by the governance program.


# Custom UI

This guide covers how to build custom governance UIs

## Custom UI Integration

Integrate Realms components into your application, and work with the Realms UI codebase.

### Important: Repository Access

* **SPL Governance** (the on-chain program and Rust/TS SDKs) is **open source** and freely available in this repository.
* **Realms UI** (the frontend application at realms.today) is a **private repository**. To access the UI codebase for integration, embedding, or forking purposes, **contact the Realms team** for repository access.

**Contact for Realms UI access:**

* Discord: [Realms](https://discord.gg/VsPbrK2hJk)

### Building Your Own Governance UI

#### Using the SDK Directly

You can build a complete governance UI using only the `@realms-today/spl-governance` SDK and `@solana/web3.js`:

```bash
npm install @realms-today/spl-governance @solana/web3.js
```

**Display Realm Info**

```typescript
import { getRealm, getAllGovernances } from '@realms-today/spl-governance';

async function RealmDashboard({ realmAddress }) {
  const realm = await getRealm(connection, realmAddress);

  return {
    name: realm.account.name,
    communityMint: realm.account.communityMint.toBase58(),
    authority: realm.account.authority?.toBase58(),
  };
}
```

**List Active Proposals**

```typescript
import { getAllProposals, ProposalState } from '@realms-today/spl-governance';

async function getActiveProposals(governanceAddress) {
  const proposals = await getAllProposals(
    connection, programId, governanceAddress
  );

  return proposals.flat().filter(
    p => p.account.state === ProposalState.Voting
  );
}
```

**Voting Component**

```typescript
import { withCastVote, Vote, YesNoVote } from '@realms-today/spl-governance';
import { TransactionInstruction, Transaction } from '@solana/web3.js';

async function voteOnProposal(proposal, approve: boolean) {
  const vote = approve
    ? Vote.fromYesNoVote(YesNoVote.Yes)
    : Vote.fromYesNoVote(YesNoVote.No);

  const instructions: TransactionInstruction[] = [];

  await withCastVote(
    instructions,
    programId, programVersion,
    realmAddress, governanceAddress,
    proposal.pubkey, proposalOwnerRecord,
    voterTokenOwnerRecord, walletAddress,
    governingTokenMint, vote,
    walletAddress,        // payer
    voterWeightRecord,    // optional
    maxVoterWeightRecord, // optional
  );

  // Send transaction with wallet adapter
  await sendTransaction(new Transaction().add(...instructions));
}
```

#### Plugin UI Integration

If your DAO uses a governance plugin (VSR, NFT Voter, etc.), your UI needs to implement the `VotePlugin` interface to handle deposits, withdrawals, and voter weight updates.

The plugin interface:

```typescript
interface VotePlugin {
  showDepositModal: boolean;

  // Initialize with realm/voter context
  initPlugin(rpcEndpoint, programId, voter, realm, mint, delegates): Promise<VotePlugin>;

  // Get current voting weight
  getVoterWeight(tokenOwnerRecord?): Promise<VoteWeight>;

  // Token deposit/withdraw instructions
  getDepositInstructions(amount): Promise<PluginInstructions>;
  getWithdrawInstructions(amount, tokenOwnerRecord): Promise<PluginInstructions>;

  // UI helpers
  getDepositMessage(): DepositMessage | null;
  getPluginDepositMint(): string | null;
  getDepositedTokenAmount(): BN | null;

  // Voter weight update (called before governance actions)
  getUpdateVoterWeightInstructions(
    tokenOwnerRecord?, actionTarget?, action?,
    governance?, proposal?
  ): Promise<UpdateInstructions>;
}
```

Each governance action (create proposal, cast vote, etc.) needs to include the voter weight update instructions in the same transaction:

```typescript
// Before casting a vote with a plugin
const { instructions: updateIxs, voterWeightRecordKey } =
  await plugin.getUpdateVoterWeightInstructions(
    tokenOwnerRecord,
    proposalAddress,
    VoterWeightAction.CastVote,
  );

await withCastVote(
  instructions,
  /* ... */
  new PublicKey(voterWeightRecordKey),  // pass the VWR
  /* ... */
);

const tx = new Transaction();
updateIxs.forEach(ix => tx.add(ix));
instructions.forEach(ix => tx.add(ix));
```

### Realms UI Architecture (Private Repo)

> Requires repository access - contact the Realms team.

The Realms UI is a Next.js application with the following structure:

```
src/
  actions/       # Transaction builders and signers
  components/    # React components (50+ components)
  constants/     # Network config, program IDs
  context/       # React context providers
  hooks/         # Custom React hooks (50+ hooks)
  lib/           # Core logic
    governance/  # Governance SDK wrappers
    sowellian/   # Sowellian prediction market logic
    token/       # Token utilities
    treasury.ts  # Treasury management
    votes/       # Vote computation
  pages/         # Next.js pages
    api/v1/      # API routes (DAOs, users, leaderboard)
    dao/         # DAO pages
    create-dao/  # DAO creation flow
    sowellian/   # Prediction market pages
  plugins/       # Governance plugin system
    plugins/     # Individual plugin implementations
      vsr/       # Voter Stake Registry
      nft-voter/ # NFT voting
      token-voter/ # Token voting
      gateway/   # Civic Gateway
      pyth/      # Pyth staking
      drift/     # Drift staking
      bonk/      # Bonk voting
      quadratic/ # Quadratic voting
      sowellian/ # Prediction market plugin
      core-voter/ # Metaplex Core NFTs
      bio-vsr/   # Bio VSR variant
      epicentral-vsr/ # Epicentral Labs staking
      parcl/     # Parcl voting
      token-haver/ # Token holder voting
    constants/   # Plugin registry and types
  stores/        # Zustand state stores
  styles/        # Tailwind CSS styles
```

#### Key Technologies

* **Next.js 15** with Pages Router
* **React 19**
* **TanStack React Query** for data fetching
* **Zustand** for state management
* **Tailwind CSS** for styling
* **@realms-today/spl-governance** SDK
* **@coral-xyz/anchor** for Anchor program interactions

#### Adding a New Plugin to the UI

If you've built a custom on-chain plugin and have UI repo access:

1. Create a new directory under `src/plugins/plugins/your-plugin/`
2. Add your Anchor IDL as `idl.json` and types as `idl.ts`
3. Implement the `VotePlugin` interface in `client.ts`
4. Register your plugin's program ID in `src/plugins/constants/index.ts`
5. Add your plugin instance to the plugins array in `src/plugins/index.ts`

```typescript
// src/plugins/constants/index.ts
export const YOUR_PLUGINS = ['YourProgramId11111111111111111111111111'];

// src/plugins/index.ts
import { YourPlugin } from './plugins/your-plugin/client';
export const plugins: VotePlugin[] = [
  // ... existing plugins
  new YourPlugin(defaultConnection),
];
```

### Embedding Governance Widgets

For lightweight integration, you can build standalone governance widgets that embed in any web page:

#### Proposal Status Widget

```typescript
// Minimal widget that shows proposal status
async function ProposalWidget({ proposalAddress }) {
  const proposal = await getProposal(connection, proposalAddress);
  const { account } = proposal;

  const yesVotes = account.options[0]?.voteWeight || new BN(0);
  const noVotes = account.denyVoteWeight || new BN(0);
  const total = yesVotes.add(noVotes);

  return {
    name: account.name,
    state: ProposalState[account.state],
    yesPercent: total.gt(new BN(0))
      ? yesVotes.mul(new BN(100)).div(total).toNumber()
      : 0,
    votingEndsAt: account.votingCompletedAt
      ? new Date(account.votingCompletedAt.toNumber() * 1000)
      : null,
  };
}
```

#### Treasury Balance Widget

```typescript
async function TreasuryWidget({ governanceAddress }) {
  const nativeTreasury = await getNativeTreasuryAddress(programId, governanceAddress);
  const balance = await connection.getBalance(nativeTreasury);

  return {
    address: nativeTreasury.toBase58(),
    solBalance: balance / 1e9,
  };
}
```

### Contact for UI Repo Access

The Realms UI repository is private. For access to the codebase for building custom integrations, embedding components, or deploying your own instance:

* **Discord**: [Realms](https://discord.gg/VsPbrK2hJk)
* Contact the Realms team directly to discuss your integration needs and get repository access.


# Custom DAO

Need something custom? We build bespoke DAO solutions for your protocol

{% embed url="<https://forms.gle/ern6NwHhV8DLvgCT6>" %}


# spl-governance

The SPL Governance is a Solana blockchain program developed as part of the Solana Program Library

## SPL Governance <a href="#spl-governance" id="spl-governance"></a>

The SPL Governance is [**a Solana blockchain program**](https://github.com/Mythic-Project/solana-program-library/tree/master/governance) developed as part of the [**Solana Program Library**](https://spl.solana.com/), meaning the program is developed by guys from Solana Labs. The program's purpose is to provide a blockchain-based tool to manage [**Decentralized Autonomous Organization (DAO)**](https://docs.marinade.finance/marinade-dao).

The SPL Governance is designed in a generic manner to cover a good number of use cases for **DAO** management. The cornerstone of functionality covers creating proposals containing blockchain instructions that **DAO** members may vote upon, and on successful voting, the instructions may be executed.

A simplistic use case could be to use the system to create a multisig control over the distribution of **DAO** funds. A heavier use runs smooth **DAO** management through created instructions that can be voted on by the community and/or council, which consists of minting tokens, transferring funds from the DAO treasury, upgrading the code of programs belonging to the **DAO**, and administering the managed programs.

## Where to find, how to get? <a href="#where-to-find-how-to-get" id="where-to-find-how-to-get"></a>

{% hint style="info" %}
This article refers to **SPL Governance** in version **3.1.0** [**released in December 2022**](https://github.com/Mythic-Project/solana-program-library/releases/tag/governance-v3.1.0).
{% endhint %}

The program of [**SPL Governance**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/README.md) is part of the Solana Program Library at <https://github.com/Mythic-Project/solana-program-library/tree/governance-v3.1.0/governance>.\
\
A shared instance of the program is deployed at **`GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw`**.

While [**it's recommended**](https://discord.com/channels/910194960941338677/945282322318655528/1079728429697597462) for **DAO** in many cases to do [**own deployment**](https://github.com/Mythic-Project/solana-program-library/tree/governance-v3.1.0/governance#1-dao-owned-instance) of the program. That way, you can take the code from the repository and publish it to the network with a unique address. An advantage of such an approach is that the DAO can manage timing and details of the upgrade of the SPL Governance program, a disadvantage could be that the DAO has responsibility to maintain the program.

{% hint style="info" %}
For your own deployment, use **`Anchor`** verifiable build.
{% endhint %}

**SPL Governance** provides a UI to do **DAO** management easily. \
\
That's available at [*https://app.realms.today/realms*](https://app.realms.today/realms) (to work on **devnet**, add [**`?cluster=devnet`**](https://app.realms.today/realms?cluster=devnet) into address bar).

The source code of the UI is available at the repository: [**https://github.com/Mythic-Project/governance-ui**](https://github.com/Mythic-Project/governance-ui)

{% hint style="info" %}
When the own deployment of the program is done, the new address should be configured in the UI, into a list of known instances. That mostly means [**creating a PR**](https://github.com/Mythic-Project/governance-ui/pull/1534) with the configuration.
{% endhint %}

To integrate the **SPL Governance** into your own application, you can use the **Typescript SDK** under the Oyster repository:\
[**https://github.com/Mythic-Project/oyster/tree/main/packages/governance-sdk**](https://github.com/Mythic-Project/oyster/tree/main/packages/governance-sdk).

## Other Resources <a href="#other-resources" id="other-resources"></a>

A good complementary resource to this article could be the official [**README of the governance program**](https://github.com/Mythic-Project/solana-program-library/blob/master/governance/README.md) at GitHub.

Then a nice technical description of the SPL Governance system can be found at sec3 article [**Solana DAO Governance (Part 1): understanding SPL Governance Workflow**](https://medium.com/coinmonks/solana-dao-governance-part-1-understanding-spl-governance-3ccf6d6912bc).\
A nice governance UI tutorial is available at [**PsyFi documentation page**](https://docs.psyoptions.io/psy-token-and-dao/governance-tutorials/governance-overview-and-walkthrough).

## Terms and Glossary <a href="#terms-and-glossary" id="terms-and-glossary"></a>

The terms used within the SPL Governance system are a bit ambiguous in some places, so let's pin some of them to clarify their meaning and not miss you in the rest of the text.

### DAO vs. Realm <a href="#dao-vs-realm" id="dao-vs-realm"></a>

The term **`realm`** is used at multiple places within the texts and documentation of the **SPL Gov system**. At some perspectives, it can be considered the equivalent of **DAO**, in cases, a **DAO** may consist of several **`realms`**. Let's elaborate.

From a technical perspective, the **`Realm`** is the top level wrapper of configuration setup for **DAO**. In this context, the [**`Realm`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/realm.rs) is the top level data structure of the program that all other data structures refer to.

If the **DAO**, as the organization itself, requires specific configuration for their voting, then such a decentralized organization could create multiple **`Realms`**, all belonging to one decentralized organization. But such a configuration is rather exceptional. It's usual that a **DAO** is managed within one **`Realm`**. For that, it's usual to consider the terms **`dao`** and a **`realm`** equivalent in the **SPL Governance** system. It's the reason why the **`governance-ui`** uses both terms interchangeably.

### Governance vs. DAO Wallet <a href="#governance-vs-dao-wallet" id="governance-vs-dao-wallet"></a>

The term governance is ubiquitous. You can find it in the name of the library; the purpose of the program is to **govern** the **DAO**. Thus, eyes looking into the repository will reach the [**governance**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/governance.rs) term naturally and quite promptly. From a code perspective, it's a data structure that defines the content of the Solana account. It's strictly bound to one `realm` (one realm consists of multiple governances). Governance contains a set of configuration parameters for voting over proposals.

On top, the governance determines a strictly unique address of [**DAO wallet**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/native_treasury.rs). It's a Solana account that holds native SOL owned by **`System Program`**, created as a PDA seeded by the governance account address. The **SPL Governance** program names the **DAO** Wallet with the term **`native treasury`**. Any transaction executed on behalf of a particular Realm falls under one particular governance where the DAO wallet address (**`native treasury`**) may be used as a fee payer.

The UI differentiates between governance and the **DAO** wallet, but it's important to know that these terms are tightly coupled and could be considered synonymous.

{% hint style="info" %}
It is highly recommended to utilize the address of [**the DAO wallet**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/NOTES.md#dao-wallet) (i.e., `native`**`treasury`**) as the authority for managing any assets under the **`Realm`**.\
\
This includes matters such as a **mint authority**, a **token owner authority**, or a **contract custom admin authority** with permission to make configuration changes.

While using the governance address for these purposes is possible, it is not considered a best practice.
{% endhint %}

## Proposal <a href="#proposal" id="proposal"></a>

It's a submission represented by a poll where voters place their pro or con attitudes. When the poll successfully passes, the proposal is considered successful, and if the submission contains a transaction, it can be executed to seal the resolution of the voting.

Every proposal belongs under one particular governance. The resolution of voting depends on the number of votes gained, while thresholds of success are defined in the configuration of the governance.

A voter is represented by a wallet containing tokens that identify the voter's voting power.

## SPL Governance Account Structure <a href="#spl-governance-account-structure" id="spl-governance-account-structure"></a>

The Governance account structure is documented [**in the repository**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance#program-accounts). But let's take a look at the account hierarchy in more detail. We will start with a picture of all available accounts, and then have a description of them.

![](https://storage.googleapis.com/papyrus_images/9c1cc9741f329262a42adc42b63efdc0.png)

The top-level account (representing a **DAO**, as explained above) is [**the `Realm` account**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/realm.rs#L124). The address of the realm account is [**calculated as a PDA address**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/realm.rs#L125) identified by its name. There **cannot** be **two realms with the same nam**e, the name cannot be changed while a display name is used for example, in the Governance UI [**can be modified**](https://discord.com/channels/910194960941338677/964818745786789898/1093478043382722580).

The realm is defined by two groups of voting population: **`council`** and **`community`**. Each voting population configures its **`mint`**. The field of **`community_mint`** can be defined only at the time of creation and cannot be changed later.

Members of the population have the ability to create a proposal with or without instructions for execution upon successful voting. The creator of the proposal establishes the voting population. Only members of the voting population can vote on the particular proposal.

For example, when a proposal is created for the council to vote on, only council members are eligible to vote. However, members of the community population may veto the proposal (when permitted in configuration).

The most of the configuration of the **`Realm`** is held in a separate Solana account with the name [**`RealmConfigAccount`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/realm_config.rs#L80). This account is pointed from **`Realm`** at the field **`realm_config`**. This account split is the result of Solana's inability to support account size changes in the past. The **`RealmConfigAccount`** specifies the type of token (liquid, membership, dormant/disabled) used for a specific group of voters or plugin usage for voter weight calculation (e.g., **VSR** plugin).

{% hint style="warning" %}
Despite the **`community_mint`** cannot be changed after the Realm is created it's possible to apply plugin functionality like [**Voter Stake Registry (VSR)**](https://github.com/blockworks-foundation/voter-stake-registry) that open a way to configure the mint later.
{% endhint %}

In addition, the realm encompasses other configuration parameters, including the rule for when a new governance instance can be created. A new governance instance can be created either when the instruction is signed by the Realm's **`authority`** address, or by a council member who owns at least one token, or by a community member who possesses enough voting power as specified in the Realm configuration.

The realm groups a few or multiple [**`Governance`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/governance.rs#L80) accounts. Governance is a basic configuration unit that defines limits for creating proposals, voting time, thresholds, and if voting may be finished before voting time elapses (known as **`vote tipping`**), if vetoing proposals is permitted, and ultimately sign the transactions to be executed using governance and native treasury (**DAO** Wallet) keys.

{% hint style="info" %}
Similar to all other accounts listed here, the governance account is a **PDA account**. It is seeded with the realm address and a **`governance_seed`**. Previously, the **`governance_seed`** was a public key of the governed program, but this concept is now considered obsolete.\
\
The **`governance_seed`** should be treated as an arbitrary public key used solely to seed the governance account address. The **`Governance`** has the ability to manage any asset, whether it be a token, program, or other, and is not limited to a single governed program address.
{% endhint %}

The next part of the account structure hierarchy is the [**`Proposal`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/proposal.rs#L105) The proposal is created within one particular governance. A proposal is bound to a single mint (**`governing_token_mint`**) that defines the population (council or community) that may vote for it. The proposal consists of several options (determined by a string label) that the voting population can choose from.

There is an optionally defined instructions for particular options that are executed when the option passes successfully. After creation, the proposal goes through a lifecycle defined by [**several states**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/enums.rs#L101). The lifecycle state designates permitted operations over the proposal — only at certain states can the proposal be cancelled, voted for, transaction execution run, etc.

Then the **`Proposal`** might or might not be linked with some instructions that will be executed when the proposal passes successfully through voting. The list of instructions is defined in one or multiple [**`ProposalTransaction`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/proposal_transaction.rs) accounts. The account consists of a list of public keys that are expected to be provided at the time of **`Execution`**, the transaction call data, and then [**metadata and configuration**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/proposal_transaction.rs#L86).

## Different types of Governances <a href="#different-types-of-governances" id="different-types-of-governances"></a>

When one checks the **SPL Governance program in version 3.1**, she may notice that different types of governance can be created. Those are the [**mint, program and token**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/governance.rs#L126) governance account types. All of those are [**considered deprecated**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/NOTES.md#asset-specific-governances-are-deprecated) but as of now they are heavily used within Governance UI (because of [**technical limitations**](https://discord.com/channels/910194960941338677/910566058740568094/1098293000028831824)).

## Lifecycle of a Proposal <a href="#lifecycle-of-a-proposal" id="lifecycle-of-a-proposal"></a>

![Image](https://paragraph.xyz/_next/image?url=https%3A%2F%2Fstorage.googleapis.com%2Fpapyrus_images%2Fcacdd490f346f5b2859974b45bb6e8e0.png\&w=1080\&q=75)

As said before, the proposal goes through a lifecycle defined by several states. Let's take a look at them in more detail.

## Draft <a href="#draft" id="draft"></a>

A new proposal is created in **`Draft`** state. The proposal consists of a set of options (each of which is determined by a string label and an index in the array where it's stored). When in **`Draft`** state, the creator of the proposal may require multiple signatories for the proposal. That's done with [**`AddSignatory` instruction**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/mod.rs#L162). The proposal moves to **`Voting`** state only when all signatories sign the "drafted" proposal (we consider the "drafted" proposal one in **`Draft`** or **`SigningOff`** state). That way, one may ensure that the proposal won't leave the "**drafted**" state until all defined signatories confirm that the proposal is prepared to be voted on (i.e., until not ready to take votes).

Calling the **`AddSignatory`** instruction is not required, but for moving the proposal to **`Voting`** state, at least the signatory of the creator is required. When a signatory has been appointed by calling the **`AddSignatory`** instruction, the signature of the creator is not demanded for the proposal to move to the **`Voting`** state.

When a first signatory signs the proposal by calling the **`SignOffProposal`** instruction the proposal moves to the **`SigningOff`** state and no more signatory can be added. When all signatories (or the creator herself) sign the proposal, the proposal moves to the **`Voting`** state. That's done immediately with execution of the last **`SignOffProposal`** instruction.

Until the proposal is in the **`Voting`** state, one can call the **`InsertTransaction`** to bound a set of instructions to an option in the proposal. Options are stored in an array structure in the **`Proposal`** account and each is defined by an index. The index is passed on execution of the **`InsertTransaction`** instruction to determine which option the instructions are bound to. The call may be repeated with the same option to bound multiple instructions to it.

As well, the instructions can be grouped into an array of instructions that are executed atomically. The inserted [**set of instructions**](https://github.com/Mythic-Project/oyster/blob/040b7c89f757846f64c2436dbb58ecc4db8c5837/packages/governance-sdk/src/governance/withInsertTransaction.ts#L14) is stored in [**a transaction account**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/proposal_transaction.rs#L102) and at the time of execution, the [**`ProcessExecuteTransaction`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/process_execute_transaction.rs) takes the transaction account and executes the instructions stored in it. The address of the transaction account is calculated from [**the proposal public key, index of the option and index of the instruction**](https://github.com/Mythic-Project/oyster/blob/040b7c89f757846f64c2436dbb58ecc4db8c5837/packages/governance-sdk/src/governance/accounts.ts#L1241).

{% hint style="info" %}
On creating a proposal, there is a deposit, [**a certain amount of SOLs**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/process_create_proposal.rs#L188) to custody of the Governance system. The amount increases based on the currently active proposals. The deposited amount [**can be refunded**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/process_refund_proposal_deposit.rs) when the voting on the proposal is finished. The reason for that is to prevent spamming the system with proposals that are not going to be voted on. It's the benefit of UI that such maintenance operations are handled automatically.
{% endhint %}

## Voting <a href="#voting" id="voting"></a>

When all signatories were added, all transactions are in place and every signatory has been acknowledged by call of [**`SignOffProposal`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/mod.rs#L168), then the proposal is moved to the **`Voting`** state. In this state, the proposal is ready to take votes. The voting population of the **`council`** or **`community`** may vote on the options of the proposal. They can vote **`Yes`** for the option, or cast **`deny` (`No`)** votes against it or may vote to **`Abstain`**. The voting is done by calling [**`CastVote` instruction**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/mod.rs#L171). Voting time is defined by [**`voting_base_time`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/governance.rs#L43) governance attribute and can be prolonged by setting-up [**`voting_cool_off_time`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/governance.rs#L65). At **`voting_cool_off_time`** period, the user may only cast negative votes (**`deny`** and **`vetoes`**) or relinquish his vote. The voting may be finished before the voting time elapses when [**`vote tipping`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/governance.rs#L45) is enabled.

The voter may change his mind and cast another vote. That has to be done by first calling the [**`RelinquishVote`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/mod.rs#L175) that removes the voting power from the option, and then a new vote can be cast.

When the voting time elapses and the proposal is not tipped to be finished sooner, one needs to call [**`FinalizeVote`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/mod.rs#L173) instruction for the proposal being moved to **`Succeeded`** (a non-final) or **`Defeated`** (a final) state. The **`FinalizeVote`** instruction checks the number (precisely the weight) of **`Yes`** votes and the number of **`deny`** votes at all options of the proposal and considers the [**type of the proposal**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/enums.rs#L144) and then decides the result.

The workflow for **`Veto`** votes is a bit different. The proposal is moved to the final **`Vetoed`** state when the veto threshold is met. This is checked at every **`CastVote`** call, regardless of whether **`vote tipping`** is enabled or not.

During the time the proposal is in the **`Draft`** state or under **`Voting`** state the proposal may be cancelled. When it happens, the proposal is moved to a final **`Cancelled`** state. Only the owner of the proposal is permitted to call the instruction [**`CancelProposal`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/mod.rs#L177). The term owner means a token owner record account (see below) that was inserted into the proposal account on its creation.

The [**proposal option**](https://github.com/Mythic-Project/solana-program-library/blob/master/governance/program/src/state/proposal.rs#L54) successfully passes when the option gains at least the weight of votes equal to [**`community/council_vote_threshold`**](https://github.com/Mythic-Project/solana-program-library/blob/master/governance/program/src/state/governance.rs#L32) configured as a parameter in **`Governance`**, and the weight of positive **`Yes`** votes is higher than the weight of deny **`No`** votes. The same weight of the positive (**`Yes`**) and weight of the deny (**`No`**) votes is a tie, and the result vote for the option is resolved as **`Defeated`**. The proposal passes when at least one option has succeeded.

## Finalization <a href="#finalization" id="finalization"></a>

When the proposal ends in the **`Succeeded`** state, then instructions bound to the successful options may be executed. Besides the proposal's final state, each option marks its final state separately. Only those options that were marked as [**`Succeeded`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/proposal.rs#L41) (i.e., not **`Defeated`**) may execute attached instructions with the call of [**`ExecuteTransactio`**`n`](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/mod.rs#L196).

The governance may be configured with [**`min_transaction_hold_up_time`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/governance.rs#L37), which defines the minimum time that the instruction execution has to wait after the proposal voting ends. Every transaction holds the configuration parameter [**`hold_up_time`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/proposal_transaction.rs#L99) that cannot be lower than the minimum configured at governance (but it can be higher), it is defined by the creator of the proposal and it sets the final time that the proposal has to wait before the instructions can be executed.

When all instructions are executed, the proposal is moved to the final [**`Completed`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/enums.rs#L121) state.

There is one more eventuality of the end state when the instructions from the proposal fail to be executed. That could happen because of wrongly composed instructions (e.g., wrong accounts passed to the instruction), the state of the blockchain changed since the proposal was created and the constraints for the instruction executions cannot be met anymore or more other reasons. In that case, the proposal may be marked as [**`ExecutingWithErrors`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/enums.rs#L121) by calling the **`FlagTransactionError`** instruction (called by the proposal owner).

## Survey Type Proposals <a href="#survey-type-proposals" id="survey-type-proposals"></a>

There is one special "**type**" of proposal that goes through the lifecycle slightly differently than usual proposals. We used the word "type" in quotes because it is not a real type of the proposal but just a proposal with specific attributes. When you create a proposal without any instructions attached to it and the deny voting [**is not permitted**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/process_create_proposal.rs#L40), it is considered a survey-type proposal.

The survey-type proposal has no effect on the state of the blockchain (no instructions) thus it is used to just collect the opinion of the community.

The survey-type proposal does not progress to the **`Succeeded`** state and immediately moves to the **`Completed`** state when the voting ends.

## Voting and Locking Tokens <a href="#voting-and-locking-tokens" id="voting-and-locking-tokens"></a>

We have discussed the data structures and workflow of **SPL Governance** but have not yet touched on the topic of voting. Who can vote on proposals and how is the voting power calculated?

The voter must be the owner of the tokens. A **`realm`** is created with the definitions of **`community`** and **`council`** mints. Ownership of the token gives the right to vote on proposals. Voting power is calculated as the ratio of the locked number of tokens owned by the voter and the maximum voter weight of tokens for the mint. The maximum voter weight could be considered the total supply of tokens for the mint. That's strictly true for **`council`** token. For community tokens, one can configure the **`realm`** attribute [**community\_mint\_max\_voter\_weight\_source**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/realm.rs#L43) where beside the total supply of tokens [**the max voter weight**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/proposal.rs#L519) could be defined as an absolute number or as a fraction of the total supply. The other option to configure this is to use the add-ins (see below).

Beside that, the **`realm`** configures [**a token type consideration**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/realm_config.rs#L21). If the token type is **`membership`** then the token is controlled by the **`realm`**. The token cannot be transferred to another wallet. When the token type is **`liquid`** then the token can be freely transferred and traded, the mint authority is controlled either by **`realm`** or by any other entity. The **`dormant`** token type says the voting population is disabled in the **`realm`**.

For the voter to employ their voting power, they must lock the tokens to the **`realm`**. This is done by a [**deposit call**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/process_deposit_governing_tokens.rs). The tokens are locked until any active proposal on which the voter voted exists. For the owner to withdraw the funds, he has to wait until the voting period ends or when he relinquishes his votes.

The **SPL Governance** creates an account [**`token owner record`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/token_owner_record.rs#L33) for each voter (more precisely, for every wallet). This record keeps track of how many tokens were locked, as well as the number of active proposals that the voter has voted for and the number of unrelinquished proposals to determine whether a withdrawal is possible.

The number of locked tokens under the **`token owner record`** determines the voting power of the owner of the record. The owner may delegate this voting power to another wallet by setting it up [**the delegate field**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/token_owner_record.rs#L80) in the **`token owner record`**. Only one delegate can be defined per token owner record.

## Vote Record <a href="#vote-record" id="vote-record"></a>

[**Casting a vote**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/process_cast_vote.rs#L31) means to add voting weight to the proposal option. The voter can choose to vote for or against the proposal.

{% hint style="info" %}
The voting logic of the abstain vote is not implemented, despite the type is available in the contract, and for this reason is not shown the **UI**.
{% endhint %}

The type of vote is defined by the [**`Vote` enum**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/vote_record.rs#L48) and passed as an argument in the [**cast vote instruction**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/processor/process_cast_vote.rs#LL34C14-L34C14).

When a voter casts their vote, information about this action is written to two places in the Solana blockchain. First, the proposal account is updated with the summary of the [**weight of votes**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/proposal.rs#L60) for each option. This information is used during proposal finalization (the **`vote records`**, see below, are not used for this purpose).

Second, a [**`vote record`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/vote_record.rs) account is created. This record gathers information such as the casted voting weight, type of vote, etc. The existence of the record attests that a vote has been cast from a particular **`token owner record`** for a particular proposal. The **`vote record`** is used to prevent double voting and for historical purposes.

## Plugin System (Add-ins) <a href="#plugin-system-add-ins" id="plugin-system-add-ins"></a>

The **SPL Governance Program** is designed to be extensible. In version **3.1**, there are two available extension points: [**`voter weight` and `max voter weight`**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/addin-api/README.md) add-ins.

The configuration of the realm defines that there is an add-in to be used for any calculation of [**the voting power (voter weight) and max voter weight**](https://github.com/Mythic-Project/solana-program-library/blob/governance-v3.1.0/governance/program/src/state/realm_config.rs#L64). This way, the voting power cannot depend solely on the number of locked tokens at the mint but mostly anything can be used for the calculation.

For the reference one can check the [**Voter Stake Registry**](https://github.com/blockworks-foundation/voter-stake-registry/), a **VSR plugin**, managed by Blockworks Foundation. The **VSR plugin** is used to calculate the voting power based on the amount of SOL tokens locked in the **VSR** contract and permits multiple mints to be used for voting weight calculation.


