use std::collections::HashMap; use log::debug; use sdk_client::api::{ answer_confirmation_transaction, create_confirmation_transaction, create_notification_transaction, encrypt_remote_key, get_outputs, pair_device, parse_network_msg, reset_device, restore_device_from_sp_wallet, set_message_cache, setup, }; use sdk_common::network::{ AnkNetworkMsg, CachedMessage, CipherMessage, NewTxMessage, TrustedChannel, }; use sdk_common::sp_client::bitcoin::consensus::deserialize; use sdk_common::sp_client::bitcoin::hex::FromHex; use sdk_common::sp_client::bitcoin::{OutPoint, ScriptBuf, Transaction}; use sdk_common::sp_client::silentpayments::utils::receiving::{ calculate_tweak_data, get_pubkey_from_input, }; use sdk_common::sp_client::spclient::{OwnedOutput, SpWallet}; use serde_json; use tsify::JsValueSerdeExt; use wasm_bindgen_test::*; wasm_bindgen_test_configure!(run_in_browser); // We're using alice and bob for clarity, but it's important to remember that here Alice and Bob are the same person const ALICE_START_WALLET: &str = "{\"client\":{\"network\":\"regtest\",\"label\":\"default\",\"scan_sk\":\"e3d8922a41a7cb1a84a90f4334e987bb5ea2df6a1fdf44f789b5302de119f9e2\",\"spend_key\":{\"Secret\":\"93292e5b21042c6cfc742ba30e9d2a1e01609b12d154a1825184ed12c7b9631b\"},\"mnemonic\":null,\"sp_receiver\":{\"version\":0,\"network\":\"Regtest\",\"scan_pubkey\":[2,104,242,105,185,6,124,208,34,44,149,52,163,38,63,221,150,12,198,24,95,143,126,235,37,149,233,88,118,32,86,233,152],\"spend_pubkey\":[3,198,82,196,243,12,59,126,109,143,144,157,128,176,168,94,54,134,232,139,115,102,11,178,128,244,239,251,40,228,67,153,72],\"change_label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"labels\":[[\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",[2,244,223,255,57,50,216,27,133,112,138,69,120,126,85,110,6,242,141,33,136,191,82,164,241,54,179,115,84,161,145,174,154]]]}},\"outputs\":{\"wallet_fingerprint\":[187,119,108,230,171,125,106,11],\"birthday\":1620,\"last_scan\":2146,\"outputs\":{\"9a4a67cc5a40bf882d8b300d91024d7c97024b3b68b2df7745a5b9ea1df1888c:1\":{\"blockheight\":1620,\"tweak\":\"b8b63b3ed97d297b744135cfac2fb4a344c881a77543b71f1fcd16bc67514f26\",\"amount\":3938643,\"script\":\"51205b7b324bb71d411e32f2c61fda5d1db23f5c7d6d416a77fab87c913a1b120be1\",\"label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"spend_status\":\"Unspent\"}}}}"; const ALICE_CHALLENGE_WALLET: &str = "{\"client\":{\"label\":\"default\",\"scan_sk\":\"e3d8922a41a7cb1a84a90f4334e987bb5ea2df6a1fdf44f789b5302de119f9e2\",\"spend_key\":{\"Secret\":\"93292e5b21042c6cfc742ba30e9d2a1e01609b12d154a1825184ed12c7b9631b\"},\"mnemonic\":null,\"sp_receiver\":{\"version\":0,\"network\":\"Regtest\",\"scan_pubkey\":[2,104,242,105,185,6,124,208,34,44,149,52,163,38,63,221,150,12,198,24,95,143,126,235,37,149,233,88,118,32,86,233,152],\"spend_pubkey\":[3,198,82,196,243,12,59,126,109,143,144,157,128,176,168,94,54,134,232,139,115,102,11,178,128,244,239,251,40,228,67,153,72],\"change_label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"labels\":[[\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",[2,244,223,255,57,50,216,27,133,112,138,69,120,126,85,110,6,242,141,33,136,191,82,164,241,54,179,115,84,161,145,174,154]]]},\"network\":\"regtest\"},\"outputs\":{\"wallet_fingerprint\":[187,119,108,230,171,125,106,11],\"birthday\":1620,\"last_scan\":0,\"outputs\":{\"d5edbf1f60ae4fd7d698626b44ed1e85edddf65b45f62e5f82928a9e12759db9:1\":{\"blockheight\":0,\"tweak\":\"28994b2f2ee8e5f35d6d2dcdee1580d0455fe3dc37f81e0a36864473ee86f5c4\",\"amount\":3937246,\"script\":\"51207d06144e982b6fd38a85d6152f1f95746b059553258a31e04df97fe6b5f19ea1\",\"label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"spend_status\":\"Unspent\"},\"9a4a67cc5a40bf882d8b300d91024d7c97024b3b68b2df7745a5b9ea1df1888c:1\":{\"blockheight\":1620,\"tweak\":\"b8b63b3ed97d297b744135cfac2fb4a344c881a77543b71f1fcd16bc67514f26\",\"amount\":3938643,\"script\":\"51205b7b324bb71d411e32f2c61fda5d1db23f5c7d6d416a77fab87c913a1b120be1\",\"label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"spend_status\":{\"Spent\":\"d5edbf1f60ae4fd7d698626b44ed1e85edddf65b45f62e5f82928a9e12759db9\"}}}}}"; const ALICE_ANSWER_WALLET: &str = "{\"client\":{\"label\":\"default\",\"scan_sk\":\"e3d8922a41a7cb1a84a90f4334e987bb5ea2df6a1fdf44f789b5302de119f9e2\",\"spend_key\":{\"Secret\":\"93292e5b21042c6cfc742ba30e9d2a1e01609b12d154a1825184ed12c7b9631b\"},\"mnemonic\":null,\"sp_receiver\":{\"version\":0,\"network\":\"Regtest\",\"scan_pubkey\":[2,104,242,105,185,6,124,208,34,44,149,52,163,38,63,221,150,12,198,24,95,143,126,235,37,149,233,88,118,32,86,233,152],\"spend_pubkey\":[3,198,82,196,243,12,59,126,109,143,144,157,128,176,168,94,54,134,232,139,115,102,11,178,128,244,239,251,40,228,67,153,72],\"change_label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"labels\":[[\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",[2,244,223,255,57,50,216,27,133,112,138,69,120,126,85,110,6,242,141,33,136,191,82,164,241,54,179,115,84,161,145,174,154]]]},\"network\":\"regtest\"},\"outputs\":{\"wallet_fingerprint\":[187,119,108,230,171,125,106,11],\"birthday\":1620,\"last_scan\":0,\"outputs\":{\"57ca073676fa6130397ce1e4738278952483cee943daa1664b9a1807d4700066:0\":{\"blockheight\":0,\"tweak\":\"b99660cd873026aebeb378ae2ff32aa1c79a5946c462a36a01247f8afcfc5dba\",\"amount\":1046,\"script\":\"51209b80b6e8b3e93437c82a26c977860fb4d2bef9f27f6332f811a41187592502ed\",\"label\":null,\"spend_status\":\"Unspent\"},\"d5edbf1f60ae4fd7d698626b44ed1e85edddf65b45f62e5f82928a9e12759db9:1\":{\"blockheight\":0,\"tweak\":\"28994b2f2ee8e5f35d6d2dcdee1580d0455fe3dc37f81e0a36864473ee86f5c4\",\"amount\":3937246,\"script\":\"51207d06144e982b6fd38a85d6152f1f95746b059553258a31e04df97fe6b5f19ea1\",\"label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"spend_status\":\"Unspent\"},\"9a4a67cc5a40bf882d8b300d91024d7c97024b3b68b2df7745a5b9ea1df1888c:1\":{\"blockheight\":1620,\"tweak\":\"b8b63b3ed97d297b744135cfac2fb4a344c881a77543b71f1fcd16bc67514f26\",\"amount\":3938643,\"script\":\"51205b7b324bb71d411e32f2c61fda5d1db23f5c7d6d416a77fab87c913a1b120be1\",\"label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"spend_status\":{\"Spent\":\"d5edbf1f60ae4fd7d698626b44ed1e85edddf65b45f62e5f82928a9e12759db9\"}}}}}"; const BOB_START_WALLET: &str = "{\"client\":{\"label\":\"default\",\"scan_sk\":\"0de90b7195c1380d5fde13de3f1d66d53423a9896314839e36ba672653af60b4\",\"spend_key\":{\"Secret\":\"affe686075ecbe17b8ce7de45ec31314804259d0a4bc1c863de21ffd6dc598f8\"},\"mnemonic\":null,\"sp_receiver\":{\"version\":0,\"network\":\"Regtest\",\"scan_pubkey\":[2,85,96,92,243,247,237,192,205,9,178,146,101,237,132,232,15,2,69,138,31,118,76,140,142,207,90,13,192,94,254,150,133],\"spend_pubkey\":[3,5,157,91,250,169,41,61,190,37,30,98,152,253,180,138,250,86,162,102,82,148,130,220,44,153,127,83,43,246,93,17,232],\"change_label\":\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",\"labels\":[[\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",[2,237,237,247,213,154,87,34,239,168,235,87,122,152,94,41,35,101,184,201,58,201,6,185,58,157,52,208,129,167,2,224,198]]]},\"network\":\"regtest\"},\"outputs\":{\"wallet_fingerprint\":[203,200,4,248,139,36,241,232],\"birthday\":2146,\"last_scan\":2146,\"outputs\":{\"fbd9c63e0dd08c2569b51a0d6095a79ee2acfcac66acdb594328a095f1fadb63:1\":{\"blockheight\":2146,\"tweak\":\"678dbcbdb40cd3733c8dbbd508761a0937009cf75a9f466e3c98877e79037cbc\",\"amount\":99896595,\"script\":\"5120deab0c5a3d23de30477b0b5a95a261c96e29afdd9813c665d2bf025ad2b3f919\",\"label\":null,\"spend_status\":\"Unspent\"}}}}"; const BOB_CHALLENGE_WALLET: &str = "{\"client\":{\"network\":\"regtest\",\"label\":\"default\",\"scan_sk\":\"0de90b7195c1380d5fde13de3f1d66d53423a9896314839e36ba672653af60b4\",\"spend_key\":{\"Secret\":\"affe686075ecbe17b8ce7de45ec31314804259d0a4bc1c863de21ffd6dc598f8\"},\"mnemonic\":null,\"sp_receiver\":{\"version\":0,\"network\":\"Regtest\",\"scan_pubkey\":[2,85,96,92,243,247,237,192,205,9,178,146,101,237,132,232,15,2,69,138,31,118,76,140,142,207,90,13,192,94,254,150,133],\"spend_pubkey\":[3,5,157,91,250,169,41,61,190,37,30,98,152,253,180,138,250,86,162,102,82,148,130,220,44,153,127,83,43,246,93,17,232],\"change_label\":\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",\"labels\":[[\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",[2,237,237,247,213,154,87,34,239,168,235,87,122,152,94,41,35,101,184,201,58,201,6,185,58,157,52,208,129,167,2,224,198]]]}},\"outputs\":{\"wallet_fingerprint\":[203,200,4,248,139,36,241,232],\"birthday\":2146,\"last_scan\":0,\"outputs\":{\"fbd9c63e0dd08c2569b51a0d6095a79ee2acfcac66acdb594328a095f1fadb63:1\":{\"blockheight\":2146,\"tweak\":\"678dbcbdb40cd3733c8dbbd508761a0937009cf75a9f466e3c98877e79037cbc\",\"amount\":99896595,\"script\":\"5120deab0c5a3d23de30477b0b5a95a261c96e29afdd9813c665d2bf025ad2b3f919\",\"label\":null,\"spend_status\":\"Unspent\"},\"d5edbf1f60ae4fd7d698626b44ed1e85edddf65b45f62e5f82928a9e12759db9:0\":{\"blockheight\":0,\"tweak\":\"0e3395ff27bde9187ffaeeb2521f6277d3b83911f16ccbaf59a1a68d99a0ab93\",\"amount\":1200,\"script\":\"512010f06f764cbc923ec3198db946307bf0c06a1b4f09206055e47a6fec0a33d52c\",\"label\":null,\"spend_status\":\"Unspent\"}}}}"; const BOB_ANSWER_WALLET: &str = "{\"client\":{\"network\":\"regtest\",\"label\":\"default\",\"scan_sk\":\"0de90b7195c1380d5fde13de3f1d66d53423a9896314839e36ba672653af60b4\",\"spend_key\":{\"Secret\":\"affe686075ecbe17b8ce7de45ec31314804259d0a4bc1c863de21ffd6dc598f8\"},\"mnemonic\":null,\"sp_receiver\":{\"version\":0,\"network\":\"Regtest\",\"scan_pubkey\":[2,85,96,92,243,247,237,192,205,9,178,146,101,237,132,232,15,2,69,138,31,118,76,140,142,207,90,13,192,94,254,150,133],\"spend_pubkey\":[3,5,157,91,250,169,41,61,190,37,30,98,152,253,180,138,250,86,162,102,82,148,130,220,44,153,127,83,43,246,93,17,232],\"change_label\":\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",\"labels\":[[\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",[2,237,237,247,213,154,87,34,239,168,235,87,122,152,94,41,35,101,184,201,58,201,6,185,58,157,52,208,129,167,2,224,198]]]}},\"outputs\":{\"wallet_fingerprint\":[203,200,4,248,139,36,241,232],\"birthday\":2146,\"last_scan\":0,\"outputs\":{\"wallet_fingerprint\":[203,200,4,248,139,36,241,232],\"birthday\":2146,\"last_scan\":0,\"outputs\":{\"d5edbf1f60ae4fd7d698626b44ed1e85edddf65b45f62e5f82928a9e12759db9:0\":{\"blockheight\":0,\"tweak\":\"0e3395ff27bde9187ffaeeb2521f6277d3b83911f16ccbaf59a1a68d99a0ab93\",\"amount\":1200,\"script\":\"512010f06f764cbc923ec3198db946307bf0c06a1b4f09206055e47a6fec0a33d52c\",\"label\":null,\"spend_status\":{\"Spent\":\"57ca073676fa6130397ce1e4738278952483cee943daa1664b9a1807d4700066\"}},\"fbd9c63e0dd08c2569b51a0d6095a79ee2acfcac66acdb594328a095f1fadb63:1\":{\"blockheight\":2146,\"tweak\":\"678dbcbdb40cd3733c8dbbd508761a0937009cf75a9f466e3c98877e79037cbc\",\"amount\":99896595,\"script\":\"5120deab0c5a3d23de30477b0b5a95a261c96e29afdd9813c665d2bf025ad2b3f919\",\"label\":null,\"spend_status\":\"Unspent\"}}}}"; const ALICE_SPK: &str = "51205b7b324bb71d411e32f2c61fda5d1db23f5c7d6d416a77fab87c913a1b120be1"; const REVOKATION_OUTPUT: &str = "3dd51588af6cc2e4ff8e405fd2620f19c8f4e09e05692ad57a9208a061687295:3"; const ALICE_CHALLENGE_CACHE: &str = "{\"id\":1283337801,\"status\":\"SentWaitingConfirmation\",\"ciphertext\":\"d53ec574b09068cc661a76e6934cb9131df1b8d84b0ec791cb2c2789c42aae53bf2e7d514a00b2c27a78a786fee97f55dd022a99551770c4f05edfc4296993b2f82104933f61cd0d7c2e02a21188c58b492ac0a190e711ddc697505e106df087f8f9d3591aa30798608c2a0eb1e7c124d54e88dd9271884a3fe7f24f628a150d0dc90ded4753f9aa4e2730c7a339bfd7ef0faa02ee6d4cd3b1de36f8796485bd6bd8eee0e78c1e6d6c822dd9532df4c963835ea412bb36827cd89d3466\",\"plaintext\":[\"TEST\"],\"commited_in\":\"d5edbf1f60ae4fd7d698626b44ed1e85edddf65b45f62e5f82928a9e12759db9:0\",\"tie_by\":null,\"commitment\":\"d12f3c5b37240bc3abf2976f41fdf9a594f0680aafd2781ac448f80440fbeb99\",\"sender\":\"sprt1qqf50y6deqe7dqg3vj562xf3lmktqe3sct78ha6e9jh54sa3q2m5esq7x2tz0xrpm0ekclyyaszc2sh3ksm5gkumxpwegpa80lv5wgsuefqaufx8q\",\"recipient\":\"sprt1qqf2kqh8n7lkupngfk2fxtmvyaq8sy3v2ramyeryweadqmsz7l6tg2qc9n4dl42ff8klz28nznr7mfzh6263xv555stwzextl2v4lvhg3aqq7ru8u\",\"shared_secret\":\"5a28562161f939bf77983df807dd914e73f02ea67a21ed976d214452887ae43e\",\"key\":null,\"confirmed_by\":null,\"timestamp\":1720966687785,\"error\":null}"; const ALICE_ANSWER_CACHE: &str = "{\"id\":1283337801,\"status\":\"MustSpendConfirmation\",\"ciphertext\":\"d53ec574b09068cc661a76e6934cb9131df1b8d84b0ec791cb2c2789c42aae53bf2e7d514a00b2c27a78a786fee97f55dd022a99551770c4f05edfc4296993b2f82104933f61cd0d7c2e02a21188c58b492ac0a190e711ddc697505e106df087f8f9d3591aa30798608c2a0eb1e7c124d54e88dd9271884a3fe7f24f628a150d0dc90ded4753f9aa4e2730c7a339bfd7ef0faa02ee6d4cd3b1de36f8796485bd6bd8eee0e78c1e6d6c822dd9532df4c963835ea412bb36827cd89d3466\",\"plaintext\":[\"TEST\"],\"commited_in\":\"d5edbf1f60ae4fd7d698626b44ed1e85edddf65b45f62e5f82928a9e12759db9:0\",\"tie_by\":null,\"commitment\":\"d12f3c5b37240bc3abf2976f41fdf9a594f0680aafd2781ac448f80440fbeb99\",\"sender\":\"sprt1qqf50y6deqe7dqg3vj562xf3lmktqe3sct78ha6e9jh54sa3q2m5esq7x2tz0xrpm0ekclyyaszc2sh3ksm5gkumxpwegpa80lv5wgsuefqaufx8q\",\"recipient\":\"sprt1qqf2kqh8n7lkupngfk2fxtmvyaq8sy3v2ramyeryweadqmsz7l6tg2qc9n4dl42ff8klz28nznr7mfzh6263xv555stwzextl2v4lvhg3aqq7ru8u\",\"shared_secret\":\"5a28562161f939bf77983df807dd914e73f02ea67a21ed976d214452887ae43e\",\"key\":null,\"confirmed_by\":\"57ca073676fa6130397ce1e4738278952483cee943daa1664b9a1807d4700066:0\",\"timestamp\":1720966687785,\"error\":null}"; const BOB_CHALLENGE_CACHE: &str = "{\"id\":2639151119,\"status\":\"ReceivedMustConfirm\",\"ciphertext\":null,\"plaintext\":[\"TEST\"],\"commited_in\":\"d5edbf1f60ae4fd7d698626b44ed1e85edddf65b45f62e5f82928a9e12759db9:0\",\"tie_by\":null,\"commitment\":\"d12f3c5b37240bc3abf2976f41fdf9a594f0680aafd2781ac448f80440fbeb99\",\"sender\":\"sprt1qqf50y6deqe7dqg3vj562xf3lmktqe3sct78ha6e9jh54sa3q2m5esq7x2tz0xrpm0ekclyyaszc2sh3ksm5gkumxpwegpa80lv5wgsuefqaufx8q\",\"recipient\":\"sprt1qqf2kqh8n7lkupngfk2fxtmvyaq8sy3v2ramyeryweadqmsz7l6tg2qc9n4dl42ff8klz28nznr7mfzh6263xv555stwzextl2v4lvhg3aqq7ru8u\",\"shared_secret\":\"5a28562161f939bf77983df807dd914e73f02ea67a21ed976d214452887ae43e\",\"key\":null,\"confirmed_by\":null,\"timestamp\":1721315780531,\"error\":null}"; const BOB_ANSWER_CACHE: &str = "{\"id\":2639151119,\"status\":\"ReceivedMustConfirm\",\"ciphertext\":null,\"plaintext\":[\"TEST\"],\"commited_in\":\"d5edbf1f60ae4fd7d698626b44ed1e85edddf65b45f62e5f82928a9e12759db9:0\",\"tie_by\":null,\"commitment\":\"d12f3c5b37240bc3abf2976f41fdf9a594f0680aafd2781ac448f80440fbeb99\",\"sender\":\"sprt1qqf50y6deqe7dqg3vj562xf3lmktqe3sct78ha6e9jh54sa3q2m5esq7x2tz0xrpm0ekclyyaszc2sh3ksm5gkumxpwegpa80lv5wgsuefqaufx8q\",\"recipient\":\"sprt1qqf2kqh8n7lkupngfk2fxtmvyaq8sy3v2ramyeryweadqmsz7l6tg2qc9n4dl42ff8klz28nznr7mfzh6263xv555stwzextl2v4lvhg3aqq7ru8u\",\"shared_secret\":\"5a28562161f939bf77983df807dd914e73f02ea67a21ed976d214452887ae43e\",\"key\":null,\"confirmed_by\":\"57ca073676fa6130397ce1e4738278952483cee943daa1664b9a1807d4700066:0\",\"timestamp\":1721315780531,\"error\":null}"; fn helper_switch_device(wallet: String) { reset_device().unwrap(); // debug!("{}", wallet); restore_device_from_sp_wallet(wallet.clone()).unwrap(); // debug!("Restored device with wallet {}", wallet); } fn helper_get_alice_address() -> String { let wallet: SpWallet = serde_json::from_str(ALICE_START_WALLET).unwrap(); wallet.get_client().get_receiving_address() } fn helper_get_bob_address() -> String { let wallet: SpWallet = serde_json::from_str(BOB_START_WALLET).unwrap(); wallet.get_client().get_receiving_address() } fn helper_get_tweak_data(transaction: &str, spk: ScriptBuf) -> String { let tx = deserialize::(&Vec::from_hex(transaction).unwrap()).unwrap(); let prevout = tx.input.get(0).unwrap().to_owned(); let outpoint_data = ( prevout.previous_output.txid.to_string(), prevout.previous_output.vout, ); let input_pubkey = get_pubkey_from_input(&vec![], &prevout.witness.to_vec(), spk.as_bytes()).unwrap(); let tweak_data = calculate_tweak_data(&vec![&input_pubkey.unwrap()], &vec![outpoint_data]).unwrap(); tweak_data.to_string() } fn helper_parse_transaction(transaction: &str, tweak_data: String) -> CachedMessage { let new_tx_msg = serde_json::to_string(&NewTxMessage::new(transaction.to_owned(), Some(tweak_data))) .unwrap(); let network_msg = serde_json::to_string(&AnkNetworkMsg::new( sdk_common::network::AnkFlag::NewTx, &new_tx_msg, )) .unwrap(); let result = parse_network_msg(network_msg, 1); match result { Ok(m) => m, Err(e) => panic!("Unexpected error: {}", e.message), } } fn helper_parse_ank_msg(ank_network_msg: String) -> CachedMessage { let result = parse_network_msg(ank_network_msg, 1); match result { Ok(r) => return r, Err(e) => panic!("Unexpected error: {}", e.message), }; } fn helper_link_alice() { const ALICE_SPEND_KEY: &str = "93292e5b21042c6cfc742ba30e9d2a1e01609b12d154a1825184ed12c7b9631b"; let encrypted_alice_key = encrypt_remote_key( ALICE_SPEND_KEY.to_owned(), Some("073ec0cd90cd77f5486cbfb586ed639c4d435d39bb038dc905d7a65762d29ff9".to_owned()), Some("46b4e8e9cfb1b6fd139d480f".to_owned()), ) .unwrap(); pair_device( Vec::from_hex(&encrypted_alice_key).unwrap(), helper_get_alice_address(), REVOKATION_OUTPUT.to_owned(), ) .unwrap(); } fn helper_link_bob() { const BOB_ENCRYPTED_KEY: &str = "62f10cffb1ed127ef88826c0e65d21dc337c763db53a3d814e1bf21460b53d84d612995ab3b272ac395221bf49cb54df6250502fc8941ba06d85bd58"; pair_device( Vec::from_hex(BOB_ENCRYPTED_KEY).unwrap(), helper_get_alice_address(), REVOKATION_OUTPUT.to_owned(), ) .unwrap(); } // #[wasm_bindgen_test] // fn test_pairing_transaction() { // setup(); // helper_switch_bob(); // // bob sends pairing transaction to alice // let result = create_pairing_transaction(helper_get_alice_address(), 1); // let bob_pairing_transaction = match result { // Ok(t) => t, // Err(e) => { // panic!("create_pairing_transaction failed with {}", e.message); // } // }; // // get the tweak data to add to the transaction // let bob_pairing_tweak_data = helper_get_tweak_data( // &bob_pairing_transaction.transaction, // ScriptBuf::from_hex(BOB_SPK).unwrap(), // ); // // dump bob message cache // let bob_msg_cache = dump_message_cache().unwrap(); // reset_message_cache().unwrap(); // // switch to alice // helper_switch_alice(); // // alice receives and parses that transaction // helper_parse_transaction(&bob_pairing_transaction.transaction, bob_pairing_tweak_data); // // alice receives and parses the message // let bob_sent_ank_msg = AnkNetworkMsg::new( // sdk_common::network::AnkFlag::Cipher, // &bob_pairing_transaction.new_network_msg.ciphertext.unwrap(), // ); // let mut pairing_msg = helper_parse_ank_msg(bob_sent_ank_msg.to_string()); // // Alice takes the key out of the plaintext cached message and returns it encrypted to Bob // let bob_key = pairing_msg.plaintext.pop().unwrap(); // let encrypted_bob_key = encrypt_remote_key( // bob_key, // Some("d8ac223089c8f5e575a06bc0e7071a0dc1124688722ecb34ccf9b3c95e5baaa8".to_owned()), // Some("62f10cffb1ed127ef88826c0".to_owned()), // ) // .unwrap(); // let cipher_msg = CipherMessage::new(helper_get_alice_address(), encrypted_bob_key.clone()); // let encrypted_payload = // encrypt_with_key(cipher_msg.to_string(), pairing_msg.shared_secret.unwrap()).unwrap(); // let alice_response_msg = // AnkNetworkMsg::new(sdk_common::network::AnkFlag::Cipher, &encrypted_payload).to_string(); // // same switch back to Bob // // let alice_msg_cache = dump_message_cache().unwrap(); // reset_message_cache().unwrap(); // helper_switch_bob(); // set_message_cache(bob_msg_cache).unwrap(); // let bob_received_msg = helper_parse_ank_msg(alice_response_msg); // assert!(*bob_received_msg.plaintext.get(0).unwrap() == encrypted_bob_key); // // take the revokation output // let keypair = Keypair::from_seckey_str( // &Secp256k1::signing_only(), // &bob_received_msg.shared_secret.clone().unwrap(), // ) // .unwrap(); // let spk = ScriptBuf::new_p2tr_tweaked(keypair.x_only_public_key().0.dangerous_assume_tweaked()); // let pairing_transaction = // deserialize::(&Vec::from_hex(&bob_pairing_transaction.transaction).unwrap()) // .unwrap(); // let vout = pairing_transaction // .output // .iter() // .position(|o| o.script_pubkey == spk) // .unwrap(); // let revokation_outpoint = // OutPoint::new(pairing_transaction.txid(), vout.try_into().unwrap()).to_string(); // pair_device( // Vec::from_hex(bob_received_msg.plaintext.get(0).unwrap()).unwrap(), // bob_received_msg.recipient.clone().unwrap(), // revokation_outpoint.clone(), // ) // .unwrap(); // // Now we can set a trusted channel, which is basically the pairing // let mut trusted_channel = TrustedChannel::new(bob_received_msg.recipient.unwrap()).unwrap(); // trusted_channel // .set_revokation(revokation_outpoint, bob_received_msg.shared_secret.unwrap()) // .unwrap(); // } #[wasm_bindgen_test] fn test_alice_notifies_bob() { setup(); debug!("==============================================\nStarting test_alice_notifies_bob\n=============================================="); // Alice notifies Bob helper_switch_device(ALICE_START_WALLET.to_owned()); helper_link_alice(); let cipher_msg = CipherMessage::new(helper_get_alice_address(), "TEST".to_owned()); debug!("Alice notifies Bob"); let notification_tx = create_notification_transaction(helper_get_bob_address(), cipher_msg, 1).unwrap(); // debug!("new_network_msg: {:?}", notification_tx.new_network_msg); // debug!("notification_tx: {}", serde_json::to_string(¬ification_tx).unwrap()); let notification_tweak_data = helper_get_tweak_data( ¬ification_tx.transaction, ScriptBuf::from_hex(ALICE_SPK).unwrap(), ); let ank_msg = AnkNetworkMsg::new( sdk_common::network::AnkFlag::Cipher, ¬ification_tx.new_network_msg.ciphertext.unwrap(), ); debug!("Alice parse her own notification transaction"); // Alice parse her own transaction to update her utxos helper_parse_transaction( ¬ification_tx.transaction, notification_tweak_data.clone(), ); // debug!("Alice parsed transaction {}", notification_tx.txid); // debug!("alice_wallet_dump: {:?}", dump_watch_only_wallet().unwrap()); reset_device().unwrap(); helper_switch_device(BOB_START_WALLET.to_owned()); helper_link_bob(); debug!( "Bob parses notification transaction {}", notification_tx.txid ); // bob parse the transaction and the message helper_parse_transaction(¬ification_tx.transaction, notification_tweak_data); helper_parse_ank_msg(ank_msg.to_string()); } #[wasm_bindgen_test] fn test_bob_challenges_alice() { setup(); debug!("==============================================\nStarting test_bob_challenges_alice\n=============================================="); helper_switch_device(BOB_CHALLENGE_WALLET.to_owned()); helper_link_bob(); set_message_cache(vec![BOB_CHALLENGE_CACHE.to_owned()]).unwrap(); let notification_msg: CachedMessage = serde_json::from_str(BOB_CHALLENGE_CACHE).unwrap(); let commited_in = notification_msg.commited_in.unwrap(); let get_outputs_result = get_outputs().unwrap(); let bob_outputs: HashMap = get_outputs_result.into_serde().unwrap(); let bob_spk = &bob_outputs.get(&commited_in).unwrap().script; debug!("Bob sends a challenge transaction back to Alice"); let confirmation_tx = create_confirmation_transaction(notification_msg.id, 1).unwrap(); let confirmation_tweak_data = helper_get_tweak_data( &confirmation_tx.transaction, ScriptBuf::from_hex(&bob_spk).unwrap(), ); debug!("Bob parsing its own confirmation tx"); helper_parse_transaction( &confirmation_tx.transaction, confirmation_tweak_data.clone(), ); reset_device().unwrap(); helper_switch_device(ALICE_CHALLENGE_WALLET.to_owned()); helper_link_alice(); set_message_cache(vec![ALICE_CHALLENGE_CACHE.to_owned()]).unwrap(); debug!("Alice parsing confirmation tx"); helper_parse_transaction(&confirmation_tx.transaction, confirmation_tweak_data); } #[wasm_bindgen_test] fn test_alice_answers_bob() { setup(); debug!("==============================================\nStarting test_alice_answers_bob\n=============================================="); helper_switch_device(ALICE_ANSWER_WALLET.to_owned()); helper_link_alice(); set_message_cache(vec![ALICE_ANSWER_CACHE.to_owned()]).unwrap(); let challenge_msg: CachedMessage = serde_json::from_str(ALICE_ANSWER_CACHE).unwrap(); debug!("Alice answers bob's challenge"); let answer_tx = answer_confirmation_transaction(challenge_msg.id, 1).unwrap(); // debug!("answer_tx: {:?}", answer_tx.new_network_msg); let confirmed_by = challenge_msg.confirmed_by.unwrap(); debug!("confirmed_by: {}", confirmed_by); let get_outputs_result = get_outputs().unwrap(); let alice_outputs: HashMap = get_outputs_result.into_serde().unwrap(); let alice_spk = &alice_outputs.get(&confirmed_by).unwrap().script; let answer_tweak_data = helper_get_tweak_data( &answer_tx.transaction, ScriptBuf::from_hex(&alice_spk).unwrap(), ); debug!("Alice parsing its own answer tx"); debug!( "message: {}", serde_json::to_string(&answer_tx.new_network_msg).unwrap() ); helper_parse_transaction(&answer_tx.transaction, answer_tweak_data.clone()); reset_device().unwrap(); helper_switch_device(BOB_ANSWER_WALLET.to_owned()); helper_link_bob(); set_message_cache(vec![BOB_ANSWER_CACHE.to_owned()]).unwrap(); debug!("Bob parses answer transaction {}", answer_tx.txid); let answer_msg = helper_parse_transaction(&answer_tx.transaction, answer_tweak_data); debug!( "bob's message: {}", serde_json::to_string(&answer_msg).unwrap() ); } // #[wasm_bindgen_test] // fn test_linking_devices() { // setup(); // helper_switch_bob(); // // bob sends pairing transaction to alice // let result = create_pairing_transaction(helper_get_alice_address(), 1); // let bob_pairing_transaction = match result { // Ok(t) => t, // Err(e) => { // panic!("create_pairing_transaction failed with {}", e.message); // } // }; // // get the tweak data to add to the transaction // let bob_pairing_tweak_data = helper_get_tweak_data( // &bob_pairing_transaction.transaction, // ScriptBuf::from_hex(BOB_SPK).unwrap(), // ); // // alice receives and parses that transaction // helper_switch_alice(); // helper_parse_transaction(&bob_pairing_transaction.transaction, bob_pairing_tweak_data); // // alice receives and parses the message // let pairing_msg = // helper_parse_cipher_msg(bob_pairing_transaction.new_network_msg.ciphertext.unwrap()); // // and sends the encrypted key back in a confirm transaction // let result = create_confirmation_transaction(pairing_msg.id, 1); // let alice_confirm_transaction = match result { // Ok(r) => r, // Err(e) => { // panic!("create_pairing_transaction failed with {}", e.message); // } // }; // // get the tweak data to add to the transaction // let alice_confirm_tweak_data = helper_get_tweak_data( // &alice_confirm_transaction.transaction, // helper_get_spk( // bob_pairing_transaction.transaction, // alice_confirm_transaction // .new_network_msg // .commited_in // .unwrap(), // ), // ); // // alice parses her own transaction to update her utxoset // helper_parse_transaction( // &alice_confirm_transaction.transaction, // alice_confirm_tweak_data.clone(), // ); // // alice sends her own pairing transaction // let result = create_pairing_transaction(helper_get_bob_address(), 1); // let alice_pairing_transaction = match result { // Ok(t) => t, // Err(e) => { // panic!("create_pairing_transaction failed with {}", e.message); // } // }; // // get the tweak data to add to the transaction // let alice_pairing_tweak_data = helper_get_tweak_data( // &alice_pairing_transaction.transaction, // ScriptBuf::from_hex(ALICE_SPK).unwrap(), // ); // helper_switch_bob(); // // bob receives the spend_key from alice and does the same thing // helper_parse_transaction( // &alice_pairing_transaction.transaction, // alice_pairing_tweak_data, // ); // let pairing_msg = helper_parse_cipher_msg( // alice_pairing_transaction // .new_network_msg // .ciphertext // .unwrap(), // ); // // let result = create_confirmation_transaction(pairing_msg.id, 1); // // let bob_confirm_transaction = match result { // // Ok(r) => r, // // Err(e) => { // // panic!("create_pairing_transaction failed with {}", e.message); // // } // // }; // // bob also received the confirmation transaction from alice, containing his own encrypted key // log::debug!("Parsing alice confirmation transaction"); // helper_parse_transaction( // &alice_confirm_transaction.transaction, // alice_confirm_tweak_data, // ); // log::debug!("Parsing the message that goes with it"); // let confirmation_msg = helper_parse_cipher_msg( // alice_confirm_transaction // .new_network_msg // .ciphertext // .unwrap(), // ); // log::debug!("{:?}", confirmation_msg); // // bob can now update its device with the linking information // pair_device( // confirmation_msg.plaintext.get(0).unwrap().to_owned().into(), // confirmation_msg.recipient.unwrap(), // OutPoint::null().to_string(), // ) // .unwrap(); // }