Skip to content

Commit

Permalink
lib: add Amount, Network
Browse files Browse the repository at this point in the history
  • Loading branch information
rustaceanrob committed Aug 16, 2024
1 parent 9567e6b commit eb01b76
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 6 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ default = ["uniffi/cli"]
[dependencies]
bitcoin = { version = "0.32.2" }
uniffi = { version = "=0.28.0" }
thiserror = "1.0.58"

[build-dependencies]
uniffi = { version = "=0.28.0", features = ["build"] }
38 changes: 38 additions & 0 deletions src/bitcoin.udl
Original file line number Diff line number Diff line change
@@ -1,7 +1,45 @@
namespace bitcoin {};

// ------------------------------------------------------------------------
// Core types
// ------------------------------------------------------------------------

interface Script {
constructor(sequence<u8> raw_output_script);

sequence<u8> to_bytes();
};

interface Amount {
[Name=from_sat]
constructor(u64 from_sat);

[Name=from_btc, Throws=ParseAmountError]
constructor(f64 from_btc);

u64 to_sat();

f64 to_btc();
};

[NonExhaustive]
enum Network {
"Bitcoin",
"Testnet",
"Signet",
"Regtest",
};

// ------------------------------------------------------------------------
// Errors
// ------------------------------------------------------------------------

[Error]
interface ParseAmountError {
OutOfRange();
TooPrecise();
MissingDigits();
InputTooLarge();
InvalidCharacter(string error_message);
OtherParseAmountErr();
};
38 changes: 38 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
pub use bitcoin::amount::ParseAmountError as BitcoinParseAmountError;

#[derive(Debug, thiserror::Error)]
pub enum ParseAmountError {
#[error("amount out of range")]
OutOfRange,

#[error("amount has a too high precision")]
TooPrecise,

#[error("the input has too few digits")]
MissingDigits,

#[error("the input is too large")]
InputTooLarge,

#[error("invalid character: {error_message}")]
InvalidCharacter { error_message: String },

// Has to handle non-exhaustive
#[error("unknown parse amount error")]
OtherParseAmountErr,
}

impl From<BitcoinParseAmountError> for ParseAmountError {
fn from(error: BitcoinParseAmountError) -> Self {
match error {
BitcoinParseAmountError::OutOfRange(_) => ParseAmountError::OutOfRange,
BitcoinParseAmountError::TooPrecise(_) => ParseAmountError::TooPrecise,
BitcoinParseAmountError::MissingDigits(_) => ParseAmountError::MissingDigits,
BitcoinParseAmountError::InputTooLarge(_) => ParseAmountError::InputTooLarge,
BitcoinParseAmountError::InvalidCharacter(c) => ParseAmountError::InvalidCharacter {
error_message: c.to_string(),
},
_ => ParseAmountError::OtherParseAmountErr,
}
}
}
41 changes: 35 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
use bitcoin::ScriptBuf as RustBitcoinScriptBuf;
use bitcoin::Amount as BitcoinAmount;
use bitcoin::ScriptBuf as BitcoinScriptBuf;

use error::ParseAmountError;

#[macro_use]
mod macros;
pub mod error;
pub use bitcoin::Network;

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Script(pub RustBitcoinScriptBuf);
pub struct Script(pub BitcoinScriptBuf);

impl Script {
pub fn new(raw_output_script: Vec<u8>) -> Self {
let script: RustBitcoinScriptBuf = raw_output_script.into();
let script: BitcoinScriptBuf = raw_output_script.into();
Script(script)
}

Expand All @@ -14,10 +22,31 @@ impl Script {
}
}

impl From<RustBitcoinScriptBuf> for Script {
fn from(script: RustBitcoinScriptBuf) -> Self {
Script(script)
impl_from_core_type!(Script, BitcoinScriptBuf);
impl_from_ffi_type!(Script, BitcoinScriptBuf);

pub struct Amount(pub BitcoinAmount);

impl Amount {
pub fn from_sat(sat: u64) -> Self {
Amount(BitcoinAmount::from_sat(sat))
}

pub fn from_btc(btc: f64) -> Result<Self, ParseAmountError> {
let bdk_amount = BitcoinAmount::from_btc(btc).map_err(ParseAmountError::from)?;
Ok(Amount(bdk_amount))
}

pub fn to_sat(&self) -> u64 {
self.0.to_sat()
}

pub fn to_btc(&self) -> f64 {
self.0.to_btc()
}
}

impl_from_core_type!(Amount, BitcoinAmount);
impl_from_ffi_type!(Amount, BitcoinAmount);

uniffi::include_scaffolding!("bitcoin");
19 changes: 19 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
macro_rules! impl_from_core_type {
($ffi_type:ident, $core_type:ident) => {
impl From<$core_type> for $ffi_type {
fn from(core_type: $core_type) -> Self {
$ffi_type(core_type)
}
}
};
}

macro_rules! impl_from_ffi_type {
($ffi_type:ident, $core_type:ident) => {
impl From<$ffi_type> for $core_type {
fn from(ffi_type: $ffi_type) -> Self {
ffi_type.0
}
}
};
}

0 comments on commit eb01b76

Please sign in to comment.