1use bech32::primitives::decode::CheckedHrpstring;
2use bech32::{encode, Bech32, Bech32m, Hrp};
3use cosmwasm_std::testing::MockApi;
4use cosmwasm_std::{
5 Addr, Api, CanonicalAddr, HashFunction, RecoverPubkeyError, StdError, StdResult,
6 VerificationError,
7};
8use sha2::{Digest, Sha256};
9
10pub struct MockApiBech<T> {
11 api: MockApi,
12 prefix: &'static str,
13 _phantom_data: std::marker::PhantomData<T>,
14}
15
16impl<T: bech32::Checksum> MockApiBech<T> {
17 pub fn new(prefix: &'static str) -> Self {
20 Self {
21 api: MockApi::default(),
22 prefix,
23 _phantom_data: std::marker::PhantomData,
24 }
25 }
26}
27
28impl<T: bech32::Checksum + 'static> Api for MockApiBech<T> {
29 fn addr_validate(&self, input: &str) -> StdResult<Addr> {
30 self.addr_humanize(&self.addr_canonicalize(input)?)
31 }
32
33 fn addr_canonicalize(&self, input: &str) -> StdResult<CanonicalAddr> {
34 if let Ok(s) = CheckedHrpstring::new::<T>(input) {
35 if s.hrp().to_string() == self.prefix {
36 return Ok(s.byte_iter().collect::<Vec<u8>>().into());
37 }
38 }
39 Err(StdError::msg("Invalid input"))
40 }
41
42 fn addr_humanize(&self, canonical: &CanonicalAddr) -> StdResult<Addr> {
43 let hrp = Hrp::parse(self.prefix)?;
44 if let Ok(encoded) = encode::<T>(hrp, canonical.as_slice()) {
45 Ok(Addr::unchecked(encoded))
46 } else {
47 Err(StdError::msg("Invalid canonical address"))
48 }
49 }
50
51 fn secp256k1_verify(
52 &self,
53 message_hash: &[u8],
54 signature: &[u8],
55 public_key: &[u8],
56 ) -> Result<bool, VerificationError> {
57 self.api
58 .secp256k1_verify(message_hash, signature, public_key)
59 }
60
61 fn secp256k1_recover_pubkey(
62 &self,
63 message_hash: &[u8],
64 signature: &[u8],
65 recovery_param: u8,
66 ) -> Result<Vec<u8>, RecoverPubkeyError> {
67 self.api
68 .secp256k1_recover_pubkey(message_hash, signature, recovery_param)
69 }
70
71 fn bls12_381_aggregate_g1(&self, g1s: &[u8]) -> Result<[u8; 48], VerificationError> {
72 self.api.bls12_381_aggregate_g1(g1s)
73 }
74
75 fn bls12_381_aggregate_g2(&self, g2s: &[u8]) -> Result<[u8; 96], VerificationError> {
76 self.api.bls12_381_aggregate_g2(g2s)
77 }
78
79 fn bls12_381_pairing_equality(
80 &self,
81 ps: &[u8],
82 qs: &[u8],
83 r: &[u8],
84 s: &[u8],
85 ) -> Result<bool, VerificationError> {
86 self.api.bls12_381_pairing_equality(ps, qs, r, s)
87 }
88
89 fn bls12_381_hash_to_g1(
90 &self,
91 hash_function: HashFunction,
92 msg: &[u8],
93 dst: &[u8],
94 ) -> Result<[u8; 48], VerificationError> {
95 self.api.bls12_381_hash_to_g1(hash_function, msg, dst)
96 }
97
98 fn bls12_381_hash_to_g2(
99 &self,
100 hash_function: HashFunction,
101 msg: &[u8],
102 dst: &[u8],
103 ) -> Result<[u8; 96], VerificationError> {
104 self.api.bls12_381_hash_to_g2(hash_function, msg, dst)
105 }
106
107 fn secp256r1_verify(
108 &self,
109 message_hash: &[u8],
110 signature: &[u8],
111 public_key: &[u8],
112 ) -> Result<bool, VerificationError> {
113 self.api
114 .secp256r1_verify(message_hash, signature, public_key)
115 }
116
117 fn secp256r1_recover_pubkey(
118 &self,
119 message_hash: &[u8],
120 signature: &[u8],
121 recovery_param: u8,
122 ) -> Result<Vec<u8>, RecoverPubkeyError> {
123 self.api
124 .secp256r1_recover_pubkey(message_hash, signature, recovery_param)
125 }
126
127 fn ed25519_verify(
128 &self,
129 message: &[u8],
130 signature: &[u8],
131 public_key: &[u8],
132 ) -> Result<bool, VerificationError> {
133 self.api.ed25519_verify(message, signature, public_key)
134 }
135
136 fn ed25519_batch_verify(
137 &self,
138 messages: &[&[u8]],
139 signatures: &[&[u8]],
140 public_keys: &[&[u8]],
141 ) -> Result<bool, VerificationError> {
142 self.api
143 .ed25519_batch_verify(messages, signatures, public_keys)
144 }
145
146 fn debug(&self, message: &str) {
147 self.api.debug(message)
148 }
149}
150
151impl<T: bech32::Checksum> MockApiBech<T> {
152 pub fn addr_make(&self, input: &str) -> Addr {
159 match Hrp::parse(self.prefix) {
160 Ok(hrp) => Addr::unchecked(encode::<T>(hrp, Sha256::digest(input).as_slice()).unwrap()),
161 Err(reason) => panic!("Generating address failed with reason: {reason}"),
162 }
163 }
164}
165
166pub type MockApiBech32 = MockApiBech<Bech32>;
171
172pub type MockApiBech32m = MockApiBech<Bech32m>;