Skip to content

Commit

Permalink
Project import generated by Copybara.
Browse files Browse the repository at this point in the history
GitOrigin-RevId: b8f9bc3ce00b1d3bbcfeb0a42da4ef6d1d160792
  • Loading branch information
Lightspark Eng authored and zhenlu committed Oct 13, 2023
1 parent f6c809b commit cdb8cbb
Show file tree
Hide file tree
Showing 12 changed files with 204 additions and 26 deletions.
40 changes: 39 additions & 1 deletion examples/uma-demo/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,40 @@
#[derive(Debug, Clone)]
pub struct Config {}
pub struct Config {
pub api_client_id: String,
pub api_client_secret: String,
pub node_id: String,
pub username: String,
pub user_id: String,
pub uma_encryption_private_key_hex: String,
pub uma_signing_private_key_hex: String,
pub node_master_seed_hex: String,
pub client_base_url: String,
}

impl Config {
pub fn new_from_env() -> Self {
let api_endpoint = std::env::var("LIGHTSPARK_API_ENDPOINT").ok();
let api_client_id = std::env::var("LIGHTSPARK_API_CLIENT_ID").ok();
let api_client_secret = std::env::var("LIGHTSPARK_API_CLIENT_SECRET").ok();
let master_seed_hex = std::env::var("LIGHTSPARK_MASTER_SEED_HEX").ok();
let node_id = std::env::var("LIGHTSPARK_NODE_ID").ok();
let username = std::env::var("LIGHTSPARK_USERNAME").ok();
let user_id = std::env::var("LIGHTSPARK_USER_ID").ok();
let uma_encryption_private_key_hex =
std::env::var("LIGHTSPARK_UMA_ENCRYPTION_PRIVATE_KEY_HEX").ok();
let uma_signing_private_key_hex =
std::env::var("LIGHTSPARK_UMA_SIGNING_PRIVATE_KEY_HEX").ok();

Config {
api_client_id: api_client_id.unwrap_or_default(),
api_client_secret: api_client_secret.unwrap_or_default(),
node_id: node_id.unwrap_or_default(),
username: username.unwrap_or_default(),
user_id: user_id.unwrap_or_default(),
uma_encryption_private_key_hex: uma_encryption_private_key_hex.unwrap_or_default(),
uma_signing_private_key_hex: uma_signing_private_key_hex.unwrap_or_default(),
node_master_seed_hex: master_seed_hex.unwrap_or_default(),
client_base_url: api_endpoint.unwrap_or_default(),
}
}
}
4 changes: 2 additions & 2 deletions examples/uma-demo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ async fn main() -> std::io::Result<()> {
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(VASP {
config: config::Config {},
config: config::Config::new_from_env(),
}))
.service(uma_lookup)
.service(client_payreq)
Expand All @@ -57,7 +57,7 @@ async fn main() -> std::io::Result<()> {
.service(lnurl_payreq)
.service(uma_payreq)
})
.bind(("127.0.0.1", port))?
.bind(("0.0.0.0", port))?
.run()
.await
}
3 changes: 3 additions & 0 deletions lightspark-remote-signing/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## v0.2.1
- Remove is_raw field for derive_key_and_sign.

