Coder Social home page Coder Social logo

bitcoindevkit / bdk-ffi Goto Github PK

View Code? Open in Web Editor NEW
87.0 11.0 37.0 5.37 MB

Please consider this project *experimental*. But we hope to have an official release out soon.

License: Other

Rust 64.58% Kotlin 18.11% Python 4.57% Swift 9.55% Shell 2.16% Nix 0.50% Just 0.53%
rust ios swift android kotlin jvm

bdk-ffi's Introduction

Native language bindings for BDK

MIT or Apache-2.0 Licensed CI Status Rustc Version 1.61.0+ Chat on Discord

๐Ÿšจ Warning ๐Ÿšจ

The master branch of this repository is being migrated to the bdk 1.0 API and is incomplete. For production-ready libraries, use the 0.31.X releases.

Readme

The workspace in this repository creates the libbdkffi multi-language library for the Rust-based bdk library from the Bitcoin Dev Kit project.

Each supported language and the platform(s) it's packaged for has its own directory. The Rust code in this project is in the bdk-ffi directory and is a wrapper around the bdk library to expose its APIs in a uniform way using the mozilla/uniffi-rs bindings generator for each supported target language.

Supported target languages and platforms

The below directories (a separate repository in the case of bdk-swift) include instructions for using, building, and publishing the native language binding for bdk supported by this project.

Language Platform Published Package Building Documentation API Docs
Kotlin JVM bdk-jvm (Maven Central) Readme bdk-jvm Kotlin JVM API Docs
Kotlin Android bdk-android (Maven Central) Readme bdk-android Android API Docs
Swift iOS, macOS bdk-swift (GitHub) Readme bdk-swift
Python linux, macOS, Windows bdk-python (PyPI) Readme bdk-python

Building and Testing the Libraries

If you are familiar with the build tools for the specific languages you wish to build the libraries for, you can use their normal build/test workflows. We also include some just files to simplify the work across different languages. If you have the just tool installed on your system, you can simply call the commands defined in the justfiles, for example:

cd bdk-android

just build
just offlinetests
just publishlocal

Minimum Supported Rust Version (MSRV)

This library should compile with any combination of features with Rust 1.77.1.

Contributing

To add new structs and functions, see the UniFFI User Guide and the uniffi-examples repository.

Goals

  1. Language bindings should feel idiomatic in target languages/platforms
  2. Adding new targets should be easy
  3. Getting up and running should be easy
  4. Contributing should be easy
  5. Get it right, then automate

Using the libraries

bdk-android

// build.gradle.kts
repositories {
    mavenCentral()
}
dependencies { 
    implementation("org.bitcoindevkit:bdk-android:<version>")
}

bdk-jvm

// build.gradle.kts
repositories {
    mavenCentral()
}
dependencies { 
    implementation("org.bitcoindevkit:bdk-jvm:<version>")
}

Note: We also publish snapshot versions of bdk-jvm and bdk-android. See the specific readmes for instructions on how to use those.

bdk-python

pip3 install bdkpython

bdk-swift

Add bdk-swift to your dependencies in XCode.

Developing language bindings using uniffi-rs

If you are interested in better understanding the base structure we use here in order to build your own Rust-to-Kotlin/Swift/Python language bindings, check out the uniffi-bindings-template repository. We maintain it as an example and starting point for other projects that wish to leverage the tech stack used in producing the BDK language bindings.

Verifying Signatures

Both libraries and all their corresponding artifacts are signed with a PGP key you can find in the root of this repository. To verify the signatures follow the below steps:

  1. Import the PGP key in your keyring.
# Navigate to the root of the repository and import the ./PGP-BDK-BINDINGS.asc public key
gpg --import ./PGP-BDK-BINDINGS.asc
    
# Alternatively, you can import the key directly from a public key server
gpg --keyserver keyserver.ubuntu.com --receive-key 2768C43E8803C6A3
    
# Verify that the correct key was imported
gpg --list-keys
# You should see the below output
pub   ed25519 2022-08-31 [SC]
    88AD93AC4589FD090FF3B8D12768C43E8803C6A3
uid           [ unknown] bitcoindevkit-bindings <[email protected]>
sub   cv25519 2022-08-31 [E]
  1. Download the binary artifacts and corresponding signature files.
  • from bdk-jvm
    • bdk-jvm-<version>.jar
    • bdk-jvm-<version>.jar.asc
  • from bdk-android
    • bdk-android-<version>.aar
    • bdk-android-<version>.aar.asc
  1. Verify the signatures.
gpg --verify bdk-jvm-<version>.jar.asc 
gpg --verify bdk-android-<version>.aar.asc

# you should see a "Good signature" result
gpg: Good signature from "bitcoindevkit-bindings <[email protected]>" [unknown]

PGP Metadata

Full key ID: 88AD 93AC 4589 FD09 0FF3 B8D1 2768 C43E 8803 C6A3
Fingerprint: 2768C43E8803C6A3
Name: bitcoindevkit-bindings
Email: [email protected]

Thanks

This project is made possible thanks to the wonderful work by the mozilla/uniffi-rs team.

bdk-ffi's People

