# SDK DAO Creation

## 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      |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.realms.today/developer-resources/sdk/sdk-dao-creation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
