Program: Token Wrap
Instruction: CreateMint
This instruction creates a wrapped token mint, enabling the wrapping of tokens between the SPL Token and the Token 2022 programs. It establishes a wrapped mint and a backpointer account to link the wrapped mint to its unwrapped counterpart. The caller must prefund the wrapped mint and backpointer accounts with sufficient lamports to cover rent exemption.
Input parameters
idempotent: bool: Determines the instruction's behavior if the wrapped mint or backpointer accounts already exist. Iftrue, the instruction is idempotent and will not fail if the accounts are already initialized. Iffalse, it fails if either account is already initialized.
Accounts
wrapped_mint_account: The unallocated account that will become the wrapped mint.Signer: No.
Init: Yes, the instruction initializes this account as a mint.
PDA: Yes, derived using
get_wrapped_mint_address(unwrapped_mint_address, wrapped_token_program_id).Mutable: Yes, the account is written to during initialization.
Constraints: Must be unallocated initially, address must match the PDA derivation, and must be prefunded with enough lamports to be rent-exempt.
wrapped_backpointer_account: The unallocated account that will store the backpointer to the unwrapped mint.Signer: No.
Init: Yes, the instruction initializes this account.
PDA: Yes, derived using
get_wrapped_mint_backpointer_address(wrapped_mint_address).Mutable: Yes, the account is written to during initialization.
Constraints: Must be unallocated initially, address must match the PDA derivation, and must be prefunded with enough lamports to be rent-exempt.
unwrapped_mint_account: The existing mint account being wrapped.Signer: No.
Init: No, it must already exist.
PDA: No.
Mutable: No.
Constraints: Must be an initialized mint account.
system_program_account: The Solana system program.Signer: No.
Init: No.
PDA: No.
Mutable: No.
Constraints: Must be the system program ID (
solana_system_interface::program::id()).
wrapped_token_program_account: The SPL Token program that will manage the wrapped mint (e.g., Token 2022 or the legacy SPL Token program).Signer: No.
Init: No.
PDA: No.
Mutable: No.
Constraints: Must be a valid SPL Token program account.
Additional checks and behavior
PDA derivation validation: It verifies that the
wrapped_mint_accountandwrapped_backpointer_accountaddresses match their expected PDA derivations based on theunwrapped_mint_addressandwrapped_token_program_id, orwrapped_mint_address, respectively.Idempotency: If
idempotentistrue, the instruction skips initialization if the accounts are already initialized and owned correctly (wrapped mint by the token program, backpointer by the program ID). Iffalse, it fails if either account is initialized.Rent checks: It ensures both
wrapped_mint_accountandwrapped_backpointer_accounthave sufficient lamports to meet the rent-exemption threshold for their respective sizes (Mintsize andBackpointersize).Mint initialization: The wrapped mint is initialized with the same decimals and freeze authority as the unwrapped mint. The mint authority is set to a PDA derived from the wrapped mint address (
get_wrapped_mint_authority).Backpointer initialization: The backpointer account is set to store the
unwrapped_mint_address, enabling reverse lookup from wrapped to unwrapped mint.Ownership checks: If idempotent, it verifies that the initialized
wrapped_mint_accountis owned by thewrapped_token_program_accountand thewrapped_backpointer_accountis owned by the program ID.
CPI
Allocate and assign: It calls
allocateandassignvia CPI to allocate space and assign ownership of thewrapped_mint_accountto thewrapped_token_program_accountand thewrapped_backpointer_accountto the program ID. These are signed with the PDA seeds.Initialize mint: It calls
initialize_mint2via CPI to initialize thewrapped_mint_accountas a mint with the specified decimals, mint authority, and freeze authority.
Instruction: Wrap
This instruction wraps tokens by transferring a specified amount of unwrapped tokens from a user's account to an escrow account, then minting an equivalent amount of wrapped tokens to a recipient account. It facilitates the transition of tokens from one program (e.g., legacy SPL Token) to another (e.g., Token 2022).
Input parameters
amount: u64: The number of tokens to wrap. Must be greater than zero.
Accounts
recipient_wrapped_token_account: The token account that will receive the newly minted wrapped tokens.Signer: No.
Init: No, must be preinitialized.
PDA: No.
Mutable: Yes, wrapped tokens are minted to this account.
Constraints: Must be associated with the
wrapped_mint.
wrapped_mint: The mint account for the wrapped tokens.Signer: No.
Init: No, must be preinitialized.
PDA: Yes, derived using
get_wrapped_mint_address(unwrapped_mint_address, wrapped_token_program_id).Mutable: Yes, its supply increases as tokens are minted.
Constraints: Must be initialized and match the PDA derivation.
wrapped_mint_authority: The authority that controls minting for the wrapped mint.Signer: No.
Init: No.
PDA: Yes, derived using
get_wrapped_mint_authority(wrapped_mint_address).Mutable: No.
Constraints: Must match the PDA derivation.
unwrapped_token_program: The SPL Token program managing the unwrapped tokens (e.g., legacy SPL Token or Token 2022).Signer: No.
Init: No.
PDA: No.
Mutable: No.
Constraints: Must be the token program ID for the unwrapped tokens.
wrapped_token_program: The SPL Token program managing the wrapped tokens.Signer: No.
Init: No.
PDA: No.
Mutable: No.
Constraints: Must be the token program ID for the wrapped tokens.
unwrapped_token_account: The user's token account containing the unwrapped tokens to wrap.Signer: No.
Init: No.
PDA: No.
Mutable: Yes, tokens are transferred out of this account.
Constraints: Must be associated with the
unwrapped_mint.
unwrapped_mint: The mint account for the unwrapped tokens.Signer: No.
Init: No.
PDA: No.
Mutable: No.
Constraints: Must be the mint for the unwrapped tokens.
unwrapped_escrow: The escrow account that holds unwrapped tokens after wrapping.Signer: No.
Init: No, must be preinitialized.
PDA: No.
Mutable: Yes, tokens are transferred into this account.
Constraints: Must be owned by the
wrapped_mint_authority.
transfer_authority: The authority that can transfer tokens from theunwrapped_token_account.Signer: Yes, unless it is a multi-sig (then optional).
Init: No.
PDA: No.
Mutable: No.
Constraints: Must have authority to transfer tokens from the
unwrapped_token_account.
multisig_signer_pubkeys: Optional additional signers for a multi-sig transfer authority.Signer: Yes, if present.
Init: No.
PDA: No.
Mutable: No.
Constraints: Required if
transfer_authorityis a multi-sig — the number of signers must match the multi-sig requirements.
Additional checks and behavior
Amount validation: It ensures
amountis greater than zero to prevent invalid wraps.Account validation: It verifies that
wrapped_mintmatches the PDA derived fromunwrapped_mintandwrapped_token_program. It confirmswrapped_mint_authoritymatches the PDA derived fromwrapped_mint.Escrow ownership: It checks that
unwrapped_escrowis owned by thewrapped_mint_authority.Token transfer: It transfers
amountof unwrapped tokens fromunwrapped_token_accounttounwrapped_escrow.Token minting: It mints
amountof wrapped tokens torecipient_wrapped_token_accountusing thewrapped_mint_authority.
CPI
Transfer checked: It calls
invoke_transfer_checkedto transferamountof unwrapped tokens fromunwrapped_token_accounttounwrapped_escrow, using thetransfer_authorityand any multi-sig signers.Mint to: It calls
mint_tovia CPI, signed with thewrapped_mint_authorityPDA seeds, to mintamountof wrapped tokens torecipient_wrapped_token_account.
Instruction: Unwrap
This instruction unwraps tokens by burning a specified amount of wrapped tokens from a user's account and transferring an equivalent amount of unwrapped tokens from an escrow account to a recipient account. It reverses the wrapping process, returning tokens to their original form.
Input parameters
amount: u64: The number of tokens to unwrap. Must be greater than zero.
Accounts
unwrapped_escrow: The escrow account holding unwrapped tokens.Signer: No.
Init: No, must be preinitialized.
PDA: No.
Mutable: Yes, tokens are transferred out of this account.
Constraints: Must be owned by the
wrapped_mint_authority.
recipient_unwrapped_token: The token account that will receive the unwrapped tokens.Signer: No.
Init: No, must be preinitialized.
PDA: No.
Mutable: Yes, tokens are transferred into this account.
Constraints: Must be associated with the
unwrapped_mint.
wrapped_mint_authority: The authority that controls the wrapped mint.Signer: No.
Init: No.
PDA: Yes, derived using
get_wrapped_mint_authority(wrapped_mint_address).Mutable: No.
Constraints: Must match the PDA derivation.
unwrapped_mint: The mint account for the unwrapped tokens.Signer: No.
Init: No.
PDA: No.
Mutable: No.
Constraints: Must be the mint for the unwrapped tokens.
wrapped_token_program: The SPL Token program managing the wrapped tokens.Signer: No.
Init: No.
PDA: No.
Mutable: No.
Constraints: Must be the token program ID for the wrapped tokens.
unwrapped_token_program: The SPL Token program managing the unwrapped tokens.Signer: No.
Init: No.
PDA: No.
Mutable: No.
Constraints: Must be the token program ID for the unwrapped tokens.
wrapped_token_account: The user's token account containing the wrapped tokens to unwrap.Signer: No.
Init: No.
PDA: No.
Mutable: Yes, tokens are burned from this account.
Constraints: Must be associated with the
wrapped_mint.
wrapped_mint: The mint account for the wrapped tokens.Signer: No.
Init: No, must be preinitialized.
PDA: Yes, derived using
get_wrapped_mint_address(unwrapped_mint_address, wrapped_token_program_id).Mutable: Yes, its supply decreases as tokens are burned.
Constraints: Must be initialized and match the PDA derivation.
transfer_authority: The authority that can burn tokens from thewrapped_token_account.Signer: Yes, unless it is a multi-sig (then optional).
Init: No.
PDA: No.
Mutable: No.
Constraints: Must have authority to burn tokens from the
wrapped_token_account.
multisig_signer_pubkeys: Optional additional signers for a multi-sig transfer authority.Signer: Yes, if present.
Init: No.
PDA: No.
Mutable: No.
Constraints: Required if
transfer_authorityis a multi-sig — the number of signers must match the multi-sig requirements.
Additional checks and behavior
Amount validation: It ensures
amountis greater than zero to prevent invalid unwraps.Account validation: It verifies that
wrapped_mintmatches the PDA derived fromunwrapped_mintandwrapped_token_program. It confirmswrapped_mint_authoritymatches the PDA derived fromwrapped_mint.Token burning: It burns
amountof wrapped tokens fromwrapped_token_accountusing thetransfer_authority.Token transfer: It transfers
amountof unwrapped tokens fromunwrapped_escrowtorecipient_unwrapped_tokenusing thewrapped_mint_authority.
CPI
Burn: It calls
burnvia CPI to burnamountof wrapped tokens fromwrapped_token_account, authorized bytransfer_authorityand any multi-sig signers.Transfer checked: It calls
invoke_transfer_checkedto transferamountof unwrapped tokens fromunwrapped_escrowtorecipient_unwrapped_token, signed with thewrapped_mint_authorityPDA seeds.