Skip to content

Commit

Permalink
Add ord wallet transactions (ordinals#951)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphjaph committed Dec 13, 2022
1 parent e3ea88c commit e2f89ff
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 11 deletions.
15 changes: 7 additions & 8 deletions Cargo.lock

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

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ rust-embed = "6.4.0"
rustls = "0.20.6"
rustls-acme = { version = "0.5.0", features = ["axum"] }
serde = { version = "1.0.137", features = ["derive"] }
serde_json = { version = "1.0.81", features = ["arbitrary_precision"] }
serde_json = { version = "1.0.81" }
sys-info = "0.9.1"
tokio = { version = "1.17.0", features = ["rt-multi-thread"] }
tokio-stream = "0.1.9"
Expand All @@ -66,3 +66,7 @@ pulldown-cmark = "0.9.2"
[patch.crates-io.jsonrpc]
git = "https://github.com/casey/rust-jsonrpc"
rev = "1826d5e7ec02d9dd3fbca94bfa3b4215870d193f"

[patch.crates-io.ord-bitcoincore-rpc-json]
git = "https://github.com/casey/rust-bitcoincore-rpc"
rev = "768725a2adf3b0a8b982d200d59080d5e69df7c9"
11 changes: 11 additions & 0 deletions docs/src/guides/inscriptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ Use a signet faucet to send satoshis to the address you generated. Two faucets
you might try are [signet.bc-2.jp](https://signet.bc-2.jp/) and
[alt.signetfaucet.com](https://alt.signetfaucet.com/).

You can see pending transactions with `ord --chain signet walet transactions`.
Once the faucet transaction confirms, you should be able to see the
transactions outputs with `ord --chain signet wallet utxos`.

Expand Down Expand Up @@ -196,6 +197,11 @@ Send the inscription by running:
ord --chain signet wallet send INSCRIPTION_ID ADDRESS
```

See the pending transaction with:
```
ord --chain signet wallet transactions
```

Once the send transaction confirms, the recipient can confirm receipt by
running:

Expand All @@ -218,6 +224,11 @@ The sender can transfer the inscription to your address using:
ord --chain signet wallet send INSCRIPTION_ID ADDRESS
```

See the pending transaction with:
```
ord --chain signet wallet transactions
```

Once the send transaction confirms, you can can confirm receipt by running:

```
Expand Down
4 changes: 4 additions & 0 deletions src/subcommand/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod receive;
mod satoshis;
mod send;
mod transaction_builder;
mod transactions;
mod utxos;

#[derive(Debug, Parser)]
Expand All @@ -20,6 +21,8 @@ pub(crate) enum Wallet {
Receive(receive::Receive),
#[clap(about = "Send a satoshi or inscription")]
Send(send::Send),
#[clap(about = "See wallet transactions")]
Transactions(transactions::Transactions),
#[clap(about = "List wallet UTXOs")]
Utxos(utxos::Utxos),
}
Expand All @@ -32,6 +35,7 @@ impl Wallet {
Self::Inscriptions(inscriptions) => inscriptions.run(options),
Self::Receive(receive) => receive.run(options),
Self::Send(send) => send.run(options),
Self::Transactions(transactions) => transactions.run(options),
Self::Utxos(utxos) => utxos.run(options),
}
}
Expand Down
21 changes: 21 additions & 0 deletions src/subcommand/wallet/transactions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use super::*;

#[derive(Debug, Parser)]
pub(crate) struct Transactions {}

impl Transactions {
pub(crate) fn run(self, options: Options) -> Result {
let txs = options
.bitcoin_rpc_client()?
.list_transactions(None, None, None, None)?
.iter()
.map(|tx| (tx.info.txid, tx.info.confirmations))
.collect::<Vec<(Txid, i32)>>();

for (txid, confirmations) in txs {
println!("{txid}\t{confirmations}");
}

Ok(())
}
}
9 changes: 9 additions & 0 deletions test-bitcoincore-rpc/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,13 @@ pub trait Api {
label: Option<String>,
address_type: Option<()>,
) -> Result<bitcoin::Address, jsonrpc_core::Error>;

#[rpc(name = "listtransactions")]
fn list_transactions(
&self,
label: Option<String>,
count: Option<usize>,
skip: Option<usize>,
include_watchonly: Option<bool>,
) -> Result<Vec<ListTransactionResult>, jsonrpc_core::Error>;
}
5 changes: 3 additions & 2 deletions test-bitcoincore-rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ use {
bitcoincore_rpc::json::{
Bip125Replaceable, CreateRawTransactionInput, GetBalancesResult, GetBalancesResultEntry,
GetBlockHeaderResult, GetBlockchainInfoResult, GetDescriptorInfoResult, GetNetworkInfoResult,
GetRawTransactionResult, GetTransactionResult, GetWalletInfoResult, ListUnspentResultEntry,
SignRawTransactionResult, WalletTxInfo,
GetRawTransactionResult, GetTransactionResult, GetTransactionResultDetail,
GetTransactionResultDetailCategory, GetWalletInfoResult, ListTransactionResult,
ListUnspentResultEntry, SignRawTransactionResult, WalletTxInfo,
},
jsonrpc_core::{IoHandler, Value},
jsonrpc_http_server::{CloseHandle, ServerBuilder},
Expand Down
44 changes: 44 additions & 0 deletions test-bitcoincore-rpc/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ impl Api for Server {
assert_eq!(address, None, "address param not supported");
assert_eq!(include_unsafe, None, "include_unsafe param not supported");
assert_eq!(query_options, None, "query_options param not supported");

Ok(
self
.state()
Expand Down Expand Up @@ -393,4 +394,47 @@ impl Api for Server {

Ok(address)
}

fn list_transactions(
&self,
_label: Option<String>,
_count: Option<usize>,
_skip: Option<usize>,
_include_watchonly: Option<bool>,
) -> Result<Vec<ListTransactionResult>, jsonrpc_core::Error> {
let state = self.state();
Ok(
state
.transactions
.iter()
.map(|(txid, tx)| (*txid, tx))
.chain(state.mempool.iter().map(|tx| (tx.txid(), tx)))
.map(|(txid, tx)| ListTransactionResult {
info: WalletTxInfo {
confirmations: state.get_confirmations(tx),
blockhash: None,
blockindex: None,
blocktime: None,
blockheight: None,
txid,
time: 0,
timereceived: 0,
bip125_replaceable: Bip125Replaceable::Unknown,
wallet_conflicts: Vec::new(),
},
detail: GetTransactionResultDetail {
address: None,
category: GetTransactionResultDetailCategory::Immature,
amount: SignedAmount::from_sat(0),
label: None,
vout: 0,
fee: Some(SignedAmount::from_sat(0)),
abandoned: None,
},
trusted: None,
comment: None,
})
.collect(),
)
}
}
10 changes: 10 additions & 0 deletions test-bitcoincore-rpc/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,14 @@ impl State {
pub(crate) fn mempool(&self) -> &[Transaction] {
&self.mempool
}

pub(crate) fn get_confirmations(&self, tx: &Transaction) -> i32 {
for (confirmations, hash) in self.hashes.iter().rev().enumerate() {
if self.blocks.get(hash).unwrap().txdata.contains(tx) {
return (confirmations + 1).try_into().unwrap();
}
}

0
}
}
38 changes: 38 additions & 0 deletions tests/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,3 +610,41 @@ fn inscribe_with_optional_satpoint_arg() {
".*HELLOWORLD.*",
);
}

#[test]
fn transactions() {
let rpc_server = test_bitcoincore_rpc::spawn_with(Network::Signet, "ord");
rpc_server.mine_blocks(1);

let stdout = CommandBuilder::new("--chain signet wallet inscribe --file degenerate.png")
.write("degenerate.png", [1; 520])
.rpc_server(&rpc_server)
.stdout_regex("commit\t[[:xdigit:]]{64}\nreveal\t[[:xdigit:]]{64}\n")
.run();

let reveal_txid = reveal_txid_from_inscribe_stdout(&stdout);

CommandBuilder::new("--chain signet wallet transactions")
.rpc_server(&rpc_server)
.stdout_regex(format!(".*{}\t0.*", reveal_txid))
.run();

rpc_server.mine_blocks(1);

CommandBuilder::new("--chain signet wallet transactions")
.rpc_server(&rpc_server)
.stdout_regex(format!(".*{}\t1\n.*", reveal_txid))
.run();

let txid = CommandBuilder::new(format!(
"--chain signet wallet send {reveal_txid} tb1qx4gf3ya0cxfcwydpq8vr2lhrysneuj5d7lqatw"
))
.rpc_server(&rpc_server)
.stdout_regex(r".*")
.run();

CommandBuilder::new("--chain signet wallet transactions")
.rpc_server(&rpc_server)
.stdout_regex(format!(".*{}\t0\n.*", txid.trim()))
.run();
}

0 comments on commit e2f89ff

Please sign in to comment.