Skip to main content

Account Structs

CPI account structures required for making calls to the Inco Lightning program.

Operation

Used for all encrypted operations (arithmetic, comparison, bitwise, random, input functions, select).
use inco_lightning::cpi::accounts::Operation;

pub struct Operation<'info> {
    /// The signer authorizing the operation
    pub signer: AccountInfo<'info>,
}
AccountMutableSignerDescription
signerTransaction signer authorizing the operation

Usage

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 for granting or revoking decryption access.
use inco_lightning::cpi::accounts::Allow;

pub struct Allow<'info> {
    /// The allowance PDA account
    pub allowance_account: AccountInfo<'info>,
    /// The signer authorizing the allowance
    pub signer: AccountInfo<'info>,
    /// The address being allowed access
    pub allowed_address: AccountInfo<'info>,
    /// System program for account creation
    pub system_program: AccountInfo<'info>,
}
AccountMutableSignerDescription
allowance_accountPDA storing allowance state
signerHandle owner authorizing the allowance
allowed_addressAddress being granted/revoked access
system_programSystem program for account creation

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(),
    },
);

allow(cpi_ctx, handle, true, allowed_address)?;

IsAllowed

Used for checking if an address has decryption permission.
use inco_lightning::cpi::accounts::IsAllowed;

pub struct IsAllowed<'info> {
    /// The allowance PDA account to check
    pub allowance_account: AccountInfo<'info>,
    /// The address to check allowance for
    pub allowed_address: AccountInfo<'info>,
}
AccountMutableSignerDescription
allowance_accountPDA storing allowance state
allowed_addressAddress to check permission for

Usage

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 for verifying Ed25519 signatures for attested decryption.
use inco_lightning::cpi::accounts::VerifySignature;

pub struct VerifySignature<'info> {
    /// The instructions sysvar account
    pub instructions: AccountInfo<'info>,
    /// The signer authorizing the verification
    pub signer: AccountInfo<'info>,
}
AccountMutableSignerDescription
instructionsInstructions sysvar (SYSVAR_INSTRUCTIONS_ID)
signerTransaction signer authorizing the verification

Usage

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),
)?;

Adding to Your Instruction

When defining your instruction’s account struct, 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 for encrypted operations
    #[account(address = INCO_LIGHTNING_ID)]
    pub inco_lightning_program: AccountInfo<'info>,
}
For access control operations, also include the allowance PDA and system program:
#[derive(Accounts)]
pub struct GrantAccess<'info> {
    #[account(mut)]
    pub authority: Signer<'info>,

    /// CHECK: Allowance PDA account
    #[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>,
}