1use std::convert::TryInto;
2
3use hex_literal::hex;
4use rust_decimal::Decimal;
5use secp256k1::{
6 rand::rngs::OsRng, All, Error as Secp256k1Error, KeyPair as Secp256k1KeyPair, Message,
7 PublicKey as Secp256k1PublicKey, Secp256k1, SecretKey as Secp256k1SecretKey,
8};
9use serde::Serialize;
10use serde_json::json;
11use serde_xrpl::types::Hash256;
12
13use crate::transaction::types::{PaymentChannelClaim, Transaction};
14use crate::types::account::AccountInfoRequest;
15use crate::types::fee::FeeRequest;
16use crate::types::ledger::LedgerRequest;
17use crate::types::{BigInt, CurrencyAmount};
18use crate::{Error as XRPLError, Transport, XRPL};
19use lazy_static::lazy_static;
20use ripemd::{Digest, Ripemd160};
21use sha2::{Sha256, Sha512};
22
23lazy_static! {
24 static ref DEFAULT_MAX_FEE: BigInt = BigInt(100);
25 static ref DEFAULT_LEDGER_OFFSET: u32 = 20; }
27
28static FAMILY_SEED: u8 = 0x21;
29
30#[derive(Debug)]
31pub enum Error {
32 InvalidSecret(bs58::decode::Error),
33 XRPLError(XRPLError),
34 SequenceRequired,
35 FeeRequired,
36 FeeAboveMax,
37 InvalidDrops,
38 Secp256k1Error(Secp256k1Error),
39 LastLedgerSequenceRequired,
40}
41
42impl From<XRPLError> for Error {
43 fn from(e: XRPLError) -> Self {
44 Self::XRPLError(e)
45 }
46}
47
48pub enum Signer {
49 Secp256k1(Secp256k1<All>),
50}
51
52pub enum KeyPair {
53 Secp256k1(Secp256k1KeyPair),
54}
55
56pub struct Wallet {
57 keypair: KeyPair,
58 sequence: Option<u32>,
59 fee: Option<BigInt>,
60 max_fee: BigInt,
61 ledger_offset: u32,
62 secret: String,
63}
64
65impl Wallet {
66 pub fn new_random() -> Result<Self, Error> {
67 let secret = generate_random_secret()?;
68 Self::from_secret(&secret)
69 }
70 pub fn address(&self) -> String {
71 let sha = sha256(match &self.keypair {
72 KeyPair::Secp256k1(keypair) => {
73 hex::decode(&Secp256k1PublicKey::from_keypair(&keypair).to_string()).unwrap()
74 }
75 });
76 let rip = ripemd160(&sha);
77 let prefixed = [vec![0x00], rip].concat();
78 let chk = double_sha256(&prefixed)[0..4].to_vec();
79 bs58::encode([prefixed, chk].concat())
80 .with_alphabet(bs58::Alphabet::RIPPLE)
81 .into_string()
82 }
83 pub fn from_secret(secret: &str) -> Result<Self, Error> {
84 let keypair = keypair_from_secret(secret)?;
85 Ok(Self {
86 keypair,
87 sequence: None,
88 fee: None,
89 max_fee: DEFAULT_MAX_FEE.to_owned(),
90 ledger_offset: DEFAULT_LEDGER_OFFSET.to_owned(),
91 secret: secret.to_owned(),
92 })
93 }
94 pub fn set_sequence(&mut self, sequence: u32) {
95 self.sequence = Some(sequence);
96 }
97 pub fn set_fee(&mut self, drops: BigInt) {
98 self.fee = Some(drops);
99 }
100 pub fn set_max_fee(&mut self, drops: BigInt) {
101 self.max_fee = drops;
102 }
103 pub fn set_ledger_offset<T: TryInto<BigInt>>(
104 &mut self,
105 ledger_offset: u32,
106 ) -> Result<(), Error> {
107 self.ledger_offset = ledger_offset;
108 Ok(())
109 }
110 pub async fn fill_and_sign<T: Transport>(
111 &mut self,
112 tx: &mut Transaction,
113 xrpl: &XRPL<T>,
114 ) -> Result<String, Error> {
115 self.auto_fill_fields(tx, xrpl).await?;
116 self.sign(tx)
117 }
118 pub async fn auto_fill_fields<T: Transport>(
119 &mut self,
120 tx: &mut Transaction,
121 xrpl: &XRPL<T>,
122 ) -> Result<(), Error> {
123 if tx.flags.is_none() {
124 tx.flags = Some(2147483648u32);
126 }
127 tx.account = self.address();
129 if self.sequence.is_none() {
131 let mut req = AccountInfoRequest::default();
132 req.account = self.address();
133 let account_info = xrpl.account_info(req).await?;
134 self.sequence = Some(account_info.account_data.sequence);
135 }
136 if let Some(sequence) = &mut self.sequence {
138 tx.sequence = *sequence;
139 *sequence += 1;
140 } else {
141 return Err(Error::SequenceRequired);
142 }
143 if self.fee.is_none() {
145 let req = FeeRequest::default();
146 let fee = xrpl.fee(req).await?;
147 if let CurrencyAmount::XRP(drops) = fee.drops.open_ledger_fee {
148 self.fee = Some(drops);
149 }
150 }
151 tx.fee = self.fee.as_ref().ok_or(Error::FeeRequired)?.clone();
153 if tx.fee > self.max_fee {
155 return Err(Error::FeeAboveMax);
156 }
157 let ledger_req = LedgerRequest::default();
159 let ledger = xrpl.ledger(ledger_req).await?;
160 tx.last_ledger_sequence = ledger
161 .ledger
162 .ledger_info
163 .ledger_index
164 .ok_or(Error::LastLedgerSequenceRequired)?
165 .0
166 + self.ledger_offset;
167 Ok(())
168 }
169 pub fn sign(&self, tx: &mut Transaction) -> Result<String, Error> {
172 match &self.keypair {
173 KeyPair::Secp256k1(keypair) => {
174 let secp = Secp256k1::new();
175 tx.signing_pub_key = Secp256k1PublicKey::from_keypair(keypair).to_string();
176 let tx_blob_for_signing =
177 serde_xrpl::ser::to_bytes_for_signing(&serde_json::to_value(&tx).unwrap())
178 .unwrap();
179 let mut mh = Sha512::new();
180 mh.update(&tx_blob_for_signing);
181 let mhh = mh.finalize()[..32].to_vec();
182 let message = Message::from_slice(&mhh).unwrap();
183 let sig = secp.sign_ecdsa(&message, &Secp256k1SecretKey::from_keypair(keypair));
184 tx.txn_signature = Some(sig.to_string().to_uppercase());
185 }
186 }
187 let tx_blob = serde_xrpl::ser::to_bytes(&serde_json::to_value(&tx).unwrap()).unwrap();
188 let mut th = Sha512::new();
189 th.update(&[hex!("54584e00").to_vec(), tx_blob.to_vec()].concat());
190 let transaction_hash = th.finalize()[..32].to_vec();
191 tx.hash = Some(hex::encode(transaction_hash).to_uppercase());
192 Ok(hex::encode(tx_blob).to_uppercase())
193 }
194 pub fn public_key(&self) -> String {
195 match &self.keypair {
196 KeyPair::Secp256k1(keypair) => {
197 return Secp256k1PublicKey::from_keypair(keypair).to_string();
198 }
199 }
200 }
201 pub fn private_key(&self) -> String {
202 match &self.keypair {
203 KeyPair::Secp256k1(keypair) => return keypair.display_secret().to_string(),
204 }
205 }
206 pub fn sign_message<T: Serialize>(&self, message: T) -> Result<String, Error> {
207 match &self.keypair {
208 KeyPair::Secp256k1(keypair) => {
209 let secp = Secp256k1::new();
210 let message_blob_for_signing =
211 serde_xrpl::ser::to_bytes_for_claim(&serde_json::to_value(&message).unwrap())
212 .unwrap();
213 let mut mh = Sha512::new();
214 mh.update(&message_blob_for_signing);
215 let mhh = mh.finalize()[..32].to_vec();
216 let message = Message::from_slice(&mhh).unwrap();
217 let sig = secp.sign_ecdsa(&message, &Secp256k1SecretKey::from_keypair(keypair));
218 Ok(sig.to_string().to_uppercase())
219 }
220 }
221 }
222 pub fn sign_payment_channel_claim(
223 &self,
224 channel: String,
225 amount: BigInt,
226 ) -> Result<String, Error> {
227 match &self.keypair {
228 KeyPair::Secp256k1(keypair) => {
229 let secp = Secp256k1::new();
230 let mut mh = Sha512::new();
231 let prefix = hex!("434c4d00").to_vec();
232 let channel_bytes = Hash256(channel).to_bytes();
233 let amount_bytes = amount.0.to_be_bytes().to_vec();
234 mh.update([prefix, channel_bytes, amount_bytes].concat());
235 let mhh = mh.finalize()[..32].to_vec();
236 let message = Message::from_slice(&mhh).unwrap();
237 let sig = secp.sign_ecdsa(&message, &Secp256k1SecretKey::from_keypair(keypair));
238 Ok(sig.to_string().to_uppercase())
239 }
240 }
241 }
242}
243
244fn decode_secret(secret: &str) -> Result<Vec<u8>, Error> {
245 Ok(bs58::decode(secret.as_bytes())
246 .with_alphabet(bs58::alphabet::Alphabet::RIPPLE)
247 .with_check(None)
248 .into_vec()
249 .map_err(|e| Error::InvalidSecret(e))?[1..]
250 .to_vec())
251}
252
253fn generate_random_secret() -> Result<String, Error> {
254 let r: [u8; 16] = rand::random();
255 Ok(bs58::encode([vec![FAMILY_SEED], r.to_vec()].concat())
256 .with_alphabet(bs58::alphabet::Alphabet::RIPPLE)
257 .with_check()
258 .into_string())
259}
260
261fn keypair_from_secret(secret: &str) -> Result<KeyPair, Error> {
262 let decoded_secret = bs58::decode(secret.as_bytes())
263 .with_alphabet(bs58::alphabet::Alphabet::RIPPLE)
264 .with_check(None)
265 .into_vec()
266 .unwrap()[1..]
267 .to_vec();
268 let secp = Secp256k1::new();
269 let mut sh = Sha512::new();
270 sh.update([decoded_secret.to_vec(), 0u32.to_be_bytes().to_vec()].concat());
271 let secret = sh.finalize();
272 let root_secret_key =
273 Secp256k1SecretKey::from_slice(&secret[..32]).map_err(|e| Error::Secp256k1Error(e))?;
274 let mut intermediate_hash = Sha512::new();
275 intermediate_hash.update(
276 [
277 Secp256k1PublicKey::from_secret_key(&secp, &root_secret_key)
278 .serialize()
279 .to_vec(),
280 0u32.to_be_bytes().to_vec(),
281 0u32.to_be_bytes().to_vec(),
282 ]
283 .concat(),
284 );
285 let mut account_secret_key =
286 Secp256k1SecretKey::from_slice(&intermediate_hash.finalize()[..32])
287 .map_err(|e| Error::Secp256k1Error(e))?;
288 account_secret_key
289 .add_assign(&root_secret_key.serialize_secret())
290 .map_err(|e| Error::Secp256k1Error(e))?;
291 let account_keypair = Secp256k1KeyPair::from_secret_key(&secp, account_secret_key);
292 Ok(KeyPair::Secp256k1(account_keypair))
293}
294
295fn sha256(i: impl AsRef<[u8]>) -> Vec<u8> {
296 let mut h = Sha256::new();
297 h.update(i);
298 h.finalize().to_vec()
299}
300
301fn double_sha256(i: impl AsRef<[u8]>) -> Vec<u8> {
302 sha256(&sha256(i))
303}
304
305fn ripemd160(i: impl AsRef<[u8]>) -> Vec<u8> {
306 let mut r = Ripemd160::new();
307 r.update(&i);
308 r.finalize().to_vec()
309}