# Integrate Realms

## 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,
  }),
);
```


---

# 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/integrate-realms.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.
