Add Auth, RpcSyncParams, and RpcConfig

This commit is contained in:
Steve Myers 2022-11-29 18:16:27 -08:00
parent f216417fd2
commit d0cd3b0f38
No known key found for this signature in database
GPG Key ID: 8105A46B22C2D051
4 changed files with 154 additions and 2 deletions

46
Cargo.lock generated
View File

@ -107,6 +107,15 @@ version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "base64-compat"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a8d4d2746f89841e49230dd26917df1876050f95abafafbe34f47cb534b88d7"
dependencies = [
"byteorder",
]
[[package]] [[package]]
name = "bdk" name = "bdk"
version = "0.25.0" version = "0.25.0"
@ -118,6 +127,7 @@ dependencies = [
"bdk-macros", "bdk-macros",
"bip39", "bip39",
"bitcoin", "bitcoin",
"bitcoincore-rpc",
"electrum-client", "electrum-client",
"esplora-client", "esplora-client",
"getrandom", "getrandom",
@ -218,6 +228,30 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "bitcoincore-rpc"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0261b2bb7617e0c91b452a837bbd1291fd34ad6990cb8e3ffc28239cc045b5ca"
dependencies = [
"bitcoincore-rpc-json",
"jsonrpc",
"log",
"serde",
"serde_json",
]
[[package]]
name = "bitcoincore-rpc-json"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c231bea28e314879c5aef240f6052e8a72a369e3c9f9b20d9bfbb33ad18029b2"
dependencies = [
"bitcoin",
"serde",
"serde_json",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@ -567,6 +601,18 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "jsonrpc"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f8423b78fc94d12ef1a4a9d13c348c9a78766dda0cc18817adf0faf77e670c8"
dependencies = [
"base64-compat",
"serde",
"serde_derive",
"serde_json",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"

View File

@ -10,7 +10,7 @@ crate-type = ["staticlib", "cdylib"]
name = "bdkffi" name = "bdkffi"
[dependencies] [dependencies]
bdk = { version = "0.25", features = ["all-keys", "use-esplora-ureq", "sqlite-bundled"] } bdk = { version = "0.25", features = ["all-keys", "use-esplora-ureq", "sqlite-bundled", "rpc"] }
uniffi_macros = { version = "0.21.0", features = ["builtin-bindgen"] } uniffi_macros = { version = "0.21.0", features = ["builtin-bindgen"] }
uniffi = { version = "0.21.0", features = ["builtin-bindgen"] } uniffi = { version = "0.21.0", features = ["builtin-bindgen"] }

View File

@ -45,6 +45,7 @@ enum BdkError {
"Esplora", "Esplora",
"Sled", "Sled",
"Rusqlite", "Rusqlite",
"Rpc",
}; };
dictionary AddressInfo { dictionary AddressInfo {
@ -126,10 +127,33 @@ dictionary EsploraConfig {
u64? timeout; u64? timeout;
}; };
[Enum]
interface Auth {
None();
UserPass(string username, string password);
Cookie(string file);
};
dictionary RpcSyncParams {
u64 start_script_count;
u64 start_time;
boolean force_start_time;
u64 poll_rate_sec;
};
dictionary RpcConfig {
string url;
Auth auth;
Network network;
string wallet_name;
RpcSyncParams? sync_params;
};
[Enum] [Enum]
interface BlockchainConfig { interface BlockchainConfig {
Electrum(ElectrumConfig config); Electrum(ElectrumConfig config);
Esplora(EsploraConfig config); Esplora(EsploraConfig config);
Rpc(RpcConfig config);
}; };
interface Blockchain { interface Blockchain {

View File

@ -7,10 +7,12 @@ use bdk::bitcoin::util::psbt::PartiallySignedTransaction as BdkPartiallySignedTr
use bdk::bitcoin::Sequence; use bdk::bitcoin::Sequence;
use bdk::bitcoin::{Address as BdkAddress, Network, OutPoint as BdkOutPoint, Txid}; use bdk::bitcoin::{Address as BdkAddress, Network, OutPoint as BdkOutPoint, Txid};
use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig}; use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig};
use bdk::blockchain::rpc::Auth as BdkAuth;
use bdk::blockchain::GetBlockHash; use bdk::blockchain::GetBlockHash;
use bdk::blockchain::GetHeight; use bdk::blockchain::GetHeight;
use bdk::blockchain::{ use bdk::blockchain::{
electrum::ElectrumBlockchainConfig, esplora::EsploraBlockchainConfig, ConfigurableBlockchain, electrum::ElectrumBlockchainConfig, esplora::EsploraBlockchainConfig,
rpc::RpcConfig as BdkRpcConfig, rpc::RpcSyncParams as BdkRpcSyncParams, ConfigurableBlockchain,
}; };
use bdk::blockchain::{Blockchain as BdkBlockchain, Progress as BdkProgress}; use bdk::blockchain::{Blockchain as BdkBlockchain, Progress as BdkProgress};
use bdk::database::any::{AnyDatabase, SledDbConfiguration, SqliteDbConfiguration}; use bdk::database::any::{AnyDatabase, SledDbConfiguration, SqliteDbConfiguration};
@ -34,6 +36,7 @@ use std::collections::HashSet;
use std::convert::{From, TryFrom}; use std::convert::{From, TryFrom};
use std::fmt; use std::fmt;
use std::ops::Deref; use std::ops::Deref;
use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use std::sync::{Arc, Mutex, MutexGuard}; use std::sync::{Arc, Mutex, MutexGuard};
@ -134,12 +137,84 @@ pub struct EsploraConfig {
pub timeout: Option<u64>, pub timeout: Option<u64>,
} }
pub enum Auth {
/// No authentication
None,
/// Authentication with username and password, usually [Auth::Cookie] should be preferred
UserPass {
/// Username
username: String,
/// Password
password: String,
},
/// Authentication with a cookie file
Cookie {
/// Cookie file
file: String,
},
}
impl From<Auth> for BdkAuth {
fn from(auth: Auth) -> Self {
match auth {
Auth::None => BdkAuth::None,
Auth::UserPass { username, password } => BdkAuth::UserPass { username, password },
Auth::Cookie { file } => BdkAuth::Cookie {
file: PathBuf::from(file),
},
}
}
}
/// Sync parameters for Bitcoin Core RPC.
///
/// In general, BDK tries to sync `scriptPubKey`s cached in `Database` with
/// `scriptPubKey`s imported in the Bitcoin Core Wallet. These parameters are used for determining
/// how the `importdescriptors` RPC calls are to be made.
pub struct RpcSyncParams {
/// The minimum number of scripts to scan for on initial sync.
pub start_script_count: u64,
/// Time in unix seconds in which initial sync will start scanning from (0 to start from genesis).
pub start_time: u64,
/// Forces every sync to use `start_time` as import timestamp.
pub force_start_time: bool,
/// RPC poll rate (in seconds) to get state updates.
pub poll_rate_sec: u64,
}
impl From<RpcSyncParams> for BdkRpcSyncParams {
fn from(params: RpcSyncParams) -> Self {
BdkRpcSyncParams {
start_script_count: params.start_script_count as usize,
start_time: params.start_time,
force_start_time: params.force_start_time,
poll_rate_sec: params.poll_rate_sec,
}
}
}
/// RpcBlockchain configuration options
pub struct RpcConfig {
/// The bitcoin node url
pub url: String,
/// The bitcoin node authentication mechanism
pub auth: Auth,
/// The network we are using (it will be checked the bitcoin node network matches this)
pub network: Network,
/// The wallet name in the bitcoin node, consider using [crate::wallet::wallet_name_from_descriptor] for this
pub wallet_name: String,
/// Sync parameters
pub sync_params: Option<RpcSyncParams>,
}
/// Type that can contain any of the blockchain configurations defined by the library. /// Type that can contain any of the blockchain configurations defined by the library.
pub enum BlockchainConfig { pub enum BlockchainConfig {
/// Electrum client /// Electrum client
Electrum { config: ElectrumConfig }, Electrum { config: ElectrumConfig },
/// Esplora client /// Esplora client
Esplora { config: EsploraConfig }, Esplora { config: EsploraConfig },
/// Bitcoin Core RPC client
Rpc { config: RpcConfig },
} }
/// A wallet transaction /// A wallet transaction
@ -200,6 +275,13 @@ impl Blockchain {
timeout: config.timeout, timeout: config.timeout,
}) })
} }
BlockchainConfig::Rpc { config } => AnyBlockchainConfig::Rpc(BdkRpcConfig {
url: config.url,
auth: config.auth.into(),
network: config.network,
wallet_name: config.wallet_name,
sync_params: config.sync_params.map(|p| p.into()),
}),
}; };
let blockchain = AnyBlockchain::from_config(&any_blockchain_config)?; let blockchain = AnyBlockchain::from_config(&any_blockchain_config)?;
Ok(Self { Ok(Self {