Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Determine approach for language bindings #232

Closed
notmandatory opened this issue Dec 16, 2020 · 8 comments
Closed

Determine approach for language bindings #232

notmandatory opened this issue Dec 16, 2020 · 8 comments
Labels
close discussion There's still a discussion ongoing

Comments

@notmandatory
Copy link
Member

notmandatory commented Dec 16, 2020

This is a tracking issue to add notes and discuss how bdk should do future language bindings. The current targets are android/kotlin (see bdk-jni), ios/swift, and python.

Related LDK projects to examine:

Contacts on the LDK project are:

@notmandatory notmandatory added the discussion There's still a discussion ongoing label Dec 16, 2020
@notmandatory
Copy link
Member Author

Other, slightly contradictory, approaches to consider are:

@afilini
Copy link
Member

afilini commented Feb 5, 2021

I've been doing some experiments for the past few days, I think a good and relatively scalable approach would be to have an extra crate library (cdylib) called bdk-ffi that wraps bdk and exposes everything as c-like functions with #[no_mangle] extern "C" fn. We would have to maintain this crate manually, meaning that every time we break or add something to the APIs in bdk we would also have to manually update this crate. But then using cbindgen we should be able to generate nice headers for it and use it directly from C/C++.

Once we have the header there are a couple of options: we could try using automated tools like SWIG to generate bindings for other languages starting from the C header. I tried playing with it once and it was horrible, but I think there are some very large projects using it, so it might be powerful enough to do what we want and we just have to accept the steep learning curve.

Alternatively, we could try writing some proc-macros to generate everything right inside rust. I'm thinking about defining a "translation table" manually for every language and then have it applied automatically by the compiler. Things like "transform a string in your native format to a *const c_char", or "call a lambda". We would implement those manually for the JNI, for Python, etc and then use the proc-macro to wrap all the C functions and perform conversions for the arguments/result. The main problem with this approach is that we not only have to wrap all our functions, but also generate some native code in the language we are targeting, like a java class or python module that calls into our functions. To do that we would have to either emit code directly from the proc-macro (which can be done now but I'm afraid it could be restricted going forward) or emit some metadata in the code inside comments and then have an external tool go through the expanded code looking for those metadata.

@afilini
Copy link
Member

afilini commented Feb 8, 2021

Pushed some stuff to this repo: https://github.com/afilini/hello-ffi

Still very WIP but some things are starting to come together

@notmandatory
Copy link
Member Author

A possibly useful project suggested by @RCasatta is robusta. It's very new but does something similar to py03 but for Java.

@notmandatory
Copy link
Member Author

A Discord discussion comparing with LDK approach is here:
https://discord.com/channels/753336465005608961/824249944810192956/832694301414785075

@notmandatory
Copy link
Member Author

I'm experimenting with creating a bdk-ffi wrapper library using safer_ffi with a bdk-kotlin companion library using Java Native Access JNA. I'm not doing any automated code generation of the wrapper code right now, only trying to understand if I can use this approach to create working bdk libraries for android/kotlin and ios/swift.

@danielnordh
Copy link

danielnordh commented Feb 9, 2022

What's the state of bindings for Swift, anything I can try using?
I'm trying to run LDK on Swift/iOS and would like to try to use BDK with it.

EDIT: found the BDK-Swift repo

nickfarrow pushed a commit to nickfarrow/bdk that referenced this issue Feb 21, 2022
@notmandatory
Copy link
Member Author

The uniffi-rs approach is working well and we have initial language binding implementations for kotlin, swift, and python.

bdk-ffi - Provides FFI bindings and code generation for all language bindings, added as git submodule to below language specific projects.

bdk-kotlin builds, packages, and tests kotlin bindings and able to publish to maven central for different platforms.
bdk-swift builds, and is an importable package for swift/xcode projects for macos and ios platforms.
bdk-python builds and packages for PyPi for different platforms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
close discussion There's still a discussion ongoing
Projects
Archived in project
Development

No branches or pull requests

3 participants