API Reference

All Instructions

This page mirrors the instruction-level reference from the core repository (docs/program-instructions.md).


Table of Contents

Authorization

The Security Token Program uses different authorization strategies depending on the instruction type. Each instruction falls into one of three authorization profiles:

Authorization Types

Permissionless

Instructions that require no special authorization.

Applicable instructions: InitializeMint, Verify

Initial Mint Authority OR Verification Programs

Instructions that can be authorized by either:

  • Verification Programs - External programs configured in VerificationConfig that validate the operation
  • OR Mint Creator Signature - The original creator who initialized the mint, verified through MintAuthority account

This dual authorization model allows flexibility: use verification programs for complex compliance workflows, or fall back to direct creator control when no verification is configured. It applies to mint configuration-related instructions.

Applicable instructions: UpdateMetadata, InitializeVerificationConfig, UpdateVerificationConfig, TrimVerificationConfig, CreateRateAccount, UpdateRateAccount, CloseRateAccount, CreateDistributionEscrow, CloseActionReceiptAccount, CloseClaimReceiptAccount

Verification Programs Only

Instructions that must be authorized through configured verification programs. These are typically token operations that require compliance checks (KYC/AML, transfer restrictions, etc.).

Applicable instructions: Mint, Burn, Pause, Resume, Freeze, Thaw, Transfer, Split, Convert, CreateProofAccount, UpdateProofAccount, ClaimDistribution

Verification Modes

When using verification programs, the Security Token Program supports two verification modes. The required verification flow is configured via the cpi_mode option in the corresponding verification config.

Introspection Mode (cpi_mode = false)

In introspection mode, the Security Token Program examines the Instructions Sysvar to verify that all required verification programs were called before the current instruction within the same transaction. In order to pass authorization via verification programs in introspection mode, the following conditions must be satisfied:

  • A corresponding instruction verification config exists with cpi_mode disabled and is passed to the Security Token Program.
  • All verification programs must be invoked before the Security Token instruction and must complete successfully.
  • Each verification program call must include the same instruction data and target instruction discriminator prefix.
  • Each verification program call must include at least all accounts used in the Security Token instruction. Additional accounts may be included for verification purposes if needed, provided they appear at the end of the instruction's required account list.

CPI Mode (cpi_mode = true)

In CPI mode, the Security Token Program directly invokes (via CPI) each configured verification program during instruction processing. In order to pass authorization via verification programs in CPI mode, the following conditions must be satisfied:

  • A corresponding instruction verification config exists with cpi_mode enabled and is passed to the Security Token Program.
  • Verification program accounts must be appended at the end of the Security Token Program instruction accounts.
  • Each verification program receives the same instruction data and accounts (verification overhead and verification program accounts are stripped before CPI).

Important: When verification programs are invoked in CPI, they receive only the core instruction accounts - the overhead accounts and CPI program accounts are stripped. This ensures verification programs have a consistent interface regardless of the verification mode used.

Verification Overhead Accounts

Instructions that require authorization should include a verification overhead - 3 accounts at the beginning of the accounts list that handle the authorization logic. The exact accounts depend on the authorization type.

Verification Programs

For instructions that support authorization via verification programs:

#AccountSignerWritableDescription
0mintThe mint account being operated on
1verification_configVerificationConfig PDA for this instruction type
2instructions_sysvarInstructions Sysvar (introspection mode) or program_id placeholder (CPI mode)

Initial Mint Authority

For instructions that support authorization via initial mint creator signature:

#AccountSignerWritableDescription
0mintThe mint account being operated on
1mint_authorityMintAuthority PDA
2creatorCreator signer

After the overhead come the instruction-specific accounts (core accounts).

Program Accounts

All program-owned accounts use a discriminator byte as the first byte of serialized data:

Account TypeDiscriminator
MintAuthority0
VerificationConfig1
Rate2
Receipt3
Proof4

MintAuthority

Stores the original mint creator information used for authorization fallback when verification programs are not configured.

Structure:

FieldTypeSizeDescription
discriminatoru81Account discriminator (0)
mintPubkey32SPL mint address this configuration belongs to
mint_creatorPubkey32Original creator address
bumpu81PDA bump seed

Total size: 66 bytes

