Skip to content

Commit 77c6722

Browse files
committed
Add list_transactions to ffi
also added a couple easy functions
1 parent d81df18 commit 77c6722

5 files changed

Lines changed: 215 additions & 29 deletions

File tree

orange-sdk/src/ffi/bitcoin_payment_instructions.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{impl_from_core_type, impl_into_core_type};
22
use bitcoin_payment_instructions::amount::Amount as BPIAmount;
3-
use std::sync::Arc;
43
use std::fmt::Display;
4+
use std::sync::Arc;
55

66
#[derive(Debug, uniffi::Error)]
77
pub enum AmountError {
@@ -10,12 +10,16 @@ pub enum AmountError {
1010
}
1111

1212
impl Display for AmountError {
13-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14-
match self {
15-
AmountError::FractionalAmountOfSats(sats) => write!(f, "Not exactly a whole number of sats: {}", sats),
16-
AmountError::MoreThanTwentyOneMillionBitcoin(sats) => write!(f, "More than 21 million bitcoin: {}", sats),
17-
}
18-
}
13+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14+
match self {
15+
AmountError::FractionalAmountOfSats(sats) => {
16+
write!(f, "Not exactly a whole number of sats: {}", sats)
17+
},
18+
AmountError::MoreThanTwentyOneMillionBitcoin(sats) => {
19+
write!(f, "More than 21 million bitcoin: {}", sats)
20+
},
21+
}
22+
}
1923
}
2024

2125
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, uniffi::Object)]

orange-sdk/src/ffi/orange/error.rs

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ pub enum ConfigError {
1010
}
1111

1212
impl Display for ConfigError {
13-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14-
match self {
15-
ConfigError::InvalidEntropySize(size) => write!(f, "Invalid entropy size: {size}. Entropy must be 64 bytes."),
16-
ConfigError::InvalidLspAddress(address) => write!(f, "Invalid LSP address: {address}"),
17-
ConfigError::InvalidLspNodeId(node_id) => write!(f, "Invalid LSP node ID: {node_id}"),
18-
}
19-
}
13+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14+
match self {
15+
ConfigError::InvalidEntropySize(size) => {
16+
write!(f, "Invalid entropy size: {size}. Entropy must be 64 bytes.")
17+
},
18+
ConfigError::InvalidLspAddress(address) => write!(f, "Invalid LSP address: {address}"),
19+
ConfigError::InvalidLspNodeId(node_id) => write!(f, "Invalid LSP node ID: {node_id}"),
20+
}
21+
}
2022
}
2123

2224
/// Represents possible failures during wallet initialization.
@@ -34,15 +36,15 @@ pub enum InitFailure {
3436
}
3537

3638
impl Display for InitFailure {
37-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38-
match self {
39-
InitFailure::IoError(e) => write!(f, "I/O error: {e}"),
40-
InitFailure::ConfigError(e) => write!(f, "Config error: {e}"),
41-
InitFailure::LdkNodeBuildFailure(e) => write!(f, "Failed to build the LDK node: {e}"),
42-
InitFailure::LdkNodeStartFailure(e) => write!(f, "Failed to start the LDK node: {e}"),
43-
InitFailure::TrustedFailure => write!(f, "Failed to create the trusted wallet"),
44-
}
45-
}
39+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40+
match self {
41+
InitFailure::IoError(e) => write!(f, "I/O error: {e}"),
42+
InitFailure::ConfigError(e) => write!(f, "Config error: {e}"),
43+
InitFailure::LdkNodeBuildFailure(e) => write!(f, "Failed to build the LDK node: {e}"),
44+
InitFailure::LdkNodeStartFailure(e) => write!(f, "Failed to start the LDK node: {e}"),
45+
InitFailure::TrustedFailure => write!(f, "Failed to create the trusted wallet"),
46+
}
47+
}
4648
}
4749

4850
impl From<std::io::Error> for InitFailure {
@@ -82,12 +84,12 @@ pub enum WalletError {
8284
}
8385

8486
impl Display for WalletError {
85-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86-
match self {
87-
WalletError::LdkNodeFailure(e) => write!(f, "Failure from LDK node: {e}"),
88-
WalletError::TrustedFailure => write!(f, "Failure from trusted wallet"),
89-
}
90-
}
87+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88+
match self {
89+
WalletError::LdkNodeFailure(e) => write!(f, "Failure from LDK node: {e}"),
90+
WalletError::TrustedFailure => write!(f, "Failure from trusted wallet"),
91+
}
92+
}
9193
}
9294