Contributors

afilini avatar andreasgriffin avatar artfuldev avatar caiofaustino avatar darkvoid32 avatar davidpsterling avatar dhruv-1001 avatar itorod avatar kirillzh avatar kornpow avatar nicbus avatar notmandatory avatar reez avatar shobitb avatar thunderbiscuit avatar waterst0ne avatar xsats avatar yellowhatpro avatar zoedberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bdk-ffi's Issues

Include static libraries for more target triples in `bdk-jvm`

We need to support the following target triples:

  • aarch64-unknown-linux-gnu ARM64 Linux (kernel 4.2, glibc 2.17+)
  • i686-pc-windows-gnu 32-bit MinGW (Windows 7+)
  • i686-pc-windows-msvc 32-bit MSVC (Windows 7+)
  • i686-unknown-linux-gnu 32-bit Linux (kernel 2.6.32+, glibc 2.11+)
  • aarch64-apple-darwin ARM64 macOS (11.0+, Big Sur+) bitcoindevkit/bdk-kotlin#5
  • x86_64-apple-darwin 64-bit macOS (10.7+, Lion+) bitcoindevkit/bdk-kotlin#5
  • x86_64-pc-windows-gnu 64-bit MinGW (Windows 7+)
  • x86_64-pc-windows-msvc 64-bit MSVC (Windows 7+)
  • x86_64-unknown-linux-gnu 64-bit Linux (kernel 2.6.32+, glibc 2.11+)

Reference: https://doc.rust-lang.org/nightly/rustc/platform-support.html#tier-1-with-host-tools

Support `bdk-jni` APIs used by `padawan-wallet`

By supporting the existing bdk-jni APIs we will be able to support the padawan-wallet project and other projects that are currently using bdk-jni.

  • Construct/destruct Wallet with db name, network, db path, descriptor, change descriptor
  • Construct Wallet with Sled key/value DB
  • Construct Wallet electrum blockchain client
  • Get new address from Wallet
  • Sync Wallet with blockchain
  • Get Wallet balance, in satoshis
  • List transactions
  • Create a transaction with single recipient
  • Sign PSBT with default options
  • Broadcast a PSBT
  • Generate an extended key
  • Restore an extended key
  • #60
  • #61
  • #62

Provide static library as part of bdk-jvm

I know the jars don't ship with the libbdkffi.dylib in them by default. Would a FAT jar be a solution for this or can they just be included with some configuration setting we need to turn on?

Other temporary solution would be to make them available as artifacts for download as part of the release page on GitHub.

Remove generated bindings code and dylib binary from source control

image
This kotlin % would just be very small (test/demo source) if we didn't have generated bindings here - and since generated bindings are just outputs, it might be a good idea to isolate them from source control.

We would still need to figure out how to test stuff. For the demo application and tests, I just use ./gradlew right now and run everything from the terminal. There might be a way to run these tests / code from scripts/clis without having to setup a complete kotlin project setup committed to source control

Support more APIs

  • #63
  • List unspent UTXOs in Wallet with outpoint, txout, keychain; txout includes script pubkey and value
  • List transactions with raw transactions
  • Sign a PSBT with Wallet, optionally assume current blockchain height
  • Extract a raw transaction from a PSBT
  • Create a transaction with multiple recipients (and fee rate)
  • Create a send-all UTXOs transaction (and fee rate)
  • Allow configuring optional utxos to include, optional unspendable utxo for transactions
  • Allow adding a spending policy map to transactions

Implement basic spending policy APIs

Description

Add or update APIs in bdk-ffi to support basic spending policy features. Also test the new APIs by updating bdk-kotlin or bdk-swift to use the new and updated APIs. See "Spending Policy Demo" for bdk-cli based example usage.

APIs include:

  1. Giving a wallet, return Policy structure (as Dictionary?) for "external" and "internal" descriptors.
  2. When creating a transaction PSBT, specify the "external policy" to use

Expected Outcomes

  • Update bdk.udl and lib.rs with functions and structs as needed
  • Update bdk-kotlin or bdk-swift and add tests to cover new spending policy functionality

Resources

Skills Required

Mentor(s)

@artfuldev @notmandatory

Difficulty

Medium

Competency Test (optional)

  • Install rust, compile bdk-ffi and build and test bdk-swift or bdk-kotlin.
  • Read through the BDK docs.
  • Use bdk-cli to walk through the "Spending Policy Demo"
  • Install and run example bdk-kotlin or bdk-swift example wallet.
  • Familiarity with basic rust, should be able to write basic structs and functions.

Demo tracking issue

Manual Testnet Demo

  • create wallet receive address
  • send bitcoin to wallet (from external faucet)
  • sync wallet via electrum
  • verify received balance
  • #4
  • #5
  • #7
  • #8

Fix androidTest tests

Error with test.sh -a. Some sort of class path problem.

