Skip to content

Commit

Permalink
Merge pull request #80 from bennyhodl/json-types
Browse files Browse the repository at this point in the history
feat: json types, kormir update, and transport nits
  • Loading branch information
bennyhodl authored Jan 17, 2025
2 parents a26a1d3 + 52d274d commit 638fab8
Show file tree
Hide file tree
Showing 23 changed files with 393 additions and 558 deletions.
299 changes: 42 additions & 257 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Application tooling to get started with [DLCs](https://github.com/discreetlogcon
Build DLC application by plugging in your own transport, storage, and oracle clients.

## Get Started

```
$ cargo add ddk
```
Expand All @@ -29,7 +30,7 @@ type ApplicationDdk = ddk::DlcDevKit<LightningTransport, SledStorage, KormirOrac
fn main() {
let transport = Arc::new(LightningTransport::new([0u8;32], <port>, Network::Regtest));
let storage = Arc::new(SledStorage::new("<storage path>")?);
let oracle_client = Arc::new(KormirOracleClient::new("<oracle host>").await?);
let oracle_client = Arc::new(KormirOracleClient::new("<oracle host>", None).await?);

let ddk: ApplicationDdk = Builder::new()
.set_seed_bytes([0u8;32])
Expand All @@ -46,6 +47,7 @@ fn main() {
```

## Crates

Ready-to-go clients for developing applications:

[`ddk`](./ddk/) - DLC management with an internal BDK wallet.
Expand All @@ -59,14 +61,17 @@ You can create a custom DDK instance by implementing the required traits for sto
To quickly get started building a DDK application, there are pre-built components.

### Storage

[`sled`](./ddk/src/storage/sled) - A simple file based storage using [sled](https://crates.io/crates/sled)

### Transport

[`LDK Peer Manager`](./ddk/src/transport/lightning/) - Communication over Lightning gossip using [`rust-dlc's implementation`](https://github.com/p2pderivatives/rust-dlc/blob/master/dlc-messages/src/message_handler.rs)

[`nostr`](./ddk/src/transport/nostr/) - DLC communication from the [NIP-88 spec](https://github.com/nostr-protocol/nips/pull/919)

### Oracle Clients

[`P2PDerivatives`](./ddk/src/oracle/p2p_derivatives.rs) - Spot price futures on the Bitcoin price [repo](https://github.com/p2pderivatives/p2pderivatives-oracle)

[`kormir`](./ddk/src/oracle/kormir.rs) - Enumeration based oracle with server and nostr support [repo](https://github.com/benthecarman/kormir)
Expand Down
4 changes: 2 additions & 2 deletions ddk-manager/tests/contract_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ async fn accept_contract_test() {
let blockchain =
Rc::new(EsploraClient::new("http://localhost:30000", Network::Regtest).unwrap());

let stuff = test_utils::create_and_fund_wallet("accept_contract_test");
let stuff = test_utils::create_and_fund_wallet("accept_contract_test").await;
let wallet = Arc::new(stuff.0);
wallet.sync().unwrap();
wallet.sync().await.unwrap();

ddk_manager::contract_updater::accept_contract(
secp256k1_zkp::SECP256K1,
Expand Down
38 changes: 19 additions & 19 deletions ddk-manager/tests/manager_execution_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ async fn manager_execution_test(test_params: TestParams, path: TestPath, manual_
let (sync_send, mut sync_receive) = channel::<()>(100);
let alice_sync_send = sync_send.clone();
let bob_sync_send = sync_send;
let (bob_wallet, bob_storage, alice_wallet, alice_storage, sink_rpc) = init_clients();
let (bob_wallet, bob_storage, alice_wallet, alice_storage, sink_rpc) = init_clients().await;
let alice_wallet = Arc::new(alice_wallet);
let bob_wallet = Arc::new(bob_wallet);
let sink = Arc::new(sink_rpc);
Expand Down Expand Up @@ -830,8 +830,8 @@ async fn manager_execution_test(test_params: TestParams, path: TestPath, manual_

assert_contract_state!(alice_manager_send, contract_id, Signed);

alice_wallet.sync().unwrap();
bob_wallet.sync().unwrap();
alice_wallet.sync().await.unwrap();
bob_wallet.sync().await.unwrap();

generate_blocks(10).await;

Expand All @@ -849,8 +849,8 @@ async fn manager_execution_test(test_params: TestParams, path: TestPath, manual_
(bob_manager_send, alice_manager_send)
};

alice_wallet.sync().unwrap();
bob_wallet.sync().unwrap();
alice_wallet.sync().await.unwrap();
bob_wallet.sync().await.unwrap();
match path {
TestPath::Close => {
let case = thread_rng().next_u64() % 3;
Expand All @@ -873,8 +873,8 @@ async fn manager_execution_test(test_params: TestParams, path: TestPath, manual_
.await
.expect("Error closing contract");

alice_wallet.sync().unwrap();
bob_wallet.sync().unwrap();
alice_wallet.sync().await.unwrap();
bob_wallet.sync().await.unwrap();

if let Contract::PreClosed(contract) = contract {
let mut s = second.lock().await;
Expand All @@ -887,17 +887,17 @@ async fn manager_execution_test(test_params: TestParams, path: TestPath, manual_
blocks.unwrap_or(0),
)
.expect("Error registering counterparty close");
alice_wallet.sync().unwrap();
bob_wallet.sync().unwrap();
alice_wallet.sync().await.unwrap();
bob_wallet.sync().await.unwrap();
} else {
panic!("Invalid contract state: {:?}", second_contract);
}
} else {
panic!("Invalid contract state {:?}", contract);
}
} else {
alice_wallet.sync().unwrap();
bob_wallet.sync().unwrap();
alice_wallet.sync().await.unwrap();
bob_wallet.sync().await.unwrap();
periodic_check!(first, contract_id, PreClosed);
}

Expand All @@ -906,8 +906,8 @@ async fn manager_execution_test(test_params: TestParams, path: TestPath, manual_
generate_blocks(b as u64).await;
}

alice_wallet.sync().unwrap();
bob_wallet.sync().unwrap();
alice_wallet.sync().await.unwrap();
bob_wallet.sync().await.unwrap();

// Randomly check with or without having the CET mined
if case == 2 {
Expand All @@ -920,8 +920,8 @@ async fn manager_execution_test(test_params: TestParams, path: TestPath, manual_
}
}
TestPath::Refund => {
alice_wallet.sync().unwrap();
bob_wallet.sync().unwrap();
alice_wallet.sync().await.unwrap();
bob_wallet.sync().await.unwrap();
periodic_check!(first, contract_id, Confirmed);

periodic_check!(second, contract_id, Confirmed);
Expand All @@ -932,8 +932,8 @@ async fn manager_execution_test(test_params: TestParams, path: TestPath, manual_

generate_blocks(10).await;

alice_wallet.sync().unwrap();
bob_wallet.sync().unwrap();
alice_wallet.sync().await.unwrap();
bob_wallet.sync().await.unwrap();

periodic_check!(first, contract_id, Refunded);

Expand All @@ -942,8 +942,8 @@ async fn manager_execution_test(test_params: TestParams, path: TestPath, manual_
generate_blocks(1).await;
}

alice_wallet.sync().unwrap();
bob_wallet.sync().unwrap();
alice_wallet.sync().await.unwrap();
bob_wallet.sync().await.unwrap();

periodic_check!(second, contract_id, Refunded);
}
Expand Down
12 changes: 6 additions & 6 deletions ddk-manager/tests/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ pub async fn refresh_wallet(wallet: &DlcDevKitWallet, expected_funds: u64) {
panic!("Wallet refresh taking too long.")
}
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
wallet.sync().unwrap();
wallet.sync().await.unwrap();
retry += 1;
}
}
Expand All @@ -595,7 +595,7 @@ pub const OFFER_PARTY: &str = "alice";
pub const ACCEPT_PARTY: &str = "bob";
pub const SINK: &str = "ddk";

pub fn init_clients() -> (
pub async fn init_clients() -> (
DlcDevKitWallet,
Arc<MemoryStorage>,
DlcDevKitWallet,
Expand All @@ -606,8 +606,8 @@ pub fn init_clients() -> (
let sink_rpc = Client::new(&rpc_base(), auth.clone()).unwrap();

std::thread::sleep(std::time::Duration::from_millis(100));
let offer_rpc = create_and_fund_wallet(OFFER_PARTY);
let accept_rpc = create_and_fund_wallet(ACCEPT_PARTY);
let offer_rpc = create_and_fund_wallet(OFFER_PARTY).await;
let accept_rpc = create_and_fund_wallet(ACCEPT_PARTY).await;

let sink_address = sink_rpc
.get_new_address(None, Some(AddressType::Bech32))
Expand All @@ -630,7 +630,7 @@ fn rpc_base() -> String {
format!("http://{}:18443", host)
}

pub fn create_and_fund_wallet(name: &str) -> (DlcDevKitWallet, Arc<MemoryStorage>) {
pub async fn create_and_fund_wallet(name: &str) -> (DlcDevKitWallet, Arc<MemoryStorage>) {
let auth = Auth::UserPass("ddk".to_string(), "ddk".to_string());
let sink_rpc = Client::new(&rpc_base(), auth.clone()).unwrap();
let sink_address = sink_rpc
Expand Down Expand Up @@ -667,7 +667,7 @@ pub fn create_and_fund_wallet(name: &str) -> (DlcDevKitWallet, Arc<MemoryStorage
sink_rpc.generate_to_address(5, &sink_address).unwrap();
let mut done = false;
while !done {
wallet.sync().unwrap();
wallet.sync().await.unwrap();
let balance = wallet.get_balance().unwrap();
if balance.confirmed > Amount::ZERO {
done = true;
Expand Down
2 changes: 2 additions & 0 deletions ddk-node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ tokio = { version = "1.38.0", features = ["full"] }
tonic = "0.10.2"
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
reqwest = { version = "0.12.12", features = ["json"] }
chrono = "0.4.39"

[build-dependencies]
tonic-build = "0.10.2"
Expand Down
6 changes: 3 additions & 3 deletions ddk-node/src/cli_opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ pub enum CliCommand {

#[derive(Parser, Clone, Debug)]
pub struct Offer {
#[arg(help = "Path to a contract input file. Eventually to be a repl asking contract params")]
#[arg(short = 'f', long = "file")]
pub contract_input_file: Option<String>,
#[arg(help = "Generate a contract automatically with peer.")]
#[arg(short = 'g', long = "generate", default_value = "false")]
pub generate: bool,
#[arg(help = "The contract counterparty to send to.")]
pub counter_party: String,
}
Expand Down
Loading

0 comments on commit 638fab8

Please sign in to comment.