From 8ca3af0938837a67b398fa45db4dfb383d82ddf1 Mon Sep 17 00:00:00 2001 From: Ross Savage <551697+dangeross@users.noreply.github.com> Date: Mon, 3 Mar 2025 05:45:10 +0100 Subject: [PATCH] Add signing and verifying message docs (#84) * Add signing and verifying message docs * Apply review feedback --- .github/workflows/main.yml | 5 - snippets/csharp/Messages.cs | 51 ++++++ snippets/dart_snippets/lib/messages.dart | 41 +++++ snippets/go/messages.go | 58 +++++++ .../com/example/kotlinmpplib/Messages.kt | 45 ++++++ snippets/python/src/messages.py | 40 +++++ snippets/react-native/messages.ts | 35 ++++ snippets/rust/src/messages.rs | 42 +++++ snippets/rust/src/pay_onchain.rs | 8 +- .../BreezSDKExamples/Sources/Messages.swift | 38 +++++ src/SUMMARY.md | 15 +- src/guide/messages.md | 149 ++++++++++++++++++ src/notifications/advanced.md | 9 ++ 13 files changed, 520 insertions(+), 16 deletions(-) create mode 100644 snippets/csharp/Messages.cs create mode 100644 snippets/dart_snippets/lib/messages.dart create mode 100644 snippets/go/messages.go create mode 100644 snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/Messages.kt create mode 100644 snippets/python/src/messages.py create mode 100644 snippets/react-native/messages.ts create mode 100644 snippets/rust/src/messages.rs create mode 100644 snippets/swift/BreezSDKExamples/Sources/Messages.swift create mode 100644 src/guide/messages.md create mode 100644 src/notifications/advanced.md diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3f7f48d9..19b41d6b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -114,11 +114,6 @@ jobs: with: dotnet-version: '7.0.x' - - name: Install Mono - run: | - sudo apt-get update - sudo apt-get install -y mono-complete - - name: Setup nuget uses: nuget/setup-nuget@v2 diff --git a/snippets/csharp/Messages.cs b/snippets/csharp/Messages.cs new file mode 100644 index 00000000..6e9dfccb --- /dev/null +++ b/snippets/csharp/Messages.cs @@ -0,0 +1,51 @@ +using Breez.Sdk.Liquid; + +public class MessagesSnippets +{ + public void SignMessage(BindingLiquidSdk sdk) + { + // ANCHOR: sign-message + var message = ""; + try + { + var signMessageRequest = new SignMessageRequest(message); + var signMessageResponse = sdk.SignMessage(signMessageRequest); + + // Get the wallet info for your pubkey + var info = sdk.GetInfo(); + + var signature = signMessageResponse?.signature; + var pubkey = info?.walletInfo?.pubkey; + + Console.WriteLine($"Pubkey: {pubkey}"); + Console.WriteLine($"Signature: {signature}"); + } + catch (Exception) + { + // Handle error + } + // ANCHOR_END: sign-message + } + + public void CheckMessage(BindingLiquidSdk sdk) + { + // ANCHOR: check-message + var message = ""; + var pubkey = ""; + var signature = ""; + try + { + var checkMessageRequest = new CheckMessageRequest(message, pubkey, signature); + var checkMessageResponse = sdk.CheckMessage(checkMessageRequest); + + var isValid = checkMessageResponse?.isValid; + + Console.WriteLine($"Signature valid: {isValid}"); + } + catch (Exception) + { + // Handle error + } + // ANCHOR_END: check-message + } +} diff --git a/snippets/dart_snippets/lib/messages.dart b/snippets/dart_snippets/lib/messages.dart new file mode 100644 index 00000000..b4e85c8b --- /dev/null +++ b/snippets/dart_snippets/lib/messages.dart @@ -0,0 +1,41 @@ +import 'package:dart_snippets/sdk_instance.dart'; +import 'package:flutter_breez_liquid/flutter_breez_liquid.dart'; + +Future signMessage() async { + // ANCHOR: sign-message + SignMessageRequest signMessageRequest = SignMessageRequest( + message: "", + ); + SignMessageResponse signMessageResponse = breezSDKLiquid.instance!.signMessage( + req: signMessageRequest, + ); + + // Get the wallet info for your pubkey + GetInfoResponse? info = await breezSDKLiquid.instance!.getInfo(); + + String signature = signMessageResponse.signature; + String pubkey = info.walletInfo.pubkey; + + print("Pubkey: $pubkey"); + print("Signature: $signature"); + // ANCHOR_END: sign-message + return signMessageResponse; +} + +Future checkMessage() async { + // ANCHOR: check-message + CheckMessageRequest checkMessageRequest = CheckMessageRequest( + message: "", + pubkey: "", + signature: "", + ); + CheckMessageResponse checkMessageResponse = breezSDKLiquid.instance!.checkMessage( + req: checkMessageRequest, + ); + + bool isValid = checkMessageResponse.isValid; + + print("Signature valid: $isValid"); + // ANCHOR_END: check-message + return checkMessageResponse; +} diff --git a/snippets/go/messages.go b/snippets/go/messages.go new file mode 100644 index 00000000..a17ee22a --- /dev/null +++ b/snippets/go/messages.go @@ -0,0 +1,58 @@ +package example + +import ( + "log" + + "github.com/breez/breez-sdk-liquid-go/breez_sdk_liquid" +) + +func SignMessage(sdk *breez_sdk_liquid.BindingLiquidSdk) { + // ANCHOR: sign-message + message := "" + + signMessageRequest := breez_sdk_liquid.SignMessageRequest{ + Message: message, + } + signMessageResponse, err := sdk.SignMessage(signMessageRequest) + if err != nil { + log.Printf("Error: %#v", err) + return + } + + // Get the wallet info for your pubkey + info, err := sdk.GetInfo() + if err != nil { + log.Printf("Error: %#v", err) + return + } + + signature := signMessageResponse.Signature + pubkey := info.WalletInfo.Pubkey + + log.Printf("Pubkey: %v", pubkey) + log.Printf("Signature: %v", signature) + // ANCHOR_END: sign-message +} + +func CheckMessage(sdk *breez_sdk_liquid.BindingLiquidSdk) { + // ANCHOR: check-message + message := "" + pubkey := "" + signature := "" + + checkMessageRequest := breez_sdk_liquid.CheckMessageRequest{ + Message: message, + Pubkey: pubkey, + Signature: signature, + } + checkMessageResponse, err := sdk.CheckMessage(checkMessageRequest) + if err != nil { + log.Printf("Error: %#v", err) + return + } + + isValid := checkMessageResponse.IsValid + + log.Printf("Signature valid: %v", isValid) + // ANCHOR_END: check-message +} diff --git a/snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/Messages.kt b/snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/Messages.kt new file mode 100644 index 00000000..4cb1c73b --- /dev/null +++ b/snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/Messages.kt @@ -0,0 +1,45 @@ +package com.example.kotlinmpplib + +import breez_sdk_liquid.* + +class Messages { + fun signMessage(sdk: BindingLiquidSdk) { + // ANCHOR: sign-message + val message = "" + try { + val signMessageRequest = SignMessageRequest(message) + val signMessageResponse = sdk.signMessage(signMessageRequest) + + // Get the wallet info for your pubkey + val info = sdk.getInfo() + + val signature = signMessageResponse?.signature + val pubkey = info?.walletInfo?.pubkey + + // Log.v("Breez", "Pubkey: ${pubkey}") + // Log.v("Breez", "Signature: ${signature}") + } catch (e: Exception) { + // handle error + } + // ANCHOR_END: sign-message + } + + fun checkMessage(sdk: BindingLiquidSdk) { + // ANCHOR: check-message + val message = "" + val pubkey = "" + val signature = "" + try { + val checkMessageRequest = CheckMessageRequest(message, pubkey, signature) + val checkMessageResponse = sdk.checkMessage(checkMessageRequest) + + val isValid = checkMessageResponse?.isValid + + // Log.v("Breez", "Signature valid: ${isValid}") + } catch (e: Exception) { + // handle error + } + // ANCHOR_END: check-message + } + +} diff --git a/snippets/python/src/messages.py b/snippets/python/src/messages.py new file mode 100644 index 00000000..1eb43f48 --- /dev/null +++ b/snippets/python/src/messages.py @@ -0,0 +1,40 @@ +import logging +from breez_sdk_liquid import BindingLiquidSdk, CheckMessageRequest, SignMessageRequest + + +def sign_message(sdk: BindingLiquidSdk): + # ANCHOR: sign-message + message = "" + try: + sign_message_request = SignMessageRequest(message) + sign_message_response = sdk.sign_message(sign_message_request) + + # Get the wallet info for your pubkey + info = sdk.get_info() + + signature = sign_message_response.signature + pubkey = info.wallet_info.pubkey + + logging.debug(f"Pubkey: {pubkey}") + logging.debug(f"Signature: {signature}") + except Exception as error: + logging.error(error) + raise + # ANCHOR_END: sign-message + +def check_message(sdk: BindingLiquidSdk): + # ANCHOR: check-message + message = "" + pubkey = "" + signature = "" + try: + check_message_request = CheckMessageRequest(message, pubkey, signature) + check_message_response = sdk.check_message(check_message_request) + + is_valid = check_message_response.is_valid + + logging.debug(f"Signature valid: {is_valid}") + except Exception as error: + logging.error(error) + raise + # ANCHOR_END: check-message diff --git a/snippets/react-native/messages.ts b/snippets/react-native/messages.ts new file mode 100644 index 00000000..14e880b8 --- /dev/null +++ b/snippets/react-native/messages.ts @@ -0,0 +1,35 @@ +import { + checkMessage, + getInfo, + signMessage +} from '@breeztech/react-native-breez-sdk-liquid' + +const exampleSignMessage = async () => { + // ANCHOR: sign-message + const signMessageResponse = await signMessage({ + message: '' + }) + + // Get the wallet info for your pubkey + const info = await getInfo() + + const signature = signMessageResponse.signature + const pubkey = info.walletInfo.pubkey + + console.log(`Pubkey: ${pubkey}`) + console.log(`Signature: ${signature}`) + // ANCHOR_END: sign-message +} + +const exampleCheckMessage = async () => { + // ANCHOR: check-message + const checkMessageResponse = await checkMessage({ + message: '', + pubkey: '', + signature: '' + }) + const isValid = checkMessageResponse.isValid + + console.log(`Signature valid: ${isValid}`) + // ANCHOR_END: check-message +} diff --git a/snippets/rust/src/messages.rs b/snippets/rust/src/messages.rs new file mode 100644 index 00000000..01ee49b3 --- /dev/null +++ b/snippets/rust/src/messages.rs @@ -0,0 +1,42 @@ +use std::sync::Arc; + +use anyhow::Result; +use breez_sdk_liquid::prelude::*; +use log::info; + +async fn sign_message(sdk: Arc) -> Result<()> { + // ANCHOR: sign-message + let sign_message_request = SignMessageRequest { + message: "".to_string(), + }; + let sign_message_response = sdk + .sign_message(&sign_message_request)?; + + // Get the wallet info for your pubkey + let info = sdk.get_info().await?; + + let signature = sign_message_response.signature; + let pubkey = info.wallet_info.pubkey; + + info!("Pubkey: {}", pubkey); + info!("Signature: {}", signature); + // ANCHOR_END: sign-message + Ok(()) +} + +fn check_message(sdk: Arc) -> Result<()> { + // ANCHOR: check-message + let check_message_request = CheckMessageRequest { + message: "".to_string(), + pubkey: "".to_string(), + signature: "".to_string(), + }; + let check_message_response = sdk + .check_message(&check_message_request)?; + + let is_valid = check_message_response.is_valid; + + info!("Signature valid: {}", is_valid); + // ANCHOR_END: check-message + Ok(()) +} diff --git a/snippets/rust/src/pay_onchain.rs b/snippets/rust/src/pay_onchain.rs index 3cb8b81d..61b1f731 100644 --- a/snippets/rust/src/pay_onchain.rs +++ b/snippets/rust/src/pay_onchain.rs @@ -19,7 +19,9 @@ async fn prepare_pay_onchain(sdk: Arc) -> Result<()> { // ANCHOR: prepare-pay-onchain let prepare_res = sdk .prepare_pay_onchain(&PreparePayOnchainRequest { - amount: PayAmount::Bitcoin { receiver_amount_sat: 5_000 }, + amount: PayAmount::Bitcoin { + receiver_amount_sat: 5_000, + }, fee_rate_sat_per_vbyte: None, }) .await?; @@ -53,7 +55,9 @@ async fn prepare_pay_onchain_fee_rate(sdk: Arc) -> Result<()> { let prepare_res = sdk .prepare_pay_onchain(&PreparePayOnchainRequest { - amount: PayAmount::Bitcoin { receiver_amount_sat: 5_000 }, + amount: PayAmount::Bitcoin { + receiver_amount_sat: 5_000, + }, fee_rate_sat_per_vbyte: optional_sat_per_vbyte, }) .await?; diff --git a/snippets/swift/BreezSDKExamples/Sources/Messages.swift b/snippets/swift/BreezSDKExamples/Sources/Messages.swift new file mode 100644 index 00000000..fe6044f5 --- /dev/null +++ b/snippets/swift/BreezSDKExamples/Sources/Messages.swift @@ -0,0 +1,38 @@ +import BreezSDKLiquid + +func signMessage(sdk: BindingLiquidSdk) -> SignMessageResponse? { + // ANCHOR: sign-message + let signMessageRequest = SignMessageRequest( + message: "" + ) + let signMessageResponse = try? sdk + .signMessage(req: signMessageRequest) + + // Get the wallet info for your pubkey + let info = try? sdk.getInfo() + + let signature = signMessageResponse!.signature + let pubkey = info!.walletInfo.pubkey + + print("Pubkey: {}", pubkey); + print("Signature: {}", signature); + // ANCHOR_END: sign-message + return signMessageResponse +} + +func checkMessage(sdk: BindingLiquidSdk) -> CheckMessageResponse? { + // ANCHOR: check-message + let checkMessageRequest = CheckMessageRequest( + message: "", + pubkey: "", + signature: "" + ) + let checkMessageResponse = try? sdk + .checkMessage(req: checkMessageRequest) + + let isValid = checkMessageResponse!.isValid + + print("Signature valid: {}", isValid); + // ANCHOR_END: check-message + return checkMessageResponse +} diff --git a/src/SUMMARY.md b/src/SUMMARY.md index b43ec414..b420a63f 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -22,6 +22,7 @@ - [Receiving payments using LNURL-Pay/Lightning address](guide/lnurl_pay_service.md) - [Receiving payments using LNURL-Withdraw](guide/lnurl_withdraw.md) - [Authenticating using LNURL-Auth](guide/lnurl_auth.md) +- [Signing and verifying messages](guide/messages.md) - [Supporting fiat currencies](guide/fiat_currencies.md) - [Buying Bitcoin](guide/buy_btc.md) - [End-user fees](guide/end-user_fees.md) @@ -43,12 +44,8 @@ - [iOS](notifications/ios_setup.md) - [Setting up the notification dervice extension](notifications/ios_service.md) - [Adding the notification plugin](notifications/ios_plugin.md) - ---- - -# Advanced - -- [Adding logging](notifications/logging.md) -- [Changing default strings](notifications/changing_strings.md) -- [Customising push messages](notifications/custom_messages.md) -- [Handling custom notifications](notifications/custom_notifications.md) +- [Advanced](notifications/advanced.md) + - [Adding logging](notifications/logging.md) + - [Changing default strings](notifications/changing_strings.md) + - [Customising push messages](notifications/custom_messages.md) + - [Handling custom notifications](notifications/custom_notifications.md) diff --git a/src/guide/messages.md b/src/guide/messages.md new file mode 100644 index 00000000..904504f0 --- /dev/null +++ b/src/guide/messages.md @@ -0,0 +1,149 @@ +# Signing and verifying messages + +Through signing and verifying messages we can provide proof that a digital signature was created by a private key. + +

+ Signing a message + API docs +

+ +By signing a message using the SDK we can provide a digital signature. Anyone with the `message`, `pubkey` and `signature` can verify the signature was created by the private key of this pubkey. + + +
Rust
+
+ +```rust,ignore +{{#include ../../snippets/rust/src/messages.rs:sign-message}} +``` +
+ +
Swift
+
+ +```swift,ignore +{{#include ../../snippets/swift/BreezSDKExamples/Sources/Messages.swift:sign-message}} +``` +
+ +
Kotlin
+
+ +```kotlin,ignore +{{#include ../../snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/Messages.kt:sign-message}} +``` +
+ +
React Native
+
+ +```typescript +{{#include ../../snippets/react-native/messages.ts:sign-message}} +``` +
+ +
Dart
+
+ +```dart,ignore +{{#include ../../snippets/dart_snippets/lib/messages.dart:sign-message}} +``` +
+ +
Python
+
+ +```python,ignore +{{#include ../../snippets/python/src/messages.py:sign-message}} +``` +
+ +
Go
+
+ +```go,ignore +{{#include ../../snippets/go/messages.go:sign-message}} +``` +
+ +
C#
+
+ +```cs,ignore +{{#include ../../snippets/csharp/Messages.cs:sign-message}} +``` +
+
+ +

+ Verifying a message + API docs +

+ +You can prove control of a private key by verifying a `message` with it's `signature` and `pubkey`. + + +
Rust
+
+ +```rust,ignore +{{#include ../../snippets/rust/src/messages.rs:check-message}} +``` +
+ +
Swift
+
+ +```swift,ignore +{{#include ../../snippets/swift/BreezSDKExamples/Sources/Messages.swift:check-message}} +``` +
+ +
Kotlin
+
+ +```kotlin,ignore +{{#include ../../snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/Messages.kt:check-message}} +``` +
+ +
React Native
+
+ +```typescript +{{#include ../../snippets/react-native/messages.ts:check-message}} +``` +
+ +
Dart
+
+ +```dart,ignore +{{#include ../../snippets/dart_snippets/lib/messages.dart:check-message}} +``` +
+ +
Python
+
+ +```python,ignore +{{#include ../../snippets/python/src/messages.py:check-message}} +``` +
+ +
Go
+
+ +```go,ignore +{{#include ../../snippets/go/messages.go:check-message}} +``` +
+ +
C#
+
+ +```cs,ignore +{{#include ../../snippets/csharp/Messages.cs:check-message}} +``` +
+
\ No newline at end of file diff --git a/src/notifications/advanced.md b/src/notifications/advanced.md new file mode 100644 index 00000000..0ab59612 --- /dev/null +++ b/src/notifications/advanced.md @@ -0,0 +1,9 @@ +# Advanced + +Here are some advanced topics to help extend and customise the Notification Plugin: + +- **[Adding logging](logging.md)** +- **[Changing default strings](changing_strings.md)** +- **[Customising push messages](custom_messages.md)** +- **[Handling custom notifications](custom_notifications.md)** +