# Index Program
The **Index Program** creates lookup tables for indexing Solana account addresses on-chain. Developers can use these tables to lookup and verify account data relevant to their programs' instructions and state.
## Get Started
```yaml
# Cargo.toml
[dependencies]
index-program = { version = "0.1.0" }
```
## Instructions
#### [`create_index`](https://github.com/faktorfi/workspace/blob/main/programs/index/src/instructions/create_index.rs)
- Initializes a new [`Index`](https://github.com/faktorfi/faktor/blob/main/programs/index/src/state/index.rs) account.
- Errors if:
- The index already exists for the given owner and namespace.
#### [`create_pointer`](https://github.com/faktorfi/workspace/blob/main/programs/index/src/instructions/create_pointer.rs)
- Initializes a new [`Pointer`](https://github.com/faktorfi/workspace/blob/main/programs/index/src/state/pointer.rs) account.
- Initializes a new [`Proof`](https://github.com/faktorfi/workspace/blob/main/programs/index/src/state/proof.rs) account.
- Appends accounts to the index's data structure.
- Errors if:
- The name is already taken in the index.
- The pointer value already exists in the index.
#### [`delete_index`](https://github.com/faktorfi/workspace/blob/main/programs/index/src/instructions/delete_index.rs)
- Closes an [`Index`](https://github.com/faktorfi/faktor/blob/main/programs/index/src/state/index.rs) account.
- Returns rent to owner.
- Errors if:
- The account does not exist.
#### [`delete_pointer`](https://github.com/faktorfi/workspace/blob/main/programs/index/src/instructions/delete_pointer.rs)
- Closes a [`Pointer`](https://github.com/faktorfi/workspace/blob/main/programs/index/src/state/pointer.rs) account.
- Closes a [`Proof`](https://github.com/faktorfi/workspace/blob/main/programs/index/src/state/proof.rs) account.
- Removes accounts from the index's data structure.
- Returns rent to owner.
- Errors if:
- The accounts do not exist.
## State
#### [`Index`](https://github.com/faktorfi/workspace/blob/main/programs/index/src/state/index.rs)
- Metadata for managing a collection of pointers.
- PDA is a hash of the owner's address and a custom namespace address.
#### [`Pointer`](https://github.com/faktorfi/workspace/blob/main/programs/index/src/state/pointer.rs)
- A named public key address value.
- PDA is a hash of the index's address and the pointer's name.
#### [`Proof`](https://github.com/faktorfi/workspace/blob/main/programs/index/src/state/proof.rs)
- A "reverse record" to lookup the name of a public key in an index.
- PDA is a hash of the index's address and the pointer's stored address value.

## Examples
These examples are for Solana programs that need to create and manage their own on-chain indices. These examples show a program built with Anchor that has a singleton "authority account" for signing instructions on behalf of the program.
### Create an index
Here is an example instruction `create_my_index` that creates an index owned by the program.
```rs
// create_my_index.rs
use {
crate::state::*,
anchor_lang::{prelude::*, solana_program::system_program},
std::mem::size_of,
};
#[derive(Accounts)]
#[instruction(index_bump: u8)]
pub struct CreateMyIndex<'info> {
#[account(mut, seeds = [SEED_AUTHORITY], bump = authority.bump, owner = crate::ID)]
pub authority: Account<'info, Authority>,
#[account(mut)]
pub index: AccountInfo<'info>,
#[account(address = index_program::ID)]
pub index_program: Program<'info, index_program::program::IndexProgram>,
#[account(init, payer = signer, space = 8 + size_of<Namespace>())]
pub namespace: Account<'info, Namespace>
#[account(mut)]
pub signer: Signer<'info>,
#[account(address = system_program::ID)]
pub system_program: Program<'info, System>,
}
pub fn handler(ctx: Context<CreateMyIndex>, index_bump: u8) -> ProgramResult {
// Get accounts.
let authority = &ctx.accounts.authority;
let index = &ctx.accounts.index;
let index_program = &ctx.accounts.index_program;
let namespace = &ctx.accounts.namespace;
let signer = &ctx.accounts.signer;
let system_program = &ctx.accounts.system_program;
// Create an index owned by the program authority.
index_program::cpi::create_index(
CpiContext::new_with_signer(
index_program.to_account_info(),
index_program::cpi::accounts::CreateIndex {
index: index.to_account_info(),
namespace: namespace.to_account_info(),
owner: authority.to_account_info(),
payer: signer.to_account_info(),
system_program: system_program.to_account_info(),
},
&[&[SEED_AUTHORITY, &[authority.bump]]],
),
index_bump,
)
}
```
### Create a pointer
Here is an example instruction `create_my_pointer` that adds a pointer to an index owned by the program.
```rs
// create_my_pointer.rs
use {
crate::state::*,
anchor_lang::{prelude::*, solana_program::system_program},
std::mem::size_of,
};
#[derive(Accounts)]
#[instruction(reference: Pubkey, pointer_bump: u8, proof_bump: u8)]
pub struct CreateMyPointer<'info> {
#[account(mut, seeds = [SEED_AUTHORITY], bump = authority.bump, owner = crate::ID)]
pub authority: Account<'info, Authority>,
#[account(
mut,
constraint = index.owner == authority.key(),
constraint = index.namespace == namespace.key(),
owner = index_program.key()
)]
pub index: AccountInfo<'info>,
#[account(address = index_program::ID)]
pub index_program: Program<'info, index_program::program::IndexProgram>,
#[account()]
pub namespace: Account<'info, Namespace>
#[account()]
pub pointer: AccountInfo<'info>,
#[account()]
pub proof: AccountInfo<'info>,
#[account(mut)]
pub signer: Signer<'info>,
#[account(address = system_program::ID)]
pub system_program: Program<'info, System>,
}
pub fn handler(
ctx: Context<CreateMyPointer>,
reference: Pubkey,
pointer_bump: u8,
proof_bump: u8
) -> ProgramResult {
// Get accounts.
let authority = &ctx.accounts.authority;
let index = &ctx.accounts.index;
let index_program = &ctx.accounts.index_program;
let pointer = &ctx.accounts.pointer;
let proof = &ctx.accounts.proof;
let signer = &ctx.accounts.signer;
let system_program = &ctx.accounts.system_program;
// Create an index owned by the program authority.
index_program::cpi::create_pointer(
CpiContext::new_with_signer(
index_program.to_account_info(),
index_program::cpi::accounts::CreatePointer {
index: index.to_account_info(),
pointer: pointer.to_account_info(),
proof: proof.to_account_info(),
owner: authority.to_account_info(),
payer: signer.to_account_info(),
system_program: system_program.to_account_info(),
},
&[&[SEED_AUTHORITY, &[authority.bump]]],
),
index.count.to_string(),
reference,
pointer_bump,
proof_bump,
)
}
```