Skip to content

Commit f779bc1

Browse files
committed
Merge branch 'feat/lending-session/contract-verification'
2 parents a8a5c01 + df82ee0 commit f779bc1

5 files changed

Lines changed: 373 additions & 51 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use lwk_wollet::{
2+
blocking::{BlockchainBackend, EsploraClient},
3+
elements::{Transaction, Txid},
4+
ElectrumClient, Wollet,
5+
};
6+
7+
pub enum AnyClient {
8+
Electrum(Box<ElectrumClient>),
9+
Esplora(EsploraClient),
10+
}
11+
12+
impl AnyClient {
13+
#[allow(dead_code)]
14+
pub fn broadcast(&self, tx: &Transaction) -> Result<Txid, lwk_wollet::Error> {
15+
match self {
16+
AnyClient::Electrum(c) => c.broadcast(tx),
17+
AnyClient::Esplora(c) => c.broadcast(tx),
18+
}
19+
}
20+
21+
pub fn full_scan(
22+
&mut self,
23+
wollet: &Wollet,
24+
) -> Result<Option<lwk_wollet::Update>, lwk_wollet::Error> {
25+
match self {
26+
AnyClient::Electrum(c) => c.full_scan(wollet),
27+
AnyClient::Esplora(c) => c.full_scan(wollet),
28+
}
29+
}
30+
31+
pub fn get_transaction(&self, txid: Txid) -> Result<Transaction, lwk_wollet::Error> {
32+
match self {
33+
AnyClient::Electrum(c) => c.get_transaction(txid),
34+
AnyClient::Esplora(c) => c.get_transaction(txid),
35+
}
36+
}
37+
38+
pub fn tip(&mut self) -> Result<lwk_wollet::elements::BlockHeader, lwk_wollet::Error> {
39+
match self {
40+
AnyClient::Electrum(c) => c.tip(),
41+
AnyClient::Esplora(c) => c.tip(),
42+
}
43+
}
44+
}

lwk_simplicity/src/lending/core.rs

