diff --git a/README.md b/README.md index 187413d..c84279c 100644 --- a/README.md +++ b/README.md @@ -1,80 +1,76 @@ -# Dlc Dev Kit +# DLC Dev Kit [![Crate](https://img.shields.io/crates/v/ddk.svg?logo=rust)](https://crates.io/crates/ddk) [![Documentation](https://img.shields.io/static/v1?logo=read-the-docs&label=docs.rs&message=ddk&color=informational)](https://docs.rs/ddk) ![Crates.io Total Downloads](https://img.shields.io/crates/d/ddk) -> :warning: `dlcdevkit` is alpha software and should not be used with real money. API is subject to change. +A ready-to-go [Discreet Log Contract](https://github.com/discreetlogcontracts/dlcspecs) node library built using [BDK](https://github.com/bitcoindevkit/bdk). -Application tooling to get started with [DLCs](https://github.com/discreetlogcontracts/dlcspecs) build with [rust-dlc](https://github.com/p2pderivatives/rust-dlc) and [bdk](https://github.com/bitcoindevkit/bdk). +DLC Dev Kit is a self-custodial DLC node in library form. Its central goal is to provide a small, simple, and straightforward interface that enables users to easily set up and run a DLC node with an integrated on-chain wallet. While minimalism is at its core, DDK aims to be sufficiently modular and configurable to be useful for a variety of use cases. -Build DLC application by plugging in your own transport, storage, and oracle clients. +## Getting Started -## Get Started - -``` -$ cargo add ddk -``` +The primary abstraction of the library is the [`DlcDevKit`](https://docs.rs/ddk/latest/ddk/struct.DlcDevKit.html), which can be retrieved by setting up and configuring a [`Builder`](https://docs.rs/ddk/latest/ddk/builder/struct.Builder.html) to your liking and calling `finish()`. `DlcDevKit` can then be controlled via commands such as `start`, `stop`, `send_dlc_offer`, `accept_dlc_offer`, etc. ```rust -use ddk::builder::Builder; -use ddk::storage::SledStorage; -use ddk::transport::lightning::LightningTransport; // with "lightning" feature -use ddk::oracle::KormirOracleClient; -use bitcoin::Network; +use ddk::builder::{Builder, SeedConfig}; +use ddk::logger::{LogLevel, Logger}; +use ddk::oracle::kormir::KormirOracleClient; +use ddk::storage::sled::SledStorage; +use ddk::transport::lightning::LightningTransport; use std::sync::Arc; type ApplicationDdk = ddk::DlcDevKit; #[tokio::main] -fn main() { - let transport = Arc::new(LightningTransport::new([0u8;32], , Network::Regtest)); - let storage = Arc::new(SledStorage::new("")?); - let oracle_client = Arc::new(KormirOracleClient::new("", None).await?); - - let ddk: ApplicationDdk = Builder::new() - .set_seed_bytes([0u8;32]) - .set_network(Network::Regtest) - .set_esplora_path("http://127.0.0.1:3000") - .set_transport(transport.clone()) - .set_storage(storage.clone()) - .set_oracle(oracle_client.clone()) - .finish() - .expect("could not build ddk node"); - - ddk.start().expect("ddk could not start"); -} -``` +async fn main() -> Result<(), ddk::error::Error> { + let logger = Arc::new(Logger::console("ddk-example".to_string(), LogLevel::Info)); -## Crates - -Ready-to-go clients for developing applications: - -[`ddk`](./ddk/) - DLC management with an internal BDK wallet. + let transport = Arc::new(LightningTransport::new(&[0u8; 32], 1776, logger.clone())?); + let storage = Arc::new(SledStorage::new("/tmp/ddk-example", logger.clone())?); + let oracle = Arc::new(KormirOracleClient::new("http://localhost:8082", None, logger.clone()).await?); -[`ddk-node`](./ddk-node/) - A ready-to-go node with an accompanying cli. + let mut builder: Builder = Builder::new(); + builder.set_seed_bytes(SeedConfig::Random)?; + builder.set_esplora_host("https://mutinynet.com/api".to_string()); + builder.set_transport(transport); + builder.set_storage(storage); + builder.set_oracle(oracle); + builder.set_logger(logger); -[`payouts`](./payouts/) - Functions to build DLC contracts. + let ddk: ApplicationDdk = builder.finish().await?; -You can create a custom DDK instance by implementing the required traits for storage and transport. DDK traits are defined in [ddk/src/lib.rs](./ddk/src/lib.rs). The traits are super traits from what is required in `bdk` and `rust-dlc`. + ddk.start()?; -To quickly get started building a DDK application, there are pre-built components. + // ... open contracts, accept offers, etc. -### Storage - -[`sled`](./ddk/src/storage/sled) - A simple file based storage using [sled](https://crates.io/crates/sled) + ddk.stop()?; + Ok(()) +} +``` -### Transport +## Modularity -[`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) +DDK is designed with a pluggable architecture, allowing you to choose or implement your own components: -[`nostr`](./ddk/src/transport/nostr/) - DLC communication from the [NIP-88 spec](https://github.com/nostr-protocol/nips/pull/919) +- **Transport**: Communication layer for DLC messages between peers. Implementations include Lightning Network gossip and Nostr protocol messaging. +- **Storage**: Persistence backend for contracts and wallet data. Implementations include Sled (embedded) and PostgreSQL. +- **Oracle**: External data source for contract attestations. Implementations include HTTP and Nostr-based oracle clients. -### Oracle Clients +You can create a custom DDK instance by implementing the required traits defined in [`ddk/src/lib.rs`](./ddk/src/lib.rs). -[`P2PDerivatives`](./ddk/src/oracle/p2p_derivatives.rs) - Spot price futures on the Bitcoin price [repo](https://github.com/p2pderivatives/p2pderivatives-oracle) +## Crates -[`kormir`](./ddk/src/oracle/kormir.rs) - Enumeration based oracle with server and nostr support [repo](https://github.com/benthecarman/kormir) +| Crate | Description | | +|-------|-------------|---------| +| [`ddk`](./ddk) | The main DDK library with an integrated BDK wallet for building DLC applications. | [![Crate](https://img.shields.io/crates/v/ddk.svg)](https://crates.io/crates/ddk) | +| [`ddk-node`](./ddk-node) | A ready-to-go DLC node with a gRPC server and accompanying CLI. | [![Crate](https://img.shields.io/crates/v/ddk-node.svg)](https://crates.io/crates/ddk-node) | +| [`ddk-payouts`](./payouts) | Functions to build payout curves for DLC contracts. | [![Crate](https://img.shields.io/crates/v/ddk-payouts.svg)](https://crates.io/crates/ddk-payouts) | +| [`ddk-manager`](./ddk-manager) | Core DLC contract creation and state machine management. | [![Crate](https://img.shields.io/crates/v/ddk-manager.svg)](https://crates.io/crates/ddk-manager) | +| [`ddk-dlc`](./dlc) | Low-level DLC transaction creation, signing, and verification. | [![Crate](https://img.shields.io/crates/v/ddk-dlc.svg)](https://crates.io/crates/ddk-dlc) | +| [`ddk-messages`](./dlc-messages) | Serialization and structs for the DLC protocol messages. | [![Crate](https://img.shields.io/crates/v/ddk-messages.svg)](https://crates.io/crates/ddk-messages) | +| [`ddk-trie`](./dlc-trie) | Data structures for storage and retrieval of numerical DLCs. | [![Crate](https://img.shields.io/crates/v/ddk-trie.svg)](https://crates.io/crates/ddk-trie) | +| [`kormir`](./kormir) | Oracle implementation for creating and attesting to DLC events. | [![Crate](https://img.shields.io/crates/v/kormir.svg)](https://crates.io/crates/kormir) | ## Development @@ -84,4 +80,22 @@ A bitcoin node, esplora server, and oracle server are required to run DDK. Devel $ just deps ``` -Go to the README in [ddk-node](./ddk-node/README.md) to start the project's DDK node example and more development information. +To run your own [Kormir](https://github.com/bennyhodl/kormir) oracle server for development, see the Kormir repository. + +See the [ddk-node README](./ddk-node/README.md) for more development information. + +## Language Bindings + +For Node.js and React Native bindings, see [ddk-ffi](https://github.com/bennyhodl/ddk-ffi). + +## Resources + +- [DLC Dev Kit Blog](https://dlcdevkit.com) - Guides and API walkthroughs +- [DLC Dev Kit: Beyond](https://benschroth.com/blog/dlcdevkit-beyond/) - Deep dive into the project +- [What is a Discreet Log Contract?](https://river.com/learn/terms/d/discreet-log-contract-dlc/) - Learn about DLCs +- [DLC Specifications](https://github.com/discreetlogcontracts/dlcspecs) - Protocol specification +- [rust-dlc](https://github.com/p2pderivatives/rust-dlc) - The original rust-dlc implementation + +## License + +This project is licensed under the [MIT License](LICENSE). diff --git a/ddk-manager/Readme.md b/ddk-manager/Readme.md index 133ca62..3b0ead1 100644 --- a/ddk-manager/Readme.md +++ b/ddk-manager/Readme.md @@ -1,6 +1,61 @@ -# DLC Manager +# ddk-manager -This crate provides a manager structure that can be used to create and process DLC. -The manager requires a number of traits which have basic implementation within this repository but that can be customized to fit specific needs. +[![Crate](https://img.shields.io/crates/v/ddk-manager.svg?logo=rust)](https://crates.io/crates/ddk-manager) +[![Documentation](https://img.shields.io/static/v1?logo=read-the-docs&label=docs.rs&message=ddk-manager&color=informational)](https://docs.rs/ddk-manager) -See [the development docs](../docs/Development.md) for information about running integration tests. +Core DLC contract creation and state machine management for Discreet Log Contracts. + +This crate provides the `Manager` component for creating, processing, and managing DLCs and DLC channels. It handles the full lifecycle from offer through settlement/closure, including both on-chain contracts and off-chain channels with support for renewals, settlements, and collaborative/unilateral closes. + +## Contract States + +| State | Description | +|-------|-------------| +| `Offered` | Contract has been proposed | +| `Accepted` | Counter party accepted the offer | +| `Signed` | Signatures have been exchanged | +| `Confirmed` | Funding transaction confirmed on-chain | +| `PreClosed` | CET broadcast but not fully confirmed | +| `Closed` | Contract fully settled | +| `Refunded` | Refund transaction was broadcast | + +## Key Traits + +Users must implement these traits for their specific backends: + +| Trait | Purpose | +|-------|---------| +| `Storage` | Persist and retrieve contracts, channels, and chain state | +| `Wallet` | Address generation, UTXO management, PSBT signing | +| `Blockchain` | Transaction broadcasting, block fetching, confirmations | +| `Oracle` | Fetch oracle announcements and attestations | +| `ContractSignerProvider` | Derive contract signing keys | + +## Manager API + +```rust +// Contract lifecycle +manager.send_offer(&contract_input, counterparty).await?; +manager.accept_contract_offer(&contract_id).await?; +manager.on_dlc_message(&message, counterparty).await?; + +// Channel operations +manager.offer_channel(&contract_input, counterparty).await?; +manager.settle_offer(&channel_id, payout).await?; +manager.renew_offer(&channel_id, &contract_input).await?; + +// Periodic maintenance +manager.periodic_check(false).await?; +``` + +## Features + +| Feature | Description | +|---------|-------------| +| `std` | Standard library support (default) | +| `parallel` | Parallel processing in ddk-trie | +| `use-serde` | Serde serialization support | + +## License + +This project is licensed under the MIT License. diff --git a/ddk-node/README.md b/ddk-node/README.md index 2f828c5..ccbd3ed 100644 --- a/ddk-node/README.md +++ b/ddk-node/README.md @@ -1,16 +1,25 @@ -# DDK Node +# ddk-node [![Crate](https://img.shields.io/crates/v/ddk-node.svg?logo=rust)](https://crates.io/crates/ddk-node) -Dlc Dev Kit node example with [`ddk`](../ddk), [`lightning`](../ddk/src/transport/lightning/), [`sled`](../ddk/src/storage/sled/), and [`kormir`](../ddk/src/oracle/kormir.rs). +A ready-to-go DLC node with a gRPC server and accompanying CLI built on the DlcDevKit framework. -Node binary is available through [`crates.io`](https://crates.io/crates/ddk-node). +The node uses Nostr for transport, PostgreSQL for storage, and Kormir as the oracle client. + +## Installation ``` $ cargo install ddk-node ``` -## Usage -The downloaded binary included the node binary and a cli interface. + +## Binaries + +| Binary | Description | +|--------|-------------| +| `ddk-node` | The DLC node server exposing a gRPC API | +| `ddk-cli` | Command-line client to interact with `ddk-node` | + +## Node Usage ``` $ ddk-node --help @@ -18,17 +27,20 @@ $ ddk-node --help Usage: ddk-node [OPTIONS] Options: - --log Set the log level. [default: info] - -n, --network Set the Bitcoin network for DDK [default: regtest] - -s, --storage-dir The path where DlcDevKit will store data. - -p, --port Listening port for network transport. [default: 1776] - --grpc Host and port the gRPC server will run on. [default: 0.0.0.0:3030] - --esplora Host to connect to an esplora server. [default: http://127.0.0.1:30000] - --oracle Host to connect to an oracle server. [default: http://127.0.0.1:8082] - --seed Seed config strategy ('bytes' OR 'file') [default: file] + --log Set the log level [default: info] + -n, --network Set the Bitcoin network [default: signet] + -s, --storage-dir Data storage path [default: ~/.ddk] + -p, --port Transport listening port [default: 1776] + --grpc gRPC server host:port [default: 0.0.0.0:3030] + --esplora Esplora server URL [default: https://mutinynet.com/api] + --oracle Kormir oracle URL [default: https://kormir.dlcdevkit.com] + --seed Seed strategy: 'file' or 'bytes' [default: file] + --postgres-url PostgreSQL connection URL -h, --help Print help ``` +## CLI Usage + ``` $ ddk-cli --help @@ -37,68 +49,75 @@ CLI for ddk-node Usage: ddk-cli [OPTIONS] Commands: - info Gets information about the DDK instance - offer-contract Pass a contract input to send an offer - offers Retrieve the offers that ddk-node has received - accept-offer Accept a DLC offer with the contract id string - contracts List contracts - wallet Wallet commands - peers Get the peers connected to the node + info Get node information (pubkey, transport, oracle) + offer-contract Send a contract offer to a counterparty + offers List received contract offers + accept-offer Accept a DLC offer by contract ID + contracts List all contracts + balance Get wallet balance + wallet Wallet commands (new-address, transactions, utxos, send, sync) + oracle Oracle commands (announcements, create-enum, create-numeric, sign) + peers List connected peers connect Connect to another DDK node - help Print this message or the help of the given subcommand(s) + sync Sync wallet and contracts + help Print help Options: - -s, --server ddk-node gRPC server to connect to. [default: http://127.0.0.1:3030] + -s, --server gRPC server to connect to [default: http://127.0.0.1:3030] -h, --help Print help - -V, --version Print version ``` -## Development +## gRPC API + +The node exposes a gRPC service with the following methods: + +| Method | Description | +|--------|-------------| +| `Info` | Get node info (pubkey, transport, oracle) | +| `SendOffer` | Send a DLC offer to a counterparty | +| `AcceptOffer` | Accept a received DLC offer | +| `ListOffers` | List all received contract offers | +| `ListContracts` | List all contracts | +| `NewAddress` | Generate a new wallet address | +| `WalletBalance` | Get wallet balance | +| `WalletSync` | Sync the on-chain wallet | +| `GetWalletTransactions` | Get wallet transactions | +| `ListUtxos` | List wallet UTXOs | +| `Send` | Send Bitcoin to an address | +| `ListPeers` | List connected peers | +| `ConnectPeer` | Connect to another DDK node | +| `ListOracles` | Get oracle info | +| `OracleAnnouncements` | Get oracle announcement by event ID | +| `CreateEnum` | Create an enum oracle event | +| `CreateNumeric` | Create a numeric oracle event | +| `SignAnnouncement` | Sign an oracle announcement | -If you are testing local changes to [`ddk`](../ddk/) or running `ddk-node` locally: +## Development -``` -# Start bitcoin and esplora +```bash +# Start bitcoin, esplora, and postgres $ just deps -$ just node-one # Start node one -$ just node-two # Start node two in a different terminal - -$ just bc ...ARGS # Interface with the Bitcoin node. -``` +# Start node one +$ just node-one -An oracle is hosted at `https://kormir.dlcdevkit.com` +# Start node two (in another terminal) +$ just node-two -To interface the nodes with the CLI, you can use `just cli-one` and `just cli-two`. +# Use the CLI +$ just cli-one info +$ just cli-two info -To create an enum event with `kormir`: +# Connect nodes +$ PUBKEY=$(just cli-one info | jq -r .pubkey) +$ just cli-two connect $PUBKEY@127.0.0.1:1776 -1. Create the event -``` -curl --location 'http://localhost:8082/create-enum' \ ---header 'Content-Type: application/json' \ ---data '{ - "event_id": "EVENT ID", - "outcomes": [ - ...OUTCOMES - ], - "event_maturity_epoch": UNIX_TIME -}' +# Create and accept a contract +$ just cli-two offer-contract $PUBKEY +$ just cli-one offers +$ just cli-one accept-offer ``` -2. Connect two ddk-nodes -``` -$ PUBKEY=$(just cli-one info | jq -r .pubkey) && just cli-two connect $PUBKEY@127.0.0.1:1776 -``` +## License -3. Offer Contract -``` -$ just cli-two offer-contract $PUBKEY # Follow the prompts and input the outcomes and payouts -``` - -4. Accept Contract -``` -$ just cli-one offers # Select the recently created offer - -$ just cli-one accept-contract -``` +This project is licensed under the MIT License. diff --git a/ddk/README.md b/ddk/README.md new file mode 100644 index 0000000..33000d1 --- /dev/null +++ b/ddk/README.md @@ -0,0 +1,81 @@ +# ddk + +[![Crate](https://img.shields.io/crates/v/ddk.svg?logo=rust)](https://crates.io/crates/ddk) +[![Documentation](https://img.shields.io/static/v1?logo=read-the-docs&label=docs.rs&message=ddk&color=informational)](https://docs.rs/ddk) + +The main DLC Dev Kit library for building DLC applications with an integrated BDK wallet. + +DDK provides a high-level, pluggable framework with an actor-based architecture for thread-safe, lock-free DLC operations. It integrates wallet management, transport layers, storage backends, and oracle clients into a unified API. + +## Usage + +``` +$ cargo add ddk +``` + +## Example + +```rust +use ddk::builder::{Builder, SeedConfig}; +use ddk::oracle::kormir::KormirOracleClient; +use ddk::storage::sled::SledStorage; +use ddk::transport::lightning::LightningTransport; +use std::sync::Arc; + +type ApplicationDdk = ddk::DlcDevKit; + +#[tokio::main] +async fn main() -> Result<(), ddk::error::Error> { + let transport = Arc::new(LightningTransport::new(&[0u8; 32], 1776, logger.clone())?); + let storage = Arc::new(SledStorage::new("/tmp/ddk-example", logger.clone())?); + let oracle = Arc::new(KormirOracleClient::new("http://localhost:8082", None, logger.clone()).await?); + + let mut builder: Builder = Builder::new(); + builder.set_seed_bytes(SeedConfig::Random)?; + builder.set_transport(transport); + builder.set_storage(storage); + builder.set_oracle(oracle); + + let ddk: ApplicationDdk = builder.finish().await?; + + ddk.start()?; + + // Send a DLC offer + let offer = ddk.send_dlc_offer(&contract_input, counterparty, announcements).await?; + + // Accept a DLC offer + let (contract_id, counter_party, accept) = ddk.accept_dlc_offer(contract_id).await?; + + // Get wallet balance + let balance = ddk.balance().await?; + + ddk.stop()?; + Ok(()) +} +``` + +## Key Types + +| Type | Description | +|------|-------------| +| [`DlcDevKit`](https://docs.rs/ddk/latest/ddk/struct.DlcDevKit.html) | Main entry point managing the DLC runtime, wallet, and background tasks | +| [`Builder`](https://docs.rs/ddk/latest/ddk/builder/struct.Builder.html) | Builder pattern for constructing `DlcDevKit` instances | +| [`Transport`](https://docs.rs/ddk/latest/ddk/trait.Transport.html) | Trait for DLC message communication between peers | +| [`Storage`](https://docs.rs/ddk/latest/ddk/trait.Storage.html) | Trait for contract and wallet data persistence | +| [`Oracle`](https://docs.rs/ddk/latest/ddk/trait.Oracle.html) | Trait for oracle client implementations | + +## Features + +| Feature | Description | +|---------|-------------| +| `lightning` | Lightning Network transport using LDK | +| `nostr` | Nostr protocol transport | +| `sled` | Sled embedded database storage | +| `postgres` | PostgreSQL storage | +| `kormir` | Kormir HTTP oracle client | +| `p2pderivatives` | P2P Derivatives oracle client | +| `nostr-oracle` | Nostr-based oracle client | + +## License + +This project is licensed under the MIT License. diff --git a/dlc-messages/Readme.md b/dlc-messages/Readme.md index 4228791..69e0302 100644 --- a/dlc-messages/Readme.md +++ b/dlc-messages/Readme.md @@ -1,3 +1,63 @@ -# DLC Messages +# ddk-messages -This crate provide the representation of DLC messages and functions to enable their serialization. \ No newline at end of file +[![Crate](https://img.shields.io/crates/v/ddk-messages.svg?logo=rust)](https://crates.io/crates/ddk-messages) +[![Documentation](https://img.shields.io/static/v1?logo=read-the-docs&label=docs.rs&message=ddk-messages&color=informational)](https://docs.rs/ddk-messages) + +Data structures and serialization for peer-to-peer communication in the Discreet Log Contract (DLC) protocol. + +This crate implements the DLC specification message formats with Lightning-compatible serialization and automatic message segmentation for large messages. + +## Contract Messages + +| Message | Description | +|---------|-------------| +| `OfferDlc` | Initial contract offer with funding details and payouts | +| `AcceptDlc` | Contract acceptance with adaptor signatures | +| `SignDlc` | Final contract signatures | +| `CloseDlc` | Contract close message | + +## Oracle Messages + +| Type | Description | +|------|-------------| +| `OracleAnnouncement` | Signed announcement of an oracle event | +| `OracleAttestation` | Oracle's signed attestation to an outcome | +| `OracleEvent` | Event details (nonces, maturity, descriptor) | + +## Channel Messages + +| Message | Description | +|---------|-------------| +| `OfferChannel` / `AcceptChannel` / `SignChannel` | Channel setup | +| `SettleOffer` / `SettleAccept` / `SettleConfirm` | Settlement flow | +| `RenewOffer` / `RenewAccept` / `RenewConfirm` | Contract renewal | +| `CollaborativeCloseOffer` | Collaborative close | +| `Reject` | Reject a received offer | + +## Message Handler + +The `MessageHandler` implements LDK's `CustomMessageHandler` for integration with Lightning peer messaging: + +```rust +use ddk_messages::message_handler::MessageHandler; + +let handler = MessageHandler::new(); + +// Send a message +handler.send_message(counterparty_pubkey, Message::Offer(offer)); + +// Get received messages +let messages = handler.get_and_clear_received_messages(); +``` + +## Features + +| Feature | Description | +|---------|-------------| +| `std` | Standard library support (default) | +| `no-std` | No standard library support | +| `use-serde` | Serde serialization for all message types | + +## License + +This project is licensed under the MIT License. diff --git a/dlc-trie/Readme.md b/dlc-trie/Readme.md index 64c7bc0..50a8e94 100644 --- a/dlc-trie/Readme.md +++ b/dlc-trie/Readme.md @@ -1,3 +1,61 @@ -# DLC Trie +# ddk-trie -This crate provide data structures for facilitating the storage and retrieval of contract information for numerical DLC. \ No newline at end of file +[![Crate](https://img.shields.io/crates/v/ddk-trie.svg?logo=rust)](https://crates.io/crates/ddk-trie) +[![Documentation](https://img.shields.io/static/v1?logo=read-the-docs&label=docs.rs&message=ddk-trie&color=informational)](https://docs.rs/ddk-trie) + +Trie-based data structures for efficient storage and retrieval of adaptor signature information in numerical Discreet Log Contracts (DLCs). + +This crate enables DLCs to handle continuous outcome ranges (e.g., prices, scores) by decomposing numeric values into digit paths, minimizing the number of adaptor signatures required. + +## Key Structures + +| Structure | Description | +|-----------|-------------| +| `DigitTrie` | Base trie indexed by digit paths (decomposed numeric values) | +| `MultiTrie` | Trie of tries for multi-oracle t-of-n threshold schemes | +| `MultiOracleTrie` | Optimized for oracles that must exactly agree | +| `MultiOracleTrieWithDiff` | Allows differences between oracle outcomes within bounds | + +## How It Works + +1. **Digit Decomposition**: Numeric outcomes (e.g., price = 1234) are decomposed into digit paths (`[1, 2, 3, 4]` in base 10) + +2. **Prefix Compression**: Ranges sharing common prefixes are covered by a single trie node. For example, outcomes 1000-1999 can be covered by prefix `[1]` + +3. **Efficient Signatures**: The `DlcTrie` trait provides: + - `generate()` - Build trie structure from range payouts + - `sign()` - Create adaptor signatures for all paths + - `verify()` - Verify adaptor signatures + +## Example + +```rust +use ddk_trie::{DlcTrie, OracleNumericInfo}; + +let oracle_info = OracleNumericInfo { + base: 2, + nb_digits: vec![20], // 20-bit precision +}; + +// Generate trie from payouts +let trie_info = trie.generate(&payouts, &oracle_info)?; + +// Sign all paths +let signatures = trie.sign(&secp, &funding_info, &secret_key)?; + +// Verify signatures +trie.verify(&secp, &funding_info, &adaptor_sigs, &public_key)?; +``` + +## Features + +| Feature | Description | +|---------|-------------| +| `std` | Standard library support (default) | +| `no-std` | No standard library for embedded/WASM | +| `parallel` | Parallel signature generation/verification using rayon | +| `use-serde` | Serde serialization support | + +## License + +This project is licensed under the MIT License. diff --git a/dlc/Readme.md b/dlc/Readme.md index 2e06a33..b6b381c 100644 --- a/dlc/Readme.md +++ b/dlc/Readme.md @@ -1,5 +1,91 @@ -# DLC +# ddk-dlc -This crate provides base functionality for creation, signing and verification of transactions used in a DLC. +[![Crate](https://img.shields.io/crates/v/ddk-dlc.svg?logo=rust)](https://crates.io/crates/ddk-dlc) +[![Documentation](https://img.shields.io/static/v1?logo=read-the-docs&label=docs.rs&message=ddk-dlc&color=informational)](https://docs.rs/ddk-dlc) -See [the development docs](../docs/Development.md) for information about running integration tests. +Low-level primitives for creating, signing, and verifying Bitcoin transactions used in Discreet Log Contract (DLC) protocols. + +This crate handles all DLC transaction types including funding, contract execution transactions (CETs), refund transactions, and DLC channel operations. + +## Transaction Creation + +```rust +use ddk_dlc::{create_dlc_transactions, PartyParams}; + +// Create complete set of DLC transactions +let dlc_txs = create_dlc_transactions( + &offer_params, + &accept_params, + &payouts, + refund_lock_time, + fee_rate, + fund_lock_time, + cet_lock_time, + fund_output_serial_id, +)?; + +// Access individual transactions +let fund_tx = dlc_txs.fund; +let cets = dlc_txs.cets; +let refund_tx = dlc_txs.refund; +``` + +## Adaptor Signatures + +```rust +use ddk_dlc::{create_cet_adaptor_sig_from_oracle_info, sign_cet}; + +// Create adaptor signature for CET +let adaptor_sig = create_cet_adaptor_sig_from_oracle_info( + &secp, + &cet, + &adaptor_info, + &funding_script_pubkey, + fund_output_value, + &secret_key, +)?; + +// Sign CET with oracle attestation +let signed_cet = sign_cet( + &secp, + &cet, + &adaptor_sig, + &oracle_signatures, + &funding_script_pubkey, + fund_output_value, + &own_secret_key, +)?; +``` + +## Key Functions + +| Function | Description | +|----------|-------------| +| `create_dlc_transactions` | Create complete set of DLC transactions | +| `create_fund_transaction` | Create 2-of-2 multisig funding transaction | +| `create_cet` / `create_cets` | Create contract execution transaction(s) | +| `create_refund_transaction` | Create refund transaction | +| `create_cet_adaptor_sig_from_oracle_info` | Create adaptor signature for CET | +| `sign_cet` | Sign CET with oracle attestation | +| `verify_cet_adaptor_sig_from_oracle_info` | Verify adaptor signature | + +## Channel Operations + +The `channel` module provides functions for DLC channels: + +- `create_channel_transactions` - Create DLC channel transactions with revocation +- `create_buffer_transaction` - Create buffer transaction for revocation +- `create_settle_transaction` - Create settle transaction +- `create_collaborative_close_transaction` - Create collaborative close + +## Features + +| Feature | Description | +|---------|-------------| +| `std` | Standard library support (default) | +| `no-std` | No standard library for embedded/WASM | +| `use-serde` | Serde serialization support | + +## License + +This project is licensed under the MIT License. diff --git a/kormir/README.md b/kormir/README.md new file mode 100644 index 0000000..522dd02 --- /dev/null +++ b/kormir/README.md @@ -0,0 +1,91 @@ +# kormir + +[![Crate](https://img.shields.io/crates/v/kormir.svg?logo=rust)](https://crates.io/crates/kormir) +[![Documentation](https://img.shields.io/static/v1?logo=read-the-docs&label=docs.rs&message=kormir&color=informational)](https://docs.rs/kormir) + +A DLC oracle implementation for creating announcements and signing attestations. + +Kormir supports both enumeration and numeric events, with optional Nostr protocol integration for publishing oracle data. + +## Usage + +```rust +use kormir::{Oracle, OracleAnnouncement, Storage}; + +// Create oracle from extended private key +let oracle = Oracle::from_xpriv(storage, xpriv)?; + +// Create an enumeration event +let announcement = oracle.create_enum_event( + "game-result", + vec!["team_a".to_string(), "team_b".to_string(), "draw".to_string()], + maturity_epoch, +).await?; + +// Sign the outcome +let attestation = oracle.sign_enum_event("game-result", "team_a").await?; +``` + +## Numeric Events + +```rust +// Create a numeric event (base 2) +let announcement = oracle.create_numeric_event( + "btc-price", + Some(20), // num_digits + Some(false), // is_signed + Some(0), // precision + "USD".to_string(), + maturity_epoch, +).await?; + +// Sign with numeric outcome +let attestation = oracle.sign_numeric_event("btc-price", 50000).await?; +``` + +## Storage Trait + +Implement the `Storage` trait for your backend: + +```rust +#[async_trait] +pub trait Storage { + async fn get_next_nonce_indexes(&self, num: usize) -> Result, Error>; + async fn save_announcement(&self, announcement: OracleAnnouncement, indexes: Vec) -> Result; + async fn save_signatures(&self, event_id: String, sigs: Vec<(String, Signature)>) -> Result; + async fn get_event(&self, event_id: String) -> Result, Error>; +} +``` + +A `MemoryStorage` implementation is provided for testing. + +## Nostr Integration + +With the `nostr` feature, publish announcements and attestations to Nostr: + +```rust +use kormir::nostr_events::{create_announcement_event, create_attestation_event}; + +// Get Nostr keys from oracle +let keys = oracle.nostr_keys(); + +// Create Nostr event for announcement (Kind 88) +let event = create_announcement_event(&keys, &announcement)?; + +// Create Nostr event for attestation (Kind 89) +let event = create_attestation_event(&keys, &attestation, &announcement_event_id)?; +``` + +## Features + +| Feature | Description | +|---------|-------------| +| `nostr` | Nostr protocol integration for publishing oracle data | + +## Running a Kormir Server + +See the [kormir repository](https://github.com/bennyhodl/kormir) for the HTTP server implementation. + +## License + +This project is licensed under the MIT License. diff --git a/payouts/README.md b/payouts/README.md new file mode 100644 index 0000000..ea5efe1 --- /dev/null +++ b/payouts/README.md @@ -0,0 +1,93 @@ +# ddk-payouts + +[![Crate](https://img.shields.io/crates/v/ddk-payouts.svg?logo=rust)](https://crates.io/crates/ddk-payouts) +[![Documentation](https://img.shields.io/static/v1?logo=read-the-docs&label=docs.rs&message=ddk-payouts&color=informational)](https://docs.rs/ddk-payouts) + +Utilities for building payout curves and contract inputs for DLC contracts. + +This crate supports both enumeration-based discrete outcomes and numerical continuous payout functions including options contracts. + +## Enumeration Contracts + +For discrete outcomes like sports events or binary choices: + +```rust +use bitcoin::Amount; +use ddk_dlc::EnumerationPayout; +use ddk_payouts::enumeration; + +let outcome_payouts = vec![ + EnumerationPayout { + outcome: "TeamA_Wins".to_string(), + payout: Payout { offer: 100_000, accept: 0 }, + }, + EnumerationPayout { + outcome: "TeamB_Wins".to_string(), + payout: Payout { offer: 0, accept: 100_000 }, + }, +]; + +let contract = enumeration::create_contract_input( + outcome_payouts, + Amount::from_sat(50_000), // offer_collateral + Amount::from_sat(50_000), // accept_collateral + 2, // fee_rate + oracle_pubkey, + event_id, +); +``` + +## Numerical Contracts + +For price-based continuous payout curves: + +```rust +use bitcoin::Amount; +use ddk_payouts::create_contract_input; + +let contract = create_contract_input( + 0, // min_price + 100_000, // max_price + 10, // num_steps + Amount::from_sat(50_000), // offer_collateral + Amount::from_sat(50_000), // accept_collateral + 2, // fee_rate + oracle_pubkey, + event_id, +); +``` + +## Options Contracts + +For call/put options with strike prices: + +```rust +use bitcoin::Amount; +use ddk_payouts::options::{build_option_order_offer, Direction, OptionType}; + +let contract = build_option_order_offer( + &oracle_announcement, + Amount::ONE_BTC, // contract_size + 50_000, // strike_price + Amount::from_sat(100_000), // premium + 2, // fee_per_byte + 100, // rounding + OptionType::Call, + Direction::Long, + Amount::from_sat(1_000_000), // total_collateral + 20, // nb_oracle_digits +)?; +``` + +## Key Functions + +| Function | Description | +|----------|-------------| +| `create_contract_input` | Build numerical contract with linear payout curve | +| `generate_payout_curve` | Create a `PayoutFunction` with custom parameters | +| `enumeration::create_contract_input` | Build enumeration contract from discrete outcomes | +| `options::build_option_order_offer` | Build options contract (call/put, long/short) | + +## License + +This project is licensed under the MIT License.