2023-05-10 23:48:13 -07:00
|
|
|
//! Instructions provided by the ZkToken Proof program
|
2021-09-29 21:45:35 -07:00
|
|
|
pub use crate::instruction::*;
|
|
|
|
use {
|
2023-03-15 15:35:20 -07:00
|
|
|
bytemuck::bytes_of,
|
2021-09-29 21:45:35 -07:00
|
|
|
num_derive::{FromPrimitive, ToPrimitive},
|
|
|
|
num_traits::{FromPrimitive, ToPrimitive},
|
2023-03-15 15:35:20 -07:00
|
|
|
solana_program::{
|
|
|
|
instruction::{AccountMeta, Instruction},
|
|
|
|
pubkey::Pubkey,
|
|
|
|
},
|
2021-09-29 21:45:35 -07:00
|
|
|
};
|
|
|
|
|
2022-05-22 18:00:42 -07:00
|
|
|
#[derive(Clone, Copy, Debug, FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
2021-09-29 21:45:35 -07:00
|
|
|
#[repr(u8)]
|
|
|
|
pub enum ProofInstruction {
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Close a zero-knowledge proof context state.
|
2021-09-29 21:45:35 -07:00
|
|
|
///
|
|
|
|
/// Accounts expected by this instruction:
|
2023-03-15 15:35:20 -07:00
|
|
|
/// 0. `[writable]` The proof context account to close
|
|
|
|
/// 1. `[writable]` The destination account for lamports
|
|
|
|
/// 2. `[signer]` The context account's owner
|
|
|
|
///
|
|
|
|
/// Data expected by this instruction:
|
|
|
|
/// None
|
|
|
|
///
|
|
|
|
CloseContextState,
|
|
|
|
|
|
|
|
/// Verify a close account zero-knowledge proof.
|
|
|
|
///
|
|
|
|
/// This instruction can be configured to optionally create a proof context state account.
|
|
|
|
///
|
|
|
|
/// Accounts expected by this instruction:
|
|
|
|
///
|
|
|
|
/// * Creating a proof context account
|
|
|
|
/// 0. `[writable]` The proof context account
|
|
|
|
/// 1. `[]` The proof context account owner
|
|
|
|
///
|
|
|
|
/// * Otherwise
|
2021-09-29 21:45:35 -07:00
|
|
|
/// None
|
|
|
|
///
|
|
|
|
/// Data expected by this instruction:
|
|
|
|
/// `CloseAccountData`
|
|
|
|
///
|
|
|
|
VerifyCloseAccount,
|
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Verify a withdraw zero-knowledge proof.
|
|
|
|
///
|
|
|
|
/// This instruction can be configured to optionally create a proof context state account.
|
2021-09-29 21:45:35 -07:00
|
|
|
///
|
|
|
|
/// Accounts expected by this instruction:
|
2023-03-15 15:35:20 -07:00
|
|
|
///
|
|
|
|
/// * Creating a proof context account
|
|
|
|
/// 0. `[writable]` The proof context account
|
|
|
|
/// 1. `[]` The proof context account owner
|
|
|
|
///
|
|
|
|
/// * Otherwise
|
2021-09-29 21:45:35 -07:00
|
|
|
/// None
|
|
|
|
///
|
|
|
|
/// Data expected by this instruction:
|
|
|
|
/// `WithdrawData`
|
|
|
|
///
|
|
|
|
VerifyWithdraw,
|
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Verify a withdraw withheld tokens zero-knowledge proof.
|
|
|
|
///
|
|
|
|
/// This instruction can be configured to optionally create a proof context state account.
|
2022-02-17 09:45:07 -08:00
|
|
|
///
|
|
|
|
/// Accounts expected by this instruction:
|
2023-03-15 15:35:20 -07:00
|
|
|
///
|
|
|
|
/// * Creating a proof context account
|
|
|
|
/// 0. `[writable]` The proof context account
|
|
|
|
/// 1. `[]` The proof context account owner
|
|
|
|
///
|
|
|
|
/// * Otherwise
|
2022-02-17 09:45:07 -08:00
|
|
|
/// None
|
|
|
|
///
|
|
|
|
/// Data expected by this instruction:
|
|
|
|
/// `WithdrawWithheldTokensData`
|
|
|
|
///
|
|
|
|
VerifyWithdrawWithheldTokens,
|
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Verify a transfer zero-knowledge proof.
|
|
|
|
///
|
|
|
|
/// This instruction can be configured to optionally create a proof context state account.
|
2021-09-29 21:45:35 -07:00
|
|
|
///
|
|
|
|
/// Accounts expected by this instruction:
|
2023-03-15 15:35:20 -07:00
|
|
|
///
|
|
|
|
/// * Creating a proof context account
|
|
|
|
/// 0. `[writable]` The proof context account
|
|
|
|
/// 1. `[]` The proof context account owner
|
|
|
|
///
|
|
|
|
/// * Otherwise
|
2021-09-29 21:45:35 -07:00
|
|
|
/// None
|
|
|
|
///
|
|
|
|
/// Data expected by this instruction:
|
2021-10-04 13:14:48 -07:00
|
|
|
/// `TransferData`
|
2021-09-29 21:45:35 -07:00
|
|
|
///
|
2021-10-04 13:14:48 -07:00
|
|
|
VerifyTransfer,
|
2022-02-04 05:52:49 -08:00
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Verify a transfer with fee zero-knowledge proof.
|
|
|
|
///
|
|
|
|
/// This instruction can be configured to optionally create a proof context state account.
|
2022-02-04 05:52:49 -08:00
|
|
|
///
|
|
|
|
/// Accounts expected by this instruction:
|
2023-03-15 15:35:20 -07:00
|
|
|
///
|
|
|
|
/// * Creating a proof context account
|
|
|
|
/// 0. `[writable]` The proof context account
|
|
|
|
/// 1. `[]` The proof context account owner
|
|
|
|
///
|
|
|
|
/// * Otherwise
|
2022-02-04 05:52:49 -08:00
|
|
|
/// None
|
|
|
|
///
|
|
|
|
/// Data expected by this instruction:
|
|
|
|
/// `TransferWithFeeData`
|
|
|
|
///
|
|
|
|
VerifyTransferWithFee,
|
2022-10-14 04:15:20 -07:00
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Verify a pubkey validity zero-knowledge proof.
|
|
|
|
///
|
|
|
|
/// This instruction can be configured to optionally create a proof context state account.
|
2022-10-14 04:15:20 -07:00
|
|
|
///
|
|
|
|
/// Accounts expected by this instruction:
|
2023-03-15 15:35:20 -07:00
|
|
|
///
|
|
|
|
/// * Creating a proof context account
|
|
|
|
/// 0. `[writable]` The proof context account
|
|
|
|
/// 1. `[]` The proof context account owner
|
|
|
|
///
|
|
|
|
/// * Otherwise
|
2022-10-14 04:15:20 -07:00
|
|
|
/// None
|
|
|
|
///
|
|
|
|
/// Data expected by this instruction:
|
|
|
|
/// `PubkeyValidityData`
|
|
|
|
///
|
|
|
|
VerifyPubkeyValidity,
|
2021-09-29 21:45:35 -07:00
|
|
|
}
|
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Pubkeys associated with a context state account to be used as parameters to functions.
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
|
|
pub struct ContextStateInfo<'a> {
|
|
|
|
pub context_state_account: &'a Pubkey,
|
|
|
|
pub context_state_authority: &'a Pubkey,
|
|
|
|
}
|
2021-09-29 21:45:35 -07:00
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Create a `CloseContextState` instruction.
|
|
|
|
pub fn close_context_state(
|
|
|
|
context_state_info: ContextStateInfo,
|
|
|
|
destination_account: &Pubkey,
|
|
|
|
) -> Instruction {
|
|
|
|
let accounts = vec![
|
|
|
|
AccountMeta::new(*context_state_info.context_state_account, false),
|
|
|
|
AccountMeta::new(*destination_account, false),
|
|
|
|
AccountMeta::new_readonly(*context_state_info.context_state_authority, true),
|
|
|
|
];
|
2021-09-29 21:45:35 -07:00
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
let data = vec![ToPrimitive::to_u8(&ProofInstruction::CloseContextState).unwrap()];
|
|
|
|
|
|
|
|
Instruction {
|
|
|
|
program_id: crate::zk_token_proof_program::id(),
|
|
|
|
accounts,
|
|
|
|
data,
|
2021-09-29 21:45:35 -07:00
|
|
|
}
|
|
|
|
}
|
2021-10-11 17:38:13 -07:00
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Create a `VerifyCloseAccount` instruction.
|
|
|
|
pub fn verify_close_account(
|
|
|
|
context_state_info: Option<ContextStateInfo>,
|
|
|
|
proof_data: &CloseAccountData,
|
|
|
|
) -> Instruction {
|
|
|
|
ProofInstruction::VerifyCloseAccount.encode_verify_proof(context_state_info, proof_data)
|
2021-10-11 17:38:13 -07:00
|
|
|
}
|
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Create a `VerifyWithdraw` instruction.
|
|
|
|
pub fn verify_withdraw(
|
|
|
|
context_state_info: Option<ContextStateInfo>,
|
|
|
|
proof_data: &WithdrawData,
|
|
|
|
) -> Instruction {
|
|
|
|
ProofInstruction::VerifyWithdraw.encode_verify_proof(context_state_info, proof_data)
|
2021-10-11 17:38:13 -07:00
|
|
|
}
|
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Create a `VerifyWithdrawWithheldTokens` instruction.
|
|
|
|
pub fn verify_withdraw_withheld_tokens(
|
|
|
|
context_state_info: Option<ContextStateInfo>,
|
|
|
|
proof_data: &WithdrawWithheldTokensData,
|
|
|
|
) -> Instruction {
|
|
|
|
ProofInstruction::VerifyWithdrawWithheldTokens
|
|
|
|
.encode_verify_proof(context_state_info, proof_data)
|
2022-02-17 09:45:07 -08:00
|
|
|
}
|
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Create a `VerifyTransfer` instruction.
|
|
|
|
pub fn verify_transfer(
|
|
|
|
context_state_info: Option<ContextStateInfo>,
|
|
|
|
proof_data: &TransferData,
|
|
|
|
) -> Instruction {
|
|
|
|
ProofInstruction::VerifyTransfer.encode_verify_proof(context_state_info, proof_data)
|
2021-10-11 17:38:13 -07:00
|
|
|
}
|
2022-02-04 05:52:49 -08:00
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Create a `VerifyTransferWithFee` instruction.
|
|
|
|
pub fn verify_transfer_with_fee(
|
|
|
|
context_state_info: Option<ContextStateInfo>,
|
|
|
|
proof_data: &TransferWithFeeData,
|
|
|
|
) -> Instruction {
|
|
|
|
ProofInstruction::VerifyTransferWithFee.encode_verify_proof(context_state_info, proof_data)
|
2022-02-04 05:52:49 -08:00
|
|
|
}
|
2022-10-14 04:15:20 -07:00
|
|
|
|
2023-03-15 15:35:20 -07:00
|
|
|
/// Create a `VerifyPubkeyValidity` instruction.
|
|
|
|
pub fn verify_pubkey_validity(
|
|
|
|
context_state_info: Option<ContextStateInfo>,
|
|
|
|
proof_data: &PubkeyValidityData,
|
|
|
|
) -> Instruction {
|
|
|
|
ProofInstruction::VerifyPubkeyValidity.encode_verify_proof(context_state_info, proof_data)
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ProofInstruction {
|
|
|
|
pub fn encode_verify_proof<T, U>(
|
|
|
|
&self,
|
|
|
|
context_state_info: Option<ContextStateInfo>,
|
|
|
|
proof_data: &T,
|
|
|
|
) -> Instruction
|
|
|
|
where
|
|
|
|
T: Pod + ZkProofData<U>,
|
|
|
|
U: Pod,
|
|
|
|
{
|
|
|
|
let accounts = if let Some(context_state_info) = context_state_info {
|
|
|
|
vec![
|
|
|
|
AccountMeta::new(*context_state_info.context_state_account, false),
|
|
|
|
AccountMeta::new_readonly(*context_state_info.context_state_authority, false),
|
|
|
|
]
|
|
|
|
} else {
|
|
|
|
vec![]
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut data = vec![ToPrimitive::to_u8(self).unwrap()];
|
|
|
|
data.extend_from_slice(bytes_of(proof_data));
|
|
|
|
|
|
|
|
Instruction {
|
|
|
|
program_id: crate::zk_token_proof_program::id(),
|
|
|
|
accounts,
|
|
|
|
data,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn instruction_type(input: &[u8]) -> Option<Self> {
|
|
|
|
input
|
|
|
|
.first()
|
|
|
|
.and_then(|instruction| FromPrimitive::from_u8(*instruction))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn proof_data<T, U>(input: &[u8]) -> Option<&T>
|
|
|
|
where
|
|
|
|
T: Pod + ZkProofData<U>,
|
|
|
|
U: Pod,
|
|
|
|
{
|
|
|
|
input
|
|
|
|
.get(1..)
|
|
|
|
.and_then(|data| bytemuck::try_from_bytes(data).ok())
|
|
|
|
}
|
2022-10-14 04:15:20 -07:00
|
|
|
}
|