Lines changed: 56 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::HashMap;
33
use lwk_common::{calculate_fee, Network};
44
use lwk_wollet::{
55
bitcoin,
6-
blocking::{BlockchainBackend, EsploraClient},
6+
blocking::EsploraClient,
77
elements::{
88
confidential::{AssetBlindingFactor, ValueBlindingFactor},
99
pset::{PartiallySignedTransaction, PsetBlindError},
@@ -28,49 +28,9 @@ use lending_contracts::programs::{lending::LendingOffer, program::SimplexProgram
2828
use lending_contracts::utils::get_random_seed;
2929
use simplicityhl::WitnessValues;
3030

31-
use crate::lending::error::LendingError;
3231
use crate::lending::network::to_simplicity_network;
33-
34-
use super::indexer::response::FactoryDetailsResponse;
35-
36-
enum AnyClient {
37-
Electrum(Box<ElectrumClient>),
38-
Esplora(EsploraClient),
39-
}
40-
41-
impl AnyClient {
42-
#[allow(dead_code)]
43-
fn broadcast(&self, tx: &Transaction) -> Result<Txid, lwk_wollet::Error> {
44-
match self {
45-
AnyClient::Electrum(c) => c.broadcast(tx),
46-
AnyClient::Esplora(c) => c.broadcast(tx),
47-
}
48-
}
49-
50-
fn full_scan(
51-
&mut self,
52-
wollet: &Wollet,
53-
) -> Result<Option<lwk_wollet::Update>, lwk_wollet::Error> {
54-
match self {
55-
AnyClient::Electrum(c) => c.full_scan(wollet),
56-
AnyClient::Esplora(c) => c.full_scan(wollet),
57-
}
58-
}
59-
60-
fn get_transaction(&self, txid: Txid) -> Result<Transaction, lwk_wollet::Error> {
61-
match self {
62-
AnyClient::Electrum(c) => c.get_transaction(txid),
63-
AnyClient::Esplora(c) => c.get_transaction(txid),
64-
}
65-
}
66-
67-
fn tip(&mut self) -> Result<lwk_wollet::elements::BlockHeader, lwk_wollet::Error> {
68-
match self {
69-
AnyClient::Electrum(c) => c.tip(),
70-
AnyClient::Esplora(c) => c.tip(),
71-
}
72-
}
73-
}
32+
use crate::lending::{client::AnyClient, indexer::response::FactoryDetailsResponse};
33+
use crate::lending::{error::LendingError, verification::parse_and_verify_lending_offer};
7434

7535
pub struct LendingSession {
7636
network: Network,
@@ -329,11 +289,14 @@ impl LendingSession {
329289
.txid;
330290

331291
let creation_tx = self.get_transaction(&creation_txid)?;
292+
let (factory_auth_tx, factory_tx) = self.extract_auth_and_factory_tx(&creation_tx)?;
332293

333-
let offer = LendingOffer::try_from_tx(
294+
let offer = parse_and_verify_lending_offer(
334295
&creation_tx,
335296
details.protocol_fee_keeper_asset_id,
336297
simplex_network,
298+
&factory_auth_tx,
299+
&factory_tx,
337300
)?;
338301

339302
let offer_params = *offer.get_parameters();
@@ -438,10 +401,14 @@ impl LendingSession {
438401
let simplex_network = to_simplicity_network(self.network);
439402

440403
let creation_tx = self.get_transaction(&details.creation_txid)?;
441-
let offer = LendingOffer::try_from_tx(
404+
let (factory_auth_tx, factory_tx) = self.extract_auth_and_factory_tx(&creation_tx)?;
405+
406+
let offer = parse_and_verify_lending_offer(
442407
&creation_tx,
443408
details.protocol_fee_keeper_asset_id,
444409
simplex_network,
410+
&factory_auth_tx,
411+
&factory_tx,
445412
)?;
446413
let offer_params = *offer.get_parameters();
447414

@@ -530,15 +497,19 @@ impl LendingSession {
530497
const COVENANT_VOUT: usize = 5;
531498

532499
let policy_asset = *self.network.policy_asset();
500+
let simplex_network = to_simplicity_network(self.network);
533501

534502
// Fetch the pending offer creation transaction
535503
let creation_tx = self.get_transaction(&details.pending_offer_creation_txid)?;
504+
let (factory_auth_tx, factory_tx) = self.extract_auth_and_factory_tx(&creation_tx)?;
536505

537506
// Reconstruct the LendingOffer from the creation transaction
538-
let mut offer = LendingOffer::try_from_tx(
507+
let mut offer = parse_and_verify_lending_offer(
539508
&creation_tx,
540509
details.protocol_fee_keeper_asset_id,
541-
to_simplicity_network(self.network),
510+
simplex_network,
511+
&factory_auth_tx,
512+
&factory_tx,
542513
)?;
543514

544515
let offer_params = *offer.get_parameters();
@@ -672,13 +643,15 @@ impl LendingSession {
672643
.txid;
673644

674645
let creation_tx = self.get_transaction(&creation_txid)?;
646+
let (factory_auth_tx, factory_tx) = self.extract_auth_and_factory_tx(&creation_tx)?;
675647

676-
let offer = LendingOffer::try_from_tx(
648+
let offer = parse_and_verify_lending_offer(
677649
&creation_tx,
678650
details.protocol_fee_keeper_asset_id,
679651
simplex_network,
652+
&factory_auth_tx,
653+
&factory_tx,
680654
)?;
681-
682655
let offer_params = *offer.get_parameters();
683656

684657
let principal_auth_txout = acceptance_tx
@@ -771,10 +744,14 @@ impl LendingSession {
771744
let simplex_network = to_simplicity_network(self.network);
772745

773746
let creation_tx = self.get_transaction(&details.lending_creation_txid)?;
774-
let offer = LendingOffer::try_from_tx(
747+
let (factory_auth_tx, factory_tx) = self.extract_auth_and_factory_tx(&creation_tx)?;
748+
749+
let offer = parse_and_verify_lending_offer(
775750
&creation_tx,
776751
details.protocol_fee_keeper_asset_id,
777752
simplex_network,
753+
&factory_auth_tx,
754+
&factory_tx,
778755
)?;
779756
let offer_params = *offer.get_parameters();
780757

@@ -881,11 +858,14 @@ impl LendingSession {
881858
.txid;
882859

883860
let creation_tx = self.get_transaction(&creation_txid)?;
861+
let (factory_auth_tx, factory_tx) = self.extract_auth_and_factory_tx(&creation_tx)?;
884862

885-
let offer = LendingOffer::try_from_tx(
863+
let offer = parse_and_verify_lending_offer(
886864
&creation_tx,
887865
details.protocol_fee_keeper_asset_id,
888866
simplex_network,
867+
&factory_auth_tx,
868+
&factory_tx,
889869
)?;
890870

891871
let offer_params = *offer.get_parameters();
@@ -1182,6 +1162,31 @@ impl LendingSession {
11821162
}
11831163
}
11841164

1165+
/// Get Factory auth and factory program from the offer creation transaction
1166+
fn extract_auth_and_factory_tx(
1167+
&self,
1168+
creation_tx: &Transaction,
1169+
) -> Result<(Transaction, Transaction), LendingError> {
1170+
Ok((
1171+
self.get_transaction(
1172+
&creation_tx
1173+
.input
1174+
.first()
1175+
.ok_or_else(|| LendingError::Generic("tx has no inputs".to_string()))?
1176+
.previous_output
1177+
.txid,
1178+
)?,
1179+
self.get_transaction(
1180+
&creation_tx
1181+
.input
1182+
.get(1)
1183+
.ok_or_else(|| LendingError::Generic("tx has no inputs".to_string()))?
1184+
.previous_output
1185+
.txid,
1186+
)?,
1187+
))
1188+
}
1189+
11851190
pub fn wollet(&self) -> &Wollet {
11861191
&self.wollet
11871192
}

lwk_simplicity/src/lending/error.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ pub enum LendingError {
2323
#[error("Lending offer error: {0}")]
2424
LendingOfferError(#[from] lending_contracts::programs::lending::LendingOfferError),
2525

26+
#[error("Factory error: {0}")]
27+
IssuanceFactoryError(
28+
#[from] lending_contracts::programs::issuance_factory::IssuanceFactoryError,
29+
),
30+
31+
#[error("Invalid lending offer: {0}")]
32+
InvalidLendingOffer(String),
33+
2634
#[error("Blinding error: {0}")]
2735
BlindingError(#[from] lwk_wollet::elements::pset::PsetBlindError),
2836

lwk_simplicity/src/lending/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
mod client;
12
mod core;
23
mod error;
34
mod indexer;
45
mod network;
6+
mod verification;
57

68
pub use indexer::client::IndexerClient;
79
pub use indexer::common::OfferStatus;

0 commit comments

Comments
 (0)