PDA Derivation:

seeds = ["mint.authority", mint_address, creator_address]
program_id = Security Token Program

VerificationConfig

Stores verification program configuration for a specific instruction type on a specific mint.

Structure:

FieldTypeSizeDescription
discriminatoru81Account discriminator (1)
instruction_discriminatoru81Instruction type this config applies to
cpi_modebool1true for CPI mode, false for introspection mode
bumpu81PDA bump seed
verification_programsVec<Pubkey>4 + 32 × NList of verification program addresses (u32 length prefix + addresses)

Minimum size: 8 bytes (empty program list)

PDA Derivation:

seeds = ["verification_config", mint_address, instruction_discriminator]
program_id = Security Token Program

Rate

Stores conversion/split rate configuration for corporate actions.

Structure:

FieldTypeSizeDescription
discriminatoru81Account discriminator (2)
roundingu81Rounding direction: 0 = Up, 1 = Down
numeratoru81Rate numerator
denominatoru81Rate denominator
bumpu81PDA bump seed

Total size: 5 bytes

PDA Derivation:

seeds = ["rate", action_id (8 bytes LE), mint_from_address, mint_to_address]
program_id = Security Token Program

Receipt

Records that a holder has participated in a corporate action (split/convert) or claimed a distribution. Prevents duplicate participation. Receipt has minimal structure (only discriminator) because all relevant information is encoded in the PDA seeds.

Structure:

FieldTypeSizeDescription
discriminatoru81Account discriminator (3)

Total size: 1 byte

PDA Derivation (Action Receipt - for Split/Convert):

seeds = ["receipt", mint_address, action_id (8 bytes LE)]
program_id = Security Token Program

PDA Derivation (Claim Receipt - for ClaimDistribution):

seeds = ["receipt", mint_address, token_account_address, action_id (8 bytes LE), proof_hash (32 bytes)]
program_id = Security Token Program

Proof

Stores Merkle proof data for distribution claims. Allows splitting large proofs into separate transactions via CreateProofAccount and UpdateProofAccount.

Structure:

FieldTypeSizeDescription
discriminatoru81Account discriminator (4)
bumpu81PDA bump seed
dataVec<[u8; 32]>4 + 32 × NMerkle proof nodes (u32 length prefix + nodes)

Minimum size: 6 bytes (empty proof - invalid state, at least one node required)

PDA Derivation:

seeds = ["proof", token_account_address, action_id (8 bytes LE)]
program_id = Security Token Program

Virtual PDAs

Virtual PDAs are program-derived addresses used as authorities when invoking SPL Token 2022 extension instructions or managing transfer-hook extras. They are not data accounts, and therefore:

  • Do not store any on-chain data and are never initialized or closed.
  • Hold no lamports and cannot be rent-exempt; they exist deterministically from seeds.
  • Are passed in instructions as authority accounts and sign via invoke_signed.
  • Are validated against expected derived keys in the program before use.
  • Use seed layouts defined by the program; some include additional components like action_id or merkle_root.

DistributionEscrowAuthority

Virtual PDA used as authority for distribution escrow token accounts. Does not store any data (not a program account).

PDA Derivation:

seeds = ["distribution_escrow_authority", mint_address, action_id (8 bytes LE), merkle_root (32 bytes)]
program_id = Security Token Program

PermanentDelegateAuthority

Virtual PDA used as authority for permanent delegate operations (forced transfers and clawbacks). This PDA does not store data; it is derived and used as a signer via invoke_signed when calling SPL Token 2022 instructions.

PDA Derivation:

seeds = ["mint.permanent_delegate", mint_address]
program_id = Security Token Program

PauseAuthority

Virtual PDA used as authority for the Pausable extension (Pause/Resume). This PDA does not store data; it is derived and used as a signer via invoke_signed when calling SPL Token 2022 instructions.

PDA Derivation:

seeds = ["mint.pause_authority", mint_address]
program_id = Security Token Program

FreezeAuthority

Virtual PDA used as authority for freezing/thawing token accounts (Freeze/Thaw). This PDA does not store data; it is derived and used as a signer via invoke_signed when calling SPL Token 2022 instructions.

PDA Derivation:

