> For the complete documentation index, see [llms.txt](https://docs.realms.today/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.realms.today/developer-resources/sdk/sdk-dao-creation.md).

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