From 91afc8d10caa75f0f5df35a187e6a0cf67bafc05 Mon Sep 17 00:00:00 2001 From: raph Date: Tue, 8 Oct 2024 22:01:55 +0200 Subject: [PATCH] Add `ord verify` (#3906) --- Cargo.lock | 249 ++++++++++++++++++++++++++++----------- Cargo.toml | 1 + src/subcommand.rs | 4 + src/subcommand/verify.rs | 40 +++++++ tests/lib.rs | 1 + tests/verify.rs | 66 +++++++++++ 6 files changed, 291 insertions(+), 70 deletions(-) create mode 100644 src/subcommand/verify.rs create mode 100644 tests/verify.rs diff --git a/Cargo.lock b/Cargo.lock index b468499319..c4818419a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] @@ -135,6 +135,12 @@ dependencies = [ "nodrop", ] +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "asn1-rs" version = "0.3.1" @@ -464,13 +470,33 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "bech32" +version = "0.10.0-beta" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98f7eed2b2781a6f0b5c903471d48e15f56fb4e1165df8a9a2337fd1a59d45ea" + +[[package]] +name = "bip322" +version = "0.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1ce446a2647b907e2b39a956e1739c9f49f12fea948a3a5ead25e5d2bf2c67c" +dependencies = [ + "base64 0.22.1", + "bitcoin 0.31.2", + "bitcoin_hashes 0.14.0", + "hex", + "miniscript 11.2.0", + "snafu", +] + [[package]] name = "bip39" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +checksum = "33415e24172c1b7d6066f6d999545375ab8e1d95421d6784bdfff9496f292387" dependencies = [ - "bitcoin_hashes 0.11.0", + "bitcoin_hashes 0.13.0", "serde", "unicode-normalization", ] @@ -481,25 +507,45 @@ version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1945a5048598e4189e239d3f809b19bdad4845c4b2ba400d304d2dcf26d2c462" dependencies = [ - "bech32", + "bech32 0.9.1", "bitcoin-private", "bitcoin_hashes 0.12.0", "hex_lit", - "secp256k1", + "secp256k1 0.27.0", "serde", ] [[package]] -name = "bitcoin-private" -version = "0.1.0" +name = "bitcoin" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" +checksum = "6c85783c2fe40083ea54a33aa2f0ba58831d90fcd190f5bdc47e74e84d2a96ae" +dependencies = [ + "bech32 0.10.0-beta", + "bitcoin-internals", + "bitcoin_hashes 0.13.0", + "hex-conservative 0.1.2", + "hex_lit", + "secp256k1 0.28.2", +] [[package]] -name = "bitcoin_hashes" -version = "0.11.0" +name = "bitcoin-internals" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" + +[[package]] +name = "bitcoin-io" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" +checksum = "340e09e8399c7bd8912f495af6aa58bea0c9214773417ffaa8f6460f93aaee56" + +[[package]] +name = "bitcoin-private" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" [[package]] name = "bitcoin_hashes" @@ -511,6 +557,26 @@ dependencies = [ "serde", ] +[[package]] +name = "bitcoin_hashes" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" +dependencies = [ + "bitcoin-internals", + "hex-conservative 0.1.2", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" +dependencies = [ + "bitcoin-io", + "hex-conservative 0.2.1", +] + [[package]] name = "bitcoincore-rpc" version = "0.17.0" @@ -531,7 +597,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d30ce6f40fb0a2e8d98522796219282504b7a4b14e2b4c26139a7bea6aec6586" dependencies = [ - "bitcoin", + "bitcoin 0.30.2", "bitcoin-private", "serde", "serde_json", @@ -642,9 +708,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.24" +version = "1.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" dependencies = [ "shlex", ] @@ -711,9 +777,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -721,9 +787,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -1232,9 +1298,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -1247,9 +1313,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -1257,15 +1323,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -1274,9 +1340,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" @@ -1305,9 +1371,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -1327,21 +1393,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -1387,9 +1453,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "globset" @@ -1519,6 +1585,21 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex-conservative" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" + +[[package]] +name = "hex-conservative" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" +dependencies = [ + "arrayvec", +] + [[package]] name = "hex_lit" version = "0.1.1" @@ -1665,7 +1746,7 @@ dependencies = [ "http 1.1.0", "hyper 1.4.1", "hyper-util", - "rustls 0.23.13", + "rustls 0.23.14", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", @@ -2038,10 +2119,21 @@ version = "10.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d371924f9eb7aa860ab395baaaa0bcdfa81a32f330b538c4e2c04617b2722fe3" dependencies = [ - "bitcoin", + "bitcoin 0.30.2", "bitcoin-private", ] +[[package]] +name = "miniscript" +version = "11.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3127e10529a57a8f7fa9b1332c4c2f72baadaca6777798f910dff3c922620b14" +dependencies = [ + "bech32 0.10.0-beta", + "bitcoin 0.31.2", + "bitcoin-internals", +] + [[package]] name = "miniz_oxide" version = "0.8.0" @@ -2068,7 +2160,7 @@ name = "mockcore" version = "0.0.1" dependencies = [ "base64 0.22.1", - "bitcoin", + "bitcoin 0.30.2", "hex", "jsonrpc-core", "jsonrpc-derive", @@ -2229,9 +2321,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.36.4" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] @@ -2247,12 +2339,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.1" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "oorandom" @@ -2319,8 +2408,9 @@ dependencies = [ "axum", "axum-server", "base64 0.22.1", + "bip322", "bip39", - "bitcoin", + "bitcoin 0.30.2", "bitcoincore-rpc", "boilerplate", "brotli", @@ -2344,7 +2434,7 @@ dependencies = [ "log", "mime", "mime_guess", - "miniscript", + "miniscript 10.2.0", "mockcore", "mp4", "nix", @@ -2395,7 +2485,7 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bb35088f918c775bc27fa79e372d034892b216fb7900aeedd6e06654879ad33" dependencies = [ - "bitcoin", + "bitcoin 0.30.2", "bitcoin-private", "serde", "serde_json", @@ -2405,7 +2495,7 @@ dependencies = [ name = "ordinals" version = "0.0.10" dependencies = [ - "bitcoin", + "bitcoin 0.30.2", "derive_more", "pretty_assertions", "serde", @@ -2462,18 +2552,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" dependencies = [ "proc-macro2", "quote", @@ -2595,9 +2685,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] @@ -2993,9 +3083,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.13" +version = "0.23.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" +checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" dependencies = [ "once_cell", "rustls-pki-types", @@ -3101,9 +3191,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" +checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" dependencies = [ "windows-sys 0.59.0", ] @@ -3132,10 +3222,20 @@ checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" dependencies = [ "bitcoin_hashes 0.12.0", "rand", - "secp256k1-sys", + "secp256k1-sys 0.8.1", "serde", ] +[[package]] +name = "secp256k1" +version = "0.28.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" +dependencies = [ + "bitcoin_hashes 0.13.0", + "secp256k1-sys 0.9.2", +] + [[package]] name = "secp256k1-sys" version = "0.8.1" @@ -3145,6 +3245,15 @@ dependencies = [ "cc", ] +[[package]] +name = "secp256k1-sys" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb" +dependencies = [ + "cc", +] + [[package]] name = "security-framework" version = "2.11.1" @@ -3236,9 +3345,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9720086b3357bcb44fce40117d769a4d068c70ecfa190850a980a71755f66fcc" +checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" dependencies = [ "base64 0.22.1", "chrono", @@ -3254,9 +3363,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f1abbfe725f27678f4663bcacb75a83e829fd464c25d78dd038a3a29e307cec" +checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" dependencies = [ "darling", "proc-macro2", @@ -3662,7 +3771,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.13", + "rustls 0.23.14", "rustls-pki-types", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index a66b50f1e8..7e2d065d3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ async-trait = "0.1.72" axum = { version = "0.6.1", features = ["http2"] } axum-server = "0.5.0" base64 = "0.22.0" +bip322 = "0.0.7" bip39 = "2.0.0" bitcoin = { version = "0.30.1", features = ["rand"] } boilerplate = { version = "1.0.0", features = ["axum"] } diff --git a/src/subcommand.rs b/src/subcommand.rs index 3b4a9b1a31..3b607ceee3 100644 --- a/src/subcommand.rs +++ b/src/subcommand.rs @@ -15,6 +15,7 @@ pub mod subsidy; pub mod supply; pub mod teleburn; pub mod traits; +pub mod verify; pub mod wallet; pub mod wallets; @@ -50,6 +51,8 @@ pub(crate) enum Subcommand { Teleburn(teleburn::Teleburn), #[command(about = "Display satoshi traits")] Traits(traits::Traits), + #[command(about = "Verify BIP322 signature")] + Verify(verify::Verify), #[command(about = "Wallet commands")] Wallet(wallet::WalletCommand), #[command(about = "List all Bitcoin Core wallets")] @@ -79,6 +82,7 @@ impl Subcommand { Self::Supply => supply::run(), Self::Teleburn(teleburn) => teleburn.run(), Self::Traits(traits) => traits.run(), + Self::Verify(verify) => verify.run(), Self::Wallet(wallet) => wallet.run(settings), Self::Wallets => wallets::run(settings), } diff --git a/src/subcommand/verify.rs b/src/subcommand/verify.rs new file mode 100644 index 0000000000..1c2dd71a42 --- /dev/null +++ b/src/subcommand/verify.rs @@ -0,0 +1,40 @@ +use super::*; + +#[derive(Debug, Parser)] +#[clap(group( + ArgGroup::new("signature") + .required(true) + .args(&["transaction", "witness"])) +)] +pub(crate) struct Verify { + #[arg(long, help = "Verify signature made by
.")] + address: Address, + #[arg(long, help = "Verify signature over .")] + message: String, + #[arg(long, help = "Verify base64-encoded .")] + witness: Option, + #[arg(long, help = "Verify base64-encoded .")] + transaction: Option, +} + +impl Verify { + pub(crate) fn run(self) -> SubcommandResult { + if let Some(witness) = self.witness { + bip322::verify_simple_encoded( + &self.address.assume_checked().to_string(), + &self.message, + &witness, + )?; + } else if let Some(transaction) = self.transaction { + bip322::verify_full_encoded( + &self.address.assume_checked().to_string(), + &self.message, + &transaction, + )?; + } else { + unreachable!(); + } + + Ok(None) + } +} diff --git a/tests/lib.rs b/tests/lib.rs index 4f00885a0e..12e2c620fb 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -68,6 +68,7 @@ mod settings; mod subsidy; mod supply; mod traits; +mod verify; mod version; mod wallet; diff --git a/tests/verify.rs b/tests/verify.rs new file mode 100644 index 0000000000..f33233137f --- /dev/null +++ b/tests/verify.rs @@ -0,0 +1,66 @@ +use super::*; + +#[test] +fn verify() { + assert_eq!( + CommandBuilder::new([ + "verify", + "--address", "bc1q9vza2e8x573nczrlzms0wvx3gsqjx7vavgkx0l", + "--message", "Hello World", + "--witness", "AkcwRAIgZRfIY3p7/DoVTty6YZbWS71bc5Vct9p9Fia83eRmw2QCICK/ENGfwLtptFluMGs2KsqoNSk89pO7F29zJLUx9a/sASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI=" + ]) + .run_and_extract_stdout(), + "" + ); +} + +#[test] +fn verify_fails() { + CommandBuilder::new([ + "verify", + "--address", "bc1q9vza2e8x573nczrlzms0wvx3gsqjx7vavgkx0l", + "--message", "Hello World - this should fail", + "--witness", "AkcwRAIgZRfIY3p7/DoVTty6YZbWS71bc5Vct9p9Fia83eRmw2QCICK/ENGfwLtptFluMGs2KsqoNSk89pO7F29zJLUx9a/sASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI=" + ]) + .expected_exit_code(1) + .stderr_regex("error: Invalid signature.*") + .run_and_extract_stdout(); +} + +#[test] +fn witness_and_transaction_conflict() { + CommandBuilder::new([ + "verify", + "--address", "bc1q9vza2e8x573nczrlzms0wvx3gsqjx7vavgkx0l", + "--message", "Hello World", + "--transaction", "asdf", + "--witness", "AkcwRAIgZRfIY3p7/DoVTty6YZbWS71bc5Vct9p9Fia83eRmw2QCICK/ENGfwLtptFluMGs2KsqoNSk89pO7F29zJLUx9a/sASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI=" + ]) + .expected_exit_code(2) + .stderr_regex(".*error.*") + .run_and_extract_stdout(); +} + +#[test] +fn verify_with_transaction() { + let tx = bip322::sign_full_encoded( + "bc1q9vza2e8x573nczrlzms0wvx3gsqjx7vavgkx0l", + "Hello World", + "L3VFeEujGtevx9w18HD1fhRbCH67Az2dpCymeRE1SoPK6XQtaN2k", + ) + .unwrap(); + + assert_eq!( + CommandBuilder::new([ + "verify", + "--address", + "bc1q9vza2e8x573nczrlzms0wvx3gsqjx7vavgkx0l", + "--message", + "Hello World", + "--transaction", + &tx, + ]) + .run_and_extract_stdout(), + "" + ); +}