Skip to content

Commit

Permalink
Change network in settings
Browse files Browse the repository at this point in the history
  • Loading branch information
Rodrigo Sanchez committed May 15, 2023
1 parent 733ef95 commit 60f4d78
Show file tree
Hide file tree
Showing 22 changed files with 229 additions and 54 deletions.
4 changes: 0 additions & 4 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,3 @@ edition = "2021"

[dependencies]
signer = { path = "../signer" }

[features]
regtest = ["signer/regtest"]
mainnet = []
7 changes: 6 additions & 1 deletion cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ fn main() {
let mut wallet = Wallet::default();
//wallet.from_seed_str("wallet 1", "solar goat auto bachelor chronic input twin depth fork scale divorce fury mushroom column image sauce car public artist announce treat spend jacket physical", "Qwerty123").unwrap();
wallet.from_xprv_str("wallet 1", "tprv8ZgxMBicQKsPduvXYAnkop1b1UoAY2pS68pe9jHuJwuMvx6G5sh4C67peYZkRawdBWbMbfoybgQJ3g8nTZAezEeHyaW9A9UjtpTRmSyJwUn", "m/48'/1'/1'", "Qwerty123").unwrap();
let signed_psbt = decode_psbt_and_sign(&args.next().unwrap(), &mut wallet, "Qwerty123");
let signed_psbt = decode_psbt_and_sign(
&args.next().unwrap(),
&mut wallet,
"Qwerty123",
signer::Network::Bitcoin,
);
println!("{}", signed_psbt.unwrap())
}
4 changes: 1 addition & 3 deletions extension/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ crate-type = ["cdylib"]

[dependencies]
anyhow = "1.0.69"
signer = { path = "../signer", features=["regtest"] }
signer = { path = "../signer" }
wasm-bindgen = { version="0.2.84" }
yew = { version = "0.20.0", features = ["csr"] }
yew-router = "0.17.0"
Expand All @@ -36,5 +36,3 @@ features = [
"Navigator"
]

[features]
regtest = []
1 change: 1 addition & 0 deletions extension/src/components/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod radio_button;
pub mod select;
pub mod text_input;
pub mod textarea;
40 changes: 40 additions & 0 deletions extension/src/components/radio_button.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use anyhow::{anyhow, Context, Result};
use wasm_bindgen::JsCast;
use web_sys::{Event, HtmlInputElement};
use yew::prelude::*;

#[derive(Clone, PartialEq, Properties, Eq)]
pub struct Props {
pub id: Option<String>,
pub value: String,
pub label: String,
pub name: String,
pub checked: bool,
}

pub fn get_value_from_radio_event(event: Event) -> Result<String> {
let event_target = event.target().context("Error accessing tareget")?;
let target: HtmlInputElement = event_target
.dyn_into()
.map_err(|_| anyhow!("Error accessing input element"))?;
Ok(target.value())
}

#[function_component(RadioButton)]
pub fn radio_button(props: &Props) -> Html {
let Props {
id,
value,
label,
name,
checked,
} = props.clone();

let for_name = name.clone();
html! {
<div>
<input type="radio" {id} {name} {value} {checked} />
<label for={for_name}>{label}</label>
</div>
}
}
9 changes: 7 additions & 2 deletions extension/src/features/approve_psbt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ use crate::{
OperationRequestData,
};
use anyhow::anyhow;
use signer::{psbt_details::PSBTDetails, signer::decode_psbt_and_sign, storage::UserStorage};
use signer::{
psbt_details::PSBTDetails,
signer::decode_psbt_and_sign,
storage::{SettingsStorage, UserStorage},
};
use std::str::FromStr;
use web_sys::window;
use yew::prelude::*;
Expand Down Expand Up @@ -52,12 +56,13 @@ pub fn approve_psbt() -> Html {
return;
}
let mut storage = UserStorage::read(LocalStorage::default());
let settings_storage = SettingsStorage::read(LocalStorage::default());

