From bcce994b977ae3bf0cbdac79544f1ec81ffc461f Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Thu, 12 Jan 2023 15:45:23 -0800 Subject: [PATCH] Output inscription ID from `ord wallet inscribe` (#1208) --- src/inscription_id.rs | 9 ++ src/main.rs | 2 +- src/subcommand/wallet/inscribe.rs | 22 ++++- tests/command_builder.rs | 6 ++ tests/lib.rs | 35 +++----- tests/server.rs | 133 +++++++++++++----------------- tests/wallet/inscribe.rs | 132 ++++++++--------------------- tests/wallet/inscriptions.rs | 40 ++++----- tests/wallet/send.rs | 76 ++++++----------- 9 files changed, 178 insertions(+), 277 deletions(-) diff --git a/src/inscription_id.rs b/src/inscription_id.rs index ca9dc263e6..a970ffe770 100644 --- a/src/inscription_id.rs +++ b/src/inscription_id.rs @@ -15,6 +15,15 @@ impl<'de> Deserialize<'de> for InscriptionId { } } +impl Serialize for InscriptionId { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.collect_str(self) + } +} + impl Display for InscriptionId { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{}i{}", self.txid, self.index) diff --git a/src/main.rs b/src/main.rs index 016031854c..ab8f2b3df3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,7 +49,7 @@ use { html_escaper::{Escape, Trusted}, lazy_static::lazy_static, regex::Regex, - serde::{Deserialize, Deserializer, Serialize}, + serde::{Deserialize, Deserializer, Serialize, Serializer}, std::{ cmp, collections::{BTreeMap, HashSet, VecDeque}, diff --git a/src/subcommand/wallet/inscribe.rs b/src/subcommand/wallet/inscribe.rs index fb01fa97f7..4c33f0ee53 100644 --- a/src/subcommand/wallet/inscribe.rs +++ b/src/subcommand/wallet/inscribe.rs @@ -16,6 +16,13 @@ use { std::collections::BTreeSet, }; +#[derive(Serialize)] +struct Output { + commit: Txid, + inscription: InscriptionId, + reveal: Txid, +} + #[derive(Debug, Parser)] pub(crate) struct Inscribe { #[clap(long, help = "Inscribe ")] @@ -69,16 +76,23 @@ impl Inscribe { .sign_raw_transaction_with_wallet(&unsigned_commit_tx, None, None)? .hex; - let commit_txid = client + let commit = client .send_raw_transaction(&signed_raw_commit_tx) .context("Failed to send commit transaction")?; - let reveal_txid = client + let reveal = client .send_raw_transaction(&reveal_tx) .context("Failed to send reveal transaction")?; - println!("commit\t{commit_txid}"); - println!("reveal\t{reveal_txid}"); + serde_json::to_writer_pretty( + io::stdout(), + &Output { + commit, + reveal, + inscription: reveal.into(), + }, + )?; + Ok(()) } diff --git a/tests/command_builder.rs b/tests/command_builder.rs index 7c16286986..0c4c5c58d4 100644 --- a/tests/command_builder.rs +++ b/tests/command_builder.rs @@ -134,4 +134,10 @@ impl CommandBuilder { stdout.into() } + + pub(crate) fn output(self) -> T { + let stdout = self.stdout_regex(".*").run(); + serde_json::from_str(&stdout) + .unwrap_or_else(|err| panic!("Failed to deserialize JSON: {err}\n{stdout}")) + } } diff --git a/tests/lib.rs b/tests/lib.rs index 4516b772fd..ae6dcac460 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -7,6 +7,7 @@ use { pretty_assertions::assert_eq as pretty_assert_eq, regex::Regex, reqwest::{StatusCode, Url}, + serde::{de::DeserializeOwned, Deserialize}, std::{ fs, net::TcpListener, @@ -35,35 +36,25 @@ macro_rules! assert_regex_match { }; } -fn reveal_txid_from_inscribe_stdout(stdout: &str) -> Txid { - stdout - .lines() - .nth(1) - .unwrap() - .split('\t') - .nth(1) - .unwrap() - .parse() - .unwrap() +#[derive(Deserialize)] +struct Inscribe { + #[allow(dead_code)] + commit: Txid, + inscription: String, + reveal: Txid, } -fn create_inscription(rpc_server: &test_bitcoincore_rpc::Handle, filename: &str) -> String { +fn inscribe(rpc_server: &test_bitcoincore_rpc::Handle) -> Inscribe { rpc_server.mine_blocks(1); - let stdout = CommandBuilder::new(format!( - "--chain {} wallet inscribe {filename}", - rpc_server.network() - )) - .write(filename, "HELLOWORLD") - .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); + let output = CommandBuilder::new("wallet inscribe foo.txt") + .write("foo.txt", "FOO") + .rpc_server(rpc_server) + .output(); rpc_server.mine_blocks(1); - format!("{reveal_txid}i0") + output } fn create_wallet(rpc_server: &test_bitcoincore_rpc::Handle) { diff --git a/tests/server.rs b/tests/server.rs index d71bedcb42..160f364f3a 100644 --- a/tests/server.rs +++ b/tests/server.rs @@ -38,37 +38,30 @@ fn run() { fn inscription_page() { let rpc_server = test_bitcoincore_rpc::spawn(); create_wallet(&rpc_server); - rpc_server.mine_blocks(1); - - let stdout = CommandBuilder::new("wallet inscribe hello.txt") - .write("hello.txt", "HELLOWORLD") - .rpc_server(&rpc_server) - .stdout_regex("commit\t[[:xdigit:]]{64}\nreveal\t[[:xdigit:]]{64}\n") - .run(); - let reveal_tx = reveal_txid_from_inscribe_stdout(&stdout); - - let inscription_id = format!("{reveal_tx}i0"); - - rpc_server.mine_blocks(1); + let Inscribe { + inscription, + reveal, + .. + } = inscribe(&rpc_server); TestServer::spawn_with_args(&rpc_server, &[]).assert_response_regex( - format!("/inscription/{inscription_id}"), + format!("/inscription/{inscription}"), format!( - ".*.* + ".*.*

Inscription 0

-.*.* +.*.*
id
-
{inscription_id}
+
{inscription}
address
bc1.*
output value
-
9860
+
9862
content
-
link
+
link
content size
-
10 bytes
+
3 bytes
content type
text/plain;charset=utf-8
timestamp
@@ -76,11 +69,11 @@ fn inscription_page() {
genesis height
2
genesis transaction
-
{reveal_tx}
+
{reveal}
location
-
{reveal_tx}:0:0
+
{reveal}:0:0
output
-
{reveal_tx}:0
+
{reveal}:0
offset
0
.*", @@ -92,21 +85,14 @@ fn inscription_page() { fn inscription_appears_on_reveal_transaction_page() { let rpc_server = test_bitcoincore_rpc::spawn(); create_wallet(&rpc_server); - let txid = rpc_server.mine_blocks(1)[0].txdata[0].txid(); - - let stdout = CommandBuilder::new(format!("wallet inscribe --satpoint {txid}:0:0 hello.txt")) - .write("hello.txt", "HELLOWORLD") - .rpc_server(&rpc_server) - .stdout_regex("commit\t[[:xdigit:]]{64}\nreveal\t[[:xdigit:]]{64}\n") - .run(); - let reveal_tx = reveal_txid_from_inscribe_stdout(&stdout); + let Inscribe { reveal, .. } = inscribe(&rpc_server); rpc_server.mine_blocks(1); TestServer::spawn_with_args(&rpc_server, &[]).assert_response_regex( - format!("/tx/{reveal_tx}"), - format!(".*

Transaction .*

.*Transaction .*.*Output {reveal_tx}:0.*Output {reveal}:0.*Inscription 0.*
location
\s*
{reveal_txid}:0:0
.*", + r".*

Inscription 0

.*
location
\s*
{reveal}:0:0
.*", ), ); let txid = CommandBuilder::new(format!( - "wallet send bc1qcqgs2pps4u4yedfyl5pysdjjncs8et5utseepv {inscription_id}" + "wallet send bc1qcqgs2pps4u4yedfyl5pysdjjncs8et5utseepv {inscription}" )) .rpc_server(&rpc_server) .stdout_regex(".*") @@ -167,13 +145,13 @@ fn inscription_page_after_send() { rpc_server.mine_blocks(1); - let send_txid = txid.trim(); + let send = txid.trim(); let ord_server = TestServer::spawn_with_args(&rpc_server, &[]); ord_server.assert_response_regex( - format!("/inscription/{inscription_id}"), + format!("/inscription/{inscription}"), format!( - r".*

Inscription 0

.*
address
\s*
bc1qcqgs2pps4u4yedfyl5pysdjjncs8et5utseepv
.*
location
\s*
{send_txid}:0:0
.*", + r".*

Inscription 0

.*
address
\s*
bc1qcqgs2pps4u4yedfyl5pysdjjncs8et5utseepv
.*
location
\s*
{send}:0:0
.*", ), ) } @@ -185,12 +163,12 @@ fn inscription_content() { rpc_server.mine_blocks(1); - let inscription_id = create_inscription(&rpc_server, "foo.txt"); + let Inscribe { inscription, .. } = inscribe(&rpc_server); rpc_server.mine_blocks(1); let response = - TestServer::spawn_with_args(&rpc_server, &[]).request(&format!("/content/{inscription_id}")); + TestServer::spawn_with_args(&rpc_server, &[]).request(&format!("/content/{inscription}")); assert_eq!(response.status(), StatusCode::OK); assert_eq!( @@ -201,7 +179,7 @@ fn inscription_content() { response.headers().get("content-security-policy").unwrap(), "default-src 'unsafe-eval' 'unsafe-inline'" ); - assert_eq!(response.bytes().unwrap(), "HELLOWORLD"); + assert_eq!(response.bytes().unwrap(), "FOO"); } #[test] @@ -209,15 +187,15 @@ fn home_page_includes_latest_inscriptions() { let rpc_server = test_bitcoincore_rpc::spawn(); create_wallet(&rpc_server); - let inscription_id = create_inscription(&rpc_server, "foo.png"); + let Inscribe { inscription, .. } = inscribe(&rpc_server); TestServer::spawn_with_args(&rpc_server, &[]).assert_response_regex( "/", format!( ".*

Latest Inscriptions

-