## v0.2.0
- Remove unnecessary lightspark dependencies.
- Expose lightspark crates.
Expand Down
2 changes: 1 addition & 1 deletion lightspark-remote-signing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "lightspark-remote-signing"
description = "Lightspark Remote Signing SDK for Rust"
authors = ["Lightspark Group, Inc. <[email protected]>"]
version = "0.2.0"
version = "0.2.1"
edition = "2021"
documentation = "https://app.lightspark.com/docs/"
homepage = "https://www.lightspark.com/"
Expand Down
2 changes: 0 additions & 2 deletions lightspark-remote-signing/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,6 @@ impl Handler {
.derive_key_and_sign(
hex::decode(signing_job.message).map_err(|_| Error::HexEncodingError)?,
signing_job.derivation_path,
signing_job.is_raw,
signing_job
.add_tweak
.map(|tweak| hex::decode(tweak).map_err(|_| Error::HexEncodingError))
Expand Down Expand Up @@ -252,5 +251,4 @@ struct SigningJob {
message: String,
add_tweak: Option<String>,
mul_tweak: Option<String>,
is_raw: bool,
}
21 changes: 6 additions & 15 deletions lightspark-remote-signing/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use std::str::FromStr;
use bitcoin::bip32::{DerivationPath, ExtendedPrivKey, ExtendedPubKey};
use bitcoin::hashes::{sha512, Hash, HashEngine, Hmac, HmacEngine};
use bitcoin::secp256k1::ecdh::SharedSecret;
use bitcoin::secp256k1::ecdsa::Signature;
use bitcoin::secp256k1::hashes::sha256;
use bitcoin::secp256k1::{Message, PublicKey, Scalar, Secp256k1, SecretKey};
use rand_core::{OsRng, RngCore};
Expand Down Expand Up @@ -161,23 +160,13 @@ impl LightsparkSigner {
&self,
message: Vec<u8>,
derivation_path: String,
is_raw: bool,
add_tweak: Option<Vec<u8>>,
mul_tweak: Option<Vec<u8>>,
) -> Result<Vec<u8>, Error> {
let secp = Secp256k1::new();
let signing_key = self.derive_and_tweak_key(derivation_path, add_tweak, mul_tweak)?;
let signature: Signature = match is_raw {
true => {
let msg = Message::from_slice(message.as_slice()).map_err(Error::Secp256k1Error)?;
secp.sign_ecdsa(&msg, &signing_key)
}
false => {
let msg = Message::from_hashed_data::<sha256::Hash>(message.as_slice());
secp.sign_ecdsa(&msg, &signing_key)
}
};

let msg = Message::from_slice(message.as_slice()).map_err(Error::Secp256k1Error)?;
let signature = secp.sign_ecdsa(&msg, &signing_key);
Ok(signature.serialize_compact().to_vec())
}

Expand Down Expand Up @@ -342,6 +331,7 @@ impl LightsparkSigner {
#[cfg(test)]
mod tests {
use super::*;
use bitcoin::secp256k1::ecdsa::Signature;
use hex;

#[test]
Expand Down Expand Up @@ -397,8 +387,9 @@ mod tests {
.public_key;

let message = b"Hello, world!";
let hash = sha256::Hash::hash(message);
let signature_bytes = signer
.derive_key_and_sign(message.to_vec(), "m".to_owned(), false, None, None)
.derive_key_and_sign(hash.to_byte_array().to_vec(), "m".to_owned(), None, None)
.unwrap();
let signature = Signature::from_compact(signature_bytes.as_slice()).unwrap();
let msg = Message::from_hashed_data::<sha256::Hash>(message);
Expand Down Expand Up @@ -525,7 +516,7 @@ mod tests {
let signer = LightsparkSigner::new(&seed, Network::Bitcoin).unwrap();

let signature_bytes = signer
.derive_key_and_sign(msg.clone(), "m/3/2106220917/0".to_owned(), true, None, None)
.derive_key_and_sign(msg.clone(), "m/3/2106220917/0".to_owned(), None, None)
.unwrap();
let pubkey = signer
.derive_public_key("m/3/2106220917/0".to_owned())
Expand Down
3 changes: 3 additions & 0 deletions lightspark/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

# v0.7.1
- Add UMA related operations in LightsparkClient.

# v0.7.0
- Refine requester.
- Separate crate into features.
Expand Down
2 changes: 1 addition & 1 deletion lightspark/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "lightspark"
description = "Lightspark Rust SDK"
authors = ["Lightspark Group, Inc. <[email protected]>"]
version = "0.7.0"
version = "0.7.1"
edition = "2021"
documentation = "https://app.lightspark.com/docs/sdk"
homepage = "https://www.lightspark.com/"
Expand Down
4 changes: 2 additions & 2 deletions lightspark/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Lightspark Rust SDK - v0.7.0
# Lightspark Rust SDK - v0.7.1

The Lightspark Rust SDK provides a convenient way to interact with the Lightspark services from applications written in the Rust language.

***WARNING: This SDK is in version 0.7.0 (active development). It means that its APIs may not be fully stable. Please expect that changes to the APIs may happen until we move to v1.0.0.***
***WARNING: This SDK is in version 0.7.1 (active development). It means that its APIs may not be fully stable. Please expect that changes to the APIs may happen until we move to v1.0.0.***

## Documentation

Expand Down
2 changes: 1 addition & 1 deletion lightspark/examples/rk_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ async fn test_payment() {
let invoice = client
.create_test_mode_invoice(&node_id, 10000, Some("test"), None)
.await;
let payment_request = invoice.unwrap().replace("\"", "");
let payment_request = invoice.unwrap().replace('\"', "");
println!("Invoice created: {:?}", payment_request);

let response = client
Expand Down
145 changes: 145 additions & 0 deletions lightspark/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::error::Error;
use crate::key::OperationSigningKey;
use crate::objects::account::Account;
use crate::objects::api_token::ApiToken;
use crate::objects::compliance_provider::ComplianceProvider;
use crate::objects::currency_amount::{self, CurrencyAmount};
use crate::objects::fee_estimate::FeeEstimate;
use crate::objects::incoming_payment::IncomingPayment;
Expand All @@ -23,6 +24,7 @@ use crate::objects::invoice_type::InvoiceType;
use crate::objects::lightning_fee_estimate_output::LightningFeeEstimateOutput;
use crate::objects::outgoing_payment::OutgoingPayment;
use crate::objects::permission::Permission;
use crate::objects::risk_rating::RiskRating;
use crate::objects::withdrawal_mode::WithdrawalMode;
use crate::objects::withdrawal_request::WithdrawalRequest;
use crate::objects::{account, invoice_data};
Expand Down Expand Up @@ -820,4 +822,147 @@ impl<K: OperationSigningKey> LightsparkClient<K> {
.map_err(Error::JsonError)?;
Ok(result)
}

pub async fn create_uma_invoice(
&self,
node_id: &str,
amount_msats: i64,
metadata: &str,
expiry_secs: Option<i32>,
) -> Result<Invoice, Error> {
let mutation = format!(
"mutation CreateUmaInvoice(
$node_id: ID!
$amount_msats: Long!
$metadata_hash: String!
$expiry_secs: Int
) {{
create_uma_invoice(input: {{
node_id: $node_id
amount_msats: $amount_msats
metadata_hash: $metadata_hash
expiry_secs: $expiry_secs
}}) {{
invoice {{
...InvoiceFragment
}}
}}
}}
{}
",
invoice::FRAGMENT
);

let mut hasher = Sha256::new();
hasher.update(metadata.as_bytes());

let metadata_hash = hex::encode(hasher.finalize());

let mut variables: HashMap<&str, Value> = HashMap::new();
variables.insert("node_id", node_id.into());
variables.insert("amount_msats", amount_msats.into());
variables.insert("metadata_hash", metadata_hash.into());
if let Some(expiry_secs) = expiry_secs {
variables.insert("expiry_secs", expiry_secs.into());
}

let value = serde_json::to_value(variables).map_err(Error::ConversionError)?;
let json = self
.requester
.execute_graphql(&mutation, Some(value))
.await?;

let result = serde_json::from_value(json["create_uma_invoice"]["invoice"].clone())
.map_err(Error::JsonError)?;
Ok(result)
}

pub async fn pay_uma_invoice(
&self,
node_id: &str,
encoded_invoice: &str,
timeout_secs: i32,
maximum_fees_msats: i64,
amount_msats: Option<i64>,
) -> Result<OutgoingPayment, Error> {
let operation = format!(
"mutation PayUmaInvoice(
$node_id: ID!
$encoded_invoice: String!
$timeout_secs: Int!
$maximum_fees_msats: Long!
$amount_msats: Long
) {{
pay_uma_invoice(input: {{
node_id: $node_id
encoded_invoice: $encoded_invoice
timeout_secs: $timeout_secs
maximum_fees_msats: $maximum_fees_msats
amount_msats: $amount_msats
}}) {{
payment {{
...OutgoingPaymentFragment
}}
}}
}}
{}
",
outgoing_payment::FRAGMENT
);

let mut variables: HashMap<&str, Value> = HashMap::new();
variables.insert("node_id", node_id.into());
variables.insert("encoded_invoice", encoded_invoice.into());
if let Some(amount_msats) = amount_msats {
variables.insert("amount_msats", amount_msats.into());
}
variables.insert("timeout_secs", timeout_secs.into());
variables.insert("maximum_fees_msats", maximum_fees_msats.into());

let value = serde_json::to_value(variables).map_err(Error::ConversionError)?;

let signing_key = self.get_node_signing_key(node_id)?;
let json = self
.requester
.execute_graphql_signing(&operation, Some(value), Some(signing_key))
.await?;

let result = serde_json::from_value(json["pay_uma_invoice"]["payment"].clone())
.map_err(Error::JsonError)?;
Ok(result)
}

pub async fn screen_node(
&self,
provider: ComplianceProvider,
destination_node_public_key: &str,
) -> Result<RiskRating, Error> {
let operation = "mutation ScreenNode(
$provider: ComplianceProvider!
$node_pubkey: String!
) {
screen_node(input: {
provider: $provider
node_pubkey: $node_pubkey
}) {
rating
}
}";

let mut variables: HashMap<&str, Value> = HashMap::new();
variables.insert("provider", provider.into());
variables.insert("node_pubkey", destination_node_public_key.into());

let value = serde_json::to_value(variables).map_err(Error::ConversionError)?;
let json = self
.requester
.execute_graphql(operation, Some(value))
.await?;

let result = serde_json::from_value(json["screen_node"]["rating"].clone())
.map_err(Error::JsonError)?;
Ok(result)
}
}
2 changes: 1 addition & 1 deletion lightspark/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
//! See more examples in examples/example.rs
//!
/// The version of this library.
pub const VERSION: &str = "0.7.0";
pub const VERSION: &str = "0.7.1";

#[cfg(feature = "client")]
pub mod client;
Expand Down

0 comments on commit cdb8cbb

Please sign in to comment.