Skip to content

Commit

Permalink
more tx work
Browse files Browse the repository at this point in the history
  • Loading branch information
ross-weir committed Nov 10, 2023
1 parent 11a092d commit f909e1e
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 24 deletions.
4 changes: 1 addition & 3 deletions chaincash_offchain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,5 @@ license = "CC0-1.0"
[dependencies]
once_cell = "1.18.0"
ergo_lib = { git = "https://github.com/ergoplatform/sigma-rust.git", branch = "master", package = "ergo-lib", features = ["compiler"] }
ergo-node-interface = "0.4.0"
# required for Url struct, should instead be re-exported from `ergo-node-interface` in the future
reqwest = { version = "0.11.4", features = ["blocking"] }
ergo-node-interface = { git = "https://github.com/ergoplatform/ergo-node-interface-rust.git", branch = "develop" }
serde = { workspace = true }
4 changes: 2 additions & 2 deletions chaincash_offchain/src/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use ergo_lib::ergoscript_compiler::compiler::compile;
use ergo_lib::ergotree_ir::ergo_tree::ErgoTree;
use once_cell::sync::Lazy;

static RESERVE_ERGO_TREE: Lazy<ErgoTree> = Lazy::new(|| {
pub(crate) static RESERVE_ERGO_TREE: Lazy<ErgoTree> = Lazy::new(|| {
let s = include_str!("../../contracts/chaincash/contracts/onchain/reserve.es");
compile(s, Default::default()).unwrap()
});

static NOTE_ERGO_TREE: Lazy<ErgoTree> = Lazy::new(|| {
pub(crate) static NOTE_ERGO_TREE: Lazy<ErgoTree> = Lazy::new(|| {
let s = include_str!("../../contracts/chaincash/contracts/onchain/note.es");
compile(s, Default::default()).unwrap()
});
5 changes: 1 addition & 4 deletions chaincash_offchain/src/node.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use reqwest::Url;

pub use ergo_node_interface::NodeInterface;

#[derive(serde::Deserialize, Debug)]
Expand All @@ -9,6 +7,5 @@ pub struct Config {
}

pub fn node_from_config(cfg: &Config) -> NodeInterface {
let url = Url::parse(&cfg.url).unwrap();
NodeInterface::from_url(&cfg.api_key, url)
NodeInterface::from_url_str(&cfg.api_key, &cfg.url).unwrap()
}
66 changes: 51 additions & 15 deletions chaincash_offchain/src/transactions.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
pub mod reserves;

use crate::NanoErg;
use ergo_lib::{ergo_chain_types::EcPoint, wallet::tx_builder::SUGGESTED_TX_FEE};
use crate::{contracts::RESERVE_ERGO_TREE, NanoErg};
use ergo_lib::{
chain::{ergo_box::box_builder::ErgoBoxCandidateBuilder, transaction::TxId},
ergo_chain_types::EcPoint,
ergotree_ir::chain::{
address::NetworkAddress,
ergo_box::{box_value::BoxValue, ErgoBox, NonMandatoryRegisterId},
token::TokenId,
token::{Token, TokenAmount},
},
wallet::{
box_selector::{BoxSelection, BoxSelector, SimpleBoxSelector},
tx_builder::{TxBuilder, SUGGESTED_TX_FEE},
},
};
use ergo_node_interface::NodeInterface;

#[derive(Clone)]
Expand All @@ -12,7 +25,7 @@ pub struct TransactionService {
}

struct TxContext {
current_height: u64,
current_height: u32,
change_address: String,
fee: NanoErg,
}
Expand All @@ -26,29 +39,52 @@ impl TransactionService {
Self { node, fee }
}

fn box_selection_with_amount(&self, amount: NanoErg) -> BoxSelection<ErgoBox> {
let inputs = self.node.unspent_boxes_with_min_total(amount).unwrap();
// kinda irrelevant since we already have suitable boxes but box selectors required by txbuilder
SimpleBoxSelector::new()
.select(inputs, amount.try_into().unwrap(), &[])
.unwrap()
}

// TODO: handle request failures
// handle wallet uninitialized/locked
// handle no change address
fn get_ctx(&self) -> TxContext {
fn get_tx_ctx(&self) -> TxContext {
let wallet_status = self.node.wallet_status().unwrap();

TxContext {
current_height: self.node.current_block_height().unwrap(),
current_height: self.node.current_block_height().unwrap() as u32,
change_address: wallet_status.change_address.unwrap(),
fee: self.fee,
}
}

pub fn create_reserve(&self, pk: EcPoint, amount: NanoErg) {
pub fn create_reserve(&self, pk: EcPoint, amount: NanoErg) -> TxId {
// TODO: get utxos from a cache
let ctx = self.get_ctx();
let inputs = self
.node
.unspent_boxes_with_min_total(amount + ctx.fee)
.unwrap();
// transform inputs into box_selector
// build reserve output ErgoboxCandidate
// still want to use a separate function to actually build the tx so we can decouple from
// node usage and make the building testable
let ctx = self.get_tx_ctx();
let selected_inputs = self.box_selection_with_amount(amount + ctx.fee);
let mut reserve_box_builder = ErgoBoxCandidateBuilder::new(
BoxValue::try_from(amount).unwrap(),
RESERVE_ERGO_TREE.clone(),
ctx.current_height,
);
reserve_box_builder.add_token(Token {
token_id: TokenId::from(selected_inputs.boxes.get(0).unwrap().box_id()),
amount: TokenAmount::try_from(1).unwrap(),
});
reserve_box_builder.set_register_value(NonMandatoryRegisterId::R4, pk.into());
let unsigned_tx = TxBuilder::new(
selected_inputs,
vec![reserve_box_builder.build().unwrap()],
ctx.current_height,
BoxValue::try_from(ctx.fee).unwrap(),
NetworkAddress::try_from(ctx.change_address)
.unwrap()
.address(),
)
.build()
.unwrap();
self.node.sign_and_submit_transaction(&unsigned_tx).unwrap()
}
}
1 change: 1 addition & 0 deletions chaincash_offchain/src/transactions/reserves.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use ergo_lib::ergo_chain_types::EcPoint;

pub fn create_reserve_tx(pk: EcPoint, amount: u64) {

todo!()
}

0 comments on commit f909e1e

Please sign in to comment.