seeds = ["mint.freeze_authority", mint_address]
program_id = Security Token Program

TransferHookAuthority

Virtual PDA used as authority for the TransferHook extension on a mint. It is also required when managing verification config for Transfer to authorize updates to the ExtraAccountMetaList associated with the mint. This PDA does not store data; it is derived and used as a signer via invoke_signed when calling SPL Token 2022 instructions.

PDA Derivation:

seeds = ["mint.transfer_hook", mint_address]
program_id = Security Token Program

Serialization Conventions

This section summarizes common encoding rules used throughout the program to keep instruction and account serialization consistent.

  • Discriminators: First byte ($u8$) identifies the instruction or account type.
  • Endianness: All integer fields use little-endian ($u32$, $u64$).
  • Strings: UTF-8 with $u32$ (LE) length prefix, followed by raw bytes.
  • Vec<T>: $u32$ (LE) length prefix, then each element in order.
  • Option<T>: 1-byte prefix (0 = None, 1 = Some); if Some, the value bytes follow immediately.
  • Fixed-size arrays: Stored inline as raw bytes in field order (e.g., 32-byte hashes).

Where a section provides explicit serialization notes, they follow these conventions. If unspecified, assume the rules above.

Errors

Errors returned by the program map to ProgramError::Custom(code). The table lists custom error codes and descriptions from SecurityTokenError.

Error NameCodeDescription
VerificationProgramNotFound1Verification program not found
NotEnoughAccountsForVerification2Not enough accounts for verification
AccountIntersectionMismatch3Required account sets do not intersect as expected
InvalidVerificationConfigPda4Provided VerificationConfig PDA does not match derivation
CannotModifyExternalMetadataAccount5External metadata account cannot be modified
InternalMetadataRequiresData6Internal metadata storage requires metadata to be present
ExternalMetadataForbidsData7External metadata storage forbids metadata in this call

Refer to these when handling failures in verification flows or metadata updates.

Instructions

All instructions use a discriminator byte as the first byte of instruction data:

InstructionDiscriminator
InitializeMint0
UpdateMetadata1
InitializeVerificationConfig2
UpdateVerificationConfig3
TrimVerificationConfig4
Verify5
Mint6
Burn7
Pause8
Resume9
Freeze10
Thaw11
Transfer12
CreateRateAccount13
UpdateRateAccount14
CloseRateAccount15
Split16
Convert17
CreateProofAccount18
UpdateProofAccount19
CreateDistributionEscrow20
ClaimDistribution21
CloseActionReceiptAccount22
CloseClaimReceiptAccount23

For general encoding rules and failure codes, see Serialization Conventions and Errors.

InitializeMint

Creates a new security token mint with required extensions and optional metadata.

Discriminator: 0

Authorization: Permissionless

Accounts:

#AccountSignerWritableDescription
0mintNew mint account (keypair)
1mint_authorityMintAuthority PDA to be created
2creatorMint creator and payer
3token_programSPL Token 2022 Program
4system_programSystem Program
5rent_sysvarRent Sysvar

Arguments:

// Serialization:
// - InitializeMintArgs: bytes = MintArgs + 1-byte presence flags (in order)
//   for ix_metadata_pointer, ix_metadata, ix_scaled_ui_amount, followed by
//   serialized bytes of each present optional struct in the same order.
struct InitializeMintArgs {
    ix_mint: MintArgs,
    ix_metadata_pointer: Option<MetadataPointerArgs>,
    ix_metadata: Option<TokenMetadataArgs>,
    ix_scaled_ui_amount: Option<ScaledUiAmountConfigArgs>,
}

// - MintArgs: decimals (1 byte), mint_authority (32 bytes), freeze_authority (32 bytes).
struct MintArgs {
    decimals: u8,
    mint_authority: Pubkey,
    freeze_authority: Pubkey,
}

// - MetadataPointerArgs: authority (32 bytes), metadata_address (32 bytes).
struct MetadataPointerArgs {
    authority: Pubkey,
    metadata_address: Pubkey,
}

// - TokenMetadataArgs (Borsh-like): name/symbol/uri as UTF-8 with u32 LE length;
//   additional_metadata as u32 LE length + raw bytes.
struct TokenMetadataArgs {
    update_authority: Pubkey,
    mint: Pubkey,
    name: String,
    symbol: String,
    uri: String,
    additional_metadata: Vec<u8>,
}