9395
impl From<OrangeWalletError> for WalletError {

orange-sdk/src/ffi/orange/mod.rs

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,155 @@
1+
use crate::bitcoin::hashes::Hash;
2+
use crate::ffi::bitcoin_payment_instructions::Amount;
3+
use crate::{PaymentId as OrangePaymentId, Transaction as OrangeTransaction};
4+
use crate::{impl_from_core_type, impl_into_core_type};
5+
use std::sync::Arc;
6+
17
pub mod config;
28
pub mod error;
39
pub mod wallet;
10+
11+
/// A transaction is a record of a payment made or received. It contains information about the
12+
/// transaction, such as the amount, fee, and status. It is used to track the state of a payment
13+
/// and to provide information about the payment to the user.
14+
#[derive(Debug, Clone, uniffi::Object)]
15+
pub struct Transaction(pub crate::store::Transaction);
16+
17+
impl_from_core_type!(OrangeTransaction, Transaction);
18+
impl_into_core_type!(Transaction, OrangeTransaction);
19+
20+
#[uniffi::export]
21+
impl Transaction {
22+
pub fn id(&self) -> PaymentId {
23+
self.0.id.into()
24+
}
25+
26+
pub fn status(&self) -> TxStatus {
27+
self.0.status.into()
28+
}
29+
30+
pub fn outbound(&self) -> bool {
31+
self.0.outbound
32+
}
33+
34+
/// The amount of the payment
35+
///
36+
/// None if the payment is not yet completed
37+
pub fn amount(&self) -> Option<Arc<Amount>> {
38+
self.0.amount.map(|a| Arc::new(a.into()))
39+
}
40+
41+
/// The fee paid for the payment
42+
///
43+
/// None if the payment is not yet completed
44+
pub fn fee(&self) -> Option<Arc<Amount>> {
45+
self.0.fee.map(|a| Arc::new(a.into()))
46+
}
47+
48+
/// The timestamp of the transaction
49+
pub fn secs_since_epoch(&self) -> u64 {
50+
self.0.time_since_epoch.as_secs()
51+
}
52+
53+
/// The type of payment being made
54+
pub fn payment_type(&self) -> PaymentType {
55+
self.0.payment_type.clone().into()
56+
}
57+
}
58+
59+
/// A PaymentId is a unique identifier for a payment. It can be either a Lightning payment or a
60+
/// Trusted payment. It is used to track the state of a payment and to provide information about
61+
/// the payment to the user.
62+
#[derive(Debug, Clone, Hash, PartialEq, Eq, uniffi::Object)]
63+
pub enum PaymentId {
64+
Lightning(Vec<u8>),
65+
Trusted(Vec<u8>),
66+
}
67+
68+
impl From<OrangePaymentId> for PaymentId {
69+
fn from(id: OrangePaymentId) -> Self {
70+
match id {
71+
OrangePaymentId::Lightning(hash) => Self::Lightning(hash.to_vec()),
72+
OrangePaymentId::Trusted(hash) => Self::Trusted(hash.to_vec()),
73+
}
74+
}
75+
}
76+
77+
/// The status of a transaction. This is used to track the state of a transaction
78+
#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)]
79+
pub enum TxStatus {
80+
/// A pending transaction has not yet been paid.
81+
Pending,
82+
/// A completed transaction has been paid.
83+
Completed,
84+
/// A transaction that has failed.
85+
Failed,
86+
}
87+
88+
impl From<crate::store::TxStatus> for TxStatus {
89+
fn from(status: crate::store::TxStatus) -> Self {
90+
match status {
91+
crate::store::TxStatus::Pending => TxStatus::Pending,
92+
crate::store::TxStatus::Completed => TxStatus::Completed,
93+
crate::store::TxStatus::Failed => TxStatus::Failed,
94+
}
95+
}
96+
}
97+
98+
/// The type of payment being made. This indicates whether the payment is incoming or outgoing,
99+
/// and what method is being used (Lightning, on-chain, etc.)
100+
#[derive(Debug, Clone, uniffi::Enum)]
101+
pub enum PaymentType {
102+
/// An outgoing Lightning payment paying a BOLT 12 offer.
103+
OutgoingLightningBolt12 {
104+
/// The lightning "payment preimage" which represents proof that the payment completed.
105+
/// Will be set for any completed payments.
106+
payment_preimage: Option<Vec<u8>>,
107+
},
108+
/// An outgoing Lightning payment paying a BOLT 11 invoice.
109+
OutgoingLightningBolt11 {
110+
/// The lightning "payment preimage" which represents proof that the payment completed.
111+
/// Will be set for any completed payments.
112+
payment_preimage: Option<Vec<u8>>,
113+
},
114+
/// An outgoing on-chain Bitcoin payment.
115+
OutgoingOnChain {
116+
/// The optional transaction ID of the on-chain payment.
117+
/// Will be set for any completed payments.
118+
txid: Option<Vec<u8>>,
119+
},
120+
/// An incoming on-chain Bitcoin payment.
121+
IncomingOnChain {
122+
/// The optional transaction ID of the on-chain payment.
123+
/// Will be set for any completed payments.
124+
txid: Option<Vec<u8>>,
125+
},
126+
/// An incoming Lightning payment.
127+
IncomingLightning {},
128+
/// A payment that is internal to the trusted service.
129+
TrustedInternal {},
130+
}
131+
132+
impl From<crate::store::PaymentType> for PaymentType {
133+
fn from(payment_type: crate::store::PaymentType) -> Self {
134+
match payment_type {
135+
crate::store::PaymentType::OutgoingLightningBolt12 { payment_preimage } => {
136+
PaymentType::OutgoingLightningBolt12 {
137+
payment_preimage: payment_preimage.map(|p| p.0.to_vec()),
138+
}
139+
},
140+
crate::store::PaymentType::OutgoingLightningBolt11 { payment_preimage } => {
141+
PaymentType::OutgoingLightningBolt11 {
142+
payment_preimage: payment_preimage.map(|p| p.0.to_vec()),
143+
}
144+
},
145+
crate::store::PaymentType::OutgoingOnChain { txid } => {
146+
PaymentType::OutgoingOnChain { txid: txid.map(|t| t.to_byte_array().to_vec()) }
147+
},
148+
crate::store::PaymentType::IncomingOnChain { txid } => {
149+
PaymentType::IncomingOnChain { txid: txid.map(|t| t.to_byte_array().to_vec()) }
150+
},
151+
crate::store::PaymentType::IncomingLightning {} => PaymentType::IncomingLightning {},
152+
crate::store::PaymentType::TrustedInternal {} => PaymentType::TrustedInternal {},
153+
}
154+
}
155+
}

orange-sdk/src/ffi/orange/wallet.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,29 @@ impl Wallet {
7575
let balance = self.inner.get_balance().await?;
7676
Ok(balance.into())
7777
}
78+
79+
pub async fn is_connected_to_lsp(&self) -> bool {
80+
self.inner.is_connected_to_lsp()
81+
}
82+
83+
/// Sets whether the wallet should automatically rebalance from trusted/onchain to lightning.
84+
pub fn set_rebalance_enabled(&self, value: bool) {
85+
self.inner.set_rebalance_enabled(value)
86+
}
87+
88+
/// Whether the wallet should automatically rebalance from trusted/onchain to lightning.
89+
pub fn get_rebalance_enabled(&self) -> bool {
90+
self.inner.get_rebalance_enabled()
91+
}
92+
93+
pub async fn list_transactions(
94+
&self,
95+
) -> Result<Vec<std::sync::Arc<crate::ffi::orange::Transaction>>, WalletError> {
96+
let transactions = self.inner.list_transactions().await?;
97+
Ok(transactions.into_iter().map(|tx| std::sync::Arc::new(tx.into())).collect())
98+
}
99+
100+
pub async fn stop(&self) {
101+
self.inner.stop().await
102+
}
78103
}

orange-sdk/src/store.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ impl From<Transaction> for StoreTransaction {
125125
}
126126
}
127127

128+
/// A PaymentId is a unique identifier for a payment. It can be either a Lightning payment or a
129+
/// Trusted payment. It is used to track the state of a payment and to provide information about
130+
/// the payment to the user.
128131
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
129132
pub enum PaymentId {
130133
Lightning([u8; 32]),

0 commit comments

Comments
 (0)