nash_protocol/types/blockchain/
eth.rs1use super::super::{Amount, Asset, AssetOrCrosschain, AssetofPrecision, Nonce, OrderRate, Rate};
4use super::{bigdecimal_to_nash_u64, nash_u64_to_bigdecimal};
5use crate::errors::{ProtocolError, Result};
6use byteorder::{BigEndian, ReadBytesExt};
7#[cfg(feature = "secp256k1")]
8use nash_mpc::curves::secp256_k1::Secp256k1Point;
9#[cfg(feature = "k256")]
10use nash_mpc::curves::secp256_k1_rust::Secp256k1Point;
11use nash_mpc::curves::traits::ECPoint;
12use sha3::{Digest, Keccak256};
13
14impl Rate {
15 pub fn to_be_bytes(&self, order_precision: u32, fee_precision: u32) -> Result<Vec<u8>> {
17 let zero_bytes = (0 as f64).to_be_bytes();
18 let bytes = match self {
19 Self::OrderRate(rate) => rate.to_be_bytes(order_precision)?.to_vec(),
20 Self::FeeRate(rate) => rate.to_be_bytes(fee_precision)?.to_vec(),
21 Self::MinOrderRate | Self::MinFeeRate => zero_bytes.to_vec(),
22 Self::MaxOrderRate => [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF].to_vec(),
23 Self::MaxFeeRate => [0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xD0, 0x90].to_vec(),
25 };
26 Ok(bytes)
27 }
28
29 pub fn from_be_bytes(bytes: [u8; 8]) -> Result<Self> {
31 Ok(Self::OrderRate(OrderRate::from_be_bytes(bytes)?))
32 }
33}
34
35impl OrderRate {
36 pub fn to_be_bytes(&self, precision: u32) -> Result<Vec<u8>> {
39 let precision = precision.max(8);
40 let bytes = bigdecimal_to_nash_u64(&self.to_bigdecimal(), precision)?.to_be_bytes();
41 let bytes = bytes.iter().cloned().take(precision as usize).collect();
42 Ok(bytes)
43 }
44
45 pub fn from_be_bytes(bytes: [u8; 8]) -> Result<Self> {
47 let num = u64::from_be_bytes(bytes);
48 let big_num = nash_u64_to_bigdecimal(num, 8);
49 Ok(OrderRate::from_bigdecimal(big_num))
50 }
51}
52
53impl Amount {
54 pub fn to_be_bytes(&self) -> Result<[u8; 8]> {
56 let bytes = bigdecimal_to_nash_u64(&self.to_bigdecimal(), 8)?.to_be_bytes();
57 Ok(bytes)
58 }
59 pub fn from_bytes(bytes: [u8; 8], precision: u32) -> Result<Self> {
61 let value = nash_u64_to_bigdecimal(
62 (&bytes[..])
63 .read_u64::<BigEndian>()
64 .map_err(|_| ProtocolError("Could not convert bytes to u64"))?,
65 precision,
66 );
67 Ok(Self { value, precision })
68 }
69}
70
71impl Nonce {
72 pub fn to_be_bytes(&self) -> [u8; 4] {
74 match self {
75 Self::Value(value) => value.to_be_bytes(),
76 Self::Crosschain => Nonce::crosschain().to_be_bytes(),
77 }
78 }
79 pub fn from_be_bytes(bytes: [u8; 4]) -> Result<Self> {
81 let value = (&bytes[..])
82 .read_u32::<BigEndian>()
83 .map_err(|_| ProtocolError("Could not read bytes into u32 for Nonce"))?;
84 if value == Nonce::crosschain() {
85 Ok(Nonce::Crosschain)
86 } else {
87 Ok(Nonce::Value(value))
88 }
89 }
90}
91
92impl Asset {
93 pub fn to_eth_bytes(&self) -> [u8; 2] {
96 match self {
97 Self::ETH => [0x00, 0x00],
98 Self::BAT => [0x00, 0x01],
99 Self::OMG => [0x00, 0x02],
100 Self::USDC => [0x00, 0x03],
101 Self::USDT => [0x00, 0x11],
102 Self::ZRX => [0x00, 0x04],
103 Self::LINK => [0x00, 0x05],
104 Self::QNT => [0x00, 0x06],
105 Self::RLC => [0x00, 0x0a],
106 Self::ANT => [0x00, 0x0e],
107 Self::TRAC => [0x00, 0x14],
108 Self::GUNTHY => [0x00, 0x15],
109 Self::NOIA => [0x00, 0x19],
110 Self::BTC => [0xff, 0xff],
111 Self::NEO => [0xff, 0xff],
112 Self::GAS => [0xff, 0xff],
113 Self::NNN => [0xff, 0xff],
114 }
115 }
116
117 pub fn from_eth_bytes(bytes: [u8; 2]) -> Result<Self> {
119 match bytes {
120 [0x00, 0x00] => Ok(Self::ETH),
121 [0x00, 0x01] => Ok(Self::BAT),
122 [0x00, 0x02] => Ok(Self::OMG),
123 [0x00, 0x03] => Ok(Self::USDC),
124 [0x00, 0x11] => Ok(Self::USDT),
125 [0x00, 0x04] => Ok(Self::ZRX),
126 [0x00, 0x05] => Ok(Self::LINK),
127 [0x00, 0x06] => Ok(Self::QNT),
128 [0x00, 0x0a] => Ok(Self::RLC),
129 [0x00, 0x0e] => Ok(Self::ANT),
130 [0x00, 0x14] => Ok(Self::TRAC),
131 [0x00, 0x15] => Ok(Self::GUNTHY),
132 [0x00, 0x19] => Ok(Self::NOIA),
133 _ => Err(ProtocolError("Invalid Asset ID in bytes")),
134 }
135 }
136}
137
138impl AssetOrCrosschain {
139 pub fn to_eth_bytes(&self) -> [u8; 2] {
142 match self {
143 Self::Crosschain => [0xff, 0xff],
144 Self::Asset(asset) => asset.to_eth_bytes(),
145 }
146 }
147 pub fn from_eth_bytes(bytes: [u8; 2]) -> Result<Self> {
150 Ok(match bytes {
151 [0xff, 0xff] => Self::Crosschain,
152 _ => Self::Asset(Asset::from_eth_bytes(bytes)?),
153 })
154 }
155}
156
157impl From<Asset> for AssetOrCrosschain {
158 fn from(asset: Asset) -> Self {
159 Self::Asset(asset)
160 }
161}
162
163impl From<AssetofPrecision> for AssetOrCrosschain {
164 fn from(asset_prec: AssetofPrecision) -> Self {
165 Self::Asset(asset_prec.asset)
166 }
167}
168
169#[derive(Clone, Debug, PartialEq)]
172pub struct Address {
173 pub(crate) inner: [u8; 20],
174}
175
176impl Address {
177 pub fn new(s: &str) -> Result<Self> {
183 let hex_bytes = hex::decode(s)
184 .map_err(|_| ProtocolError("Could not decode string to hex in ETH address"))?;
185 match hex_bytes.len() {
186 20 => {
187 let mut inner: [u8; 20] = [0; 20];
188 inner[..20].copy_from_slice(&hex_bytes[..20]);
189 Ok(Self { inner })
190 }
191 _ => Err(ProtocolError("Invalid address, string hex length != 20")),
192 }
193 }
194
195 pub fn to_bytes(&self) -> [u8; 20] {
197 self.inner
198 }
199
200 pub fn from_bytes(bytes: [u8; 20]) -> Result<Self> {
202 let _to_validate = hex::encode(bytes);
203 Ok(Self { inner: bytes })
205 }
206}
207
208#[derive(Clone, Debug, PartialEq)]
210pub struct PublicKey {
211 inner: Secp256k1Point,
212}
213
214impl PublicKey {
215 pub fn new(hex_str: &str) -> Result<Self> {
217 let inner = Secp256k1Point::from_hex(hex_str).map_err(|_| {
218 ProtocolError("Could not create public key (Secp256r1Point) from hex string")
219 })?;
220 Ok(Self { inner })
221 }
222
223 pub fn to_address(&self) -> Address {
225 let pk_bytes = &self.inner.to_vec()[1..];
227 let hash: [u8; 32] = Keccak256::digest(&pk_bytes).into();
229 Address::new(&hex::encode(&hash[12..])).unwrap()
231 }
232 pub fn to_hex(&self) -> String {
234 self.inner.to_hex()
235 }
236}
237
238#[cfg(test)]
239mod tests {
240 use super::{Address, PublicKey};
241 use crate::types::{Amount, Asset, Nonce};
242
243 #[test]
244 fn test_serialize_and_deserialize() {
245 let nonce = Nonce::Value(35);
246 assert_eq!(nonce, Nonce::from_be_bytes(nonce.to_be_bytes()).unwrap());
247 let address = Address::new("D58547F100B67BB99BBE8E94523B6BB4FDA76954").unwrap();
248 assert_eq!(address, Address::from_bytes(address.to_bytes()).unwrap());
249 let asset = Asset::ETH;
250 assert_eq!(asset, Asset::from_eth_bytes(asset.to_eth_bytes()).unwrap());
251 let amount = Amount::new("45", 8).unwrap();
252 assert_eq!(
253 amount,
254 Amount::from_bytes(amount.to_be_bytes().unwrap(), 8).unwrap()
255 );
256 }
257
258 #[test]
259 fn test_pk_to_addr() {
260 assert_eq!(
261 PublicKey::new("04be641c583207c310739a23973fb7cb7336d2b835517ede791e9fa53fa5b0fc46390ebb4dab62e8b01352f37308dbff1512615856bffd3c752db95737d3bc93a4").unwrap().to_address(),
262 Address::new("55D16CA38DFB219141AB6617B2872B978AF84702").unwrap(),
263 );
264 assert_eq!(
265 PublicKey::new("0475f8a0f4eda35b7194d265df33720cf80164f196765980fae29795f713b340d93a0fa0632f56b265450c8d9d3a631c9a79089a57f40316bb3b66a09c51ba9fcb").unwrap().to_address(),
266 Address::new("CA7E5135E04371D048A78C4592BA3B61A984B563").unwrap(),
267 );
268 }
269}