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

# Events

> All events emitted by the NullGraph program for indexing and monitoring

The NullGraph program emits 6 events to enable off-chain indexing, UI updates, and monitoring. All events are defined using Anchor's `#[event]` macro.

## Event Structure

Events are emitted using Anchor's `emit!` macro and written to transaction logs. They can be parsed by indexers like Helius, QuickNode, or custom RPC listeners.

**Location**: `lib.rs:532-573`

***

## ProtocolInitialized

Emitted once when the protocol is first initialized.

**Location**: `lib.rs:532-536`

**Emitted by**: `initialize_protocol` (line 30)

### Fields

<ResponseField name="authority" type="Pubkey" required>
  The protocol admin wallet address that initialized the protocol.
</ResponseField>

<ResponseField name="fee_basis_points" type="u16" required>
  The protocol fee rate in basis points (e.g., 250 = 2.5%).
</ResponseField>

### Code Reference

```rust theme={null}
#[event]
pub struct ProtocolInitialized {
    pub authority: Pubkey,
    pub fee_basis_points: u16,
}
```

### Example Usage

Indexers can track protocol deployment and fee configuration:

```typescript theme={null}
program.addEventListener('ProtocolInitialized', (event) => {
  console.log('Protocol initialized by:', event.authority.toString());
  console.log('Fee rate:', event.feeBasisPoints / 100, '%');
});
```

***

## NullResultSubmitted

Emitted when a new Null Knowledge Asset (NKA) is submitted.

**Location**: `lib.rs:538-542`

**Emitted by**: `submit_null_result` (line 65)

### Fields

<ResponseField name="specimen_number" type="u64" required>
  The sequential ID assigned to this NKA (e.g., 1, 2, 3...). Displayed as `NKA-{specimen_number:04}` in the UI.
</ResponseField>

<ResponseField name="researcher" type="Pubkey" required>
  The wallet address of the researcher who submitted the NKA.
</ResponseField>

### Code Reference

```rust theme={null}
#[event]
pub struct NullResultSubmitted {
    pub specimen_number: u64,
    pub researcher: Pubkey,
}
```

### Example Usage

Track new NKA submissions in real-time:

```typescript theme={null}
program.addEventListener('NullResultSubmitted', (event) => {
  console.log(`NKA-${event.specimenNumber.toString().padStart(4, '0')} submitted`);
  console.log('Researcher:', event.researcher.toString());
});
```

***

## BountyCreated

Emitted when a new bounty is created and USDC is escrowed.

**Location**: `lib.rs:544-550`

**Emitted by**: `create_bounty` (line 114)

### Fields

<ResponseField name="bounty_number" type="u64" required>
  The sequential ID assigned to this bounty (e.g., 1, 2, 3...). Displayed as `NB-{bounty_number:04}` in the UI.
</ResponseField>

<ResponseField name="creator" type="Pubkey" required>
  The wallet address of the bounty creator.
</ResponseField>

<ResponseField name="reward_amount" type="u64" required>
  The USDC reward amount in base units (6 decimals). Divide by 1,000,000 to get human-readable USDC.

  **Example**: `2500000` = 2.5 USDC
</ResponseField>

<ResponseField name="deadline" type="i64" required>
  Unix timestamp deadline for submissions.
</ResponseField>

### Code Reference

```rust theme={null}
#[event]
pub struct BountyCreated {
    pub bounty_number: u64,
    pub creator: Pubkey,
    pub reward_amount: u64,
    pub deadline: i64,
}
```

### Example Usage

Monitor new bounties and their rewards:

```typescript theme={null}
program.addEventListener('BountyCreated', (event) => {
  const usdcAmount = event.rewardAmount.toNumber() / 1_000_000;
  console.log(`Bounty NB-${event.bountyNumber.toString().padStart(4, '0')} created`);
  console.log(`Reward: ${usdcAmount} USDC`);
  console.log(`Deadline: ${new Date(event.deadline.toNumber() * 1000).toISOString()}`);
});
```

***

## BountySubmissionCreated

Emitted when a researcher submits their NKA to a bounty.

**Location**: `lib.rs:552-557`

**Emitted by**: `submit_to_bounty` (line 147)

### Fields

<ResponseField name="bounty_number" type="u64" required>
  The sequential ID of the bounty receiving the submission.
</ResponseField>

<ResponseField name="specimen_number" type="u64" required>
  The sequential ID of the NKA being submitted.
</ResponseField>

<ResponseField name="researcher" type="Pubkey" required>
  The wallet address of the researcher submitting the NKA.
</ResponseField>

### Code Reference

```rust theme={null}
#[event]
pub struct BountySubmissionCreated {
    pub bounty_number: u64,
    pub specimen_number: u64,
    pub researcher: Pubkey,
}
```

### Example Usage

Track bounty-NKA matching:

```typescript theme={null}
program.addEventListener('BountySubmissionCreated', (event) => {
  console.log(`NKA-${event.specimenNumber.toString().padStart(4, '0')} submitted to Bounty NB-${event.bountyNumber.toString().padStart(4, '0')}`);
  console.log('Researcher:', event.researcher.toString());
});
```

