Skip to content

Commit

Permalink
Merge pull request #37 from RGB-WG/cli
Browse files Browse the repository at this point in the history
Command-line improvements
  • Loading branch information
dr-orlovsky authored Nov 19, 2023
2 parents 20be7b4 + 623fdd7 commit 63a666c
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 287 deletions.
20 changes: 8 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ amplify = "4.5.0"
baid58 = "0.4.4"
strict_encoding = "2.6.1"
strict_types = "1.6.3"
bp-dbc = "0.11.0-beta.1"
bp-core = "0.11.0-beta.1"
bp-seals = "0.11.0-beta.1"
bp-std = "0.11.0-beta.1"
bp-wallet = "0.11.0-beta.1"
Expand Down Expand Up @@ -59,8 +59,9 @@ name = "rgb_rt"

[dependencies]
amplify = { workspace = true }
baid58 = { workspace = true }
strict_types = { workspace = true }
bp-dbc = { workspace = true }
bp-core = { workspace = true }
bp-std = { workspace = true }
bp-wallet = { workspace = true, features = ["fs"] }
bp-esplora = { workspace = true, optional = true }
Expand All @@ -85,3 +86,9 @@ features = [ "all" ]
aluvm = { git = "https://github.com/AluVM/rust-aluvm", branch = "v0.11" }
rgb-core = { git = "https://github.com/RGB-WG/rgb-core", branch = "v0.11" }
rgb-std = { git = "https://github.com/RGB-WG/rgb-std", branch = "v0.11" }

descriptors = { git = "https://github.com/BP-WG/bp-std", branch = "v0.11" }
psbt = { git = "https://github.com/BP-WG/bp-std", branch = "v0.11" }
bp-std = { git = "https://github.com/BP-WG/bp-std", branch = "v0.11" }
bp-wallet = { git = "https://github.com/BP-WG/bp-wallet", branch = "v0.11" }
bp-util = { git = "https://github.com/BP-WG/bp-wallet", branch = "v0.11" }
12 changes: 7 additions & 5 deletions cli/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@

#![allow(clippy::needless_update)] // Caused by the From derivation macro

use bp_util::DescriptorOpts;
use bp_util::{Config, DescriptorOpts};
use bpstd::XpubDerivable;
use rgb_rt::{DescriptorRgb, Runtime, RuntimeError, TapretKey};
use rgb_rt::{RgbDescr, Runtime, RuntimeError, TapretKey};

use crate::Command;

Expand All @@ -35,7 +35,7 @@ pub struct DescrRgbOpts {
}

