diff --git a/Cargo.lock b/Cargo.lock index 8779450a69..d8df101e55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,9 +64,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" dependencies = [ "anstyle", "anstyle-parse", @@ -79,43 +79,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.90" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" +checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" dependencies = [ "backtrace", ] @@ -273,7 +273,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -643,7 +643,7 @@ dependencies = [ "new_mime_guess", "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -691,9 +691,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "cast" @@ -801,7 +801,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -812,9 +812,9 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "colored" @@ -990,7 +990,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -1001,7 +1001,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -1052,7 +1052,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -1062,7 +1062,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -1082,7 +1082,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", "unicode-xid", ] @@ -1140,7 +1140,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -1157,9 +1157,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if 1.0.0", ] @@ -1372,7 +1372,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -2368,7 +2368,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -2546,29 +2546,29 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -2679,9 +2679,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -2813,14 +2813,14 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -2993,7 +2993,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.82", + "syn 2.0.85", "walkdir", ] @@ -3254,9 +3254,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.210" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" dependencies = [ "serde_derive", ] @@ -3274,13 +3274,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -3345,7 +3345,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -3430,7 +3430,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -3512,9 +3512,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.82" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote", @@ -3619,22 +3619,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -3695,9 +3695,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", "bytes", @@ -3717,7 +3717,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -4046,7 +4046,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", "wasm-bindgen-shared", ] @@ -4080,7 +4080,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4177,7 +4177,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -4188,7 +4188,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -4439,7 +4439,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] diff --git a/crates/mockcore/Cargo.toml b/crates/mockcore/Cargo.toml index 50cd155cdd..9ba3495753 100644 --- a/crates/mockcore/Cargo.toml +++ b/crates/mockcore/Cargo.toml @@ -4,12 +4,12 @@ description = "Mock Bitcoin Core RPC server" version = "0.0.1" edition = "2021" license = "CC0-1.0" -homepage = "https://github.com/ordinals/ord" +homepage = "https://github.com/ordinals/ord/tree/master/crates/mockcore" repository = "https://github.com/ordinals/ord" [dependencies] -bitcoin = { version = "0.32.3", features = ["serde", "rand"] } base64 = "0.22.0" +bitcoin = { version = "0.32.3", features = ["serde", "rand"] } hex = "0.4.3" jsonrpc-core = "18.0.0" jsonrpc-derive = "18.0.0" diff --git a/crates/mockcore/src/state.rs b/crates/mockcore/src/state.rs index e2678f61a0..232614b8d8 100644 --- a/crates/mockcore/src/state.rs +++ b/crates/mockcore/src/state.rs @@ -59,8 +59,8 @@ impl State { pub(crate) fn new_address(&mut self, change: bool) -> Address { let secp256k1 = Secp256k1::new(); - let key_pair = Keypair::new(&secp256k1, &mut rand::thread_rng()); - let (public_key, _parity) = XOnlyPublicKey::from_keypair(&key_pair); + let keypair = Keypair::new(&secp256k1, &mut rand::thread_rng()); + let (public_key, _parity) = XOnlyPublicKey::from_keypair(&keypair); let address = Address::p2tr(&secp256k1, public_key, None, self.network); if change { &mut self.change_addresses diff --git a/src/subcommand/wallet.rs b/src/subcommand/wallet.rs index 94bd4ec0c8..00775aa52c 100644 --- a/src/subcommand/wallet.rs +++ b/src/subcommand/wallet.rs @@ -24,6 +24,7 @@ pub mod runics; pub mod sats; pub mod send; mod shared_args; +pub mod sign; pub mod transactions; #[derive(Debug, Parser)] @@ -82,6 +83,8 @@ pub(crate) enum Subcommand { Sats(sats::Sats), #[command(about = "Send sat or inscription")] Send(send::Send), + #[command(about = "Sign message")] + Sign(sign::Sign), #[command(about = "See wallet transactions")] Transactions(transactions::Transactions), } @@ -127,6 +130,7 @@ impl WalletCommand { Subcommand::Runics => runics::run(wallet), Subcommand::Sats(sats) => sats.run(wallet), Subcommand::Send(send) => send.run(wallet), + Subcommand::Sign(sign) => sign.run(wallet), Subcommand::Transactions(transactions) => transactions.run(wallet), } } diff --git a/src/subcommand/wallet/sign.rs b/src/subcommand/wallet/sign.rs new file mode 100644 index 0000000000..5dddf9a1de --- /dev/null +++ b/src/subcommand/wallet/sign.rs @@ -0,0 +1,53 @@ +use { + super::*, + base64::{engine::general_purpose, Engine}, +}; + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub struct Output { + pub address: Address, + pub message: String, + pub witness: String, +} + +#[derive(Debug, Parser)] +pub(crate) struct Sign { + #[arg(long, help = "Sign for
.")] + address: Address, + #[arg(long, help = "Sign .")] + message: String, +} + +impl Sign { + pub(crate) fn run(self, wallet: Wallet) -> SubcommandResult { + let address = self.address.require_network(wallet.chain().network())?; + + let to_spend = bip322::create_to_spend(&address, self.message.as_bytes())?; + + let to_sign = bip322::create_to_sign(&to_spend, None)?; + + let result = wallet.bitcoin_client().sign_raw_transaction_with_wallet( + &to_sign.extract_tx()?, + Some(&[bitcoincore_rpc::json::SignRawTransactionInput { + txid: to_spend.compute_txid(), + vout: 0, + script_pub_key: address.script_pubkey(), + redeem_script: None, + amount: Some(Amount::ZERO), + }]), + None, + )?; + + let mut buffer = Vec::new(); + + Transaction::consensus_decode(&mut result.hex.as_slice())?.input[0] + .witness + .consensus_encode(&mut buffer)?; + + Ok(Some(Box::new(Output { + address: address.as_unchecked().clone(), + message: self.message, + witness: general_purpose::STANDARD.encode(buffer), + }))) + } +} diff --git a/tests/wallet.rs b/tests/wallet.rs index 9fc57a182e..1a873ec79f 100644 --- a/tests/wallet.rs +++ b/tests/wallet.rs @@ -23,4 +23,5 @@ mod runics; mod sats; mod selection; mod send; +mod sign; mod transactions; diff --git a/tests/wallet/sign.rs b/tests/wallet/sign.rs new file mode 100644 index 0000000000..7ae2a9fae2 --- /dev/null +++ b/tests/wallet/sign.rs @@ -0,0 +1,35 @@ +use { + super::*, + ord::subcommand::wallet::{addresses::Output as AddressesOutput, sign::Output as SignOutput}, +}; + +#[test] +fn sign() { + let core = mockcore::spawn(); + + let ord = TestServer::spawn_with_server_args(&core, &[], &[]); + + create_wallet(&core, &ord); + + core.mine_blocks(1); + + let addresses = CommandBuilder::new("wallet addresses") + .core(&core) + .ord(&ord) + .run_and_deserialize_output::, Vec>>(); + + let address = addresses.first_key_value().unwrap().0; + + let message = "HelloWorld"; + + let sign = CommandBuilder::new(format!( + "wallet sign --address {} --message {message}", + address.clone().assume_checked(), + )) + .core(&core) + .ord(&ord) + .run_and_deserialize_output::(); + + assert_eq!(address, &sign.address); + assert_eq!(message, &sign.message); +}