diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 732be77..403e2bc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,9 +2,9 @@ name: CI
on:
push:
- branches: [ main, "**" ]
+ branches: [main, "**"]
pull_request:
- branches: [ main ]
+ branches: [main]
jobs:
build-and-test:
@@ -15,8 +15,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- with:
- submodules: recursive
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
@@ -29,7 +27,7 @@ jobs:
- name: Setup Dart
uses: dart-lang/setup-dart@v1
with:
- sdk: "3.9.2"
+ sdk: "3.10.0"
- name: Install lipo (macOS)
if: matrix.os == 'macos-latest'
@@ -52,10 +50,10 @@ jobs:
run: flutter pub get
- name: Format check
- run: dart format --output=none --set-exit-if-changed lib test examples bdk_demo/lib bdk_demo/test
+ run: dart format --output=none --set-exit-if-changed lib test example bdk_demo/lib bdk_demo/test
- name: Analyze
- run: dart analyze --fatal-infos --fatal-warnings lib test examples
+ run: dart analyze --fatal-infos --fatal-warnings lib test example
- name: Analyze (bdk_demo)
working-directory: bdk_demo
diff --git a/.gitignore b/.gitignore
index deca7a5..3adc1b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
# Rust
/target
+native/target/
**/*.rs.bk
Cargo.lock
@@ -31,11 +32,8 @@ Thumbs.db
*.log
# Native libs built locally
-libbdkffi.*
-android/libs
-bdk_demo/android/app/src/main/jniLibs
-ios/Release/
-bdk_demo/ios/ios/
+*.dylib
+*.so
+*.dll
test_output.txt
test output.txt
-lib/bdk.dart
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index c582725..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "bdk-ffi"]
- path = bdk-ffi
- url = https://github.com/bitcoindevkit/bdk-ffi.git
diff --git a/Cargo.toml b/Cargo.toml
deleted file mode 100644
index 021c3ea..0000000
--- a/Cargo.toml
+++ /dev/null
@@ -1,45 +0,0 @@
-[package]
-name = "bdk-dart"
-version = "2.0.0-alpha.0"
-homepage = "https://bitcoindevkit.org"
-repository = "https://github.com/bitcoindevkit/bdk-dart"
-edition = "2021"
-license = "MIT OR Apache-2.0"
-
-[lib]
-crate-type = ["lib", "staticlib", "cdylib"]
-name = "bdkffi"
-path = "bdk-ffi/bdk-ffi/src/lib.rs"
-
-[[bin]]
-name = "uniffi-bindgen"
-path = "uniffi-bindgen.rs"
-
-[features]
-default = ["uniffi/cli"]
-
-[dependencies]
-bdk_wallet = { version = "2.2.0", features = ["all-keys", "keys-bip39", "rusqlite"] }
-bdk_esplora = { version = "0.22.1", default-features = false, features = ["std", "blocking", "blocking-https-rustls"] }
-bdk_electrum = { version = "0.23.2", default-features = false, features = ["use-rustls-ring"] }
-bdk_kyoto = { version = "0.15.1" }
-
-uniffi = { version = "=0.29.4" }
-uniffi-dart = { git = "https://github.com/Uniffi-Dart/uniffi-dart.git", rev = "946c5642c0521a184c4b52dcf0d203edb97f1ffc" }
-thiserror = "1.0.65"
-
-[build-dependencies]
-uniffi = { version = "=0.29.4", features = ["build"] }
-uniffi-dart = { git = "https://github.com/Uniffi-Dart/uniffi-dart.git", rev = "946c5642c0521a184c4b52dcf0d203edb97f1ffc", features = ["build"] }
-
-[dev-dependencies]
-uniffi = { version = "=0.29.4", features = ["bindgen-tests"] }
-assert_matches = "1.5.0"
-
-[profile.release-smaller]
-inherits = "release"
-opt-level = 'z' # Optimize for size.
-lto = true # Enable Link Time Optimization
-codegen-units = 1 # Reduce number of codegen units to increase optimizations.
-panic = "abort" # Abort on panic
-strip = "debuginfo" # Partially strip symbols from binary
diff --git a/README.md b/README.md
index a341d09..fbbb9f0 100644
--- a/README.md
+++ b/README.md
@@ -2,57 +2,48 @@
Dart bindings for the [Bitcoin Dev Kit (BDK)](https://bitcoindevkit.org/) wallet library.
The repo contains the sources for generating UniFFI-based bindings (`lib/bdk.dart`) and the
-`libbdkffi` native library, both of which are produced locally (they are gitignored and not
-checked into the repository) so Dart and Flutter apps can work with descriptor-based wallets,
+`libbdk_dart_ffi` native library, so Dart and Flutter apps can work with descriptor-based wallets,
key management utilities, and blockchain backends from BDK.
## Repository layout
-| Path | Purpose |
-| ---- | ------- |
-| `bdk-ffi/` | Rust sources and build scripts for the underlying `bdk-ffi` crate. |
-| `lib/` | Dart bindings (`bdk.dart`) generated locally by UniFFI-Dart. |
-| `examples/` | Standalone Dart examples that exercise common workflows. |
-| `test/` | Offline/construction/persistence tests (not full integration tests). |
-| `bdk_demo/` | Flutter sample app you can point at mobile targets once the bindings are built. |
-| `scripts/generate_bindings.sh` | Helper used to rebuild the native library and regenerate the Dart bindings. |
+| Path | Purpose |
+| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
+| `native/` | Rust sources and uniffi-dart build scripts and configs wrapping the underlying `bdk-ffi` crate to be used by the Dart build hook. |
+| `lib/` | Dart bindings (`bdk.dart`) generated by UniFFI-Dart. |
+| `example/` | Standalone Dart example to showcase, test and play with the bindings. |
+| `test/` | Offline/construction/persistence tests (not full integration tests). |
+| `bdk_demo/` | Flutter sample app you can point at mobile targets once the bindings are built. |
+| `scripts/generate_bindings.sh` | Helper used to rebuild the native library and regenerate the Dart bindings. |
## Prerequisites
To build the bindings locally you need:
-- Dart SDK 3.2 or newer (see `pubspec.yaml`).
+- Dart SDK >= 3.10 or newer (see `pubspec.yaml`).
- Rust toolchain with `cargo` and the native targets you intend to build.
- `clang`/`lld` (or equivalent platform toolchain) for producing the shared library.
- Flutter (optional) if you plan to run `bdk_demo`.
-Make sure submodules are cloned because the Rust crate lives in `bdk-ffi/`:
+### Add to your project
-```bash
-git clone --recurse-submodules https://github.com/bitcoindevkit/bdk-dart.git
-cd bdk-dart
+**Via git:**
+
+```yaml
+dependencies:
+ bdk_dart:
+ git:
+ url: https://github.com/bitcoindevkit/bdk-dart.git
+ ref: main # or specific tag
```
-## Installation
+**Via pub.dev:**
-1. Install dependencies:
- ```bash
- dart pub get
- ```
-2. Generate the Dart bindings and native binary (requires a macOS or Linux host):
- ```bash
- ./scripts/generate_bindings.sh
- ```
- The script builds `bdk-ffi`, runs the local `uniffi-bindgen` wrapper, and drops the
- resulting `libbdkffi.*` alongside the freshly generated `lib/bdk.dart`.
-3. Make sure the produced library is discoverable at runtime. For CLI usage you can export
- `LD_LIBRARY_PATH`/`DYLD_LIBRARY_PATH` or keep the binary in the same directory as your
- Dart entrypoint.
+COMING SOON: Currently not published on pub.dev yet.
## Usage
-After generating the bindings you can run the examples or consume the package from your
-own project. For instance, the `examples/network_example.dart` walkthrough shows how to:
+Check out the example in `example/main.dart` for a walkthrough of how to use the bindings to:
1. Create a new mnemonic and derive BIP84 descriptors.
2. Instantiate a wallet backed by the in-memory persister.
@@ -62,14 +53,26 @@ own project. For instance, the `examples/network_example.dart` walkthrough shows
Run it with:
```bash
-dart run examples/network_example.dart
+dart run example/main.dart
```
-When embedding in Flutter, add a path or git dependency on this package and ensure the
-native library is bundled per target platform (e.g., via `flutter_rust_bridge`-style
-build steps or platform-specific build scripts).
+The native library will be automatically built by Dart's Native Assets system.
+As a user of the package, you don't need to worry about building the native library or bindings yourself.
+Only if you want to contribute to the bindings or modify the native code yourself, you can follow the instructions in [development](#development) below.
+
+## Development
+
+### Generating bindings
+
+1. Modify the native Rust code and configuration files in `native/` as needed.
+
+2. Run the bindings generator script:
+
+ ```bash
+ bash ./scripts/generate_bindings.sh
+ ```
-## Testing
+### Testing
Once you have generated `lib/bdk.dart` and the native library locally you can execute the
Dart test suite, which covers wallet creation, persistence, offline behavior, and descriptor APIs:
@@ -82,4 +85,4 @@ dart test
The Rust crate and generated bindings are dual-licensed under MIT or Apache 2.0 per the
`license = "MIT OR Apache-2.0"` entry in `Cargo.toml`. You may choose either license when
-using the library in your project.
\ No newline at end of file
+using the library in your project.
diff --git a/bdk-ffi b/bdk-ffi
deleted file mode 160000
index c9f11de..0000000
--- a/bdk-ffi
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit c9f11de2b289d4bee9d5f880b18e0527b100b5ee
diff --git a/bdk_demo/ios/Flutter/AppFrameworkInfo.plist b/bdk_demo/ios/Flutter/AppFrameworkInfo.plist
index 7c56964..1dc6cf7 100644
--- a/bdk_demo/ios/Flutter/AppFrameworkInfo.plist
+++ b/bdk_demo/ios/Flutter/AppFrameworkInfo.plist
@@ -21,6 +21,6 @@
CFBundleVersion
1.0
MinimumOSVersion
- 12.0
+ 13.0
diff --git a/bdk_demo/ios/Flutter/Debug.xcconfig b/bdk_demo/ios/Flutter/Debug.xcconfig
index 592ceee..ec97fc6 100644
--- a/bdk_demo/ios/Flutter/Debug.xcconfig
+++ b/bdk_demo/ios/Flutter/Debug.xcconfig
@@ -1 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
diff --git a/bdk_demo/ios/Flutter/Release.xcconfig b/bdk_demo/ios/Flutter/Release.xcconfig
index 592ceee..c4855bf 100644
--- a/bdk_demo/ios/Flutter/Release.xcconfig
+++ b/bdk_demo/ios/Flutter/Release.xcconfig
@@ -1 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
diff --git a/bdk_demo/ios/Podfile b/bdk_demo/ios/Podfile
new file mode 100644
index 0000000..2dbf7d7
--- /dev/null
+++ b/bdk_demo/ios/Podfile
@@ -0,0 +1,43 @@
+# Uncomment this line to define a global platform for your project
+platform :ios, '13.0'
+
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
+
+project 'Runner', {
+ 'Debug' => :debug,
+ 'Profile' => :release,
+ 'Release' => :release,
+}
+
+def flutter_root
+ generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
+ unless File.exist?(generated_xcode_build_settings_path)
+ raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
+ end
+
+ File.foreach(generated_xcode_build_settings_path) do |line|
+ matches = line.match(/FLUTTER_ROOT\=(.*)/)
+ return matches[1].strip if matches
+ end
+ raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
+end
+
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
+
+flutter_ios_podfile_setup
+
+target 'Runner' do
+ use_frameworks!
+
+ flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
+ target 'RunnerTests' do
+ inherit! :search_paths
+ end
+end
+
+post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ flutter_additional_ios_build_settings(target)
+ end
+end
diff --git a/bdk_demo/ios/Podfile.lock b/bdk_demo/ios/Podfile.lock
new file mode 100644
index 0000000..8e007a1
--- /dev/null
+++ b/bdk_demo/ios/Podfile.lock
@@ -0,0 +1,16 @@
+PODS:
+ - Flutter (1.0.0)
+
+DEPENDENCIES:
+ - Flutter (from `Flutter`)
+
+EXTERNAL SOURCES:
+ Flutter:
+ :path: Flutter
+
+SPEC CHECKSUMS:
+ Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
+
+PODFILE CHECKSUM: 251cb053df7158f337c0712f2ab29f4e0fa474ce
+
+COCOAPODS: 1.16.2
diff --git a/bdk_demo/ios/Runner.xcodeproj/project.pbxproj b/bdk_demo/ios/Runner.xcodeproj/project.pbxproj
index 42725f3..f95e151 100644
--- a/bdk_demo/ios/Runner.xcodeproj/project.pbxproj
+++ b/bdk_demo/ios/Runner.xcodeproj/project.pbxproj
@@ -10,7 +10,9 @@
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+ 7267FE792F2335544B49B6DE /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 051F7C14E1849E9022C15AFE /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
+ 7B1A64CF96A40FF2FEB7E8D4 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78429447DD8D064999F6131C /* Pods_RunnerTests.framework */; };
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 */; };
@@ -40,13 +42,19 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 051F7C14E1849E9022C15AFE /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.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 = ""; };
+ 2ACF58D96E53774C8B32AB34 /* 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 = ""; };
+ 2DA866BBBEC6FE23F2C830BA /* 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 = ""; };
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 = ""; };
+ 562CD21D00E2298B8A61DBE7 /* 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 = ""; };
+ 723E6F053C47926D84ED588C /* 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 = ""; };
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 = ""; };
+ 78429447DD8D064999F6131C /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.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 = ""; };
@@ -55,13 +63,24 @@
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 = ""; };
+ B921216A1BBF3DCEC247541B /* 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 = ""; };
+ CDCE6A119A078C5DE8489B25 /* 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 = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
+ 1A09149109DF004A465444C9 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 7B1A64CF96A40FF2FEB7E8D4 /* Pods_RunnerTests.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 7267FE792F2335544B49B6DE /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -76,6 +95,15 @@
path = RunnerTests;
sourceTree = "";
};
+ 66B8A2169B9DA38957E28F5B /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 051F7C14E1849E9022C15AFE /* Pods_Runner.framework */,
+ 78429447DD8D064999F6131C /* Pods_RunnerTests.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
@@ -94,6 +122,8 @@
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
+ DF9AE2D7BA4D937A0D4E5B2A /* Pods */,
+ 66B8A2169B9DA38957E28F5B /* Frameworks */,
);
sourceTree = "";
};
@@ -121,6 +151,20 @@
path = Runner;
sourceTree = "";
};
+ DF9AE2D7BA4D937A0D4E5B2A /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 562CD21D00E2298B8A61DBE7 /* Pods-Runner.debug.xcconfig */,
+ B921216A1BBF3DCEC247541B /* Pods-Runner.release.xcconfig */,
+ 723E6F053C47926D84ED588C /* Pods-Runner.profile.xcconfig */,
+ CDCE6A119A078C5DE8489B25 /* Pods-RunnerTests.debug.xcconfig */,
+ 2DA866BBBEC6FE23F2C830BA /* Pods-RunnerTests.release.xcconfig */,
+ 2ACF58D96E53774C8B32AB34 /* Pods-RunnerTests.profile.xcconfig */,
+ );
+ name = Pods;
+ path = Pods;
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -128,8 +172,10 @@
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
+ E2CB103D2651042A0805D1BA /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
+ 1A09149109DF004A465444C9 /* Frameworks */,
);
buildRules = (
);
@@ -145,6 +191,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
+ 8E049878B4F3F7BF19589B67 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
@@ -238,6 +285,28 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
+ 8E049878B4F3F7BF19589B67 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-Runner-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;
+ };
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
@@ -253,6 +322,28 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
+ E2CB103D2651042A0805D1BA /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ 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;
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -346,7 +437,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@@ -379,6 +470,7 @@
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
+ baseConfigurationReference = CDCE6A119A078C5DE8489B25 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@@ -396,6 +488,7 @@
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
+ baseConfigurationReference = 2DA866BBBEC6FE23F2C830BA /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@@ -411,6 +504,7 @@
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
+ baseConfigurationReference = 2ACF58D96E53774C8B32AB34 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@@ -473,7 +567,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -524,7 +618,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
diff --git a/bdk_demo/ios/Runner.xcworkspace/contents.xcworkspacedata b/bdk_demo/ios/Runner.xcworkspace/contents.xcworkspacedata
index 1d526a1..21a3cc1 100644
--- a/bdk_demo/ios/Runner.xcworkspace/contents.xcworkspacedata
+++ b/bdk_demo/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -4,4 +4,7 @@
+
+
diff --git a/bdk_demo/lib/main.dart b/bdk_demo/lib/main.dart
index bac91e6..3781f74 100644
--- a/bdk_demo/lib/main.dart
+++ b/bdk_demo/lib/main.dart
@@ -1,32 +1,5 @@
-import 'dart:io' as io;
-
import 'package:bdk_dart/bdk.dart' as bdk;
import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
-
-const _nativeLibChannel = MethodChannel('bdk_demo/native_lib_dir');
-String? _cachedNativeLibDir;
-
-Future _ensureNativeLibraryDir() async {
- if (_cachedNativeLibDir != null) {
- io.Directory.current = io.Directory(_cachedNativeLibDir!);
- return;
- }
-
- if (io.Platform.isAndroid) {
- final dir = await _nativeLibChannel.invokeMethod('getNativeLibDir');
- if (dir == null || dir.isEmpty) {
- throw StateError('Native library directory channel returned empty path');
- }
- _cachedNativeLibDir = dir;
- } else {
- _cachedNativeLibDir = io.File(io.Platform.resolvedExecutable).parent.path;
- }
-
- if (_cachedNativeLibDir != null) {
- io.Directory.current = io.Directory(_cachedNativeLibDir!);
- }
-}
void main() {
runApp(const MyApp());
@@ -61,10 +34,8 @@ class _MyHomePageState extends State {
String? _descriptorSnippet;
String? _error;
- Future _loadBindingData() async {
+ void _showSignetNetwork() {
try {
- await _ensureNativeLibraryDir();
-
final network = bdk.Network.testnet;
final descriptor = bdk.Descriptor(
'wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/'
@@ -144,7 +115,7 @@ class _MyHomePageState extends State {
),
),
floatingActionButton: FloatingActionButton.extended(
- onPressed: _loadBindingData,
+ onPressed: _showSignetNetwork,
backgroundColor: Colors.orange,
icon: const Icon(Icons.play_circle_fill),
label: const Text('Load Dart binding'),
diff --git a/bdk_demo/pubspec.yaml b/bdk_demo/pubspec.yaml
index ad381e6..f631c13 100644
--- a/bdk_demo/pubspec.yaml
+++ b/bdk_demo/pubspec.yaml
@@ -2,7 +2,7 @@ name: bdk_demo
description: "A new Flutter project."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
-publish_to: 'none' # Remove this line if you wish to publish to pub.dev
+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
@@ -19,7 +19,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
- sdk: ^3.8.1
+ sdk: ^3.10.1
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
@@ -30,7 +30,6 @@ environment:
dependencies:
flutter:
sdk: flutter
-
bdk_dart:
path: ../
@@ -54,7 +53,6 @@ dev_dependencies:
# The following section is specific to Flutter packages.
flutter:
-
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
diff --git a/bdk_demo/test/widget_test.dart b/bdk_demo/test/widget_test.dart
index 6ba7cbe..b2a716f 100644
--- a/bdk_demo/test/widget_test.dart
+++ b/bdk_demo/test/widget_test.dart
@@ -1,30 +1,30 @@
-// This is a basic Flutter widget test.
-//
-// To perform an interaction with a widget in your test, use the WidgetTester
-// utility in the flutter_test package. For example, you can send tap and scroll
-// gestures. You can also use WidgetTester to find child widgets in the widget
-// tree, read text, and verify that the values of widget properties are correct.
-
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:bdk_demo/main.dart';
void main() {
- testWidgets('Counter increments smoke test', (WidgetTester tester) async {
+ testWidgets('BDK bindings demo test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
- // Verify that our counter starts at 0.
- expect(find.text('0'), findsOneWidget);
- expect(find.text('1'), findsNothing);
+ // Verify initial state shows the prompt message.
+ expect(find.text('Press the button to load bindings'), findsOneWidget);
+ expect(find.text('BDK bindings status'), findsOneWidget);
+ expect(find.byIcon(Icons.network_check), findsOneWidget);
+
+ // Verify the button exists.
+ expect(find.text('Load Dart binding'), findsOneWidget);
+ expect(find.byIcon(Icons.play_circle_fill), findsOneWidget);
- // Tap the '+' icon and trigger a frame.
- await tester.tap(find.byIcon(Icons.add));
+ // Tap the 'Load Dart binding' button and trigger a frame.
+ await tester.tap(find.byType(FloatingActionButton));
await tester.pump();
- // Verify that our counter has incremented.
- expect(find.text('0'), findsNothing);
- expect(find.text('1'), findsOneWidget);
+ // Verify that the network and descriptor are displayed.
+ expect(find.textContaining('Network:'), findsOneWidget);
+ expect(find.textContaining('testnet'), findsOneWidget);
+ expect(find.textContaining('Descriptor sample:'), findsOneWidget);
+ expect(find.byIcon(Icons.check_circle), findsOneWidget);
});
}
diff --git a/examples/network_example.dart b/example/main.dart
similarity index 80%
rename from examples/network_example.dart
rename to example/main.dart
index 17d74dc..ed28d92 100644
--- a/examples/network_example.dart
+++ b/example/main.dart
@@ -16,10 +16,16 @@ void main() {
// 2. Turn the mnemonic into descriptor keys for external/change paths.
final rootKey = DescriptorSecretKey(network, mnemonic, null);
- final externalDescriptor =
- Descriptor.newBip84(rootKey, KeychainKind.external_, network);
- final changeDescriptor =
- Descriptor.newBip84(rootKey, KeychainKind.internal, network);
+ final externalDescriptor = Descriptor.newBip84(
+ rootKey,
+ KeychainKind.external_,
+ network,
+ );
+ final changeDescriptor = Descriptor.newBip84(
+ rootKey,
+ KeychainKind.internal,
+ network,
+ );
stdout
..writeln('\nExternal descriptor:\n $externalDescriptor')
@@ -27,22 +33,30 @@ void main() {
// 3. Spin up an in-memory wallet using the descriptors.
final persister = Persister.newInMemory();
- final wallet =
- Wallet(externalDescriptor, changeDescriptor, network, persister, 25);
+ final wallet = Wallet(
+ externalDescriptor,
+ changeDescriptor,
+ network,
+ persister,
+ 25,
+ );
stdout.writeln('\nWallet ready on ${wallet.network()}');
// 4. Hand out the next receive address and persist the staged change.
final receive = wallet.revealNextAddress(KeychainKind.external_);
stdout.writeln(
- 'Next receive address (#${receive.index}): ${receive.address.toString()}');
+ 'Next receive address (#${receive.index}): ${receive.address.toString()}',
+ );
final persisted = wallet.persist(persister);
stdout.writeln('Persisted staged wallet changes: $persisted');
// 5. Try a quick Electrum sync to fetch history/balances.
try {
stdout.writeln('\nSyncing via Electrum (blockstream.info)…');
- final client =
- ElectrumClient('ssl://electrum.blockstream.info:60002', null);
+ final client = ElectrumClient(
+ 'ssl://electrum.blockstream.info:60002',
+ null,
+ );
final syncRequest = wallet.startSyncWithRevealedSpks().build();
final update = client.sync_(syncRequest, 100, true);
diff --git a/hook/build.dart b/hook/build.dart
new file mode 100644
index 0000000..7e7790e
--- /dev/null
+++ b/hook/build.dart
@@ -0,0 +1,10 @@
+import 'package:hooks/hooks.dart';
+import 'package:native_toolchain_rust/native_toolchain_rust.dart';
+
+void main(List args) async {
+ await build(args, (input, output) async {
+ await const RustBuilder(
+ assetName: 'uniffi:bdk_dart_ffi',
+ ).run(input: input, output: output);
+ });
+}
diff --git a/justfile b/justfile
index f5c35a5..47badbf 100644
--- a/justfile
+++ b/justfile
@@ -8,24 +8,6 @@
repo:
open https://github.com/bitcoindevkit/bdk-dart
-[group("Submodule")]
-[doc("Initialize bdk-ffi submodule to committed hash.")]
-submodule-init:
- git submodule update --init
-
-[group("Submodule")]
-[doc("Hard reset the bdk-ffi submodule to committed hash.")]
-submodule-reset:
- git submodule update --force
-
-[group("Submodule")]
-[doc("Checkout the bdk-ffi submodule to the latest commit on master.")]
-submodule-to-master:
- cd ./bdk-ffi/ \
- && git fetch origin \
- && git checkout master \
- && git pull origin master
-
[group("Dart")]
[doc("Format the Dart codebase.")]
format:
@@ -51,10 +33,9 @@ test *ARGS:
clean:
rm -rf .dart_tool/
rm -rf build/
- rm -rf target/
- rm -rf bdk-ffi/target/
+ rm -rf native/target/
rm -rf coverage/
rm -rf bdk_demo/.dart_tool/
rm -rf bdk_demo/build/
- rm -rf examples/.dart_tool/
- rm -rf examples/build/
\ No newline at end of file
+ rm -rf example/.dart_tool/
+ rm -rf example/build/
\ No newline at end of file
diff --git a/lib/README.md b/lib/README.md
deleted file mode 100644
index 9df1efd..0000000
--- a/lib/README.md
+++ /dev/null
@@ -1,126 +0,0 @@
-# Generated bindings live here
-
-The Dart bindings are produced by UniFFI-Dart and are **not** checked into
-source control. Run `scripts/generate_bindings.sh` to regenerate
-`bdk.dart` before building or testing.
-
-This placeholder file keeps the `lib/` directory present in the
-repository so that `dart` tooling can resolve the package structure.
-
-## Mobile build artifacts
-
-Mobile consumers (Flutter/Dart) can build platform-specific binaries using the
-scripts in `scripts/`.
-
-### iOS (XCFramework)
-
-1. Generate the required static libraries:
- ```bash
- ./scripts/generate_bindings.sh --target ios
- ```
-2. Package them into an XCFramework:
- ```bash
- ./scripts/build-ios-xcframework.sh
- ```
- The framework is written to `ios/Release/bdkffi.xcframework/`. Keep it there to
- reuse across multiple apps, or direct the output into a Flutter project with the
- optional flag:
-
- ```bash
- ./scripts/build-ios-xcframework.sh --output bdk_demo/ios/ios
- ```
-
-### Android (.so libraries)
-
-1. Ensure `ANDROID_NDK_ROOT` points to an Android NDK r26c (or compatible) installation. For example:
- - macOS/Linux (adjust the NDK directory as needed):
- ```bash
- export ANDROID_NDK_ROOT="$HOME/Library/Android/sdk/ndk/29.0.14206865"
- ```
- - Windows PowerShell:
- ```powershell
- $Env:ANDROID_NDK_ROOT = "C:\\Users\\\\AppData\\Local\\Android\\Sdk\\ndk\\29.0.14206865"
- ```
- (Use `setx ANDROID_NDK_ROOT ` if you want the variable persisted for future shells.)
-2. Build the shared objects:
- ```bash
- ./scripts/generate_bindings.sh --target android
- ```
-3. Stage the artifacts for inclusion in a Flutter project (make script executable or run with `bash`):
- ```bash
- chmod +x scripts/build-android.sh
- ./scripts/build-android.sh
- # or
- bash ./scripts/build-android.sh
- ```
-
- By default the script stages artifacts in `android/libs//libbdkffi.so` so the same
- slices can be reused across multiple apps; direct them into the demo’s `jniLibs`
- by passing `--output` as shown below.
-
- ```bash
- chmod +x scripts/build-android.sh
- ./scripts/build-android.sh --output bdk_demo/android/app/src/main/jniLibs
- # or, without changing permissions
- bash ./scripts/build-android.sh --output bdk_demo/android/app/src/main/jniLibs
-
-### Desktop tests (macOS/Linux)
-
-- Run the base script without a target flag before executing `dart test`:
- ```bash
- ./scripts/generate_bindings.sh
- ```
- This regenerates the Dart bindings and drops the host dynamic library
- (`libbdkffi.dylib` on macOS, `libbdkffi.so` on Linux) in the project root.
- The generated loader expects those files when running in the VM, so tests fail if you only invoke the platform-specific targets.
-
-### Verification
-
-- On iOS, confirm the framework slices:
- ```bash
- lipo -info ios/Release/bdkffi.xcframework/ios-arm64/libbdkffi.a
- lipo -info ios/Release/bdkffi.xcframework/ios-arm64_x86_64-simulator/libbdkffi.a
- ```
-- On Android, verify the shared objects:
- ```bash
- find android/libs -name "libbdkffi.so"
- ```
-
-## Flutter demo (`bdk_demo/`)
-
-Once the native artifacts are staged you can run the sample Flutter app to confirm
-the bindings load end-to-end.
-
-### Prerequisites
-
-1. Generate bindings and host libraries:
- ```bash
- ./scripts/generate_bindings.sh
- ./scripts/generate_bindings.sh --target android
- ```
-2. Stage Android shared objects into the app’s `jniLibs` (repeat per update):
- ```bash
- bash ./scripts/build-android.sh --output bdk_demo/android/app/src/main/jniLibs
- ```
-
-### Run the app
-
-```bash
-cd bdk_demo
-flutter pub get
-flutter run
-```
-
-The Android variant uses a small MethodChannel to discover where the system
-actually deploys `libbdkffi.so` (some devices nest ABI folders under
-`nativeLibraryDir`). That path is fed back into Dart so the generated loader in
-`lib/bdk.dart` can `dlopen` the correct slice.
-
-### What the demo verifies
-
-- The native dynamic library loads on-device via the generated FFI loader.
-- A BIP84 descriptor string is constructed through the Dart bindings and displayed to the UI.
-- The UI badge switches between success and error states, so you immediately see
- if the bindings failed to load or threw during descriptor creation (delete the android artifacts and rerun the app to simulate a failure).
-
-Use this screen as a smoke test after rebuilding bindings or regenerating artifacts; if it turns green and shows `Network: testnet` the demo is exercising the FFI surface successfully.
diff --git a/lib/bdk.dart b/lib/bdk.dart
new file mode 100644
index 0000000..bfd1928
--- /dev/null
+++ b/lib/bdk.dart
@@ -0,0 +1,32115 @@
+library bdk_dart;
+
+import "dart:async";
+import "dart:convert";
+import "dart:ffi";
+import "dart:io" show Platform, File, Directory;
+import "dart:isolate";
+import "dart:typed_data";
+import "package:ffi/ffi.dart";
+
+class AddressInfo {
+ final int index;
+ final Address address;
+ final KeychainKind keychain;
+ AddressInfo(this.index, this.address, this.keychain);
+}
+
+class FfiConverterAddressInfo {
+ static AddressInfo lift(RustBuffer buf) {
+ return FfiConverterAddressInfo.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final index_lifted = FfiConverterUInt32.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final index = index_lifted.value;
+ new_offset += index_lifted.bytesRead;
+ final address_lifted = Address.read(Uint8List.view(buf.buffer, new_offset));
+ final address = address_lifted.value;
+ new_offset += address_lifted.bytesRead;
+ final keychain_lifted = FfiConverterKeychainKind.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final keychain = keychain_lifted.value;
+ new_offset += keychain_lifted.bytesRead;
+ return LiftRetVal(
+ AddressInfo(index, address, keychain),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(AddressInfo value) {
+ final total_length =
+ FfiConverterUInt32.allocationSize(value.index) +
+ Address.allocationSize(value.address) +
+ FfiConverterKeychainKind.allocationSize(value.keychain) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(AddressInfo value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterUInt32.write(
+ value.index,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += Address.write(
+ value.address,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterKeychainKind.write(
+ value.keychain,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(AddressInfo value) {
+ return FfiConverterUInt32.allocationSize(value.index) +
+ Address.allocationSize(value.address) +
+ FfiConverterKeychainKind.allocationSize(value.keychain) +
+ 0;
+ }
+}
+
+class Anchor {
+ final ConfirmationBlockTime confirmationBlockTime;
+ final Txid txid;
+ Anchor(this.confirmationBlockTime, this.txid);
+}
+
+class FfiConverterAnchor {
+ static Anchor lift(RustBuffer buf) {
+ return FfiConverterAnchor.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final confirmationBlockTime_lifted = FfiConverterConfirmationBlockTime.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final confirmationBlockTime = confirmationBlockTime_lifted.value;
+ new_offset += confirmationBlockTime_lifted.bytesRead;
+ final txid_lifted = Txid.read(Uint8List.view(buf.buffer, new_offset));
+ final txid = txid_lifted.value;
+ new_offset += txid_lifted.bytesRead;
+ return LiftRetVal(
+ Anchor(confirmationBlockTime, txid),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(Anchor value) {
+ final total_length =
+ FfiConverterConfirmationBlockTime.allocationSize(
+ value.confirmationBlockTime,
+ ) +
+ Txid.allocationSize(value.txid) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(Anchor value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterConfirmationBlockTime.write(
+ value.confirmationBlockTime,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += Txid.write(
+ value.txid,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(Anchor value) {
+ return FfiConverterConfirmationBlockTime.allocationSize(
+ value.confirmationBlockTime,
+ ) +
+ Txid.allocationSize(value.txid) +
+ 0;
+ }
+}
+
+class Balance {
+ final Amount immature;
+ final Amount trustedPending;
+ final Amount untrustedPending;
+ final Amount confirmed;
+ final Amount trustedSpendable;
+ final Amount total;
+ Balance(
+ this.immature,
+ this.trustedPending,
+ this.untrustedPending,
+ this.confirmed,
+ this.trustedSpendable,
+ this.total,
+ );
+}
+
+class FfiConverterBalance {
+ static Balance lift(RustBuffer buf) {
+ return FfiConverterBalance.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final immature_lifted = Amount.read(Uint8List.view(buf.buffer, new_offset));
+ final immature = immature_lifted.value;
+ new_offset += immature_lifted.bytesRead;
+ final trustedPending_lifted = Amount.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final trustedPending = trustedPending_lifted.value;
+ new_offset += trustedPending_lifted.bytesRead;
+ final untrustedPending_lifted = Amount.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final untrustedPending = untrustedPending_lifted.value;
+ new_offset += untrustedPending_lifted.bytesRead;
+ final confirmed_lifted = Amount.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final confirmed = confirmed_lifted.value;
+ new_offset += confirmed_lifted.bytesRead;
+ final trustedSpendable_lifted = Amount.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final trustedSpendable = trustedSpendable_lifted.value;
+ new_offset += trustedSpendable_lifted.bytesRead;
+ final total_lifted = Amount.read(Uint8List.view(buf.buffer, new_offset));
+ final total = total_lifted.value;
+ new_offset += total_lifted.bytesRead;
+ return LiftRetVal(
+ Balance(
+ immature,
+ trustedPending,
+ untrustedPending,
+ confirmed,
+ trustedSpendable,
+ total,
+ ),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(Balance value) {
+ final total_length =
+ Amount.allocationSize(value.immature) +
+ Amount.allocationSize(value.trustedPending) +
+ Amount.allocationSize(value.untrustedPending) +
+ Amount.allocationSize(value.confirmed) +
+ Amount.allocationSize(value.trustedSpendable) +
+ Amount.allocationSize(value.total) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(Balance value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += Amount.write(
+ value.immature,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += Amount.write(
+ value.trustedPending,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += Amount.write(
+ value.untrustedPending,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += Amount.write(
+ value.confirmed,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += Amount.write(
+ value.trustedSpendable,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += Amount.write(
+ value.total,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(Balance value) {
+ return Amount.allocationSize(value.immature) +
+ Amount.allocationSize(value.trustedPending) +
+ Amount.allocationSize(value.untrustedPending) +
+ Amount.allocationSize(value.confirmed) +
+ Amount.allocationSize(value.trustedSpendable) +
+ Amount.allocationSize(value.total) +
+ 0;
+ }
+}
+
+class BlockId {
+ final int height;
+ final BlockHash hash;
+ BlockId(this.height, this.hash);
+}
+
+class FfiConverterBlockId {
+ static BlockId lift(RustBuffer buf) {
+ return FfiConverterBlockId.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final height_lifted = FfiConverterUInt32.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final height = height_lifted.value;
+ new_offset += height_lifted.bytesRead;
+ final hash_lifted = BlockHash.read(Uint8List.view(buf.buffer, new_offset));
+ final hash = hash_lifted.value;
+ new_offset += hash_lifted.bytesRead;
+ return LiftRetVal(BlockId(height, hash), new_offset - buf.offsetInBytes);
+ }
+
+ static RustBuffer lower(BlockId value) {
+ final total_length =
+ FfiConverterUInt32.allocationSize(value.height) +
+ BlockHash.allocationSize(value.hash) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(BlockId value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterUInt32.write(
+ value.height,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += BlockHash.write(
+ value.hash,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(BlockId value) {
+ return FfiConverterUInt32.allocationSize(value.height) +
+ BlockHash.allocationSize(value.hash) +
+ 0;
+ }
+}
+
+class CanonicalTx {
+ final Transaction transaction;
+ final ChainPosition chainPosition;
+ CanonicalTx(this.transaction, this.chainPosition);
+}
+
+class FfiConverterCanonicalTx {
+ static CanonicalTx lift(RustBuffer buf) {
+ return FfiConverterCanonicalTx.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final transaction_lifted = Transaction.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final transaction = transaction_lifted.value;
+ new_offset += transaction_lifted.bytesRead;
+ final chainPosition_lifted = FfiConverterChainPosition.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final chainPosition = chainPosition_lifted.value;
+ new_offset += chainPosition_lifted.bytesRead;
+ return LiftRetVal(
+ CanonicalTx(transaction, chainPosition),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(CanonicalTx value) {
+ final total_length =
+ Transaction.allocationSize(value.transaction) +
+ FfiConverterChainPosition.allocationSize(value.chainPosition) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(CanonicalTx value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += Transaction.write(
+ value.transaction,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterChainPosition.write(
+ value.chainPosition,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(CanonicalTx value) {
+ return Transaction.allocationSize(value.transaction) +
+ FfiConverterChainPosition.allocationSize(value.chainPosition) +
+ 0;
+ }
+}
+
+class CbfComponents {
+ final CbfClient client;
+ final CbfNode node;
+ CbfComponents(this.client, this.node);
+}
+
+class FfiConverterCbfComponents {
+ static CbfComponents lift(RustBuffer buf) {
+ return FfiConverterCbfComponents.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final client_lifted = CbfClient.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final client = client_lifted.value;
+ new_offset += client_lifted.bytesRead;
+ final node_lifted = CbfNode.read(Uint8List.view(buf.buffer, new_offset));
+ final node = node_lifted.value;
+ new_offset += node_lifted.bytesRead;
+ return LiftRetVal(
+ CbfComponents(client, node),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(CbfComponents value) {
+ final total_length =
+ CbfClient.allocationSize(value.client) +
+ CbfNode.allocationSize(value.node) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(CbfComponents value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += CbfClient.write(
+ value.client,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += CbfNode.write(
+ value.node,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(CbfComponents value) {
+ return CbfClient.allocationSize(value.client) +
+ CbfNode.allocationSize(value.node) +
+ 0;
+ }
+}
+
+class ChainChange {
+ final int height;
+ final BlockHash? hash;
+ ChainChange(this.height, this.hash);
+}
+
+class FfiConverterChainChange {
+ static ChainChange lift(RustBuffer buf) {
+ return FfiConverterChainChange.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final height_lifted = FfiConverterUInt32.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final height = height_lifted.value;
+ new_offset += height_lifted.bytesRead;
+ final hash_lifted = FfiConverterOptionalBlockHash.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final hash = hash_lifted.value;
+ new_offset += hash_lifted.bytesRead;
+ return LiftRetVal(
+ ChainChange(height, hash),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(ChainChange value) {
+ final total_length =
+ FfiConverterUInt32.allocationSize(value.height) +
+ FfiConverterOptionalBlockHash.allocationSize(value.hash) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(ChainChange value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterUInt32.write(
+ value.height,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterOptionalBlockHash.write(
+ value.hash,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(ChainChange value) {
+ return FfiConverterUInt32.allocationSize(value.height) +
+ FfiConverterOptionalBlockHash.allocationSize(value.hash) +
+ 0;
+ }
+}
+
+class Condition {
+ final int? csv;
+ final LockTime? timelock;
+ Condition(this.csv, this.timelock);
+}
+
+class FfiConverterCondition {
+ static Condition lift(RustBuffer buf) {
+ return FfiConverterCondition.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final csv_lifted = FfiConverterOptionalUInt32.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final csv = csv_lifted.value;
+ new_offset += csv_lifted.bytesRead;
+ final timelock_lifted = FfiConverterOptionalLockTime.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final timelock = timelock_lifted.value;
+ new_offset += timelock_lifted.bytesRead;
+ return LiftRetVal(Condition(csv, timelock), new_offset - buf.offsetInBytes);
+ }
+
+ static RustBuffer lower(Condition value) {
+ final total_length =
+ FfiConverterOptionalUInt32.allocationSize(value.csv) +
+ FfiConverterOptionalLockTime.allocationSize(value.timelock) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(Condition value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterOptionalUInt32.write(
+ value.csv,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterOptionalLockTime.write(
+ value.timelock,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(Condition value) {
+ return FfiConverterOptionalUInt32.allocationSize(value.csv) +
+ FfiConverterOptionalLockTime.allocationSize(value.timelock) +
+ 0;
+ }
+}
+
+class ConfirmationBlockTime {
+ final BlockId blockId;
+ final int confirmationTime;
+ ConfirmationBlockTime(this.blockId, this.confirmationTime);
+}
+
+class FfiConverterConfirmationBlockTime {
+ static ConfirmationBlockTime lift(RustBuffer buf) {
+ return FfiConverterConfirmationBlockTime.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final blockId_lifted = FfiConverterBlockId.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final blockId = blockId_lifted.value;
+ new_offset += blockId_lifted.bytesRead;
+ final confirmationTime_lifted = FfiConverterUInt64.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final confirmationTime = confirmationTime_lifted.value;
+ new_offset += confirmationTime_lifted.bytesRead;
+ return LiftRetVal(
+ ConfirmationBlockTime(blockId, confirmationTime),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(ConfirmationBlockTime value) {
+ final total_length =
+ FfiConverterBlockId.allocationSize(value.blockId) +
+ FfiConverterUInt64.allocationSize(value.confirmationTime) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(ConfirmationBlockTime value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterBlockId.write(
+ value.blockId,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterUInt64.write(
+ value.confirmationTime,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(ConfirmationBlockTime value) {
+ return FfiConverterBlockId.allocationSize(value.blockId) +
+ FfiConverterUInt64.allocationSize(value.confirmationTime) +
+ 0;
+ }
+}
+
+class Conflict {
+ final int vin;
+ final Txid txid;
+ Conflict(this.vin, this.txid);
+}
+
+class FfiConverterConflict {
+ static Conflict lift(RustBuffer buf) {
+ return FfiConverterConflict.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final vin_lifted = FfiConverterUInt32.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final vin = vin_lifted.value;
+ new_offset += vin_lifted.bytesRead;
+ final txid_lifted = Txid.read(Uint8List.view(buf.buffer, new_offset));
+ final txid = txid_lifted.value;
+ new_offset += txid_lifted.bytesRead;
+ return LiftRetVal(Conflict(vin, txid), new_offset - buf.offsetInBytes);
+ }
+
+ static RustBuffer lower(Conflict value) {
+ final total_length =
+ FfiConverterUInt32.allocationSize(value.vin) +
+ Txid.allocationSize(value.txid) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(Conflict value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterUInt32.write(
+ value.vin,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += Txid.write(
+ value.txid,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(Conflict value) {
+ return FfiConverterUInt32.allocationSize(value.vin) +
+ Txid.allocationSize(value.txid) +
+ 0;
+ }
+}
+
+class ControlBlock {
+ final Uint8List internalKey;
+ final List merkleBranch;
+ final int outputKeyParity;
+ final int leafVersion;
+ ControlBlock(
+ this.internalKey,
+ this.merkleBranch,
+ this.outputKeyParity,
+ this.leafVersion,
+ );
+}
+
+class FfiConverterControlBlock {
+ static ControlBlock lift(RustBuffer buf) {
+ return FfiConverterControlBlock.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final internalKey_lifted = FfiConverterUint8List.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final internalKey = internalKey_lifted.value;
+ new_offset += internalKey_lifted.bytesRead;
+ final merkleBranch_lifted = FfiConverterSequenceString.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final merkleBranch = merkleBranch_lifted.value;
+ new_offset += merkleBranch_lifted.bytesRead;
+ final outputKeyParity_lifted = FfiConverterUInt8.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final outputKeyParity = outputKeyParity_lifted.value;
+ new_offset += outputKeyParity_lifted.bytesRead;
+ final leafVersion_lifted = FfiConverterUInt8.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final leafVersion = leafVersion_lifted.value;
+ new_offset += leafVersion_lifted.bytesRead;
+ return LiftRetVal(
+ ControlBlock(internalKey, merkleBranch, outputKeyParity, leafVersion),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(ControlBlock value) {
+ final total_length =
+ FfiConverterUint8List.allocationSize(value.internalKey) +
+ FfiConverterSequenceString.allocationSize(value.merkleBranch) +
+ FfiConverterUInt8.allocationSize(value.outputKeyParity) +
+ FfiConverterUInt8.allocationSize(value.leafVersion) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(ControlBlock value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterUint8List.write(
+ value.internalKey,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterSequenceString.write(
+ value.merkleBranch,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterUInt8.write(
+ value.outputKeyParity,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterUInt8.write(
+ value.leafVersion,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(ControlBlock value) {
+ return FfiConverterUint8List.allocationSize(value.internalKey) +
+ FfiConverterSequenceString.allocationSize(value.merkleBranch) +
+ FfiConverterUInt8.allocationSize(value.outputKeyParity) +
+ FfiConverterUInt8.allocationSize(value.leafVersion) +
+ 0;
+ }
+}
+
+class EvictedTx {
+ final Txid txid;
+ final int evictedAt;
+ EvictedTx(this.txid, this.evictedAt);
+}
+
+class FfiConverterEvictedTx {
+ static EvictedTx lift(RustBuffer buf) {
+ return FfiConverterEvictedTx.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final txid_lifted = Txid.read(Uint8List.view(buf.buffer, new_offset));
+ final txid = txid_lifted.value;
+ new_offset += txid_lifted.bytesRead;
+ final evictedAt_lifted = FfiConverterUInt64.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final evictedAt = evictedAt_lifted.value;
+ new_offset += evictedAt_lifted.bytesRead;
+ return LiftRetVal(
+ EvictedTx(txid, evictedAt),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(EvictedTx value) {
+ final total_length =
+ Txid.allocationSize(value.txid) +
+ FfiConverterUInt64.allocationSize(value.evictedAt) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(EvictedTx value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += Txid.write(
+ value.txid,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterUInt64.write(
+ value.evictedAt,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(EvictedTx value) {
+ return Txid.allocationSize(value.txid) +
+ FfiConverterUInt64.allocationSize(value.evictedAt) +
+ 0;
+ }
+}
+
+class FinalizedPsbtResult {
+ final Psbt psbt;
+ final bool couldFinalize;
+ final List? errors;
+ FinalizedPsbtResult(this.psbt, this.couldFinalize, this.errors);
+}
+
+class FfiConverterFinalizedPsbtResult {
+ static FinalizedPsbtResult lift(RustBuffer buf) {
+ return FfiConverterFinalizedPsbtResult.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final psbt_lifted = Psbt.read(Uint8List.view(buf.buffer, new_offset));
+ final psbt = psbt_lifted.value;
+ new_offset += psbt_lifted.bytesRead;
+ final couldFinalize_lifted = FfiConverterBool.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final couldFinalize = couldFinalize_lifted.value;
+ new_offset += couldFinalize_lifted.bytesRead;
+ final errors_lifted =
+ FfiConverterOptionalSequencePsbtFinalizeException.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final errors = errors_lifted.value;
+ new_offset += errors_lifted.bytesRead;
+ return LiftRetVal(
+ FinalizedPsbtResult(psbt, couldFinalize, errors),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(FinalizedPsbtResult value) {
+ final total_length =
+ Psbt.allocationSize(value.psbt) +
+ FfiConverterBool.allocationSize(value.couldFinalize) +
+ FfiConverterOptionalSequencePsbtFinalizeException.allocationSize(
+ value.errors,
+ ) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(FinalizedPsbtResult value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += Psbt.write(
+ value.psbt,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterBool.write(
+ value.couldFinalize,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterOptionalSequencePsbtFinalizeException.write(
+ value.errors,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(FinalizedPsbtResult value) {
+ return Psbt.allocationSize(value.psbt) +
+ FfiConverterBool.allocationSize(value.couldFinalize) +
+ FfiConverterOptionalSequencePsbtFinalizeException.allocationSize(
+ value.errors,
+ ) +
+ 0;
+ }
+}
+
+class Header {
+ final int version;
+ final BlockHash prevBlockhash;
+ final TxMerkleNode merkleRoot;
+ final int time;
+ final int bits;
+ final int nonce;
+ Header(
+ this.version,
+ this.prevBlockhash,
+ this.merkleRoot,
+ this.time,
+ this.bits,
+ this.nonce,
+ );
+}
+
+class FfiConverterHeader {
+ static Header lift(RustBuffer buf) {
+ return FfiConverterHeader.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final version_lifted = FfiConverterInt32.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final version = version_lifted.value;
+ new_offset += version_lifted.bytesRead;
+ final prevBlockhash_lifted = BlockHash.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final prevBlockhash = prevBlockhash_lifted.value;
+ new_offset += prevBlockhash_lifted.bytesRead;
+ final merkleRoot_lifted = TxMerkleNode.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final merkleRoot = merkleRoot_lifted.value;
+ new_offset += merkleRoot_lifted.bytesRead;
+ final time_lifted = FfiConverterUInt32.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final time = time_lifted.value;
+ new_offset += time_lifted.bytesRead;
+ final bits_lifted = FfiConverterUInt32.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final bits = bits_lifted.value;
+ new_offset += bits_lifted.bytesRead;
+ final nonce_lifted = FfiConverterUInt32.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final nonce = nonce_lifted.value;
+ new_offset += nonce_lifted.bytesRead;
+ return LiftRetVal(
+ Header(version, prevBlockhash, merkleRoot, time, bits, nonce),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(Header value) {
+ final total_length =
+ FfiConverterInt32.allocationSize(value.version) +
+ BlockHash.allocationSize(value.prevBlockhash) +
+ TxMerkleNode.allocationSize(value.merkleRoot) +
+ FfiConverterUInt32.allocationSize(value.time) +
+ FfiConverterUInt32.allocationSize(value.bits) +
+ FfiConverterUInt32.allocationSize(value.nonce) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(Header value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterInt32.write(
+ value.version,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += BlockHash.write(
+ value.prevBlockhash,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += TxMerkleNode.write(
+ value.merkleRoot,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterUInt32.write(
+ value.time,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterUInt32.write(
+ value.bits,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterUInt32.write(
+ value.nonce,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(Header value) {
+ return FfiConverterInt32.allocationSize(value.version) +
+ BlockHash.allocationSize(value.prevBlockhash) +
+ TxMerkleNode.allocationSize(value.merkleRoot) +
+ FfiConverterUInt32.allocationSize(value.time) +
+ FfiConverterUInt32.allocationSize(value.bits) +
+ FfiConverterUInt32.allocationSize(value.nonce) +
+ 0;
+ }
+}
+
+class HeaderNotification {
+ final int height;
+ final Header header;
+ HeaderNotification(this.height, this.header);
+}
+
+class FfiConverterHeaderNotification {
+ static HeaderNotification lift(RustBuffer buf) {
+ return FfiConverterHeaderNotification.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final height_lifted = FfiConverterUInt64.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final height = height_lifted.value;
+ new_offset += height_lifted.bytesRead;
+ final header_lifted = FfiConverterHeader.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final header = header_lifted.value;
+ new_offset += header_lifted.bytesRead;
+ return LiftRetVal(
+ HeaderNotification(height, header),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(HeaderNotification value) {
+ final total_length =
+ FfiConverterUInt64.allocationSize(value.height) +
+ FfiConverterHeader.allocationSize(value.header) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(HeaderNotification value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterUInt64.write(
+ value.height,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterHeader.write(
+ value.header,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(HeaderNotification value) {
+ return FfiConverterUInt64.allocationSize(value.height) +
+ FfiConverterHeader.allocationSize(value.header) +
+ 0;
+ }
+}
+
+class IndexerChangeSet {
+ final Map lastRevealed;
+ IndexerChangeSet(this.lastRevealed);
+}
+
+class FfiConverterIndexerChangeSet {
+ static IndexerChangeSet lift(RustBuffer buf) {
+ return FfiConverterIndexerChangeSet.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final lastRevealed_lifted = FfiConverterMapDescriptorIdToUInt32.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final lastRevealed = lastRevealed_lifted.value;
+ new_offset += lastRevealed_lifted.bytesRead;
+ return LiftRetVal(
+ IndexerChangeSet(lastRevealed),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(IndexerChangeSet value) {
+ final total_length =
+ FfiConverterMapDescriptorIdToUInt32.allocationSize(value.lastRevealed) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(IndexerChangeSet value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterMapDescriptorIdToUInt32.write(
+ value.lastRevealed,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(IndexerChangeSet value) {
+ return FfiConverterMapDescriptorIdToUInt32.allocationSize(
+ value.lastRevealed,
+ ) +
+ 0;
+ }
+}
+
+class Input {
+ final Transaction? nonWitnessUtxo;
+ final TxOut? witnessUtxo;
+ final Map partialSigs;
+ final String? sighashType;
+ final Script? redeemScript;
+ final Script? witnessScript;
+ final Map bip32Derivation;
+ final Script? finalScriptSig;
+ final List? finalScriptWitness;
+ final Map ripemd160Preimages;
+ final Map sha256Preimages;
+ final Map hash160Preimages;
+ final Map hash256Preimages;
+ final Uint8List? tapKeySig;
+ final Map tapScriptSigs;
+ final Map tapScripts;
+ final Map tapKeyOrigins;
+ final String? tapInternalKey;
+ final String? tapMerkleRoot;
+ final Map proprietary;
+ final Map unknown;
+ Input(
+ this.nonWitnessUtxo,
+ this.witnessUtxo,
+ this.partialSigs,
+ this.sighashType,
+ this.redeemScript,
+ this.witnessScript,
+ this.bip32Derivation,
+ this.finalScriptSig,
+ this.finalScriptWitness,
+ this.ripemd160Preimages,
+ this.sha256Preimages,
+ this.hash160Preimages,
+ this.hash256Preimages,
+ this.tapKeySig,
+ this.tapScriptSigs,
+ this.tapScripts,
+ this.tapKeyOrigins,
+ this.tapInternalKey,
+ this.tapMerkleRoot,
+ this.proprietary,
+ this.unknown,
+ );
+}
+
+class FfiConverterInput {
+ static Input lift(RustBuffer buf) {
+ return FfiConverterInput.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final nonWitnessUtxo_lifted = FfiConverterOptionalTransaction.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final nonWitnessUtxo = nonWitnessUtxo_lifted.value;
+ new_offset += nonWitnessUtxo_lifted.bytesRead;
+ final witnessUtxo_lifted = FfiConverterOptionalTxOut.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final witnessUtxo = witnessUtxo_lifted.value;
+ new_offset += witnessUtxo_lifted.bytesRead;
+ final partialSigs_lifted = FfiConverterMapStringToUint8List.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final partialSigs = partialSigs_lifted.value;
+ new_offset += partialSigs_lifted.bytesRead;
+ final sighashType_lifted = FfiConverterOptionalString.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final sighashType = sighashType_lifted.value;
+ new_offset += sighashType_lifted.bytesRead;
+ final redeemScript_lifted = FfiConverterOptionalScript.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final redeemScript = redeemScript_lifted.value;
+ new_offset += redeemScript_lifted.bytesRead;
+ final witnessScript_lifted = FfiConverterOptionalScript.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final witnessScript = witnessScript_lifted.value;
+ new_offset += witnessScript_lifted.bytesRead;
+ final bip32Derivation_lifted = FfiConverterMapStringToKeySource.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final bip32Derivation = bip32Derivation_lifted.value;
+ new_offset += bip32Derivation_lifted.bytesRead;
+ final finalScriptSig_lifted = FfiConverterOptionalScript.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final finalScriptSig = finalScriptSig_lifted.value;
+ new_offset += finalScriptSig_lifted.bytesRead;
+ final finalScriptWitness_lifted =
+ FfiConverterOptionalSequenceUint8List.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final finalScriptWitness = finalScriptWitness_lifted.value;
+ new_offset += finalScriptWitness_lifted.bytesRead;
+ final ripemd160Preimages_lifted = FfiConverterMapStringToUint8List.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final ripemd160Preimages = ripemd160Preimages_lifted.value;
+ new_offset += ripemd160Preimages_lifted.bytesRead;
+ final sha256Preimages_lifted = FfiConverterMapStringToUint8List.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final sha256Preimages = sha256Preimages_lifted.value;
+ new_offset += sha256Preimages_lifted.bytesRead;
+ final hash160Preimages_lifted = FfiConverterMapStringToUint8List.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final hash160Preimages = hash160Preimages_lifted.value;
+ new_offset += hash160Preimages_lifted.bytesRead;
+ final hash256Preimages_lifted = FfiConverterMapStringToUint8List.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final hash256Preimages = hash256Preimages_lifted.value;
+ new_offset += hash256Preimages_lifted.bytesRead;
+ final tapKeySig_lifted = FfiConverterOptionalUint8List.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final tapKeySig = tapKeySig_lifted.value;
+ new_offset += tapKeySig_lifted.bytesRead;
+ final tapScriptSigs_lifted = FfiConverterMapTapScriptSigKeyToUint8List.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final tapScriptSigs = tapScriptSigs_lifted.value;
+ new_offset += tapScriptSigs_lifted.bytesRead;
+ final tapScripts_lifted = FfiConverterMapControlBlockToTapScriptEntry.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final tapScripts = tapScripts_lifted.value;
+ new_offset += tapScripts_lifted.bytesRead;
+ final tapKeyOrigins_lifted = FfiConverterMapStringToTapKeyOrigin.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final tapKeyOrigins = tapKeyOrigins_lifted.value;
+ new_offset += tapKeyOrigins_lifted.bytesRead;
+ final tapInternalKey_lifted = FfiConverterOptionalString.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final tapInternalKey = tapInternalKey_lifted.value;
+ new_offset += tapInternalKey_lifted.bytesRead;
+ final tapMerkleRoot_lifted = FfiConverterOptionalString.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final tapMerkleRoot = tapMerkleRoot_lifted.value;
+ new_offset += tapMerkleRoot_lifted.bytesRead;
+ final proprietary_lifted = FfiConverterMapProprietaryKeyToUint8List.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final proprietary = proprietary_lifted.value;
+ new_offset += proprietary_lifted.bytesRead;
+ final unknown_lifted = FfiConverterMapKeyToUint8List.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final unknown = unknown_lifted.value;
+ new_offset += unknown_lifted.bytesRead;
+ return LiftRetVal(
+ Input(
+ nonWitnessUtxo,
+ witnessUtxo,
+ partialSigs,
+ sighashType,
+ redeemScript,
+ witnessScript,
+ bip32Derivation,
+ finalScriptSig,
+ finalScriptWitness,
+ ripemd160Preimages,
+ sha256Preimages,
+ hash160Preimages,
+ hash256Preimages,
+ tapKeySig,
+ tapScriptSigs,
+ tapScripts,
+ tapKeyOrigins,
+ tapInternalKey,
+ tapMerkleRoot,
+ proprietary,
+ unknown,
+ ),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(Input value) {
+ final total_length =
+ FfiConverterOptionalTransaction.allocationSize(value.nonWitnessUtxo) +
+ FfiConverterOptionalTxOut.allocationSize(value.witnessUtxo) +
+ FfiConverterMapStringToUint8List.allocationSize(value.partialSigs) +
+ FfiConverterOptionalString.allocationSize(value.sighashType) +
+ FfiConverterOptionalScript.allocationSize(value.redeemScript) +
+ FfiConverterOptionalScript.allocationSize(value.witnessScript) +
+ FfiConverterMapStringToKeySource.allocationSize(value.bip32Derivation) +
+ FfiConverterOptionalScript.allocationSize(value.finalScriptSig) +
+ FfiConverterOptionalSequenceUint8List.allocationSize(
+ value.finalScriptWitness,
+ ) +
+ FfiConverterMapStringToUint8List.allocationSize(
+ value.ripemd160Preimages,
+ ) +
+ FfiConverterMapStringToUint8List.allocationSize(value.sha256Preimages) +
+ FfiConverterMapStringToUint8List.allocationSize(
+ value.hash160Preimages,
+ ) +
+ FfiConverterMapStringToUint8List.allocationSize(
+ value.hash256Preimages,
+ ) +
+ FfiConverterOptionalUint8List.allocationSize(value.tapKeySig) +
+ FfiConverterMapTapScriptSigKeyToUint8List.allocationSize(
+ value.tapScriptSigs,
+ ) +
+ FfiConverterMapControlBlockToTapScriptEntry.allocationSize(
+ value.tapScripts,
+ ) +
+ FfiConverterMapStringToTapKeyOrigin.allocationSize(
+ value.tapKeyOrigins,
+ ) +
+ FfiConverterOptionalString.allocationSize(value.tapInternalKey) +
+ FfiConverterOptionalString.allocationSize(value.tapMerkleRoot) +
+ FfiConverterMapProprietaryKeyToUint8List.allocationSize(
+ value.proprietary,
+ ) +
+ FfiConverterMapKeyToUint8List.allocationSize(value.unknown) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(Input value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterOptionalTransaction.write(
+ value.nonWitnessUtxo,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterOptionalTxOut.write(
+ value.witnessUtxo,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterMapStringToUint8List.write(
+ value.partialSigs,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterOptionalString.write(
+ value.sighashType,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterOptionalScript.write(
+ value.redeemScript,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterOptionalScript.write(
+ value.witnessScript,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterMapStringToKeySource.write(
+ value.bip32Derivation,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterOptionalScript.write(
+ value.finalScriptSig,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterOptionalSequenceUint8List.write(
+ value.finalScriptWitness,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterMapStringToUint8List.write(
+ value.ripemd160Preimages,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterMapStringToUint8List.write(
+ value.sha256Preimages,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterMapStringToUint8List.write(
+ value.hash160Preimages,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterMapStringToUint8List.write(
+ value.hash256Preimages,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterOptionalUint8List.write(
+ value.tapKeySig,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterMapTapScriptSigKeyToUint8List.write(
+ value.tapScriptSigs,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterMapControlBlockToTapScriptEntry.write(
+ value.tapScripts,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterMapStringToTapKeyOrigin.write(
+ value.tapKeyOrigins,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterOptionalString.write(
+ value.tapInternalKey,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterOptionalString.write(
+ value.tapMerkleRoot,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterMapProprietaryKeyToUint8List.write(
+ value.proprietary,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterMapKeyToUint8List.write(
+ value.unknown,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(Input value) {
+ return FfiConverterOptionalTransaction.allocationSize(
+ value.nonWitnessUtxo,
+ ) +
+ FfiConverterOptionalTxOut.allocationSize(value.witnessUtxo) +
+ FfiConverterMapStringToUint8List.allocationSize(value.partialSigs) +
+ FfiConverterOptionalString.allocationSize(value.sighashType) +
+ FfiConverterOptionalScript.allocationSize(value.redeemScript) +
+ FfiConverterOptionalScript.allocationSize(value.witnessScript) +
+ FfiConverterMapStringToKeySource.allocationSize(value.bip32Derivation) +
+ FfiConverterOptionalScript.allocationSize(value.finalScriptSig) +
+ FfiConverterOptionalSequenceUint8List.allocationSize(
+ value.finalScriptWitness,
+ ) +
+ FfiConverterMapStringToUint8List.allocationSize(
+ value.ripemd160Preimages,
+ ) +
+ FfiConverterMapStringToUint8List.allocationSize(value.sha256Preimages) +
+ FfiConverterMapStringToUint8List.allocationSize(
+ value.hash160Preimages,
+ ) +
+ FfiConverterMapStringToUint8List.allocationSize(
+ value.hash256Preimages,
+ ) +
+ FfiConverterOptionalUint8List.allocationSize(value.tapKeySig) +
+ FfiConverterMapTapScriptSigKeyToUint8List.allocationSize(
+ value.tapScriptSigs,
+ ) +
+ FfiConverterMapControlBlockToTapScriptEntry.allocationSize(
+ value.tapScripts,
+ ) +
+ FfiConverterMapStringToTapKeyOrigin.allocationSize(
+ value.tapKeyOrigins,
+ ) +
+ FfiConverterOptionalString.allocationSize(value.tapInternalKey) +
+ FfiConverterOptionalString.allocationSize(value.tapMerkleRoot) +
+ FfiConverterMapProprietaryKeyToUint8List.allocationSize(
+ value.proprietary,
+ ) +
+ FfiConverterMapKeyToUint8List.allocationSize(value.unknown) +
+ 0;
+ }
+}
+
+class Key {
+ final int typeValue;
+ final Uint8List key;
+ Key(this.typeValue, this.key);
+}
+
+class FfiConverterKey {
+ static Key lift(RustBuffer buf) {
+ return FfiConverterKey.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final typeValue_lifted = FfiConverterUInt8.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final typeValue = typeValue_lifted.value;
+ new_offset += typeValue_lifted.bytesRead;
+ final key_lifted = FfiConverterUint8List.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final key = key_lifted.value;
+ new_offset += key_lifted.bytesRead;
+ return LiftRetVal(Key(typeValue, key), new_offset - buf.offsetInBytes);
+ }
+
+ static RustBuffer lower(Key value) {
+ final total_length =
+ FfiConverterUInt8.allocationSize(value.typeValue) +
+ FfiConverterUint8List.allocationSize(value.key) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(Key value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterUInt8.write(
+ value.typeValue,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterUint8List.write(
+ value.key,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(Key value) {
+ return FfiConverterUInt8.allocationSize(value.typeValue) +
+ FfiConverterUint8List.allocationSize(value.key) +
+ 0;
+ }
+}
+
+class KeySource {
+ final String fingerprint;
+ final DerivationPath path;
+ KeySource(this.fingerprint, this.path);
+}
+
+class FfiConverterKeySource {
+ static KeySource lift(RustBuffer buf) {
+ return FfiConverterKeySource.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final fingerprint_lifted = FfiConverterString.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final fingerprint = fingerprint_lifted.value;
+ new_offset += fingerprint_lifted.bytesRead;
+ final path_lifted = DerivationPath.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final path = path_lifted.value;
+ new_offset += path_lifted.bytesRead;
+ return LiftRetVal(
+ KeySource(fingerprint, path),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(KeySource value) {
+ final total_length =
+ FfiConverterString.allocationSize(value.fingerprint) +
+ DerivationPath.allocationSize(value.path) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(KeySource value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterString.write(
+ value.fingerprint,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += DerivationPath.write(
+ value.path,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(KeySource value) {
+ return FfiConverterString.allocationSize(value.fingerprint) +
+ DerivationPath.allocationSize(value.path) +
+ 0;
+ }
+}
+
+class KeychainAndIndex {
+ final KeychainKind keychain;
+ final int index;
+ KeychainAndIndex(this.keychain, this.index);
+}
+
+class FfiConverterKeychainAndIndex {
+ static KeychainAndIndex lift(RustBuffer buf) {
+ return FfiConverterKeychainAndIndex.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final keychain_lifted = FfiConverterKeychainKind.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final keychain = keychain_lifted.value;
+ new_offset += keychain_lifted.bytesRead;
+ final index_lifted = FfiConverterUInt32.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final index = index_lifted.value;
+ new_offset += index_lifted.bytesRead;
+ return LiftRetVal(
+ KeychainAndIndex(keychain, index),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(KeychainAndIndex value) {
+ final total_length =
+ FfiConverterKeychainKind.allocationSize(value.keychain) +
+ FfiConverterUInt32.allocationSize(value.index) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(KeychainAndIndex value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterKeychainKind.write(
+ value.keychain,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterUInt32.write(
+ value.index,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(KeychainAndIndex value) {
+ return FfiConverterKeychainKind.allocationSize(value.keychain) +
+ FfiConverterUInt32.allocationSize(value.index) +
+ 0;
+ }
+}
+
+class LocalChainChangeSet {
+ final List changes;
+ LocalChainChangeSet(this.changes);
+}
+
+class FfiConverterLocalChainChangeSet {
+ static LocalChainChangeSet lift(RustBuffer buf) {
+ return FfiConverterLocalChainChangeSet.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final changes_lifted = FfiConverterSequenceChainChange.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final changes = changes_lifted.value;
+ new_offset += changes_lifted.bytesRead;
+ return LiftRetVal(
+ LocalChainChangeSet(changes),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(LocalChainChangeSet value) {
+ final total_length =
+ FfiConverterSequenceChainChange.allocationSize(value.changes) + 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(LocalChainChangeSet value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterSequenceChainChange.write(
+ value.changes,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(LocalChainChangeSet value) {
+ return FfiConverterSequenceChainChange.allocationSize(value.changes) + 0;
+ }
+}
+
+class LocalOutput {
+ final OutPoint outpoint;
+ final TxOut txout;
+ final KeychainKind keychain;
+ final bool isSpent;
+ final int derivationIndex;
+ final ChainPosition chainPosition;
+ LocalOutput(
+ this.outpoint,
+ this.txout,
+ this.keychain,
+ this.isSpent,
+ this.derivationIndex,
+ this.chainPosition,
+ );
+}
+
+class FfiConverterLocalOutput {
+ static LocalOutput lift(RustBuffer buf) {
+ return FfiConverterLocalOutput.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final outpoint_lifted = FfiConverterOutPoint.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final outpoint = outpoint_lifted.value;
+ new_offset += outpoint_lifted.bytesRead;
+ final txout_lifted = FfiConverterTxOut.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final txout = txout_lifted.value;
+ new_offset += txout_lifted.bytesRead;
+ final keychain_lifted = FfiConverterKeychainKind.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final keychain = keychain_lifted.value;
+ new_offset += keychain_lifted.bytesRead;
+ final isSpent_lifted = FfiConverterBool.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final isSpent = isSpent_lifted.value;
+ new_offset += isSpent_lifted.bytesRead;
+ final derivationIndex_lifted = FfiConverterUInt32.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final derivationIndex = derivationIndex_lifted.value;
+ new_offset += derivationIndex_lifted.bytesRead;
+ final chainPosition_lifted = FfiConverterChainPosition.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final chainPosition = chainPosition_lifted.value;
+ new_offset += chainPosition_lifted.bytesRead;
+ return LiftRetVal(
+ LocalOutput(
+ outpoint,
+ txout,
+ keychain,
+ isSpent,
+ derivationIndex,
+ chainPosition,
+ ),
+ new_offset - buf.offsetInBytes,
+ );
+ }
+
+ static RustBuffer lower(LocalOutput value) {
+ final total_length =
+ FfiConverterOutPoint.allocationSize(value.outpoint) +
+ FfiConverterTxOut.allocationSize(value.txout) +
+ FfiConverterKeychainKind.allocationSize(value.keychain) +
+ FfiConverterBool.allocationSize(value.isSpent) +
+ FfiConverterUInt32.allocationSize(value.derivationIndex) +
+ FfiConverterChainPosition.allocationSize(value.chainPosition) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(LocalOutput value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += FfiConverterOutPoint.write(
+ value.outpoint,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterTxOut.write(
+ value.txout,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterKeychainKind.write(
+ value.keychain,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterBool.write(
+ value.isSpent,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterUInt32.write(
+ value.derivationIndex,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterChainPosition.write(
+ value.chainPosition,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(LocalOutput value) {
+ return FfiConverterOutPoint.allocationSize(value.outpoint) +
+ FfiConverterTxOut.allocationSize(value.txout) +
+ FfiConverterKeychainKind.allocationSize(value.keychain) +
+ FfiConverterBool.allocationSize(value.isSpent) +
+ FfiConverterUInt32.allocationSize(value.derivationIndex) +
+ FfiConverterChainPosition.allocationSize(value.chainPosition) +
+ 0;
+ }
+}
+
+class OutPoint {
+ final Txid txid;
+ final int vout;
+ OutPoint(this.txid, this.vout);
+}
+
+class FfiConverterOutPoint {
+ static OutPoint lift(RustBuffer buf) {
+ return FfiConverterOutPoint.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal read(Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ final txid_lifted = Txid.read(Uint8List.view(buf.buffer, new_offset));
+ final txid = txid_lifted.value;
+ new_offset += txid_lifted.bytesRead;
+ final vout_lifted = FfiConverterUInt32.read(
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ final vout = vout_lifted.value;
+ new_offset += vout_lifted.bytesRead;
+ return LiftRetVal(OutPoint(txid, vout), new_offset - buf.offsetInBytes);
+ }
+
+ static RustBuffer lower(OutPoint value) {
+ final total_length =
+ Txid.allocationSize(value.txid) +
+ FfiConverterUInt32.allocationSize(value.vout) +
+ 0;
+ final buf = Uint8List(total_length);
+ write(value, buf);
+ return toRustBuffer(buf);
+ }
+
+ static int write(OutPoint value, Uint8List buf) {
+ int new_offset = buf.offsetInBytes;
+ new_offset += Txid.write(
+ value.txid,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ new_offset += FfiConverterUInt32.write(
+ value.vout,
+ Uint8List.view(buf.buffer, new_offset),
+ );
+ return new_offset - buf.offsetInBytes;
+ }
+
+ static int allocationSize(OutPoint value) {
+ return Txid.allocationSize(value.txid) +
+ FfiConverterUInt32.allocationSize(value.vout) +
+ 0;
+ }
+}
+
+class Output {
+ final Script? redeemScript;
+ final Script? witnessScript;
+ final Map bip32Derivation;
+ final String? tapInternalKey;
+ final TapTree? tapTree;
+ final Map tapKeyOrigins;
+ final Map proprietary;
+ final Map unknown;
+ Output(
+ this.redeemScript,
+ this.witnessScript,
+ this.bip32Derivation,
+ this.tapInternalKey,
+ this.tapTree,
+ this.tapKeyOrigins,
+ this.proprietary,
+ this.unknown,
+ );
+}
+
+class FfiConverterOutput {
+ static Output lift(RustBuffer buf) {
+ return FfiConverterOutput.read(buf.asUint8List()).value;
+ }
+
+ static LiftRetVal