> Task :android:mergeLibDexDebugAndroidTest FAILED
ERROR:/Users/steve/git/notmandatory/bdk-ffi/bindings/bdk-kotlin/android/build/.transforms/f8f486ba184b26ea1f15591ec62fc9a1/transformed/classes/classes.dex: D8: Type org.bitcoindevkit.BdkException$ErrorHandler$lift$1 is defined multiple times: /Users/steve/git/notmandatory/bdk-ffi/bindings/bdk-kotlin/android/build/.transforms/f8f486ba184b26ea1f15591ec62fc9a1/transformed/classes/classes.dex, /Users/steve/git/notmandatory/bdk-ffi/bindings/bdk-kotlin/jvm/build/.transforms/4e2c77aa7006fe94dfc61462ec41c77b/transformed/jetified-jvm/classes.dex
com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 
Learn how to resolve the issue at https://developer.android.com/studio/build/dependencies#duplicate_classes.
Type org.bitcoindevkit.BdkException$ErrorHandler$lift$1 is defined multiple times: /Users/steve/git/notmandatory/bdk-ffi/bindings/bdk-kotlin/android/build/.transforms/f8f486ba184b26ea1f15591ec62fc9a1/transformed/classes/classes.dex, /Users/steve/git/notmandatory/bdk-ffi/bindings/bdk-kotlin/jvm/build/.transforms/4e2c77aa7006fe94dfc61462ec41c77b/transformed/jetified-jvm/classes.dex
        at com.android.builder.dexing.D8DexArchiveMerger.getExceptionToRethrow(D8DexArchiveMerger.java:128)
        at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:115)
        at com.android.build.gradle.internal.transforms.DexMergerTransformCallable.call(DexMergerTransformCallable.java:111)
        at com.android.build.gradle.internal.tasks.DexMergingWorkAction.merge(DexMergingTask.kt:805)
        at com.android.build.gradle.internal.tasks.DexMergingWorkAction.run(DexMergingTask.kt:760)
        at com.android.build.gradle.internal.profile.ProfileAwareWorkAction.execute(ProfileAwareWorkAction.kt:74)
        at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
        at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:66)
        at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:62)
        at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:97)
        at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:62)
        at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
        at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:79)
        at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:79)
        at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
        at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:59)
        at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$2(DefaultWorkerExecutor.java:206)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:214)
        at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
        at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:131)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:61)
        at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: com.android.tools.r8.CompilationFailedException: Compilation failed to complete, origin: /Users/steve/git/notmandatory/bdk-ffi/bindings/bdk-kotlin/android/build/.transforms/f8f486ba184b26ea1f15591ec62fc9a1/transformed/classes/classes.dex
        at Version.fakeStackEntry(Version_2.2.66.java:0)
        at com.android.tools.r8.utils.a0.a(SourceFile:89)
        at com.android.tools.r8.D8.run(D8.java:11)
        at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:113)
        ... 36 more
Caused by: com.android.tools.r8.utils.b: Type org.bitcoindevkit.BdkException$ErrorHandler$lift$1 is defined multiple times: /Users/steve/git/notmandatory/bdk-ffi/bindings/bdk-kotlin/android/build/.transforms/f8f486ba184b26ea1f15591ec62fc9a1/transformed/classes/classes.dex, /Users/steve/git/notmandatory/bdk-ffi/bindings/bdk-kotlin/jvm/build/.transforms/4e2c77aa7006fe94dfc61462ec41c77b/transformed/jetified-jvm/classes.dex
        at com.android.tools.r8.utils.V0.a(SourceFile:22)
        at com.android.tools.r8.utils.V0.a(SourceFile:25)
        at com.android.tools.r8.utils.T0.b(SourceFile:6)
        at com.android.tools.r8.utils.T0.a(SourceFile:24)
        at com.android.tools.r8.utils.T0.a(SourceFile:10)
        at java.base/java.util.concurrent.ConcurrentHashMap.merge(ConcurrentHashMap.java:2056)
        at com.android.tools.r8.utils.T0.a(SourceFile:6)
        at com.android.tools.r8.graph.i1$c.e(SourceFile:3)
        at com.android.tools.r8.dex.a.a(SourceFile:336)
        at com.android.tools.r8.dex.a.a(SourceFile:265)
        at com.android.tools.r8.D8.a(D8.java:22)
        at com.android.tools.r8.D8.d(D8.java:6)
        at com.android.tools.r8.D8.b(D8.java:1)
        at com.android.tools.r8.utils.a0.a(SourceFile:47)
        ... 38 more


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':android:mergeLibDexDebugAndroidTest'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.DexMergingTaskDelegate
   > There was a failure while executing work items
      > A failure occurred while executing com.android.build.gradle.internal.tasks.DexMergingWorkAction
         > com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 
           Learn how to resolve the issue at https://developer.android.com/studio/build/dependencies#duplicate_classes.
           Type org.bitcoindevkit.BdkException$ErrorHandler$lift$1 is defined multiple times: /Users/steve/git/notmandatory/bdk-ffi/bindings/bdk-kotlin/android/build/.transforms/f8f486ba184b26ea1f15591ec62fc9a1/transformed/classes/classes.dex, /Users/steve/git/notmandatory/bdk-ffi/bindings/bdk-kotlin/jvm/build/.transforms/4e2c77aa7006fe94dfc61462ec41c77b/transformed/jetified-jvm/classes.dex

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 8s

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.