Skip to main content

sla_escrow_api/state/
mod.rs

1mod authority_transfer;
2mod bank;
3mod config;
4mod escrow;
5mod payment;
6
7pub use authority_transfer::*;
8pub use bank::*;
9pub use config::*;
10pub use escrow::*;
11pub use payment::*;
12
13use steel::*;
14
15use crate::consts::*;
16
17#[repr(u8)]
18#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)]
19pub enum EscrowAccount {
20    Bank = 100,
21    Config = 101,
22    Escrow = 102,
23    Payment = 103,
24    AuthorityTransfer = 104,
25}
26
27/// Derive the PDA of the bank account.
28pub fn bank_pda() -> (Pubkey, u8) {
29    Pubkey::find_program_address(&[BANK], &crate::id())
30}
31
32/// Derive the PDA of the config account.
33pub fn config_pda() -> (Pubkey, u8) {
34    Pubkey::find_program_address(&[CONFIG], &crate::id())
35}
36
37/// Derive the PDA of an escrow account.
38pub fn escrow_pda(mint: Pubkey, bank: Pubkey) -> (Pubkey, u8) {
39    Pubkey::find_program_address(&[ESCROW, mint.as_ref(), bank.as_ref()], &crate::id())
40}
41
42/// Derive the PDA of a payment account.
43pub fn payment_pda(payment_uid: &str, bank: Pubkey) -> (Pubkey, u8) {
44    let payment_uid = normalize_payment_uid(payment_uid);
45    payment_pda_from_bytes(&payment_uid, bank)
46}
47
48/// Normalize a payment UID string into the canonical 32-byte seed format.
49pub fn normalize_payment_uid(payment_uid: &str) -> [u8; 32] {
50    let mut uid_bytes = [0u8; 32];
51    let uid_str = payment_uid.replace('-', "");
52    let uid_bytes_str = uid_str.as_bytes();
53    let len = uid_bytes_str.len().min(32);
54    uid_bytes[..len].copy_from_slice(&uid_bytes_str[..len]);
55    uid_bytes
56}
57
58/// Derive the PDA of a payment account from its canonical 32-byte seed payload.
59pub fn payment_pda_from_bytes(payment_uid: &[u8; 32], bank: Pubkey) -> (Pubkey, u8) {
60    Pubkey::find_program_address(&[PAYMENT, payment_uid, bank.as_ref()], &crate::id())
61}
62
63/// Derive the PDA of a SOL storage account.
64/// This account holds SOL for escrows and can be used for transfers (no data, just lamports).
65pub fn sol_storage_pda(mint: Pubkey, bank: Pubkey, escrow: Pubkey) -> (Pubkey, u8) {
66    Pubkey::find_program_address(
67        &[SOL_STORAGE, mint.as_ref(), bank.as_ref(), escrow.as_ref()],
68        &crate::id(),
69    )
70}
71
72/// Derive the PDA of an authority transfer proposal.
73pub fn authority_transfer_pda(bank: Pubkey) -> (Pubkey, u8) {
74    Pubkey::find_program_address(&[AUTHORITY_TRANSFER, bank.as_ref()], &crate::id())
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    #[test]
82    fn normalized_and_raw_payment_uid_match() {
83        let bank = Pubkey::new_unique();
84        let uid = "123e4567-e89b-12d3-a456-426614174000";
85
86        let normalized = normalize_payment_uid(uid);
87        let from_str = payment_pda(uid, bank);
88        let from_bytes = payment_pda_from_bytes(&normalized, bank);
89
90        assert_eq!(from_str, from_bytes);
91    }
92}