Skip to content

Commit

Permalink
WIP: Notification client
Browse files Browse the repository at this point in the history
  • Loading branch information
benthecarman committed Oct 18, 2023
1 parent 328571f commit 6205bcb
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 0 deletions.
39 changes: 39 additions & 0 deletions mutiny-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ mod networking;
mod node;
pub mod nodemanager;
pub mod nostr;
pub mod notifications;
mod onchain;
mod peermanager;
pub mod redshift;
Expand All @@ -52,13 +53,16 @@ pub use crate::ldkstorage::{CHANNEL_MANAGER_KEY, MONITORS_PREFIX_KEY};
use crate::auth::MutinyAuthClient;
use crate::labels::{Contact, LabelStorage};
use crate::nostr::nwc::{NwcProfileTag, SpendingConditions};
use crate::notifications::MutinyNotificationClient;
use crate::storage::{MutinyStorage, DEVICE_ID_KEY, EXPECTED_NETWORK_KEY, NEED_FULL_SYNC_KEY};
use crate::{error::MutinyError, nostr::ReservedProfile};
use crate::{nodemanager::NodeManager, nostr::ProfileType};
use crate::{nostr::NostrManager, utils::sleep};
use ::nostr::key::XOnlyPublicKey;
use ::nostr::{Event, Kind, Metadata};
use bip39::Mnemonic;
use bitcoin::hashes::hex::ToHex;
use bitcoin::hashes::{sha256, Hash};
use bitcoin::secp256k1::PublicKey;
use bitcoin::util::bip32::ExtendedPrivKey;
use bitcoin::Network;
Expand All @@ -84,6 +88,7 @@ pub struct MutinyWalletConfig {
auth_client: Option<Arc<MutinyAuthClient>>,
subscription_url: Option<String>,
scorer_url: Option<String>,
notification_url: Option<String>,
do_not_connect_peers: bool,
skip_device_lock: bool,
pub safe_mode: bool,
Expand All @@ -101,6 +106,7 @@ impl MutinyWalletConfig {
auth_client: Option<Arc<MutinyAuthClient>>,
subscription_url: Option<String>,
scorer_url: Option<String>,
notification_url: Option<String>,
skip_device_lock: bool,
) -> Self {
Self {
Expand All @@ -111,6 +117,7 @@ impl MutinyWalletConfig {
user_esplora_url,
user_rgs_url,
scorer_url,
notification_url,
lsp_url,
auth_client,
subscription_url,
Expand Down Expand Up @@ -140,6 +147,7 @@ pub struct MutinyWallet<S: MutinyStorage> {
pub storage: S,
pub node_manager: Arc<NodeManager<S>>,
pub nostr: Arc<NostrManager<S>>,
pub notification_client: Option<Arc<MutinyNotificationClient>>,
}

impl<S: MutinyStorage> MutinyWallet<S> {
Expand All @@ -161,6 +169,31 @@ impl<S: MutinyStorage> MutinyWallet<S> {

NodeManager::start_sync(node_manager.clone());

let notification_client = match config.notification_url.clone() {
Some(url) => {
let client = match config.auth_client.clone() {
Some(auth_client) => MutinyNotificationClient::new_authenticated(
auth_client,
url,
node_manager.logger.clone(),
),
None => {
// hash key and use that as identifier
let hash = sha256::Hash::hash(&config.xprivkey.private_key.secret_bytes());
let identifier_key = hash.to_hex();
MutinyNotificationClient::new_unauthenticated(
url,
identifier_key,
node_manager.logger.clone(),
)
}
};

Some(Arc::new(client))
}
None => None,
};

// create nostr manager
let nostr = Arc::new(NostrManager::from_mnemonic(
node_manager.xprivkey,
Expand All @@ -173,6 +206,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
storage,
node_manager,
nostr,
notification_client,
};

#[cfg(not(test))]
Expand Down Expand Up @@ -606,6 +640,7 @@ mod tests {
None,
None,
None,
None,
false,
);
let mw = MutinyWallet::new(storage.clone(), config)
Expand Down Expand Up @@ -636,6 +671,7 @@ mod tests {
None,
None,
None,
None,
false,
);
let mut mw = MutinyWallet::new(storage.clone(), config)
Expand Down Expand Up @@ -672,6 +708,7 @@ mod tests {
None,
None,
None,
None,
false,
);
let mut mw = MutinyWallet::new(storage.clone(), config)
Expand Down Expand Up @@ -709,6 +746,7 @@ mod tests {
None,
None,
None,
None,
false,
);
let mw = MutinyWallet::new(storage.clone(), config)
Expand All @@ -734,6 +772,7 @@ mod tests {
None,
None,
None,
None,
false,
);
let mw2 = MutinyWallet::new(storage2.clone(), config2.clone())
Expand Down
4 changes: 4 additions & 0 deletions mutiny-core/src/nodemanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2692,6 +2692,7 @@ mod tests {
None,
None,
None,
None,
false,
);
NodeManager::new(c, storage.clone())
Expand Down Expand Up @@ -2722,6 +2723,7 @@ mod tests {
None,
None,
None,
None,
false,
);
let nm = NodeManager::new(c, storage)
Expand Down Expand Up @@ -2773,6 +2775,7 @@ mod tests {
None,
None,
None,
None,
false,
);
let c = c.with_safe_mode();
Expand Down Expand Up @@ -2809,6 +2812,7 @@ mod tests {
None,
None,
None,
None,
false,
);
let nm = NodeManager::new(c, storage)
Expand Down
84 changes: 84 additions & 0 deletions mutiny-core/src/notifications.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use crate::auth::MutinyAuthClient;
use crate::{error::MutinyError, logging::MutinyLogger};
use anyhow::anyhow;
use lightning::util::logger::*;
use lightning::{log_error, log_info};
use reqwest::{Method, Url};
use serde_json::{json, Value};
use std::sync::Arc;

#[derive(Clone)]
pub struct MutinyNotificationClient {
auth_client: Option<Arc<MutinyAuthClient>>,
client: Option<reqwest::Client>,
url: String,
id: Option<String>,
pub logger: Arc<MutinyLogger>,
}

impl MutinyNotificationClient {
pub fn new_authenticated(
auth_client: Arc<MutinyAuthClient>,
url: String,
logger: Arc<MutinyLogger>,
) -> Self {
log_info!(logger, "Creating authenticated notification client");
Self {
auth_client: Some(auth_client),
client: None,
url,
id: None, // we get this from the auth client
logger,
}
}

pub fn new_unauthenticated(
url: String,
identifier_key: String,
logger: Arc<MutinyLogger>,
) -> Self {
log_info!(logger, "Creating unauthenticated notification client");
Self {
auth_client: None,
client: Some(reqwest::Client::new()),
url,
id: Some(identifier_key),
logger,
}
}

async fn make_request(
&self,
method: Method,
url: Url,
body: Option<Value>,
) -> Result<reqwest::Response, MutinyError> {
match (self.auth_client.as_ref(), self.client.as_ref()) {
(Some(auth), _) => auth.request(method, url, body).await,
(None, Some(client)) => {
let mut request = client.request(method, url);
if let Some(body) = body {
request = request.json(&body);
}
request.send().await.map_err(|e| {
log_error!(self.logger, "Error making request: {e}");
MutinyError::Other(anyhow!("Error making request: {e}"))
})
}
(None, None) => unreachable!("No auth client or http client"),
}
}

pub async fn register(&self, info: Value) -> Result<(), MutinyError> {
let url = Url::parse(&format!("{}/register", self.url)).map_err(|e| {
log_error!(self.logger, "Error parsing register url: {e}");
MutinyError::InvalidArgumentsError
})?;

let body = json!({"id": self.id, "info": info});

self.make_request(Method::POST, url, Some(body)).await?;

Ok(())
}
}
66 changes: 66 additions & 0 deletions mutiny-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use lnurl::lnurl::LnUrl;
use mutiny_core::auth::MutinyAuthClient;
use mutiny_core::lnurlauth::AuthManager;
use mutiny_core::nostr::nwc::{BudgetedSpendingConditions, NwcProfileTag, SpendingConditions};
use mutiny_core::notifications::MutinyNotificationClient;
use mutiny_core::redshift::RedshiftManager;
use mutiny_core::redshift::RedshiftRecipient;
use mutiny_core::scb::EncryptedSCB;
Expand Down Expand Up @@ -80,6 +81,7 @@ impl MutinyWallet {
subscription_url: Option<String>,
storage_url: Option<String>,
scorer_url: Option<String>,
notification_url: Option<String>,
do_not_connect_peers: Option<bool>,
skip_device_lock: Option<bool>,
safe_mode: Option<bool>,
Expand Down Expand Up @@ -174,6 +176,7 @@ impl MutinyWallet {
auth_client,
subscription_url,
scorer_url,
notification_url,
skip_device_lock.unwrap_or(false),
);

Expand Down Expand Up @@ -1356,6 +1359,64 @@ impl MutinyWallet {
Ok(self.inner.reset_onchain_tracker().await?)
}

/// Register the wallet for web-push notifications
#[wasm_bindgen]
pub async fn register_web_push(&self, info: JsValue) -> Result<(), MutinyJsError> {
match self.inner.notification_client.as_ref() {
Some(client) => {
let info = info.into_serde()?;
client.register(info).await?;
}
None => return Err(MutinyJsError::NotFound),
}

Ok(())
}

/// test function for now, will delete in future
#[wasm_bindgen]
pub async fn test_register_web_push(
auth_url: String,
notification_url: String,
info: JsValue,
) -> Result<(), MutinyJsError> {
let logger = Arc::new(MutinyLogger::default());
let storage = IndexedDbStorage::new(None, None, None, logger.clone()).await?;

let mnemonic = storage.get_mnemonic()?.unwrap();

let seed = mnemonic.to_seed("");
let xprivkey = ExtendedPrivKey::new_master(Network::Signet, &seed).unwrap();

let auth_manager = AuthManager::new(xprivkey).unwrap();

let lnurl_client = Arc::new(
lnurl::Builder::default()
.build_async()
.expect("failed to make lnurl client"),
);

let auth_client = Arc::new(MutinyAuthClient::new(
auth_manager,
lnurl_client,
logger.clone(),
auth_url,
));

let notification_client = MutinyNotificationClient::new_authenticated(
auth_client,
notification_url,
logger.clone(),
);

let info = info.into_serde()?;
notification_client.register(info).await?;

log::info!("Registered!");

Ok(())
}

/// Exports the current state of the node manager to a json object.
#[wasm_bindgen]
pub async fn export_json(password: Option<String>) -> Result<String, MutinyJsError> {
Expand Down Expand Up @@ -1485,6 +1546,7 @@ mod tests {
None,
None,
None,
None,
)
.await
.expect("mutiny wallet should initialize");
Expand Down Expand Up @@ -1519,6 +1581,7 @@ mod tests {
None,
None,
None,
None,
)
.await
.unwrap();
Expand Down Expand Up @@ -1556,6 +1619,7 @@ mod tests {
None,
None,
None,
None,
)
.await
.expect("mutiny wallet should initialize");
Expand Down Expand Up @@ -1621,6 +1685,7 @@ mod tests {
None,
None,
None,
None,
)
.await
.expect("mutiny wallet should initialize");
Expand Down Expand Up @@ -1674,6 +1739,7 @@ mod tests {
None,
None,
None,
None,
)
.await
.expect("mutiny wallet should initialize");
Expand Down

0 comments on commit 6205bcb

Please sign in to comment.