> For the complete documentation index, see [llms.txt](https://hinkal-team.gitbook.io/hinkal/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hinkal-team.gitbook.io/hinkal/protocol/solana-program/events-and-errors.md).

# Events & Errors

#### Events

Defined in `hinkal_events.rs`.

Indexers should subscribe to these to reconstruct shielded state.

**`NewCommitment`**

```rust
pub struct NewCommitment {
    pub commitment: Bytes32,
    pub index: Bytes32,
    pub encrypted_output: Vec<u8>,
    pub on_chain_data: [Bytes32; 8],
}
```

* Emitted on every commitment inserted into the Merkle tree.
* For proof-derived commitments: `encrypted_output` is the ciphertext; `on_chain_data` is all zeros.
* For on-chain-created commitments (proofless deposits, swap outputs): `encrypted_output` is empty; `on_chain_data = [amount, mint_part1, mint_part2, extra_randomization, stealth_address, h0, h1, timestamp]`.
* Swap variants (`swap2`, `swap6`) emit via `emit_cpi!` (event-CPI, requires `#[event_cpi]` accounts) — indexers must subscribe to inner instructions, not just program logs.

**`Nullified`**

```rust
pub struct Nullified { pub nullifier: Bytes32 }
```

Emitted whenever a non-zero nullifier transitions to `is_used = true`.

**`NewAccessKeyAdded`**

```rust
pub struct NewAccessKeyAdded {
    pub access_key: Bytes32,
    pub index: Bytes32,
    pub sender_address: Bytes32,
}
```

Emitted by `add_access_token` after the key lands in the access-token Merkle tree.

**`BlockedUtxosCreated`**

```rust
pub struct BlockedUtxosCreated {
    pub sender: Pubkey,
    pub mint: Pubkey,           // system_program::ID for SOL
    pub amounts: Vec<u64>,
}
```

Emitted by `proofless_deposit` when the caller passes `create_blocked_utxos = true`. Allows downstream services to surface "blocked" deposits (e.g. cooldown windows).

**Lifecycle events**

* `RelayerStatusUpdated { relayer, status }`
* `TokenLimitUpdated { mint: Option<Pubkey>, amount_limit }`
* `AccessTokenOwnerChanged { old_owner, new_owner }`
* `OwnershipTransferred { previous_owner, new_pending_owner }`
* `OwnershipAccepted { previous_owner, new_owner }`

#### Errors

Defined in `error.rs` (`HinkalError`). Selected categories:

**Configuration / supply issues**

* `InvalidMintConfiguration`, `MissingMintFrom`, `MissingMintTo`, `IdenticalTokenMints`
* `MissingStorageSourceAta`, `MissingStorageDestinationAta`, `MissingSwapperSourceAta`, `MissingSwapperDestinationAta`
* `ATAValidationFailed`

**Amount / dimension invariants**

* `ReceivedAmountLowerThanExpected`
* `ExpectedNegativeInputAmount`, `ExpectedPositiveOutputAmount`
* `UnexpectedDimensions`, `UnsupportedDimensions`, `UnsupportedDimensionsError`
* `InvalidPublicSignalsSize`
* `InvalidAmountChange`
* `OnChainCreationLengthMismatch`, `EncryptedOutputsLengthMismatch`
* `BalanceDiffMismatch`

**Proof / cryptography**

* `ProofVerificationFailed`
* `CalldataHashMismatch`
* `RootHashDoesNotExist`
* `ValueLargerThanCircomP`
* `PoseidonHashFailed`
* `ZeroRandomizationForbidden`
* `ExpectedMintAddressZero`, `ExpectedMintAddressNotZero`

**Nullifier integrity**

* `NullifierUsed`
* `NullifierNotZeroButAccountNotSpecified`
* `NullifierAccountsListLengthMustBeEven`
* `NullifierAlreadyUsed` (returned by `close_nullifier`)
* `InNullifiersLengthMismatch`, `InNullifierMismatch`
* `InvalidNullifierPDA`

**Authorization**

* `Unauthorized`
* `RelayerNotWhitelisted`
* `ExpectedAccessTokenOwner`, `AccessTokenRequired`, `AccessTokenAlreadyAdded`
* `AccessTokenOwnerDepositForbidden`
* `DepositForbidden`

**External call safety**

* `RemainingAccountSignerForbidden`
* `SelfCPIForbidden`

**Swap-specific**

* `SwapperAccountAdditionalSeedMismatch`
* `FeeCalculationOverflow`

**Generic**

* `UnsafeArithmetic`
* `UnexpectedValue`
* `UnexpectedOnchainCreation`
* `InvalidVersion`

`merkle.rs` defines a separate `MerkleError` enum:

* `TreeIsFull`
* `IncompleteHash`
