The Farcaster atomic swaps project core library aim to implement in Rust the following functionnalities needed to build a swap node:
- Swap offers
- Swap roles and trade roles
- Transaction templates implementing on-chain behaviours (arbitration)
- Signature and cryptographic utilities
-
experimental
ECDSA adaptor signatures (withecdsa_fun
) - Cross-group discrete logarithm proof system
- Schnorr adaptor signature
-
- Messages exchanged between farcaster-node's microservices
- Tasks and blockchain events used by syncers
Currently can be found on docs.rs/farcaster_core. All possible improvments, to add usage examples and to expand on existing docs would be extremely appreciated.
This library is twofold: providing a flexible framework to add specific blockchain support and implementing these specific blockchain. The framework is accessible in modules at the root of the crate:
blockchain
: generic types and constraint traits for on-chain behavior.bundle
: generic types for inter-microservice communication, bonded to arbitrating and accordant traits.consensus
: encoding and decoding implementation for all types in the crate.crypto
: traits and generic types to define cryptographic interactions (wallet capability, commit/reveal scheme, signature and key types, etc).instruction
: types for inter-microservice communication.negotiation
: generic types and utilities for handling the negotiation phase.protocol_message
: generic types exchanged between daemons running a swap toghether.role
: role definition (trade and swap) and implementation over the generic framework.script
: generic types for transaction data management.swap
: swap trait definition, utility types, and swap instance like Btc/Xmr.syncer
: tasks, blockchain events, and errors used by syncers in the microservice architecture.transaction
: transaction traits for building and validating the arbitrating set of transaction.
The blockchain specific support is added under the the following modules:
bitcoin
: support for Bitcoin, implementation of all required traits from the framework, e.g. theArbitrating
trait inrole
module.monero
: support for Monero, implementation of all required traits from the framework, e.g. theAccordant
trait inrole
module.swap/btcxmr
: definition of a swap betweenbitcoin
andmonero
modules.
As default the experimental
feature is enable.
- serde: enable serde implementation on some of the types in the library.
- experimental: enable experimental cryptography, i.e. not battle tested nor peer reviewed and not intended for production use.
To add a blockchain implementation you must implements Aribtrating
or Accordant
trait on your blockchain definition, the trait implemented depends on its blockchain on-chain features, see RFCs for more details.
To add support for Bitcoin we implement the Arbitrating
trait on our definition of Bitcoin
. The implementation contains a strategy allowing variations in SegWit versions or with cryptographic protocols. An experimental
feature include SegwitV0
implementation that supports ECDSA for SegWit v0.
#[derive(Clone, Debug, Copy, Eq, PartialEq)]
pub struct Bitcoin<S: Strategy> { ... };
#[derive(Clone, Debug, Copy, Eq, PartialEq)]
pub struct SegwitV0;
impl Strategy for SegwitV0 {}
impl Arbitrating for Bitcoin<SegwitV0> {}
The implementation of Arbitrating
is void but requires a list of other traits (see src/role.rs
):
pub trait Arbitrating:
Asset
+ Address
+ Fee
+ Keys
+ Onchain
+ Signatures
+ Timelock
+ Transactions
+ SharedPrivateKeys
+ ...
{
}
By implementing all the required traits on our Bitcoin definition we associate external concrete types used later in the framework logic.
impl<S: Strategy> blockchain::Asset for Bitcoin<S> {
/// Type for the traded asset unit for a blockchain.
type AssetUnit = bitcoin::Amount;
...
}
impl<S: Strategy> blockchain::Address for Bitcoin<S> {
/// Defines the address format for the arbitrating blockchain
type Address = bitcoin::Address;
}
impl<S: Strategy> blockchain::Timelock for Bitcoin<S> {
/// Defines the type of timelock used for the arbitrating transactions
type Timelock = bitcoin::timelock::CSVTimelock;
}
Some traits only associate types, some carry more logic such as Keys
in crypto
module that defines the type of keys (public and private) and the number of extra keys needed during the swap. This is useful when off-chain cryptographic protocols such as MuSig2 is used in the implementation and requires extra keys, e.g. nonces.
impl crypto::Keys for Bitcoin<SegwitV0> {
/// Private key type for the blockchain
type PrivateKey = bitcoin::PrivateKey;
/// Public key type for the blockchain
type PublicKey = bitcoin::PublicKey;
fn extra_keys() -> Vec<u16> {
// No extra key
vec![]
}
}
For an arbitrating implementation transactions are required through Onchain
and Transactions
traits, former associate types for partial and final transaction and latter give concrete implementation for every type of transaction.
impl<S: Strategy> blockchain::Onchain for Bitcoin<S> {
/// Defines the transaction format used to transfer partial transaction between participant for
/// the arbitrating blockchain
type PartialTransaction = bitcoin::PartiallySignedTransaction;
/// Defines the finalized transaction format for the arbitrating blockchain
type Transaction = bitcoin::Transaction;
}
impl blockchain::Transactions for Bitcoin<SegwitV0> {
type Metadata = transaction::MetadataOutput;
type Funding = Funding;
type Lock = Tx<Lock>;
type Buy = Tx<Buy>;
type Cancel = Tx<Cancel>;
type Refund = Tx<Refund>;
type Punish = Tx<Punish>;
}
See CHANGELOG.md.
This work is part of the Farcaster cross-chain atomic swap project, see Farcaster Project.
The code in this project is licensed under the LGPL-3.0 License