Documentation Index
Fetch the complete documentation index at: https://docs.inco.org/llms.txt
Use this file to discover all available pages before exploring further.
Account Structs
When making CPI calls to Inco Lightning, you need to pass specific account structures. This guide explains each account struct and when to use it.
Overview
| Struct | Purpose | Used By |
|---|
Operation | General encrypted operations | All arithmetic, comparison, bitwise, random, input, select functions |
Allow | Grant/revoke decryption access | allow function |
IsAllowed | Check decryption permissions | is_allowed function |
VerifySignature | Verify attestation signatures | is_validsignature function |
Operation
The simplest account struct, used for most encrypted operations.
use inco_lightning::cpi::accounts::Operation;
pub struct Operation<'info> {
pub signer: AccountInfo<'info>,
}
When to use: Any encrypted computation - arithmetic (e_add, e_sub, e_mul, e_rem), comparisons (e_ge, e_gt, e_le, e_lt, e_eq), bitwise operations (e_and, e_or, e_not, e_shl, e_shr), random generation (e_rand), input functions (new_euint128, new_ebool, as_euint128, as_ebool), and conditional selection (e_select).
let cpi_ctx = CpiContext::new(
ctx.accounts.inco_lightning_program.to_account_info(),
Operation {
signer: ctx.accounts.authority.to_account_info(),
},
);
let result = e_add(cpi_ctx, a, b, 0)?;
Allow
Used to grant or revoke decryption permissions for a handle.
use inco_lightning::cpi::accounts::Allow;
pub struct Allow<'info> {
pub allowance_account: AccountInfo<'info>,
pub signer: AccountInfo<'info>,
pub allowed_address: AccountInfo<'info>,
pub system_program: AccountInfo<'info>,
}
When to use: When you need to grant an address permission to decrypt a handle, or revoke previously granted permission.
| Account | Description |
|---|
allowance_account | PDA that stores the allowance state (mutable) |
signer | The handle owner who can grant permissions (mutable, signer) |
allowed_address | The address being granted/revoked access |
system_program | Required for PDA creation |
Allowance PDA Derivation
The allowance account is a PDA derived from the handle and allowed address:
seeds = [handle.to_le_bytes(), allowed_address]
Client-side (TypeScript):
import { PublicKey } from '@solana/web3.js';
const INCO_LIGHTNING_PROGRAM_ID = new PublicKey('5sjEbPiqgZrYwR31ahR6Uk9wf5awoX61YGg7jExQSwaj');
function findAllowanceAccount(handle: bigint, allowedAddress: PublicKey): PublicKey {
const handleBuffer = Buffer.alloc(16);
handleBuffer.writeBigUInt64LE(handle & BigInt('0xFFFFFFFFFFFFFFFF'), 0);
handleBuffer.writeBigUInt64LE(handle >> BigInt(64), 8);
const [allowanceAccount] = PublicKey.findProgramAddressSync(
[handleBuffer, allowedAddress.toBuffer()],
INCO_LIGHTNING_PROGRAM_ID
);
return allowanceAccount;
}
Usage
let cpi_ctx = CpiContext::new(
ctx.accounts.inco_lightning_program.to_account_info(),
Allow {
allowance_account: ctx.accounts.allowance_account.to_account_info(),
signer: ctx.accounts.authority.to_account_info(),
allowed_address: ctx.accounts.allowed_address.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
},
);
// Grant access
allow(cpi_ctx, handle, true, allowed_address)?;
// Or revoke access
allow(cpi_ctx, handle, false, allowed_address)?;
IsAllowed
Used to check if an address has decryption permission.
use inco_lightning::cpi::accounts::IsAllowed;
pub struct IsAllowed<'info> {
pub allowance_account: AccountInfo<'info>,
pub allowed_address: AccountInfo<'info>,
}
When to use: When you need to verify if an address can decrypt a handle before performing an action.
let cpi_ctx = CpiContext::new(
ctx.accounts.inco_lightning_program.to_account_info(),
IsAllowed {
allowance_account: ctx.accounts.allowance_account.to_account_info(),
allowed_address: ctx.accounts.allowed_address.to_account_info(),
},
);
let has_access = is_allowed(cpi_ctx, handle)?;
VerifySignature
Used to verify Ed25519 signatures from the covalidator network for attested decryption.
use inco_lightning::cpi::accounts::VerifySignature;
pub struct VerifySignature<'info> {
pub instructions: AccountInfo<'info>,
pub signer: AccountInfo<'info>,
}
When to use: When verifying that decrypted values came from the covalidator network (attested decryption).
| Account | Description |
|---|
instructions | The instructions sysvar (SYSVAR_INSTRUCTIONS_ID) |
signer | Transaction signer (mutable, signer) |
use solana_program::sysvar::instructions::ID as SYSVAR_INSTRUCTIONS_ID;
let cpi_ctx = CpiContext::new(
ctx.accounts.inco_lightning_program.to_account_info(),
VerifySignature {
instructions: ctx.accounts.instructions.to_account_info(),
signer: ctx.accounts.authority.to_account_info(),
},
);
let results = is_validsignature(
cpi_ctx,
1, // expected signature count
Some(handles),
Some(plaintext_values),
)?;
Setting Up Your Instruction
Your instruction’s account struct needs to include the Inco Lightning program:
use inco_lightning::ID as INCO_LIGHTNING_ID;
#[derive(Accounts)]
pub struct MyInstruction<'info> {
#[account(mut)]
pub authority: Signer<'info>,
#[account(mut)]
pub my_account: Account<'info, MyAccount>,
/// CHECK: Inco Lightning program
#[account(address = INCO_LIGHTNING_ID)]
pub inco_lightning_program: AccountInfo<'info>,
}
For access control operations, include additional accounts:
#[derive(Accounts)]
pub struct GrantAccess<'info> {
#[account(mut)]
pub authority: Signer<'info>,
/// CHECK: Allowance PDA
#[account(mut)]
pub allowance_account: AccountInfo<'info>,
/// CHECK: Address being granted access
pub allowed_address: AccountInfo<'info>,
/// CHECK: Inco Lightning program
#[account(address = INCO_LIGHTNING_ID)]
pub inco_lightning_program: AccountInfo<'info>,
pub system_program: Program<'info, System>,
}
For signature verification, include the instructions sysvar:
use solana_program::sysvar::instructions::ID as SYSVAR_INSTRUCTIONS_ID;
#[derive(Accounts)]
pub struct VerifyDecryption<'info> {
#[account(mut)]
pub authority: Signer<'info>,
/// CHECK: Instructions sysvar
#[account(address = SYSVAR_INSTRUCTIONS_ID)]
pub instructions: AccountInfo<'info>,
/// CHECK: Inco Lightning program
#[account(address = INCO_LIGHTNING_ID)]
pub inco_lightning_program: AccountInfo<'info>,
}