// - ScaledUiAmountConfigArgs: authority (32 bytes); multiplier and new_multiplier
//   are [u8; 8] containing f64 little-endian bytes; new_multiplier_effective_timestamp
//   is i64 little-endian.
struct ScaledUiAmountConfigArgs {
    authority: Pubkey,
    multiplier: [u8; 8],
    new_multiplier_effective_timestamp: i64,
    new_multiplier: [u8; 8],
}

Description:

Initializes a new SPL Token 2022 mint with the following extensions:

  • PermanentDelegate - Enables forced transfers and clawbacks
  • TransferHook - Routes transfers through verification
  • Pausable - Enables emergency pause functionality
  • MetadataPointer (optional) - Points to metadata location
  • TokenMetadata (optional) - Stores metadata in mint account
  • ScaledUiAmount (optional) - Display scaling for UI

After initialization, mint authority is transferred to a program-controlled MintAuthority PDA. The provided creator is stored in the MintAuthority account, and the creator's signature may authorize subsequent instructions that use the Initial Mint Authority authorization type.

UpdateMetadata

Updates the token metadata stored in the mint account.

Discriminator: 1

Authorization: Initial Mint Authority OR Verification Programs

Accounts:

#AccountSignerWritableDescription
0mint_authorityMintAuthority PDA
1payerTransaction fee payer
2mint_accountMint account to update
3token_programSPL Token 2022 Program
4system_programSystem Program

Arguments:

struct UpdateMetadataArgs {
    metadata: TokenMetadataArgs,
}

// - TokenMetadataArgs (Borsh-like): name/symbol/uri as UTF-8 with u32 LE length;
//   additional_metadata as u32 LE length + raw bytes.
struct TokenMetadataArgs {
    update_authority: Pubkey,
    mint: Pubkey,
    name: String,
    symbol: String,
    uri: String,
    additional_metadata: Vec<u8>,
}

Description:

Updates the token metadata stored in the mint account. If a metadata pointer is used, perform the update via the SPL Token 2022 Program directly.

InitializeVerificationConfig

Creates a new verification configuration for a specific instruction type.

Discriminator: 2

Authorization: Initial Mint Authority OR Verification Programs

Accounts:

#AccountSignerWritableDescription
0payerTransaction fee payer
1mint_accountMint account
2config_accountVerificationConfig account to create
3system_programSystem Program
4account_metas_pdaExtraAccountMetaList PDA *
5transfer_hook_pdaTransferHookAuthority PDA *
6transfer_hook_programTransfer hook program *

* Required only when instruction_discriminator = 12 (Transfer) to manage ExtraAccountMetaList for transfer hook.

Arguments:

// Serialization: instruction_discriminator (1 byte) + cpi_mode (1 byte, 0/1)
// + program_addresses count (u32 LE) + each Pubkey (32 bytes).
struct InitializeVerificationConfigArgs {
    instruction_discriminator: u8,
    cpi_mode: bool,
    program_addresses: Vec<Pubkey>,
}

UpdateVerificationConfig

Updates an existing verification configuration.

Discriminator: 3

Authorization: Initial Mint Authority OR Verification Programs

Accounts:

#AccountSignerWritableDescription
0payerTransaction fee payer
1mint_accountMint account
2config_accountVerificationConfig account to update
3system_programSystem Program
4account_metas_pdaExtraAccountMetaList PDA *
5transfer_hook_pdaTransferHookAuthority PDA *
6transfer_hook_programTransfer hook program *

* Required only when instruction_discriminator = 12 (Transfer) to manage ExtraAccountMetaList for transfer hook.

Arguments:

// Serialization: instruction_discriminator (1 byte) + cpi_mode (1 byte, 0/1)
// + offset (1 byte) + program_addresses count (u32 LE) + each Pubkey (32 bytes).
struct UpdateVerificationConfigArgs {
    instruction_discriminator: u8,
    cpi_mode: bool,
    offset: u8,
    program_addresses: Vec<Pubkey>,
}

Description:

