From 6bef82c7f49649f6fba82cd32847b88c147a68b9 Mon Sep 17 00:00:00 2001 From: ok300 <106775972+ok300@users.noreply.github.com> Date: Mon, 8 Jul 2024 12:40:13 +0000 Subject: [PATCH] Add dart snippets (#5) * Add dart snippets * Remove listPaymentsFiltered * Target published Dart/Flutter packages on git repository by default * Fix imports * Add BreezLiquidSDK wrapper class to manage wallet instance & SDK streams * Add rxdart * [Dart] Initialize Liquid SDK library * [Dart] Update LNURL snippets * [Dart] Update Fiat Currency snippets * CI: update references to breez-liquid-sdk * Flutter setup instructions: update repo links * Dart snippets: rewrite to match Rust snippets * CI: Update default SDK ref and package version * Address linter issues and run dart format * Add extension on Config * Fix indentation * Fix enum name * Add print statements to remove unused_variable warnings * Remove unused import * CI: Re-add default value for sdk-ref * Dart setup: add hint about initialization approach * Dart setup: update hint with more details * Update link syntax --------- Co-authored-by: Erdem Yerebasmaz --- .github/workflows/main.yml | 18 +- snippets/dart_snippets/.gitignore | 7 + snippets/dart_snippets/README.md | 11 + snippets/dart_snippets/analysis_options.yaml | 30 ++ snippets/dart_snippets/bin/dart_snippets.dart | 6 + snippets/dart_snippets/flake.lock | 61 +++ snippets/dart_snippets/flake.nix | 26 + .../dart_snippets/lib/fiat_currencies.dart | 22 + .../dart_snippets/lib/getting_started.dart | 50 ++ snippets/dart_snippets/lib/list_payments.dart | 9 + snippets/dart_snippets/lib/lnurl_auth.dart | 21 + snippets/dart_snippets/lib/lnurl_pay.dart | 26 + .../dart_snippets/lib/lnurl_withdraw.dart | 23 + snippets/dart_snippets/lib/pay_onchain.dart | 42 ++ .../dart_snippets/lib/receive_onchain.dart | 65 +++ .../dart_snippets/lib/receive_payment.dart | 30 ++ snippets/dart_snippets/lib/sdk_instance.dart | 181 +++++++ snippets/dart_snippets/lib/send_payment.dart | 22 + snippets/dart_snippets/pubspec.lock | 482 ++++++++++++++++++ snippets/dart_snippets/pubspec.yaml | 27 + src/guide/install.md | 8 +- 21 files changed, 1157 insertions(+), 10 deletions(-) create mode 100644 snippets/dart_snippets/.gitignore create mode 100644 snippets/dart_snippets/README.md create mode 100644 snippets/dart_snippets/analysis_options.yaml create mode 100644 snippets/dart_snippets/bin/dart_snippets.dart create mode 100644 snippets/dart_snippets/flake.lock create mode 100644 snippets/dart_snippets/flake.nix create mode 100644 snippets/dart_snippets/lib/fiat_currencies.dart create mode 100644 snippets/dart_snippets/lib/getting_started.dart create mode 100644 snippets/dart_snippets/lib/list_payments.dart create mode 100644 snippets/dart_snippets/lib/lnurl_auth.dart create mode 100644 snippets/dart_snippets/lib/lnurl_pay.dart create mode 100644 snippets/dart_snippets/lib/lnurl_withdraw.dart create mode 100644 snippets/dart_snippets/lib/pay_onchain.dart create mode 100644 snippets/dart_snippets/lib/receive_onchain.dart create mode 100644 snippets/dart_snippets/lib/receive_payment.dart create mode 100644 snippets/dart_snippets/lib/sdk_instance.dart create mode 100644 snippets/dart_snippets/lib/send_payment.dart create mode 100644 snippets/dart_snippets/pubspec.lock create mode 100644 snippets/dart_snippets/pubspec.yaml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7784eafc..e269b624 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,10 +11,10 @@ on: workflow_dispatch: inputs: sdk-ref: - description: 'sdk commit/tag/branch reference. Defaults to main.' + description: 'sdk commit/tag/branch reference. Defaults to 0.1.2-dev4.' required: false type: string - default: main + default: 0.1.2-dev4 concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -25,17 +25,19 @@ jobs: name: setup runs-on: ubuntu-latest outputs: - sdk-ref: ${{ inputs.sdk-ref || '08b2e5a6e2e095a8aaa1cdb7650b3b1b7348dc65' }} - package-version: '0.1.1' + # Used only for Rust snippets + sdk-ref: ${{ inputs.sdk-ref || '0.1.2-dev4' }} + # Used for RN and Flutter snippets + package-version: '0.1.2-dev4' steps: - run: echo "set pre-setup output variables" build-packages: needs: setup name: build packages - uses: breez/breez-sdk/.github/workflows/publish-all-platforms.yml@main + uses: breez/breez-liquid-sdk/.github/workflows/publish-all-platforms.yml@main with: - repository: breez/breez-sdk + repository: breez/breez-liquid-sdk ref: ${{ needs.setup.outputs.sdk-ref }} package-version: ${{ needs.setup.outputs.package-version }} packages-to-publish: '["csharp", "flutter", "golang", "react-native", "python"]' @@ -110,8 +112,8 @@ jobs: - uses: actions/download-artifact@v4 with: - name: breez-sdk-flutter-${{ needs.setup.outputs.package-version }} - path: snippets/dart_snippets/packages/breez-sdk-flutter + name: breez-liquid-sdk-flutter-${{ needs.setup.outputs.package-version }} + path: snippets/dart_snippets/packages/breez-liquid-sdk-flutter - name: pub-get working-directory: snippets/dart_snippets diff --git a/snippets/dart_snippets/.gitignore b/snippets/dart_snippets/.gitignore new file mode 100644 index 00000000..bf02cc3b --- /dev/null +++ b/snippets/dart_snippets/.gitignore @@ -0,0 +1,7 @@ +# https://dart.dev/guides/libraries/private-files +# Created by `dart pub` +.dart_tool/ +packages/ +.flutter-version +.flutter-plugins +.flutter-plugins-dependencies \ No newline at end of file diff --git a/snippets/dart_snippets/README.md b/snippets/dart_snippets/README.md new file mode 100644 index 00000000..6fbbae1a --- /dev/null +++ b/snippets/dart_snippets/README.md @@ -0,0 +1,11 @@ +## Steps to compile the snippets locally +1. Build a flutter package + - By running the publish-all-platforms CI in the breez-liquid-sdk repository (use dummy binaries) + - or by cloning https://github.com/breez/breez-liquid-sdk-flutter +2. Place the files in the folder `snippets/dart-snippets/packages/breez-liquid-sdk-flutter` +3. Happy coding + +To use a local path to the flutter bindings, see the `dependency_overrides` section in `pubspec.yaml`. + +## Nix +Use the command `nix develop` \ No newline at end of file diff --git a/snippets/dart_snippets/analysis_options.yaml b/snippets/dart_snippets/analysis_options.yaml new file mode 100644 index 00000000..6dd972f3 --- /dev/null +++ b/snippets/dart_snippets/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + +include: package:lints/recommended.yaml + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +analyzer: + exclude: + - packages/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/snippets/dart_snippets/bin/dart_snippets.dart b/snippets/dart_snippets/bin/dart_snippets.dart new file mode 100644 index 00000000..589fb4ad --- /dev/null +++ b/snippets/dart_snippets/bin/dart_snippets.dart @@ -0,0 +1,6 @@ +import 'package:flutter_breez_liquid/flutter_breez_liquid.dart' as liquid_sdk; + +void main() async { + // Initialize library + await liquid_sdk.initialize(); +} diff --git a/snippets/dart_snippets/flake.lock b/snippets/dart_snippets/flake.lock new file mode 100644 index 00000000..a068d8e3 --- /dev/null +++ b/snippets/dart_snippets/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1719838683, + "narHash": "sha256-Zw9rQjHz1ilNIimEXFeVa1ERNRBF8DoXDhLAZq5B4pE=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d032c1a6dfad4eedec7e35e91986becc699d7d69", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/snippets/dart_snippets/flake.nix b/snippets/dart_snippets/flake.nix new file mode 100644 index 00000000..3a989cd2 --- /dev/null +++ b/snippets/dart_snippets/flake.nix @@ -0,0 +1,26 @@ +{ + description = "Flutter flake"; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05"; + flake-utils.url = "github:numtide/flake-utils"; + }; + outputs = + { self + , nixpkgs + , flake-utils + , + }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + in + { + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ + flutter + ]; + }; + + formatter = pkgs.nixpkgs-fmt; + }); +} diff --git a/snippets/dart_snippets/lib/fiat_currencies.dart b/snippets/dart_snippets/lib/fiat_currencies.dart new file mode 100644 index 00000000..243bca3e --- /dev/null +++ b/snippets/dart_snippets/lib/fiat_currencies.dart @@ -0,0 +1,22 @@ +import 'package:dart_snippets/sdk_instance.dart'; +import 'package:flutter_breez_liquid/flutter_breez_liquid.dart'; + +Future> listFiatCurrencies() async { + // ANCHOR: list-fiat-currencies + List fiatCurrencyList = await breezLiquidSDK.instance!.listFiatCurrencies(); + // ANCHOR_END: list-fiat-currencies + return fiatCurrencyList; +} + +Future> fetchFiatRates() async { + // ANCHOR: fetch-fiat-rates + final List rates = await breezLiquidSDK.instance!.fetchFiatRates(); + final fiatRatesMap = rates.fold>({}, (map, rate) { + map[rate.coin] = rate; + return map; + }); + // print your desired rate + print(fiatRatesMap["USD"]?.value); + // ANCHOR_END: fetch-fiat-rates + return fiatRatesMap; +} diff --git a/snippets/dart_snippets/lib/getting_started.dart b/snippets/dart_snippets/lib/getting_started.dart new file mode 100644 index 00000000..5d921714 --- /dev/null +++ b/snippets/dart_snippets/lib/getting_started.dart @@ -0,0 +1,50 @@ +import 'package:dart_snippets/sdk_instance.dart'; +import 'package:flutter_breez_liquid/flutter_breez_liquid.dart'; + +Future initializeSDK() async { + // ANCHOR: init-sdk + // It is recommended to use a single instance of BreezSDKLiquid across your Dart/Flutter app. + // + // All of the snippets assume a BreezSDKLiquid object is created on entrypoint of the app as such: + // + // ConnectRequest req = ConnectRequest(...); + // BindingLiquidSdk instance = await connect(req: req); + // + // and is accessible throughout the app. There are various approaches on how to achieve this: + // creating a Singleton class using factory constructor, using state management libraries such as 'provider', 'GetX', + // 'Riverpod' and 'Redux' to name a few. + // + // The Dart snippets included here rely on the example approach seen on sdk_instance.dart to manage wallet connection + // and Liquid SDK streams. This approach also has essential helper methods to ensure wallet data is in sync. + // Please see sdk_instance.dart for more details: + // [sdk_instance.dart](https://github.com/breez/breez-sdk-liquid-docs/blob/main/snippets/dart_snippets/lib/sdk_instance.dart) + + // Create the default config + String mnemonic = ""; + + // Create the default config + Config config = defaultConfig( + network: LiquidNetwork.mainnet, + ); + + // Customize the config object according to your needs + config = config.copyWith(workingDir: "path to an existing directory"); + + ConnectRequest connectRequest = ConnectRequest(mnemonic: mnemonic, config: config); + + await breezLiquidSDK.connect(req: connectRequest); + + // ANCHOR_END: init-sdk +} + +Future fetchBalance(String lspId) async { + // ANCHOR: fetch-balance + GetInfoResponse? nodeState = await breezLiquidSDK.instance!.getInfo(); + BigInt balanceSat = nodeState.balanceSat; + BigInt pendingSendSat = nodeState.pendingSendSat; + BigInt pendingReceiveSat = nodeState.pendingReceiveSat; + // ANCHOR_END: fetch-balance + print(balanceSat); + print(pendingSendSat); + print(pendingReceiveSat); +} diff --git a/snippets/dart_snippets/lib/list_payments.dart b/snippets/dart_snippets/lib/list_payments.dart new file mode 100644 index 00000000..9f2c9b22 --- /dev/null +++ b/snippets/dart_snippets/lib/list_payments.dart @@ -0,0 +1,9 @@ +import 'package:dart_snippets/sdk_instance.dart'; +import 'package:flutter_breez_liquid/flutter_breez_liquid.dart'; + +Future> listPayments() async { + // ANCHOR: list-payments + List paymentsList = await breezLiquidSDK.instance!.listPayments(); + // ANCHOR_END: list-payments + return paymentsList; +} diff --git a/snippets/dart_snippets/lib/lnurl_auth.dart b/snippets/dart_snippets/lib/lnurl_auth.dart new file mode 100644 index 00000000..49cec768 --- /dev/null +++ b/snippets/dart_snippets/lib/lnurl_auth.dart @@ -0,0 +1,21 @@ +import 'package:dart_snippets/sdk_instance.dart'; +import 'package:flutter_breez_liquid/flutter_breez_liquid.dart'; + +Future lnurlAuth() async { + // ANCHOR: lnurl-auth + /// Endpoint can also be of the form: + /// keyauth://domain.com/auth?key=val + String lnurlAuthUrl = + "lnurl1dp68gurn8ghj7mr0vdskc6r0wd6z7mrww4excttvdankjm3lw3skw0tvdankjm3xdvcn6vtp8q6n2dfsx5mrjwtrxdjnqvtzv56rzcnyv3jrxv3sxqmkyenrvv6kve3exv6nqdtyv43nqcmzvdsnvdrzx33rsenxx5unqc3cxgeqgntfgu"; + + InputType inputType = await parse(input: lnurlAuthUrl); + if (inputType is InputType_LnUrlAuth) { + LnUrlCallbackStatus result = await breezLiquidSDK.instance!.lnurlAuth(reqData: inputType.data); + if (result is LnUrlCallbackStatus_Ok) { + print("Successfully authenticated"); + } else { + print("Failed to authenticate"); + } + } + // ANCHOR_END: lnurl-auth +} diff --git a/snippets/dart_snippets/lib/lnurl_pay.dart b/snippets/dart_snippets/lib/lnurl_pay.dart new file mode 100644 index 00000000..0388c81c --- /dev/null +++ b/snippets/dart_snippets/lib/lnurl_pay.dart @@ -0,0 +1,26 @@ +import 'package:dart_snippets/sdk_instance.dart'; +import 'package:flutter_breez_liquid/flutter_breez_liquid.dart'; + +Future lnurlPay() async { + // ANCHOR: lnurl-pay + /// Endpoint can also be of the form: + /// lnurlp://domain.com/lnurl-pay?key=val + /// lnurl1dp68gurn8ghj7mr0vdskc6r0wd6z7mrww4excttsv9un7um9wdekjmmw84jxywf5x43rvv35xgmr2enrxanr2cfcvsmnwe3jxcukvde48qukgdec89snwde3vfjxvepjxpjnjvtpxd3kvdnxx5crxwpjvyunsephsz36jf + String lnurlPayUrl = "lightning@address.com"; + + InputType inputType = await parse(input: lnurlPayUrl); + if (inputType is InputType_LnUrlPay) { + BigInt amountMsat = inputType.data.minSendable; + String optionalComment = ""; + String optionalPaymentLabel = "