diff --git a/contrib/clean-and-gen-bindings.sh b/contrib/clean-and-gen-bindings.sh new file mode 100755 index 0000000..df284a6 --- /dev/null +++ b/contrib/clean-and-gen-bindings.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Delete generated files in lib/src/generated +echo "Deleting generated files in lib/src/generated..." +rm -rf lib/src/generated/* + +# Delete generated files in rust/src/frb_generated +echo "Deleting generated files in rust/src/frb_generated..." +rm -rf rust/src/frb_generated* + +# Clean the Flutter project +echo "Running flutter clean..." +flutter clean + +# Get Flutter dependencies +echo "Running flutter pub get..." +flutter pub get + +# Run make all +echo "Running make all..." +make all + +echo "Script execution completed." \ No newline at end of file diff --git a/example/.gitignore b/example/.gitignore index 29a3a50..b98b79c 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -9,6 +9,7 @@ .history .svn/ migrate_working_dir/ +.vscode/settings.json # IntelliJ related *.iml @@ -27,10 +28,14 @@ migrate_working_dir/ .dart_tool/ .flutter-plugins .flutter-plugins-dependencies +.packages .pub-cache/ .pub/ /build/ +# Web related +lib/generated_plugin_registrant.dart + # Symbolication related app.*.symbols diff --git a/example/.metadata b/example/.metadata new file mode 100644 index 0000000..bbf096b --- /dev/null +++ b/example/.metadata @@ -0,0 +1,33 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 + channel: stable + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 + base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 + - platform: android + create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 + base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 + - platform: ios + create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 + base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/example/README.md b/example/README.md index 1cbe9b3..1df00a3 100644 --- a/example/README.md +++ b/example/README.md @@ -1,6 +1,6 @@ -# payjoin_example +# payjoin_flutter_demo -Demonstrates how to use the payjoin plugin. +A new Flutter project. ## Getting Started @@ -12,5 +12,7 @@ A few resources to get you started if this is your first Flutter project: - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) For help getting started with Flutter development, view the -[online documentation](https://docs.flutter.dev/), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +[online documentation](https://docs.flutter.dev/), which offers tutorials, samples, guidance on +mobile development, and a full API reference. + +# payjoin-flutter-demo diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml index 0d29021..ae08714 100644 --- a/example/analysis_options.yaml +++ b/example/analysis_options.yaml @@ -13,7 +13,8 @@ linter: # The lint rules applied to this project can be customized in the # section below to disable rules from the `package:flutter_lints/flutter.yaml` # included above or to enable additional rules. A list of all available lints - # and their documentation is published at https://dart.dev/lints. + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. # # Instead of disabling a lint rule for the entire project in the # section below, it can also be suppressed for a single line of code @@ -21,8 +22,8 @@ linter: # `// ignore_for_file: name_of_lint` syntax on the line or in the file # producing the lint. rules: - # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 7407a59..d8abf64 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -1,9 +1,3 @@ -plugins { - id "com.android.application" - id "kotlin-android" - id "dev.flutter.flutter-gradle-plugin" -} - def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -12,6 +6,11 @@ if (localPropertiesFile.exists()) { } } +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' @@ -22,8 +21,11 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + android { - namespace "io.f.payjoin.payjoin_example" compileSdkVersion flutter.compileSdkVersion ndkVersion flutter.ndkVersion @@ -42,9 +44,9 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "io.f.payjoin.payjoin_example" + applicationId "com.bdk.f.bdk_flutter_app" // You can update the following values to match your application needs. - // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. minSdkVersion 23 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() @@ -64,4 +66,6 @@ flutter { source '../..' } -dependencies {} +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml index 399f698..20dbe43 100644 --- a/example/android/app/src/debug/AndroidManifest.xml +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -1,7 +1,8 @@ - + - + diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index afb4191..5aec134 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,27 +1,28 @@ - + + + android:icon="@mipmap/ic_launcher" + android:label="bdk_flutter_app"> + android:name="io.flutter.embedding.android.NormalTheme" + android:resource="@style/NormalTheme" /> - - + + + diff --git a/example/android/app/src/main/res/drawable/launch_background.xml b/example/android/app/src/main/res/drawable/launch_background.xml index 304732f..0db4a83 100644 --- a/example/android/app/src/main/res/drawable/launch_background.xml +++ b/example/android/app/src/main/res/drawable/launch_background.xml @@ -1,5 +1,4 @@ - - + diff --git a/example/android/app/src/profile/AndroidManifest.xml b/example/android/app/src/profile/AndroidManifest.xml index 399f698..20dbe43 100644 --- a/example/android/app/src/profile/AndroidManifest.xml +++ b/example/android/app/src/profile/AndroidManifest.xml @@ -1,7 +1,8 @@ - + - + diff --git a/example/android/build.gradle b/example/android/build.gradle index e83fb5d..8b2a770 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,11 +1,12 @@ buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '2.0.0' repositories { google() mavenCentral() } dependencies { + classpath 'com.android.tools.build:gradle:7.1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 598d13f..94adc3a 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -1,3 +1,3 @@ -org.gradle.jvmargs=-Xmx4G +org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 3c472b9..cc5527d 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip diff --git a/example/android/settings.gradle b/example/android/settings.gradle index 7cd7128..44e62bc 100644 --- a/example/android/settings.gradle +++ b/example/android/settings.gradle @@ -1,29 +1,11 @@ -pluginManagement { - def flutterSdkPath = { - def properties = new Properties() - file("local.properties").withInputStream { properties.load(it) } - def flutterSdkPath = properties.getProperty("flutter.sdk") - assert flutterSdkPath != null, "flutter.sdk not set in local.properties" - return flutterSdkPath - } - settings.ext.flutterSdkPath = flutterSdkPath() +include ':app' - includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() - repositories { - google() - mavenCentral() - gradlePluginPortal() - } +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } - plugins { - id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false - } -} - -plugins { - id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "7.3.0" apply false -} - -include ":app" +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/example/assets/pdk_logo.png b/example/assets/pdk_logo.png new file mode 100644 index 0000000..43e4f0f Binary files /dev/null and b/example/assets/pdk_logo.png differ diff --git a/example/cargokit_options.yaml b/example/cargokit_options.yaml deleted file mode 100644 index 01f175a..0000000 --- a/example/cargokit_options.yaml +++ /dev/null @@ -1,2 +0,0 @@ -verbose_logging: false -use_precompiled_binaries: true \ No newline at end of file diff --git a/example/integration_test/bdk_full_cycle_test.dart b/example/integration_test/bdk_full_cycle_test.dart deleted file mode 100644 index 509cc44..0000000 --- a/example/integration_test/bdk_full_cycle_test.dart +++ /dev/null @@ -1,131 +0,0 @@ -import 'dart:convert'; - -import 'package:bdk_flutter/bdk_flutter.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:integration_test/integration_test.dart'; -import 'package:payjoin_flutter/common.dart' as common; -import 'package:payjoin_flutter/receive/v1.dart' as v1; -import 'package:payjoin_flutter/send.dart' as send; -import 'package:payjoin_flutter/uri.dart' as pay_join_uri; -import 'package:payjoin_flutter_example/bdk_client.dart'; -import 'package:payjoin_flutter_example/btc_client.dart'; - -void main() { - IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - - group('v1_to_v1', () { - setUp(() async {}); - testWidgets('full_cycle', (WidgetTester tester) async { - final btcClient = BtcClient("sender"); - await btcClient.loadWallet(); - final sender = BdkClient( - "wpkh(tprv8ZgxMBicQKsPemPN83fE95XY5PRnDJZ6YcTHbFACvme5Rwi2RRoivdksZzrP3M61Vz13pva5LjaY1TA9JezqgzLoaNG5SXpCAcyY5w2ursV)", - Network.regtest); - final receiver = BdkClient( - "wpkh(tprv8ZgxMBicQKsPdD2rdKcJCtGop4vqW3cmvikhzVy42iCev4E9JpeJgnHXdMKLnmAyXatvhXPi8KomgWMa316mwyirBiLXi3MMPhRV1ikfNTJ)", - Network.regtest); - await sender.restoreWallet(); - await receiver.restoreWallet(); - // Receiver creates the payjoin URI - final pjReceiverAddress = receiver.getNewAddress().address; - final pjSenderAddress = sender.getNewAddress().address; - await btcClient.sendToAddress(pjSenderAddress.toString(), 1); - await btcClient.sendToAddress(pjReceiverAddress.toString(), 1); - await btcClient.generate(11, pjSenderAddress.toString()); - await receiver.syncWallet(); - await sender.syncWallet(); - // Sender create a funded PSBT (not broadcast) to address with amount given in the pjUri - debugPrint("Sender Balance: ${sender.getBalance().toString()}"); - final uri = await pay_join_uri.Uri.fromStr( - "${pjReceiverAddress.toQrUri()}?amount=${0.0083285}&pj=https://example.com"); - final address = uri.address(); - int amount = (((uri.amount()) ?? 0) * 100000000).toInt(); - - final senderPsbt = (await sender.createPsbt(address, amount, 2000)); - final senderPsbtBase64 = senderPsbt.toString(); - debugPrint( - "\nOriginal sender psbt: $senderPsbtBase64", - ); - - // Receiver part - final (req, ctx) = await (await (await send.RequestBuilder.fromPsbtAndUri( - psbtBase64: senderPsbtBase64, pjUri: uri.checkPjSupported())) - .buildWithAdditionalFee( - maxFeeContribution: BigInt.from(10000), - minFeeRate: BigInt.zero, - clampFeeContribution: false)) - .extractV1(); - final headers = common.Headers(map: { - 'content-type': 'text/plain', - 'content-length': req.body.length.toString(), - }); - final uncheckedProposal = await v1.UncheckedProposal.fromRequest( - body: req.body.toList(), query: (req.url.query())!, headers: headers); - // in a payment processor where the sender could go offline, this is where you schedule to broadcast the original_tx - var _ = await uncheckedProposal.extractTxToScheduleBroadcast(); - final inputsOwned = await uncheckedProposal.checkBroadcastSuitability( - canBroadcast: (e) async { - return true; - }); - // Receive Check 2: receiver can't sign for proposal inputs - final mixedInputScripts = - await inputsOwned.checkInputsNotOwned(isOwned: (e) async { - return receiver.getAddressInfo(ScriptBuf(bytes: e)); - }); - - // Receive Check 3: receiver can't sign for proposal inputs - final seenInputs = await mixedInputScripts.checkNoMixedInputScripts(); - // Receive Check 4: have we seen this input before? More of a check for non-interactive i.e. payment processor receivers. - final provisionalProposal = - await (await seenInputs.checkNoInputsSeenBefore(isKnown: (e) async { - return false; - })) - .identifyReceiverOutputs(isReceiverOutput: (e) async { - return receiver.getAddressInfo(ScriptBuf(bytes: e)); - }); - final unspent = receiver.listUnspent(); - // Select receiver payjoin inputs. - Map candidateInputs = { - for (var input in unspent) - input.txout.value: common.OutPoint( - txid: input.outpoint.txid.toString(), vout: input.outpoint.vout) - }; - final selectedOutpoint = await provisionalProposal.tryPreservingPrivacy( - candidateInputs: candidateInputs); - var selectedUtxo = unspent.firstWhere( - (i) => - i.outpoint.txid.toString() == selectedOutpoint.txid && - i.outpoint.vout == selectedOutpoint.vout, - orElse: () => throw Exception('UTXO not found')); - var txoToContribute = common.TxOut( - value: selectedUtxo.txout.value, - scriptPubkey: selectedUtxo.txout.scriptPubkey.bytes, - ); - - var outpointToContribute = common.OutPoint( - txid: selectedUtxo.outpoint.txid.toString(), - vout: selectedUtxo.outpoint.vout, - ); - await provisionalProposal.contributeWitnessInput( - txo: txoToContribute, outpoint: outpointToContribute); - - final payJoinProposal = - await provisionalProposal.finalizeProposal(processPsbt: (e) async { - debugPrint("\n Original receiver unsigned psbt: $e"); - return (await receiver - .signPsbt(await PartiallySignedTransaction.fromString(e))) - .toString(); - }); - final receiverPsbt = await payJoinProposal.psbt(); - debugPrint("\n Original receiver psbt: $receiverPsbt"); - final receiverProcessedPsbt = - await ctx.processResponse(response: utf8.encode(receiverPsbt)); - final senderProcessedPsbt = (await sender.signPsbt( - await PartiallySignedTransaction.fromString(receiverProcessedPsbt))); - - final txid = await sender.broadcastPsbt(senderProcessedPsbt); - debugPrint("Broadcast success: $txid"); - }); - }); -} diff --git a/example/integration_test/bitcoin_core_full_cycle_test.dart b/example/integration_test/bitcoin_core_full_cycle_test.dart deleted file mode 100644 index d9a0406..0000000 --- a/example/integration_test/bitcoin_core_full_cycle_test.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'dart:convert'; - -import 'package:bdk_flutter/bdk_flutter.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:integration_test/integration_test.dart'; -import 'package:payjoin_flutter/common.dart' as common; -import 'package:payjoin_flutter/uri.dart' as pay_join_uri; -import 'package:payjoin_flutter_example/btc_client.dart'; -import 'package:payjoin_flutter_example/payjoin_library.dart'; - -void main() { - IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - - group('v1_to_v1', () { - setUp(() async {}); - testWidgets('full_cycle', (WidgetTester tester) async { - final payJoinLib = PayJoinLibrary(); - final sender = BtcClient("receiver"); - final client = BtcClient(""); - final receiver = BtcClient("sender"); - // Receiver creates the payjoin URI - final pjReceiverAddress = await receiver.getNewAddress(); - final pjSenderAddress = await sender.getNewAddress(); - //Generate blocks to receiver and sender - await client.sendToAddress(pjSenderAddress, 10); - await client.sendToAddress(pjReceiverAddress, 1); - await sender.generate(11, pjSenderAddress); - await receiver.generate(1, pjReceiverAddress); - final pjUri = await payJoinLib.buildPjUri(0.0083285, pjReceiverAddress); - // Sender create a funded PSBT (not broadcast) to address with amount given in the pjUri - debugPrint("Sender Balance: ${(await sender.getBalance()).toString()}"); - final uri = await pay_join_uri.Uri.fromStr(pjUri); - final address = uri.address(); - final amount = uri.amount(); - final senderPsbt = - (await sender.walletCreateFundedPsbt(amount, address, 2000))["psbt"]; - debugPrint( - "\nOriginal sender psbt: $senderPsbt", - ); - final (provisionalProposal, ctx) = - await payJoinLib.handlePjRequest(senderPsbt, pjUri, (e) async { - final script = ScriptBuf(bytes: e); - final address = - (await Address.fromScript(script: script, network: Network.regtest)) - .asString(); - return (await receiver.getAddressInfo(address))["ismine"]; - }); - final availableInputs = await receiver.listUnspent([]); - // Select receiver payjoin inputs. - Map candidateInputs = {}; - for (var e in availableInputs) { - var amount = BigInt.from(e["amount"] * 100000000); - candidateInputs[amount] = - common.OutPoint(txid: e["txid"], vout: e["vout"]); - } - final selectedOutpoint = await provisionalProposal.tryPreservingPrivacy( - candidateInputs: candidateInputs); - - final selectedUtxo = availableInputs.firstWhere((e) => - (e["txid"] == selectedOutpoint.txid) && - (e["vout"] == selectedOutpoint.vout)); - final selectedUtxoScriptPubKey = - await ScriptBuf.fromHex(selectedUtxo["scriptPubKey"]); - final selectedUtxoAmount = - BigInt.from(selectedUtxo["amount"] * 100000000); - final txoutToContribute = common.TxOut( - scriptPubkey: selectedUtxoScriptPubKey.bytes, - value: selectedUtxoAmount, - ); - final outputToContribute = common.OutPoint( - txid: selectedUtxo["txid"], vout: selectedUtxo["vout"]); - await provisionalProposal.contributeWitnessInput( - txo: txoutToContribute, outpoint: outputToContribute); - final payJoinProposal = - await provisionalProposal.finalizeProposal(processPsbt: (e) async { - return (await receiver.walletProcessPsbt(e))["psbt"]; - }); - final receiverPsbt = await payJoinProposal.psbt(); - debugPrint("\n Original receiver psbt: $receiverPsbt"); - final receiverProcessedPsbt = - await ctx.processResponse(response: utf8.encode(receiverPsbt)); - final senderProcessedPsbt = - (await sender.walletProcessPsbt(receiverProcessedPsbt))["psbt"]; - final senderFinalizedPsbt = - (await sender.finalizePsbt(senderProcessedPsbt)); - final res = await sender.sendRawTransaction(senderFinalizedPsbt["hex"]); - debugPrint("Broadcast success: $res"); - }); - }); -} diff --git a/example/ios/Podfile b/example/ios/Podfile index 3e44f9c..2c068c4 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '13.0' +platform :ios, '12.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -32,9 +32,6 @@ target 'Runner' do use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) - target 'RunnerTests' do - inherit! :search_paths - end end post_install do |installer| diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 53d24dd..70e7a9a 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -2,39 +2,32 @@ PODS: - bdk_flutter (0.31.2): - Flutter - Flutter (1.0.0) - - integration_test (0.0.1): - - Flutter - - path_provider_foundation (0.0.1): - - Flutter - - FlutterMacOS - payjoin_flutter (0.20.0) + - url_launcher_ios (0.0.1): + - Flutter DEPENDENCIES: - bdk_flutter (from `.symlinks/plugins/bdk_flutter/ios`) - Flutter (from `Flutter`) - - integration_test (from `.symlinks/plugins/integration_test/ios`) - - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - payjoin_flutter (from `.symlinks/plugins/payjoin_flutter/ios`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) EXTERNAL SOURCES: bdk_flutter: :path: ".symlinks/plugins/bdk_flutter/ios" Flutter: :path: Flutter - integration_test: - :path: ".symlinks/plugins/integration_test/ios" - path_provider_foundation: - :path: ".symlinks/plugins/path_provider_foundation/darwin" payjoin_flutter: :path: ".symlinks/plugins/payjoin_flutter/ios" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" SPEC CHECKSUMS: bdk_flutter: fb57a7400a7f3f181c5977bcdc2a5ef347ae4e7f Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4 - path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 payjoin_flutter: 6397d7b698cdad6453be4949ab6aca1863f6c5e5 + url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe -PODFILE CHECKSUM: a57f30d18f102dd3ce366b1d62a55ecbef2158e5 +PODFILE CHECKSUM: 4e8f8b2be68aeea4c0d5beb6ff1e79fface1d048 COCOAPODS: 1.15.2 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index cd39452..6037e13 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -7,27 +7,15 @@ objects = { /* Begin PBXBuildFile section */ - 0B7724A19811C3537C6551DD /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AA90EFB70C05CBF4DC4253D /* Pods_RunnerTests.framework */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 32F26491FD7FC39895395889 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B2E59BEA4BF034E53714D59 /* Pods_Runner.framework */; }; - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 67E8DEAAA97EBDCF33906F8C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 71C8A080783F20AB4638E0DD /* Pods_Runner.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ -/* Begin PBXContainerItemProxy section */ - 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 97C146E61CF9000F007C117D /* Project object */; - proxyType = 1; - remoteGlobalIDString = 97C146ED1CF9000F007C117D; - remoteInfo = Runner; - }; -/* End PBXContainerItemProxy section */ - /* Begin PBXCopyFilesBuildPhase section */ 9705A1C41CF9048500538489 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; @@ -42,22 +30,14 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 02DBE28BC41A8AD830D38853 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; - 0AA90EFB70C05CBF4DC4253D /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; - 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3CB6680DB9FF3C385886CAE4 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - 4A92EAFE33F4FB4E395A3D05 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; - 59E2FEABC3EECFE3ED40B68C /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 6B2E59BEA4BF034E53714D59 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 71C8A080783F20AB4638E0DD /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 768068DA3BD988AD0A63B0BF /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 794B5B9D3B473B3CAE5ED526 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 8DA5CA6D073802017968271F /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -65,59 +45,30 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A2BB0CFD7FBA59C5B5E8CDDD /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + A34B7D78C27A1FAE83BD3010 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 086409089849FCA317BBAFE0 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 0B7724A19811C3537C6551DD /* Pods_RunnerTests.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 32F26491FD7FC39895395889 /* Pods_Runner.framework in Frameworks */, + 67E8DEAAA97EBDCF33906F8C /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 331C8082294A63A400263BE5 /* RunnerTests */ = { + 469380F9773AA7CC2A5F83BA /* Frameworks */ = { isa = PBXGroup; children = ( - 331C807B294A618700263BE5 /* RunnerTests.swift */, - ); - path = RunnerTests; - sourceTree = ""; - }; - 725C8D40F8382BEEBA6C43CF /* Frameworks */ = { - isa = PBXGroup; - children = ( - 6B2E59BEA4BF034E53714D59 /* Pods_Runner.framework */, - 0AA90EFB70C05CBF4DC4253D /* Pods_RunnerTests.framework */, + 71C8A080783F20AB4638E0DD /* Pods_Runner.framework */, ); name = Frameworks; sourceTree = ""; }; - 7D11CAF4462D5901360C006B /* Pods */ = { - isa = PBXGroup; - children = ( - 59E2FEABC3EECFE3ED40B68C /* Pods-Runner.debug.xcconfig */, - 768068DA3BD988AD0A63B0BF /* Pods-Runner.release.xcconfig */, - 3CB6680DB9FF3C385886CAE4 /* Pods-Runner.profile.xcconfig */, - 02DBE28BC41A8AD830D38853 /* Pods-RunnerTests.debug.xcconfig */, - 4A92EAFE33F4FB4E395A3D05 /* Pods-RunnerTests.release.xcconfig */, - 8DA5CA6D073802017968271F /* Pods-RunnerTests.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -135,9 +86,8 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, - 331C8082294A63A400263BE5 /* RunnerTests */, - 7D11CAF4462D5901360C006B /* Pods */, - 725C8D40F8382BEEBA6C43CF /* Frameworks */, + E56AB0CE13A8D55B7633A3E8 /* Pods */, + 469380F9773AA7CC2A5F83BA /* Frameworks */, ); sourceTree = ""; }; @@ -145,7 +95,6 @@ isa = PBXGroup; children = ( 97C146EE1CF9000F007C117D /* Runner.app */, - 331C8081294A63A400263BE5 /* RunnerTests.xctest */, ); name = Products; sourceTree = ""; @@ -165,40 +114,31 @@ path = Runner; sourceTree = ""; }; + E56AB0CE13A8D55B7633A3E8 /* Pods */ = { + isa = PBXGroup; + children = ( + 794B5B9D3B473B3CAE5ED526 /* Pods-Runner.debug.xcconfig */, + A34B7D78C27A1FAE83BD3010 /* Pods-Runner.release.xcconfig */, + A2BB0CFD7FBA59C5B5E8CDDD /* Pods-Runner.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 331C8080294A63A400263BE5 /* RunnerTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; - buildPhases = ( - A07273C1F654F2C6610828C8 /* [CP] Check Pods Manifest.lock */, - 331C807D294A63A400263BE5 /* Sources */, - 331C807F294A63A400263BE5 /* Resources */, - 086409089849FCA317BBAFE0 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 331C8086294A63A400263BE5 /* PBXTargetDependency */, - ); - name = RunnerTests; - productName = RunnerTests; - productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; 97C146ED1CF9000F007C117D /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - 56BBD6330CBEFF144654628E /* [CP] Check Pods Manifest.lock */, + 13F610236E8F725E5129825C /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - BD40211822B1E9A61F99F669 /* [CP] Embed Pods Frameworks */, + 9DD3113125E020DC4E0AC81E /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -215,14 +155,9 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - BuildIndependentTargetsInParallel = YES; LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { - 331C8080294A63A400263BE5 = { - CreatedOnToolsVersion = 14.0; - TestTargetID = 97C146ED1CF9000F007C117D; - }; 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; LastSwiftMigration = 1100; @@ -243,19 +178,11 @@ projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, - 331C8080294A63A400263BE5 /* RunnerTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 331C807F294A63A400263BE5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 97C146EC1CF9000F007C117D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -270,23 +197,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; - }; - 56BBD6330CBEFF144654628E /* [CP] Check Pods Manifest.lock */ = { + 13F610236E8F725E5129825C /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -308,44 +219,38 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 9740EEB61CF901F6004384FC /* Run Script */ = { + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); - name = "Run Script"; + name = "Thin Binary"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - A07273C1F654F2C6610828C8 /* [CP] Check Pods Manifest.lock */ = { + 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( ); + name = "Run Script"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - BD40211822B1E9A61F99F669 /* [CP] Embed Pods Frameworks */ = { + 9DD3113125E020DC4E0AC81E /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -365,14 +270,6 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 331C807D294A63A400263BE5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 97C146EA1CF9000F007C117D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -384,14 +281,6 @@ }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXTargetDependency section */ - 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 97C146ED1CF9000F007C117D /* Runner */; - targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - /* Begin PBXVariantGroup section */ 97C146FA1CF9000F007C117D /* Main.storyboard */ = { isa = PBXVariantGroup; @@ -435,6 +324,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -469,14 +359,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 3HTGYB84TJ; + DEVELOPMENT_TEAM = 6477GJYWXR; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = io.f.payjoin.payjoinExample; + PRODUCT_BUNDLE_IDENTIFIER = com.bdk.f.bdkFlutterApp; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -484,56 +374,6 @@ }; name = Profile; }; - 331C8088294A63A400263BE5 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 02DBE28BC41A8AD830D38853 /* Pods-RunnerTests.debug.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = io.f.payjoin.payjoinExample.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Debug; - }; - 331C8089294A63A400263BE5 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4A92EAFE33F4FB4E395A3D05 /* Pods-RunnerTests.release.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = io.f.payjoin.payjoinExample.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Release; - }; - 331C808A294A63A400263BE5 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8DA5CA6D073802017968271F /* Pods-RunnerTests.profile.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = io.f.payjoin.payjoinExample.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Profile; - }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -557,6 +397,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -612,6 +453,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -648,14 +490,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 3HTGYB84TJ; + DEVELOPMENT_TEAM = 6477GJYWXR; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = io.f.payjoin.payjoinExample; + PRODUCT_BUNDLE_IDENTIFIER = com.bdk.f.bdkFlutterApp; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -671,14 +513,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 3HTGYB84TJ; + DEVELOPMENT_TEAM = 6477GJYWXR; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = io.f.payjoin.payjoinExample; + PRODUCT_BUNDLE_IDENTIFIER = com.bdk.f.bdkFlutterApp; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -689,16 +531,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 331C8088294A63A400263BE5 /* Debug */, - 331C8089294A63A400263BE5 /* Release */, - 331C808A294A63A400263BE5 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 8e3ca5d..5e31d3d 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -37,17 +37,6 @@ - - - - CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Payjoin + Bdk Flutter App CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -13,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - payjoin_example + bdk_flutter_app CFBundlePackageType APPL CFBundleShortVersionString @@ -41,6 +41,8 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + UIViewControllerBasedStatusBarAppearance + CADisableMinimumFrameDurationOnPhone UIApplicationSupportsIndirectInputEvents diff --git a/example/ios/RunnerTests/RunnerTests.swift b/example/ios/RunnerTests/RunnerTests.swift deleted file mode 100644 index 86a7c3b..0000000 --- a/example/ios/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Flutter -import UIKit -import XCTest - -class RunnerTests: XCTestCase { - - func testExample() { - // If you add code to the Runner application, consider adding tests here. - // See https://developer.apple.com/documentation/xctest for more information about using XCTest. - } - -} diff --git a/example/lib/bdk_client.dart b/example/lib/bdk_client.dart deleted file mode 100644 index e840164..0000000 --- a/example/lib/bdk_client.dart +++ /dev/null @@ -1,112 +0,0 @@ -import 'package:bdk_flutter/bdk_flutter.dart'; -import 'package:flutter/cupertino.dart'; - -class BdkClient { - // Bitcoin core credentials - // String localEsploraUrl = 'http://0.0.0.0:30000'; - - late Wallet wallet; - late Blockchain blockchain; - final String descriptor; - final Network network; - - BdkClient(this.descriptor, this.network); - - Future restoreWallet() async { - try { - await initBlockchain(); - wallet = await Wallet.create( - descriptor: - await Descriptor.create(descriptor: descriptor, network: network), - network: network, - databaseConfig: const DatabaseConfig.memory()); - debugPrint(getNewAddress().address.toString()); - } on Exception { - rethrow; - } - } - - Future initBlockchain() async { - // String esploraUrl = - // Platform.isAndroid ? 'http://10.0.2.2:30000' : localEsploraUrl; - try { - blockchain = await Blockchain.create( - config: BlockchainConfig.esplora( - config: EsploraConfig( - baseUrl: "https://mutinynet.com/api", - stopGap: BigInt.from(144)))); - } on Exception { - rethrow; - } - } - - AddressInfo getNewAddress() { - final res = wallet.getAddress(addressIndex: const AddressIndex.increase()); - return res; - } - - List listTransactions() { - final res = wallet.listTransactions(includeRaw: true); - return res; - } - - Future signPsbt( - PartiallySignedTransaction psbt) async { - await wallet.sign( - psbt: psbt, - signOptions: const SignOptions( - trustWitnessUtxo: true, - allowAllSighashes: false, - removePartialSigs: true, - tryFinalize: true, - signWithTapInternalKey: true, - allowGrinding: false)); - return psbt; - } - - Future createPsbt( - String addressStr, int amount, int fee) async { - try { - final txBuilder = TxBuilder(); - final address = await Address.fromString(s: addressStr, network: network); - final script = address.scriptPubkey(); - final (psbt, _) = await txBuilder - .addRecipient(script, BigInt.from(amount)) - .feeAbsolute(BigInt.from(fee)) - .finish(wallet); - return signPsbt(psbt); - } on Exception { - rethrow; - } - } - - int getBalance() { - final balance = wallet.getBalance(); - final res = "Total Balance: ${balance.total.toString()}"; - debugPrint(res); - return balance.total.toInt(); - } - - Future broadcastPsbt(PartiallySignedTransaction psbt) async { - try { - final tx = psbt.extractTx(); - final txid = await blockchain.broadcast(transaction: tx); - return txid; - } on Exception { - rethrow; - } - } - - bool getAddressInfo(ScriptBuf script) { - final res = wallet.isMine(script: script); - return res; - } - - Future syncWallet() async { - wallet.sync(blockchain: blockchain); - } - - List listUnspent() { - return wallet.listUnspent(); - } -} diff --git a/example/lib/btc_client.dart b/example/lib/btc_client.dart deleted file mode 100644 index c949e90..0000000 --- a/example/lib/btc_client.dart +++ /dev/null @@ -1,213 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:dio/dio.dart'; -import 'package:flutter/cupertino.dart'; - -class BtcClient { - // Bitcoin core credentials - String rpcUser = "admin1"; - String rpcPassword = "123"; - int rpcPort = 18443; - - Dio? _dioClient; - late Map _headers; - late String _url; - final String wallet; - - String getConnectionString(String host, int port, String wallet) { - return 'http://$host:$port/wallet/$wallet'; - } - - BtcClient(this.wallet) { - _headers = { - 'Content-Type': 'application/json', - 'authorization': - 'Basic ${base64.encode(utf8.encode("$rpcUser:$rpcPassword"))}' - }; - _url = getConnectionString( - Platform.isAndroid ? "10.0.2.2" : "0.0.0.0", rpcPort, wallet); - _dioClient = Dio(); - } - - Future loadWallet() async { - try { - var params = [wallet]; - await call("loadwallet", params); - } on Exception catch (e) { - if (e.toString().contains("-4")) { - debugPrint(" $wallet already loaded!"); - } else if (e.toString().contains("-18")) { - debugPrint("$wallet doesn't exist!"); - var params = [wallet]; - await call("createwallet", params); - } - } - } - - Future testMemPoolAccept(String rawtx) async { - var params = [ - [rawtx] - ]; - final res = await call("testmempoolaccept", params); - return res; - } - - Future getNewAddress() async { - var params = []; - final res = await call("getnewaddress", params); - return res; - } - - Future> generate(int nblocks, String address) async { - var params = [ - nblocks, - address, - ]; - final res = await call("generatetoaddress", params); - return res; - } - - Future getBalance() async { - var params = []; - final res = await call("getbalance", params); - return res; - } - - Future> getAddressInfo(String address) async { - var params = [address]; - final res = await call("getaddressinfo", params); - return res; - } - - Future sendRawTransaction(String psbt) async { - var params = [psbt]; - final res = await call("sendrawtransaction", params); - return res; - } - - Future sendToAddress(String address, int amount) async { - var params = [address, amount]; - final res = await call("sendtoaddress", params); - return res; - } - - Future> walletProcessPsbt(String psbt) async { - var params = [psbt, true, "ALL", false]; - final res = await call("walletprocesspsbt", params); - return res as Map; - } - - Future> finalizePsbt(String psbt) async { - var params = [psbt, true]; - final res = await call("finalizepsbt", params); - return res as Map; - } - - Future> listUnspent(List addresses) async { - var params = [ - 1, - 9999999, - addresses, - ]; - final res = await call("listunspent", params); - if (res == []) { - return res; - } else { - return res; - } - } - - Future> walletCreateFundedPsbt( - amount, - address, - int feeRate, - ) async { - var params = [ - [], - [ - {address: amount} - ], - 0, - {"lockUnspents": false, "fee_rate": feeRate} - ]; - final res = await call("walletcreatefundedpsbt", params); - return res as Map; - } - - Future call(var methodName, [var params]) async { - var body = { - 'jsonrpc': '2.0', - 'method': methodName, - 'params': params ?? [], - 'id': '1' - }; - - try { - var response = await _dioClient!.post( - _url, - data: body, - options: Options( - headers: _headers, - ), - ); - if (response.statusCode == HttpStatus.ok) { - var body = response.data as Map; - if (body.containsKey('error') && body["error"] != null) { - var error = body['error']; - - if (error["message"] is Map) { - error = error['message']; - } - - throw Exception( - "errorCode: ${error['code']},errorMsg: ${error['message']}", - ); - } - return body['result']; - } - } on DioException catch (e) { - if (e.type == DioExceptionType.badResponse) { - var errorResponseBody = e.response!.data; - - switch (e.response!.statusCode) { - case 401: - throw Exception( - " code: 401, message: Unauthorized", - ); - case 403: - throw Exception( - "code: 403,message: Forbidden", - ); - case 404: - if (errorResponseBody['error'] != null) { - var error = errorResponseBody['error']; - throw Exception( - "errorCode: ${error['code']},errorMsg: ${error['message']}", - ); - } - throw Exception( - "code: 500, message: Internal Server Error", - ); - default: - if (errorResponseBody['error'] != null) { - var error = errorResponseBody['error']; - throw Exception( - "errorCode: ${error['code']},errorMsg: ${error['message']}", - ); - } - throw Exception( - "code: 500, message: 'Internal Server Error'", - ); - } - } else if (e.type == DioExceptionType.connectionError) { - throw Exception( - "code: 500,message: e.message ?? 'Connection Error'", - ); - } - throw Exception( - "code: 500, message: e.message ?? 'Unknown Error'", - ); - } - } -} diff --git a/example/lib/main.dart b/example/lib/main.dart index dc2f45f..96d8108 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,244 +1,22 @@ -import 'dart:convert'; - -import 'package:bdk_flutter/bdk_flutter.dart'; +import 'package:bdk_flutter_demo/screens/home.dart'; +import 'package:bdk_flutter_demo/styles/theme.dart'; import 'package:flutter/material.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:payjoin_flutter/common.dart' as common; -import 'package:payjoin_flutter/uri.dart' as pay_join_uri; -import 'package:payjoin_flutter_example/bdk_client.dart'; -import 'package:payjoin_flutter_example/payjoin_library.dart'; -void main() async { +void main() { runApp(const MyApp()); } -class MyApp extends StatefulWidget { - const MyApp({super.key}); - - @override - State createState() => _MyAppState(); -} - -class _MyAppState extends State { - @override - void initState() { - super.initState(); - } +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + // This widget is the root of your application. @override Widget build(BuildContext context) { - return const MaterialApp( - debugShowCheckedModeBanner: false, home: PayJoin()); - } -} - -class PayJoin extends StatefulWidget { - const PayJoin({super.key}); - - @override - State createState() => _PayJoinState(); -} - -class _PayJoinState extends State { - static const primaryColor = 0xffC71585; - PayJoinLibrary payJoinLibrary = PayJoinLibrary(); - final sender = BdkClient( - "wpkh(tprv8ZgxMBicQKsPdgsqhkRVYkBBULxG3HvyXtwhWKEgfH4bsU8bmaqhdbZvxq4Z7BLFtUrT58ynRDrBcfG3vNpNHsKTV5xCEgRoKaNNzcVW3HW/84'/1'/0'/0/*)#ln3hfgcf", - Network.signet); - final receiver = BdkClient( - "wpkh(tprv8ZgxMBicQKsPfKJjrApLfm2BhWhV1JpL3StS8UPagm91Y215JGZktQKTtvErD92RKxEDYD9Sfc9eGZVkuH94NgEHPhz7rpgzhiNm2UPs1G1/84'/1'/0'/0/*)#h8uywf09", - Network.signet); - - String displayText = ""; - String pjUri = ""; - late PartiallySignedTransaction senderPsbt; - late PartiallySignedTransaction processedAndFinalizedPsbt; - @override - void initState() { - sender.restoreWallet(); - receiver.restoreWallet(); - setState(() { - displayText = "sender & receiver restored"; - }); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - backgroundColor: const Color(primaryColor), - elevation: 0, - centerTitle: false, - title: Text('PayJoin App', - style: GoogleFonts.ibmPlexMono( - fontWeight: FontWeight.w900, - fontSize: 18, - color: Colors.white)), // Set this heigh - ), - body: SingleChildScrollView( - child: Column( - children: [ - Container( - margin: const EdgeInsets.only(bottom: 50), - padding: const EdgeInsets.only(left: 15, right: 15, bottom: 20), - color: const Color(primaryColor), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text("Response: ", - textAlign: TextAlign.center, - style: GoogleFonts.manrope( - color: Colors.white, - fontSize: 12, - fontWeight: FontWeight.w700)), - Expanded( - child: SelectableText( - displayText, - maxLines: 3, - textAlign: TextAlign.start, - style: GoogleFonts.ibmPlexMono( - color: Colors.white, - fontSize: 12, - fontWeight: FontWeight.w700), - ), - ), - ], - ), - ), - TextButton( - onPressed: () async { - await sender.syncWallet(); - await receiver.syncWallet(); - setState(() { - displayText = "sync complete"; - }); - debugPrint( - "sender balance: ${(sender.getBalance()).toString()}"); - }, - child: Text( - "Sync wallets", - style: GoogleFonts.manrope( - color: Colors.black, - fontSize: 14, - fontWeight: FontWeight.w800), - )), - TextButton( - onPressed: () async { - final address = (receiver.getNewAddress()).address; - final res = await payJoinLibrary.buildPjUri( - 0.0083285, address.toQrUri()); - setState(() { - pjUri = res; - displayText = res; - }); - }, - child: Text( - "Build Receiver pj Uri", - style: GoogleFonts.manrope( - color: Colors.black, - fontSize: 14, - fontWeight: FontWeight.w800), - )), - TextButton( - onPressed: () async { - final balance = sender.getBalance(); - debugPrint("Sender Balance: ${balance.toString()}"); - final uri = await pay_join_uri.Uri.fromStr(pjUri); - final address = uri.address(); - int amount = (((uri.amount()) ?? 0) * 100000000).toInt(); - final psbt = (await sender.createPsbt(address, amount, 2000)); - debugPrint( - "\nOriginal sender psbt: ${psbt.toString()}", - ); - setState(() { - senderPsbt = psbt; - }); - }, - child: Text( - "Create Sender psbt using receiver pjUri", - style: GoogleFonts.manrope( - color: Colors.black, - fontSize: 14, - fontWeight: FontWeight.w800), - )), - TextButton( - onPressed: () async { - final (provisionalProposal, contextV1) = await payJoinLibrary - .handlePjRequest(senderPsbt.toString(), pjUri, (e) async { - final script = ScriptBuf(bytes: e); - - return (receiver.getAddressInfo(script)); - }); - final unspent = receiver.listUnspent(); - // Select receiver payjoin inputs. - Map candidateInputs = { - for (var input in unspent) - input.txout.value: common.OutPoint( - txid: input.outpoint.txid.toString(), - vout: input.outpoint.vout) - }; - final selectedOutpoint = await provisionalProposal - .tryPreservingPrivacy(candidateInputs: candidateInputs); - var selectedUtxo = unspent.firstWhere( - (i) => - i.outpoint.txid.toString() == selectedOutpoint.txid && - i.outpoint.vout == selectedOutpoint.vout, - orElse: () => throw Exception('UTXO not found')); - var txoToContribute = common.TxOut( - value: selectedUtxo.txout.value, - scriptPubkey: selectedUtxo.txout.scriptPubkey.bytes, - ); - - var outpointToContribute = common.OutPoint( - txid: selectedUtxo.outpoint.txid.toString(), - vout: selectedUtxo.outpoint.vout, - ); - - await provisionalProposal.contributeWitnessInput( - txo: txoToContribute, outpoint: outpointToContribute); - final payJoinProposal = await provisionalProposal - .finalizeProposal(processPsbt: (e) async { - debugPrint("\n Original receiver unsigned psbt: $e"); - return (await receiver.signPsbt( - await PartiallySignedTransaction.fromString(e))) - .toString(); - }); - final receiverPsbt = await payJoinProposal.psbt(); - debugPrint("\n Original receiver psbt: $receiverPsbt"); - final receiverProcessedPsbt = await contextV1.processResponse( - response: utf8.encode(receiverPsbt)); - final senderProcessedPsbt = (await sender.signPsbt( - await PartiallySignedTransaction.fromString( - receiverProcessedPsbt))); - setState(() { - processedAndFinalizedPsbt = senderProcessedPsbt; - }); - }, - child: Text( - "Process and finalize receiver Pj request", - style: GoogleFonts.manrope( - color: Colors.black, - fontSize: 14, - fontWeight: FontWeight.w800), - )), - TextButton( - onPressed: () async { - final res = - await sender.broadcastPsbt(processedAndFinalizedPsbt); - debugPrint("Broadcast success: $res"); - }, - child: Text( - "Broadcast processed psbt", - style: GoogleFonts.manrope( - color: Colors.black, - fontSize: 14, - fontWeight: FontWeight.w800), - )) - ], - ), - ), + return MaterialApp( + debugShowCheckedModeBanner: false, + title: 'Payjoin Flutter Demo', + theme: theme(), + home: const Home(), ); } } diff --git a/example/lib/managers/payjoin_manager.dart b/example/lib/managers/payjoin_manager.dart new file mode 100644 index 0000000..ac08c4f --- /dev/null +++ b/example/lib/managers/payjoin_manager.dart @@ -0,0 +1,369 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:bdk_flutter/bdk_flutter.dart' as bdk; +import 'package:flutter/widgets.dart'; +import 'package:http/http.dart' as http; +import 'package:payjoin_flutter/receive.dart' as receive; +// ignore: implementation_imports +import 'package:payjoin_flutter/src/generated/utils/types.dart' as types; +import 'package:payjoin_flutter/common.dart'; +import 'package:payjoin_flutter/uri.dart' as pj_uri; +import 'package:payjoin_flutter/send.dart' as send; + +class PayjoinManager { + static const pjUrl = "https://localhost:8088"; + static const ohttpRelay = "https://pj.bobspacebkk.com"; + static const payjoinDirectory = "https://payjo.in"; + static const v1ContentType = "text/plain"; + static const v2ContentType = "message/ohttp-req"; + + Future buildV1PjStr( + int amount, + String address, { + String? pj, + }) async { + try { + final pjUri = + "bitcoin:$address?amount=${amount / 100000000}&pj=${pj ?? pjUrl}"; + debugPrint("pjUri: : $pjUri"); + return pjUri; + } catch (e) { + debugPrint(e.toString()); + rethrow; + } + } + + Future<(String, receive.Receiver)> buildV2PjStr({ + int? amount, + required String address, + required Network network, + required int expireAfter, + }) async { + final session = await startV2ReceiveSession( + address: address, + network: network, + expireAfter: expireAfter, + ); + String pjUriStr; + final pjUriBuilder = session.pjUriBuilder(); + if (amount != null) { + final pjUriBuilderWithAmount = + pjUriBuilder.amountSats(amount: BigInt.from(amount)); + final pjUri = pjUriBuilderWithAmount.build(); + pjUriStr = pjUri.asString(); + } else { + final pjUri = pjUriBuilder.build(); + pjUriStr = pjUri.asString(); + } + + return (pjUriStr, session); + } + + Future stringToUri(String pj) async { + try { + return await pj_uri.Uri.fromStr(pj); + } catch (e) { + debugPrint(e.toString()); + rethrow; + } + } + + Future buildOriginalPsbt( + bdk.Wallet senderWallet, + pj_uri.Uri pjUri, + int fee, + ) async { + final txBuilder = bdk.TxBuilder(); + final address = await bdk.Address.fromString( + s: pjUri.address(), network: bdk.Network.signet); + final script = address.scriptPubkey(); + BigInt uriAmount = pjUri.amountSats() ?? BigInt.zero; + final (psbt, _) = await txBuilder + .addRecipient(script, uriAmount) + .feeAbsolute(BigInt.from(fee)) + .finish(senderWallet); + await senderWallet.sign( + psbt: psbt, + signOptions: const bdk.SignOptions( + trustWitnessUtxo: true, + allowAllSighashes: false, + removePartialSigs: true, + tryFinalize: true, + signWithTapInternalKey: true, + allowGrinding: false, + ), + ); + + final psbtBase64 = psbt.asString(); + debugPrint('Original Sender Psbt for request: $psbtBase64'); + return psbtBase64; + } + + Future buildPayjoinRequest( + String originalPsbt, + pj_uri.Uri pjUri, + int fee, + ) async { + final senderBuilder = await send.SenderBuilder.fromPsbtAndUri( + psbtBase64: originalPsbt, pjUri: pjUri.checkPjSupported()); + final sender = + await senderBuilder.buildRecommended(minFeeRate: BigInt.from(250)); + + return sender; + } + + Future requestAndPollV2Proposal( + send.Sender sender, + ) async { + debugPrint('Sending V2 Proposal Request...'); + try { + // Extract the request and context once + final (request, postCtx) = await sender.extractV2( + ohttpProxyUrl: await pj_uri.Url.fromStr(ohttpRelay), + ); + + // Post the request to the server + final response = await http.post( + Uri.parse(request.url.asString()), + headers: { + 'Content-Type': v2ContentType, + }, + body: request.body, + ); + + // Process the server response to get the context + final getCtx = + await postCtx.processResponse(response: response.bodyBytes); + + // Loop to extract (request, ctx) from get_ctx + while (true) { + debugPrint('Polling for V2 Proposal...'); + try { + final (getReq, ohttpCtx) = await getCtx.extractReq( + ohttpRelay: await pj_uri.Url.fromStr(ohttpRelay), + ); + + // Post the loop request to the server + final loopResponse = await http.post( + Uri.parse(getReq.url.asString()), + headers: { + 'Content-Type': v2ContentType, + }, + body: getReq.body, + ); + + // Process the loop response + final proposal = await getCtx.processResponse( + response: loopResponse.bodyBytes, ohttpCtx: ohttpCtx); + + // If a valid proposal is received, return it + if (proposal != null) { + debugPrint('Received V2 proposal: $proposal'); + return proposal; + } + + debugPrint('No valid proposal received, retrying after 2 seconds...'); + + // Add a delay to avoid spamming the server with requests + await Future.delayed(const Duration(seconds: 2)); + } catch (e) { + // If the session times out or another error occurs, rethrow the error + rethrow; + } + } + } catch (e) { + // If the initial request fails, rethrow the error + rethrow; + } + } + + // Future<(bdk.Transaction originalTx, receive.PayjoinProposal)> handleV2Request( + // receive.UncheckedProposal uncheckedProposal, + // bdk.Wallet receiverWallet, + // ) async { + // final (originalTx, payjoinProposal) = await _handleV2Request( + // proposal: uncheckedProposal, + // receiverWallet: receiverWallet, + // ); + // final (proposalReq, proposalCtx) = await payjoinProposal.extractV2Req(); + // final res = await http.post( + // Uri.parse(proposalReq.url.asString()), + // body: proposalReq.body, + // headers: { + // 'Content-Type': v2ContentType, + // }, + // ); + // await payjoinProposal.processRes( + // res: res.bodyBytes, + // ohttpContext: proposalCtx, + // ); + + // return (originalTx, payjoinProposal); + // } + + Future getTxIdFromPsbt( + String psbtBase64, + ) async { + final psbt = await bdk.PartiallySignedTransaction.fromString(psbtBase64); + final txId = psbt.extractTx().txid(); + return txId; + } + + Future processV1Proposal( + send.Sender sender, + String proposalPsbt, + ) async { + final (_, ctx) = await sender.extractV1(); + final checkedProposal = + await ctx.processResponse(response: utf8.encode(proposalPsbt)); + debugPrint('Processed Response: $checkedProposal'); + return checkedProposal; + } + + // Future processV2Proposal( + // send.Sender sender, + // String proposalPsbt, + // ) async { + // final (_, ctx) = await sender.extractV2( + // ohttpProxyUrl: await pj_uri.Url.fromStr(payjoinDirectory), + // ); + // final checkedProposal = + // await ctx.processResponse(response: utf8.encode(proposalPsbt)); + // debugPrint('Processed Response: $checkedProposal'); + // return checkedProposal!; // Since this is called after the original request, the response should not be null + // } + + Future extractPjTx( + bdk.Wallet senderWallet, String psbtString) async { + final psbt = await bdk.PartiallySignedTransaction.fromString(psbtString); + debugPrint('PSBT before: ${psbt.toString()}'); + senderWallet.sign( + psbt: psbt, + signOptions: const bdk.SignOptions( + trustWitnessUtxo: true, + allowAllSighashes: false, + removePartialSigs: true, + tryFinalize: true, + signWithTapInternalKey: true, + allowGrinding: false)); + debugPrint('PSBT after: ${psbt.toString()}'); + var transaction = psbt.extractTx(); + return transaction; + } + + Future startV2ReceiveSession({ + required String address, + required Network network, + required int expireAfter, + }) async { + final ohttpRelayUrl = await pj_uri.Url.fromStr(ohttpRelay); + final payjoinDirectoryUrl = await pj_uri.Url.fromStr(payjoinDirectory); + pj_uri.OhttpKeys ohttpKeys = await pj_uri.fetchOhttpKeys( + ohttpRelay: ohttpRelayUrl, + payjoinDirectory: payjoinDirectoryUrl, + ); + + return await receive.Receiver.create( + address: address, + ohttpRelay: ohttpRelayUrl, + directory: payjoinDirectoryUrl, + ohttpKeys: ohttpKeys, + network: Network.signet, + expireAfter: BigInt.from(expireAfter), + ); + } + + // Future<(bdk.Transaction originalTx, receive.PayjoinProposal)> + // _handleV2Request({ + // required receive.UncheckedProposal proposal, + // required bdk.Wallet receiverWallet, + // }) async { + // try { + // final originalTxBytes = await proposal.extractTxToScheduleBroadcast(); + // final originalTx = + // await bdk.Transaction.fromBytes(transactionBytes: originalTxBytes); + + // final ownedInputs = + // await proposal.checkBroadcastSuitability(canBroadcast: (e) async { + // return true; + // }); + // final seenInputs = await ownedInputs.checkInputsNotOwned( + // isOwned: (i) => _isOwned(i, receiverWallet)); + // final wantsInputs = + // await (await seenInputs.checkNoInputsSeenBefore(isKnown: (e) async { + // return false; + // })) + // .identifyReceiverOutputs( + // isReceiverOutput: (i) => _isOwned(i, receiverWallet), + // ); + + // final availableInputs = receiverWallet.listUnspent(); + // Map candidateInputs = { + // for (var input in availableInputs) + // input.txout.value: types.OutPoint( + // txid: input.outpoint.txid.toString(), + // vout: input.outpoint.vout, + // ) + // }; + // final selectedOutpoint = await wantsInputs.tryPreservingPrivacy( + // candidateInputs: candidateInputs, + // ); + // var selectedUtxo = availableInputs.firstWhere( + // (i) => + // i.outpoint.txid == selectedOutpoint.txid && + // i.outpoint.vout == selectedOutpoint.vout, + // orElse: () => throw Exception('UTXO not found')); + // var txoToContribute = types.TxOut( + // value: selectedUtxo.txout.value, + // scriptPubkey: selectedUtxo.txout.scriptPubkey.bytes, + // ); + + // var outpointToContribute = types.OutPoint( + // txid: selectedUtxo.outpoint.txid.toString(), + // vout: selectedUtxo.outpoint.vout, + // ); + // await wantsInputs.contributeWitnessInput( + // txo: txoToContribute, + // outpoint: outpointToContribute, + // ); + + // /* PjUri is generated with pjos=0, so no output substitution is permitted + // await payjoin.trySubstituteReceiverOutput( + // generateScript: () async => receiverWallet + // .getAddress(addressIndex: const bdk.AddressIndex.increase()) + // .address + // .scriptPubkey() + // .bytes);*/ + // final payjoinProposal = await wantsInputs.finalizeProposal( + // processPsbt: (i) => _processPsbt(i, receiverWallet)); + // return (originalTx, payjoinProposal); + // } on Exception catch (e) { + // debugPrint(e.toString()); + // rethrow; + // } + // } + + Future _isOwned(Uint8List bytes, bdk.Wallet wallet) async { + final script = bdk.ScriptBuf(bytes: bytes); + return wallet.isMine(script: script); + } + + Future processPsbt(String preProcessed, bdk.Wallet wallet) async { + final psbt = await bdk.PartiallySignedTransaction.fromString(preProcessed); + debugPrint('PSBT before: ${psbt.toString()}'); + await wallet.sign( + psbt: psbt, + signOptions: const bdk.SignOptions( + trustWitnessUtxo: true, + allowAllSighashes: false, + removePartialSigs: true, + tryFinalize: true, + signWithTapInternalKey: true, + allowGrinding: false, + ), + ); + debugPrint('PSBT after: ${psbt.toString()}'); + return psbt.asString(); + } +} diff --git a/example/lib/payjoin_library.dart b/example/lib/payjoin_library.dart deleted file mode 100644 index 9724c0a..0000000 --- a/example/lib/payjoin_library.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'dart:async'; -import 'dart:typed_data'; - -import 'package:flutter/cupertino.dart'; -import 'package:payjoin_flutter/common.dart' as common; -import 'package:payjoin_flutter/receive/v1.dart' as v1; -import 'package:payjoin_flutter/send.dart' as send; -import 'package:payjoin_flutter/uri.dart' as pj_uri; - -class PayJoinLibrary { - static const pjUrl = "https://localhost:8088"; - static const ohRelay = "https://localhost:8088"; - static const localCertFile = "localhost.der"; - Future buildPjUri(double amount, String address, {String? pj}) async { - try { - final pjUri = "bitcoin:$address?amount=$amount&pj=${pj ?? pjUrl}"; - await pj_uri.Uri.fromStr(pjUri); - return pjUri; - } catch (e) { - debugPrint(e.toString()); - rethrow; - } - } - - Future<(v1.ProvisionalProposal, send.ContextV1)> handlePjRequest( - String psbtBase64, - String uriStr, - Future Function(Uint8List) isOwned) async { - final uri = await pj_uri.Uri.fromStr(uriStr); - final (req, cxt) = await (await (await send.RequestBuilder.fromPsbtAndUri( - psbtBase64: psbtBase64, pjUri: uri.checkPjSupported())) - .buildWithAdditionalFee( - maxFeeContribution: BigInt.from(10000), - minFeeRate: BigInt.zero, - clampFeeContribution: false)) - .extractV1(); - final headers = common.Headers(map: { - 'content-type': 'text/plain', - 'content-length': req.body.length.toString(), - }); - final unchecked = await v1.UncheckedProposal.fromRequest( - body: req.body.toList(), query: (req.url.query())!, headers: headers); - final provisionalProposal = await handleUnckedProposal(unchecked, isOwned); - return (provisionalProposal, cxt); - } - - Future handleUnckedProposal( - v1.UncheckedProposal uncheckedProposal, - Future Function(Uint8List) isOwned) async { - // in a payment processor where the sender could go offline, this is where you schedule to broadcast the original_tx - var _ = await uncheckedProposal.extractTxToScheduleBroadcast(); - final inputsOwned = await uncheckedProposal.assumeInteractiveReceiver(); - // Receive Check 2: receiver can't sign for proposal inputs - final mixedInputScripts = - await inputsOwned.checkInputsNotOwned(isOwned: isOwned); - - // Receive Check 3: receiver can't sign for proposal inputs - final seenInputs = await mixedInputScripts.checkNoMixedInputScripts(); - // Receive Check 4: have we seen this input before? More of a check for non-interactive i.e. payment processor receivers. - final provisionalProposal = - await (await seenInputs.checkNoInputsSeenBefore(isKnown: (e) async { - return false; - })) - .identifyReceiverOutputs(isReceiverOutput: isOwned); - return provisionalProposal; - } -} diff --git a/example/lib/screens/home.dart b/example/lib/screens/home.dart new file mode 100644 index 0000000..76ddeb2 --- /dev/null +++ b/example/lib/screens/home.dart @@ -0,0 +1,742 @@ +import 'dart:io'; + +import 'package:bdk_flutter/bdk_flutter.dart' as bdk; +import 'package:bdk_flutter_demo/managers/payjoin_manager.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:payjoin_flutter/bitcoin_ffi.dart'; +import 'package:payjoin_flutter/common.dart'; +import 'package:payjoin_flutter/receive.dart'; +import 'package:payjoin_flutter/send.dart'; +import 'package:payjoin_flutter/uri.dart' as pjuri; +import 'package:url_launcher/url_launcher.dart'; +import '../widgets/widgets.dart'; + +class Home extends StatefulWidget { + const Home({Key? key}) : super(key: key); + + @override + State createState() => _HomeState(); +} + +class _HomeState extends State { + late bdk.Wallet wallet; + late bdk.Blockchain blockchain; + String? displayText; + String? address; + String balance = "0"; + TextEditingController mnemonic = TextEditingController(); + TextEditingController recipientAddress = TextEditingController(); + TextEditingController amountController = TextEditingController(); + TextEditingController pjUriController = TextEditingController(); + TextEditingController psbtController = TextEditingController(); + TextEditingController receiverPsbtController = TextEditingController(); + bool _isPayjoinEnabled = false; + bool isReceiver = false; + Receiver? v2Session; + Sender? sender; + UncheckedProposal? uncheckedProposal; + PayjoinProposal? payjoinProposal; + FeeRangeEnum? feeRange; + PayjoinManager payjoinManager = PayjoinManager(); + String pjUri = ''; + + String get getSubmitButtonTitle => _isPayjoinEnabled + ? sender != null + ? "Finalize Payjoin" + : isReceiver + ? pjUri.isNotEmpty + ? "Handle Request" + : "Build Pj Uri" + : "Perform Payjoin" + : "Send Bit"; + + Future generateMnemonicHandler() async { + var res = (await bdk.Mnemonic.create(bdk.WordCount.words12)).asString(); + + setState(() { + mnemonic.text = res; + displayText = res; + }); + } + + Future> getDescriptors(String mnemonicStr) async { + final descriptors = []; + try { + for (var e in [ + bdk.KeychainKind.externalChain, + bdk.KeychainKind.internalChain + ]) { + final mnemonic = await bdk.Mnemonic.fromString(mnemonicStr); + final descriptorSecretKey = await bdk.DescriptorSecretKey.create( + network: bdk.Network.signet, + mnemonic: mnemonic, + ); + final descriptor = await bdk.Descriptor.newBip86( + secretKey: descriptorSecretKey, + network: bdk.Network.signet, + keychain: e); + descriptors.add(descriptor); + } + return descriptors; + } on Exception catch (e) { + setState(() { + displayText = "Error : ${e.toString()}"; + }); + rethrow; + } + } + + createOrRestoreWallet( + String mnemonic, + bdk.Network network, + String? password, + String path, //TODO: Derived error: Address contains key path + ) async { + try { + final descriptors = await getDescriptors(mnemonic); + await blockchainInit(); + final res = await bdk.Wallet.create( + descriptor: descriptors[0], + changeDescriptor: descriptors[1], + network: network, + databaseConfig: const bdk.DatabaseConfig.memory()); + setState(() { + wallet = res; + }); + var addressInfo = getNewAddress(); + address = addressInfo.address.asString(); + setState(() { + displayText = "Wallet Created: $address"; + }); + } on Exception catch (e) { + setState(() { + displayText = "Error: ${e.toString()}"; + }); + } + } + + Future getBalance() async { + final balanceObj = wallet.getBalance(); + final res = "Total Balance: ${balanceObj.total.toString()}"; + if (kDebugMode) { + print(res); + } + setState(() { + balance = balanceObj.total.toString(); + displayText = res; + }); + } + + bdk.AddressInfo getNewAddress() { + final res = + wallet.getAddress(addressIndex: const bdk.AddressIndex.increase()); + if (kDebugMode) { + print(res.address); + } + address = res.address.asString(); + setState(() { + displayText = address; + if (isReceiver && address != null) { + recipientAddress.text = address!; + } + }); + return res; + } + + Future sendTx(String addressStr, int amount) async { + try { + final txBuilder = bdk.TxBuilder(); + final address = await bdk.Address.fromString( + s: addressStr, network: bdk.Network.signet); + final script = await address.scriptPubkey(); + + final psbt = await txBuilder + .addRecipient(script, BigInt.from(amount)) + .feeRate(1.0) + .finish(wallet); + + final isFinalized = await wallet.sign(psbt: psbt.$1); + if (isFinalized) { + final tx = psbt.$1.extractTx(); + final res = await blockchain.broadcast(transaction: tx); + debugPrint(res); + } else { + debugPrint("psbt not finalized!"); + } + + setState(() { + displayText = "Successfully broadcast $amount Sats to $addressStr"; + }); + } on Exception catch (e) { + setState(() { + displayText = "Error: ${e.toString()}"; + }); + } + } + +/* const BlockchainConfig.electrum( + config: ElectrumConfig( + stopGap: 10, + timeout: 5, + retry: 5, + url: "ssl://electrum.blockstream.info:60002", + validateDomain: false)) */ + ///Step2:Client + blockchainInit() async { + String esploraUrl = 'https://mutinynet.com/api'; + try { + blockchain = await bdk.Blockchain.create( + config: bdk.BlockchainConfig.esplora( + config: bdk.EsploraConfig( + baseUrl: esploraUrl, stopGap: BigInt.from(10)))); + } on Exception catch (e) { + setState(() { + displayText = "Error: ${e.toString()}"; + }); + } + } + + Future syncWallet() async { + wallet.sync(blockchain: blockchain); + await getBalance(); + } + + Future changePayjoin(bool value) async { + setState(() { + _isPayjoinEnabled = value; + }); + // Reset the payjoin state when disabling it. + // This is useful to start a new payjoin session by toggling the switch. + if (!value) { + resetPayjoinSession(); + } + } + + Future changeFrom(bool value) async { + setState(() { + isReceiver = value; + }); + } + + Future chooseFeeRange() async { + feeRange = await showModalBottomSheet( + context: context, + builder: (context) => SelectFeeRange(feeRange: feeRange), + constraints: const BoxConstraints.tightFor(height: 300), + ); + } + + @override + Widget build(BuildContext context) { + final formKey = GlobalKey(); + return Scaffold( + resizeToAvoidBottomInset: true, + backgroundColor: Colors.white, + /* Header */ + appBar: buildAppBar(context), + body: SingleChildScrollView( + padding: const EdgeInsets.all(30), + child: Column( + children: [ + /* Balance */ + BalanceContainer( + text: "$balance Sats", + ), + /* Result */ + ResponseContainer( + text: displayText ?? " ", + ), + StyledContainer( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SubmitButton( + text: "Generate Mnemonic", + callback: () async { + await generateMnemonicHandler(); + }), + TextFieldContainer( + child: TextFormField( + controller: mnemonic, + style: Theme.of(context).textTheme.bodyLarge, + keyboardType: TextInputType.multiline, + maxLines: 5, + decoration: const InputDecoration( + hintText: "Enter your mnemonic")), + ), + SubmitButton( + text: "Create Wallet", + callback: () async { + await createOrRestoreWallet(mnemonic.text, + bdk.Network.signet, "password", "m/84'/1'/0'"); + }, + ), + SubmitButton( + text: "Sync Wallet", + callback: () async { + await syncWallet(); + }, + ), + SubmitButton( + callback: () { + getNewAddress(); + }, + text: "Get Address"), + ])), + /* Send Transaction */ + StyledContainer( + child: Form( + key: formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CustomSwitchTile( + title: "Payjoin", + value: _isPayjoinEnabled, + onChanged: changePayjoin, + ), + _isPayjoinEnabled ? buildPayjoinFields() : buildFields(), + v2Session == null && sender == null + ? SubmitButton( + text: getSubmitButtonTitle, + callback: () async { + _isPayjoinEnabled + ? performPayjoin(formKey) + : await onSendBit(formKey); + }, + ) + : Row( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + const CircularProgressIndicator(), + const SizedBox(width: 16), + Expanded( + child: Text( + v2Session != null + ? payjoinProposal != null + ? 'Proposal sent, waiting for tx...' + : uncheckedProposal != null + ? 'Received request, adding inputs to proposal...' + : 'Session initiated, waiting for request...' + : 'Request sent, waiting for proposal to finalize tx...', + ), + ), + ], + ), + ]), + )) + ], + ), + )); + } + + onSendBit(formKey) async { + if (formKey.currentState!.validate()) { + await sendTx(recipientAddress.text, int.parse(amountController.text)); + } + } + + showBottomSheet( + String text, { + String? toCopy, + String? toUrl, + }) { + return showModalBottomSheet( + useSafeArea: true, + context: context, + builder: (context) => Padding( + padding: const EdgeInsets.all(16.0), + child: Row( + children: [ + Expanded(child: Text(text)), + if (toCopy != null && toCopy.isNotEmpty) + IconButton( + onPressed: () { + Clipboard.setData(ClipboardData(text: toCopy)); + Navigator.pop(context); + ScaffoldMessenger.of(context).showSnackBar(const SnackBar( + content: Text('Copied to clipboard!'), + )); + }, + icon: const Icon( + Icons.copy, + size: 36, + ), + ), + if (toUrl != null && toUrl.isNotEmpty) + IconButton( + onPressed: () { + launchUrl(Uri.parse(toUrl)); + }, + icon: const Icon( + Icons.open_in_browser, + size: 36, + ), + ), + ], + ), + ), + ); + } + + Widget buildFields() { + return Column( + children: [ + TextFieldContainer( + child: TextFormField( + controller: recipientAddress, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your address'; + } + return null; + }, + style: Theme.of(context).textTheme.bodyLarge, + decoration: const InputDecoration( + hintText: "Enter Address", + ), + ), + ), + TextFieldContainer( + child: TextFormField( + controller: amountController, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter the amount'; + } + return null; + }, + keyboardType: TextInputType.number, + style: Theme.of(context).textTheme.bodyLarge, + decoration: const InputDecoration( + hintText: "Enter Amount", + ), + ), + ), + ], + ); + } + + Widget buildPayjoinFields() { + return Column( + children: [ + CustomSwitchTile( + title: isReceiver ? "Receiver" : "Sender", + value: isReceiver, + onChanged: changeFrom, + ), + if (isReceiver) ...[ + buildReceiverFields(), + ] else + ...buildSenderFields() + ], + ); + } + + List buildSenderFields() { + if (sender == null) { + return [ + TextFieldContainer( + child: TextFormField( + controller: pjUriController, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter the pjUri'; + } + return null; + }, + style: Theme.of(context).textTheme.bodyLarge, + keyboardType: TextInputType.multiline, + maxLines: 5, + decoration: const InputDecoration(hintText: "Enter pjUri"), + ), + ), + Center( + child: TextButton( + onPressed: () => chooseFeeRange(), + child: const Text( + "Choose fee range", + ), + ), + ), + ]; + } + return []; + } + + Widget buildReceiverFields() { + return pjUri.isEmpty ? buildFields() : Container(); + } + + Future performPayjoin(formKey) async { + if (formKey.currentState!.validate()) { + if (isReceiver) { + await performReceiver(receiverWallet: wallet); + } else { + await performSender(); + } + } + } + + //Sender + Future performSender() async { + // Build payjoin request with original psbt and send it to the + // payjoin directory where the receiver can poll it + final pjUri = await payjoinManager.stringToUri(pjUriController.text); + final originalPsbt = await payjoinManager.buildOriginalPsbt( + wallet, + pjUri, + feeRange?.feeValue ?? FeeRangeEnum.high.feeValue, + ); + final request = await payjoinManager.buildPayjoinRequest( + originalPsbt, + pjUri, + feeRange?.feeValue ?? FeeRangeEnum.high.feeValue, + ); + setState(() { + sender = request; + }); + + // Request and keep polling the payjoin directoy for the proposal + // from the receiver + String psbt = originalPsbt; + try { + psbt = await payjoinManager.requestAndPollV2Proposal( + sender!, + ); + debugPrint('Receiver proposed payjoin PSBT: $psbt'); + } catch (e) { + // No proposal received, make a normal tx with the original psbt + debugPrint('No proposal received, broadcasting original tx'); + } + + // If a proposal is received, finalize the payjoin + final transaction = await payjoinManager.extractPjTx(wallet, psbt); + final txId = await blockchain.broadcast(transaction: transaction); + debugPrint('Broacasted tx: $txId'); + resetPayjoinSession(); + + showBottomSheet( + '${psbt == originalPsbt ? 'Original tx with id' : 'Payjoin tx with id'} ' + '$txId broadcasted!', + toCopy: txId, + toUrl: 'https://mutinynet.com/tx/$txId', + ); + } + + //Receiver + Future performReceiver({required bdk.Wallet receiverWallet}) async { + try { + await initReceiverSession(); + + final httpClient = HttpClient(); + UncheckedProposal? proposal; + while (proposal == null) { + final (request, clientResponse) = await v2Session!.extractReq(); + final url = Uri.parse(request.url.asString()); + final httpRequest = await httpClient.postUrl(url); + + httpRequest.headers.set('Content-Type', request.contentType); + + httpRequest.add(request.body); + + final response = await httpRequest.close(); + final responseBody = await response.fold>( + [], (previous, element) => previous..addAll(element)); + final uint8Response = Uint8List.fromList(responseBody); + proposal = await v2Session! + .processRes(body: uint8Response, ctx: clientResponse); + } + + setState(() { + uncheckedProposal = proposal; + }); + + // Extract the original transaction from the proposal in case you want + // to broadcast it if the sender doesn't finalize the payjoin + final originalTxBytes = await proposal.extractTxToScheduleBroadcast(); + final originalTx = + await bdk.Transaction.fromBytes(transactionBytes: originalTxBytes); + + // Process the proposal through the various checks + final maybeInputsOwned = await proposal.assumeInteractiveReceiver(); + + final maybeInputsSeen = await maybeInputsOwned.checkInputsNotOwned( + isOwned: (outpoint) async => + false // TODO Implement actual ownership check + ); + + final outputsUnknown = await maybeInputsSeen.checkNoInputsSeenBefore( + isKnown: (outpoint) async => false // TODO Implement actual seen check + ); + + final wantsOutputs = await outputsUnknown.identifyReceiverOutputs( + isReceiverOutput: (script) async { + return receiverWallet.isMine(script: bdk.ScriptBuf(bytes: script)); + }); + + var wantsInputs = await wantsOutputs.commitOutputs(); + + // Select and contribute inputs + final unspent = receiverWallet.listUnspent(); + List candidateInputs = []; + for (var input in unspent) { + final txout = TxOut( + value: input.txout.value, + scriptPubkey: input.txout.scriptPubkey.bytes, + ); + final psbtin = PsbtInput( + witnessUtxo: txout, redeemScript: null, witnessScript: null); + final previousOutput = OutPoint( + txid: input.outpoint.txid.toString(), vout: input.outpoint.vout); + final txin = TxIn( + previousOutput: previousOutput, + scriptSig: await Script.newInstance(rawOutputScript: []), + witness: [], + sequence: 0); + final ip = await InputPair.newInstance(txin, psbtin); + candidateInputs.add(ip); + } + final inputPair = await wantsInputs.tryPreservingPrivacy( + candidateInputs: candidateInputs); + + wantsInputs = + await wantsInputs.contributeInputs(replacementInputs: [inputPair]); + final provisionalProposal = await wantsInputs.commitInputs(); + + final finalProposal = await provisionalProposal.finalizeProposal( + processPsbt: (i) => payjoinManager.processPsbt(i, receiverWallet), + maxFeeRateSatPerVb: BigInt.from(25)); + + setState(() { + payjoinProposal = finalProposal; + }); + + final proposalPsbt = await finalProposal.psbt(); + final proposalTxId = await payjoinManager.getTxIdFromPsbt(proposalPsbt); + debugPrint('Receiver proposal tx: $proposalTxId'); + + // Send the proposal via POST request to directory + final (proposalReq, proposalCtx) = await finalProposal.extractV2Req(); + final httpRequest = await httpClient.postUrl( + Uri.parse(proposalReq.url.asString()), + ); + httpRequest.headers.set('content-type', 'message/ohttp-req'); + httpRequest.add(proposalReq.body); + final response = await httpRequest.close(); + final responseBody = await response.fold>( + [], + (previous, element) => previous..addAll(element), + ); + await finalProposal.processRes( + res: responseBody, ohttpContext: proposalCtx); + + // Wait for the payjoin transaction to be broadcasted by the sender + // Still possible the payjoin wasn't finalized and the original tx was + // broadcasted instead by the sender, so also check for that + // You could also put a timeout on waiting for the transaction and then + // broadcast the original tx yourself if no transaction is received + final receivedTxId = await waitForTransaction( + originalTxId: await originalTx.txid(), + proposalTxId: proposalTxId, + ); + resetPayjoinSession(); + + if (receivedTxId.isNotEmpty) { + showBottomSheet( + '${receivedTxId == proposalTxId ? 'Payjoin' : 'Original'} tx received!', + toCopy: receivedTxId, + toUrl: 'https://mutinynet.com/tx/$receivedTxId', + ); + } + } catch (e) { + debugPrint(e.toString()); + if (e is PayjoinException) { + showBottomSheet('PayJoin error: ${e.message}'); + resetPayjoinSession(); + } + } + } + + Future initReceiverSession() async { + final amountSats = BigInt.parse(amountController.text); + debugPrint('AMOUNT SATS: $amountSats'); + final payjoinDirectory = await pjuri.Url.fromStr("https://payjo.in"); + final ohttpRelay = await pjuri.Url.fromStr("https://pj.bobspacebkk.com"); + + final ohttpKeys = await pjuri.fetchOhttpKeys( + ohttpRelay: ohttpRelay, + payjoinDirectory: payjoinDirectory, + ); + debugPrint('OHTTP KEYS FETCHED ${ohttpKeys.toString()}'); + // Create receiver session with new bindings + final receiver = await Receiver.create( + address: recipientAddress.text, + network: Network.signet, + directory: payjoinDirectory, + ohttpKeys: ohttpKeys, + ohttpRelay: ohttpRelay, + expireAfter: BigInt.from(60 * 5), // 5 minutes + ); + debugPrint('INITIALIZED RECEIVER'); + + final pjUrl = + receiver.pjUriBuilder().amountSats(amount: amountSats).build(); + final pjStr = pjUrl.asString(); + debugPrint('PAYJOIN URL: $pjStr'); + + setState(() { + v2Session = receiver; + displayText = pjStr; + pjUri = pjStr; + }); + } + + Future waitForTransaction({ + required String originalTxId, + required String proposalTxId, + int timeout = 1, + }) async { + debugPrint('Waiting for payjoin tx to be sent...'); + await syncWallet(); + final txs = wallet.listTransactions(includeRaw: false); + try { + final tx = txs.firstWhere( + (tx) => tx.txid == originalTxId || tx.txid == proposalTxId); + debugPrint('Tx found: ${tx.txid}'); + return tx.txid; + } catch (e) { + debugPrint('Tx not found, retrying after $timeout second(s)...'); + if (v2Session == null) { + // The session was canceled, stop polling + return ''; + } + await Future.delayed(Duration(seconds: timeout)); + return waitForTransaction( + originalTxId: originalTxId, + proposalTxId: proposalTxId, + ); + } + } + + void resetPayjoinSession() { + setState(() { + pjUri = ''; + v2Session = null; + sender = null; + uncheckedProposal = null; + payjoinProposal = null; + }); + // Also clean the text controllers to start a new payjoin session + recipientAddress.clear(); + amountController.clear(); + pjUriController.clear(); + receiverPsbtController.clear(); + psbtController.clear(); + } +} diff --git a/example/lib/styles/theme.dart b/example/lib/styles/theme.dart new file mode 100644 index 0000000..b9f6b46 --- /dev/null +++ b/example/lib/styles/theme.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; + +ThemeData theme() { + Color secondaryColor = Colors.orange; + Color primaryColor = Colors.blue.withOpacity(.8); + return ThemeData( + primaryColor: primaryColor, + secondaryHeaderColor: secondaryColor, + appBarTheme: const AppBarTheme( + centerTitle: true, + elevation: 0, + backgroundColor: Colors.white, + ), + textTheme: TextTheme( + displayLarge: const TextStyle( + color: Colors.black, fontWeight: FontWeight.w900, fontSize: 18), + displayMedium: const TextStyle( + color: Colors.black, fontWeight: FontWeight.w900, fontSize: 14.5), + bodyLarge: TextStyle( + color: Colors.black.withOpacity(.8), + fontWeight: FontWeight.w500, + fontSize: 12), + labelLarge: const TextStyle( + color: Colors.white, fontWeight: FontWeight.w800, fontSize: 13)), + inputDecorationTheme: InputDecorationTheme( + border: InputBorder.none, + contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), + hintStyle: TextStyle( + color: Colors.black.withOpacity(.4), + fontWeight: FontWeight.w500, + fontSize: 10), + )); +} diff --git a/example/lib/widgets/widgets.dart b/example/lib/widgets/widgets.dart new file mode 100644 index 0000000..49d2f70 --- /dev/null +++ b/example/lib/widgets/widgets.dart @@ -0,0 +1,258 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class SubmitButton extends StatelessWidget { + final String text; + final VoidCallback callback; + + const SubmitButton({Key? key, required this.text, required this.callback}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: callback, + child: Container( + margin: const EdgeInsets.only(bottom: 5), + decoration: BoxDecoration( + color: Theme.of(context).primaryColor, + borderRadius: BorderRadius.circular(5)), + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20), + width: double.infinity, + child: Center( + child: Text(text, style: Theme.of(context).textTheme.labelLarge), + ), + ), + ); + } +} + +class TextFieldContainer extends StatelessWidget { + final Widget child; + + const TextFieldContainer({Key? key, required this.child}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 2.5), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + border: Border.all(width: 2, color: Theme.of(context).primaryColor)), + child: child, + ); + } +} + +class StyledContainer extends StatelessWidget { + final Widget child; + + const StyledContainer({Key? key, required this.child}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 5), + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 50), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + border: Border.all( + width: 2, + color: Theme.of(context).primaryColor, + )), + child: child, + ); + } +} + +class BalanceContainer extends StatelessWidget { + final String text; + + const BalanceContainer({Key? key, required this.text}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 5), + padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5), + width: double.infinity, + child: StyledContainer( + child: SelectableText.rich( + TextSpan( + children: [ + TextSpan( + text: "Balance: ", + style: Theme.of(context).textTheme.displayMedium), + TextSpan( + text: text, style: Theme.of(context).textTheme.bodyLarge), + ], + ), + ), + )); + } +} + +class ResponseContainer extends StatelessWidget { + final String text; + + const ResponseContainer({Key? key, required this.text}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 5), + padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5), + width: double.infinity, + child: StyledContainer( + child: SelectableText.rich( + TextSpan( + children: [ + TextSpan( + text: "Response: ", + style: Theme.of(context).textTheme.displayMedium), + TextSpan( + text: text, style: Theme.of(context).textTheme.bodyLarge), + ], + ), + ), + )); + } +} + +AppBar buildAppBar(BuildContext context) { + return AppBar( + leadingWidth: 80, + actions: [ + Padding( + padding: const EdgeInsets.only(right: 20, bottom: 10, top: 10), + child: Image.asset("assets/pdk_logo.png"), + ) + ], + leading: Icon( + CupertinoIcons.bitcoin_circle_fill, + color: Theme.of(context).secondaryHeaderColor, + size: 40, + ), + title: + Text("Payjoin Demo", style: Theme.of(context).textTheme.displayLarge), + ); +} + +class SelectFeeRange extends StatelessWidget { + const SelectFeeRange({super.key, this.feeRange}); + final FeeRangeEnum? feeRange; + @override + Widget build(BuildContext context) { + return Column( + children: [ + const Padding( + padding: EdgeInsets.symmetric(horizontal: 24, vertical: 8), + child: Text( + 'Choose a Fee Range', + ), + ), + FeesRangeOptions( + feeRange: feeRange, + ), + ], + ); + } +} + +enum FeeRangeEnum { + high('High', 2000), + medium('Medium', 1000), + low('Low', 500); + + final String name; + final int feeValue; + + const FeeRangeEnum(this.name, this.feeValue); + + @override + String toString() => '$feeValue sats'; +} + +class FeesRangeOptions extends StatefulWidget { + FeesRangeOptions({super.key, this.feeRange = FeeRangeEnum.high}); + FeeRangeEnum? feeRange; + @override + State createState() => _FeesRangeOptionsState(); +} + +class _FeesRangeOptionsState extends State { + @override + Widget build(BuildContext context) { + return Column( + children: [ + RadioListTile( + title: ListTile( + title: Text(FeeRangeEnum.high.name), + subtitle: const Text('10 - 30 minutes'), + trailing: Text(FeeRangeEnum.high.toString()), + ), + value: FeeRangeEnum.high, + groupValue: widget.feeRange, + onChanged: onChangeFeeRange, + ), + RadioListTile( + title: ListTile( + title: Text(FeeRangeEnum.medium.name), + subtitle: const Text('30 - 60 minutes'), + trailing: Text(FeeRangeEnum.medium.toString()), + ), + value: FeeRangeEnum.medium, + groupValue: widget.feeRange, + onChanged: onChangeFeeRange, + ), + RadioListTile( + title: ListTile( + title: Text(FeeRangeEnum.low.name), + subtitle: const Text('2 - 12 hours'), + trailing: Text(FeeRangeEnum.low.toString()), + ), + value: FeeRangeEnum.low, + groupValue: widget.feeRange, + onChanged: onChangeFeeRange, + ), + ], + ); + } + + onChangeFeeRange(FeeRangeEnum? value) { + setState(() { + widget.feeRange = value; + Navigator.pop(context, widget.feeRange); + }); + } +} + +class CustomSwitchTile extends StatelessWidget { + const CustomSwitchTile( + {super.key, + required this.title, + required this.onChanged, + required this.value}); + final String title; + final bool value; + final Function(bool) onChanged; + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + title, + style: Theme.of(context).textTheme.bodyLarge, + ), + Align( + alignment: Alignment.centerRight, + child: Switch( + value: value, + onChanged: onChanged, + ), + ), + ], + ); + } +} diff --git a/example/pubspec.lock b/example/pubspec.lock index 391d1d6..04e2662 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,26 +5,31 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 url: "https://pub.dev" source: hosted - version: "67.0.0" + version: "72.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.3.2" analyzer: dependency: transitive description: name: analyzer - sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 url: "https://pub.dev" source: hosted - version: "6.4.1" + version: "6.7.0" args: dependency: transitive description: name: args - sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.6.0" async: dependency: transitive description: @@ -38,7 +43,7 @@ packages: description: path: "." ref: main - resolved-ref: "8a9bd981078eaa8692fc2bed869810acc9918a2c" + resolved-ref: "8d7d89b47a2766ec55bd6710403d212f4e4432cb" url: "https://github.com/LtbLightning/bdk-flutter" source: git version: "0.31.2" @@ -102,10 +107,10 @@ packages: dependency: transitive description: name: code_builder - sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 + sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" url: "https://pub.dev" source: hosted - version: "4.10.0" + version: "4.10.1" collection: dependency: transitive description: @@ -118,18 +123,18 @@ packages: dependency: transitive description: name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" crypto: dependency: transitive description: name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.6" cupertino_icons: dependency: "direct main" description: @@ -142,18 +147,10 @@ packages: dependency: transitive description: name: dart_style - sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" - url: "https://pub.dev" - source: hosted - version: "2.3.6" - dio: - dependency: "direct main" - description: - name: dio - sha256: "11e40df547d418cc0c4900a9318b26304e665da6fa4755399a9ff9efd09034b5" + sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab" url: "https://pub.dev" source: hosted - version: "5.4.3+1" + version: "2.3.7" fake_async: dependency: transitive description: @@ -166,36 +163,31 @@ packages: dependency: transitive description: name: ffi - sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" file: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" fixnum: dependency: transitive description: name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" - flutter_driver: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" flutter_lints: dependency: "direct dev" description: @@ -217,19 +209,19 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" freezed_annotation: dependency: transitive description: name: freezed_annotation - sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d + sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 url: "https://pub.dev" source: hosted - version: "2.4.1" - fuchsia_remote_debug_protocol: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" + version: "2.4.4" glob: dependency: transitive description: @@ -238,22 +230,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" - google_fonts: - dependency: "direct main" - description: - name: google_fonts - sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82 - url: "https://pub.dev" - source: hosted - version: "6.2.1" http: - dependency: transitive + dependency: "direct main" description: name: http - sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" http_parser: dependency: transitive description: @@ -262,11 +246,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" - integration_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" json_annotation: dependency: transitive description: @@ -279,18 +258,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.4" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -311,10 +290,18 @@ packages: dependency: transitive description: name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" + macros: + dependency: transitive + description: + name: macros + sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + url: "https://pub.dev" + source: hosted + version: "0.1.2-main.4" matcher: dependency: transitive description: @@ -327,18 +314,18 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.15.0" mockito: dependency: transitive description: @@ -363,54 +350,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.0" - path_provider: - dependency: transitive - description: - name: path_provider - sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161 - url: "https://pub.dev" - source: hosted - version: "2.1.3" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - sha256: bca87b0165ffd7cdb9cad8edd22d18d2201e886d9a9f19b4fb3452ea7df3a72a - url: "https://pub.dev" - source: hosted - version: "2.2.6" - path_provider_foundation: - dependency: transitive - description: - name: path_provider_foundation - sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 - url: "https://pub.dev" - source: hosted - version: "2.4.0" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 - url: "https://pub.dev" - source: hosted - version: "2.2.1" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" - url: "https://pub.dev" - source: hosted - version: "2.2.1" payjoin_flutter: dependency: "direct main" description: @@ -418,14 +357,6 @@ packages: relative: true source: path version: "0.20.0" - platform: - dependency: transitive - description: - name: platform - sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" - url: "https://pub.dev" - source: hosted - version: "3.1.4" plugin_platform_interface: dependency: transitive description: @@ -434,14 +365,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" - process: - dependency: transitive - description: - name: process - sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" - url: "https://pub.dev" - source: hosted - version: "5.0.2" pub_semver: dependency: transitive description: @@ -503,14 +426,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" - sync_http: - dependency: transitive - description: - name: sync_http - sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" - url: "https://pub.dev" - source: hosted - version: "0.3.1" term_glyph: dependency: transitive description: @@ -523,26 +438,90 @@ packages: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.2" typed_data: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603" + url: "https://pub.dev" + source: hosted + version: "6.3.1" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193" + url: "https://pub.dev" + source: hosted + version: "6.3.14" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e + url: "https://pub.dev" + source: hosted + version: "6.3.1" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "769549c999acdb42b8bcfa7c43d72bf79a382ca7441ab18a808e101149daf672" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "2.3.3" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "44cf3aabcedde30f2dba119a9dea3b0f2672fbe6fa96e85536251d678216b3c4" + url: "https://pub.dev" + source: hosted + version: "3.1.3" uuid: dependency: transitive description: name: uuid - sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8" + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff url: "https://pub.dev" source: hosted - version: "4.4.0" + version: "4.5.1" vector_math: dependency: transitive description: @@ -555,10 +534,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "14.2.1" + version: "14.2.5" watcher: dependency: transitive description: @@ -575,30 +554,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.1" - webdriver: - dependency: transitive - description: - name: webdriver - sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" - url: "https://pub.dev" - source: hosted - version: "3.0.3" - win32: - dependency: transitive - description: - name: win32 - sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4 - url: "https://pub.dev" - source: hosted - version: "5.5.1" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d - url: "https://pub.dev" - source: hosted - version: "1.0.4" yaml: dependency: transitive description: @@ -608,5 +563,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.4.0 <4.0.0" - flutter: ">=3.22.0" + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 77cf38a..d90021f 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,62 +1,26 @@ -name: payjoin_flutter_example -description: "Demonstrates how to use the payjoin plugin." -# The following line prevents the package from being accidentally published to -# pub.dev using `flutter pub publish`. This is preferred for private packages. +name: bdk_flutter_demo +description: A new Flutter project. publish_to: "none" # Remove this line if you wish to publish to pub.dev - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -# In Windows, build-name is used as the major, minor, and patch parts -# of the product and file versions while build-number is used as the build suffix. -version: 1.0.0+1 - +version: 0.3.0 environment: sdk: ">=3.2.3 <4.0.0" - -# Dependencies specify other packages that your package needs in order to work. -# To automatically upgrade your package dependencies to the latest versions -# consider running `flutter pub upgrade --major-versions`. Alternatively, -# dependencies can be manually updated by changing the version numbers below to -# the latest version available on pub.dev. To see which dependencies have newer -# versions available, run `flutter pub outdated`. dependencies: - flutter: - sdk: flutter - payjoin_flutter: - # When depending on this package from a real application you should use: - # payjoin: ^x.y.z - # See https://dart.dev/tools/pub/dependencies#version-constraints - # The example app is bundled with the plugin so we use a path dependency on - # the parent directory to use the current plugin's version. - path: ../ - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.2 - dio: ^5.4.3+1 bdk_flutter: git: url: https://github.com/LtbLightning/bdk-flutter ref: main - - google_fonts: ^6.2.1 - + cupertino_icons: ^1.0.2 + flutter: + sdk: flutter + http: ^1.2.1 + payjoin_flutter: + path: ../ + url_launcher: ^6.3.0 dev_dependencies: + flutter_lints: ^2.0.0 flutter_test: sdk: flutter - integration_test: - sdk: flutter - flutter_driver: - sdk: flutter - flutter_lints: ^2.0.0 - flutter: uses-material-design: true + assets: + - assets/ diff --git a/ios/Classes/frb_generated.h b/ios/Classes/frb_generated.h index fcb436a..f9f5bd1 100644 --- a/ios/Classes/frb_generated.h +++ b/ios/Classes/frb_generated.h @@ -14,22 +14,51 @@ void store_dart_post_cobject(DartPostCObjectFnType ptr); // EXTRA END typedef struct _Dart_Handle* Dart_Handle; -typedef struct wire_cst_ffi_url { +typedef struct wire_cst_list_prim_u_8_loose { + uint8_t *ptr; + int32_t len; +} wire_cst_list_prim_u_8_loose; + +typedef struct wire_cst_ffi_script { uintptr_t field0; -} wire_cst_ffi_url; +} wire_cst_ffi_script; -typedef struct wire_cst_ffi_active_session { +typedef struct wire_cst_ffi_url { uintptr_t field0; -} wire_cst_ffi_active_session; +} wire_cst_ffi_url; -typedef struct wire_cst_list_prim_u_8_loose { +typedef struct wire_cst_list_prim_u_8_strict { uint8_t *ptr; int32_t len; -} wire_cst_list_prim_u_8_loose; +} wire_cst_list_prim_u_8_strict; -typedef struct wire_cst_client_response { - uintptr_t field0; -} wire_cst_client_response; +typedef struct wire_cst_out_point { + struct wire_cst_list_prim_u_8_strict *txid; + uint32_t vout; +} wire_cst_out_point; + +typedef struct wire_cst_list_list_prim_u_8_strict { + struct wire_cst_list_prim_u_8_strict **ptr; + int32_t len; +} wire_cst_list_list_prim_u_8_strict; + +typedef struct wire_cst_tx_in { + struct wire_cst_out_point previous_output; + struct wire_cst_ffi_script script_sig; + uint32_t sequence; + struct wire_cst_list_list_prim_u_8_strict *witness; +} wire_cst_tx_in; + +typedef struct wire_cst_tx_out { + uint64_t value; + struct wire_cst_list_prim_u_8_strict *script_pubkey; +} wire_cst_tx_out; + +typedef struct wire_cst_psbt_input { + struct wire_cst_tx_out *witness_utxo; + struct wire_cst_ffi_script *redeem_script; + struct wire_cst_ffi_script *witness_script; +} wire_cst_psbt_input; typedef struct wire_cst_ffi_maybe_inputs_owned { uintptr_t field0; @@ -39,10 +68,6 @@ typedef struct wire_cst_ffi_maybe_inputs_seen { uintptr_t field0; } wire_cst_ffi_maybe_inputs_seen; -typedef struct wire_cst_ffi_maybe_mixed_input_scripts { - uintptr_t field0; -} wire_cst_ffi_maybe_mixed_input_scripts; - typedef struct wire_cst_ffi_outputs_unknown { uintptr_t field0; } wire_cst_ffi_outputs_unknown; @@ -51,108 +76,71 @@ typedef struct wire_cst_ffi_payjoin_proposal { uintptr_t field0; } wire_cst_ffi_payjoin_proposal; -typedef struct wire_cst_ffi_provisional_proposal { +typedef struct wire_cst_client_response { uintptr_t field0; -} wire_cst_ffi_provisional_proposal; - -typedef struct wire_cst_list_prim_u_8_strict { - uint8_t *ptr; - int32_t len; -} wire_cst_list_prim_u_8_strict; - -typedef struct wire_cst_tx_out { - uint64_t value; - struct wire_cst_list_prim_u_8_strict *script_pubkey; -} wire_cst_tx_out; - -typedef struct wire_cst_out_point { - struct wire_cst_list_prim_u_8_strict *txid; - uint32_t vout; -} wire_cst_out_point; - -typedef struct wire_cst_record_u_64_out_point { - uint64_t field0; - struct wire_cst_out_point field1; -} wire_cst_record_u_64_out_point; - -typedef struct wire_cst_list_record_u_64_out_point { - struct wire_cst_record_u_64_out_point *ptr; - int32_t len; -} wire_cst_list_record_u_64_out_point; +} wire_cst_client_response; -typedef struct wire_cst_ffi_session_initializer { +typedef struct wire_cst_ffi_provisional_proposal { uintptr_t field0; -} wire_cst_ffi_session_initializer; +} wire_cst_ffi_provisional_proposal; typedef struct wire_cst_ffi_ohttp_keys { uintptr_t field0; } wire_cst_ffi_ohttp_keys; -typedef struct wire_cst_ffi_unchecked_proposal { +typedef struct wire_cst_ffi_receiver { uintptr_t field0; -} wire_cst_ffi_unchecked_proposal; +} wire_cst_ffi_receiver; -typedef struct wire_cst_record_string_string { - struct wire_cst_list_prim_u_8_strict *field0; - struct wire_cst_list_prim_u_8_strict *field1; -} wire_cst_record_string_string; - -typedef struct wire_cst_list_record_string_string { - struct wire_cst_record_string_string *ptr; - int32_t len; -} wire_cst_list_record_string_string; - -typedef struct wire_cst_headers { - struct wire_cst_list_record_string_string *map; -} wire_cst_headers; - -typedef struct wire_cst_ffi_v_2_maybe_inputs_owned { +typedef struct wire_cst_ffi_unchecked_proposal { uintptr_t field0; -} wire_cst_ffi_v_2_maybe_inputs_owned; +} wire_cst_ffi_unchecked_proposal; -typedef struct wire_cst_ffi_v_2_maybe_inputs_seen { +typedef struct wire_cst_ffi_wants_inputs { uintptr_t field0; -} wire_cst_ffi_v_2_maybe_inputs_seen; +} wire_cst_ffi_wants_inputs; -typedef struct wire_cst_ffi_v_2_maybe_mixed_input_scripts { +typedef struct wire_cst_ffi_input_pair { uintptr_t field0; -} wire_cst_ffi_v_2_maybe_mixed_input_scripts; +} wire_cst_ffi_input_pair; -typedef struct wire_cst_ffi_v_2_outputs_unknown { - uintptr_t field0; -} wire_cst_ffi_v_2_outputs_unknown; +typedef struct wire_cst_list_ffi_input_pair { + struct wire_cst_ffi_input_pair *ptr; + int32_t len; +} wire_cst_list_ffi_input_pair; -typedef struct wire_cst_ffi_v_2_payjoin_proposal { +typedef struct wire_cst_ffi_wants_outputs { uintptr_t field0; -} wire_cst_ffi_v_2_payjoin_proposal; +} wire_cst_ffi_wants_outputs; -typedef struct wire_cst_ffi_v_2_provisional_proposal { - uintptr_t field0; -} wire_cst_ffi_v_2_provisional_proposal; +typedef struct wire_cst_list_tx_out { + struct wire_cst_tx_out *ptr; + int32_t len; +} wire_cst_list_tx_out; -typedef struct wire_cst_ffi_v_2_unchecked_proposal { +typedef struct wire_cst_ffi_sender_builder { uintptr_t field0; -} wire_cst_ffi_v_2_unchecked_proposal; +} wire_cst_ffi_sender_builder; -typedef struct wire_cst_ffi_context_v_1 { +typedef struct wire_cst_ffi_pj_uri { uintptr_t field0; -} wire_cst_ffi_context_v_1; +} wire_cst_ffi_pj_uri; -typedef struct wire_cst_ffi_context_v_2 { +typedef struct wire_cst_ffi_sender { uintptr_t field0; -} wire_cst_ffi_context_v_2; +} wire_cst_ffi_sender; -typedef struct wire_cst_ffi_request_builder { +typedef struct wire_cst_ffi_v_1_context { uintptr_t field0; -} wire_cst_ffi_request_builder; +} wire_cst_ffi_v_1_context; -typedef struct wire_cst_ffi_pj_uri { +typedef struct wire_cst_ffi_v_2_get_context { uintptr_t field0; -} wire_cst_ffi_pj_uri; +} wire_cst_ffi_v_2_get_context; -typedef struct wire_cst_ffi_request_context { +typedef struct wire_cst_ffi_v_2_post_context { uintptr_t field0; -} wire_cst_ffi_request_context; +} wire_cst_ffi_v_2_post_context; typedef struct wire_cst_ffi_pj_uri_builder { uintptr_t internal; @@ -167,11 +155,6 @@ typedef struct wire_cst_list_out_point { int32_t len; } wire_cst_list_out_point; -typedef struct wire_cst_list_prim_u_64_strict { - uint64_t *ptr; - int32_t len; -} wire_cst_list_prim_u_64_strict; - typedef struct wire_cst_PayjoinError_InvalidAddress { struct wire_cst_list_prim_u_8_strict *message; } wire_cst_PayjoinError_InvalidAddress; @@ -244,6 +227,18 @@ typedef struct wire_cst_PayjoinError_IoError { struct wire_cst_list_prim_u_8_strict *message; } wire_cst_PayjoinError_IoError; +typedef struct wire_cst_PayjoinError_OutputSubstitutionError { + struct wire_cst_list_prim_u_8_strict *message; +} wire_cst_PayjoinError_OutputSubstitutionError; + +typedef struct wire_cst_PayjoinError_InputContributionError { + struct wire_cst_list_prim_u_8_strict *message; +} wire_cst_PayjoinError_InputContributionError; + +typedef struct wire_cst_PayjoinError_InputPairError { + struct wire_cst_list_prim_u_8_strict *message; +} wire_cst_PayjoinError_InputPairError; + typedef union PayjoinErrorKind { struct wire_cst_PayjoinError_InvalidAddress InvalidAddress; struct wire_cst_PayjoinError_InvalidScript InvalidScript; @@ -263,6 +258,9 @@ typedef union PayjoinErrorKind { struct wire_cst_PayjoinError_OhttpError OhttpError; struct wire_cst_PayjoinError_UrlError UrlError; struct wire_cst_PayjoinError_IoError IoError; + struct wire_cst_PayjoinError_OutputSubstitutionError OutputSubstitutionError; + struct wire_cst_PayjoinError_InputContributionError InputContributionError; + struct wire_cst_PayjoinError_InputPairError InputPairError; } PayjoinErrorKind; typedef struct wire_cst_payjoin_error { @@ -272,6 +270,7 @@ typedef struct wire_cst_payjoin_error { typedef struct wire_cst_request { struct wire_cst_ffi_url url; + struct wire_cst_list_prim_u_8_strict *content_type; struct wire_cst_list_prim_u_8_strict *body; } wire_cst_request; @@ -280,34 +279,29 @@ typedef struct wire_cst_record_request_client_response { struct wire_cst_client_response field1; } wire_cst_record_request_client_response; -typedef struct wire_cst_record_request_ffi_context_v_1 { +typedef struct wire_cst_record_request_ffi_v_1_context { struct wire_cst_request field0; - struct wire_cst_ffi_context_v_1 field1; -} wire_cst_record_request_ffi_context_v_1; + struct wire_cst_ffi_v_1_context field1; +} wire_cst_record_request_ffi_v_1_context; -typedef struct wire_cst_record_request_ffi_context_v_2 { +typedef struct wire_cst_record_request_ffi_v_2_post_context { struct wire_cst_request field0; - struct wire_cst_ffi_context_v_2 field1; -} wire_cst_record_request_ffi_context_v_2; + struct wire_cst_ffi_v_2_post_context field1; +} wire_cst_record_request_ffi_v_2_post_context; + +void frbgen_payjoin_flutter_wire__crate__api__bitcoin_ffi__ffi_script_new(int64_t port_, + struct wire_cst_list_prim_u_8_loose *raw_output_script); + +void frbgen_payjoin_flutter_wire__crate__api__bitcoin_ffi__ffi_script_to_bytes(int64_t port_, + struct wire_cst_ffi_script *that); void frbgen_payjoin_flutter_wire__crate__api__io__fetch_ohttp_keys(int64_t port_, struct wire_cst_ffi_url *ohttp_relay, struct wire_cst_ffi_url *payjoin_directory); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_active_session_extract_req(int64_t port_, - struct wire_cst_ffi_active_session *that); - -WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__receive__ffi_active_session_pj_uri_builder(struct wire_cst_ffi_active_session *that); - -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_active_session_pj_url(int64_t port_, - struct wire_cst_ffi_active_session *that); - -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_active_session_process_res(int64_t port_, - struct wire_cst_ffi_active_session *that, - struct wire_cst_list_prim_u_8_loose *body, - struct wire_cst_client_response *ctx); - -WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__receive__ffi_active_session_public_key(struct wire_cst_ffi_active_session *that); +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_input_pair_new(int64_t port_, + struct wire_cst_tx_in *txin, + struct wire_cst_psbt_input *psbtin); void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_maybe_inputs_owned_check_inputs_not_owned(int64_t port_, struct wire_cst_ffi_maybe_inputs_owned *that, @@ -317,18 +311,23 @@ void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_maybe_inputs_seen_che struct wire_cst_ffi_maybe_inputs_seen *that, const void *is_known); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_maybe_mixed_input_scripts_check_no_mixed_input_scripts(int64_t port_, - struct wire_cst_ffi_maybe_mixed_input_scripts *that); - void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_outputs_unknown_identify_receiver_outputs(int64_t port_, struct wire_cst_ffi_outputs_unknown *that, const void *is_receiver_output); +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_extract_v1_req(int64_t port_, + struct wire_cst_ffi_payjoin_proposal *that); + +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_extract_v2_req(int64_t port_, + struct wire_cst_ffi_payjoin_proposal *that); + void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_is_output_substitution_disabled(int64_t port_, struct wire_cst_ffi_payjoin_proposal *that); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_owned_vouts(int64_t port_, - struct wire_cst_ffi_payjoin_proposal *that); +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_process_res(int64_t port_, + struct wire_cst_ffi_payjoin_proposal *that, + struct wire_cst_list_prim_u_8_loose *res, + struct wire_cst_client_response *ohttp_context); void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_psbt(int64_t port_, struct wire_cst_ffi_payjoin_proposal *that); @@ -336,39 +335,34 @@ void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_psbt void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_utxos_to_be_locked(int64_t port_, struct wire_cst_ffi_payjoin_proposal *that); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_provisional_proposal_contribute_witness_input(int64_t port_, - struct wire_cst_ffi_provisional_proposal *that, - struct wire_cst_tx_out *txo, - struct wire_cst_out_point *outpoint); - void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_provisional_proposal_finalize_proposal(int64_t port_, struct wire_cst_ffi_provisional_proposal *that, const void *process_psbt, - uint64_t *min_fee_rate_sat_per_vb); + uint64_t *min_fee_rate_sat_per_vb, + uint64_t max_fee_rate_sat_per_vb); + +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_receiver_create(int64_t port_, + struct wire_cst_list_prim_u_8_strict *address, + int32_t network, + struct wire_cst_ffi_url *directory, + struct wire_cst_ffi_ohttp_keys *ohttp_keys, + struct wire_cst_ffi_url *ohttp_relay, + uint64_t *expire_after); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_provisional_proposal_try_preserving_privacy(int64_t port_, - struct wire_cst_ffi_provisional_proposal *that, - struct wire_cst_list_record_u_64_out_point *candidate_inputs); +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_receiver_extract_req(int64_t port_, + struct wire_cst_ffi_receiver *that); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_provisional_proposal_try_substitute_receiver_output(int64_t port_, - struct wire_cst_ffi_provisional_proposal *that, - const void *generate_script); +WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__receive__ffi_receiver_id(struct wire_cst_ffi_receiver *that); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_session_initializer_extract_req(int64_t port_, - struct wire_cst_ffi_session_initializer *that); +WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__receive__ffi_receiver_pj_uri_builder(struct wire_cst_ffi_receiver *that); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_session_initializer_new(int64_t port_, - struct wire_cst_list_prim_u_8_strict *address, - uint64_t *expire_after, - int32_t network, - struct wire_cst_ffi_url *directory, - struct wire_cst_ffi_ohttp_keys *ohttp_keys, - struct wire_cst_ffi_url *ohttp_relay); +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_receiver_pj_url(int64_t port_, + struct wire_cst_ffi_receiver *that); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_session_initializer_process_res(int64_t port_, - struct wire_cst_ffi_session_initializer *that, - struct wire_cst_list_prim_u_8_loose *body, - struct wire_cst_client_response *ctx); +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_receiver_process_res(int64_t port_, + struct wire_cst_ffi_receiver *that, + struct wire_cst_list_prim_u_8_loose *body, + struct wire_cst_client_response *ctx); void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_unchecked_proposal_assume_interactive_receiver(int64_t port_, struct wire_cst_ffi_unchecked_proposal *that); @@ -381,139 +375,93 @@ void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_unchecked_proposal_ch void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_unchecked_proposal_extract_tx_to_schedule_broadcast(int64_t port_, struct wire_cst_ffi_unchecked_proposal *that); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_unchecked_proposal_from_request(int64_t port_, - struct wire_cst_list_prim_u_8_loose *body, - struct wire_cst_list_prim_u_8_strict *query, - struct wire_cst_headers *headers); - -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_maybe_inputs_owned_check_inputs_not_owned(int64_t port_, - struct wire_cst_ffi_v_2_maybe_inputs_owned *that, - const void *is_owned); - -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_maybe_inputs_seen_check_no_inputs_seen_before(int64_t port_, - struct wire_cst_ffi_v_2_maybe_inputs_seen *that, - const void *is_known); - -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_maybe_mixed_input_scripts_check_no_mixed_input_scripts(int64_t port_, - struct wire_cst_ffi_v_2_maybe_mixed_input_scripts *that); +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_inputs_commit_inputs(int64_t port_, + struct wire_cst_ffi_wants_inputs *that); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_outputs_unknown_identify_receiver_outputs(int64_t port_, - struct wire_cst_ffi_v_2_outputs_unknown *that, - const void *is_receiver_output); +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_inputs_contribute_inputs(int64_t port_, + struct wire_cst_ffi_wants_inputs *that, + struct wire_cst_list_ffi_input_pair *replacement_inputs); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_extract_v1_req(int64_t port_, - struct wire_cst_ffi_v_2_payjoin_proposal *that); +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_inputs_try_preserving_privacy(int64_t port_, + struct wire_cst_ffi_wants_inputs *that, + struct wire_cst_list_ffi_input_pair *candidate_inputs); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_extract_v2_req(int64_t port_, - struct wire_cst_ffi_v_2_payjoin_proposal *that); +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_outputs_commit_outputs(int64_t port_, + struct wire_cst_ffi_wants_outputs *that); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_is_output_substitution_disabled(int64_t port_, - struct wire_cst_ffi_v_2_payjoin_proposal *that); +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_outputs_is_output_substitution_disabled(int64_t port_, + struct wire_cst_ffi_wants_outputs *that); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_owned_vouts(int64_t port_, - struct wire_cst_ffi_v_2_payjoin_proposal *that); +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_outputs_replace_receiver_outputs(int64_t port_, + struct wire_cst_ffi_wants_outputs *that, + struct wire_cst_list_tx_out *replacement_outputs, + struct wire_cst_ffi_script *drain_script); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_process_res(int64_t port_, - struct wire_cst_ffi_v_2_payjoin_proposal *that, - struct wire_cst_list_prim_u_8_loose *res, - struct wire_cst_client_response *ohttp_context); +void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_outputs_substitute_receiver_script(int64_t port_, + struct wire_cst_ffi_wants_outputs *that, + struct wire_cst_ffi_script *output_script); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_psbt(int64_t port_, - struct wire_cst_ffi_v_2_payjoin_proposal *that); +void frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_builder_always_disable_output_substitution(int64_t port_, + struct wire_cst_ffi_sender_builder *that, + bool disable); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_utxos_to_be_locked(int64_t port_, - struct wire_cst_ffi_v_2_payjoin_proposal *that); +void frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_builder_build_non_incentivizing(int64_t port_, + struct wire_cst_ffi_sender_builder *that, + uint64_t min_fee_rate); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_provisional_proposal_contribute_witness_input(int64_t port_, - struct wire_cst_ffi_v_2_provisional_proposal *that, - struct wire_cst_tx_out *txo, - struct wire_cst_out_point *outpoint); +void frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_builder_build_recommended(int64_t port_, + struct wire_cst_ffi_sender_builder *that, + uint64_t min_fee_rate); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_provisional_proposal_finalize_proposal(int64_t port_, - struct wire_cst_ffi_v_2_provisional_proposal *that, - const void *process_psbt, - uint64_t *min_fee_rate_sat_per_vb); +void frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_builder_build_with_additional_fee(int64_t port_, + struct wire_cst_ffi_sender_builder *that, + uint64_t max_fee_contribution, + uint8_t *change_index, + uint64_t min_fee_rate, + bool clamp_fee_contribution); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_provisional_proposal_is_output_substitution_disabled(int64_t port_, - struct wire_cst_ffi_v_2_provisional_proposal *that); +void frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_builder_from_psbt_and_uri(int64_t port_, + struct wire_cst_list_prim_u_8_strict *psbt_base64, + struct wire_cst_ffi_pj_uri *pj_uri); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_provisional_proposal_try_preserving_privacy(int64_t port_, - struct wire_cst_ffi_v_2_provisional_proposal *that, - struct wire_cst_list_record_u_64_out_point *candidate_inputs); +void frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_extract_v1(int64_t port_, + struct wire_cst_ffi_sender *that); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_provisional_proposal_try_substitute_receiver_output(int64_t port_, - struct wire_cst_ffi_v_2_provisional_proposal *that, - const void *generate_script); +void frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_extract_v2(int64_t port_, + struct wire_cst_ffi_sender *that, + struct wire_cst_ffi_url *ohttp_proxy_url); -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_unchecked_proposal_assume_interactive_receiver(int64_t port_, - struct wire_cst_ffi_v_2_unchecked_proposal *that); - -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_unchecked_proposal_check_broadcast_suitability(int64_t port_, - struct wire_cst_ffi_v_2_unchecked_proposal *that, - uint64_t *min_fee_rate, - const void *can_broadcast); - -void frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_unchecked_proposal_extract_tx_to_schedule_broadcast(int64_t port_, - struct wire_cst_ffi_v_2_unchecked_proposal *that); - -void frbgen_payjoin_flutter_wire__crate__api__send__ffi_context_v_1_process_response(int64_t port_, - struct wire_cst_ffi_context_v_1 *that, - struct wire_cst_list_prim_u_8_loose *response); - -void frbgen_payjoin_flutter_wire__crate__api__send__ffi_context_v_2_process_response(int64_t port_, - struct wire_cst_ffi_context_v_2 *that, +void frbgen_payjoin_flutter_wire__crate__api__send__ffi_v_1_context_process_response(int64_t port_, + struct wire_cst_ffi_v_1_context *that, struct wire_cst_list_prim_u_8_loose *response); -void frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_builder_always_disable_output_substitution(int64_t port_, - struct wire_cst_ffi_request_builder *that, - bool disable); - -void frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_builder_build_non_incentivizing(int64_t port_, - struct wire_cst_ffi_request_builder *that, - uint64_t min_fee_rate); - -void frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_builder_build_recommended(int64_t port_, - struct wire_cst_ffi_request_builder *that, - uint64_t min_fee_rate); - -void frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_builder_build_with_additional_fee(int64_t port_, - struct wire_cst_ffi_request_builder *that, - uint64_t max_fee_contribution, - uint8_t *change_index, - uint64_t min_fee_rate, - bool clamp_fee_contribution); +void frbgen_payjoin_flutter_wire__crate__api__send__ffi_v_2_get_context_extract_req(int64_t port_, + struct wire_cst_ffi_v_2_get_context *that, + struct wire_cst_ffi_url *ohttp_relay); -void frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_builder_from_psbt_and_uri(int64_t port_, - struct wire_cst_list_prim_u_8_strict *psbt_base64, - struct wire_cst_ffi_pj_uri *pj_uri); +void frbgen_payjoin_flutter_wire__crate__api__send__ffi_v_2_get_context_process_response(int64_t port_, + struct wire_cst_ffi_v_2_get_context *that, + struct wire_cst_list_prim_u_8_loose *response, + struct wire_cst_client_response *ohttp_ctx); -void frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_context_extract_v1(int64_t port_, - struct wire_cst_ffi_request_context *that); - -void frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_context_extract_v2(int64_t port_, - struct wire_cst_ffi_request_context *that, - struct wire_cst_ffi_url *ohttp_proxy_url); +void frbgen_payjoin_flutter_wire__crate__api__send__ffi_v_2_post_context_process_response(int64_t port_, + struct wire_cst_ffi_v_2_post_context *that, + struct wire_cst_list_prim_u_8_loose *response); void frbgen_payjoin_flutter_wire__crate__api__uri__ffi_ohttp_keys_decode(int64_t port_, struct wire_cst_list_prim_u_8_loose *bytes); WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_address(struct wire_cst_ffi_pj_uri *that); -WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_amount(struct wire_cst_ffi_pj_uri *that); +WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_amount_sats(struct wire_cst_ffi_pj_uri *that); WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_as_string(struct wire_cst_ffi_pj_uri *that); -WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_builder_amount(struct wire_cst_ffi_pj_uri_builder *that, - uint64_t amount); +WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_builder_amount_sats(struct wire_cst_ffi_pj_uri_builder *that, + uint64_t amount); WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_builder_build(struct wire_cst_ffi_pj_uri_builder *that); -void frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_builder_create(int64_t port_, - struct wire_cst_list_prim_u_8_strict *address, - struct wire_cst_ffi_url *pj, - struct wire_cst_ffi_ohttp_keys *ohttp_keys, - uint64_t *expiry); - WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_builder_label(struct wire_cst_ffi_pj_uri_builder *that, struct wire_cst_list_prim_u_8_strict *label); @@ -525,103 +473,91 @@ WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_bu WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_address(struct wire_cst_ffi_uri *that); -WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_amount(struct wire_cst_ffi_uri *that); +WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_amount_sats(struct wire_cst_ffi_uri *that); WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_as_string(struct wire_cst_ffi_uri *that); WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_check_pj_supported(struct wire_cst_ffi_uri *that); -WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_from_str(struct wire_cst_list_prim_u_8_strict *uri); +WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_parse(struct wire_cst_list_prim_u_8_strict *uri); WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_url_as_string(struct wire_cst_ffi_url *that); -WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_url_from_str(struct wire_cst_list_prim_u_8_strict *url); +WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_url_parse(struct wire_cst_list_prim_u_8_strict *url); WireSyncRust2DartDco frbgen_payjoin_flutter_wire__crate__api__uri__ffi_url_query(struct wire_cst_ffi_url *that); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_Arcpayjoin_ffireceivev2V2PayjoinProposal(const void *ptr); - -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_Arcpayjoin_ffireceivev2V2PayjoinProposal(const void *ptr); - -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_Arcpayjoin_ffisendv1ContextV1(const void *ptr); - -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_Arcpayjoin_ffisendv1ContextV1(const void *ptr); - -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_Arcpayjoin_ffisendv2ContextV2(const void *ptr); - -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_Arcpayjoin_ffisendv2ContextV2(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_bitcoin_ffiScript(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1MaybeInputsOwned(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_bitcoin_ffiScript(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1MaybeInputsOwned(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffiOhttpKeys(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1MaybeInputsSeen(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffiOhttpKeys(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1MaybeInputsSeen(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffiUrl(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1MaybeMixedInputScripts(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffiUrl(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1MaybeMixedInputScripts(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveInputPair(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1OutputsUnknown(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveInputPair(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1OutputsUnknown(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveMaybeInputsOwned(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1PayjoinProposal(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveMaybeInputsOwned(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1PayjoinProposal(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveMaybeInputsSeen(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1ProvisionalProposal(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveMaybeInputsSeen(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1ProvisionalProposal(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveOutputsUnknown(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1UncheckedProposal(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveOutputsUnknown(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1UncheckedProposal(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivePayjoinProposal(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2ActiveSession(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivePayjoinProposal(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2ActiveSession(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveProvisionalProposal(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2SessionInitializer(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveProvisionalProposal(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2SessionInitializer(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveReceiver(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2V2MaybeInputsOwned(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveReceiver(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2V2MaybeInputsOwned(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveUncheckedProposal(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2V2MaybeInputsSeen(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveUncheckedProposal(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2V2MaybeInputsSeen(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveWantsInputs(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2V2MaybeMixedInputScripts(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveWantsInputs(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2V2MaybeMixedInputScripts(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveWantsOutputs(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2V2OutputsUnknown(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveWantsOutputs(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2V2OutputsUnknown(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendSender(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2V2ProvisionalProposal(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendSender(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2V2ProvisionalProposal(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendSenderBuilder(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2V2UncheckedProposal(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendSenderBuilder(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2V2UncheckedProposal(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendV1Context(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendv1RequestBuilder(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendV1Context(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendv1RequestBuilder(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendV2GetContext(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendv1RequestContext(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendV2GetContext(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendv1RequestContext(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendV2PostContext(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffitypesOhttpKeys(const void *ptr); - -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffitypesOhttpKeys(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendV2PostContext(const void *ptr); void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffiuriPjUri(const void *ptr); @@ -635,30 +571,16 @@ void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_f void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffiuriUri(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffiuriUrl(const void *ptr); - -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffiuriUrl(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_stdsyncMutexcoreoptionOptionpayjoin_ffiClientResponse(const void *ptr); -void frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_stdsyncMutexcoreoptionOptionohttpClientResponse(const void *ptr); - -void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_stdsyncMutexcoreoptionOptionohttpClientResponse(const void *ptr); +void frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_stdsyncMutexcoreoptionOptionpayjoin_ffiClientResponse(const void *ptr); struct wire_cst_client_response *frbgen_payjoin_flutter_cst_new_box_autoadd_client_response(void); -double *frbgen_payjoin_flutter_cst_new_box_autoadd_f_64(double value); - -struct wire_cst_ffi_active_session *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_active_session(void); - -struct wire_cst_ffi_context_v_1 *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_context_v_1(void); - -struct wire_cst_ffi_context_v_2 *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_context_v_2(void); - struct wire_cst_ffi_maybe_inputs_owned *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_maybe_inputs_owned(void); struct wire_cst_ffi_maybe_inputs_seen *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_maybe_inputs_seen(void); -struct wire_cst_ffi_maybe_mixed_input_scripts *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_maybe_mixed_input_scripts(void); - struct wire_cst_ffi_ohttp_keys *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_ohttp_keys(void); struct wire_cst_ffi_outputs_unknown *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_outputs_unknown(void); @@ -671,11 +593,13 @@ struct wire_cst_ffi_pj_uri_builder *frbgen_payjoin_flutter_cst_new_box_autoadd_f struct wire_cst_ffi_provisional_proposal *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_provisional_proposal(void); -struct wire_cst_ffi_request_builder *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_request_builder(void); +struct wire_cst_ffi_receiver *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_receiver(void); -struct wire_cst_ffi_request_context *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_request_context(void); +struct wire_cst_ffi_script *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_script(void); -struct wire_cst_ffi_session_initializer *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_session_initializer(void); +struct wire_cst_ffi_sender *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_sender(void); + +struct wire_cst_ffi_sender_builder *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_sender_builder(void); struct wire_cst_ffi_unchecked_proposal *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_unchecked_proposal(void); @@ -683,23 +607,19 @@ struct wire_cst_ffi_uri *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_uri(void struct wire_cst_ffi_url *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_url(void); -struct wire_cst_ffi_v_2_maybe_inputs_owned *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_maybe_inputs_owned(void); - -struct wire_cst_ffi_v_2_maybe_inputs_seen *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_maybe_inputs_seen(void); +struct wire_cst_ffi_v_1_context *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_1_context(void); -struct wire_cst_ffi_v_2_maybe_mixed_input_scripts *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_maybe_mixed_input_scripts(void); +struct wire_cst_ffi_v_2_get_context *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_get_context(void); -struct wire_cst_ffi_v_2_outputs_unknown *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_outputs_unknown(void); +struct wire_cst_ffi_v_2_post_context *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_post_context(void); -struct wire_cst_ffi_v_2_payjoin_proposal *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_payjoin_proposal(void); +struct wire_cst_ffi_wants_inputs *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_wants_inputs(void); -struct wire_cst_ffi_v_2_provisional_proposal *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_provisional_proposal(void); +struct wire_cst_ffi_wants_outputs *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_wants_outputs(void); -struct wire_cst_ffi_v_2_unchecked_proposal *frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_unchecked_proposal(void); +struct wire_cst_psbt_input *frbgen_payjoin_flutter_cst_new_box_autoadd_psbt_input(void); -struct wire_cst_headers *frbgen_payjoin_flutter_cst_new_box_autoadd_headers(void); - -struct wire_cst_out_point *frbgen_payjoin_flutter_cst_new_box_autoadd_out_point(void); +struct wire_cst_tx_in *frbgen_payjoin_flutter_cst_new_box_autoadd_tx_in(void); struct wire_cst_tx_out *frbgen_payjoin_flutter_cst_new_box_autoadd_tx_out(void); @@ -707,179 +627,152 @@ uint64_t *frbgen_payjoin_flutter_cst_new_box_autoadd_u_64(uint64_t value); uint8_t *frbgen_payjoin_flutter_cst_new_box_autoadd_u_8(uint8_t value); -struct wire_cst_list_out_point *frbgen_payjoin_flutter_cst_new_list_out_point(int32_t len); +struct wire_cst_list_ffi_input_pair *frbgen_payjoin_flutter_cst_new_list_ffi_input_pair(int32_t len); -struct wire_cst_list_prim_u_64_strict *frbgen_payjoin_flutter_cst_new_list_prim_u_64_strict(int32_t len); +struct wire_cst_list_list_prim_u_8_strict *frbgen_payjoin_flutter_cst_new_list_list_prim_u_8_strict(int32_t len); + +struct wire_cst_list_out_point *frbgen_payjoin_flutter_cst_new_list_out_point(int32_t len); struct wire_cst_list_prim_u_8_loose *frbgen_payjoin_flutter_cst_new_list_prim_u_8_loose(int32_t len); struct wire_cst_list_prim_u_8_strict *frbgen_payjoin_flutter_cst_new_list_prim_u_8_strict(int32_t len); -struct wire_cst_list_record_string_string *frbgen_payjoin_flutter_cst_new_list_record_string_string(int32_t len); - -struct wire_cst_list_record_u_64_out_point *frbgen_payjoin_flutter_cst_new_list_record_u_64_out_point(int32_t len); +struct wire_cst_list_tx_out *frbgen_payjoin_flutter_cst_new_list_tx_out(int32_t len); static int64_t dummy_method_to_enforce_bundling(void) { int64_t dummy_var = 0; dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_client_response); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_f_64); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_active_session); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_context_v_1); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_context_v_2); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_maybe_inputs_owned); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_maybe_inputs_seen); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_maybe_mixed_input_scripts); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_ohttp_keys); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_outputs_unknown); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_payjoin_proposal); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_pj_uri); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_pj_uri_builder); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_provisional_proposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_request_builder); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_request_context); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_session_initializer); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_receiver); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_script); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_sender); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_sender_builder); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_unchecked_proposal); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_uri); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_url); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_maybe_inputs_owned); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_maybe_inputs_seen); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_maybe_mixed_input_scripts); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_outputs_unknown); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_payjoin_proposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_provisional_proposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_unchecked_proposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_headers); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_out_point); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_1_context); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_get_context); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_v_2_post_context); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_wants_inputs); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_ffi_wants_outputs); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_psbt_input); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_tx_in); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_tx_out); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_u_64); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_box_autoadd_u_8); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_list_ffi_input_pair); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_list_list_prim_u_8_strict); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_list_out_point); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_list_prim_u_64_strict); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_list_prim_u_8_loose); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_list_prim_u_8_strict); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_list_record_string_string); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_list_record_u_64_out_point); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_Arcpayjoin_ffireceivev2V2PayjoinProposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_Arcpayjoin_ffisendv1ContextV1); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_Arcpayjoin_ffisendv2ContextV2); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1MaybeInputsOwned); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1MaybeInputsSeen); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1MaybeMixedInputScripts); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1OutputsUnknown); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1PayjoinProposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1ProvisionalProposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev1UncheckedProposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2ActiveSession); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2SessionInitializer); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2V2MaybeInputsOwned); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2V2MaybeInputsSeen); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2V2MaybeMixedInputScripts); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2V2OutputsUnknown); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2V2ProvisionalProposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivev2V2UncheckedProposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendv1RequestBuilder); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendv1RequestContext); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffitypesOhttpKeys); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_cst_new_list_tx_out); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_bitcoin_ffiScript); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffiOhttpKeys); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffiUrl); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveInputPair); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveMaybeInputsOwned); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveMaybeInputsSeen); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveOutputsUnknown); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceivePayjoinProposal); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveProvisionalProposal); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveReceiver); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveUncheckedProposal); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveWantsInputs); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffireceiveWantsOutputs); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendSender); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendSenderBuilder); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendV1Context); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendV2GetContext); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffisendV2PostContext); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffiuriPjUri); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffiuriPjUriBuilder); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffiuriUri); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_payjoin_ffiuriUrl); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_stdsyncMutexcoreoptionOptionohttpClientResponse); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_Arcpayjoin_ffireceivev2V2PayjoinProposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_Arcpayjoin_ffisendv1ContextV1); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_Arcpayjoin_ffisendv2ContextV2); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1MaybeInputsOwned); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1MaybeInputsSeen); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1MaybeMixedInputScripts); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1OutputsUnknown); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1PayjoinProposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1ProvisionalProposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev1UncheckedProposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2ActiveSession); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2SessionInitializer); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2V2MaybeInputsOwned); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2V2MaybeInputsSeen); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2V2MaybeMixedInputScripts); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2V2OutputsUnknown); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2V2ProvisionalProposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivev2V2UncheckedProposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendv1RequestBuilder); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendv1RequestContext); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffitypesOhttpKeys); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_decrement_strong_count_RustOpaque_stdsyncMutexcoreoptionOptionpayjoin_ffiClientResponse); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_bitcoin_ffiScript); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffiOhttpKeys); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffiUrl); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveInputPair); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveMaybeInputsOwned); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveMaybeInputsSeen); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveOutputsUnknown); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceivePayjoinProposal); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveProvisionalProposal); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveReceiver); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveUncheckedProposal); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveWantsInputs); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffireceiveWantsOutputs); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendSender); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendSenderBuilder); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendV1Context); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendV2GetContext); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffisendV2PostContext); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffiuriPjUri); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffiuriPjUriBuilder); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffiuriUri); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_payjoin_ffiuriUrl); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_stdsyncMutexcoreoptionOptionohttpClientResponse); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_rust_arc_increment_strong_count_RustOpaque_stdsyncMutexcoreoptionOptionpayjoin_ffiClientResponse); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__bitcoin_ffi__ffi_script_new); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__bitcoin_ffi__ffi_script_to_bytes); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__io__fetch_ohttp_keys); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_active_session_extract_req); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_active_session_pj_uri_builder); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_active_session_pj_url); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_active_session_process_res); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_active_session_public_key); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_input_pair_new); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_maybe_inputs_owned_check_inputs_not_owned); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_maybe_inputs_seen_check_no_inputs_seen_before); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_maybe_mixed_input_scripts_check_no_mixed_input_scripts); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_outputs_unknown_identify_receiver_outputs); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_extract_v1_req); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_extract_v2_req); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_is_output_substitution_disabled); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_owned_vouts); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_process_res); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_psbt); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_payjoin_proposal_utxos_to_be_locked); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_provisional_proposal_contribute_witness_input); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_provisional_proposal_finalize_proposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_provisional_proposal_try_preserving_privacy); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_provisional_proposal_try_substitute_receiver_output); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_session_initializer_extract_req); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_session_initializer_new); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_session_initializer_process_res); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_receiver_create); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_receiver_extract_req); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_receiver_id); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_receiver_pj_uri_builder); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_receiver_pj_url); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_receiver_process_res); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_unchecked_proposal_assume_interactive_receiver); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_unchecked_proposal_check_broadcast_suitability); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_unchecked_proposal_extract_tx_to_schedule_broadcast); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_unchecked_proposal_from_request); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_maybe_inputs_owned_check_inputs_not_owned); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_maybe_inputs_seen_check_no_inputs_seen_before); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_maybe_mixed_input_scripts_check_no_mixed_input_scripts); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_outputs_unknown_identify_receiver_outputs); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_extract_v1_req); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_extract_v2_req); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_is_output_substitution_disabled); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_owned_vouts); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_process_res); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_psbt); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_payjoin_proposal_utxos_to_be_locked); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_provisional_proposal_contribute_witness_input); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_provisional_proposal_finalize_proposal); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_provisional_proposal_is_output_substitution_disabled); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_provisional_proposal_try_preserving_privacy); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_provisional_proposal_try_substitute_receiver_output); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_unchecked_proposal_assume_interactive_receiver); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_unchecked_proposal_check_broadcast_suitability); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_v_2_unchecked_proposal_extract_tx_to_schedule_broadcast); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_context_v_1_process_response); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_context_v_2_process_response); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_builder_always_disable_output_substitution); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_builder_build_non_incentivizing); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_builder_build_recommended); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_builder_build_with_additional_fee); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_builder_from_psbt_and_uri); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_context_extract_v1); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_request_context_extract_v2); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_inputs_commit_inputs); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_inputs_contribute_inputs); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_inputs_try_preserving_privacy); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_outputs_commit_outputs); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_outputs_is_output_substitution_disabled); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_outputs_replace_receiver_outputs); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__receive__ffi_wants_outputs_substitute_receiver_script); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_builder_always_disable_output_substitution); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_builder_build_non_incentivizing); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_builder_build_recommended); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_builder_build_with_additional_fee); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_builder_from_psbt_and_uri); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_extract_v1); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_sender_extract_v2); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_v_1_context_process_response); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_v_2_get_context_extract_req); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_v_2_get_context_process_response); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__send__ffi_v_2_post_context_process_response); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_ohttp_keys_decode); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_address); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_amount); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_amount_sats); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_as_string); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_builder_amount); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_builder_amount_sats); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_builder_build); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_builder_create); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_builder_label); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_builder_message); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_pj_uri_builder_pjos); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_address); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_amount); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_amount_sats); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_as_string); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_check_pj_supported); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_from_str); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_uri_parse); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_url_as_string); - dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_url_from_str); + dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_url_parse); dummy_var ^= ((int64_t) (void*) frbgen_payjoin_flutter_wire__crate__api__uri__ffi_url_query); dummy_var ^= ((int64_t) (void*) store_dart_post_cobject); return dummy_var; diff --git a/lib/bitcoin_ffi.dart b/lib/bitcoin_ffi.dart new file mode 100644 index 0000000..920219c --- /dev/null +++ b/lib/bitcoin_ffi.dart @@ -0,0 +1,19 @@ +import 'dart:async'; + +import 'src/exceptions.dart'; +import 'src/generated/api/bitcoin_ffi.dart'; +import 'src/generated/utils/error.dart' as error; + +class Script extends FfiScript { + Script._({required super.field0}); + + static Future