Updates the verification program list starting at the specified offset. You can also toggle CPI mode for the instruction config. If resizing is required, the VerificationConfig account is reallocated returning reclaimed rent to the payer.

TrimVerificationConfig

Reduces the size of or closes a verification configuration.

Discriminator: 4

Authorization: Initial Mint Authority OR Verification Programs

Accounts:

#AccountSignerWritableDescription
0mint_accountMint account
1config_accountVerificationConfig account to trim
2recipientRecipient for reclaimed rent
3system_programSystem Program
4account_metas_pdaExtraAccountMetaList PDA *
5transfer_hook_pdaTransferHookAuthority PDA *
6transfer_hook_programTransfer hook program *

* Required only when instruction_discriminator = 12 (Transfer) to manage ExtraAccountMetaList for transfer hook.

Arguments:

// Serialization: instruction_discriminator (1 byte) + size (1 byte) + close (1 byte, 0/1).
struct TrimVerificationConfigArgs {
    instruction_discriminator: u8,
    size: u8,
    close: bool,
}

Description:

Reduces the verification program list to the specified size or closes the account, returning reclaimed rent to the recipient.

Verify

Validates that the caller has authority to execute a specific instruction. Used in introspection mode.

Discriminator: 5

Authorization: Permissionless

Accounts:

#AccountSignerWritableDescription
0mintMint account
1verification_configVerificationConfig account
2instructions_sysvarInstructions Sysvar

Arguments:

// Serialization: ix (1 byte) + instruction_data raw bytes (opaque to this instruction).
struct VerifyArgs {
    ix: u8,
    instruction_data: Vec<u8>,
}

Description:

This instruction performs a check that a specified instruction is successfully verified by all required verification programs and can proceed to execution.

Mint

Mints new tokens to a destination account.

Discriminator: 6

Authorization: Verification Programs Only

Accounts:

#AccountSignerWritableDescription
0mint_authorityMintAuthority PDA
1mint_accountMint account
2destinationDestination token account
3token_programSPL Token 2022 Program

Arguments:

// Serialization: amount (u64 LE, 8 bytes).
amount: u64

Description:

Increases token supply and immediately credits the specified destination token account.

Burn

Burns tokens from a token account.

Discriminator: 7

Authorization: Verification Programs Only

Accounts:

#AccountSignerWritableDescription
0permanent_delegatePermanentDelegate PDA
1mint_accountMint account
2token_accountToken account to burn from
3token_programSPL Token 2022 Program

Arguments:

// Serialization: amount (u64 LE, 8 bytes).
amount: u64

Description:

Decreases token supply and immediately debits the specified token account.

Pause

Pauses all token transfers for the mint.

Discriminator: 8

Authorization: Verification Programs Only

Accounts:

#AccountSignerWritableDescription
0pause_authorityPauseAuthority PDA
1mint_accountMint account
2token_programSPL Token 2022 Program

Arguments: None

Resume

Resumes token transfers for a paused mint.

Discriminator: 9

Authorization: Verification Programs Only

Accounts:

#AccountSignerWritableDescription
0pause_authorityPauseAuthority PDA
1mint_accountMint account
2token_programSPL Token 2022 Program

Arguments: None

Freeze

Freezes a specific token account, preventing transfers.

Discriminator: 10

Authorization: Verification Programs Only

Accounts:

#AccountSignerWritableDescription
0freeze_authorityFreezeAuthority PDA
1mint_accountMint account
2token_accountToken account to freeze
3token_programSPL Token 2022 Program

Arguments: None

Thaw

Unfreezes a frozen token account.

Discriminator: 11

Authorization: Verification Programs Only

Accounts:

#AccountSignerWritableDescription
0freeze_authorityFreezeAuthority PDA
1mint_accountMint account
2token_accountToken account to thaw
3token_programSPL Token 2022 Program

Arguments: None

Transfer

Transfers tokens between accounts (forced transfer).

Discriminator: 12

Authorization: Verification Programs Only

Accounts:

#AccountSignerWritableDescription
0permanent_delegate_authorityPermanentDelegate PDA
1mint_accountMint account
2from_token_accountSource token account
3to_token_accountDestination token account
4transfer_hook_programTransfer hook program
5token_programSPL Token 2022 Program

