poseidon_client/transactions/
ed25519_program.rs1use crate::{Instruction, ED25519_PROGRAM_ID};
2use bytemuck::{bytes_of, Pod, Zeroable};
3
4pub const PUBKEY_SERIALIZED_SIZE: usize = 32;
5pub const SIGNATURE_SERIALIZED_SIZE: usize = 64;
6pub const SIGNATURE_OFFSETS_SERIALIZED_SIZE: usize = 14;
7pub const SIGNATURE_OFFSETS_START: usize = 2;
9pub const DATA_START: usize = SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_START;
10
11#[derive(Debug)]
12pub struct Ed25519ProgramCPI {
13 public_key: [u8; 32],
14 signature: [u8; 64],
15}
16
17impl Ed25519ProgramCPI {
18 pub fn new(public_key: [u8; 32]) -> Self {
19 Ed25519ProgramCPI {
20 public_key: public_key,
21 signature: [0u8; 64],
22 }
23 }
24
25 pub fn add_signature(&mut self, signature: [u8; 64]) -> &mut Self {
26 self.signature = signature;
27
28 self
29 }
30
31 pub fn build(&self, message: &[u8]) -> Instruction {
32 let mut instruction_data = Vec::with_capacity(
33 DATA_START
34 .saturating_add(SIGNATURE_SERIALIZED_SIZE)
35 .saturating_add(PUBKEY_SERIALIZED_SIZE)
36 .saturating_add(message.len()),
37 );
38
39 let num_signatures: u8 = 1;
40 let public_key_offset = DATA_START;
41 let signature_offset = public_key_offset.saturating_add(PUBKEY_SERIALIZED_SIZE);
42 let message_data_offset = signature_offset.saturating_add(SIGNATURE_SERIALIZED_SIZE);
43
44 instruction_data.extend_from_slice(bytes_of(&[num_signatures, 0]));
46
47 let offsets = Ed25519SignatureOffsets {
48 signature_offset: signature_offset as u16,
49 signature_instruction_index: u16::MAX,
50 public_key_offset: public_key_offset as u16,
51 public_key_instruction_index: u16::MAX,
52 message_data_offset: message_data_offset as u16,
53 message_data_size: message.len() as u16,
54 message_instruction_index: u16::MAX,
55 };
56
57 instruction_data.extend_from_slice(bytes_of(&offsets));
58
59 debug_assert_eq!(instruction_data.len(), public_key_offset);
60
61 instruction_data.extend_from_slice(&self.public_key);
62
63 debug_assert_eq!(instruction_data.len(), signature_offset);
64
65 instruction_data.extend_from_slice(&self.signature);
66
67 debug_assert_eq!(instruction_data.len(), message_data_offset);
68
69 instruction_data.extend_from_slice(message);
70
71 Instruction {
72 program_id: ED25519_PROGRAM_ID,
73 accounts: vec![],
74 data: instruction_data,
75 }
76 }
77}
78
79use borsh::{BorshDeserialize, BorshSerialize};
80
81#[derive(Default, Debug, Copy, Clone, Zeroable, Pod, BorshDeserialize, BorshSerialize)]
82#[repr(C)]
83pub struct Ed25519SignatureOffsets {
84 signature_offset: u16, signature_instruction_index: u16, public_key_offset: u16, public_key_instruction_index: u16, message_data_offset: u16, message_data_size: u16, message_instruction_index: u16, }