let result = storage
.get_wallet_mut(&selected_wallet_value)
.ok_or_else(|| anyhow!("Wallet not found"))
.and_then(|wallet| {
decode_psbt_and_sign(&psbt, wallet, &password)
decode_psbt_and_sign(&psbt, wallet, &password, settings_storage.get_network())
.map_err(|e| anyhow!("Error while signing PSBT {e}"))
})
.and_then(|signed_psbt| {
Expand Down
5 changes: 3 additions & 2 deletions extension/src/features/export_xpub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
utils::{helpers::get_clipboard, storage::LocalStorage},
};
use anyhow::Result;
use signer::storage::UserStorage;
use signer::storage::{SettingsStorage, UserStorage};
use web_sys::MouseEvent;
use yew::prelude::*;
use yew_router::prelude::use_navigator;
Expand Down Expand Up @@ -46,6 +46,7 @@ pub fn export_xpub(props: &Props) -> Html {
move |_| {
if !password_value_ue.is_empty() {
let mut storage = UserStorage::read(LocalStorage::default());
let settings = SettingsStorage::read(LocalStorage::default());
let wallet = storage.get_wallet_mut(&wallet_name);
if let Some(w) = wallet {
let full_path = if next_derivation_value_ue.is_empty() {
Expand All @@ -56,7 +57,7 @@ pub fn export_xpub(props: &Props) -> Html {
if full_path.ends_with('/') {
return;
}
w.derive_xpub(&full_path, &password_value_ue)
w.derive_xpub(&full_path, &password_value_ue, settings.get_network())
.as_ref()
.map_or_else(
|_| revealed_xpub_ue.set("Incorrect derivation path".to_string()),
Expand Down
8 changes: 8 additions & 0 deletions extension/src/features/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ pub fn home() -> Html {
})
};

let onclick_settings = {
let navigator = navigator.clone();
Callback::from(move |_: MouseEvent| {
navigator.push(&Route::Settings);
})
};

let onclick_export = {
let selected_wallet_value = selected_wallet_value.clone();
Callback::from(move |_: MouseEvent| {
Expand Down Expand Up @@ -124,6 +131,7 @@ pub fn home() -> Html {
<button onclick={onclick_reveal}>{reveal_message}</button>
<button onclick={onclick_import}>{"Import another wallet"}</button>
<button onclick={onclick_export}>{"Export XPUB"}</button>
<button onclick={onclick_settings}>{"Settings"}</button>
</>
}
}
1 change: 1 addition & 0 deletions extension/src/features/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ pub mod import_from_xprv;
pub mod import_wallet;
pub mod input_password_modal;
pub mod password_injector;
pub mod settings;
5 changes: 4 additions & 1 deletion extension/src/features/password_injector.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
context::{ContextAction, UserContext},
get_password,
get_password, session_exists,
};
use wasm_bindgen_futures::spawn_local;
use yew::prelude::*;
Expand All @@ -16,6 +16,9 @@ pub fn PasswordInjector(props: &PasswordInjectorProps) -> Html {
let context = use_context::<UserContext>().unwrap();
let existing_password = context.password.clone().unwrap_or_default();
use_effect(move || {
if !session_exists().unwrap_or_default() {
return;
}
spawn_local(async move {
match get_password().await {
Ok(password) if !password.is_empty() && password != existing_password => {
Expand Down
53 changes: 53 additions & 0 deletions extension/src/features/settings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use signer::{storage::SettingsStorage, Network};
use std::str::FromStr;
use yew::prelude::*;
use yew_router::prelude::use_navigator;

use crate::{
components::radio_button::{get_value_from_radio_event, RadioButton},
switch::Route,
utils::storage::LocalStorage,
};

#[function_component(Settings)]
pub fn settings() -> Html {
let storage = SettingsStorage::read(LocalStorage::default());
let navigator = use_navigator().unwrap();
let network = use_state(|| storage.get_network());
let error = use_state(String::new);
let network_value = *network;
let error_value = (*error).clone();

let on_network_change = Callback::from(move |input_event: Event| {
let value = get_value_from_radio_event(input_event).unwrap();
network.set(Network::from_str(&value).unwrap());
});

let onclick_save = {
Callback::from(move |_| {
let mut storage = SettingsStorage::read(LocalStorage::default());
storage.set_network(&network_value.to_string());
let stored = storage.save();

if stored.is_err() {
error.set("Unable to save settings".to_string());
} else {
navigator.push(&Route::Home);
}
})
};

html! {
<>
<fieldset onchange={on_network_change} >
<legend>{"Select a network"}</legend>
<RadioButton id="mainnet" name="mainnet" value={Network::Bitcoin.to_string()} checked={network_value == Network::Bitcoin} label="Mainnet" />
<RadioButton id="regtest" name="regtest" value={Network::Regtest.to_string()} checked={network_value == Network::Regtest} label="Regtest" />
<RadioButton id="signet" name="signet" value={Network::Signet.to_string()} checked={network_value == Network::Signet} label="Signet" />
<RadioButton id="testnet" name="testnet" value={Network::Testnet.to_string()} checked={network_value == Network::Testnet} label="Testnet" />
</fieldset>
<div class="error">{error_value}</div>
<button onclick={onclick_save}>{"Save"}</button>
</>
}
}
1 change: 1 addition & 0 deletions extension/src/import_wasm.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const import_wasm: () => Promise<typeof import('../pkg/extension')>;

interface CustomWindow extends Window {
sessionExists(): bool;
pastePSBT(psbt: string): Promise<void>;
savePassword(password: string): Promise<void>;
getPassword(): Promise<{ password: string; }>;
Expand Down
6 changes: 5 additions & 1 deletion extension/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use anyhow::Result;
use app::App;
use serde::Deserialize;
use utils::{
casts::{call_fn_str, call_fn_str_async, call_fn_to_str_async},
casts::{call_fn_str, call_fn_str_async, call_fn_to_bool, call_fn_to_str_async},
events::{EventManager, State},
};
use wasm_bindgen::prelude::*;
Expand Down Expand Up @@ -53,3 +53,7 @@ pub async fn save_password(password: &str) -> Result<()> {
pub async fn get_password() -> Result<String> {
call_fn_to_str_async("getPassword").await
}

pub fn session_exists() -> Result<bool> {
call_fn_to_bool("sessionExists")
}
22 changes: 15 additions & 7 deletions extension/src/popup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,31 @@ declare namespace browser.storage.session {
}
}

window.sessionExists = () => !!browser?.storage?.session;

const clearPassword = async () => {
console.log("clearing password");
await browser.storage.session.clear();
if (!browser) {
return;
}
await browser?.storage?.session?.clear?.();
};

window.savePassword = async (password: string) => {
await browser.storage.session.set({ password, expiration: Date.now() + 1000 * 60 * 5 });
if (!browser) {
return;
}
await browser?.storage?.session?.set?.({ password, expiration: Date.now() + 1000 * 60 * 5 });
};

window.getPassword = async () => {
let password_data = await browser.storage.session.get("password");
let expiration_data = await browser.storage.session.get("expiration");
console.log(expiration_data);
if (!browser) {
return "";
}
let password_data = await browser?.storage?.session?.get?.("password");
let expiration_data = await browser?.storage?.session?.get?.("expiration");
if (!expiration_data?.expiration || expiration_data.expiration < Date.now()) {
await clearPassword();
return "";
}
console.log(password_data);
return password_data.password;
};
5 changes: 4 additions & 1 deletion extension/src/switch.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::features::{
approve_psbt::ApprovePSBT, create_account::CreateAccount, export_xpub::ExportXPUB,
generate_seed::GenerateSeed, home::Home, import_from_seed::ImportFromSeed,
import_from_xprv::ImportFromXprv, import_wallet::ImportWallet,
import_from_xprv::ImportFromXprv, import_wallet::ImportWallet, settings::Settings,
};
use yew::{function_component, html, Html};
use yew_router::{prelude::use_navigator, Routable, Switch};
Expand All @@ -20,6 +20,8 @@ pub enum Route {
ApprovePSBT,
#[at("/exportxpub/:wallet_name")]
ExportXPUB { wallet_name: String },
#[at("/settings")]
Settings,
#[not_found]
#[at("/404")]
NotFound,
Expand Down Expand Up @@ -57,6 +59,7 @@ pub fn switch(routes: Route) -> Html {
}
Route::ApprovePSBT => html! { <ApprovePSBT/> },
Route::ExportXPUB { wallet_name } => html! { <ExportXPUB wallet_name={wallet_name}/> },
Route::Settings => html! { <Settings /> },
Route::NotFound => html! { <Redirect /> },
};

Expand Down
12 changes: 12 additions & 0 deletions extension/src/utils/casts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ pub async fn call_fn_to_str_async(fn_name: &str) -> Result<String> {
.context("Error while casting JS value to string")
}

pub fn call_fn_to_bool(fn_name: &str) -> Result<bool> {
let js_function = get_fn(fn_name)?;

let js_value = js_function
.call0(&JsValue::undefined())
.map_err(|_| anyhow!("Error while calling JS function"))?;

js_value
.as_bool()
.context("Error while casting JS value to string")
}

pub fn call_fn(fn_name: &str) -> Result<()> {
let js_function = get_fn(fn_name)?;

Expand Down
2 changes: 1 addition & 1 deletion extension/static/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "PSBT Signer",
"description": "Sign your Nodeguard PSBTs with a few clicks",
"description": "Import or generate your Bitcoin mnemonics, export your xpubs and sign your PSBTs with a few clicks. Your private keys never leave your browser, we don't store any data in our servers.",
"version": "0.1.0",
"action": {
"default_popup": "popup.html"
Expand Down
5 changes: 0 additions & 5 deletions signer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,3 @@ chacha20poly1305 = "0.10.1"
ccm = "0.5.0"
aes = "0.8.2"
aes-gcm = "0.10.1"

[features]
regtest = []
testnet = []
signet = []
14 changes: 1 addition & 13 deletions signer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
use bitcoin::Network;
pub use bitcoin::Network;

pub mod psbt_details;
pub mod signer;
pub mod storage;
pub mod utils;
pub mod wallet;

#[cfg(feature = "regtest")]
pub const NETWORK: Network = Network::Regtest;

#[cfg(feature = "testnet")]
pub const NETWORK: Network = Network::Testnet;

#[cfg(feature = "signet")]
pub const NETWORK: Network = Network::Signet;

#[cfg(not(any(feature = "regtest", feature = "testnet", feature = "signet")))]
pub const NETWORK: Network = Network::Bitcoin;
Loading

0 comments on commit 60f4d78

Please sign in to comment.