Arguments:

// Serialization: amount (u64 LE, 8 bytes).
amount: u64

CreateRateAccount

Creates a rate configuration for split/convert operations.

Discriminator: 13

Authorization: Initial Mint Authority OR Verification Programs

Accounts:

#AccountSignerWritableDescription
0payerTransaction fee payer
1rate_accountRate account to create
2mint_fromSource mint
3mint_toDestination mint
4system_programSystem Program

Arguments:

// Serialization: action_id (u64 LE, 8 bytes) + rate.rounding (u8)
// + rate.numerator (u8) + rate.denominator (u8).
struct CreateRateArgs {
    action_id: u64,
    rate: RateArgs,
}

struct RateArgs {
    rounding: u8,    // 0 = Up, 1 = Down
    numerator: u8,
    denominator: u8,
}

UpdateRateAccount

Updates an existing rate configuration.

Discriminator: 14

Authorization: Initial Mint Authority OR Verification Programs

Accounts:

#AccountSignerWritableDescription
0rate_accountRate account to update
1mint_fromSource mint
2mint_toDestination mint

Arguments:

// Serialization: action_id (u64 LE, 8 bytes) + rate.rounding (u8)
// + rate.numerator (u8) + rate.denominator (u8).
struct UpdateRateArgs {
    action_id: u64,
    rate: RateArgs,
}

struct RateArgs {
    rounding: u8,    // 0 = Up, 1 = Down
    numerator: u8,
    denominator: u8,
}

CloseRateAccount

Closes a rate account and reclaims rent.

Discriminator: 15

Authorization: Initial Mint Authority OR Verification Programs

Accounts:

#AccountSignerWritableDescription
0rate_accountRate account to close
1destinationRecipient for reclaimed rent
2mint_fromSource mint
3mint_toDestination mint

Arguments:

// Serialization: action_id (u64 LE, 8 bytes).
struct CloseRateArgs {
    action_id: u64,
}

Split

Executes a token split operation (e.g., stock split). Mints additional tokens to holder based on rate.

Discriminator: 16

Authorization: Verification Programs Only

Accounts:

#AccountSignerWritableDescription
0mint_authorityMintAuthority PDA
1permanent_delegatePermanentDelegate PDA
2payerTransaction fee payer
3mint_accountMint account
4token_accountHolder's token account
5rate_accountRate account
6receipt_accountReceipt account to create
7token_programSPL Token 2022 Program
8system_programSystem Program

Arguments:

// Serialization: action_id (u64 LE, 8 bytes).
struct SplitArgs {
    action_id: u64,
}

Convert

Converts tokens from one mint to another based on rate (e.g., bond conversion).

Discriminator: 17

Authorization: Verification Programs Only

Accounts:

#AccountSignerWritableDescription
0mint_authorityMintAuthority PDA
1permanent_delegatePermanentDelegate PDA
2payerTransaction fee payer
3mint_fromSource mint account
4mint_toDestination mint account
5token_account_fromSource token account
6token_account_toDestination token account
7rate_accountRate account
8receipt_accountReceipt account to create
9token_programSPL Token 2022 Program
10system_programSystem Program

Arguments:

// Serialization: action_id (u64 LE, 8 bytes) + amount_to_convert (u64 LE, 8 bytes).
struct ConvertArgs {
    action_id: u64,
    amount_to_convert: u64,
}

CreateProofAccount

Creates a Proof account to store Merkle proof data for distribution claims.

Discriminator: 18

Authorization: Verification Programs Only

Accounts:

#AccountSignerWritableDescription
0payerTransaction fee payer
1mint_accountMint account
2proof_accountProof account to create
3token_accountToken account the proof is for
4system_programSystem Program

Arguments:

// Serialization: action_id (u64 LE, 8 bytes) + data length (u32 LE)
// followed by each node as 32 raw bytes.
struct CreateProofArgs {
    action_id: u64,
    data: Vec<[u8; 32]>,
}

UpdateProofAccount

Updates an existing Proof account with additional proof nodes.

Discriminator: 19

Authorization: Verification Programs Only

Accounts:

#AccountSignerWritableDescription
0payerTransaction fee payer
1mint_accountMint account
2proof_accountProof account to update
3token_accountToken account the proof is for
4system_programSystem Program

