Browse Source
- Add wallet to maker and taker. For now we have different, static descriptors with a hardcoded DB path. We also only operate on testnet and use sled as a database. - Associate each CET with a unique nonce_pk Eventually a set of `(message, nonce_pk)`. - Share transactions with maker - Add serialisation support to adaptor signature Co-authored-by: Mariusz Klochowicz <mariusz@klochowicz.com> Co-authored-by: Lucas Soriano del Pino <l.soriano.del.pino@gmail.com>verify-transactions
Thomas Eizinger
3 years ago
committed by
Mariusz Klochowicz
16 changed files with 899 additions and 250 deletions
@ -0,0 +1,13 @@ |
|||
use bdk::bitcoin; |
|||
use bdk::bitcoin::secp256k1::{self, SECP256K1}; |
|||
use rand::{CryptoRng, RngCore}; |
|||
|
|||
pub fn new<R>(rng: &mut R) -> (secp256k1::SecretKey, bitcoin::PublicKey) |
|||
where |
|||
R: RngCore + CryptoRng, |
|||
{ |
|||
let sk = secp256k1::SecretKey::new(rng); |
|||
let pk = bitcoin::PublicKey::new(secp256k1::PublicKey::from_secret_key(SECP256K1, &sk)); |
|||
|
|||
(sk, pk) |
|||
} |
@ -1,21 +1,150 @@ |
|||
use crate::model::cfd::CfdOfferId; |
|||
use crate::model::Usd; |
|||
use crate::CfdOffer; |
|||
use bdk::bitcoin::secp256k1::Signature; |
|||
use bdk::bitcoin::util::psbt::PartiallySignedTransaction; |
|||
use bdk::bitcoin::{Address, Amount, PublicKey, Txid}; |
|||
use cfd_protocol::{CfdTransactions, PartyParams, PunishParams}; |
|||
use serde::{Deserialize, Serialize}; |
|||
use serde_with::{serde_as, DisplayFromStr}; |
|||
|
|||
#[serde_as] |
|||
#[derive(Debug, Serialize, Deserialize)] |
|||
pub struct AdaptorSignature(#[serde_as(as = "DisplayFromStr")] cfd_protocol::EcdsaAdaptorSignature); |
|||
|
|||
impl std::ops::Deref for AdaptorSignature { |
|||
type Target = cfd_protocol::EcdsaAdaptorSignature; |
|||
|
|||
fn deref(&self) -> &Self::Target { |
|||
&self.0 |
|||
} |
|||
} |
|||
|
|||
#[derive(Debug, Serialize, Deserialize)] |
|||
#[serde(tag = "type", content = "payload")] |
|||
#[allow(clippy::large_enum_variant)] |
|||
pub enum TakerToMaker { |
|||
TakeOffer { offer_id: CfdOfferId, quantity: Usd }, |
|||
// TODO: Currently the taker starts, can already send some stuff for signing over in the first message.
|
|||
// TODO: Currently the taker starts, can already send some stuff for signing over in the first
|
|||
// message.
|
|||
StartContractSetup(CfdOfferId), |
|||
Protocol(SetupMsg), |
|||
} |
|||
|
|||
#[derive(Debug, Serialize, Deserialize)] |
|||
#[serde(tag = "type", content = "payload")] |
|||
#[allow(clippy::large_enum_variant)] |
|||
pub enum MakerToTaker { |
|||
CurrentOffer(Option<CfdOffer>), |
|||
// TODO: Needs RejectOffer as well
|
|||
ConfirmTakeOffer(CfdOfferId), |
|||
ConfirmTakeOffer(CfdOfferId), // TODO: Include payout curve in "accept" message from maker
|
|||
InvalidOfferId(CfdOfferId), |
|||
Protocol(SetupMsg), |
|||
} |
|||
|
|||
#[derive(Debug, Serialize, Deserialize)] |
|||
#[serde(tag = "type", content = "payload")] |
|||
pub enum SetupMsg { |
|||
Msg0(Msg0), |
|||
Msg1(Msg1), |
|||
} |
|||
|
|||
impl SetupMsg { |
|||
pub fn try_into_msg0(self) -> Result<Msg0, Self> { |
|||
if let Self::Msg0(v) = self { |
|||
Ok(v) |
|||
} else { |
|||
Err(self) |
|||
} |
|||
} |
|||
|
|||
pub fn try_into_msg1(self) -> Result<Msg1, Self> { |
|||
if let Self::Msg1(v) = self { |
|||
Ok(v) |
|||
} else { |
|||
Err(self) |
|||
} |
|||
} |
|||
} |
|||
|
|||
#[derive(Debug, Serialize, Deserialize)] |
|||
pub struct Msg0 { |
|||
pub lock_psbt: PartiallySignedTransaction, // TODO: Use binary representation
|
|||
pub identity_pk: PublicKey, |
|||
#[serde(with = "bdk::bitcoin::util::amount::serde::as_sat")] |
|||
pub lock_amount: Amount, |
|||
pub address: Address, |
|||
pub revocation_pk: PublicKey, |
|||
pub publish_pk: PublicKey, |
|||
} |
|||
|
|||
impl From<(PartyParams, PunishParams)> for Msg0 { |
|||
fn from((party, punish): (PartyParams, PunishParams)) -> Self { |
|||
let PartyParams { |
|||
lock_psbt, |
|||
identity_pk, |
|||
lock_amount, |
|||
address, |
|||
} = party; |
|||
let PunishParams { |
|||
revocation_pk, |
|||
publish_pk, |
|||
} = punish; |
|||
|
|||
Self { |
|||
lock_psbt, |
|||
identity_pk, |
|||
lock_amount, |
|||
address, |
|||
revocation_pk, |
|||
publish_pk, |
|||
} |
|||
} |
|||
} |
|||
|
|||
impl From<Msg0> for (PartyParams, PunishParams) { |
|||
fn from(msg0: Msg0) -> Self { |
|||
let Msg0 { |
|||
lock_psbt, |
|||
identity_pk, |
|||
lock_amount, |
|||
address, |
|||
revocation_pk, |
|||
publish_pk, |
|||
} = msg0; |
|||
|
|||
let party = PartyParams { |
|||
lock_psbt, |
|||
identity_pk, |
|||
lock_amount, |
|||
address, |
|||
}; |
|||
let punish = PunishParams { |
|||
revocation_pk, |
|||
publish_pk, |
|||
}; |
|||
|
|||
(party, punish) |
|||
} |
|||
} |
|||
|
|||
#[derive(Debug, Serialize, Deserialize)] |
|||
pub struct Msg1 { |
|||
pub commit: AdaptorSignature, |
|||
pub cets: Vec<(Txid, AdaptorSignature)>, |
|||
pub refund: Signature, |
|||
} |
|||
|
|||
impl From<CfdTransactions> for Msg1 { |
|||
fn from(txs: CfdTransactions) -> Self { |
|||
Self { |
|||
commit: AdaptorSignature(txs.commit.1), |
|||
cets: txs |
|||
.cets |
|||
.into_iter() |
|||
.map(|(tx, sig, _, _)| (tx.txid(), AdaptorSignature(sig))) |
|||
.collect(), |
|||
refund: txs.refund.1, |
|||
} |
|||
} |
|||
} |
|||
|
Loading…
Reference in new issue