***

## BountyFulfilled

Emitted when a bounty creator approves a submission and payouts are executed.

**Location**: `lib.rs:559-566`

**Emitted by**: `approve_bounty_submission` (line 221)

### Fields

<ResponseField name="bounty_number" type="u64" required>
  The sequential ID of the bounty being fulfilled.
</ResponseField>

<ResponseField name="specimen_number" type="u64" required>
  The sequential ID of the NKA that won the bounty.
</ResponseField>

<ResponseField name="researcher" type="Pubkey" required>
  The wallet address of the researcher receiving the payout.
</ResponseField>

<ResponseField name="payout" type="u64" required>
  The USDC amount paid to the researcher in base units (6 decimals). Equals `reward_amount - fee`.

  **Example**: `97500000` = 97.5 USDC
</ResponseField>

<ResponseField name="fee" type="u64" required>
  The USDC protocol fee paid to the treasury in base units (6 decimals).

  **Example**: `2500000` = 2.5 USDC (2.5% of 100 USDC)
</ResponseField>

### Code Reference

```rust theme={null}
#[event]
pub struct BountyFulfilled {
    pub bounty_number: u64,
    pub specimen_number: u64,
    pub researcher: Pubkey,
    pub payout: u64,
    pub fee: u64,
}
```

### Example Usage

Monitor payouts and fee collection:

```typescript theme={null}
program.addEventListener('BountyFulfilled', (event) => {
  const researcherPayout = event.payout.toNumber() / 1_000_000;
  const treasuryFee = event.fee.toNumber() / 1_000_000;
  const total = researcherPayout + treasuryFee;
  
  console.log(`Bounty NB-${event.bountyNumber.toString().padStart(4, '0')} fulfilled`);
  console.log(`NKA-${event.specimenNumber.toString().padStart(4, '0')} won`);
  console.log(`Researcher payout: ${researcherPayout} USDC`);
  console.log(`Protocol fee: ${treasuryFee} USDC (${(treasuryFee/total*100).toFixed(2)}%)`);
});
```

***

## BountyClosed

Emitted when a bounty creator closes a bounty and reclaims escrowed USDC.

**Location**: `lib.rs:568-573`

**Emitted by**: `close_bounty` (line 267)

### Fields

<ResponseField name="bounty_number" type="u64" required>
  The sequential ID of the bounty being closed.
</ResponseField>

<ResponseField name="creator" type="Pubkey" required>
  The wallet address of the bounty creator receiving the refund.
</ResponseField>

<ResponseField name="refunded_amount" type="u64" required>
  The USDC amount refunded to the creator in base units (6 decimals). Equals the vault's balance at closure time.

  **Example**: `100000000` = 100 USDC
</ResponseField>

### Code Reference

```rust theme={null}
#[event]
pub struct BountyClosed {
    pub bounty_number: u64,
    pub creator: Pubkey,
    pub refunded_amount: u64,
}
```

### Example Usage

Track bounty closures and refunds:

```typescript theme={null}
program.addEventListener('BountyClosed', (event) => {
  const refund = event.refundedAmount.toNumber() / 1_000_000;
  console.log(`Bounty NB-${event.bountyNumber.toString().padStart(4, '0')} closed`);
  console.log(`Refunded ${refund} USDC to creator`);
});
```

***

## Event Summary Table

| Event                     | Trigger                 | Key Data                              | Use Case                                       |
| ------------------------- | ----------------------- | ------------------------------------- | ---------------------------------------------- |
| `ProtocolInitialized`     | Protocol setup          | Authority, fee rate                   | Track deployment, monitor fee changes          |
| `NullResultSubmitted`     | New NKA                 | Specimen number, researcher           | NKA registry indexing, researcher analytics    |
| `BountyCreated`           | New bounty              | Bounty number, reward, deadline       | Bounty marketplace indexing, expiry monitoring |
| `BountySubmissionCreated` | NKA submitted to bounty | Bounty & specimen numbers, researcher | Match tracking, notification systems           |
| `BountyFulfilled`         | Approval & payout       | Payout breakdown, winner              | Payment verification, fee analytics            |
| `BountyClosed`            | Bounty refund           | Refund amount                         | Lifecycle tracking, treasury accounting        |

## Indexing Events

All events can be indexed using Anchor's event listener:

```typescript theme={null}
import { Program, AnchorProvider } from '@coral-xyz/anchor';
import { Connection } from '@solana/web3.js';
import idl from './nullgraph.json';

const connection = new Connection('https://api.devnet.solana.com');
const provider = new AnchorProvider(connection, wallet, {});
const program = new Program(idl, provider);

// Listen to all events
const listener = program.addEventListener('NullResultSubmitted', (event, slot) => {
  console.log(`[Slot ${slot}] New NKA:`, event);
});

// Remove listener when done
program.removeEventListener(listener);
```

For production indexing, consider using:

* **Helius** or **QuickNode** webhooks for real-time event streams
* **The Graph** protocol for decentralized indexing
* Custom RPC polling with `getProgramAccounts` + transaction parsing