Arguments:

// Serialization: action_id (u64 LE, 8 bytes) + data (32 raw bytes)
// + offset (u32 LE).
struct UpdateProofArgs {
    action_id: u64,
    data: [u8; 32],
    offset: u32,
}

CreateDistributionEscrow

Creates an escrow token account for distribution (dividends/coupons).

Discriminator: 20

Authorization: Initial Mint Authority OR Verification Programs

Accounts:

#AccountSignerWritableDescription
0distribution_escrow_authorityDistributionEscrowAuthority PDA
1payerTransaction fee payer
2distribution_token_accountEscrow token account to create
3distribution_mintDistribution mint
4token_programSPL Token 2022 Program
5associated_token_account_programAssociated Token Account Program
6system_programSystem Program

Arguments:

// Serialization: action_id (u64 LE, 8 bytes) + merkle_root (32 raw bytes).
struct CreateDistributionEscrowArgs {
    action_id: u64,
    merkle_root: [u8; 32],
}

ClaimDistribution

Claims tokens from a distribution escrow based on Merkle proof.

Discriminator: 21

Authorization: Verification Programs Only

Accounts:

#AccountSignerWritableDescription
0permanent_delegate_authorityPermanentDelegate PDA
1payerTransaction fee payer
2mint_accountMint account
3eligible_token_accountClaimant's token account
4escrow_token_account(Optional) Escrow token account
5receipt_accountReceipt account to create
6proof_account(Optional) Proof account
7transfer_hook_programTransfer hook program
8token_programSPL Token 2022 Program
9system_programSystem Program

Arguments:

// Serialization: action_id (u64 LE, 8 bytes) + amount (u64 LE, 8 bytes) + merkle_root (32 raw bytes)
// + leaf_index (u32 LE) + Option prefix (1 byte: 0 = None, 1 = Some) for merkle_proof.
// If Some: proof length (u32 LE) followed by each node (32 raw bytes).
struct ClaimDistributionArgs {
    action_id: u64,
    amount: u64,
    merkle_root: [u8; 32],
    leaf_index: u32,
    merkle_proof: Option<Vec<[u8; 32]>>,
}

CloseActionReceiptAccount

Closes an action receipt account (for Split/Convert) and reclaims rent.

Discriminator: 22

Authorization: Initial Mint Authority OR Verification Programs

Accounts:

#AccountSignerWritableDescription
0receipt_accountReceipt account to close
1destinationRecipient for reclaimed rent
2mint_accountMint account

Arguments:

// Serialization: action_id (u64 LE, 8 bytes).
struct CloseActionReceiptArgs {
    action_id: u64,
}

CloseClaimReceiptAccount

Closes a claim receipt account (for ClaimDistribution) and reclaims rent.

Discriminator: 23

Authorization: Initial Mint Authority OR Verification Programs

Accounts:

#AccountSignerWritableDescription
0receipt_accountReceipt account to close
1destinationRecipient for reclaimed rent
2mint_accountMint account
3eligible_token_accountToken account from the claim
4proof_account(Optional) Proof account

Arguments:

// Serialization: action_id (u64 LE, 8 bytes) + Option prefix (1 byte: 0 = None, 1 = Some).
// If Some: proof length (u32 LE) followed by each node (32 raw bytes).
struct CloseClaimReceiptArgs {
    action_id: u64,
    merkle_proof: Option<Vec<[u8; 32]>>,
}

Verification Program Interface

Verification programs must implement a specific interface to be compatible with the Security Token Program.

A boilerplate example for a verification program is provided.

Instruction Format

Verification programs receive instructions with the following data format:

[instruction_discriminator: u8, ...instruction_args]

The discriminator byte matches the Security Token instruction being verified, followed by the same arguments.

Account Format

Verification programs receive the same accounts as the Security Token instruction (excluding verification overhead accounts).

Expected Behavior

  • Success: Return Ok(()) to approve the operation
  • Failure: Return an error to reject the operation

In CPI mode, any error from a verification program will cause the entire Security Token instruction to fail.

In introspection mode, the verification program must have been called successfully before the Security Token instruction.

Previous
API overview