riftenlabs-indexer/src/electrum.rs

81 lines
2.5 KiB
Rust
Raw Normal View History

2024-02-14 11:11:16 +01:00
// Copyright (C) 2024 Riften Labs AS
//
// This software is licensed under the GNU Affero General Public License (AGPL), version 3.0 or later.
// A copy of the license can be found in the LICENSE file or at https://www.gnu.org/licenses/agpl-3.0.html
2024-02-16 09:11:40 +01:00
use std::{collections::HashSet, str::FromStr};
2024-02-14 11:11:16 +01:00
use anyhow::{Context, Result};
2024-02-16 09:11:40 +01:00
use bitcoin_hashes::hex::ToHex;
use bitcoincash::{consensus::deserialize, BlockHeader, Transaction, Txid};
use electrum_client_netagnostic::{Client, ElectrumApi, Param};
2024-02-16 09:11:40 +01:00
use log::info;
use riftenlabs_defi::cauldron::V2_CONTRACT_TEMPLATE;
use serde_json::{json, Value};
2024-02-14 11:11:16 +01:00
/// Fetch blockchain tip from electrum server
pub fn electrum_get_tip(client: &Client) -> Result<(BlockHeader, u64)> {
let tip: Value =
serde_json::from_str(&client.raw_call("blockchain.headers.tip", [])?.to_string())?;
let height = tip
.get("height")
.context("no height")?
.as_i64()
.context("no int")?;
let header = tip
.get("hex")
.context("no hex in header")?
.as_str()
.context("hex not str")?;
Ok((deserialize(&hex::decode(header)?)?, height as u64))
}
2024-02-16 09:11:40 +01:00
/// Fetch cauldron mempool transactions
pub fn electrum_fetch_mempool(client: &Client) -> Result<HashSet<Txid>> {
let filter = json!({
"scriptsig": hex::encode(&V2_CONTRACT_TEMPLATE[(V2_CONTRACT_TEMPLATE.len() - 43)..])
});
let response = client.raw_call("mempool.get", [Param::Value(filter)])?;
let txs = response
.get("transactions")
.context("no txs in mempool get")?
.as_array()
.context("txs not array")?;
Ok(txs
.iter()
.filter_map(|txid| match txid.as_str() {
Some(txid_hex) => match Txid::from_str(txid_hex) {
Ok(txid) => Some(txid),
Err(e) => {
info!("Txid not hex: {}", e);
None
}
},
None => {
info!("Failed to read txid from electrum response {:?}", txid);
None
}
})
.collect())
}
/// Fetch blockchain tip from electrum server
pub fn electrum_get_tx(client: &Client, txid: &Txid) -> Result<Transaction> {
let tx: Value = serde_json::from_str(
&client
.raw_call("blockchain.transaction.get", [Param::String(txid.to_hex())])?
.to_string(),
)?;
let tx: Transaction = deserialize(
&hex::decode(tx.as_str().context("no tx in response")?).context("failed to decode tx")?,
)?;
Ok(tx)
}