> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Ge0frey/nullgraph/llms.txt
> Use this file to discover all available pages before exploring further.

# Deployment

> Deploy the NullGraph program to Solana devnet and initialize the protocol

## Overview

Deploying NullGraph to devnet involves three key steps:

1. **Build and deploy the Anchor program** to Solana devnet
2. **Initialize the protocol** by creating the ProtocolState singleton
3. **Update the frontend IDL** to match the deployed program

<Note>
  The deployed program ID on devnet is: `2u3DXQq9A6UgMryeVSWCNdYLy3Fjh391R5hcfWYkCgZK`
</Note>

## Prerequisites

Before deploying, ensure you have:

* Completed the [local setup](/development/local-setup)
* Built the program with `anchor build`
* At least **2 SOL** in your devnet wallet for deployment
* Configured Solana CLI to devnet: `solana config set --url devnet`

## Deployment Steps

<Steps>
  <Step title="Build the program">
    Compile the Anchor program and generate the IDL:

    ```bash theme={null}
    anchor build
    ```

    This creates:

    * Compiled program binary: `target/deploy/nullgraph.so`
    * IDL file: `target/idl/nullgraph.json`
    * TypeScript types: `target/types/nullgraph.ts`
  </Step>

  <Step title="Fund your wallet">
    Ensure your wallet has sufficient devnet SOL:

    ```bash theme={null}
    # Check balance
    solana balance

    # Request airdrop if needed
    solana airdrop 2
    ```

    <Warning>
      Program deployment requires \~2 SOL. Make sure you have enough before proceeding.
    </Warning>
  </Step>

  <Step title="Deploy to devnet">
    Deploy the program to the Solana devnet cluster:

    ```bash theme={null}
    anchor deploy --provider.cluster devnet
    ```

    This command:

    * Uploads the compiled program to devnet
    * Uses the program ID from `Anchor.toml`: `2u3DXQq9A6UgMryeVSWCNdYLy3Fjh391R5hcfWYkCgZK`
    * Deducts deployment costs from your wallet

    Expected output:

    ```
    Deploying workspace: https://explorer.solana.com/address/2u3DXQq9A6UgMryeVSWCNdYLy3Fjh391R5hcfWYkCgZK?cluster=devnet
    Upgrade authority: <your-wallet-pubkey>
    Deploying program "nullgraph"...
    Program path: /path/to/nullgraph/target/deploy/nullgraph.so...
    Program Id: 2u3DXQq9A6UgMryeVSWCNdYLy3Fjh391R5hcfWYkCgZK
    Deploy success
    ```
  </Step>

  <Step title="Initialize the protocol">
    Run the one-time initialization script to create the ProtocolState singleton:

    ```bash theme={null}
    npx ts-node scripts/init-protocol.ts
    ```

    This script:

    * Derives the ProtocolState PDA: `["protocol_state"]`
    * Calls `initialize_protocol` with fee rate of **250 basis points (2.5%)**
    * Sets the treasury address
    * Initializes counters (`nka_counter`, `bounty_counter`) to zero

    <Note>
      This script only needs to run **once** per deployment. If the PDA already exists, it will fail with "already in use".
    </Note>
  </Step>

  <Step title="Verify deployment">
    Verify the program deployed successfully:

    ```bash theme={null}
    solana program show 2u3DXQq9A6UgMryeVSWCNdYLy3Fjh391R5hcfWYkCgZK --url devnet
    ```

    You can also view the program on Solana Explorer:

    [https://explorer.solana.com/address/2u3DXQq9A6UgMryeVSWCNdYLy3Fjh391R5hcfWYkCgZK?cluster=devnet](https://explorer.solana.com/address/2u3DXQq9A6UgMryeVSWCNdYLy3Fjh391R5hcfWYkCgZK?cluster=devnet)
  </Step>
</Steps>

## Anchor Configuration

The deployment configuration is defined in `Anchor.toml`:

```toml theme={null}
[toolchain]
package_manager = "npm"

[features]
resolution = true
skip-lint = false

[programs.devnet]
nullgraph = "2u3DXQq9A6UgMryeVSWCNdYLy3Fjh391R5hcfWYkCgZK"

[registry]
url = "https://api.apr.dev"

[provider]
cluster = "devnet"
wallet = "~/.config/solana/nullgraph.json"

[scripts]
test = "npm test"
```

| Field                       | Description                                    |
| --------------------------- | ---------------------------------------------- |
| `programs.devnet.nullgraph` | Program ID for devnet deployment               |
| `provider.cluster`          | Target cluster (devnet, testnet, mainnet-beta) |
| `provider.wallet`           | Path to keypair file for deployment authority  |

## Protocol Initialization Details

The `initialize_protocol` instruction creates the global ProtocolState account:

<CodeGroup>
  ```typescript Initialization Script theme={null}
  // scripts/init-protocol.ts
  import * as anchor from "@coral-xyz/anchor";
  import { Program } from "@coral-xyz/anchor";
  import { Nullgraph } from "../target/types/nullgraph";
  import { PublicKey, SystemProgram } from "@solana/web3.js";

  const provider = anchor.AnchorProvider.env();
  anchor.setProvider(provider);
  const program = anchor.workspace.nullgraph as Program<Nullgraph>;

  const [protocolStatePDA] = PublicKey.findProgramAddressSync(
    [Buffer.from("protocol_state")],
    program.programId
  );

  const treasuryKeypair = anchor.web3.Keypair.generate();

  await program.methods
    .initializeProtocol(250) // 2.5% fee
    .accounts({
      authority: provider.wallet.publicKey,
      protocolState: protocolStatePDA,
      treasury: treasuryKeypair.publicKey,
      systemProgram: SystemProgram.programId,
    })
    .rpc();

  console.log("Protocol initialized:", protocolStatePDA.toString());
  ```

  ```rust On-Chain Instruction theme={null}
  #[program]
  pub mod nullgraph {
      pub fn initialize_protocol(
          ctx: Context<InitializeProtocol>,
          fee_basis_points: u16,
      ) -> Result<()> {
          let protocol_state = &mut ctx.accounts.protocol_state;
          protocol_state.authority = ctx.accounts.authority.key();
          protocol_state.nka_counter = 0;
          protocol_state.bounty_counter = 0;
          protocol_state.fee_basis_points = fee_basis_points;
          protocol_state.treasury = ctx.accounts.treasury.key();
          protocol_state.bump = ctx.bumps.protocol_state;
          
          emit!(ProtocolInitialized {
              authority: protocol_state.authority,
              fee_basis_points,
          });
          
          Ok(())
      }
  }
  ```
</CodeGroup>

**ProtocolState Fields:**

| Field              | Type     | Initial Value   | Description                      |
| ------------------ | -------- | --------------- | -------------------------------- |
| `authority`        | `Pubkey` | Deployer wallet | Protocol admin                   |
| `nka_counter`      | `u64`    | `0`             | Auto-incrementing NKA counter    |
| `bounty_counter`   | `u64`    | `0`             | Auto-incrementing bounty counter |
| `fee_basis_points` | `u16`    | `250`           | Fee on settlement (2.5%)         |
| `treasury`         | `Pubkey` | Treasury wallet | Fee collection address           |
| `bump`             | `u8`     | PDA bump        | PDA derivation seed              |

## Updating the Frontend IDL

After deploying or updating the program, synchronize the frontend IDL:

```bash theme={null}
anchor build
cp target/idl/nullgraph.json app/src/lib/nullgraph.json
cp target/types/nullgraph.ts app/src/lib/nullgraph_types.ts
```

This ensures the frontend's Anchor client uses the correct program interface.

<Warning>
  If you modify the program and redeploy, you **must** update the IDL files in the frontend. Mismatched IDLs will cause transaction failures.
</Warning>

## Program Upgrades

To upgrade an existing deployment with new program code:

<Steps>
  <Step title="Make your code changes">
    Edit `programs/nullgraph/src/lib.rs` with your updates.
  </Step>

  <Step title="Rebuild the program">
    ```bash theme={null}
    anchor build
    ```
  </Step>

  <Step title="Deploy the upgrade">
    ```bash theme={null}
    anchor upgrade target/deploy/nullgraph.so \
      --program-id 2u3DXQq9A6UgMryeVSWCNdYLy3Fjh391R5hcfWYkCgZK \
      --provider.cluster devnet
    ```
  </Step>

  <Step title="Update the frontend IDL">
    ```bash theme={null}
    cp target/idl/nullgraph.json app/src/lib/nullgraph.json
    cp target/types/nullgraph.ts app/src/lib/nullgraph_types.ts
    ```
  </Step>
</Steps>

<Note>
  Only the **upgrade authority** (the wallet that deployed the program) can upgrade it. Check the upgrade authority with:

  ```bash theme={null}
  solana program show 2u3DXQq9A6UgMryeVSWCNdYLy3Fjh391R5hcfWYkCgZK --url devnet
  ```
</Note>

## Deployment Checklist

* [ ] Built program: `anchor build`
* [ ] Funded wallet with 2+ SOL: `solana balance`
* [ ] Deployed program: `anchor deploy --provider.cluster devnet`
* [ ] Initialized protocol: `npx ts-node scripts/init-protocol.ts`
* [ ] Verified deployment: `solana program show <program-id>`
* [ ] Updated frontend IDL: `cp target/idl/nullgraph.json app/src/lib/`
* [ ] Tested frontend connection: `cd app && npm run dev`

## Deployment Costs

| Action                  | Approximate Cost | Description                                      |
| ----------------------- | ---------------- | ------------------------------------------------ |
| Program deployment      | \~2 SOL          | One-time program account rent + transaction fees |
| Protocol initialization | \~0.001 SOL      | ProtocolState PDA creation                       |
| NKA submission          | \~0.001 SOL      | NullResult PDA creation                          |
| Bounty creation         | \~0.002 SOL      | NullBounty + vault PDA creation                  |

<Note>
  Costs are for devnet and may vary. Mainnet costs will be similar but use real SOL.
</Note>

## Verifying On-Chain State

After initialization, verify the ProtocolState account:

```bash theme={null}
# Using Anchor CLI
anchor account protocol-state <protocol-state-pda> --provider.cluster devnet
```

Or query directly via the frontend hooks:

```typescript theme={null}
import { useProtocolState } from './hooks/useProtocolState';

const { data: protocolState, loading } = useProtocolState();
console.log('NKA Counter:', protocolState?.nkaCounter.toString());
console.log('Fee Rate:', protocolState?.feeBasisPoints, 'bps');
```

## Troubleshooting

### "Insufficient funds" error

**Solution:** Request more devnet SOL:

```bash theme={null}
solana airdrop 2
```

### "Program already deployed" error

**Solution:** Use `anchor upgrade` instead of `anchor deploy`:

```bash theme={null}
anchor upgrade target/deploy/nullgraph.so --program-id <program-id> --provider.cluster devnet
```

### "PDA already in use" during initialization

**Solution:** The protocol is already initialized. Skip the initialization step.

### "Transaction simulation failed" on frontend

**Solution:** Ensure the frontend IDL matches the deployed program:

```bash theme={null}
cp target/idl/nullgraph.json app/src/lib/nullgraph.json
cp target/types/nullgraph.ts app/src/lib/nullgraph_types.ts
```

## Next Steps

* Run the [test suite](/development/testing) against devnet
* Explore [program architecture](/protocol/architecture)
* Learn about [accounts and instructions](/protocol/instructions)
* Connect the [frontend](/getting-started/quickstart) to your deployment
