From 8ffe11c489743c4f094d8c94a2d4e4770cccfe73 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 24 Jan 2025 16:17:04 +0100 Subject: [PATCH 01/11] update to use payment branch --- Cargo.lock | 66 +++++++++++++++++++++++++------------------------- Cargo.toml | 4 +-- cli/src/cmd.rs | 13 +++++----- src/runtime.rs | 6 ++--- 4 files changed, 45 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c27d40..4a8de99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -175,9 +175,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "aws-lc-rs" -version = "1.12.0" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f409eb70b561706bf8abba8ca9c112729c481595893fd06a2dd9af8ed8441148" +checksum = "4c2b7ddaa2c56a367ad27a094ad8ef4faacf8a617c2575acb2ba88949df999ca" dependencies = [ "aws-lc-sys", "paste", @@ -186,9 +186,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "923ded50f602b3007e5e63e3f094c479d9c8a9b42d7f4034e4afe456aa48bfd2" +checksum = "71b2ddd3ada61a305e1d8bb6c005d1eaa7d14d903681edfc400406d523a9b491" dependencies = [ "bindgen", "cc", @@ -345,7 +345,7 @@ dependencies = [ "bp-invoice", "commit_verify", "hmac", - "indexmap 2.7.0", + "indexmap 2.7.1", "serde", "sha2", ] @@ -471,9 +471,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.2.9" +version = "1.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" +checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" dependencies = [ "jobserver", "libc", @@ -523,9 +523,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.26" +version = "4.5.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" +checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796" dependencies = [ "clap_builder", "clap_derive", @@ -533,9 +533,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.26" +version = "4.5.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" +checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" dependencies = [ "anstream", "anstyle", @@ -702,7 +702,7 @@ source = "git+https://github.com/BP-WG/bp-std?branch=v0.12#f34c9a1de88293a370095 dependencies = [ "amplify", "bp-derive", - "indexmap 2.7.0", + "indexmap 2.7.1", "serde", ] @@ -930,13 +930,13 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hypersonic" version = "0.12.0-beta.4" -source = "git+https://github.com/AluVM/sonic?branch=master#5eb21d80bb2e00ff386adcd12b191be1e937a6f2" +source = "git+https://github.com/AluVM/sonic?branch=master#02fea6d4472bfada05555f2a01348787498add23" dependencies = [ "aluvm", "amplify", "commit_verify", "getrandom", - "indexmap 2.7.0", + "indexmap 2.7.1", "serde", "serde_yaml", "sonic-api", @@ -1128,9 +1128,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -1373,7 +1373,7 @@ dependencies = [ "bp-derive", "commit_verify", "descriptors", - "indexmap 2.7.0", + "indexmap 2.7.1", "serde", "strict_encoding", ] @@ -1496,7 +1496,7 @@ dependencies = [ [[package]] name = "rgb-invoice" version = "0.12.0-beta.4" -source = "git+https://github.com/RGB-WG/rgb-std?branch=v0.12#b0b072f48799d40c9ce279e60e7f3870449040a9" +source = "git+https://github.com/RGB-WG/rgb-std?branch=payments#688aa844b36aeb8fde9c18c9aec27d318f3941f2" dependencies = [ "amplify", "baid64", @@ -1529,7 +1529,7 @@ dependencies = [ "bp-wallet", "commit_verify", "getrandom", - "indexmap 2.7.0", + "indexmap 2.7.1", "log", "nonasync", "rand", @@ -1543,7 +1543,7 @@ dependencies = [ [[package]] name = "rgb-std" version = "0.12.0-beta.4" -source = "git+https://github.com/RGB-WG/rgb-std?branch=v0.12#b0b072f48799d40c9ce279e60e7f3870449040a9" +source = "git+https://github.com/RGB-WG/rgb-std?branch=payments#688aa844b36aeb8fde9c18c9aec27d318f3941f2" dependencies = [ "amplify", "bp-core", @@ -1611,9 +1611,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.43" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags", "errno", @@ -1720,9 +1720,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.135" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" +checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b" dependencies = [ "itoa", "memchr", @@ -1759,7 +1759,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.7.0", + "indexmap 2.7.1", "serde", "serde_derive", "serde_json", @@ -1785,7 +1785,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.7.0", + "indexmap 2.7.1", "itoa", "ryu", "serde", @@ -1848,7 +1848,7 @@ dependencies = [ [[package]] name = "sonic-api" version = "0.12.0-beta.4" -source = "git+https://github.com/AluVM/sonic?branch=master#5eb21d80bb2e00ff386adcd12b191be1e937a6f2" +source = "git+https://github.com/AluVM/sonic?branch=master#02fea6d4472bfada05555f2a01348787498add23" dependencies = [ "aluvm", "amplify", @@ -1867,13 +1867,13 @@ dependencies = [ [[package]] name = "sonic-callreq" version = "0.12.0-beta.4" -source = "git+https://github.com/AluVM/sonic?branch=master#5eb21d80bb2e00ff386adcd12b191be1e937a6f2" +source = "git+https://github.com/AluVM/sonic?branch=master#02fea6d4472bfada05555f2a01348787498add23" dependencies = [ "amplify", "baid64", "chrono", "fluent-uri", - "indexmap 2.7.0", + "indexmap 2.7.1", "percent-encoding", "serde", "strict_encoding", @@ -1926,7 +1926,7 @@ checksum = "3e208d1bd29a0f70d7ee90a91d76446b8bb7b1b8212d06e031e396d52e2fe891" dependencies = [ "amplify", "baid64", - "indexmap 2.7.0", + "indexmap 2.7.1", "serde", "serde_json", "serde_yaml", @@ -2080,7 +2080,7 @@ version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.7.0", + "indexmap 2.7.1", "serde", "serde_spanned", "toml_datetime", @@ -2110,9 +2110,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "11cd88e12b17c6494200a9c1b683a04fcac9573ed74cd1b62aeb2727c5592243" [[package]] name = "unsafe-libyaml" diff --git a/Cargo.toml b/Cargo.toml index c390a79..37ca44f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -105,5 +105,5 @@ psbt = { git = "https://github.com/BP-WG/bp-std", branch = "v0.12" } bp-std = { git = "https://github.com/BP-WG/bp-std", branch = "v0.12" } bp-wallet = { git = "https://github.com/BP-WG/bp-wallet", branch = "v0.12" } rgb-core = { git = "https://github.com/RGB-WG/rgb-core", branch = "v0.12" } -rgb-std = { git = "https://github.com/RGB-WG/rgb-std", branch = "v0.12" } -rgb-invoice = { git = "https://github.com/RGB-WG/rgb-std", branch = "v0.12" } +rgb-std = { git = "https://github.com/RGB-WG/rgb-std", branch = "payments" } +rgb-invoice = { git = "https://github.com/RGB-WG/rgb-std", branch = "payments" } diff --git a/cli/src/cmd.rs b/cli/src/cmd.rs index 2960a15..4423125 100644 --- a/cli/src/cmd.rs +++ b/cli/src/cmd.rs @@ -37,7 +37,7 @@ use bpwallet::{AnyIndexer, Keychain, Network, Psbt, Sats, Wpkh, XpubDerivable}; use clap::ValueHint; use rgb::invoice::RgbInvoice; use rgb::popls::bp::file::{BpDirMound, DirBarrow}; -use rgb::popls::bp::{PrefabBundle, PrefabParamsSet, WoutAssignment}; +use rgb::popls::bp::{OpRequestSet, PrefabBundle, WoutAssignment}; use rgb::{AuthToken, Consensus, ContractId, CreateParams, Outpoint}; use rgbp::descriptor::RgbDescr; use rgbp::{CoinselectStrategy, RgbDirRuntime, RgbWallet}; @@ -427,7 +427,7 @@ impl Args { let state = if *all { runtime.state_all(*contract).collect::>() } else { - runtime.state(*contract).collect() + runtime.state_own(*contract).collect() }; for (contract_id, state) in state { println!("{contract_id}"); @@ -502,7 +502,8 @@ impl Args { } => { let mut runtime = self.runtime(wallet.as_deref()); let src = File::open(script).expect("Unable to open script file"); - let items = serde_yaml::from_reader::<_, PrefabParamsSet>(src)?; + let items = + serde_yaml::from_reader::<_, OpRequestSet>>(src)?; let (mut psbt, meta) = runtime .construct_psbt(&items, TxParams::with(*fee)) @@ -518,8 +519,8 @@ impl Args { // Here we send PSBT to other payjoin parties so they add their inputs and outputs, // or even re-order existing ones - let items = items.resolve_seals(psbt.script_resolver())?; - let bundle = runtime.bundle(items, meta.change_vout.expect("no change output")); + let items = items.resolve_seals(psbt.script_resolver(), meta.change_vout)?; + let bundle = runtime.bundle(items, meta.change_vout)?; bundle .strict_serialize_to_file::<{ usize::MAX }>(&bundle_filename) .expect("Unable to write output file"); @@ -550,7 +551,7 @@ impl Args { let mut runtime = self.runtime(wallet.as_deref()); let (mpc, dbc) = psbt.dbc_commit()?; let tx = psbt.to_unsigned_tx(); - runtime.attest(&bundle, &tx.into(), mpc, dbc, &prevouts); + runtime.include(&bundle, &tx.into(), mpc, dbc, &prevouts)?; psbt.encode( psbt.version, diff --git a/src/runtime.rs b/src/runtime.rs index ca2fd9d..0cdff9c 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -27,7 +27,7 @@ use std::ops::{Deref, DerefMut}; use bpstd::psbt::{Beneficiary, ConstructionError, PsbtConstructor, PsbtMeta, TxParams}; use bpstd::seals::TxoSeal; use bpstd::{Address, Psbt}; -use rgb::popls::bp::{Barrow, PrefabParamsSet, WoutAssignment}; +use rgb::popls::bp::{Barrow, OpRequestSet, WoutAssignment}; use rgb::{EitherSeal, Excavate, Pile, Supply}; use crate::wallet::RgbWallet; @@ -53,7 +53,7 @@ impl, X: Excavate> DerefMut for RgbRunt impl, X: Excavate> RgbRuntime { pub fn construct_psbt( &mut self, - bundle: &PrefabParamsSet, + bundle: &OpRequestSet>, params: TxParams, ) -> Result<(Psbt, PsbtMeta), ConstructionError> { let closes = bundle @@ -65,7 +65,7 @@ impl, X: Excavate> RgbRuntime .iter() .flat_map(|params| ¶ms.owned) .filter_map(|assignment| match &assignment.state.seal { - EitherSeal::Alt(seal) => Some(seal), + EitherSeal::Alt(seal) => seal.as_ref(), EitherSeal::Token(_) => None, }) .map(|seal| { From 74be135368ccd3bc026afccf9fb9555e9d4f8184 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 18 Jan 2025 18:49:27 +0100 Subject: [PATCH 02/11] payments workflows --- Cargo.lock | 12 +++-- Cargo.toml | 3 ++ cli/src/cmd.rs | 36 +++++++++++-- psbt/src/bp.rs | 8 +-- psbt/src/common.rs | 2 +- src/coinselect.rs | 51 +++++++++++++++++-- src/lib.rs | 4 +- src/runtime.rs | 123 ++++++++++++++++++++++++++++++++++++--------- src/wallet.rs | 33 ++++++++++-- 9 files changed, 224 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a8de99..b7adffb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -930,7 +930,7 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hypersonic" version = "0.12.0-beta.4" -source = "git+https://github.com/AluVM/sonic?branch=master#02fea6d4472bfada05555f2a01348787498add23" +source = "git+https://github.com/AluVM/sonic?branch=master#9c26410b570b9d51f54bb92f2909333631b16a01" dependencies = [ "aluvm", "amplify", @@ -1496,7 +1496,7 @@ dependencies = [ [[package]] name = "rgb-invoice" version = "0.12.0-beta.4" -source = "git+https://github.com/RGB-WG/rgb-std?branch=payments#688aa844b36aeb8fde9c18c9aec27d318f3941f2" +source = "git+https://github.com/RGB-WG/rgb-std?branch=payments#d19bfefb813240e2e6edbcb99dfb1abd0358166c" dependencies = [ "amplify", "baid64", @@ -1533,9 +1533,11 @@ dependencies = [ "log", "nonasync", "rand", + "rgb-psbt", "rgb-std", "serde", "serde_yaml", + "strict_types", "wasm-bindgen", "wasm-bindgen-test", ] @@ -1543,7 +1545,7 @@ dependencies = [ [[package]] name = "rgb-std" version = "0.12.0-beta.4" -source = "git+https://github.com/RGB-WG/rgb-std?branch=payments#688aa844b36aeb8fde9c18c9aec27d318f3941f2" +source = "git+https://github.com/RGB-WG/rgb-std?branch=payments#d19bfefb813240e2e6edbcb99dfb1abd0358166c" dependencies = [ "amplify", "bp-core", @@ -1848,7 +1850,7 @@ dependencies = [ [[package]] name = "sonic-api" version = "0.12.0-beta.4" -source = "git+https://github.com/AluVM/sonic?branch=master#02fea6d4472bfada05555f2a01348787498add23" +source = "git+https://github.com/AluVM/sonic?branch=master#9c26410b570b9d51f54bb92f2909333631b16a01" dependencies = [ "aluvm", "amplify", @@ -1867,7 +1869,7 @@ dependencies = [ [[package]] name = "sonic-callreq" version = "0.12.0-beta.4" -source = "git+https://github.com/AluVM/sonic?branch=master#02fea6d4472bfada05555f2a01348787498add23" +source = "git+https://github.com/AluVM/sonic?branch=master#9c26410b570b9d51f54bb92f2909333631b16a01" dependencies = [ "amplify", "baid64", diff --git a/Cargo.toml b/Cargo.toml index 37ca44f..f2e1ef7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ license = "Apache-2.0" amplify = "4.8.0" nonasync = "0.1.2" strict_encoding = "2.8.1" +strict_types = "2.8.1" commit_verify = "=0.12.0-beta.4" bp-std = { version = "=0.12.0-beta.4", features = ["client-side-validation"] } bp-electrum = "=0.12.0-beta.4" @@ -51,10 +52,12 @@ crate-type = ["cdylib", "rlib"] [dependencies] amplify = { workspace = true } commit_verify = { workspace = true } +strict_types = { workspace = true } nonasync = { workspace = true } bp-std = { workspace = true } bp-wallet = { workspace = true } rgb-std = { workspace = true, features = ["bitcoin"] } +rgb-psbt.workspace = true indexmap = { workspace = true } serde = { workspace = true, optional = true } serde_yaml = { workspace = true, optional = true } diff --git a/cli/src/cmd.rs b/cli/src/cmd.rs index 4423125..9d7a6da 100644 --- a/cli/src/cmd.rs +++ b/cli/src/cmd.rs @@ -210,8 +210,17 @@ pub enum Cmd { #[clap(short, long, default_value = "aggregate", env = RGB_COINSELECT_STRATEGY_ENV)] strategy: CoinselectStrategy, - /// Invoice to fylfill - invoice: RgbInvoice, + /// Invoice to fulfill + invoice: RgbInvoice, + + /// Fees for PSBT + fee: Sats, + + /// File to save the produced PSBT + /// + /// If not provided, prints PSBT to standard output. + #[clap(value_hint = ValueHint::FilePath)] + psbt: Option, }, /// Execute a script, producing prefabricated operation bundle and PSBT @@ -492,6 +501,23 @@ impl Args { } } + Cmd::Pay { wallet, strategy, invoice, fee, psbt: psbt_filename } => { + let mut runtime = self.runtime(wallet.wallet.as_deref()); + // TODO: sync wallet if needed + // TODO: Add params and giveway to arguments + let params = TxParams::with(*fee); + let giveaway = Some(Sats::from(500u16)); + let psbt = runtime.pay_invoice(invoice, *strategy, params, giveaway)?; + if let Some(psbt_filename) = psbt_filename { + psbt.encode( + psbt.version, + &mut File::create(psbt_filename).expect("Unable to write PSBT"), + )?; + } else { + println!("{psbt}"); + } + } + Cmd::Exec { wallet, script, @@ -506,7 +532,8 @@ impl Args { serde_yaml::from_reader::<_, OpRequestSet>>(src)?; let (mut psbt, meta) = runtime - .construct_psbt(&items, TxParams::with(*fee)) + .wallet + .compose_psbt(&items, TxParams::with(*fee)) .expect("Unable to construct PSBT"); let mut psbt_file = File::create_new( psbt_filename @@ -519,13 +546,14 @@ impl Args { // Here we send PSBT to other payjoin parties so they add their inputs and outputs, // or even re-order existing ones + // TODO: Replace this with `color` function let items = items.resolve_seals(psbt.script_resolver(), meta.change_vout)?; let bundle = runtime.bundle(items, meta.change_vout)?; bundle .strict_serialize_to_file::<{ usize::MAX }>(&bundle_filename) .expect("Unable to write output file"); - psbt.rgb_fill_csv(bundle) + psbt.rgb_fill_csv(&bundle) .expect("Unable to embed RGB information to PSBT"); psbt.encode(psbt.version, &mut psbt_file) .expect("Unable to write PSBT"); diff --git a/psbt/src/bp.rs b/psbt/src/bp.rs index 8c97bb2..5900469 100644 --- a/psbt/src/bp.rs +++ b/psbt/src/bp.rs @@ -30,16 +30,16 @@ use rgb::popls::bp::PrefabBundle; use crate::{RgbPsbt, RgbPsbtError, ScriptResolver}; impl RgbPsbt for Psbt { - fn rgb_fill_csv(&mut self, bundle: PrefabBundle) -> Result<(), RgbPsbtError> { + fn rgb_fill_csv(&mut self, bundle: &PrefabBundle) -> Result<(), RgbPsbtError> { for prefab in bundle { let id = mpc::ProtocolId::from_byte_array(prefab.operation.contract_id.to_byte_array()); let opid = prefab.operation.opid(); let msg = mmb::Message::from_byte_array(opid.to_byte_array()); - for outpoint in prefab.closes { + for outpoint in &prefab.closes { let input = self .inputs_mut() - .find(|inp| inp.previous_outpoint == outpoint) - .ok_or(RgbPsbtError::InputAbsent(outpoint))?; + .find(|inp| inp.previous_outpoint == *outpoint) + .ok_or(RgbPsbtError::InputAbsent(*outpoint))?; input.set_mmb_message(id, msg).map_err(|_| { RgbPsbtError::InputAlreadyUsed(input.index(), prefab.operation.contract_id) })?; diff --git a/psbt/src/common.rs b/psbt/src/common.rs index 5ed1bf5..4e440a4 100644 --- a/psbt/src/common.rs +++ b/psbt/src/common.rs @@ -28,7 +28,7 @@ use rgb::{ContractId, Outpoint}; pub trait RgbPsbt { // TODO: Add rgb_embed to embed operations for hardware signers - fn rgb_fill_csv(&mut self, bundle: PrefabBundle) -> Result<(), RgbPsbtError>; + fn rgb_fill_csv(&mut self, bundle: &PrefabBundle) -> Result<(), RgbPsbtError>; fn rgb_complete(&mut self) -> Result<(), Unmodifiable>; } diff --git a/src/coinselect.rs b/src/coinselect.rs index ece933c..4557c90 100644 --- a/src/coinselect.rs +++ b/src/coinselect.rs @@ -22,14 +22,22 @@ // or implied. See the License for the specific language governing permissions and limitations under // the License. -use std::str::FromStr; +use core::str::FromStr; + +use rgb::popls::bp::Coinselect; +use rgb::{CellAddr, StateCalc}; +use strict_types::StrictVal; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Display, Default)] #[display(lowercase)] pub enum CoinselectStrategy { + /// Collect them most small outputs unless the invoiced value if reached #[default] Aggregate, - Size, + + /// Collect the minimum number of outputs (with the large value) to reduce the resulting input + /// count + SmallSize, } impl FromStr for CoinselectStrategy { @@ -38,8 +46,45 @@ impl FromStr for CoinselectStrategy { fn from_str(s: &str) -> Result { match s.to_lowercase().as_str() { "aggregate" => Ok(CoinselectStrategy::Aggregate), - "size" => Ok(CoinselectStrategy::Size), + "smallsize" => Ok(CoinselectStrategy::SmallSize), s => Err(s.to_string()), } } } + +impl Coinselect for CoinselectStrategy { + fn coinselect( + &mut self, + invoiced_state: &StrictVal, + calc: &mut (impl StateCalc + ?Sized), + owned_state: Vec<(CellAddr, &StrictVal)>, + ) -> Option> { + let res = match self { + CoinselectStrategy::Aggregate => owned_state + .into_iter() + .take_while(|(_, val)| { + if calc.is_satisfied(invoiced_state) { + return false; + } + calc.accumulate(*val).is_ok() + }) + .map(|(addr, _)| addr) + .collect(), + CoinselectStrategy::SmallSize => owned_state + .into_iter() + .rev() + .take_while(|(_, val)| { + if calc.is_satisfied(invoiced_state) { + return false; + } + calc.accumulate(*val).is_ok() + }) + .map(|(addr, _)| addr) + .collect(), + }; + if !calc.is_satisfied(invoiced_state) { + return None; + }; + Some(res) + } +} diff --git a/src/lib.rs b/src/lib.rs index bc212d9..9fceccb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,6 +39,6 @@ mod runtime; pub use coinselect::CoinselectStrategy; #[cfg(feature = "fs")] -pub use runtime::file::RgbDirRuntime; -pub use runtime::RgbRuntime; +pub use runtime::file::{ConsignmentStream, RgbDirRuntime, Transfer}; +pub use runtime::{PayError, RgbRuntime, TransferError}; pub use wallet::RgbWallet; diff --git a/src/runtime.rs b/src/runtime.rs index 0cdff9c..0549fc7 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -24,13 +24,18 @@ use std::ops::{Deref, DerefMut}; -use bpstd::psbt::{Beneficiary, ConstructionError, PsbtConstructor, PsbtMeta, TxParams}; +use bpstd::psbt::{ConstructionError, DbcPsbtError, TxParams}; use bpstd::seals::TxoSeal; -use bpstd::{Address, Psbt}; -use rgb::popls::bp::{Barrow, OpRequestSet, WoutAssignment}; -use rgb::{EitherSeal, Excavate, Pile, Supply}; +use bpstd::{Psbt, Sats}; +use rgb::invoice::RgbInvoice; +use rgb::popls::bp::{ + Barrow, BundleError, FulfillError, IncludeError, OpRequestSet, WoutAssignment, +}; +use rgb::{ContractId, Excavate, Pile, Supply}; +use rgpsbt::{RgbPsbt, RgbPsbtError, ScriptResolver}; use crate::wallet::RgbWallet; +use crate::CoinselectStrategy; pub struct RgbRuntime, X: Excavate>( Barrow, @@ -51,37 +56,105 @@ impl, X: Excavate> DerefMut for RgbRunt } impl, X: Excavate> RgbRuntime { - pub fn construct_psbt( + /// Pays an invoice producing PSBT ready to be signed + /// + /// Should not be used in multi-party protocols like coinjoins, when a PSBT may needs to be + /// modified in the number of inputs or outputs. Use `construct_psbt` method for such + /// scenarios. + /// + /// If you need more flexibility in constructing payments (do multiple payments with multiple + /// contracts, use global state etc.) in a single PSBT, please use `pay_custom` APIs and + /// [`PrefabBundleSet`] stead of this simplified API. + pub fn pay_invoice( &mut self, - bundle: &OpRequestSet>, + invoice: &RgbInvoice, + strategy: CoinselectStrategy, params: TxParams, - ) -> Result<(Psbt, PsbtMeta), ConstructionError> { - let closes = bundle - .iter() - .flat_map(|params| ¶ms.using) - .map(|used| used.outpoint); - let network = self.0.wallet.network(); - let beneficiaries = bundle - .iter() - .flat_map(|params| ¶ms.owned) - .filter_map(|assignment| match &assignment.state.seal { - EitherSeal::Alt(seal) => seal.as_ref(), - EitherSeal::Token(_) => None, - }) - .map(|seal| { - let address = Address::with(&seal.wout.script_pubkey(), network) - .expect("script pubkey which is not representable as an address"); - Beneficiary::new(address, seal.amount) - }); - self.0.wallet.construct_psbt(closes, beneficiaries, params) + giveaway: Option, + ) -> Result { + let request = self.fulfill(invoice, strategy, giveaway)?; + let bundle = OpRequestSet::with(request); + let psbt = self.transfer(bundle, params)?; + Ok(psbt) } + + /// Constructs transfer, consisting of PSBT and a consignment stream + // TODO: Return a dedicated Transfer object which can stream a consignment + pub fn transfer( + &mut self, + set: OpRequestSet>, + params: TxParams, + ) -> Result { + let (mut psbt, meta) = self.0.wallet.compose_psbt(&set, params)?; + let items = set + .resolve_seals(psbt.script_resolver(), meta.change_vout) + .map_err(|_| TransferError::ChangeRequired)?; + let bundle = self.bundle(items, meta.change_vout)?; + + psbt.rgb_fill_csv(&bundle)?; + + psbt.rgb_complete() + .expect("PSBT is modifiable since it is just constructed"); + let (mpc, dbc) = psbt.dbc_commit()?; + let tx = psbt.to_unsigned_tx(); + + let prevouts = psbt + .inputs() + .map(|inp| inp.previous_outpoint) + .collect::>(); + self.include(&bundle, &tx.into(), mpc, dbc, &prevouts)?; + + Ok(psbt) + } +} + +#[derive(Clone, Debug, Display, Error, From)] +#[display(inner)] +pub enum PayError { + #[from] + Fulfill(FulfillError), + #[from] + Transfer(TransferError), +} + +#[derive(Clone, Debug, Display, Error, From)] +#[display(inner)] +pub enum TransferError { + #[from] + PsbtConstruct(ConstructionError), + + #[from] + PsbtRgb(RgbPsbtError), + + #[from] + PsbtDbc(DbcPsbtError), + + #[from] + Bundle(BundleError), + + #[from] + Include(IncludeError), + + #[display("transfer doesn't create BTC change output, which is required for RGB change")] + ChangeRequired, } #[cfg(feature = "fs")] pub mod file { + use std::io; + use rgb::{DirExcavator, FilePile, FileSupply}; use super::*; pub type RgbDirRuntime = RgbRuntime, DirExcavator>; + + pub trait ConsignmentStream { + fn write(self, writer: impl io::Write) -> io::Result<()>; + } + + pub struct Transfer { + pub psbt: Psbt, + pub consignment: C, + } } diff --git a/src/wallet.rs b/src/wallet.rs index 74092f0..cb74844 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -25,13 +25,13 @@ use std::convert::Infallible; use amplify::Bytes32; -use bpstd::psbt::PsbtConstructor; +use bpstd::psbt::{Beneficiary, ConstructionError, PsbtConstructor, PsbtMeta, TxParams}; use bpstd::seals::TxoSeal; -use bpstd::{Address, Keychain, Network, Outpoint, XpubDerivable}; +use bpstd::{Address, Keychain, Network, Outpoint, Psbt, XpubDerivable}; use bpwallet::{Layer2Empty, NoLayer2, Wallet, WalletCache, WalletData, WalletDescr}; use nonasync::persistence::{PersistenceError, PersistenceProvider}; -use rgb::popls::bp::WalletProvider; -use rgb::{AuthToken, SealAuthToken}; +use rgb::popls::bp::{OpRequestSet, WalletProvider, WoutAssignment}; +use rgb::{AuthToken, EitherSeal, SealAuthToken}; use crate::descriptor::RgbDescr; @@ -103,4 +103,29 @@ impl RgbWallet { + 'static { Wallet::load(provider, autosave).map(RgbWallet) } + + pub fn compose_psbt( + &mut self, + bundle: &OpRequestSet>, + params: TxParams, + ) -> Result<(Psbt, PsbtMeta), ConstructionError> { + let closes = bundle + .iter() + .flat_map(|params| ¶ms.using) + .map(|used| used.outpoint); + let network = self.network(); + let beneficiaries = bundle + .iter() + .flat_map(|params| ¶ms.owned) + .filter_map(|assignment| match &assignment.state.seal { + EitherSeal::Alt(seal) => seal.as_ref(), + EitherSeal::Token(_) => None, + }) + .map(|seal| { + let address = Address::with(&seal.wout.script_pubkey(), network) + .expect("script pubkey which is not representable as an address"); + Beneficiary::new(address, seal.amount) + }); + self.construct_psbt(closes, beneficiaries, params) + } } From 1c59090ef291ef9f1b4818dee94483d2fe03f477 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 25 Jan 2025 12:32:31 +0100 Subject: [PATCH 03/11] use PaymentScript type alias --- Cargo.lock | 8 ++++---- src/runtime.rs | 4 ++-- src/wallet.rs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b7adffb..0551f4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -624,9 +624,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] @@ -1496,7 +1496,7 @@ dependencies = [ [[package]] name = "rgb-invoice" version = "0.12.0-beta.4" -source = "git+https://github.com/RGB-WG/rgb-std?branch=payments#d19bfefb813240e2e6edbcb99dfb1abd0358166c" +source = "git+https://github.com/RGB-WG/rgb-std?branch=payments#79e68c101d8e297a9e3a99100f1da727deda00e5" dependencies = [ "amplify", "baid64", @@ -1545,7 +1545,7 @@ dependencies = [ [[package]] name = "rgb-std" version = "0.12.0-beta.4" -source = "git+https://github.com/RGB-WG/rgb-std?branch=payments#d19bfefb813240e2e6edbcb99dfb1abd0358166c" +source = "git+https://github.com/RGB-WG/rgb-std?branch=payments#79e68c101d8e297a9e3a99100f1da727deda00e5" dependencies = [ "amplify", "bp-core", diff --git a/src/runtime.rs b/src/runtime.rs index 0549fc7..6075458 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -29,7 +29,7 @@ use bpstd::seals::TxoSeal; use bpstd::{Psbt, Sats}; use rgb::invoice::RgbInvoice; use rgb::popls::bp::{ - Barrow, BundleError, FulfillError, IncludeError, OpRequestSet, WoutAssignment, + Barrow, BundleError, FulfillError, IncludeError, OpRequestSet, PaymentScript, }; use rgb::{ContractId, Excavate, Pile, Supply}; use rgpsbt::{RgbPsbt, RgbPsbtError, ScriptResolver}; @@ -82,7 +82,7 @@ impl, X: Excavate> RgbRuntime // TODO: Return a dedicated Transfer object which can stream a consignment pub fn transfer( &mut self, - set: OpRequestSet>, + set: PaymentScript, params: TxParams, ) -> Result { let (mut psbt, meta) = self.0.wallet.compose_psbt(&set, params)?; diff --git a/src/wallet.rs b/src/wallet.rs index cb74844..b0e84ff 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -30,7 +30,7 @@ use bpstd::seals::TxoSeal; use bpstd::{Address, Keychain, Network, Outpoint, Psbt, XpubDerivable}; use bpwallet::{Layer2Empty, NoLayer2, Wallet, WalletCache, WalletData, WalletDescr}; use nonasync::persistence::{PersistenceError, PersistenceProvider}; -use rgb::popls::bp::{OpRequestSet, WalletProvider, WoutAssignment}; +use rgb::popls::bp::{PaymentScript, WalletProvider}; use rgb::{AuthToken, EitherSeal, SealAuthToken}; use crate::descriptor::RgbDescr; @@ -106,7 +106,7 @@ impl RgbWallet { pub fn compose_psbt( &mut self, - bundle: &OpRequestSet>, + bundle: &PaymentScript, params: TxParams, ) -> Result<(Psbt, PsbtMeta), ConstructionError> { let closes = bundle From 6920e0788031672606f1e6f94d59c191bb564e14 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 25 Jan 2025 12:33:13 +0100 Subject: [PATCH 04/11] chore: fix clippy lints --- cli/src/cmd.rs | 2 +- src/coinselect.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/src/cmd.rs b/cli/src/cmd.rs index 9d7a6da..32b5129 100644 --- a/cli/src/cmd.rs +++ b/cli/src/cmd.rs @@ -309,7 +309,7 @@ impl Args { pub fn mound(&self) -> BpDirMound { if self.init { - let _ = fs::create_dir_all(&self.data_dir()); + let _ = fs::create_dir_all(self.data_dir()); } if !self.network.is_testnet() { panic!("Non-testnet networks are not yet supported"); diff --git a/src/coinselect.rs b/src/coinselect.rs index 4557c90..5c2d4b9 100644 --- a/src/coinselect.rs +++ b/src/coinselect.rs @@ -66,7 +66,7 @@ impl Coinselect for CoinselectStrategy { if calc.is_satisfied(invoiced_state) { return false; } - calc.accumulate(*val).is_ok() + calc.accumulate(val).is_ok() }) .map(|(addr, _)| addr) .collect(), @@ -77,7 +77,7 @@ impl Coinselect for CoinselectStrategy { if calc.is_satisfied(invoiced_state) { return false; } - calc.accumulate(*val).is_ok() + calc.accumulate(val).is_ok() }) .map(|(addr, _)| addr) .collect(), From cff6b11f8dc697210febb3af69a1afe58fd1fa3b Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 25 Jan 2025 12:35:52 +0100 Subject: [PATCH 05/11] ci: bump MSRV --- .github/workflows/build.yml | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 979c58b..b599b32 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -65,7 +65,7 @@ jobs: strategy: fail-fast: false matrix: - toolchain: [ nightly, beta, stable, 1.77.0 ] + toolchain: [ nightly, beta, stable, 1.82.0 ] steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master diff --git a/Cargo.toml b/Cargo.toml index f2e1ef7..91d6dac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ categories = ["cryptography::cryptocurrencies"] authors = ["Dr Maxim Orlovsky "] homepage = "https://rgb.tech" repository = "https://github.com/RGB-WG/rgb" -rust-version = "1.77.0" +rust-version = "1.82.0" edition = "2021" license = "Apache-2.0" From 80cc027cb7937b681b5452dc54ef5a530ac38c95 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 25 Jan 2025 12:36:00 +0100 Subject: [PATCH 06/11] ci: remove past features --- .github/workflows/build.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b599b32..1eb248c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,11 +35,6 @@ jobs: matrix: feature: - fs - - cli - - log - - esplora_blocking - - electrum_blocking - - mempool_blocking - serde steps: - uses: actions/checkout@v4 From 1ba38dba09c89a2bb4f11e81fc05f59c5e4397a2 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 25 Jan 2025 12:36:29 +0100 Subject: [PATCH 07/11] ci: temporarily disable codecov target requirements --- codecov.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codecov.yml b/codecov.yml index 240d731..4a291d8 100644 --- a/codecov.yml +++ b/codecov.yml @@ -8,12 +8,12 @@ coverage: status: project: default: - target: 75% + # target: 75% threshold: 1% branches: - master patch: default: - target: 60% + # target: 60% threshold: 1% only_pulls: true From c2870c8d6b1c01234760b829ac06d305a7ab1971 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 25 Jan 2025 12:42:39 +0100 Subject: [PATCH 08/11] test coinselect display/from_str --- src/coinselect.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/coinselect.rs b/src/coinselect.rs index 5c2d4b9..e9552ea 100644 --- a/src/coinselect.rs +++ b/src/coinselect.rs @@ -88,3 +88,16 @@ impl Coinselect for CoinselectStrategy { Some(res) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn display_from_str() { + assert_eq!(CoinselectStrategy::Aggregate.to_string(), "aggregate"); + assert_eq!(CoinselectStrategy::SmallSize.to_string(), "smallsize"); + assert_eq!(CoinselectStrategy::Aggregate, "aggregate".parse().unwrap()); + assert_eq!(CoinselectStrategy::SmallSize, "smallsize".parse().unwrap()); + } +} From 97f780a161631134907a20fbb9adf14419842453 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 25 Jan 2025 12:48:06 +0100 Subject: [PATCH 09/11] psbt: avoid dependencies on bpstd when bp feature is not active --- Cargo.lock | 2 +- Cargo.toml | 1 + psbt/Cargo.toml | 2 +- psbt/src/bp.rs | 9 ++++++--- psbt/src/common.rs | 10 ++++++++-- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0551f4f..0cc7439 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1515,8 +1515,8 @@ name = "rgb-psbt" version = "0.12.0-beta.4" dependencies = [ "amplify", + "bp-core", "bp-std", - "commit_verify", "rgb-std", ] diff --git a/Cargo.toml b/Cargo.toml index 91d6dac..18d3bc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ nonasync = "0.1.2" strict_encoding = "2.8.1" strict_types = "2.8.1" commit_verify = "=0.12.0-beta.4" +bp-core = "=0.12.0-beta.4" bp-std = { version = "=0.12.0-beta.4", features = ["client-side-validation"] } bp-electrum = "=0.12.0-beta.4" bp-esplora = { version = "=0.12.0-beta.4", default-features = false } diff --git a/psbt/Cargo.toml b/psbt/Cargo.toml index f31b5f3..beb4b02 100644 --- a/psbt/Cargo.toml +++ b/psbt/Cargo.toml @@ -16,8 +16,8 @@ name = "rgpsbt" [dependencies] amplify = { workspace = true } -commit_verify = { workspace = true } rgb-std = { workspace = true, features = ["bitcoin"] } +bp-core = { workspace = true } bp-std = { workspace = true, optional = true } [features] diff --git a/psbt/src/bp.rs b/psbt/src/bp.rs index 5900469..bb37d8f 100644 --- a/psbt/src/bp.rs +++ b/psbt/src/bp.rs @@ -24,9 +24,10 @@ use amplify::ByteArray; use bpstd::seals::{mmb, mpc}; -use bpstd::{Psbt, Sats, ScriptPubkey, Unmodifiable, Vout}; +use bpstd::{Psbt, Sats, ScriptPubkey, Vout}; use rgb::popls::bp::PrefabBundle; +use crate::common::RgbPsbtUnfinalizable; use crate::{RgbPsbt, RgbPsbtError, ScriptResolver}; impl RgbPsbt for Psbt { @@ -48,9 +49,11 @@ impl RgbPsbt for Psbt { Ok(()) } - fn rgb_complete(&mut self) -> Result<(), Unmodifiable> { + fn rgb_complete(&mut self) -> Result<(), RgbPsbtUnfinalizable> { if self.outputs().all(|out| !out.is_opret_host()) && self.opret_hosts().count() == 0 { - let host = self.construct_output(ScriptPubkey::op_return(&[]), Sats::ZERO)?; + let host = self + .construct_output(ScriptPubkey::op_return(&[]), Sats::ZERO) + .map_err(|_| RgbPsbtUnfinalizable)?; host.set_opret_host().ok(); } self.complete_construction(); diff --git a/psbt/src/common.rs b/psbt/src/common.rs index 4e440a4..359f158 100644 --- a/psbt/src/common.rs +++ b/psbt/src/common.rs @@ -22,15 +22,21 @@ // or implied. See the License for the specific language governing permissions and limitations under // the License. -use bpstd::{ScriptPubkey, Unmodifiable, Vout}; +use bp::{ScriptPubkey, Vout}; use rgb::popls::bp::PrefabBundle; use rgb::{ContractId, Outpoint}; +#[derive(Copy, Clone, Eq, PartialEq, Debug, Display, Error)] +#[display( + "in order to complete RGB processing the PSBT must have PSBT_GLOBAL_TX_MODIFIABLE flag set on" +)] +pub struct RgbPsbtUnfinalizable; + pub trait RgbPsbt { // TODO: Add rgb_embed to embed operations for hardware signers fn rgb_fill_csv(&mut self, bundle: &PrefabBundle) -> Result<(), RgbPsbtError>; - fn rgb_complete(&mut self) -> Result<(), Unmodifiable>; + fn rgb_complete(&mut self) -> Result<(), RgbPsbtUnfinalizable>; } /// Errors embedding RGB-related information. From 18df3d681d5e9f68276ef9c48915def067976b64 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 25 Jan 2025 12:54:57 +0100 Subject: [PATCH 10/11] chore: fix use of bp feature in rgb-psbt from rgb-runtime crate --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 18d3bc5..9b93471 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,7 +58,7 @@ nonasync = { workspace = true } bp-std = { workspace = true } bp-wallet = { workspace = true } rgb-std = { workspace = true, features = ["bitcoin"] } -rgb-psbt.workspace = true +rgb-psbt = { workspace = true, features = ["bp"] } indexmap = { workspace = true } serde = { workspace = true, optional = true } serde_yaml = { workspace = true, optional = true } From 5a05fcc004d391da5fdbebc4084a488a8e0623a4 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 25 Jan 2025 13:03:13 +0100 Subject: [PATCH 11/11] ci: use latest wasm-pack version --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3d6542b..d9c899f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,6 +34,8 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - uses: jetli/wasm-pack-action@v0.4.0 + with: + version: 'latest' - name: Add wasm32 target run: rustup target add wasm32-unknown-unknown - name: Test in headless Chrome