impl DescriptorOpts for DescrRgbOpts {
type Descr = DescriptorRgb;
type Descr = RgbDescr;

fn is_some(&self) -> bool { self.tapret_key_only.is_some() }

Expand Down Expand Up @@ -63,11 +63,13 @@ impl Default for RgbArgs {
}

impl RgbArgs {
pub fn rgb_runtime(&self) -> Result<Runtime, RuntimeError> {
pub fn rgb_runtime(&self, config: &Config) -> Result<Runtime, RuntimeError> {
let bprt = self.inner.bp_runtime::<RgbDescr>(config)?;
eprint!("Loading stock ... ");
let runtime = Runtime::<DescriptorRgb>::load_pure_rgb(
let runtime = Runtime::<RgbDescr>::load_attach(
self.general.data_dir.clone(),
self.general.network,
bprt,
)?;
eprintln!("success");

Expand Down
119 changes: 78 additions & 41 deletions cli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ use std::str::FromStr;

use amplify::confinement::U16;
use bp_util::{Config, Exec};
use bpstd::Txid;
use rgb_rt::{DescriptorRgb, RuntimeError};
use rgbinvoice::{InvoiceState, RgbInvoice, RgbTransport};
use bpstd::{Sats, Txid};
use rgb_rt::{DescriptorRgb, RgbDescr, RgbKeychain, RuntimeError};
use rgbinvoice::{Beneficiary, InvoiceState, RgbInvoice, RgbTransport};
use rgbstd::containers::{Bindle, Transfer, UniversalBindle};
use rgbstd::contract::{ContractId, GenesisSeal, GraphSeal, StateType};
use rgbstd::interface::{ContractBuilder, FilterExclude, SchemaIfaces};
use rgbstd::interface::{ContractBuilder, FilterExclude, IfaceId, SchemaIfaces};
use rgbstd::persistence::{Inventory, Stash};
use rgbstd::schema::SchemaId;
use rgbstd::SealDefinition;
use seals::txout::{CloseMethod, ExplicitSeal, TxPtr};
use seals::txout::{CloseMethod, ExplicitSeal};
use strict_types::encoding::{FieldName, TypeName};
use strict_types::StrictVal;

Expand Down Expand Up @@ -112,16 +112,17 @@ pub enum Command {
/// Schema name to use for the contract.
schema: SchemaId, //String,

/// Interface name to use for the contract.
iface: String,

/// File containing contract genesis description in YAML format.
contract: PathBuf,
},

/// Create new invoice.
#[display("invoice")]
Invoice {
/// Force address-based invoice.
#[clap(short, long)]
address_based: bool,

/// Contract identifier.
contract_id: ContractId,

Expand All @@ -130,9 +131,6 @@ pub enum Command {

/// Value to transfer.
value: u64,

/// Seal to get the transfer to.
seal: ExplicitSeal<TxPtr>,
},

/// Create new transfer.
Expand Down Expand Up @@ -208,10 +206,14 @@ impl Exec for RgbArgs {
fn exec(self, config: Config, _name: &'static str) -> Result<(), RuntimeError> {
match &self.command {
Command::Bp(cmd) => {
self.inner.translate(cmd).exec(config, "rgb")?;
return self
.inner
.translate(cmd)
.exec(config, "rgb")
.map_err(RuntimeError::from);
}
Command::Schemata => {
let runtime = self.rgb_runtime()?;
let runtime = self.rgb_runtime(&config)?;
for id in runtime.schema_ids()? {
print!("{id} ");
for iimpl in runtime.schema(id)?.iimpls.values() {
Expand All @@ -222,20 +224,20 @@ impl Exec for RgbArgs {
}
}
Command::Interfaces => {
let runtime = self.rgb_runtime()?;
let runtime = self.rgb_runtime(&config)?;
for (id, name) in runtime.ifaces()? {
println!("{} {id}", name);
}
}
Command::Contracts => {
let runtime = self.rgb_runtime()?;
let runtime = self.rgb_runtime(&config)?;
for id in runtime.contract_ids()? {
println!("{id}");
}
}

Command::Import { armored, file } => {
let mut runtime = self.rgb_runtime()?;
let mut runtime = self.rgb_runtime(&config)?;
if *armored {
todo!()
} else {
Expand Down Expand Up @@ -287,7 +289,7 @@ impl Exec for RgbArgs {
contract,
file,
} => {
let mut runtime = self.rgb_runtime()?;
let mut runtime = self.rgb_runtime(&config)?;
let bindle = runtime
.export_contract(*contract)
.map_err(|err| err.to_string())?;
Expand All @@ -301,8 +303,8 @@ impl Exec for RgbArgs {
}

Command::State { contract_id, iface } => {
let mut runtime = self.rgb_runtime()?;
let bp_runtime = self.bp_runtime::<DescriptorRgb>(&config)?;
let mut runtime = self.rgb_runtime(&config)?;
let bp_runtime = self.bp_runtime::<RgbDescr>(&config)?;
runtime.attach(bp_runtime.detach());

let iface = runtime.iface_by_name(&tn!(iface.to_owned()))?.clone();
Expand Down Expand Up @@ -341,18 +343,34 @@ impl Exec for RgbArgs {
// TODO: Print out other types of state
}
}
Command::Issue {
schema,
iface: iface_name,
contract,
} => {
let mut runtime = self.rgb_runtime()?;
Command::Issue { schema, contract } => {
let mut runtime = self.rgb_runtime(&config)?;

let file = fs::File::open(contract)?;

let code = serde_yaml::from_reader::<_, serde_yaml::Value>(file)?;

let code = code
.as_mapping()
.expect("invalid YAML root-level structure");

let iface_name = code
.get("interface")
.expect("contract must specify interface under which it is constructed")
.as_str()
.expect("interface name must be a string");
let SchemaIfaces {
ref schema,
ref iimpls,
} = runtime.schema(*schema)?;
let iface_name = tn!(iface_name.to_owned());
let iface = runtime.iface_by_name(&iface_name)?.clone();
let iface = runtime
.iface_by_name(&iface_name)
.or_else(|_| {
let id = IfaceId::from_str(iface_name.as_str())?;
runtime.iface_by_id(id).map_err(RuntimeError::from)
})?
.clone();
let iface_id = iface.iface_id();
let iface_impl = iimpls.get(&iface_id).ok_or_else(|| {
RuntimeError::Custom(format!(
Expand All @@ -361,21 +379,13 @@ impl Exec for RgbArgs {
})?;
let types = &schema.type_system;

let file = fs::File::open(contract)?;

let mut builder = ContractBuilder::with(
iface.clone(),
schema.clone(),
iface_impl.clone(),
self.general.network.is_testnet(),
)?;

let code = serde_yaml::from_reader::<_, serde_yaml::Value>(file)?;

let code = code
.as_mapping()
.expect("invalid YAML root-level structure");

if let Some(globals) = code.get("globals") {
for (name, val) in globals
.as_mapping()
Expand Down Expand Up @@ -499,27 +509,52 @@ impl Exec for RgbArgs {
);
}
Command::Invoice {
address_based,
contract_id,
iface,
value,
seal,
} => {
let mut runtime = self.rgb_runtime()?;
let mut runtime = self.rgb_runtime(&config)?;
let iface = TypeName::try_from(iface.to_owned()).expect("invalid interface name");
let seal = GraphSeal::from(seal);

let outpoint = runtime
.wallet()
.coinselect(Sats::ZERO, |utxo| {
RgbKeychain::contains_rgb(utxo.terminal.keychain)
})
.next();
let beneficiary = match (address_based, outpoint) {
(true, _) | (false, None) => {
let addr = runtime
.wallet()
.addresses(RgbKeychain::Rgb)
.next()
.expect("no addresses left")
.addr;
Beneficiary::WitnessUtxo(addr)
}
(_, Some(outpoint)) => {
let seal = GraphSeal::new(
runtime.wallet().seal_close_method(),
outpoint.txid,
outpoint.vout,
);
runtime.store_seal_secret(SealDefinition::Bitcoin(seal))?;
Beneficiary::BlindedSeal(seal.to_concealed_seal())
}
};
let invoice = RgbInvoice {
transports: vec![RgbTransport::UnspecifiedMeans],
contract: Some(*contract_id),
iface: Some(iface),
operation: None,
assignment: None,
beneficiary: seal.to_concealed_seal().into(),
beneficiary,
owned_state: InvoiceState::Amount(*value),
network: None,
expiry: None,
unknown_query: none!(),
};
runtime.store_seal_secret(SealDefinition::Bitcoin(seal))?;
println!("{invoice}");
}
#[allow(unused_variables)]
Expand Down Expand Up @@ -570,7 +605,7 @@ impl Exec for RgbArgs {
println!("{s}");
}
Command::Dump { root_dir } => {
let runtime = self.rgb_runtime()?;
let runtime = self.rgb_runtime(&config)?;

fs::remove_dir_all(root_dir).ok();
fs::create_dir_all(format!("{root_dir}/stash/schemata"))?;
Expand Down Expand Up @@ -673,7 +708,7 @@ impl Exec for RgbArgs {
eprintln!("{status}");
}
Command::Accept { force, file } => {
let mut runtime = self.rgb_runtime()?;
let mut runtime = self.rgb_runtime(&config)?;
let mut resolver = self.resolver();
let bindle = Bindle::<Transfer>::load_file(file)?;
let transfer = bindle
Expand Down Expand Up @@ -731,6 +766,8 @@ impl Exec for RgbArgs {
}
}

println!();

Ok(())
}
}
Loading

0 comments on commit 63a666c

Please sign in to comment.