1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//! Stateless DLC contract lifecycle.
//!
//! This module completes a DLC using only wire messages, explicit party data,
//! and PSBTs. There is no contract manager, no persisted contract state, no
//! storage backend, and no blockchain client: every operation rebuilds and
//! validates what it needs from the [`OfferDlc`](ddk_messages::OfferDlc),
//! [`AcceptDlc`](ddk_messages::AcceptDlc), and [`SignDlc`](ddk_messages::SignDlc)
//! messages, which are the authoritative state.
//!
//! # Lifecycle
//!
//! ```text
//! offer party accept party
//! ----------- ------------
//! create_offer ──────────── OfferDlc ──────► accept_offer ─┐
//! │ AcceptResult
//! ┌──────────────────────── AcceptDlc ◄─────────────────────┘
//! │ create_funding_psbt
//! │ sign own inputs (signing::*)
//! │ sign_accept ──────────── SignDlc ──────► create_funding_psbt
//! │ sign own inputs (signing::*)
//! │ finalize_sign ──► Transaction
//! │ broadcast via chain client
//! │
//! │ ... the oracles attest, or the refund locktime passes ...
//! │
//! └─ sign_cet / sign_refund ──► Transaction sign_cet / sign_refund ──► Transaction
//! broadcast via chain client broadcast via chain client
//! ```
//!
//! Either party can settle on its own, and neither needs the other's
//! cooperation to do it: the counterparty's half of the 2-of-2 spend was
//! committed in the messages it already sent.
//!
//! Each party retains only the three wire messages, its DLC funding secret key,
//! and access to the keys of its funding inputs. Everything else — the funding
//! transaction, the CETs, the refund transaction, the contract id, the adaptor
//! information — is rebuilt from those messages whenever it is needed.
//!
//! The `SignDlc` matters to each side differently: the accepting party settles
//! with the signatures it carries, while for the offering party it only
//! confirms that the three messages describe one contract.
//!
//! # PSBT as the signing boundary
//!
//! Funding inputs are regular wallet UTXOs, and wallets speak PSBT. The
//! funding PSBT built by [`create_funding_psbt`](crate::contract::create_funding_psbt) carries everything a signer
//! needs (`witness_utxo`, `non_witness_utxo`, redeem scripts, sighash type)
//! and never contains private key material. [`sign_accept`](crate::contract::sign_accept) and
//! [`finalize_sign`](crate::contract::finalize_sign) verify that a returned PSBT spends exactly the funding
//! transaction rebuilt from the messages — input count, outpoints, outputs,
//! locktime, and sequences — before extracting witnesses, so a signer cannot
//! mutate the transaction.
//!
//! Four funding sources produce those witnesses through the same lifecycle
//! (see [`signing`](crate::contract::signing)):
//!
//! | Source | How |
//! |--------|-----|
//! | DDK wallet | [`signing::sign_funding_psbt_with_wallet`](crate::contract::signing::sign_funding_psbt_with_wallet) with any [`ddk_manager::Wallet`] |
//! | Raw xpriv | [`signing::sign_funding_psbt_with_xpriv`](crate::contract::signing::sign_funding_psbt_with_xpriv) with per-input BIP32 paths |
//! | Private descriptor | [`signing::sign_funding_psbt_with_descriptor`](crate::contract::signing::sign_funding_psbt_with_descriptor) with per-input indexes |
//! | External / hardware signer | serialize the PSBT, sign and finalize externally, deserialize |
//!
//! # DLC funding keys versus wallet input keys
//!
//! Each party uses two kinds of keys. The *DLC funding key*
//! ([`PartyParams::funding_pubkey`](crate::contract::PartyParams::funding_pubkey) and the `funding_secret_key` arguments) is
//! a single secp256k1 key that controls the 2-of-2 funding output, the CET
//! adaptor signatures, and the refund signature. The *wallet input keys*
//! control the UTXOs spent into the funding transaction and never touch DLC
//! cryptography — they only sign the funding PSBT. A hardware wallet can hold
//! the input keys (PSBT exchange) while the application holds the DLC funding
//! key.
//!
//! # Script support
//!
//! Built-in signers support native P2WPKH and P2SH-P2WPKH funding inputs;
//! descriptor signing supports `wpkh()` and `sh(wpkh())`, with or without a
//! wildcard. Unsupported script types fail with
//! [`ContractError::UnsupportedScriptType`](crate::contract::ContractError::UnsupportedScriptType) rather than producing incomplete
//! signatures. External signers can fund with any script type they can
//! finalize themselves.
//!
//! # Splicing
//!
//! A new contract can spend a previous contract's 2-of-2 funding output as an
//! input (a *splice*), which is how rollovers and collateral changes are
//! expressed. Only the offering party may contribute a splice input. Build it
//! from the previous contract's messages with
//! [`create_dlc_splice_input`](crate::contract::create_dlc_splice_input) and
//! place it in the offering party's funding inputs. Signing the prior 2-of-2
//! additionally requires each party's *previous-contract* funding secret key,
//! supplied to [`sign_accept_spliced`](crate::contract::sign_accept_spliced)
//! (offering party) and
//! [`finalize_sign_spliced`](crate::contract::finalize_sign_spliced) (accepting
//! party) as [`DlcInputSigningKey`](crate::contract::DlcInputSigningKey) values.
//!
//! # Settlement
//!
//! A funded contract ends in one of two transactions, both of which spend the
//! 2-of-2 funding output and are built entirely from the wire messages:
//!
//! | Outcome | Function | Counterparty's half comes from |
//! |---------|----------|-------------------------------|
//! | the oracles attest | [`sign_cet`](crate::contract::sign_cet) | its CET adaptor signature, decrypted with the oracle signatures |
//! | nobody attests | [`sign_refund`](crate::contract::sign_refund) | its refund signature, sent with the accept or sign message |
//!
//! Both take the settling party's DLC funding secret key, which supplies this
//! party's half of the 2-of-2 spend and identifies which side is settling — so
//! the same call works for either party. [`sign_cet`](crate::contract::sign_cet)
//! additionally takes the oracle attestations, each paired with the index of
//! its oracle in the contract's announcements; it selects the matching CET,
//! verifies the attestations against the announcements they claim to come from,
//! and returns the signed transaction.
//!
//! Neither function enforces *when* a transaction may be broadcast. CETs carry
//! the offer's `cet_locktime` and the refund its `refund_locktime`; the chain
//! enforces those, and deciding which settlement path to take is the caller's
//! policy.
//!
//! Settling is the most expensive operation in the module: selecting a CET
//! means reconstructing the contract's adaptor information, which for a
//! large numeric contract is the same order of work as accepting it. That is
//! the cost of keeping no state.
//!
//! # Broadcasting and storage stay with the caller
//!
//! [`finalize_sign`](crate::contract::finalize_sign) returns a fully signed [`bitcoin::Transaction`];
//! broadcast it with the chain client of your choice (for example
//! [`ddk_manager::Blockchain::send_transaction`] implemented by
//! [`crate::chain::EsploraClient`]). Persisting messages for later execution
//! is likewise the caller's responsibility.
//!
//! Lower-level operations (raw witnesses, adaptor signatures, contract ids)
//! live in [`advanced`](crate::contract::advanced).
pub use ;
pub use ;
pub use ContractError;
pub use ;
pub use ContractKeyProvider;
pub use create_funding_psbt;
pub use ;
pub use ;
pub use ;
pub use ;
/// The current DLC protocol version used by DDK.
pub const PROTOCOL_VERSION: u32 = 1;