Skip to main content

Overview

The closeContextStateProof function creates an instruction to close a context state account that was created during proof verification. This allows you to reclaim the rent exemption balance stored in the account.

Function Signature

function closeContextStateProof({
  contextState,
  authority,
  destination,
  programId = ZK_ELGAMAL_PROOF_PROGRAM_ADDRESS,
}: CloseContextStateArgs): Instruction

Parameters

contextState
Address
required
Address of the context state account to close
authority
TransactionSigner
required
Authority that was specified when creating the context state account. Must sign the transaction.
destination
Address
required
Address that will receive the reclaimed rent lamports from the closed account
programId
Address
ZK ElGamal Proof program address. Defaults to ZK_ELGAMAL_PROOF_PROGRAM_ADDRESS

Returns

Instruction - Single instruction to close the context state account

Usage Example

Basic Context State Closure

Close a context state account after verification:
import { verifyZeroCiphertext, closeContextStateProof } from '@solana/zk-elgamal-proof';
import { ElGamalKeypair, ZeroCiphertextProofData } from '@solana/zk-sdk/node';
import { generateKeyPairSigner } from '@solana/kit';

// Create and verify a proof with context state
const contextAccount = await generateKeyPairSigner();
const keypair = new ElGamalKeypair();
const ciphertext = keypair.pubkey().encryptU64(0n);
const proof = new ZeroCiphertextProofData(keypair, ciphertext);

const verifyIxs = await verifyZeroCiphertext({
  rpc: client.rpc,
  payer,
  proofData: proof.toBytes(),
  contextState: {
    contextAccount,
    authority: payer.address,
  },
});

await sendAndConfirmInstructions(client, payer, verifyIxs);

// Verify context state account exists
let accountInfo = await client.rpc
  .getAccountInfo(contextAccount.address, { encoding: 'base64' })
  .send();
console.log('Account exists:', accountInfo.value !== null);

// Close the context state account
const destination = await generateKeyPairSigner();
const closeIx = closeContextStateProof({
  contextState: contextAccount.address,
  authority: payer, // Must match the authority from creation
  destination: destination.address,
});

await sendAndConfirmInstructions(client, payer, [closeIx]);

// Verify account is closed
accountInfo = await client.rpc
  .getAccountInfo(contextAccount.address, { encoding: 'base64' })
  .send();
console.log('Account closed:', accountInfo.value === null);

// Check destination received rent
const destBalance = await client.rpc.getBalance(destination.address).send();
console.log('Destination balance:', destBalance.value);

Closing Multiple Context States

Close multiple context state accounts in a single transaction:
const closeIxs = contextAccounts.map(contextAccount =>
  closeContextStateProof({
    contextState: contextAccount.address,
    authority: payer,
    destination: payer.address, // Return rent to payer
  })
);

await sendAndConfirmInstructions(client, payer, closeIxs);

Notes

Authority RequirementThe authority parameter must match the authority that was specified when creating the context state account. This authority must sign the transaction.
Rent ReclamationWhen a context state account is closed, all lamports (rent exemption balance) are transferred to the specified destination address.
Authority MismatchIf the provided authority doesn’t match the authority stored in the context state account, the transaction will fail.

Use Cases

  • Cleaning up context state accounts after proof verification is no longer needed
  • Reclaiming rent from temporary proof storage
  • Managing on-chain storage costs by closing unused accounts
  • Batch closing multiple context states to reduce account clutter

Context State Account Types

Context state accounts can be created by various verification functions: All context state accounts created by these functions can be closed using closeContextStateProof.

Build docs developers (and LLMs) love