smplx_sdk/provider/rpc/
elements.rs1use std::str::FromStr;
2
3use electrsd::bitcoind::bitcoincore_rpc::{Auth, Client, RpcApi};
4
5use serde_json::Value;
6
7use simplicityhl::elements::{Address, AssetId, Txid};
8use simplicityhl::simplicity::bitcoin;
9
10use super::error::RpcError;
11
12use crate::utils::sat2btc;
13
14pub struct ElementsRpc {
15 pub inner: Client,
16 pub auth: Auth,
17 pub url: String,
18}
19
20impl ElementsRpc {
21 pub fn new(url: String, auth: Auth) -> Result<Self, RpcError> {
22 let inner = Client::new(url.as_str(), auth.clone())?;
23 inner.ping()?;
24
25 Ok(Self { inner, auth, url })
26 }
27
28 pub fn get_new_address(&self, label: &str) -> Result<Address, RpcError> {
29 const METHOD: &str = "getnewaddress";
30
31 let addr: Value = self.inner.call(METHOD, &[label.into(), "bech32".to_string().into()])?;
32
33 Ok(Address::from_str(addr.as_str().unwrap()).unwrap())
34 }
35
36 pub fn send_to_address(&self, address: &Address, satoshi: u64, asset: Option<AssetId>) -> Result<Txid, RpcError> {
37 const METHOD: &str = "sendtoaddress";
38
39 let btc = sat2btc(satoshi);
40 let btc = bitcoin::amount::Amount::from_btc(btc)
41 .unwrap()
42 .to_string_in(bitcoin::amount::Denomination::Bitcoin);
43
44 let r = match asset {
45 Some(asset) => self.inner.call::<Value>(
46 METHOD,
47 &[
48 address.to_string().into(),
49 btc.into(),
50 "".into(),
51 "".into(),
52 false.into(),
53 false.into(),
54 1.into(),
55 "UNSET".into(),
56 false.into(),
57 asset.to_string().into(),
58 ],
59 )?,
60 None => self
61 .inner
62 .call::<Value>(METHOD, &[address.to_string().into(), btc.into()])?,
63 };
64
65 Ok(Txid::from_str(r.as_str().unwrap()).unwrap())
66 }
67
68 pub fn rescan_blockchain(&self, start: Option<u64>, stop: Option<u64>) -> Result<(), RpcError> {
69 const METHOD: &str = "rescanblockchain";
70
71 let mut args = Vec::with_capacity(2);
72
73 if start.is_some() {
74 args.push(start.into());
75 }
76
77 if stop.is_some() {
78 args.push(stop.into());
79 }
80
81 self.inner.call::<Value>(METHOD, &args)?;
82
83 Ok(())
84 }
85
86 pub fn generate_blocks(&self, block_num: u32) -> Result<(), RpcError> {
87 const METHOD: &str = "generatetoaddress";
88
89 let address = self.get_new_address("")?.to_string();
90 self.inner.call::<Value>(METHOD, &[block_num.into(), address.into()])?;
91
92 Ok(())
93 }
94
95 pub fn sweep_initialfreecoins(&self) -> Result<(), RpcError> {
96 const METHOD: &str = "sendtoaddress";
97
98 let address = self.get_new_address("")?;
99 self.inner.call::<Value>(
100 METHOD,
101 &[
102 address.to_string().into(),
103 "21".into(),
104 "".into(),
105 "".into(),
106 true.into(),
107 ],
108 )?;
109
110 Ok(())
111 }
112}