shadow_nft_common/
program_ids.rs1pub use anchor_lang::prelude::Pubkey;
5
6pub const MINTER_PROGRAM: Pubkey = from_str("AzCnwh6WUTNmwn1GAF7VP3bnP6VxHCcgP3iWzgmwAxUu");
8
9pub const STANDARD_PROGRAM: Pubkey = from_str("9fQse1hBRfzWweeUod6WEsR4jZf7hVucetEheCaWooY5");
11
12pub const fn try_from_str(input: &str) -> Result<Pubkey, &'static str> {
13 match decode_pubkey(input.as_bytes()) {
14 Ok(bytes) => Ok(Pubkey::new_from_array(bytes)),
15 Err(e) => Err(e),
16 }
17}
18
19pub const fn from_str(input: &str) -> Pubkey {
20 match try_from_str(input) {
21 Ok(pubkey) => pubkey,
22 Err(_) => panic!("Invalid base58 Pubkey (Solana & Bitcoin Alphabet)"),
23 }
24}
25
26const fn new(base: &[u8; 58]) -> ([u8; 58], [u8; 128]) {
28 let mut encode = [0x00; 58];
29 let mut decode = [0xFF; 128];
30
31 let mut i = 0;
32 while i < encode.len() {
33 encode[i] = base[i];
34 decode[base[i] as usize] = i as u8;
35 i += 1;
36 }
37
38 (encode, decode)
39}
40
41const fn decode_pubkey(input: &[u8]) -> Result<[u8; 32], &'static str> {
45 let mut output = [0; 32];
46
47 const SOLANA_ALPHABET: [u8; 58] =
48 *b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
49 const ENCODE_DECODE: ([u8; 58], [u8; 128]) = new(&SOLANA_ALPHABET);
50 const ENCODE: [u8; 58] = ENCODE_DECODE.0;
51 const DECODE: [u8; 128] = ENCODE_DECODE.1;
52 const ZERO: u8 = ENCODE[0];
53
54 let mut index = 0;
55
56 let len = input.len();
57 let mut i = 0;
58 while i < len {
59 let c = &input[i];
60
61 if *c > 127 {
62 return Err("Input contains non-ASCII");
63 }
64
65 let mut val = DECODE[*c as usize] as usize;
66 if val == 0xFF {
67 return Err("Input contains invalid char");
68 }
69
70 let mut inner_idx = 0;
71 while inner_idx < index {
72 val += (output[inner_idx] as usize) * 58;
73 output[inner_idx] = (val & 0xFF) as u8;
74 val >>= 8;
75 inner_idx += 1;
76 }
77
78 while val > 0 {
79 output[index] = (val & 0xFF) as u8;
80 index += 1;
81 val >>= 8;
82 }
83
84 i += 1;
85 }
86
87 let mut idx = 0;
88 let mut c = input[idx];
89 while c == ZERO {
90 c = input[idx];
91 idx += 1;
92
93 output[index] = 0;
94 index += 1;
95 }
96
97 let mut rev_output = [0; 32];
98 let mut idx = 0;
99 while idx < 32 {
100 rev_output[idx] = output[31 - idx];
101 idx += 1;
102 }
103 Ok(rev_output)
104}
105
106#[test]
107fn test_two_cases() {
108 let input = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS";
109 let expected = Pubkey::new_from_array([
110 218, 7, 92, 178, 255, 94, 198, 129, 118, 19, 222, 83, 11, 105, 42, 135, 53, 71, 119, 105,
111 218, 71, 67, 12, 189, 129, 84, 51, 92, 74, 131, 39,
112 ]);
113 assert_eq!(from_str(input), expected);
114
115 let input = "fBhaujR6iaQkiaDZPsQb5LXLK7y5cRsTaddBV3UWNTq";
116 let expected = Pubkey::new_from_array([
117 9, 200, 43, 65, 225, 51, 167, 33, 30, 3, 37, 197, 7, 16, 205, 73, 131, 203, 140, 102, 102,
118 250, 52, 161, 17, 175, 31, 193, 190, 161, 212, 128,
119 ]);
120 assert_eq!(from_str(input), expected);
121}