Skip to content

Commit

Permalink
Add ord wallet send (ordinals#618)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphjaph authored Oct 7, 2022
1 parent 7b3583a commit 80f0536
Show file tree
Hide file tree
Showing 12 changed files with 675 additions and 344 deletions.
54 changes: 43 additions & 11 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions src/subcommand/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use {super::*, bitcoincore_rpc::RpcApi};

mod identify;
mod list;
mod send;

fn list_unspent(options: Options) -> Result<Vec<(OutPoint, Vec<(u64, u64)>)>> {
let index = Index::open(&options)?;
Expand All @@ -27,13 +28,15 @@ fn list_unspent(options: Options) -> Result<Vec<(OutPoint, Vec<(u64, u64)>)>> {
pub(crate) enum Wallet {
Identify,
List,
Send(send::Send),
}

impl Wallet {
pub(crate) fn run(self, options: Options) -> Result<()> {
match self {
Self::Identify => identify::run(options),
Self::List => list::run(options),
Self::Send(send) => send.run(options),
}
}
}
Expand Down
56 changes: 56 additions & 0 deletions src/subcommand/wallet/send.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use {super::*, bitcoin::util::amount::Amount, bitcoincore_rpc::json::CreateRawTransactionInput};

#[derive(Debug, Parser)]
pub(crate) struct Send {
ordinal: Ordinal,
address: Address,
}

impl Send {
pub(crate) fn run(self, options: Options) -> Result {
let client = options.bitcoin_rpc_client()?;
if options.chain.network() == Network::Bitcoin
|| client.get_blockchain_info().unwrap().chain == "main"
{
bail!("Send command is not allowed on mainnet yet. Try on regtest/signet/testnet.")
}

let index = Index::open(&options)?;
index.index()?;

let output = match index.find(self.ordinal.0)? {
Some(satpoint) => satpoint.outpoint,
None => bail!(format!("Could not find {} in index", self.ordinal.0)),
};

let amount = client
.get_transaction(&output.txid, Some(true))?
.amount
.to_sat()
.try_into()
.unwrap();

let signed_tx = client
.sign_raw_transaction_with_wallet(
client.create_raw_transaction_hex(
&[CreateRawTransactionInput {
txid: output.txid,
vout: output.vout,
sequence: None,
}],
&[(self.address.to_string(), Amount::from_sat(amount))]
.into_iter()
.collect(),
None,
None,
)?,
None,
None,
)?
.hex;
let txid = client.send_raw_transaction(&signed_tx)?;

println!("{txid}");
Ok(())
}
}
3 changes: 1 addition & 2 deletions test-bitcoincore-rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ repository = "https://github.com/casey/ord"

[dependencies]
bitcoin = { version = "0.29.1", features = ["serde"] }
bitcoincore-rpc = "0.16.0"
bitcoincore-rpc-json = "0.16.0"
bitcoincore-rpc = { version = "0.16.0", git = "https://github.com/casey/rust-bitcoincore-rpc", branch = "ord" }
hex = "0.4.3"
jsonrpc-core = "18.0.0"
jsonrpc-core-client = "18.0.0"
Expand Down
69 changes: 69 additions & 0 deletions test-bitcoincore-rpc/src/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use super::*;

#[doc(hidden)]
#[jsonrpc_derive::rpc(server)]
pub trait Api {
#[rpc(name = "getblockchaininfo")]
fn get_blockchain_info(&self) -> Result<GetBlockchainInfoResult, jsonrpc_core::Error>;

#[rpc(name = "getnetworkinfo")]
fn get_network_info(&self) -> Result<GetNetworkInfoResult, jsonrpc_core::Error>;

#[rpc(name = "getblockhash")]
fn get_block_hash(&self, height: usize) -> Result<BlockHash, jsonrpc_core::Error>;

#[rpc(name = "getblockheader")]
fn get_block_header(
&self,
block_hash: BlockHash,
verbose: bool,
) -> Result<Value, jsonrpc_core::Error>;

#[rpc(name = "getblock")]
fn get_block(&self, blockhash: BlockHash, verbosity: u64) -> Result<String, jsonrpc_core::Error>;

#[rpc(name = "createrawtransaction")]
fn create_raw_transaction(
&self,
utxos: Vec<CreateRawTransactionInput>,
outs: HashMap<String, f64>,
locktime: Option<i64>,
replaceable: Option<bool>,
) -> Result<String, jsonrpc_core::Error>;

#[rpc(name = "signrawtransactionwithwallet")]
fn sign_raw_transaction_with_wallet(
&self,
tx: String,
utxos: Option<()>,
sighash_type: Option<()>,
) -> Result<Value, jsonrpc_core::Error>;

#[rpc(name = "sendrawtransaction")]
fn send_raw_transaction(&self, tx: String) -> Result<String, jsonrpc_core::Error>;

#[rpc(name = "gettransaction")]
fn get_transaction(
&self,
txid: Txid,
include_watchonly: Option<bool>,
) -> Result<Value, jsonrpc_core::Error>;

#[rpc(name = "getrawtransaction")]
fn get_raw_transaction(
&self,
txid: Txid,
verbose: bool,
blockhash: Option<BlockHash>,
) -> Result<Value, jsonrpc_core::Error>;

#[rpc(name = "listunspent")]
fn list_unspent(
&self,
minconf: Option<usize>,
maxconf: Option<usize>,
address: Option<bitcoin::Address>,
include_unsafe: Option<bool>,
query_options: Option<String>,
) -> Result<Vec<ListUnspentResultEntry>, jsonrpc_core::Error>;
}
Loading

0 comments on commit 80f0536

Please sign in to comment.