Compare commits
82 Commits
release/0.
...
v0.29.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b66ac96ab | ||
|
|
039b64de5c | ||
|
|
fe7e4e21c0 | ||
|
|
77f89afc68 | ||
|
|
25033f6bd6 | ||
|
|
3cb2c2c394 | ||
|
|
5092987b26 | ||
|
|
aea25dbf21 | ||
|
|
ed67eba910 | ||
|
|
90606b2455 | ||
|
|
49e8fe461e | ||
|
|
de88184b8c | ||
|
|
3be2c0495f | ||
|
|
2c4c64515f | ||
|
|
17323d3184 | ||
|
|
b382511a9e | ||
|
|
d3895441d3 | ||
|
|
269512a673 | ||
|
|
d27206787a | ||
|
|
c1b1fd6f5d | ||
|
|
7062fbd047 | ||
|
|
0e34a6bacf | ||
|
|
89e85a20cf | ||
|
|
d8718c3f05 | ||
|
|
871a06d1ce | ||
|
|
b820d6a2ba | ||
|
|
79d9fa2909 | ||
|
|
a0e0467d39 | ||
|
|
f2296704e6 | ||
|
|
b8b60dda87 | ||
|
|
a50e19e7e0 | ||
|
|
fab9ae8ae5 | ||
|
|
478b12c489 | ||
|
|
63b85b9100 | ||
|
|
0e6b472793 | ||
|
|
beb75dd552 | ||
|
|
5ee8698e0a | ||
|
|
ac600a1312 | ||
|
|
f26031db80 | ||
|
|
e7e1a6057e | ||
|
|
2b7c104f11 | ||
|
|
6bab5a159d | ||
|
|
b6c8b145bb | ||
|
|
67610abeb6 | ||
|
|
4e5537acd2 | ||
|
|
6be4ddaf7b | ||
|
|
cd10c75e96 | ||
|
|
cbd44249f3 | ||
|
|
20c31d5383 | ||
|
|
616cb21738 | ||
|
|
d3a6453eda | ||
|
|
cba69e681a | ||
|
|
35d8fb3139 | ||
|
|
f003a6275e | ||
|
|
2f62377eec | ||
|
|
81e208222a | ||
|
|
3dc6596aa2 | ||
|
|
2342265c26 | ||
|
|
6c561228c2 | ||
|
|
e86909ab3d | ||
|
|
8e51756a3a | ||
|
|
40263b425e | ||
|
|
9437051668 | ||
|
|
7557e214c8 | ||
|
|
40ca62086c | ||
|
|
e0506deffa | ||
|
|
d3e183a498 | ||
|
|
1e9ecfbe52 | ||
|
|
d48bacd29b | ||
|
|
c1243f9e1c | ||
|
|
9c6069e389 | ||
|
|
488edf8bd2 | ||
|
|
90763d42a2 | ||
|
|
44b2ef1382 | ||
|
|
25617d1f23 | ||
|
|
2fcafe2b80 | ||
|
|
5728b50100 | ||
|
|
d08317775b | ||
|
|
c93f292b0e | ||
|
|
a75c868eb2 | ||
|
|
974ff66caf | ||
|
|
2309b19209 |
17
.github/ISSUE_TEMPLATE/enhancement_request.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/enhancement_request.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Enhancement request
|
||||
about: Request a new feature or change to an existing feature
|
||||
title: ''
|
||||
labels: 'enhancement'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the enhancement**
|
||||
<!-- A clear and concise description of what you would like added or changed. -->
|
||||
|
||||
**Use case**
|
||||
<!-- Tell us how you or others will use this new feature or change to an existing feature. -->
|
||||
|
||||
**Additional context**
|
||||
<!-- Add any other context about the enhancement here. -->
|
||||
164
.github/ISSUE_TEMPLATE/minor_release.md
vendored
164
.github/ISSUE_TEMPLATE/minor_release.md
vendored
@@ -4,98 +4,82 @@ about: Create a new minor release [for release managers only]
|
||||
title: 'Release MAJOR.MINOR+1.0'
|
||||
labels: 'release'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Create a new minor release
|
||||
## Bumping BDK Rust Version
|
||||
1. - [ ] Open a PR with an update to `Cargo.toml` to the new bdk release candidate and ensure all CI workflows run correctly. Fix errors if necessary.
|
||||
2. - [ ] Once the new bdk release is out, update the PR to replace the release candidate with the full release and merge.
|
||||
|
||||
### Summary
|
||||
### Specific Libraries' Workflows
|
||||
#### _Android_
|
||||
3. - [ ] Update the API docs to reflect the changes in the API
|
||||
4. - [ ] Delete the `target` directory in bdk-ffi and all previous artifacts to make sure you're building the library from scratch.
|
||||
5. - [ ] Build the library and run the tests, and adjust if necessary.
|
||||
```sh
|
||||
# start an emulator prior to running the tests
|
||||
cd ./bdk-android/
|
||||
./gradlew buildAndroidLib
|
||||
./gradlew connectedAndroidTest
|
||||
```
|
||||
6. - [ ] Update the readme if necessary
|
||||
#### _JVM_
|
||||
7. - [ ] Update the API docs to reflect the changes in the API
|
||||
8. - [ ] Delete the `target` directory in bdk-ffi and all previous artifacts to make sure you're building the library from scratch
|
||||
9. - [ ] Build the library and run the tests, and adjust if necessary
|
||||
```sh
|
||||
cd ./bdk-jvm/
|
||||
./gradlew buildJvmLib
|
||||
./gradlew test
|
||||
```
|
||||
10. - [ ] Update the readme if necessary
|
||||
#### _Swift_
|
||||
11. - [ ] Run the tests and adjust if necessary
|
||||
```sh
|
||||
./bdk-swift/build-local-swift.sh
|
||||
cd ./bdk-swift/
|
||||
swift test
|
||||
```
|
||||
12. - [ ] Update the readme if necessary
|
||||
#### _Python_
|
||||
13. - [ ] Delete the `.tox`, `dist`, `build`, and `bdkpython.egg-info` and rust `target` directories to make sure you are building the library from scratch without any caches
|
||||
14. - [ ] Build the library
|
||||
```shell
|
||||
cd ./bdk-python/
|
||||
pip3 install --requirement requirements.txt
|
||||
bash ./generate.sh
|
||||
python3 setup.py --verbose bdist_wheel
|
||||
```
|
||||
15. - [ ] Run the tests and adjust if necessary
|
||||
```shell
|
||||
pip3 install ./dist/bdkpython-<yourversion>-py3-none-any.whl --force-reinstall
|
||||
python -m unittest --verbose tests/test_bdk.py
|
||||
```
|
||||
16. - [ ] Update the readme and `setup.py` if necessary
|
||||
|
||||
<--release summary to be used in announcements-->
|
||||
|
||||
### Commit
|
||||
|
||||
<--latest commit ID to include in this release-->
|
||||
|
||||
### Changelog
|
||||
|
||||
<--add notices from PRs merged since the prior release, see ["keep a changelog"]-->
|
||||
|
||||
### Checklist
|
||||
|
||||
Release numbering must follow [Semantic Versioning]. These steps assume the current `master`
|
||||
branch **development** version is *MAJOR.MINOR.0*.
|
||||
|
||||
#### On the day of the feature freeze
|
||||
|
||||
Change the `master` branch to the next MINOR+1 version:
|
||||
|
||||
- [ ] Switch to the `master` branch.
|
||||
- [ ] Create a new PR branch called `bump_dev_MAJOR_MINOR+1`, eg. `bump_dev_0_22`.
|
||||
- [ ] Bump the `bump_dev_MAJOR_MINOR+1` branch to the next development MINOR+1 version.
|
||||
- Change the `Cargo.toml` version value to `MAJOR.MINOR+1.0`.
|
||||
- The commit message should be "Bump version to MAJOR.MINOR+1.0".
|
||||
- [ ] Create PR and merge the `bump_dev_MAJOR_MINOR+1` branch to `master`.
|
||||
- Title PR "Bump version to MAJOR.MINOR+1.0".
|
||||
|
||||
Create a new release branch:
|
||||
|
||||
- [ ] Double check that your local `master` is up-to-date with the upstream repo.
|
||||
- [ ] Create a new branch called `release/MAJOR.MINOR+1` from `master`.
|
||||
|
||||
Add a release candidate tag, this is optional and only needed for major `bdk-ffi` changes that
|
||||
require a longer testing cycle:
|
||||
|
||||
- [ ] Bump the `release/MAJOR.MINOR+1` branch to `MAJOR.MINOR+1.0-rc.1` version.
|
||||
- Change the `Cargo.toml` version value to `MAJOR.MINOR+1.0-rc.1`.
|
||||
- The commit message should be "Bump version to MAJOR.MINOR+1.0-rc.1".
|
||||
- [ ] Add a tag to the `HEAD` commit in the `release/MAJOR.MINOR+1` branch.
|
||||
- The tag name should be `vMAJOR.MINOR+1.0-rc.1`
|
||||
- Use message "Release MAJOR.MINOR+1.0 rc.1".
|
||||
- Make sure the tag is signed, for extra safety use the explicit `--sign` flag.
|
||||
- [ ] Push the `release/MAJOR.MINOR` branch and new tag to the `bitcoindevkit/bdk` repo.
|
||||
- Use `git push --tags` option to push the new `vMAJOR.MINOR+1.0-rc.1` tag.
|
||||
|
||||
If any issues need to be fixed before the *MAJOR.MINOR+1.0* version is released:
|
||||
|
||||
- [ ] Merge fix PRs to the `master` branch.
|
||||
- [ ] Git cherry-pick fix commits to the `release/MAJOR.MINOR+1` branch.
|
||||
- [ ] Verify fixes in `release/MAJOR.MINOR+1` branch.
|
||||
- [ ] Bump the `release/MAJOR.MINOR+1` branch to `MAJOR.MINOR+1.0-rc.x+1` version.
|
||||
- Change the `Cargo.toml` version value to `MAJOR.MINOR+1.0-rc.x+1`.
|
||||
- The commit message should be "Bump version to MAJOR.MINOR+1.0-rc.x+1".
|
||||
- [ ] Add a tag to the `HEAD` commit in the `release/MAJOR.MINOR+1` branch.
|
||||
- The tag name should be `vMAJOR.MINOR+1.0-rc.x+1`, where x is the current release candidate number.
|
||||
- Use tag message "Release MAJOR.MINOR+1.0 rc.x+1".
|
||||
- Make sure the tag is signed, for extra safety use the explicit `--sign` flag.
|
||||
- [ ] Push the new tag to the `bitcoindevkit/bdk` repo.
|
||||
- Use `git push --tags` option to push the new `vMAJOR.MINOR+1.0-rc.x+1` tag.
|
||||
|
||||
#### On the day of the release
|
||||
|
||||
Tag and publish new release:
|
||||
|
||||
- [ ] Bump the `release/MAJOR.MINOR+1` branch to `MAJOR.MINOR+1.0` version.
|
||||
- Change the `Cargo.toml` version value to `MAJOR.MINOR+1.0`.
|
||||
- The commit message should be "Bump version to MAJOR.MINOR+1.0".
|
||||
- [ ] Add a tag to the `HEAD` commit in the `release/MAJOR.MINOR+1` branch.
|
||||
- The tag name should be `vMAJOR.MINOR+1.0`
|
||||
- The first line of the tag message should be "Release MAJOR.MINOR+1.0".
|
||||
- In the body of the tag message put a copy of the **Summary** and **Changelog** for the release.
|
||||
- Make sure the tag is signed, for extra safety use the explicit `--sign` flag.
|
||||
- [ ] Wait for the CI to finish one last time.
|
||||
- [ ] Push the new tag to the `bitcoindevkit/bdk` repo.
|
||||
- [ ] Create the release on GitHub.
|
||||
- Go to "tags", click on the dots on the right and select "Create Release".
|
||||
- Set the title to `Release MAJOR.MINOR+1.0`.
|
||||
- In the release notes body put the **Summary** and **Changelog**.
|
||||
- Use the "+ Auto-generate release notes" button to add details from included PRs.
|
||||
- Until we reach a `1.0.0` release check the "Pre-release" box.
|
||||
- [ ] After downstream language repos are also updated announce the release, using the **Summary**,
|
||||
on Discord, Twitter and Mastodon.
|
||||
- [ ] Celebrate 🎉
|
||||
|
||||
[Semantic Versioning]: https://semver.org/
|
||||
[crates.io]: https://crates.io/crates/bdk
|
||||
[docs.rs]: https://docs.rs/bdk/latest/bdk
|
||||
["keep a changelog"]: https://keepachangelog.com/en/1.0.0/
|
||||
### Release Workflow
|
||||
17. - [ ] Update the Android, JVM, Python, and Swift libraries as per the _Specific Libraries' Workflows_ section above. Open a single PR on master for all of these changes called `Prepare language bindings libraries for 0.X release`. See [example PR here](https://github.com/bitcoindevkit/bdk-ffi/pull/315).
|
||||
- [ ] Create a new branch off of `master` called `release/version`
|
||||
18. - [ ] Open a PR to that branch to update the Android, JVM, and Python libraries' versions. See [example PR here](https://github.com/bitcoindevkit/bdk-ffi/pull/316).
|
||||
- [ ] Update bdk-android version from `SNAPSHOT` version to release version
|
||||
- [ ] Update bdk-jvm version from `SNAPSHOT` version to release version
|
||||
- [ ] Update bdk-python version from `.dev` version to release version
|
||||
19. - [ ] Merge the PR updating all the languages to their release versions
|
||||
20. - [ ] Create the tag and make sure to add the changelog info to the tag (works better if you prepare the tag message on the side in a text editor) and push it to GitHub.
|
||||
```sh
|
||||
git tag v0.6.0 --sign --edit
|
||||
git push upstream v0.6.0
|
||||
```
|
||||
21. - [ ] Aggregate all the changelog notices from the PRs and add them to the changelog file
|
||||
22. - [ ] Open a PR on master with the changes to the changelog file and the development versions bump. See [example PR here](https://github.com/bitcoindevkit/bdk-ffi/pull/317).
|
||||
23. - [ ] Make release on GitHub (set as pre-release and generate auto release notes between the previous tag and the new one)
|
||||
24. - [ ] Trigger manual releases for all 4 libraries (for Swift, simply add the version number in the text field when running the workflow manually. Note that the version number must not contain the `v`, i.e. `0.26.0`)
|
||||
25. - [ ] Bump the versions on master from `0.9.0-SNAPSHOT` to `0.10.0-SNAPSHOT`, `0.6.0.dev0` to `0.7.0.dev0`
|
||||
26. - [ ] Build and publish API docs for JVM, Android, and Java on the website
|
||||
```bash!
|
||||
./gradlew dokkaHtml # bdk-jvm (Dokka)
|
||||
./gradlew dokkaJavadoc # bdk-jvm (java-style documentation)
|
||||
./gradlew dokkaHtml # bdk-android (Dokka)
|
||||
```
|
||||
27. - [ ] Tweet about the library
|
||||
28. - [ ] Post in the announcement channel
|
||||
|
||||
134
.github/ISSUE_TEMPLATE/patch_release.md
vendored
134
.github/ISSUE_TEMPLATE/patch_release.md
vendored
@@ -4,66 +4,82 @@ about: Create a new patch release [for release managers only]
|
||||
title: 'Release MAJOR.MINOR.PATCH+1'
|
||||
labels: 'release'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Create a new patch release
|
||||
# Creating a new patch release
|
||||
## Bumping BDK Rust Version
|
||||
1. - [ ] Open a PR with an update to `Cargo.toml` to the new bdk release candidate and ensure all CI workflows run correctly. Fix errors if necessary.
|
||||
2. - [ ] Once the new bdk release is out, update the PR to replace the release candidate with the full release and merge.
|
||||
|
||||
### Summary
|
||||
### Specific Libraries' Workflows
|
||||
#### _Android_
|
||||
3. - [ ] Update the API docs to reflect the changes in the API
|
||||
4. - [ ] Delete the `target` directory in bdk-ffi and all previous artifacts to make sure you're building the library from scratch.
|
||||
5. - [ ] Build the library and run the tests, and adjust if necessary.
|
||||
```sh
|
||||
# start an emulator prior to running the tests
|
||||
cd ./bdk-android/
|
||||
./gradlew buildAndroidLib
|
||||
./gradlew connectedAndroidTest
|
||||
```
|
||||
6. - [ ] Update the readme if necessary
|
||||
#### _JVM_
|
||||
7. - [ ] Update the API docs to reflect the changes in the API
|
||||
8. - [ ] Delete the `target` directory in bdk-ffi and all previous artifacts to make sure you're building the library from scratch
|
||||
9. - [ ] Build the library and run the tests, and adjust if necessary
|
||||
```sh
|
||||
cd ./bdk-jvm/
|
||||
./gradlew buildJvmLib
|
||||
./gradlew test
|
||||
```
|
||||
10. - [ ] Update the readme if necessary
|
||||
#### _Swift_
|
||||
11. - [ ] Run the tests and adjust if necessary
|
||||
```sh
|
||||
./bdk-swift/build-local-swift.sh
|
||||
cd ./bdk-swift/
|
||||
swift test
|
||||
```
|
||||
12. - [ ] Update the readme if necessary
|
||||
#### _Python_
|
||||
13. - [ ] Delete the `.tox`, `dist`, `build`, and `bdkpython.egg-info` and rust `target` directories to make sure you are building the library from scratch without any caches
|
||||
14. - [ ] Build the library
|
||||
```shell
|
||||
cd ./bdk-python/
|
||||
pip3 install --requirement requirements.txt
|
||||
bash ./generate.sh
|
||||
python3 setup.py --verbose bdist_wheel
|
||||
```
|
||||
15. - [ ] Run the tests and adjust if necessary
|
||||
```shell
|
||||
pip3 install ./dist/bdkpython-<yourversion>-py3-none-any.whl --force-reinstall
|
||||
python -m unittest --verbose tests/test_bdk.py
|
||||
```
|
||||
16. - [ ] Update the readme and `setup.py` if necessary
|
||||
|
||||
<--release summary to be used in announcements-->
|
||||
|
||||
### Commit
|
||||
|
||||
<--latest commit ID to include in this release-->
|
||||
|
||||
### Changelog
|
||||
|
||||
<--add notices from PRs merged since the prior release, see ["keep a changelog"]-->
|
||||
|
||||
### Checklist
|
||||
|
||||
Release numbering must follow [Semantic Versioning]. These steps assume the current `master`
|
||||
branch **development** version is *MAJOR.MINOR.PATCH*.
|
||||
|
||||
### On the day of the patch release
|
||||
|
||||
Change the `master` branch to the new PATCH+1 version:
|
||||
|
||||
- [ ] Switch to the `master` branch.
|
||||
- [ ] Create a new PR branch called `bump_dev_MAJOR_MINOR_PATCH+1`, eg. `bump_dev_0_22_1`.
|
||||
- [ ] Bump the `bump_dev_MAJOR_MINOR` branch to the next development PATCH+1 version.
|
||||
- Change the `Cargo.toml` version value to `MAJOR.MINOR.PATCH+1`.
|
||||
- The commit message should be "Bump version to MAJOR.MINOR.PATCH+1".
|
||||
- [ ] Create PR and merge the `bump_dev_MAJOR_MINOR_PATCH+1` branch to `master`.
|
||||
- Title PR "Bump version to MAJOR.MINOR.PATCH+1".
|
||||
|
||||
Cherry-pick, tag and publish new PATCH+1 release:
|
||||
|
||||
- [ ] Merge fix PRs to the `master` branch.
|
||||
- [ ] Git cherry-pick fix commits to the `release/MAJOR.MINOR` branch to be patched.
|
||||
- [ ] Verify fixes in `release/MAJOR.MINOR` branch.
|
||||
- [ ] Bump the `release/MAJOR.MINOR.PATCH+1` branch to `MAJOR.MINOR.PATCH+1` version.
|
||||
- Change the `Cargo.toml` version value to `MAJOR.MINOR.MINOR.PATCH+1`.
|
||||
- The commit message should be "Bump version to MAJOR.MINOR.PATCH+1".
|
||||
- [ ] Add a tag to the `HEAD` commit in the `release/MAJOR.MINOR` branch.
|
||||
- The tag name should be `vMAJOR.MINOR.PATCH+1`
|
||||
- The first line of the tag message should be "Release MAJOR.MINOR.PATCH+1".
|
||||
- In the body of the tag message put a copy of the **Summary** and **Changelog** for the release.
|
||||
- Make sure the tag is signed, for extra safety use the explicit `--sign` flag.
|
||||
- [ ] Wait for the CI to finish one last time.
|
||||
- [ ] Push the new tag to the `bitcoindevkit/bdk` repo.
|
||||
- [ ] Create the release on GitHub.
|
||||
- Go to "tags", click on the dots on the right and select "Create Release".
|
||||
- Set the title to `Release MAJOR.MINOR.PATCH+1`.
|
||||
- In the release notes body put the **Summary** and **Changelog**.
|
||||
- Use the "+ Auto-generate release notes" button to add details from included PRs.
|
||||
- Until we reach a `1.0.0` release check the "Pre-release" box.
|
||||
- [ ] After downstream language repos are also updated announce the release, using the **Summary**,
|
||||
on Discord, Twitter and Mastodon.
|
||||
- [ ] Celebrate 🎉
|
||||
|
||||
[Semantic Versioning]: https://semver.org/
|
||||
[crates.io]: https://crates.io/crates/bdk
|
||||
[docs.rs]: https://docs.rs/bdk/latest/bdk
|
||||
["keep a changelog"]: https://keepachangelog.com/en/1.0.0/
|
||||
### Release Workflow
|
||||
17. - [ ] Update the Android, JVM, Python, and Swift libraries as per the _Specific Libraries' Workflows_ section above. Open a single PR on master for all of these changes called `Prepare language bindings libraries for 0.X release`. See [example PR here](https://github.com/bitcoindevkit/bdk-ffi/pull/315).
|
||||
- [ ] Create a new branch off of `master` called `release/version`
|
||||
18. - [ ] Open a PR to that branch to update the Android, JVM, and Python libraries' versions. See [example PR here](https://github.com/bitcoindevkit/bdk-ffi/pull/316).
|
||||
- [ ] Update bdk-android version from `SNAPSHOT` version to release version
|
||||
- [ ] Update bdk-jvm version from `SNAPSHOT` version to release version
|
||||
- [ ] Update bdk-python version from `.dev` version to release version
|
||||
19. - [ ] Merge the PR updating all the languages to their release versions
|
||||
20. - [ ] Create the tag and make sure to add the changelog info to the tag (works better if you prepare the tag message on the side in a text editor) and push it to GitHub.
|
||||
```sh
|
||||
git tag v0.6.0 --sign --edit
|
||||
git push upstream v0.6.0
|
||||
```
|
||||
21. - [ ] Aggregate all the changelog notices from the PRs and add them to the changelog file
|
||||
22. - [ ] Open a PR on master with the changes to the changelog file and the development versions bump. See [example PR here](https://github.com/bitcoindevkit/bdk-ffi/pull/317).
|
||||
23. - [ ] Make release on GitHub (set as pre-release and generate auto release notes between the previous tag and the new one)
|
||||
24. - [ ] Trigger manual releases for all 4 libraries (for Swift, simply add the version number in the text field when running the workflow manually. Note that the version number must not contain the `v`, i.e. `0.26.0`)
|
||||
25. - [ ] Bump the versions on master from `0.9.0-SNAPSHOT` to `0.10.0-SNAPSHOT`, `0.6.0.dev0` to `0.7.0.dev0`
|
||||
26. - [ ] Build and publish API docs for JVM, Android, and Java on the website
|
||||
```bash!
|
||||
./gradlew dokkaHtml # bdk-jvm (Dokka)
|
||||
./gradlew dokkaJavadoc # bdk-jvm (java-style documentation)
|
||||
./gradlew dokkaHtml # bdk-android (Dokka)
|
||||
```
|
||||
27. - [ ] Tweet about the library
|
||||
28. - [ ] Post in the announcement channel
|
||||
|
||||
2
.github/workflows/audit.yml
vendored
2
.github/workflows/audit.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
|
||||
jobs:
|
||||
security_audit:
|
||||
name: Security Audit
|
||||
name: Security audit
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
126
.github/workflows/build-python-wheels.yaml
vendored
126
.github/workflows/build-python-wheels.yaml
vendored
@@ -1,126 +0,0 @@
|
||||
name: Build Python wheels
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "bdk-ffi/**"
|
||||
- "bdk-python/**"
|
||||
pull_request:
|
||||
paths:
|
||||
- "bdk-ffi/**"
|
||||
- "bdk-python/**"
|
||||
|
||||
# We use manylinux2014 because older CentOS versions used by 2010 and 1 have a very old glibc version, which
|
||||
# makes it very hard to use GitHub's javascript actions (checkout, upload-artifact, etc).
|
||||
# They mount their own nodejs interpreter inside your container, but since that's not statically linked it
|
||||
# tries to load glibc and fails because it requires a more recent version.
|
||||
|
||||
jobs:
|
||||
build-manylinux2014-x86_64-wheel:
|
||||
name: 'Build Manylinux 2014 x86_64 wheel'
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: bdk-python
|
||||
container:
|
||||
image: quay.io/pypa/manylinux2014_x86_64
|
||||
env:
|
||||
PLAT: manylinux2014_x86_64
|
||||
PYBIN: '/opt/python/${{ matrix.python }}/bin'
|
||||
strategy:
|
||||
matrix:
|
||||
python: # Update this list whenever the docker image is updated (check /opt/python/)
|
||||
# - cp36-cp36m
|
||||
# - cp37-cp37m
|
||||
# - cp38-cp38
|
||||
# - cp39-cp39
|
||||
- cp310-cp310
|
||||
# - pp37-pypy37_pp73
|
||||
# - pp38-pypy38_pp73
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
- name: install requirements
|
||||
run: ${PYBIN}/pip install -r requirements.txt
|
||||
- name: generate bindings
|
||||
run: bash generate.sh
|
||||
- name: build wheel
|
||||
run: ${PYBIN}/pip wheel . --no-deps -w /tmp/wheelhouse
|
||||
- name: repair wheel
|
||||
run: auditwheel repair /tmp/wheelhouse/* --plat "$PLAT" -w /tmp/wheelhouse-repaired
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: bdkpython-manylinux2014-x86_64-${{ matrix.python }}
|
||||
path: /tmp/wheelhouse-repaired/*.whl
|
||||
|
||||
build-macos-universal-wheel:
|
||||
name: 'Build macOS universal wheel'
|
||||
runs-on: macos-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: bdk-python
|
||||
strategy:
|
||||
matrix:
|
||||
python:
|
||||
# - '3.7'
|
||||
# - '3.8'
|
||||
# - '3.9'
|
||||
- '3.10'
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
- run: python3 --version
|
||||
- run: rustup target add aarch64-apple-darwin
|
||||
- run: pip3 install --user -r requirements.txt
|
||||
- run: pip3 install --user wheel
|
||||
- run: bash generate.sh
|
||||
- name: build wheel
|
||||
env:
|
||||
ARCHFLAGS: "-arch x86_64 -arch arm64"
|
||||
run: python3 setup.py -v bdist_wheel
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: bdkpython-macos-${{ matrix.python }}
|
||||
path: /Users/runner/work/bdk-ffi/bdk-ffi/bdk-python/dist/*.whl
|
||||
|
||||
build-windows-wheel:
|
||||
name: 'Build windows wheel'
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: bdk-python
|
||||
strategy:
|
||||
matrix:
|
||||
python:
|
||||
# - '3.7'
|
||||
# - '3.8'
|
||||
# - '3.9'
|
||||
- '3.10'
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
- run: python --version
|
||||
- run: pip install --user -r requirements.txt
|
||||
- run: bash generate.sh
|
||||
shell: bash
|
||||
- run: pip install --user wheel
|
||||
- name: build wheel
|
||||
run: python setup.py -v bdist_wheel
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: bdkpython-win-${{ matrix.python }}
|
||||
path: D:\a\bdk-ffi\bdk-ffi\bdk-python\dist\*.whl
|
||||
27
.github/workflows/cont_integration.yml
vendored
27
.github/workflows/cont_integration.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: bdk-ffi CI
|
||||
name: Rust layer CI
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
@@ -8,10 +8,9 @@ on:
|
||||
- "bdk-ffi/**"
|
||||
|
||||
jobs:
|
||||
|
||||
build-test:
|
||||
name: Build and test
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
rust:
|
||||
@@ -19,11 +18,13 @@ jobs:
|
||||
clippy: true
|
||||
- version: 1.61.0 # MSRV
|
||||
steps:
|
||||
- name: checkout
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Generate cache key
|
||||
run: echo "${{ matrix.rust.version }} ${{ matrix.features }}" | tee .cache_key
|
||||
- name: cache
|
||||
|
||||
- name: Cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
@@ -31,22 +32,29 @@ jobs:
|
||||
~/.cargo/git
|
||||
target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('.cache_key') }}-${{ hashFiles('**/Cargo.toml','**/Cargo.lock') }}
|
||||
|
||||
- name: Set default toolchain
|
||||
run: rustup default ${{ matrix.rust.version }}
|
||||
|
||||
- name: Set profile
|
||||
run: rustup set profile minimal
|
||||
|
||||
- name: Add clippy
|
||||
if: ${{ matrix.rust.clippy }}
|
||||
run: rustup component add clippy
|
||||
|
||||
- name: Update toolchain
|
||||
run: rustup update
|
||||
|
||||
- name: Build
|
||||
run: cargo build
|
||||
|
||||
- name: Clippy
|
||||
if: ${{ matrix.rust.clippy }}
|
||||
run: cargo clippy --all-targets -- -D warnings
|
||||
run: cargo clippy --all-targets --features "uniffi/bindgen-tests" -- -D warnings
|
||||
|
||||
- name: Test
|
||||
run: CLASSPATH=./tests/jna/jna-5.8.0.jar cargo test
|
||||
run: CLASSPATH=./tests/jna/jna-5.8.0.jar cargo test --features uniffi/bindgen-tests
|
||||
|
||||
fmt:
|
||||
name: Rust fmt
|
||||
@@ -54,13 +62,18 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set default toolchain
|
||||
run: rustup default nightly
|
||||
|
||||
- name: Set profile
|
||||
run: rustup set profile minimal
|
||||
|
||||
- name: Add rustfmt
|
||||
run: rustup component add rustfmt
|
||||
|
||||
- name: Update toolchain
|
||||
run: rustup update
|
||||
|
||||
- name: Check fmt
|
||||
run: cargo fmt --all -- --config format_code_in_doc_comments=true --check
|
||||
|
||||
23
.github/workflows/publish-android.yaml
vendored
23
.github/workflows/publish-android.yaml
vendored
@@ -1,26 +1,28 @@
|
||||
name: Publish bdk-android to Maven Central
|
||||
on: [workflow_dispatch]
|
||||
|
||||
# The default Android NDK on the ubuntu-22.04 image is 25.2.9519653
|
||||
# We replace the default environment variable ANDROID_NDK_ROOT: /usr/local/lib/android/sdk/ndk/25.2.9519653
|
||||
# with an older version of the NDK (21.4.7075529) using the fix proposed here: https://github.com/actions/runner-images/issues/5930
|
||||
# For information on why this is needed at the moment see issues #242 and #243, and PR #282
|
||||
env:
|
||||
ANDROID_NDK_ROOT: /usr/local/lib/android/sdk/ndk/21.4.7075529
|
||||
# By default, the new ubuntu-20.04 images use the following ANDROID_NDK_ROOT
|
||||
# ANDROID_NDK_ROOT: /usr/local/lib/android/sdk/ndk/25.0.8775105
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Install Android NDK 21.4.7075529
|
||||
- name: "Install Android NDK 21.4.7075529"
|
||||
run: |
|
||||
ANDROID_ROOT=/usr/local/lib/android
|
||||
ANDROID_SDK_ROOT=${ANDROID_ROOT}/sdk
|
||||
SDKMANAGER=${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager
|
||||
echo "y" | $SDKMANAGER "ndk;21.4.7075529"
|
||||
|
||||
- name: Check out PR branch
|
||||
- name: "Check out PR branch"
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: cache
|
||||
- name: "Cache"
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
@@ -29,21 +31,24 @@ jobs:
|
||||
./target
|
||||
key: ${{ runner.os }}-${{ hashFiles('**/Cargo.toml','**/Cargo.lock') }}
|
||||
|
||||
- name: Set up JDK
|
||||
- name: "Set up JDK"
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 11
|
||||
|
||||
- name: Install rust android targets
|
||||
- name: "Set default Rust version to 1.67.0"
|
||||
run: rustup default 1.67.0
|
||||
|
||||
- name: "Install Rust Android targets"
|
||||
run: rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabi
|
||||
|
||||
- name: Build bdk-android library
|
||||
- name: "Build bdk-android library"
|
||||
run: |
|
||||
cd bdk-android
|
||||
./gradlew buildAndroidLib
|
||||
|
||||
- name: Publish to Maven Local and Maven Central
|
||||
- name: "Publish to Maven Local and Maven Central"
|
||||
env:
|
||||
ORG_GRADLE_PROJECT_signingKeyId: ${{ secrets.PGP_KEY_ID }}
|
||||
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.PGP_SECRET_KEY }}
|
||||
|
||||
12
.github/workflows/publish-jvm.yaml
vendored
12
.github/workflows/publish-jvm.yaml
vendored
@@ -3,10 +3,10 @@ on: [workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
build-jvm-macOS-M1-native-lib:
|
||||
name: Create M1 and x86_64 JVM native binaries
|
||||
name: "Create M1 and x86_64 JVM native binaries"
|
||||
runs-on: macos-12
|
||||
steps:
|
||||
- name: Checkout publishing branch
|
||||
- name: "Checkout publishing branch"
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Cache
|
||||
@@ -24,6 +24,9 @@ jobs:
|
||||
distribution: temurin
|
||||
java-version: 11
|
||||
|
||||
- name: "Set default Rust version to 1.67.0"
|
||||
run: rustup default 1.67.0
|
||||
|
||||
- name: Install aarch64 Rust target
|
||||
run: rustup target add aarch64-apple-darwin
|
||||
|
||||
@@ -43,7 +46,7 @@ jobs:
|
||||
build-jvm-full-library:
|
||||
name: Create full bdk-jvm library
|
||||
needs: [build-jvm-macOS-M1-native-lib]
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout publishing branch
|
||||
uses: actions/checkout@v2
|
||||
@@ -68,6 +71,9 @@ jobs:
|
||||
distribution: temurin
|
||||
java-version: 11
|
||||
|
||||
- name: "Set default Rust version to 1.67.0"
|
||||
run: rustup default 1.67.0
|
||||
|
||||
- name: Build bdk-jvm library
|
||||
run: |
|
||||
cd bdk-jvm
|
||||
|
||||
112
.github/workflows/publish-python.yaml
vendored
112
.github/workflows/publish-python.yaml
vendored
@@ -8,8 +8,8 @@ on: [workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
build-manylinux2014-x86_64-wheel:
|
||||
name: 'Build Manylinux 2014 x86_64 wheel'
|
||||
runs-on: ubuntu-latest
|
||||
name: "Build Manylinux 2014 x86_64 wheel"
|
||||
runs-on: ubuntu-20.04
|
||||
defaults:
|
||||
run:
|
||||
working-directory: bdk-python
|
||||
@@ -17,127 +17,133 @@ jobs:
|
||||
image: quay.io/pypa/manylinux2014_x86_64
|
||||
env:
|
||||
PLAT: manylinux2014_x86_64
|
||||
PYBIN: '/opt/python/${{ matrix.python }}/bin'
|
||||
PYBIN: "/opt/python/${{ matrix.python }}/bin"
|
||||
strategy:
|
||||
matrix:
|
||||
python: # Update this list whenever the docker image is updated (check /opt/python/)
|
||||
- cp36-cp36m
|
||||
- cp37-cp37m
|
||||
- cp38-cp38
|
||||
- cp39-cp39
|
||||
- cp310-cp310
|
||||
- pp37-pypy37_pp73
|
||||
- pp38-pypy38_pp73
|
||||
steps:
|
||||
- name: checkout
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
- name: install requirements
|
||||
|
||||
- name: "Set default Rust version to 1.67.0"
|
||||
run: rustup default 1.67.0
|
||||
|
||||
- name: "Install requirements"
|
||||
run: ${PYBIN}/pip install -r requirements.txt
|
||||
- name: generate bindings
|
||||
|
||||
- name: "Generate bdk.py and binaries"
|
||||
run: bash generate.sh
|
||||
- name: build wheel
|
||||
run: ${PYBIN}/pip wheel . --no-deps -w /tmp/wheelhouse
|
||||
- name: repair wheel
|
||||
run: auditwheel repair /tmp/wheelhouse/* --plat "$PLAT" -w /tmp/wheelhouse-repaired
|
||||
|
||||
- name: "Build wheel"
|
||||
# Specifying the plat-name argument is necessary to build a wheel with the correct name,
|
||||
# see issue #350 for more information
|
||||
run: ${PYBIN}/python setup.py bdist_wheel --plat-name manylinux_2_17_x86_64 --verbose
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: bdkpython-manylinux2014-x86_64-${{ matrix.python }}
|
||||
path: /tmp/wheelhouse-repaired/*.whl
|
||||
path: /home/runner/work/bdk-ffi/bdk-ffi/bdk-python/dist/*.whl
|
||||
|
||||
build-macos-universal-wheel:
|
||||
name: 'Build macOS universal wheel'
|
||||
runs-on: macos-latest
|
||||
name: "Build macOS universal wheel"
|
||||
runs-on: macos-12
|
||||
defaults:
|
||||
run:
|
||||
working-directory: bdk-python
|
||||
strategy:
|
||||
matrix:
|
||||
python:
|
||||
- '3.7'
|
||||
- '3.8'
|
||||
- '3.9'
|
||||
- '3.10'
|
||||
- "3.8"
|
||||
- "3.9"
|
||||
- "3.10"
|
||||
steps:
|
||||
- name: checkout
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
- run: python3 --version
|
||||
- run: rustup target add aarch64-apple-darwin
|
||||
- run: pip3 install --user -r requirements.txt
|
||||
- run: pip3 install --user wheel
|
||||
- run: bash generate.sh
|
||||
- name: build wheel
|
||||
|
||||
- name: "Generate bdk.py and binaries"
|
||||
run: |
|
||||
python3 --version
|
||||
rustup target add aarch64-apple-darwin
|
||||
pip3 install --user -r requirements.txt
|
||||
bash generate.sh
|
||||
|
||||
- name: "Build wheel"
|
||||
env:
|
||||
ARCHFLAGS: "-arch x86_64 -arch arm64"
|
||||
run: python3 setup.py -v bdist_wheel
|
||||
# Specifying the plat-name argument is necessary to build a wheel with the correct name,
|
||||
# see issue #350 for more information
|
||||
run: python3 setup.py bdist_wheel --plat-name macosx_12_0_universal2 --verbose
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: bdkpython-macos-${{ matrix.python }}
|
||||
path: /Users/runner/work/bdk-ffi/bdk-ffi/bdk-python/dist/*.whl
|
||||
|
||||
build-windows-wheel:
|
||||
name: 'Build windows wheel'
|
||||
runs-on: windows-latest
|
||||
name: "Build Windows wheel"
|
||||
runs-on: windows-2022
|
||||
defaults:
|
||||
run:
|
||||
working-directory: bdk-python
|
||||
strategy:
|
||||
matrix:
|
||||
python:
|
||||
- '3.7'
|
||||
- '3.8'
|
||||
- '3.9'
|
||||
- '3.10'
|
||||
- "3.8"
|
||||
- "3.9"
|
||||
- "3.10"
|
||||
steps:
|
||||
- name: checkout
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
- run: python --version
|
||||
- run: pip install --user -r requirements.txt
|
||||
- run: bash generate.sh
|
||||
shell: bash
|
||||
- run: pip install --user wheel
|
||||
- name: build wheel
|
||||
run: python setup.py -v bdist_wheel
|
||||
|
||||
- name: "Generate bdk.py and binaries"
|
||||
run: |
|
||||
python --version
|
||||
pip install --user -r requirements.txt
|
||||
bash generate.sh
|
||||
|
||||
- name: "Build wheel"
|
||||
run: python setup.py bdist_wheel --verbose
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: bdkpython-win-${{ matrix.python }}
|
||||
path: D:\a\bdk-ffi\bdk-ffi\bdk-python\dist\*.whl
|
||||
|
||||
publish-pypi:
|
||||
name: 'Publish on PyPI'
|
||||
runs-on: ubuntu-latest
|
||||
name: "Publish on PyPI"
|
||||
runs-on: ubuntu-20.04
|
||||
defaults:
|
||||
run:
|
||||
working-directory: bdk-python
|
||||
needs: [build-manylinux2014-x86_64-wheel, build-macos-universal-wheel, build-windows-wheel]
|
||||
# needs: [build-macos-universal-wheel]
|
||||
steps:
|
||||
- name: Checkout
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: 'Download artifacts in dist/ directory'
|
||||
- name: "Download artifacts in dist/ directory"
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
path: dist/
|
||||
|
||||
# - name: Display structure of downloaded files
|
||||
# run: ls -R
|
||||
|
||||
# - name: 'Publish on test PyPI'
|
||||
# - name: "Publish on test PyPI"
|
||||
# uses: pypa/gh-action-pypi-publish@release/v1
|
||||
# with:
|
||||
# user: __token__
|
||||
@@ -145,7 +151,7 @@ jobs:
|
||||
# repository_url: https://test.pypi.org/legacy/
|
||||
# packages_dir: dist/*/
|
||||
|
||||
- name: 'Publish on PyPI'
|
||||
- name: "Publish on PyPI"
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
user: __token__
|
||||
|
||||
31
.github/workflows/test-android.yaml
vendored
31
.github/workflows/test-android.yaml
vendored
@@ -1,5 +1,6 @@
|
||||
name: Test Android
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- "bdk-ffi/**"
|
||||
@@ -9,26 +10,28 @@ on:
|
||||
- "bdk-ffi/**"
|
||||
- "bdk-android/**"
|
||||
|
||||
# The default Android NDK on the ubuntu-22.04 image is 25.2.9519653
|
||||
# We replace the default environment variable ANDROID_NDK_ROOT: /usr/local/lib/android/sdk/ndk/25.2.9519653
|
||||
# with an older version of the NDK (21.4.7075529) using the fix proposed here: https://github.com/actions/runner-images/issues/5930
|
||||
# For information on why this is needed at the moment see issues #242 and #243, and PR #282
|
||||
env:
|
||||
ANDROID_NDK_ROOT: /usr/local/lib/android/sdk/ndk/21.4.7075529
|
||||
# By default, the new ubuntu-20.04 images use the following ANDROID_NDK_ROOT
|
||||
# ANDROID_NDK_ROOT: /usr/local/lib/android/sdk/ndk/25.0.8775105
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Install Android NDK 21.4.7075529
|
||||
- name: "Install Android NDK 21.4.7075529"
|
||||
run: |
|
||||
ANDROID_ROOT=/usr/local/lib/android
|
||||
ANDROID_SDK_ROOT=${ANDROID_ROOT}/sdk
|
||||
SDKMANAGER=${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager
|
||||
echo "y" | $SDKMANAGER "ndk;21.4.7075529"
|
||||
|
||||
- name: Check out PR branch
|
||||
- name: "Check out PR branch"
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: cache
|
||||
- name: "Cache"
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
@@ -37,16 +40,26 @@ jobs:
|
||||
./target
|
||||
key: ${{ runner.os }}-${{ hashFiles('**/Cargo.toml','**/Cargo.lock') }}
|
||||
|
||||
- name: Set up JDK
|
||||
- name: "Set up JDK"
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 11
|
||||
|
||||
- name: Install rust android targets
|
||||
- name: "Set default Rust version to 1.67.0"
|
||||
run: rustup default 1.67.0
|
||||
|
||||
- name: "Install Rust Android targets"
|
||||
run: rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabi
|
||||
|
||||
- name: Run Android tests
|
||||
- name: "Build Android library"
|
||||
run: |
|
||||
cd bdk-android
|
||||
./gradlew test --console=rich
|
||||
./gradlew buildAndroidLib
|
||||
|
||||
# There are currently no unit tests for bdk-android and the integration tests require the macOS image
|
||||
# which is not working with the older NDK version we are using, so for now we just make sure that the library builds.
|
||||
# - name: "Run Android unit tests"
|
||||
# run: |
|
||||
# cd bdk-android
|
||||
# ./gradlew test --console=rich
|
||||
|
||||
8
.github/workflows/test-jvm.yaml
vendored
8
.github/workflows/test-jvm.yaml
vendored
@@ -1,5 +1,6 @@
|
||||
name: Test JVM
|
||||
name: Test Kotlin/JVM
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- "bdk-ffi/**"
|
||||
@@ -16,7 +17,7 @@ jobs:
|
||||
- name: Check out PR branch
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: cache
|
||||
- name: Cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
@@ -31,6 +32,9 @@ jobs:
|
||||
distribution: temurin
|
||||
java-version: 11
|
||||
|
||||
- name: "Set default Rust version to 1.67.0"
|
||||
run: rustup default 1.67.0
|
||||
|
||||
- name: Run JVM tests
|
||||
run: |
|
||||
cd bdk-jvm
|
||||
|
||||
150
.github/workflows/test-python.yaml
vendored
Normal file
150
.github/workflows/test-python.yaml
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
name: Test Python
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- "bdk-ffi/**"
|
||||
- "bdk-python/**"
|
||||
pull_request:
|
||||
paths:
|
||||
- "bdk-ffi/**"
|
||||
- "bdk-python/**"
|
||||
|
||||
# We use manylinux2014 because older CentOS versions used by 2010 and 1 have a very old glibc version, which
|
||||
# makes it very hard to use GitHub's javascript actions (checkout, upload-artifact, etc).
|
||||
# They mount their own nodejs interpreter inside your container, but since that's not statically linked it
|
||||
# tries to load glibc and fails because it requires a more recent version.
|
||||
|
||||
jobs:
|
||||
build-manylinux2014-x86_64-wheel:
|
||||
name: "Build and test Manylinux 2014 x86_64 wheels"
|
||||
runs-on: ubuntu-20.04
|
||||
defaults:
|
||||
run:
|
||||
working-directory: bdk-python
|
||||
container:
|
||||
image: quay.io/pypa/manylinux2014_x86_64
|
||||
env:
|
||||
PLAT: manylinux2014_x86_64
|
||||
PYBIN: "/opt/python/${{ matrix.python }}/bin"
|
||||
strategy:
|
||||
matrix:
|
||||
python:
|
||||
- cp38-cp38
|
||||
- cp39-cp39
|
||||
- cp310-cp310
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
|
||||
- name: "Set default Rust version to 1.67.0"
|
||||
run: rustup default 1.67.0
|
||||
|
||||
- name: "Install requirements"
|
||||
run: ${PYBIN}/pip install -r requirements.txt
|
||||
|
||||
- name: "Generate bdk.py and binaries"
|
||||
run: bash generate.sh
|
||||
|
||||
- name: "Build wheel"
|
||||
# Specifying the plat-name argument is necessary to build a wheel with the correct name,
|
||||
# see issue #350 for more information
|
||||
run: ${PYBIN}/python setup.py bdist_wheel --plat-name manylinux_2_17_x86_64 --verbose
|
||||
|
||||
- name: "Install wheel"
|
||||
run: ${PYBIN}/pip install ./dist/*.whl
|
||||
|
||||
- name: "Run tests"
|
||||
run: ${PYBIN}/python -m unittest tests/test_bdk.py --verbose
|
||||
|
||||
- name: "Upload artifact test"
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: bdkpython-manylinux2014-x86_64-${{ matrix.python }}
|
||||
path: /home/runner/work/bdk-ffi/bdk-ffi/bdk-python/dist/*.whl
|
||||
|
||||
build-macos-universal-wheel:
|
||||
name: "Build and test macOS wheels"
|
||||
runs-on: macos-12
|
||||
defaults:
|
||||
run:
|
||||
working-directory: bdk-python
|
||||
strategy:
|
||||
matrix:
|
||||
python:
|
||||
# 3.8 returns an error for the macos-12 image when we try to install the wheel:
|
||||
# bdkpython-0.28.0.dev0-cp38-cp38-macosx_12_0_universal2.whl is not a supported wheel on this platform.
|
||||
# - "3.8"
|
||||
- "3.9"
|
||||
- "3.10"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
|
||||
- name: "Generate bdk.py and binaries"
|
||||
run: |
|
||||
python3 --version
|
||||
rustup target add aarch64-apple-darwin
|
||||
pip3 install --user -r requirements.txt
|
||||
bash generate.sh
|
||||
|
||||
- name: "Build wheel"
|
||||
env:
|
||||
ARCHFLAGS: "-arch x86_64 -arch arm64"
|
||||
run: python3 setup.py bdist_wheel --plat-name macosx_12_0_universal2 --verbose
|
||||
|
||||
- name: "Install wheel"
|
||||
run: pip3 install ./dist/*.whl
|
||||
|
||||
- name: "Run tests"
|
||||
run: python3 -m unittest tests/test_bdk.py --verbose
|
||||
|
||||
build-windows-wheel:
|
||||
name: "Build and test Windows wheels"
|
||||
runs-on: windows-2022
|
||||
defaults:
|
||||
run:
|
||||
working-directory: bdk-python
|
||||
strategy:
|
||||
matrix:
|
||||
python:
|
||||
- "3.8"
|
||||
- "3.9"
|
||||
- "3.10"
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
|
||||
- name: "Generate bdk.py"
|
||||
run: |
|
||||
python --version
|
||||
pip install --user -r requirements.txt
|
||||
bash generate.sh
|
||||
|
||||
- name: "Build wheel"
|
||||
run: python setup.py bdist_wheel --verbose
|
||||
|
||||
# TODO: On Windows the pip install ./dist/*.whl step fails with the following error:
|
||||
# Run pip install ./dist/*.whl
|
||||
# WARNING: Requirement './dist/*.whl' looks like a filename, but the file does not exist
|
||||
# ERROR: *.whl is not a valid wheel filename.*.whl is not a valid wheel name
|
||||
# So we skip the installing and the tests and simply test that the wheel builds
|
||||
# - name: Install wheel
|
||||
# run: pip install ./dist/*.whl
|
||||
# - name: Run tests
|
||||
# run: python -m unittest tests/test_bdk.py --verbose
|
||||
14
.github/workflows/test-swift.yaml
vendored
14
.github/workflows/test-swift.yaml
vendored
@@ -1,5 +1,6 @@
|
||||
name: Test Swift
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- "bdk-ffi/**"
|
||||
@@ -13,9 +14,12 @@ jobs:
|
||||
build:
|
||||
runs-on: macos-12
|
||||
steps:
|
||||
- name: Checkout branch
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: "Set default Rust version to 1.67.0"
|
||||
run: rustup default 1.67.0
|
||||
|
||||
- name: Install Rust targets
|
||||
run: |
|
||||
rustup install nightly-x86_64-apple-darwin
|
||||
@@ -24,15 +28,15 @@ jobs:
|
||||
|
||||
- name: Run bdk-ffi-bindgen
|
||||
working-directory: bdk-ffi
|
||||
run: cargo run --package bdk-ffi-bindgen -- --language swift --out-dir ../bdk-swift/Sources/BitcoinDevKit
|
||||
run: cargo run --bin uniffi-bindgen generate src/bdk.udl --language swift --out-dir ../bdk-swift/Sources/BitcoinDevKit --no-format
|
||||
|
||||
- name: Build bdk-ffi for x86_64-apple-darwin
|
||||
run: cargo build --profile release-smaller --target x86_64-apple-darwin
|
||||
run: cargo build --package bdk-ffi --profile release-smaller --target x86_64-apple-darwin
|
||||
|
||||
- name: Build bdk-ffi for aarch64-apple-darwin
|
||||
run: cargo build --profile release-smaller --target aarch64-apple-darwin
|
||||
run: cargo build --package bdk-ffi --profile release-smaller --target aarch64-apple-darwin
|
||||
|
||||
- name: Create lipo-ios-sim and lipo-macos
|
||||
- name: Create lipo-macos
|
||||
run: |
|
||||
mkdir -p target/lipo-macos/release-smaller
|
||||
lipo target/aarch64-apple-darwin/release-smaller/libbdkffi.a target/x86_64-apple-darwin/release-smaller/libbdkffi.a -create -output target/lipo-macos/release-smaller/libbdkffi.a
|
||||
|
||||
119
CHANGELOG.md
119
CHANGELOG.md
@@ -1,13 +1,111 @@
|
||||
# Changelog
|
||||
All notable changes to this project prior to release **0.9.0** are documented in this file. Future
|
||||
changelog information can be found in each release's git tag and can be viewed with `git tag -ln100 "v*"`.
|
||||
Changelog info is also documented on the [GitHub releases](https://github.com/bitcoindevkit/bdk-ffi/releases)
|
||||
page. See [DEVELOPMENT_CYCLE.md](DEVELOPMENT_CYCLE.md) for more details.
|
||||
Changelog information can also be found in each release's git tag (which can be viewed with `git tag -ln100 "v*"`), as well as on the [GitHub releases](https://github.com/bitcoindevkit/bdk-ffi/releases) page. See [DEVELOPMENT_CYCLE.md](DEVELOPMENT_CYCLE.md) for more details.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
## [v0.28.0]
|
||||
- Update BDK to version 0.28.0 [#341]
|
||||
- Drop support of pypy releases of Python libraries [#351]
|
||||
- Drop support for Python 3.6 and 3.7 [#351]
|
||||
- Drop support for very old Linux versions that do not support the manylinux_2_17_x86_64 platform tag [#351]
|
||||
- APIs changed:
|
||||
- Expose Address payload and network properties. [#325]
|
||||
- Add SignOptions to Wallet.sign() params. [#326]
|
||||
- address field on `AddressInfo` type is now of type `Address` [#333]
|
||||
- new PartiallySignedTransaction.json_serialize() function to get JSON serialized value of all PSBT fields. [#334]
|
||||
- Add from_script constructor to `Address` type [#337]
|
||||
|
||||
[#325]: https://github.com/bitcoindevkit/bdk-ffi/pull/325
|
||||
[#326]: https://github.com/bitcoindevkit/bdk-ffi/pull/326
|
||||
[#333]: https://github.com/bitcoindevkit/bdk-ffi/pull/333
|
||||
[#334]: https://github.com/bitcoindevkit/bdk-ffi/pull/334
|
||||
[#337]: https://github.com/bitcoindevkit/bdk-ffi/pull/337
|
||||
[#341]: https://github.com/bitcoindevkit/bdk-ffi/pull/341
|
||||
[#351]: https://github.com/bitcoindevkit/bdk-ffi/pull/351
|
||||
|
||||
## [v0.27.1]
|
||||
- Update BDK to version 0.27.1 [#312]
|
||||
- APIs changed
|
||||
- `PartiallySignedTransaction.extract_tx()` returns a `Transaction` instead of the transaction bytes. [#296]
|
||||
- `Blockchain.broadcast()` takes a `Transaction` instead of a `PartiallySignedTransaction`. [#296]
|
||||
- APIs added
|
||||
- New `Transaction` structure that can be created from or serialized to consensus encoded bytes. [#296]
|
||||
- Add Wallet.get_internal_address() API [#304]
|
||||
- Add `AddressIndex::Peek(index)` and `AddressIndex::Reset(index)` APIs [#305]
|
||||
|
||||
[#296]: https://github.com/bitcoindevkit/bdk-ffi/pull/296
|
||||
[#304]: https://github.com/bitcoindevkit/bdk-ffi/pull/304
|
||||
[#305]: https://github.com/bitcoindevkit/bdk-ffi/pull/305
|
||||
[#312]: https://github.com/bitcoindevkit/bdk-ffi/pull/312
|
||||
|
||||
## [v0.26.0]
|
||||
- Update BDK to version 0.26.0 [#288]
|
||||
- APIs changed
|
||||
- The descriptor and change_descriptor arguments on the wallet constructor now take a `Descriptor` instead of a `String`. [#260]
|
||||
- TxBuilder.drain_to() argument is now `Script` instead of address `String`. [#279]
|
||||
- APIs added
|
||||
- Added RpcConfig, BlockchainConfig::Rpc, and Auth [#125]
|
||||
- Added Descriptor type in [#260] with the following methods:
|
||||
- Default constructor requires a descriptor in String format and a Network
|
||||
- new_bip44 constructor returns a Descriptor with structure pkh(key/44'/{0,1}'/0'/{0,1}/*)
|
||||
- new_bip44_public constructor returns a Descriptor with structure pkh(key/{0,1}/*)
|
||||
- new_bip49 constructor returns a Descriptor with structure sh(wpkh(key/49'/{0,1}'/0'/{0,1}/*))
|
||||
- new_bip49_public constructor returns a Descriptor with structure sh(wpkh(key/{0,1}/*))
|
||||
- new_bip84 constructor returns a Descriptor with structure wpkh(key/84'/{0,1}'/0'/{0,1}/*)
|
||||
- new_bip84_public constructor returns a Descriptor with structure wpkh(key/{0,1}/*)
|
||||
- as_string returns the public version of the output descriptor
|
||||
- as_string_private returns the private version of the output descriptor if available, otherwise return the public version
|
||||
|
||||
[#125]: https://github.com/bitcoindevkit/bdk-ffi/pull/125
|
||||
[#260]: https://github.com/bitcoindevkit/bdk-ffi/pull/260
|
||||
[#279]: https://github.com/bitcoindevkit/bdk-ffi/pull/279
|
||||
[#288]: https://github.com/bitcoindevkit/bdk-ffi/pull/288
|
||||
|
||||
## [v0.25.0]
|
||||
- Update BDK to version 0.25.0 [#272]
|
||||
- APIs Added:
|
||||
- from_string() constructors now available on DescriptorSecretKey and DescriptorPublicKey [#247]
|
||||
|
||||
[#247]: https://github.com/bitcoindevkit/bdk-ffi/pull/247
|
||||
[#272]: https://github.com/bitcoindevkit/bdk-ffi/pull/272
|
||||
|
||||
## [v0.11.0]
|
||||
- Update BDK to version 0.24.0 [#221]
|
||||
- APIs changed
|
||||
- The constructor on the DescriptorSecretKey type now takes a Mnemonic instead of a String.
|
||||
- APIs added
|
||||
- Added Mnemonic struct [#219] with following methods:
|
||||
- new(word_count: WordCount) generates and returns Mnemonic with random entropy
|
||||
- from_string(mnemonic: String) converts string Mnemonic to Mnemonic type with error
|
||||
- from_entropy(entropy: Vec<u8>) generates and returns Mnemonic with given entropy
|
||||
- as_string() view Mnemonic as string
|
||||
- APIs removed
|
||||
- generate_mnemonic(word_count: WordCount)
|
||||
|
||||
[#219]: https://github.com/bitcoindevkit/bdk-ffi/pull/219
|
||||
[#221]: https://github.com/bitcoindevkit/bdk-ffi/pull/221
|
||||
|
||||
## [v0.10.0]
|
||||
- Update BDK to version 0.23.0 [#204]
|
||||
- Update uniffi-rs to latest version 0.21.0 [#216]
|
||||
- Breaking Changes
|
||||
- Changed `TxBuilder.finish()` to return new `TxBuilderResult` [#209]
|
||||
- `TxBuilder.add_recipient()` now takes a `Script` instead of an `Address` [#192]
|
||||
- `AddressAmount` is now `ScriptAmount` [#192]
|
||||
- APIs Added
|
||||
- Added `TxBuilderResult` with PSBT and TransactionDetails [#209]
|
||||
- `Address` and `Script` structs have been added [#192]
|
||||
- Add `PartiallySignedBitcoinTransaction.extract_tx()` function [#192]
|
||||
- Add `secret_bytes()` method on the `DescriptorSecretKey` [#199]
|
||||
- Add `PartiallySignedBitcoinTransaction.combine()` method [#200]
|
||||
|
||||
[#192]: https://github.com/bitcoindevkit/bdk-ffi/pull/192
|
||||
[#199]: https://github.com/bitcoindevkit/bdk-ffi/pull/199
|
||||
[#200]: https://github.com/bitcoindevkit/bdk-ffi/pull/200
|
||||
[#204]: https://github.com/bitcoindevkit/bdk-ffi/pull/204
|
||||
[#209]: https://github.com/bitcoindevkit/bdk-ffi/pull/209
|
||||
[#216]: https://github.com/bitcoindevkit/bdk-ffi/pull/216
|
||||
|
||||
## [v0.9.0]
|
||||
- Breaking Changes
|
||||
@@ -22,7 +120,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- APIs Added [#154]
|
||||
- `generate_mnemonic()`, returns string mnemonic
|
||||
- `interface DescriptorSecretKey`
|
||||
- `new(Network, string_mnenoinc, password)`, contructs DescriptorSecretKey
|
||||
- `new(Network, string_mnenoinc, password)`, constructs DescriptorSecretKey
|
||||
- `derive(DerivationPath)`, derives and returns child DescriptorSecretKey
|
||||
- `extend(DerivationPath)`, extends and returns DescriptorSecretKey
|
||||
- `as_public()`, returns DescriptorSecretKey as DescriptorPublicKey
|
||||
@@ -102,9 +200,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
[BIP 0174]:https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#encoding
|
||||
|
||||
## [v0.2.0]
|
||||
|
||||
[unreleased]: https://github.com/bitcoindevkit/bdk-ffi/compare/v0.9.0...HEAD
|
||||
[v0.28.0]: https://github.com/bitcoindevkit/bdk-ffi/compare/v0.27.1...v0.28.0
|
||||
[v0.27.1]: https://github.com/bitcoindevkit/bdk-ffi/compare/v0.26.0...v0.27.1
|
||||
[v0.26.0]: https://github.com/bitcoindevkit/bdk-ffi/compare/v0.25.0...v0.26.0
|
||||
[v0.25.0]: https://github.com/bitcoindevkit/bdk-ffi/compare/v0.11.0...v0.25.0
|
||||
[v0.11.0]: https://github.com/bitcoindevkit/bdk-ffi/compare/v0.10.0...v0.11.0
|
||||
[v0.10.0]: https://github.com/bitcoindevkit/bdk-ffi/compare/v0.9.0...v0.10.0
|
||||
[v0.9.0]: https://github.com/bitcoindevkit/bdk-ffi/compare/v0.8.0...v0.9.0
|
||||
[v0.8.0]: https://github.com/bitcoindevkit/bdk-ffi/compare/v0.7.0...v0.8.0
|
||||
[v0.7.0]: https://github.com/bitcoindevkit/bdk-ffi/compare/v0.6.0...v0.7.0
|
||||
|
||||
548
Cargo.lock
generated
548
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
[workspace]
|
||||
members = ["bdk-ffi", "bdk-ffi-bindgen"]
|
||||
default-members = ["bdk-ffi", "bdk-ffi-bindgen"]
|
||||
members = ["bdk-ffi"]
|
||||
default-members = ["bdk-ffi"]
|
||||
exclude = ["api-docs", "bdk-android", "bdk-jvm", "bdk-python", "bdk-swift"]
|
||||
|
||||
[profile.release-smaller]
|
||||
@@ -9,4 +9,4 @@ 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 = true # Strip symbols from binary*
|
||||
strip = true # Strip symbols from binary*
|
||||
|
||||
10
README.md
10
README.md
@@ -8,8 +8,7 @@
|
||||
</p>
|
||||
|
||||
The workspace in this repository creates the `libbdkffi` multi-language library for the Rust-based
|
||||
[bdk] library from the [Bitcoin Dev Kit] project. The `bdk-ffi-bindgen` package builds a tool for
|
||||
generating the actual language binding code used to access the `libbdkffi` library.
|
||||
[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.
|
||||
|
||||
@@ -23,13 +22,6 @@ The below directories (a separate repository in the case of bdk-swift) include i
|
||||
| Swift | iOS, macOS | [bdk-swift (GitHub)] | [Readme bdk-swift] | |
|
||||
| Python | linux, macOS, Windows | [bdk-python (PyPI)] | [Readme bdk-python] | |
|
||||
|
||||
## Language bindings generator tool
|
||||
Use the `bdk-ffi-bindgen` tool to generate language binding code for the above supported languages.
|
||||
To run `bdk-ffi-bindgen` and see the available options use the command:
|
||||
```shell
|
||||
cargo run -p bdk-ffi-bindgen -- --help
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
### Adding new structs and functions
|
||||
|
||||
@@ -24,12 +24,14 @@ enum class Network {
|
||||
*
|
||||
* @property index Child index of this address.
|
||||
* @property address Address.
|
||||
* @property keychain Type of keychain.
|
||||
*
|
||||
* @sample org.bitcoindevkit.addressInfoSample
|
||||
*/
|
||||
data class AddressInfo (
|
||||
var index: UInt,
|
||||
var address: String
|
||||
var address: Address,
|
||||
var keychain: KeychainKind
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -248,6 +250,7 @@ sealed class BlockchainConfig {
|
||||
* @property confirmationTime If the transaction is confirmed, [BlockTime] contains height and timestamp of the block containing the transaction. This property is null for unconfirmed transactions.
|
||||
*/
|
||||
data class TransactionDetails (
|
||||
var transaction?: Transaction,
|
||||
var fee: ULong?,
|
||||
var received: ULong,
|
||||
var sent: ULong,
|
||||
@@ -288,8 +291,60 @@ class Blockchain(
|
||||
* @param transactionBytes The transaction bytes, bitcoin consensus encoded.
|
||||
*/
|
||||
class Transaction(transactionBytes: List<UByte>) {
|
||||
/** Computes the txid. */
|
||||
fun txid(): String {}
|
||||
|
||||
/**
|
||||
* Returns the "weight" of this transaction, as defined by BIP141.
|
||||
*
|
||||
* For transactions with an empty witness, this is simply the consensus-serialized size times four.
|
||||
* For transactions with a witness, this is the non-witness consensus-serialized size multiplied by three
|
||||
* plus the with-witness consensus-serialized size.
|
||||
*/
|
||||
fun weight(): ULong {}
|
||||
|
||||
/** Returns the regular byte-wise consensus-serialized size of this transaction. */
|
||||
fun size(): ULong {}
|
||||
|
||||
/**
|
||||
* Returns the "virtual size" (vsize) of this transaction.
|
||||
*
|
||||
* Will be ceil(weight / 4.0). Note this implements the virtual size as per BIP141, which is different to
|
||||
* what is implemented in Bitcoin Core. The computation should be the same for any remotely sane transaction.
|
||||
*/
|
||||
fun vsize(): ULong {}
|
||||
|
||||
/** Return the transaction bytes, bitcoin consensus encoded. */
|
||||
fun serialize(): List<UByte> {}
|
||||
|
||||
/** Is this a coin base transaction? */
|
||||
fun isCoinBase(): Boolean {}
|
||||
|
||||
/**
|
||||
* Returns true if the transaction itself opted in to be BIP-125-replaceable (RBF).
|
||||
* This does not cover the case where a transaction becomes replaceable due to ancestors being RBF.
|
||||
*/
|
||||
fun isExplicitlyRbf(): Boolean {}
|
||||
|
||||
/** Returns true if this transactions nLockTime is enabled (BIP-65). */
|
||||
fun isLockTimeEnabled(): Boolean {}
|
||||
|
||||
/** The protocol version, is currently expected to be 1 or 2 (BIP 68). */
|
||||
fun version(): Int {}
|
||||
|
||||
/**
|
||||
* Block height or timestamp. Transaction cannot be included in a block until this height/time.
|
||||
* Relevant BIPs
|
||||
* BIP-65 OP_CHECKLOCKTIMEVERIFY
|
||||
* BIP-113 Median time-past as endpoint for lock-time calculations
|
||||
*/
|
||||
fun lockTime(): UInt {}
|
||||
|
||||
/** List of transaction inputs. */
|
||||
fun input(): List<TxIn> {}
|
||||
|
||||
/** List of transaction outputs. */
|
||||
fun output(): List<TxOut> {}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,6 +369,9 @@ class PartiallySignedTransaction(psbtBase64: String) {
|
||||
* In accordance with BIP 174 this function is commutative i.e., `A.combine(B) == B.combine(A)`
|
||||
*/
|
||||
fun combine(other: PartiallySignedTransaction): PartiallySignedTransaction
|
||||
|
||||
/** Serialize the PSBT data structure as a String of JSON. */
|
||||
fun jsonSerialize(): String
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,11 +389,29 @@ data class OutPoint (
|
||||
* A transaction output, which defines new coins to be created from old ones.
|
||||
*
|
||||
* @property value The value of the output, in satoshis.
|
||||
* @property address The address of the output.
|
||||
* @property scriptPubkey The script which must be satisfied for the output to be spent.
|
||||
*/
|
||||
data class TxOut (
|
||||
var value: ULong,
|
||||
var address: String
|
||||
var scriptPubkey: Script
|
||||
)
|
||||
|
||||
/**
|
||||
* Bitcoin transaction input.
|
||||
*
|
||||
* It contains the location of the previous transaction’s output, that it spends and set of scripts that satisfy its spending conditions.
|
||||
*
|
||||
* @property previousOutput The reference to the previous output that is being used an an input.
|
||||
* @property scriptSig The script which pushes values on the stack which will cause the referenced output’s script to be accepted.
|
||||
* @property sequence The sequence number, which suggests to miners which of two conflicting transactions should be preferred, or 0xFFFFFFFF to ignore this feature. This is generally never used since the miner behaviour cannot be enforced.
|
||||
* @property witness Witness data: an array of byte-arrays. Note that this field is not (de)serialized with the rest of the TxIn in Encodable/Decodable, as it is (de)serialized at the end of the full Transaction. It is (de)serialized with the rest of the TxIn in other (de)serialization routines.
|
||||
*
|
||||
*/
|
||||
data class TxIn (
|
||||
var previousOutput: OutPoint,
|
||||
var scriptSig: Script,
|
||||
var sequence: UInt,
|
||||
var witness: List<List<UByte>>
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -413,14 +489,29 @@ class Wallet(
|
||||
*/
|
||||
fun getInternalAddress(addressIndex: AddressIndex): AddressInfo {}
|
||||
|
||||
/** Return whether or not a script is part of this wallet (either internal or external). */
|
||||
fun isMine(script: Script): Boolean {}
|
||||
|
||||
/** Return the wallet's balance, across different categories. See [Balance] for the categories. Note that this method only operates on the internal database, which first needs to be [Wallet.sync] manually. */
|
||||
fun getBalance(): Balance {}
|
||||
|
||||
/** Sign a transaction with all the wallet’s signers. */
|
||||
fun sign(psbt: PartiallySignedTransaction): Boolean {}
|
||||
/**
|
||||
* Sign a transaction with all the wallet's signers, in the order specified by every signer's
|
||||
* `SignerOrdering`.
|
||||
*
|
||||
* The `SignOptions` can be used to tweak the behavior of the software signers, and the way
|
||||
* the transaction is finalized at the end. Note that it can't be guaranteed that *every*
|
||||
* signers will follow the options, but the "software signers" (WIF keys and `xprv`) defined
|
||||
* in this library will.
|
||||
*
|
||||
* @param psbt PSBT to be signed
|
||||
* @param signOptions signing options
|
||||
* @return true if the PSBT was finalized, or false otherwise
|
||||
*/
|
||||
fun sign(psbt: PartiallySignedTransaction, signOptions: SignOptions?): Boolean {}
|
||||
|
||||
/** Return the list of transactions made and received by the wallet. Note that this method only operate on the internal database, which first needs to be [Wallet.sync] manually. */
|
||||
fun listTransactions(): List<TransactionDetails> {}
|
||||
fun listTransactions(includeRaw: Boolean): List<TransactionDetails> {}
|
||||
|
||||
/** Get the Bitcoin network the wallet is using. */
|
||||
fun network(): Network {}
|
||||
@@ -525,6 +616,29 @@ class TxBuilder() {
|
||||
fun finish(wallet: Wallet): TxBuilderResult {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for a software signer.
|
||||
*
|
||||
* Adjust the behavior of our software signers and the way a transaction is finalized.
|
||||
*
|
||||
* @property trustWitnessUtxo Whether the signer should trust the `witness_utxo`, if the `non_witness_utxo` hasn't been provided. Defaults to `false`.
|
||||
* @property assumeHeight Whether the wallet should assume a specific height has been reached when trying to finalize a transaction.
|
||||
* @property allowAllSighashes Whether the signer should use the sighash_type set in the PSBT when signing, no matter what its value is. Defaults to `false`.
|
||||
* @property removePartialSigs Whether to remove partial signatures from the PSBT inputs while finalizing PSBT. Defaults to `true`.
|
||||
* @property tryFinalize Whether to try finalizing the PSBT after the inputs are signed. Defaults to `true`.
|
||||
* @property signWithTapInternalKey Whether we should try to sign a taproot transaction with the taproot internal key or not. This option is ignored if we're signing a non-taproot PSBT. Defaults to `true`.
|
||||
* @property allowGrinding Whether we should grind ECDSA signature to ensure signing with low r or not. Defaults to `true`.
|
||||
*/
|
||||
data class SignOptions (
|
||||
var trustWitnessUtxo: Boolean,
|
||||
var assumeHeight: UInt?,
|
||||
var allowAllSighashes: Boolean,
|
||||
var removePartialSigs: Boolean,
|
||||
var tryFinalize: Boolean,
|
||||
var signWithTapInternalKey: Boolean,
|
||||
var allowGrinding: Boolean
|
||||
)
|
||||
|
||||
/**
|
||||
* A object holding a ScriptPubKey and an amount.
|
||||
*
|
||||
@@ -715,7 +829,10 @@ data class TxBuilderResult (
|
||||
/**
|
||||
* A bitcoin script.
|
||||
*/
|
||||
class Script(rawOutputScript: List<UByte>)
|
||||
class Script(rawOutputScript: List<UByte>) {
|
||||
/** Return the script as bytes. */
|
||||
fun toBytes(): List<UByte> {}
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitcoin address.
|
||||
@@ -723,8 +840,62 @@ class Script(rawOutputScript: List<UByte>)
|
||||
* @param address The address in string format.
|
||||
*/
|
||||
class Address(address: String) {
|
||||
/** Construct an [`Address`] from an output script. */
|
||||
fun fromScript(script: Script, network: Network): Address {}
|
||||
|
||||
/** Return the Payload */
|
||||
fun payload(): Payload
|
||||
|
||||
/** Return the Network. */
|
||||
fun network(): Network
|
||||
|
||||
/** Return the ScriptPubKey. */
|
||||
fun scriptPubkey(): Script
|
||||
|
||||
/**
|
||||
* Creates a URI string bitcoin:address optimized to be encoded in QR codes.
|
||||
*
|
||||
* If the address is bech32, both the schema and the address become uppercase. If the address is base58, the schema is lowercase and the address is left mixed case.
|
||||
*
|
||||
* Quoting BIP 173 "inside QR codes uppercase SHOULD be used, as those permit the use of alphanumeric mode, which is 45% more compact than the normal byte mode."
|
||||
*/
|
||||
fun toQrUri(): String
|
||||
|
||||
/** Return the address as a string. */
|
||||
fun asString(): String
|
||||
}}
|
||||
|
||||
/**
|
||||
* The method used to produce an address.
|
||||
*/
|
||||
sealed class Payload {
|
||||
/** P2PKH address. */
|
||||
data class PubkeyHash(
|
||||
val pubkeyHash: List<UByte>
|
||||
) : Payload()
|
||||
|
||||
/** P2SH address. */
|
||||
data class ScriptHash(
|
||||
val scriptHash: List<UByte>
|
||||
) : Payload()
|
||||
|
||||
/** Segwit address. */
|
||||
data class WitnessProgram(
|
||||
val version: WitnessVersion,
|
||||
val program: List<UByte>
|
||||
) : Payload()
|
||||
}
|
||||
|
||||
/**
|
||||
* Version of the witness program.
|
||||
*
|
||||
* Helps limit possible versions of the witness according to the specification. If a plain u8 type
|
||||
* was used instead it would mean that the version may be > 16, which would be incorrect.
|
||||
* First byte of scriptPubkey in transaction output for transactions starting with opcodes ranging
|
||||
* from 0 to 16 (inclusive).
|
||||
*/
|
||||
enum class WitnessVersion {
|
||||
V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -87,7 +87,7 @@ fun addressInfoSample() {
|
||||
|
||||
val newAddress: AddressInfo = wallet.getAddress(AddressIndex.New)
|
||||
|
||||
println("New address at index ${newAddress.index} is ${newAddress.address}")
|
||||
println("New address at index ${newAddress.index} is ${newAddress.address.asString()}")
|
||||
}
|
||||
|
||||
fun blockchainSample() {
|
||||
|
||||
@@ -19,8 +19,8 @@ import org.bitcoindevkit.*
|
||||
|
||||
// ...
|
||||
|
||||
val externalDescriptor = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"
|
||||
val internalDescriptor = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"
|
||||
val externalDescriptor = Descriptor("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)", Network.TESTNET)
|
||||
val internalDescriptor = Descriptor("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)", Network.TESTNET)
|
||||
|
||||
val databaseConfig = DatabaseConfig.Memory
|
||||
|
||||
@@ -54,19 +54,23 @@ _Note that Kotlin version `1.6.10` or later is required to build the library._
|
||||
```shell
|
||||
git clone https://github.com/bitcoindevkit/bdk-ffi
|
||||
```
|
||||
2. Follow the "General" bdk-ffi ["Getting Started (Developer)"] instructions.
|
||||
3. If building on macOS install required intel and m1 jvm targets
|
||||
2. Follow the "General" bdk-ffi ["Getting Started (Developer)"] instructions.
|
||||
3. Install Rust (note that we are currently building using Rust 1.67.0):
|
||||
```shell
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
rustup default 1.67.0
|
||||
```
|
||||
4. Install required targets
|
||||
```sh
|
||||
rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabi
|
||||
```
|
||||
```sh
|
||||
rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabi
|
||||
```
|
||||
5. Install Android SDK and Build-Tools for API level 30+
|
||||
6. Setup `$ANDROID_SDK_ROOT` and `$ANDROID_NDK_ROOT` path variables (which are required by the
|
||||
build tool), for example (NDK major version 21 is required):
|
||||
```shell
|
||||
export ANDROID_SDK_ROOT=~/Android/Sdk
|
||||
export ANDROID_NDK_ROOT=$ANDROID_SDK_ROOT/ndk/21.<NDK_VERSION>
|
||||
```
|
||||
build tool), for example (note that currently, NDK version 21.4.7075529 is required):
|
||||
```shell
|
||||
export ANDROID_SDK_ROOT=~/Android/Sdk
|
||||
export ANDROID_NDK_ROOT=$ANDROID_SDK_ROOT/ndk/21.4.7075529
|
||||
```
|
||||
7. Build kotlin bindings
|
||||
```sh
|
||||
# build Android library
|
||||
|
||||
@@ -2,4 +2,4 @@ org.gradle.jvmargs=-Xmx1536m
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
kotlin.code.style=official
|
||||
libraryVersion=0.27.1
|
||||
libraryVersion=0.29.0
|
||||
|
||||
@@ -54,7 +54,7 @@ class AndroidLibTest {
|
||||
@Test
|
||||
fun memoryWalletNewAddress() {
|
||||
val wallet = Wallet(descriptor, null, Network.TESTNET, databaseConfig)
|
||||
val address = wallet.getAddress(AddressIndex.New).address
|
||||
val address = wallet.getAddress(AddressIndex.New).address.asString()
|
||||
assertEquals("tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e", address)
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,7 @@ internal class UniFfiAndroidPlugin : Plugin<Project> {
|
||||
val buildAndroidAarch64Binary by tasks.register<Exec>("buildAndroidAarch64Binary") {
|
||||
|
||||
workingDir("${projectDir}/../../bdk-ffi")
|
||||
val cargoArgs: MutableList<String> =
|
||||
mutableListOf("build", "--profile", "release-smaller", "--target", "aarch64-linux-android")
|
||||
val cargoArgs: List<String> = listOf("build", "--profile", "release-smaller", "--target", "aarch64-linux-android")
|
||||
|
||||
executable("cargo")
|
||||
args(cargoArgs)
|
||||
@@ -36,10 +35,9 @@ internal class UniFfiAndroidPlugin : Plugin<Project> {
|
||||
|
||||
environment(
|
||||
// add build toolchain to PATH
|
||||
Pair("PATH",
|
||||
"${System.getenv("PATH")}:${System.getenv("ANDROID_NDK_ROOT")}/toolchains/llvm/prebuilt/$llvmArchPath/bin"),
|
||||
|
||||
Pair("CFLAGS", "-D__ANDROID_API__=21"),
|
||||
Pair("PATH", "${System.getenv("PATH")}:${System.getenv("ANDROID_NDK_ROOT")}/toolchains/llvm/prebuilt/$llvmArchPath/bin"),
|
||||
Pair("CFLAGS", "-D__ANDROID_MIN_SDK_VERSION__=21"),
|
||||
Pair("AR", "llvm-ar"),
|
||||
Pair("CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER", "aarch64-linux-android21-clang"),
|
||||
Pair("CC", "aarch64-linux-android21-clang")
|
||||
)
|
||||
@@ -53,8 +51,7 @@ internal class UniFfiAndroidPlugin : Plugin<Project> {
|
||||
val buildAndroidX86_64Binary by tasks.register<Exec>("buildAndroidX86_64Binary") {
|
||||
|
||||
workingDir("${project.projectDir}/../../bdk-ffi")
|
||||
val cargoArgs: MutableList<String> =
|
||||
mutableListOf("build", "--profile", "release-smaller", "--target", "x86_64-linux-android")
|
||||
val cargoArgs: List<String> = listOf("build", "--profile", "release-smaller", "--target", "x86_64-linux-android")
|
||||
|
||||
executable("cargo")
|
||||
args(cargoArgs)
|
||||
@@ -68,10 +65,9 @@ internal class UniFfiAndroidPlugin : Plugin<Project> {
|
||||
|
||||
environment(
|
||||
// add build toolchain to PATH
|
||||
Pair("PATH",
|
||||
"${System.getenv("PATH")}:${System.getenv("ANDROID_NDK_ROOT")}/toolchains/llvm/prebuilt/$llvmArchPath/bin"),
|
||||
|
||||
Pair("CFLAGS", "-D__ANDROID_API__=21"),
|
||||
Pair("PATH", "${System.getenv("PATH")}:${System.getenv("ANDROID_NDK_ROOT")}/toolchains/llvm/prebuilt/$llvmArchPath/bin"),
|
||||
Pair("CFLAGS", "-D__ANDROID_MIN_SDK_VERSION__=21"),
|
||||
Pair("AR", "llvm-ar"),
|
||||
Pair("CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER", "x86_64-linux-android21-clang"),
|
||||
Pair("CC", "x86_64-linux-android21-clang")
|
||||
)
|
||||
@@ -85,8 +81,7 @@ internal class UniFfiAndroidPlugin : Plugin<Project> {
|
||||
val buildAndroidArmv7Binary by tasks.register<Exec>("buildAndroidArmv7Binary") {
|
||||
|
||||
workingDir("${project.projectDir}/../../bdk-ffi")
|
||||
val cargoArgs: MutableList<String> =
|
||||
mutableListOf("build", "--profile", "release-smaller", "--target", "armv7-linux-androideabi")
|
||||
val cargoArgs: List<String> = listOf("build", "--profile", "release-smaller", "--target", "armv7-linux-androideabi")
|
||||
|
||||
executable("cargo")
|
||||
args(cargoArgs)
|
||||
@@ -100,12 +95,10 @@ internal class UniFfiAndroidPlugin : Plugin<Project> {
|
||||
|
||||
environment(
|
||||
// add build toolchain to PATH
|
||||
Pair("PATH",
|
||||
"${System.getenv("PATH")}:${System.getenv("ANDROID_NDK_ROOT")}/toolchains/llvm/prebuilt/$llvmArchPath/bin"),
|
||||
|
||||
Pair("CFLAGS", "-D__ANDROID_API__=21"),
|
||||
Pair("CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER",
|
||||
"armv7a-linux-androideabi21-clang"),
|
||||
Pair("PATH", "${System.getenv("PATH")}:${System.getenv("ANDROID_NDK_ROOT")}/toolchains/llvm/prebuilt/$llvmArchPath/bin"),
|
||||
Pair("CFLAGS", "-D__ANDROID_MIN_SDK_VERSION__=21"),
|
||||
Pair("AR", "llvm-ar"),
|
||||
Pair("CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER", "armv7a-linux-androideabi21-clang"),
|
||||
Pair("CC", "armv7a-linux-androideabi21-clang")
|
||||
)
|
||||
|
||||
@@ -145,17 +138,10 @@ internal class UniFfiAndroidPlugin : Plugin<Project> {
|
||||
dependsOn(moveNativeAndroidLibs)
|
||||
|
||||
workingDir("${project.projectDir}/../../bdk-ffi")
|
||||
val cargoArgs: List<String> = listOf("run", "--bin", "uniffi-bindgen", "generate", "src/bdk.udl", "--language", "kotlin", "--out-dir", "../bdk-android/lib/src/main/kotlin", "--no-format")
|
||||
|
||||
executable("cargo")
|
||||
args(
|
||||
"run",
|
||||
"--package",
|
||||
"bdk-ffi-bindgen",
|
||||
"--",
|
||||
"--language",
|
||||
"kotlin",
|
||||
"--out-dir",
|
||||
"../bdk-android/lib/src/main/kotlin"
|
||||
)
|
||||
args(cargoArgs)
|
||||
|
||||
doLast {
|
||||
println("Android bindings file successfully created")
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
[package]
|
||||
name = "bdk-ffi-bindgen"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.45" # remove after upgrading to next version of uniffi
|
||||
structopt = "0.3"
|
||||
uniffi_bindgen = "0.21.0"
|
||||
camino = "1.0.9"
|
||||
@@ -1,138 +0,0 @@
|
||||
use camino::Utf8Path;
|
||||
use std::fmt;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum Language {
|
||||
Kotlin,
|
||||
Python,
|
||||
Swift,
|
||||
}
|
||||
|
||||
impl fmt::Display for Language {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Language::Kotlin => write!(f, "kotlin"),
|
||||
Language::Swift => write!(f, "swift"),
|
||||
Language::Python => write!(f, "python"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
UnsupportedLanguage,
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Language {
|
||||
type Err = Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"kotlin" => Ok(Language::Kotlin),
|
||||
"python" => Ok(Language::Python),
|
||||
"swift" => Ok(Language::Swift),
|
||||
_ => Err(Error::UnsupportedLanguage),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_bindings(opt: &Opt) -> anyhow::Result<(), anyhow::Error> {
|
||||
let path: &Utf8Path = Utf8Path::from_path(&opt.udl_file).unwrap();
|
||||
let out_dir: &Utf8Path = Utf8Path::from_path(&opt.out_dir).unwrap();
|
||||
uniffi_bindgen::generate_bindings(
|
||||
path,
|
||||
None,
|
||||
vec![opt.language.to_string().as_str()],
|
||||
Some(out_dir),
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fixup_python_lib_path(
|
||||
out_dir: &Path,
|
||||
lib_name: &Path,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
|
||||
const LOAD_INDIRECT_DEF: &str = "def loadIndirect():";
|
||||
|
||||
let bindings_file = out_dir.join("bdk.py");
|
||||
let mut data = fs::read_to_string(&bindings_file)?;
|
||||
|
||||
let pos = data
|
||||
.find(LOAD_INDIRECT_DEF)
|
||||
.unwrap_or_else(|| panic!("loadIndirect not found in `{}`", bindings_file.display()));
|
||||
let range = pos..pos + LOAD_INDIRECT_DEF.len();
|
||||
|
||||
let replacement = format!(
|
||||
r#"
|
||||
def loadIndirect():
|
||||
import glob
|
||||
return getattr(ctypes.cdll, glob.glob(os.path.join(os.path.dirname(os.path.abspath(__file__)), '{}.*'))[0])
|
||||
|
||||
def _loadIndirectOld():"#,
|
||||
&lib_name.to_str().expect("lib name")
|
||||
);
|
||||
data.replace_range(range, &replacement);
|
||||
|
||||
let mut file = fs::OpenOptions::new()
|
||||
.write(true)
|
||||
.truncate(true)
|
||||
.open(&bindings_file)?;
|
||||
file.write_all(data.as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(
|
||||
name = "bdk-ffi-bindgen",
|
||||
about = "A tool to generate bdk-ffi language bindings"
|
||||
)]
|
||||
struct Opt {
|
||||
/// UDL file
|
||||
#[structopt(env = "BDKFFI_BINDGEN_UDL", short, long, default_value("src/bdk.udl"), parse(try_from_str = PathBuf::from_str))]
|
||||
udl_file: PathBuf,
|
||||
|
||||
/// Language to generate bindings for
|
||||
#[structopt(env = "BDKFFI_BINDGEN_LANGUAGE", short, long, possible_values(&["kotlin","swift","python"]), parse(try_from_str = Language::from_str))]
|
||||
language: Language,
|
||||
|
||||
/// Output directory to put generated language bindings
|
||||
#[structopt(env = "BDKFFI_BINDGEN_OUTPUT_DIR", short, long, parse(try_from_str = PathBuf::from_str))]
|
||||
out_dir: PathBuf,
|
||||
|
||||
/// Python fix up lib path
|
||||
#[structopt(env = "BDKFFI_BINDGEN_PYTHON_FIXUP_PATH", short, long, parse(try_from_str = PathBuf::from_str))]
|
||||
python_fixup_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let opt = Opt::from_args();
|
||||
|
||||
println!("Input UDL file is {:?}", opt.udl_file);
|
||||
println!("Chosen language is {}", opt.language);
|
||||
println!("Output directory is {:?}", opt.out_dir);
|
||||
|
||||
generate_bindings(&opt)?;
|
||||
|
||||
if opt.language == Language::Python {
|
||||
if let Some(path) = opt.python_fixup_path {
|
||||
println!("Fixing up python lib path, {:?}", &path);
|
||||
fixup_python_lib_path(&opt.out_dir, &path)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,21 +1,28 @@
|
||||
[package]
|
||||
name = "bdk-ffi"
|
||||
version = "0.27.0"
|
||||
version = "0.29.0"
|
||||
authors = ["Steve Myers <steve@notmandatory.org>", "Sudarsan Balaji <sudarsan.balaji@artfuldev.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib", "cdylib"]
|
||||
crate-type = ["lib", "staticlib", "cdylib"]
|
||||
name = "bdkffi"
|
||||
|
||||
[[bin]]
|
||||
name = "uniffi-bindgen"
|
||||
path = "uniffi-bindgen.rs"
|
||||
|
||||
[features]
|
||||
default = ["uniffi/cli"]
|
||||
|
||||
[dependencies]
|
||||
bdk = { version = "0.27.1", features = ["all-keys", "use-esplora-ureq", "sqlite-bundled", "rpc"] }
|
||||
uniffi_macros = { version = "0.21.0", features = ["builtin-bindgen"] }
|
||||
uniffi = { version = "0.21.0", features = ["builtin-bindgen"] }
|
||||
bdk = { version = "0.28", features = ["all-keys", "use-esplora-ureq", "sqlite-bundled", "rpc"] }
|
||||
uniffi = { version = "0.23.0" }
|
||||
|
||||
[build-dependencies]
|
||||
uniffi_build = { version = "0.21.0", features = ["builtin-bindgen"] }
|
||||
uniffi = { version = "0.23.0", features = ["build"] }
|
||||
|
||||
[dev-dependencies]
|
||||
uniffi = { version = "0.23.0", features = ["bindgen-tests"] }
|
||||
assert_matches = "1.5.0"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
fn main() {
|
||||
uniffi_build::generate_scaffolding("src/bdk.udl").unwrap();
|
||||
uniffi::generate_scaffolding("./src/bdk.udl").unwrap();
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@ enum BdkError {
|
||||
|
||||
dictionary AddressInfo {
|
||||
u32 index;
|
||||
string address;
|
||||
Address address;
|
||||
KeychainKind keychain;
|
||||
};
|
||||
|
||||
[Enum]
|
||||
@@ -94,6 +95,7 @@ interface DatabaseConfig {
|
||||
};
|
||||
|
||||
dictionary TransactionDetails {
|
||||
Transaction? transaction;
|
||||
u64? fee;
|
||||
u64 received;
|
||||
u64 sent;
|
||||
@@ -186,9 +188,16 @@ dictionary OutPoint {
|
||||
u32 vout;
|
||||
};
|
||||
|
||||
dictionary TxIn {
|
||||
OutPoint previous_output;
|
||||
Script script_sig;
|
||||
u32 sequence;
|
||||
sequence<sequence<u8>> witness;
|
||||
};
|
||||
|
||||
dictionary TxOut {
|
||||
u64 value;
|
||||
string address;
|
||||
Script script_pubkey;
|
||||
};
|
||||
|
||||
enum KeychainKind {
|
||||
@@ -212,6 +221,8 @@ interface Wallet {
|
||||
[Throws=BdkError]
|
||||
constructor(Descriptor descriptor, Descriptor? change_descriptor, Network network, DatabaseConfig database_config);
|
||||
|
||||
Network network();
|
||||
|
||||
[Throws=BdkError]
|
||||
AddressInfo get_address(AddressIndex address_index);
|
||||
|
||||
@@ -219,21 +230,22 @@ interface Wallet {
|
||||
AddressInfo get_internal_address(AddressIndex address_index);
|
||||
|
||||
[Throws=BdkError]
|
||||
Balance get_balance();
|
||||
|
||||
[Throws=BdkError]
|
||||
boolean sign([ByRef] PartiallySignedTransaction psbt);
|
||||
|
||||
[Throws=BdkError]
|
||||
sequence<TransactionDetails> list_transactions();
|
||||
|
||||
Network network();
|
||||
|
||||
[Throws=BdkError]
|
||||
void sync([ByRef] Blockchain blockchain, Progress? progress);
|
||||
boolean is_mine(Script script);
|
||||
|
||||
[Throws=BdkError]
|
||||
sequence<LocalUtxo> list_unspent();
|
||||
|
||||
[Throws=BdkError]
|
||||
sequence<TransactionDetails> list_transactions(boolean include_raw);
|
||||
|
||||
[Throws=BdkError]
|
||||
Balance get_balance();
|
||||
|
||||
[Throws=BdkError]
|
||||
boolean sign([ByRef] PartiallySignedTransaction psbt, SignOptions? sign_options);
|
||||
|
||||
[Throws=BdkError]
|
||||
void sync([ByRef] Blockchain blockchain, Progress? progress);
|
||||
};
|
||||
|
||||
interface FeeRate {
|
||||
@@ -243,11 +255,43 @@ interface FeeRate {
|
||||
float as_sat_per_vb();
|
||||
};
|
||||
|
||||
interface Transaction {
|
||||
[Throws=BdkError]
|
||||
constructor(sequence<u8> transaction_bytes);
|
||||
dictionary SignOptions {
|
||||
boolean trust_witness_utxo;
|
||||
u32? assume_height;
|
||||
boolean allow_all_sighashes;
|
||||
boolean remove_partial_sigs;
|
||||
boolean try_finalize;
|
||||
boolean sign_with_tap_internal_key;
|
||||
boolean allow_grinding;
|
||||
};
|
||||
|
||||
sequence<u8> serialize();
|
||||
interface Transaction {
|
||||
[Throws=BdkError]
|
||||
constructor(sequence<u8> transaction_bytes);
|
||||
|
||||
string txid();
|
||||
|
||||
u64 weight();
|
||||
|
||||
u64 size();
|
||||
|
||||
u64 vsize();
|
||||
|
||||
sequence<u8> serialize();
|
||||
|
||||
boolean is_coin_base();
|
||||
|
||||
boolean is_explicitly_rbf();
|
||||
|
||||
boolean is_lock_time_enabled();
|
||||
|
||||
i32 version();
|
||||
|
||||
u32 lock_time();
|
||||
|
||||
sequence<TxIn> input();
|
||||
|
||||
sequence<TxOut> output();
|
||||
};
|
||||
|
||||
interface PartiallySignedTransaction {
|
||||
@@ -266,6 +310,8 @@ interface PartiallySignedTransaction {
|
||||
u64? fee_amount();
|
||||
|
||||
FeeRate? fee_rate();
|
||||
|
||||
string json_serialize();
|
||||
};
|
||||
|
||||
dictionary TxBuilderResult {
|
||||
@@ -405,9 +451,51 @@ interface Address {
|
||||
[Throws=BdkError]
|
||||
constructor(string address);
|
||||
|
||||
[Name=from_script, Throws=BdkError]
|
||||
constructor(Script script, Network network);
|
||||
|
||||
Payload payload();
|
||||
|
||||
Network network();
|
||||
|
||||
Script script_pubkey();
|
||||
|
||||
string to_qr_uri();
|
||||
|
||||
string as_string();
|
||||
};
|
||||
|
||||
[Enum]
|
||||
interface Payload {
|
||||
PubkeyHash(sequence<u8> pubkey_hash);
|
||||
|
||||
ScriptHash(sequence<u8> script_hash);
|
||||
|
||||
WitnessProgram(WitnessVersion version, sequence<u8> program);
|
||||
};
|
||||
|
||||
enum WitnessVersion {
|
||||
"V0",
|
||||
"V1",
|
||||
"V2",
|
||||
"V3",
|
||||
"V4",
|
||||
"V5",
|
||||
"V6",
|
||||
"V7",
|
||||
"V8",
|
||||
"V9",
|
||||
"V10",
|
||||
"V11",
|
||||
"V12",
|
||||
"V13",
|
||||
"V14",
|
||||
"V15",
|
||||
"V16"
|
||||
};
|
||||
|
||||
interface Script {
|
||||
constructor(sequence<u8> raw_output_script);
|
||||
|
||||
sequence<u8> to_bytes();
|
||||
};
|
||||
|
||||
@@ -13,10 +13,14 @@ use crate::descriptor::Descriptor;
|
||||
use crate::keys::DerivationPath;
|
||||
use crate::keys::{DescriptorPublicKey, DescriptorSecretKey, Mnemonic};
|
||||
use crate::psbt::PartiallySignedTransaction;
|
||||
use crate::wallet::SignOptions;
|
||||
use crate::wallet::{BumpFeeTxBuilder, TxBuilder, Wallet};
|
||||
use bdk::bitcoin::blockdata::script::Script as BdkScript;
|
||||
use bdk::bitcoin::blockdata::transaction::TxIn as BdkTxIn;
|
||||
use bdk::bitcoin::blockdata::transaction::TxOut as BdkTxOut;
|
||||
use bdk::bitcoin::consensus::Decodable;
|
||||
use bdk::bitcoin::psbt::serialize::Serialize;
|
||||
use bdk::bitcoin::util::address::{Payload as BdkPayload, WitnessVersion};
|
||||
use bdk::bitcoin::{
|
||||
Address as BdkAddress, Network, OutPoint as BdkOutPoint, Transaction as BdkTransaction, Txid,
|
||||
};
|
||||
@@ -25,14 +29,17 @@ use bdk::database::any::{SledDbConfiguration, SqliteDbConfiguration};
|
||||
use bdk::keys::bip39::WordCount;
|
||||
use bdk::wallet::AddressIndex as BdkAddressIndex;
|
||||
use bdk::wallet::AddressInfo as BdkAddressInfo;
|
||||
use bdk::LocalUtxo as BdkLocalUtxo;
|
||||
use bdk::TransactionDetails as BdkTransactionDetails;
|
||||
use bdk::{Balance as BdkBalance, BlockTime, Error as BdkError, FeeRate, KeychainKind};
|
||||
use std::convert::From;
|
||||
use std::fmt;
|
||||
use std::fmt::Debug;
|
||||
use std::io::Cursor;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
uniffi_macros::include_scaffolding!("bdk");
|
||||
uniffi::include_scaffolding!("bdk");
|
||||
|
||||
/// A output script and an amount of satoshis.
|
||||
pub struct ScriptAmount {
|
||||
@@ -42,17 +49,20 @@ pub struct ScriptAmount {
|
||||
|
||||
/// A derived address and the index it was found at.
|
||||
pub struct AddressInfo {
|
||||
/// Child index of this address
|
||||
/// Child index of this address.
|
||||
pub index: u32,
|
||||
/// Address
|
||||
pub address: String,
|
||||
/// Address.
|
||||
pub address: Arc<Address>,
|
||||
/// Type of keychain.
|
||||
pub keychain: KeychainKind,
|
||||
}
|
||||
|
||||
impl From<BdkAddressInfo> for AddressInfo {
|
||||
fn from(x: bdk::wallet::AddressInfo) -> AddressInfo {
|
||||
fn from(address_info: BdkAddressInfo) -> Self {
|
||||
AddressInfo {
|
||||
index: x.index,
|
||||
address: x.address.to_string(),
|
||||
index: address_info.index,
|
||||
address: Arc::new(Address::from(address_info.address)),
|
||||
keychain: address_info.keychain,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,14 +89,14 @@ pub enum AddressIndex {
|
||||
/// Use with caution, if an index is given that is less than the current descriptor index
|
||||
/// then the returned address and subsequent addresses returned by calls to `AddressIndex::New`
|
||||
/// and `AddressIndex::LastUsed` may have already been used. Also if the index is reset to a
|
||||
/// value earlier than the [`crate::blockchain::Blockchain`] stop_gap (default is 20) then a
|
||||
/// value earlier than the [`Blockchain`] stop_gap (default is 20) then a
|
||||
/// larger stop_gap should be used to monitor for all possibly used addresses.
|
||||
Reset { index: u32 },
|
||||
}
|
||||
|
||||
impl From<AddressIndex> for BdkAddressIndex {
|
||||
fn from(x: AddressIndex) -> BdkAddressIndex {
|
||||
match x {
|
||||
fn from(address_index: AddressIndex) -> Self {
|
||||
match address_index {
|
||||
AddressIndex::New => BdkAddressIndex::New,
|
||||
AddressIndex::LastUnused => BdkAddressIndex::LastUnused,
|
||||
AddressIndex::Peek { index } => BdkAddressIndex::Peek(index),
|
||||
@@ -98,6 +108,7 @@ impl From<AddressIndex> for BdkAddressIndex {
|
||||
/// A wallet transaction
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||
pub struct TransactionDetails {
|
||||
pub transaction: Option<Arc<Transaction>>,
|
||||
/// Transaction id.
|
||||
pub txid: String,
|
||||
/// Received value (sats)
|
||||
@@ -116,14 +127,18 @@ pub struct TransactionDetails {
|
||||
pub confirmation_time: Option<BlockTime>,
|
||||
}
|
||||
|
||||
impl From<&bdk::TransactionDetails> for TransactionDetails {
|
||||
fn from(x: &bdk::TransactionDetails) -> TransactionDetails {
|
||||
impl From<BdkTransactionDetails> for TransactionDetails {
|
||||
fn from(tx_details: BdkTransactionDetails) -> Self {
|
||||
let optional_tx: Option<Arc<Transaction>> =
|
||||
tx_details.transaction.map(|tx| Arc::new(tx.into()));
|
||||
|
||||
TransactionDetails {
|
||||
fee: x.fee,
|
||||
txid: x.txid.to_string(),
|
||||
received: x.received,
|
||||
sent: x.sent,
|
||||
confirmation_time: x.confirmation_time.clone(),
|
||||
transaction: optional_tx,
|
||||
fee: tx_details.fee,
|
||||
txid: tx_details.txid.to_string(),
|
||||
received: tx_details.received,
|
||||
sent: tx_details.sent,
|
||||
confirmation_time: tx_details.confirmation_time,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,10 +153,10 @@ pub struct OutPoint {
|
||||
}
|
||||
|
||||
impl From<&OutPoint> for BdkOutPoint {
|
||||
fn from(x: &OutPoint) -> BdkOutPoint {
|
||||
fn from(outpoint: &OutPoint) -> Self {
|
||||
BdkOutPoint {
|
||||
txid: Txid::from_str(&x.txid).unwrap(),
|
||||
vout: x.vout,
|
||||
txid: Txid::from_str(&outpoint.txid).unwrap(),
|
||||
vout: outpoint.vout,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,11 +190,23 @@ impl From<BdkBalance> for Balance {
|
||||
}
|
||||
|
||||
/// A transaction output, which defines new coins to be created from old ones.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TxOut {
|
||||
/// The value of the output, in satoshis.
|
||||
value: u64,
|
||||
/// The address of the output.
|
||||
address: String,
|
||||
script_pubkey: Arc<Script>,
|
||||
}
|
||||
|
||||
impl From<&BdkTxOut> for TxOut {
|
||||
fn from(tx_out: &BdkTxOut) -> Self {
|
||||
TxOut {
|
||||
value: tx_out.value,
|
||||
script_pubkey: Arc::new(Script {
|
||||
script: tx_out.script_pubkey.clone(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LocalUtxo {
|
||||
@@ -189,27 +216,21 @@ pub struct LocalUtxo {
|
||||
is_spent: bool,
|
||||
}
|
||||
|
||||
// This trait is used to convert the bdk TxOut type with field `script_pubkey: Script`
|
||||
// into the bdk-ffi TxOut type which has a field `address: String` instead
|
||||
trait NetworkLocalUtxo {
|
||||
fn from_utxo(x: &bdk::LocalUtxo, network: Network) -> LocalUtxo;
|
||||
}
|
||||
|
||||
impl NetworkLocalUtxo for LocalUtxo {
|
||||
fn from_utxo(x: &bdk::LocalUtxo, network: Network) -> LocalUtxo {
|
||||
impl From<BdkLocalUtxo> for LocalUtxo {
|
||||
fn from(local_utxo: BdkLocalUtxo) -> Self {
|
||||
LocalUtxo {
|
||||
outpoint: OutPoint {
|
||||
txid: x.outpoint.txid.to_string(),
|
||||
vout: x.outpoint.vout,
|
||||
txid: local_utxo.outpoint.txid.to_string(),
|
||||
vout: local_utxo.outpoint.vout,
|
||||
},
|
||||
txout: TxOut {
|
||||
value: x.txout.value,
|
||||
address: BdkAddress::from_script(&x.txout.script_pubkey, network)
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
value: local_utxo.txout.value,
|
||||
script_pubkey: Arc::new(Script {
|
||||
script: local_utxo.txout.script_pubkey,
|
||||
}),
|
||||
},
|
||||
keychain: x.keychain,
|
||||
is_spent: x.is_spent,
|
||||
keychain: local_utxo.keychain,
|
||||
is_spent: local_utxo.is_spent,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,14 +253,38 @@ impl BdkProgress for ProgressHolder {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ProgressHolder {
|
||||
impl Debug for ProgressHolder {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("ProgressHolder").finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TxIn {
|
||||
pub previous_output: OutPoint,
|
||||
pub script_sig: Arc<Script>,
|
||||
pub sequence: u32,
|
||||
pub witness: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl From<&BdkTxIn> for TxIn {
|
||||
fn from(tx_in: &BdkTxIn) -> Self {
|
||||
TxIn {
|
||||
previous_output: OutPoint {
|
||||
txid: tx_in.previous_output.txid.to_string(),
|
||||
vout: tx_in.previous_output.vout,
|
||||
},
|
||||
script_sig: Arc::new(Script {
|
||||
script: tx_in.script_sig.clone(),
|
||||
}),
|
||||
sequence: tx_in.sequence.0,
|
||||
witness: tx_in.witness.to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A Bitcoin transaction.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Transaction {
|
||||
internal: BdkTransaction,
|
||||
}
|
||||
@@ -251,13 +296,64 @@ impl Transaction {
|
||||
Ok(Transaction { internal: tx })
|
||||
}
|
||||
|
||||
fn txid(&self) -> String {
|
||||
self.internal.txid().to_string()
|
||||
}
|
||||
|
||||
fn weight(&self) -> u64 {
|
||||
self.internal.weight() as u64
|
||||
}
|
||||
|
||||
fn size(&self) -> u64 {
|
||||
self.internal.size() as u64
|
||||
}
|
||||
|
||||
fn vsize(&self) -> u64 {
|
||||
self.internal.vsize() as u64
|
||||
}
|
||||
|
||||
fn serialize(&self) -> Vec<u8> {
|
||||
self.internal.serialize()
|
||||
}
|
||||
|
||||
fn is_coin_base(&self) -> bool {
|
||||
self.internal.is_coin_base()
|
||||
}
|
||||
|
||||
fn is_explicitly_rbf(&self) -> bool {
|
||||
self.internal.is_explicitly_rbf()
|
||||
}
|
||||
|
||||
fn is_lock_time_enabled(&self) -> bool {
|
||||
self.internal.is_lock_time_enabled()
|
||||
}
|
||||
|
||||
fn version(&self) -> i32 {
|
||||
self.internal.version
|
||||
}
|
||||
|
||||
fn lock_time(&self) -> u32 {
|
||||
self.internal.lock_time.0
|
||||
}
|
||||
|
||||
fn input(&self) -> Vec<TxIn> {
|
||||
self.internal.input.iter().map(|x| x.into()).collect()
|
||||
}
|
||||
|
||||
fn output(&self) -> Vec<TxOut> {
|
||||
self.internal.output.iter().map(|x| x.into()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BdkTransaction> for Transaction {
|
||||
fn from(tx: BdkTransaction) -> Self {
|
||||
Transaction { internal: tx }
|
||||
}
|
||||
}
|
||||
|
||||
/// A Bitcoin address.
|
||||
struct Address {
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Address {
|
||||
address: BdkAddress,
|
||||
}
|
||||
|
||||
@@ -268,11 +364,67 @@ impl Address {
|
||||
.map_err(|e| BdkError::Generic(e.to_string()))
|
||||
}
|
||||
|
||||
/// alternative constructor
|
||||
fn from_script(script: Arc<Script>, network: Network) -> Result<Self, BdkError> {
|
||||
BdkAddress::from_script(&script.script, network)
|
||||
.map(|a| Address { address: a })
|
||||
.map_err(|e| BdkError::Generic(e.to_string()))
|
||||
}
|
||||
|
||||
fn payload(&self) -> Payload {
|
||||
match &self.address.payload.clone() {
|
||||
BdkPayload::PubkeyHash(pubkey_hash) => Payload::PubkeyHash {
|
||||
pubkey_hash: pubkey_hash.to_vec(),
|
||||
},
|
||||
BdkPayload::ScriptHash(script_hash) => Payload::ScriptHash {
|
||||
script_hash: script_hash.to_vec(),
|
||||
},
|
||||
BdkPayload::WitnessProgram { version, program } => Payload::WitnessProgram {
|
||||
version: *version,
|
||||
program: program.clone(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn network(&self) -> Network {
|
||||
self.address.network
|
||||
}
|
||||
|
||||
fn script_pubkey(&self) -> Arc<Script> {
|
||||
Arc::new(Script {
|
||||
script: self.address.script_pubkey(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_qr_uri(&self) -> String {
|
||||
self.address.to_qr_uri()
|
||||
}
|
||||
|
||||
fn as_string(&self) -> String {
|
||||
self.address.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BdkAddress> for Address {
|
||||
fn from(address: BdkAddress) -> Self {
|
||||
Address { address }
|
||||
}
|
||||
}
|
||||
|
||||
/// The method used to produce an address.
|
||||
#[derive(Debug)]
|
||||
pub enum Payload {
|
||||
/// P2PKH address.
|
||||
PubkeyHash { pubkey_hash: Vec<u8> },
|
||||
/// P2SH address.
|
||||
ScriptHash { script_hash: Vec<u8> },
|
||||
/// Segwit address.
|
||||
WitnessProgram {
|
||||
/// The witness program version.
|
||||
version: WitnessVersion,
|
||||
/// The witness program.
|
||||
program: Vec<u8>,
|
||||
},
|
||||
}
|
||||
|
||||
/// A Bitcoin script.
|
||||
@@ -286,6 +438,16 @@ impl Script {
|
||||
let script: BdkScript = BdkScript::from(raw_output_script);
|
||||
Script { script }
|
||||
}
|
||||
|
||||
fn to_bytes(&self) -> Vec<u8> {
|
||||
self.script.to_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BdkScript> for Script {
|
||||
fn from(bdk_script: BdkScript) -> Self {
|
||||
Script { script: bdk_script }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -309,7 +471,11 @@ uniffi::deps::static_assertions::assert_impl_all!(Wallet: Sync, Send);
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::Transaction;
|
||||
use crate::Network::Regtest;
|
||||
use crate::{Address, Payload};
|
||||
use assert_matches::assert_matches;
|
||||
use bdk::bitcoin::hashes::hex::FromHex;
|
||||
use bdk::bitcoin::util::address::WitnessVersion;
|
||||
|
||||
// Verify that bdk-ffi Transaction can be created from valid bytes and serialized back into the same bytes.
|
||||
#[test]
|
||||
@@ -319,4 +485,17 @@ mod test {
|
||||
let serialized_tx_to_bytes = new_tx_from_bytes.serialize();
|
||||
assert_eq!(test_tx_bytes, serialized_tx_to_bytes);
|
||||
}
|
||||
|
||||
// Verify that bdk-ffi Address.payload includes expected WitnessProgram variant, version and program bytes.
|
||||
#[test]
|
||||
fn test_address_witness_program() {
|
||||
let address =
|
||||
Address::new("bcrt1qqjn9gky9mkrm3c28e5e87t5akd3twg6xezp0tv".to_string()).unwrap();
|
||||
let payload = address.payload();
|
||||
assert_matches!(payload, Payload::WitnessProgram { version, program } => {
|
||||
assert_eq!(version,WitnessVersion::V0);
|
||||
assert_eq!(program, Vec::from_hex("04a6545885dd87b8e147cd327f2e9db362b72346").unwrap());
|
||||
});
|
||||
assert_eq!(address.network(), Regtest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use bdk::bitcoin::hashes::hex::ToHex;
|
||||
use bdk::bitcoin::util::psbt::PartiallySignedTransaction as BdkPartiallySignedTransaction;
|
||||
use bdk::bitcoincore_rpc::jsonrpc::serde_json;
|
||||
use bdk::psbt::PsbtUtils;
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
@@ -34,7 +36,7 @@ impl PartiallySignedTransaction {
|
||||
/// Return the transaction.
|
||||
pub(crate) fn extract_tx(&self) -> Arc<Transaction> {
|
||||
let tx = self.internal.lock().unwrap().clone().extract_tx();
|
||||
Arc::new(Transaction { internal: tx })
|
||||
Arc::new(tx.into())
|
||||
}
|
||||
|
||||
/// Combines this PartiallySignedTransaction with other PSBT as described by BIP 174.
|
||||
@@ -66,6 +68,12 @@ impl PartiallySignedTransaction {
|
||||
pub(crate) fn fee_rate(&self) -> Option<Arc<FeeRate>> {
|
||||
self.internal.lock().unwrap().fee_rate().map(Arc::new)
|
||||
}
|
||||
|
||||
/// Serialize the PSBT data structure as a String of JSON.
|
||||
pub(crate) fn json_serialize(&self) -> String {
|
||||
let psbt = self.internal.lock().unwrap();
|
||||
serde_json::to_string(psbt.deref()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// The goal of these tests to to ensure `bdk-ffi` intermediate code correctly calls `bdk` APIs.
|
||||
|
||||
@@ -3,7 +3,10 @@ use bdk::bitcoin::{Address as BdkAddress, Network, OutPoint as BdkOutPoint, Sequ
|
||||
use bdk::database::any::AnyDatabase;
|
||||
use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase};
|
||||
use bdk::wallet::tx_builder::ChangeSpendPolicy;
|
||||
use bdk::{FeeRate, SignOptions, SyncOptions as BdkSyncOptions, Wallet as BdkWallet};
|
||||
use bdk::{
|
||||
FeeRate, LocalUtxo as BdkLocalUtxo, SignOptions as BdkSignOptions,
|
||||
SyncOptions as BdkSyncOptions, Wallet as BdkWallet,
|
||||
};
|
||||
use std::collections::HashSet;
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
@@ -14,8 +17,8 @@ use crate::database::DatabaseConfig;
|
||||
use crate::descriptor::Descriptor;
|
||||
use crate::psbt::PartiallySignedTransaction;
|
||||
use crate::{
|
||||
AddressIndex, AddressInfo, Balance, BdkError, LocalUtxo, NetworkLocalUtxo, OutPoint, Progress,
|
||||
ProgressHolder, RbfValue, Script, ScriptAmount, TransactionDetails, TxBuilderResult,
|
||||
AddressIndex, AddressInfo, Balance, BdkError, LocalUtxo, OutPoint, Progress, ProgressHolder,
|
||||
RbfValue, Script, ScriptAmount, TransactionDetails, TxBuilderResult,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -62,6 +65,11 @@ impl Wallet {
|
||||
self.get_wallet().network()
|
||||
}
|
||||
|
||||
/// Return whether or not a script is part of this wallet (either internal or external).
|
||||
pub(crate) fn is_mine(&self, script: Arc<Script>) -> Result<bool, BdkError> {
|
||||
self.get_wallet().is_mine(&script.script)
|
||||
}
|
||||
|
||||
/// Sync the internal database with the blockchain.
|
||||
pub(crate) fn sync(
|
||||
&self,
|
||||
@@ -110,17 +118,34 @@ impl Wallet {
|
||||
self.get_wallet().get_balance().map(|b| b.into())
|
||||
}
|
||||
|
||||
/// Sign a transaction with all the wallet’s signers.
|
||||
pub(crate) fn sign(&self, psbt: &PartiallySignedTransaction) -> Result<bool, BdkError> {
|
||||
/// Sign a transaction with all the wallet's signers, in the order specified by every signer's
|
||||
/// [`SignerOrdering`]. This function returns the `Result` type with an encapsulated `bool` that
|
||||
/// has the value true if the PSBT was finalized, or false otherwise.
|
||||
///
|
||||
/// The [`SignOptions`] can be used to tweak the behavior of the software signers, and the way
|
||||
/// the transaction is finalized at the end. Note that it can't be guaranteed that *every*
|
||||
/// signers will follow the options, but the "software signers" (WIF keys and `xprv`) defined
|
||||
/// in this library will.
|
||||
pub(crate) fn sign(
|
||||
&self,
|
||||
psbt: &PartiallySignedTransaction,
|
||||
sign_options: Option<SignOptions>,
|
||||
) -> Result<bool, BdkError> {
|
||||
let mut psbt = psbt.internal.lock().unwrap();
|
||||
self.get_wallet().sign(&mut psbt, SignOptions::default())
|
||||
self.get_wallet().sign(
|
||||
&mut psbt,
|
||||
sign_options.map(SignOptions::into).unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Return the list of transactions made and received by the wallet. Note that this method only operate on the internal database, which first needs to be [Wallet.sync] manually.
|
||||
pub(crate) fn list_transactions(&self) -> Result<Vec<TransactionDetails>, BdkError> {
|
||||
let transaction_details = self.get_wallet().list_transactions(true)?;
|
||||
pub(crate) fn list_transactions(
|
||||
&self,
|
||||
include_raw: bool,
|
||||
) -> Result<Vec<TransactionDetails>, BdkError> {
|
||||
let transaction_details = self.get_wallet().list_transactions(include_raw)?;
|
||||
Ok(transaction_details
|
||||
.iter()
|
||||
.into_iter()
|
||||
.map(TransactionDetails::from)
|
||||
.collect())
|
||||
}
|
||||
@@ -128,11 +153,83 @@ impl Wallet {
|
||||
/// Return the list of unspent outputs of this wallet. Note that this method only operates on the internal database,
|
||||
/// which first needs to be Wallet.sync manually.
|
||||
pub(crate) fn list_unspent(&self) -> Result<Vec<LocalUtxo>, BdkError> {
|
||||
let unspents = self.get_wallet().list_unspent()?;
|
||||
Ok(unspents
|
||||
.iter()
|
||||
.map(|u| LocalUtxo::from_utxo(u, self.network()))
|
||||
.collect())
|
||||
let unspents: Vec<BdkLocalUtxo> = self.get_wallet().list_unspent()?;
|
||||
Ok(unspents.into_iter().map(LocalUtxo::from).collect())
|
||||
}
|
||||
}
|
||||
|
||||
/// Options for a software signer
|
||||
///
|
||||
/// Adjust the behavior of our software signers and the way a transaction is finalized
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct SignOptions {
|
||||
/// Whether the signer should trust the `witness_utxo`, if the `non_witness_utxo` hasn't been
|
||||
/// provided
|
||||
///
|
||||
/// Defaults to `false` to mitigate the "SegWit bug" which should trick the wallet into
|
||||
/// paying a fee larger than expected.
|
||||
///
|
||||
/// Some wallets, especially if relatively old, might not provide the `non_witness_utxo` for
|
||||
/// SegWit transactions in the PSBT they generate: in those cases setting this to `true`
|
||||
/// should correctly produce a signature, at the expense of an increased trust in the creator
|
||||
/// of the PSBT.
|
||||
///
|
||||
/// For more details see: <https://blog.trezor.io/details-of-firmware-updates-for-trezor-one-version-1-9-1-and-trezor-model-t-version-2-3-1-1eba8f60f2dd>
|
||||
pub trust_witness_utxo: bool,
|
||||
|
||||
/// Whether the wallet should assume a specific height has been reached when trying to finalize
|
||||
/// a transaction
|
||||
///
|
||||
/// The wallet will only "use" a timelock to satisfy the spending policy of an input if the
|
||||
/// timelock height has already been reached. This option allows overriding the "current height" to let the
|
||||
/// wallet use timelocks in the future to spend a coin.
|
||||
pub assume_height: Option<u32>,
|
||||
|
||||
/// Whether the signer should use the `sighash_type` set in the PSBT when signing, no matter
|
||||
/// what its value is
|
||||
///
|
||||
/// Defaults to `false` which will only allow signing using `SIGHASH_ALL`.
|
||||
pub allow_all_sighashes: bool,
|
||||
|
||||
/// Whether to remove partial signatures from the PSBT inputs while finalizing PSBT.
|
||||
///
|
||||
/// Defaults to `true` which will remove partial signatures during finalization.
|
||||
pub remove_partial_sigs: bool,
|
||||
|
||||
/// Whether to try finalizing the PSBT after the inputs are signed.
|
||||
///
|
||||
/// Defaults to `true` which will try finalizing PSBT after inputs are signed.
|
||||
pub try_finalize: bool,
|
||||
|
||||
// Specifies which Taproot script-spend leaves we should sign for. This option is
|
||||
// ignored if we're signing a non-taproot PSBT.
|
||||
//
|
||||
// Defaults to All, i.e., the wallet will sign all the leaves it has a key for.
|
||||
// TODO pub tap_leaves_options: TapLeavesOptions,
|
||||
/// Whether we should try to sign a taproot transaction with the taproot internal key
|
||||
/// or not. This option is ignored if we're signing a non-taproot PSBT.
|
||||
///
|
||||
/// Defaults to `true`, i.e., we always try to sign with the taproot internal key.
|
||||
pub sign_with_tap_internal_key: bool,
|
||||
|
||||
/// Whether we should grind ECDSA signature to ensure signing with low r
|
||||
/// or not.
|
||||
/// Defaults to `true`, i.e., we always grind ECDSA signature to sign with low r.
|
||||
pub allow_grinding: bool,
|
||||
}
|
||||
|
||||
impl From<SignOptions> for BdkSignOptions {
|
||||
fn from(sign_options: SignOptions) -> Self {
|
||||
BdkSignOptions {
|
||||
trust_witness_utxo: sign_options.trust_witness_utxo,
|
||||
assume_height: sign_options.assume_height,
|
||||
allow_all_sighashes: sign_options.allow_all_sighashes,
|
||||
remove_partial_sigs: sign_options.remove_partial_sigs,
|
||||
try_finalize: sign_options.try_finalize,
|
||||
tap_leaves_options: Default::default(),
|
||||
sign_with_tap_internal_key: sign_options.sign_with_tap_internal_key,
|
||||
allow_grinding: sign_options.allow_grinding,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,7 +470,7 @@ impl TxBuilder {
|
||||
psbt: Arc::new(PartiallySignedTransaction {
|
||||
internal: Mutex::new(psbt),
|
||||
}),
|
||||
transaction_details: TransactionDetails::from(&tx_details),
|
||||
transaction_details: TransactionDetails::from(tx_details),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -468,9 +565,13 @@ impl BumpFeeTxBuilder {
|
||||
mod test {
|
||||
use crate::database::DatabaseConfig;
|
||||
use crate::descriptor::Descriptor;
|
||||
use crate::keys::{DescriptorSecretKey, Mnemonic};
|
||||
use crate::wallet::{AddressIndex, TxBuilder, Wallet};
|
||||
use crate::Script;
|
||||
use assert_matches::assert_matches;
|
||||
use bdk::bitcoin::{Address, Network};
|
||||
use bdk::wallet::get_funded_wallet;
|
||||
use bdk::KeychainKind;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
@@ -563,7 +664,8 @@ mod test {
|
||||
wallet
|
||||
.get_address(AddressIndex::Peek { index: 2 })
|
||||
.unwrap()
|
||||
.address,
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1q5g0mq6dkmwzvxscqwgc932jhgcxuqqkjv09tkj"
|
||||
);
|
||||
|
||||
@@ -571,34 +673,38 @@ mod test {
|
||||
wallet
|
||||
.get_address(AddressIndex::Peek { index: 1 })
|
||||
.unwrap()
|
||||
.address,
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1q0xs7dau8af22rspp4klya4f7lhggcnqfun2y3a"
|
||||
);
|
||||
|
||||
// new index still 0
|
||||
assert_eq!(
|
||||
wallet
|
||||
.get_address(crate::AddressIndex::New)
|
||||
.get_address(AddressIndex::New)
|
||||
.unwrap()
|
||||
.address,
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1qqjn9gky9mkrm3c28e5e87t5akd3twg6xezp0tv"
|
||||
);
|
||||
|
||||
// new index now 1
|
||||
assert_eq!(
|
||||
wallet
|
||||
.get_address(crate::AddressIndex::New)
|
||||
.get_address(AddressIndex::New)
|
||||
.unwrap()
|
||||
.address,
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1q0xs7dau8af22rspp4klya4f7lhggcnqfun2y3a"
|
||||
);
|
||||
|
||||
// new index now 2
|
||||
assert_eq!(
|
||||
wallet
|
||||
.get_address(crate::AddressIndex::New)
|
||||
.get_address(AddressIndex::New)
|
||||
.unwrap()
|
||||
.address,
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1q5g0mq6dkmwzvxscqwgc932jhgcxuqqkjv09tkj"
|
||||
);
|
||||
|
||||
@@ -607,7 +713,8 @@ mod test {
|
||||
wallet
|
||||
.get_address(AddressIndex::Peek { index: 1 })
|
||||
.unwrap()
|
||||
.address,
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1q0xs7dau8af22rspp4klya4f7lhggcnqfun2y3a"
|
||||
);
|
||||
|
||||
@@ -616,13 +723,18 @@ mod test {
|
||||
wallet
|
||||
.get_address(AddressIndex::Reset { index: 0 })
|
||||
.unwrap()
|
||||
.address,
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1qqjn9gky9mkrm3c28e5e87t5akd3twg6xezp0tv"
|
||||
);
|
||||
|
||||
// new index 1 again
|
||||
assert_eq!(
|
||||
wallet.get_address(AddressIndex::New).unwrap().address,
|
||||
wallet
|
||||
.get_address(AddressIndex::New)
|
||||
.unwrap()
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1q0xs7dau8af22rspp4klya4f7lhggcnqfun2y3a"
|
||||
);
|
||||
}
|
||||
@@ -647,50 +759,99 @@ mod test {
|
||||
|
||||
assert_eq!(
|
||||
wallet
|
||||
.get_address(crate::AddressIndex::New)
|
||||
.get_address(AddressIndex::New)
|
||||
.unwrap()
|
||||
.address,
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1qqjn9gky9mkrm3c28e5e87t5akd3twg6xezp0tv"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
wallet
|
||||
.get_address(crate::AddressIndex::New)
|
||||
.get_address(AddressIndex::New)
|
||||
.unwrap()
|
||||
.address,
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1q0xs7dau8af22rspp4klya4f7lhggcnqfun2y3a"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
wallet
|
||||
.get_address(crate::AddressIndex::LastUnused)
|
||||
.get_address(AddressIndex::LastUnused)
|
||||
.unwrap()
|
||||
.address,
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1q0xs7dau8af22rspp4klya4f7lhggcnqfun2y3a"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
wallet
|
||||
.get_internal_address(crate::AddressIndex::New)
|
||||
.get_internal_address(AddressIndex::New)
|
||||
.unwrap()
|
||||
.address,
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1qpmz73cyx00r4a5dea469j40ax6d6kqyd67nnpj"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
wallet
|
||||
.get_internal_address(crate::AddressIndex::New)
|
||||
.get_internal_address(AddressIndex::New)
|
||||
.unwrap()
|
||||
.address,
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1qaux734vuhykww9632v8cmdnk7z2mw5lsf74v6k"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
wallet
|
||||
.get_internal_address(crate::AddressIndex::LastUnused)
|
||||
.get_internal_address(AddressIndex::LastUnused)
|
||||
.unwrap()
|
||||
.address,
|
||||
.address
|
||||
.as_string(),
|
||||
"bcrt1qaux734vuhykww9632v8cmdnk7z2mw5lsf74v6k"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_mine() {
|
||||
// is_mine should return true for addresses generated by the wallet
|
||||
let mnemonic: Mnemonic = Mnemonic::from_string("chaos fabric time speed sponsor all flat solution wisdom trophy crack object robot pave observe combine where aware bench orient secret primary cable detect".to_string()).unwrap();
|
||||
let secret_key: DescriptorSecretKey =
|
||||
DescriptorSecretKey::new(Network::Testnet, Arc::new(mnemonic), None);
|
||||
let descriptor: Descriptor = Descriptor::new_bip84(
|
||||
Arc::new(secret_key),
|
||||
KeychainKind::External,
|
||||
Network::Testnet,
|
||||
);
|
||||
let wallet: Wallet = Wallet::new(
|
||||
Arc::new(descriptor),
|
||||
None,
|
||||
Network::Testnet,
|
||||
DatabaseConfig::Memory,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let address = wallet.get_address(AddressIndex::New).unwrap();
|
||||
let script: Arc<Script> = address.address.script_pubkey();
|
||||
|
||||
let is_mine_1: bool = wallet.is_mine(script).unwrap();
|
||||
assert!(is_mine_1);
|
||||
|
||||
// is_mine returns false when provided a script that is not in the wallet
|
||||
let other_wpkh = "wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)";
|
||||
let other_descriptor = Descriptor::new(other_wpkh.to_string(), Network::Testnet).unwrap();
|
||||
|
||||
let other_wallet = Wallet::new(
|
||||
Arc::new(other_descriptor),
|
||||
None,
|
||||
Network::Testnet,
|
||||
DatabaseConfig::Memory,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let other_address = other_wallet.get_address(AddressIndex::New).unwrap();
|
||||
let other_script: Arc<Script> = other_address.address.script_pubkey();
|
||||
let is_mine_2: bool = wallet.is_mine(other_script).unwrap();
|
||||
assert_matches!(is_mine_2, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,5 @@ class TestBdk(unittest.TestCase):
|
||||
def test_some_enum(self):
|
||||
network = Network.TESTNET
|
||||
|
||||
def test_some_dict(self):
|
||||
a = AddressInfo(index=42, address="testaddress")
|
||||
self.assertEqual(42, a.index)
|
||||
self.assertEqual("testaddress", a.address)
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main()
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
uniffi_macros::build_foreign_language_testcases!(
|
||||
["src/bdk.udl",],
|
||||
[
|
||||
"tests/bindings/test.kts",
|
||||
"tests/bindings/test.swift",
|
||||
"tests/bindings/test.py"
|
||||
]
|
||||
uniffi::build_foreign_language_testcases!(
|
||||
"tests/bindings/test.kts",
|
||||
"tests/bindings/test.swift",
|
||||
"tests/bindings/test.py",
|
||||
);
|
||||
|
||||
3
bdk-ffi/uniffi-bindgen.rs
Normal file
3
bdk-ffi/uniffi-bindgen.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
uniffi::uniffi_bindgen_main()
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
# bdk-android
|
||||
# bdk-jvm
|
||||
This project builds a .jar package for the JVM platform that provide Kotlin language bindings for the [`bdk`] library. The Kotlin language bindings are created by the `bdk-ffi` project which is included in the root of this repository.
|
||||
|
||||
## How to Use
|
||||
@@ -19,8 +19,8 @@ import org.bitcoindevkit.*
|
||||
|
||||
// ...
|
||||
|
||||
val externalDescriptor = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"
|
||||
val internalDescriptor = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"
|
||||
val externalDescriptor = Descriptor("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)", Network.TESTNET)
|
||||
val internalDescriptor = Descriptor("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)", Network.TESTNET)
|
||||
|
||||
val databaseConfig = DatabaseConfig.Memory
|
||||
|
||||
@@ -43,27 +43,34 @@ dependencies {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Example Projects
|
||||
* [Tatooine Faucet](https://github.com/thunderbiscuit/tatooine)
|
||||
|
||||
## How to build
|
||||
_Note that Kotlin version `1.6.10` or later is required to build the library._
|
||||
|
||||
1. Clone this repository.
|
||||
1. Install JDK 11. It must be version 11 (not 17), otherwise it won't build. For example, with SDKMAN!:
|
||||
```shell
|
||||
curl -s "https://get.sdkman.io" | bash
|
||||
source "$HOME/.sdkman/bin/sdkman-init.sh"
|
||||
sdk install java 11.0.19-tem
|
||||
```
|
||||
2. Install Rust (note that we are currently building using Rust 1.67.0):
|
||||
```shell
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
rustup default 1.67.0
|
||||
```
|
||||
3. Clone this repository.
|
||||
```shell
|
||||
git clone https://github.com/bitcoindevkit/bdk-ffi
|
||||
```
|
||||
2. Follow the "General" bdk-ffi ["Getting Started (Developer)"] instructions.
|
||||
3. If building on macOS install required intel and m1 jvm targets
|
||||
4. If building on macOS install required intel and m1 jvm targets
|
||||
```sh
|
||||
rustup target add x86_64-apple-darwin aarch64-apple-darwin
|
||||
```
|
||||
4. Build kotlin bindings
|
||||
```sh
|
||||
# build JVM library
|
||||
./gradlew buildJvmLib
|
||||
```
|
||||
5. Build kotlin bindings
|
||||
```sh
|
||||
./gradlew buildJvmLib
|
||||
```
|
||||
|
||||
## How to publish to your local Maven repo
|
||||
```shell
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
android.enableJetifier=true
|
||||
kotlin.code.style=official
|
||||
libraryVersion=0.27.1
|
||||
libraryVersion=0.29.0
|
||||
|
||||
@@ -20,8 +20,8 @@ repositories {
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
@@ -107,4 +107,8 @@ signing {
|
||||
// binaries before running the tests
|
||||
tasks.withType<KotlinCompile> {
|
||||
dependsOn("buildJvmLib")
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class JvmLibTest {
|
||||
@Test
|
||||
fun memoryWalletNewAddress() {
|
||||
val wallet = Wallet(descriptor, null, Network.TESTNET, databaseConfig)
|
||||
val address = wallet.getAddress(AddressIndex.New).address
|
||||
val address = wallet.getAddress(AddressIndex.New).address.asString()
|
||||
assertEquals("tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e", address)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,13 @@ package org.bitcoindevkit.plugins
|
||||
val operatingSystem: OS = when {
|
||||
System.getProperty("os.name").contains("mac", ignoreCase = true) -> OS.MAC
|
||||
System.getProperty("os.name").contains("linux", ignoreCase = true) -> OS.LINUX
|
||||
System.getProperty("os.name").contains("windows", ignoreCase = true) -> OS.WINDOWS
|
||||
else -> OS.OTHER
|
||||
}
|
||||
|
||||
enum class OS {
|
||||
MAC,
|
||||
LINUX,
|
||||
WINDOWS,
|
||||
OTHER,
|
||||
}
|
||||
|
||||
@@ -27,13 +27,20 @@ internal class UniFfiJvmPlugin : Plugin<Project> {
|
||||
val cargoArgs: List<String> = listOf("build", "--profile", "release-smaller", "--target", "aarch64-apple-darwin")
|
||||
args(cargoArgs)
|
||||
}
|
||||
} else if(operatingSystem == OS.LINUX) {
|
||||
} else if (operatingSystem == OS.LINUX) {
|
||||
exec {
|
||||
workingDir("${project.projectDir}/../../bdk-ffi")
|
||||
executable("cargo")
|
||||
val cargoArgs: List<String> = listOf("build", "--profile", "release-smaller", "--target", "x86_64-unknown-linux-gnu")
|
||||
args(cargoArgs)
|
||||
}
|
||||
} else if (operatingSystem == OS.WINDOWS) {
|
||||
exec {
|
||||
workingDir("${project.projectDir}/../../bdk-ffi")
|
||||
executable("cargo")
|
||||
val cargoArgs: List<String> = listOf("build", "--profile", "release-smaller", "--target", "x86_64-pc-windows-msvc")
|
||||
args(cargoArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,13 +77,25 @@ internal class UniFfiJvmPlugin : Plugin<Project> {
|
||||
ext = "so"
|
||||
)
|
||||
)
|
||||
} else if (operatingSystem == OS.WINDOWS) {
|
||||
libsToCopy.add(
|
||||
CopyMetadata(
|
||||
targetDir = "x86_64-pc-windows-msvc",
|
||||
resDir = "win32-x86-64",
|
||||
ext = "dll"
|
||||
)
|
||||
)
|
||||
}
|
||||
val libName = when (operatingSystem) {
|
||||
OS.WINDOWS -> "bdkffi"
|
||||
else -> "libbdkffi"
|
||||
}
|
||||
|
||||
libsToCopy.forEach {
|
||||
doFirst {
|
||||
copy {
|
||||
with(it) {
|
||||
from("${project.projectDir}/../../target/${this.targetDir}/release-smaller/libbdkffi.${this.ext}")
|
||||
from("${project.projectDir}/../../target/${this.targetDir}/release-smaller/${libName}.${this.ext}")
|
||||
into("${project.projectDir}/../../bdk-jvm/lib/src/main/resources/${this.resDir}/")
|
||||
}
|
||||
}
|
||||
@@ -90,17 +109,10 @@ internal class UniFfiJvmPlugin : Plugin<Project> {
|
||||
dependsOn(moveNativeJvmLibs)
|
||||
|
||||
workingDir("${project.projectDir}/../../bdk-ffi")
|
||||
val cargoArgs: List<String> = listOf("run", "--bin", "uniffi-bindgen", "generate", "src/bdk.udl", "--language", "kotlin", "--out-dir", "../bdk-jvm/lib/src/main/kotlin", "--no-format")
|
||||
|
||||
executable("cargo")
|
||||
args(
|
||||
"run",
|
||||
"--package",
|
||||
"bdk-ffi-bindgen",
|
||||
"--",
|
||||
"--language",
|
||||
"kotlin",
|
||||
"--out-dir",
|
||||
"../bdk-jvm/lib/src/main/kotlin"
|
||||
)
|
||||
args(cargoArgs)
|
||||
|
||||
doLast {
|
||||
println("JVM bindings file successfully created")
|
||||
|
||||
2
bdk-python/MANIFEST.in
Normal file
2
bdk-python/MANIFEST.in
Normal file
@@ -0,0 +1,2 @@
|
||||
include ./src/bdkpython/libbdkffi.dylib
|
||||
include ./src/bdkpython/libbdkffi.so
|
||||
@@ -11,10 +11,10 @@ pip install bdkpython
|
||||
|
||||
## Run the tests
|
||||
```shell
|
||||
pip3 install --requirement requirements.txt
|
||||
pip install --requirement requirements.txt
|
||||
bash ./generate.sh
|
||||
python3 setup.py --verbose bdist_wheel
|
||||
pip3 install ./dist/bdkpython-<yourversion>-py3-none-any.whl
|
||||
python setup.py bdist_wheel --verbose
|
||||
pip install ./dist/bdkpython-<yourversion>-py3-none-any.whl --force-reinstall
|
||||
python -m unittest --verbose tests/test_bdk.py
|
||||
```
|
||||
|
||||
@@ -23,11 +23,11 @@ python -m unittest --verbose tests/test_bdk.py
|
||||
# Install dependencies
|
||||
pip install --requirement requirements.txt
|
||||
|
||||
# Generate the bindings first
|
||||
# Generate the bindings
|
||||
bash generate.sh
|
||||
|
||||
# Build the wheel
|
||||
python3 setup.py --verbose bdist_wheel
|
||||
python setup.py --verbose bdist_wheel
|
||||
```
|
||||
|
||||
## Run tox to build and test locally
|
||||
@@ -35,7 +35,7 @@ python3 setup.py --verbose bdist_wheel
|
||||
# install dev requirements
|
||||
pip install --requirement requirements-dev.txt
|
||||
|
||||
# build bindings glue code (located at .bdk-python/src/bdkpython/bdk.py)
|
||||
# build bindings glue code (located at ./src/bdkpython/bdk.py)
|
||||
source ./generate.sh
|
||||
|
||||
# build and test
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR=$(dirname "$(realpath $0)")
|
||||
PY_SRC="${SCRIPT_DIR}/src/bdkpython/"
|
||||
OS=$(uname -s)
|
||||
|
||||
echo "Generating bdk.py..."
|
||||
# GENERATE_PYTHON_BINDINGS_OUT="$PY_SRC" GENERATE_PYTHON_BINDINGS_FIXUP_LIB_PATH=bdkffi cargo run --manifest-path ./bdk-ffi/Cargo.toml --release --bin generate --features generate-python
|
||||
# BDKFFI_BINDGEN_PYTHON_FIXUP_PATH=bdkffi cargo run --manifest-path ./bdk-ffi/Cargo.toml --package bdk-ffi-bindgen -- --language python --udl-file ./bdk-ffi/src/bdk.udl --out-dir ./src/bdkpython/
|
||||
BDKFFI_BINDGEN_OUTPUT_DIR="$PY_SRC" BDKFFI_BINDGEN_PYTHON_FIXUP_PATH=bdkffi cargo run --manifest-path ../bdk-ffi/Cargo.toml --package bdk-ffi-bindgen -- --language python --udl-file ../bdk-ffi/src/bdk.udl
|
||||
cd ../bdk-ffi/
|
||||
cargo run --bin uniffi-bindgen generate src/bdk.udl --language python --out-dir ../bdk-python/src/bdkpython/ --no-format
|
||||
|
||||
echo "Generating native binaries..."
|
||||
cargo build --profile release-smaller
|
||||
case $OS in
|
||||
"Darwin")
|
||||
echo "Copying macOS libbdkffi.dylib..."
|
||||
cp ../target/release-smaller/libbdkffi.dylib ../bdk-python/src/bdkpython/libbdkffi.dylib
|
||||
;;
|
||||
"Linux")
|
||||
echo "Copying linux libbdkffi.so..."
|
||||
cp ../target/release-smaller/libbdkffi.so ../bdk-python/src/bdkpython/libbdkffi.so
|
||||
;;
|
||||
esac
|
||||
cd ../bdk-python/
|
||||
|
||||
echo "All done!"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
semantic-version==2.9.0
|
||||
setuptools-rust==1.1.2
|
||||
typing_extensions==4.0.1
|
||||
setuptools==67.4.0
|
||||
wheel==0.38.4
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
|
||||
from setuptools import setup
|
||||
from setuptools_rust import Binding, RustExtension
|
||||
|
||||
LONG_DESCRIPTION = """# bdkpython
|
||||
The Python language bindings for the [Bitcoin Dev Kit](https://github.com/bitcoindevkit).
|
||||
@@ -52,23 +49,20 @@ balance = wallet.get_balance()
|
||||
print(f"Wallet balance is: {balance.total}")
|
||||
"""
|
||||
|
||||
rust_ext = RustExtension(
|
||||
target="bdkpython.bdkffi",
|
||||
path="../bdk-ffi/Cargo.toml",
|
||||
binding=Binding.NoBinding,
|
||||
)
|
||||
|
||||
setup(
|
||||
name='bdkpython',
|
||||
version='0.27.1',
|
||||
name="bdkpython",
|
||||
version="0.29.0",
|
||||
description="The Python language bindings for the Bitcoin Development Kit",
|
||||
long_description=LONG_DESCRIPTION,
|
||||
long_description_content_type='text/markdown',
|
||||
rust_extensions=[rust_ext],
|
||||
long_description_content_type="text/markdown",
|
||||
include_package_data = True,
|
||||
zip_safe=False,
|
||||
packages=['bdkpython'],
|
||||
package_dir={'bdkpython': './src/bdkpython'},
|
||||
packages=["bdkpython"],
|
||||
package_dir={"bdkpython": "./src/bdkpython"},
|
||||
url="https://github.com/bitcoindevkit/bdk-ffi",
|
||||
author="Alekos Filini <alekos.filini@gmail.com>, Steve Myers <steve@notmandatory.org>",
|
||||
license="MIT or Apache 2.0",
|
||||
# This is required to ensure the library name includes the python version, abi, and platform tags
|
||||
# See issue #350 for more information
|
||||
has_ext_modules=lambda: True,
|
||||
)
|
||||
|
||||
@@ -1 +1 @@
|
||||
from bdkpython.bdk import *
|
||||
from bdkpython.bdk import *
|
||||
0
bdk-python/tests/__init__.py
Normal file
0
bdk-python/tests/__init__.py
Normal file
@@ -27,7 +27,7 @@ class TestSimpleBip84Wallet(unittest.TestCase):
|
||||
database_config=db_config
|
||||
)
|
||||
address_info = wallet.get_address(bdk.AddressIndex.LAST_UNUSED())
|
||||
address = address_info.address
|
||||
address = address_info.address.as_string()
|
||||
# print(f"New address is {address}")
|
||||
assert address == "tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e", f"Wrong address {address}, should be tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e"
|
||||
|
||||
@@ -43,6 +43,21 @@ class TestSimpleBip84Wallet(unittest.TestCase):
|
||||
# print(f"Balance is {balance.total} sat")
|
||||
assert balance.total > 0, "Balance is 0, send testnet coins to tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e"
|
||||
|
||||
|
||||
def test_output_address_from_script_pubkey(self):
|
||||
wallet = bdk.Wallet(
|
||||
descriptor=descriptor,
|
||||
change_descriptor=None,
|
||||
network=bdk.Network.TESTNET,
|
||||
database_config=db_config,
|
||||
)
|
||||
wallet.sync(blockchain, None)
|
||||
first_tx = list(wallet.list_transactions(True))[0]
|
||||
assert first_tx.txid == '35d3de8dd429ec4c9684168c1fbb9a4fb6db6f2ce89be214a024657a73ef4908'
|
||||
|
||||
output1, output2 = list(first_tx.transaction.output())
|
||||
|
||||
assert bdk.Address.from_script(output1.script_pubkey, bdk.Network.TESTNET).as_string() == 'tb1qw6ly2te8k9vy2mwj3g6gx82hj7hc8f5q3vry8t'
|
||||
assert bdk.Address.from_script(output2.script_pubkey, bdk.Network.TESTNET).as_string() == 'tb1qzsvpnmme78yl60j7ldh9aqvhvxr4mz7mjpmh22'
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
@@ -10,7 +10,7 @@ deps =
|
||||
-rrequirements.txt
|
||||
-rrequirements-dev.txt
|
||||
commands =
|
||||
python3 setup.py -v build
|
||||
python3 setup.py -v install
|
||||
python3 setup.py build --verbose
|
||||
python3 setup.py install --verbose
|
||||
pytest --verbose --override-ini console_output_style=count
|
||||
python3 setup.py --verbose bdist_wheel
|
||||
python3 setup.py bdist_wheel --verbose
|
||||
|
||||
@@ -29,7 +29,9 @@ let package = Package(
|
||||
.binaryTarget(name: "bdkFFI", path: "./bdkFFI.xcframework"),
|
||||
.target(
|
||||
name: "BitcoinDevKit",
|
||||
dependencies: ["bdkFFI"]),
|
||||
dependencies: ["bdkFFI"],
|
||||
swiftSettings: [.unsafeFlags(["-suppress-warnings"])]
|
||||
),
|
||||
.testTarget(
|
||||
name: "BitcoinDevKitTests",
|
||||
dependencies: ["BitcoinDevKit"]),
|
||||
|
||||
@@ -10,6 +10,6 @@ final class BitcoinDevKitTests: XCTestCase {
|
||||
let databaseConfig = DatabaseConfig.memory
|
||||
let wallet = try Wallet.init(descriptor: desc, changeDescriptor: nil, network: Network.regtest, databaseConfig: databaseConfig)
|
||||
let addressInfo = try wallet.getAddress(addressIndex: AddressIndex.new)
|
||||
XCTAssertEqual(addressInfo.address, "bcrt1qzg4mckdh50nwdm9hkzq06528rsu73hjxytqkxs")
|
||||
XCTAssertEqual(addressInfo.address.asString(), "bcrt1qzg4mckdh50nwdm9hkzq06528rsu73hjxytqkxs")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,25 +5,25 @@
|
||||
#
|
||||
# Run the script from the repo root directory, ie: ./bdk-swift/build-local-swift.sh
|
||||
|
||||
rustup install nightly-x86_64-apple-darwin
|
||||
rustup component add rust-src --toolchain nightly-x86_64-apple-darwin
|
||||
rustup install nightly-2023-04-10
|
||||
rustup component add rust-src --toolchain nightly-2023-04-10
|
||||
rustup target add aarch64-apple-ios x86_64-apple-ios
|
||||
rustup target add aarch64-apple-ios-sim --toolchain nightly
|
||||
rustup target add aarch64-apple-ios-sim --toolchain nightly-2023-04-10
|
||||
rustup target add aarch64-apple-darwin x86_64-apple-darwin
|
||||
|
||||
pushd bdk-ffi
|
||||
mkdir -p Sources/BitcoinDevKit
|
||||
cargo run --package bdk-ffi-bindgen -- --language swift --out-dir ../bdk-swift/Sources/BitcoinDevKit
|
||||
cargo run --bin uniffi-bindgen generate src/bdk.udl --language swift --out-dir ../bdk-swift/Sources/BitcoinDevKit --no-format
|
||||
popd
|
||||
|
||||
cargo build --package bdk-ffi --profile release-smaller --target x86_64-apple-darwin
|
||||
cargo build --package bdk-ffi --profile release-smaller --target aarch64-apple-darwin
|
||||
cargo build --package bdk-ffi --profile release-smaller --target x86_64-apple-ios
|
||||
cargo build --package bdk-ffi --profile release-smaller --target aarch64-apple-ios
|
||||
cargo +nightly build --package bdk-ffi --release -Z build-std --target aarch64-apple-ios-sim
|
||||
cargo +nightly-2023-04-10 build --package bdk-ffi --profile release-smaller --target aarch64-apple-ios-sim
|
||||
|
||||
mkdir -p target/lipo-ios-sim/release-smaller
|
||||
lipo target/aarch64-apple-ios-sim/release/libbdkffi.a target/x86_64-apple-ios/release-smaller/libbdkffi.a -create -output target/lipo-ios-sim/release-smaller/libbdkffi.a
|
||||
lipo target/aarch64-apple-ios-sim/release-smaller/libbdkffi.a target/x86_64-apple-ios/release-smaller/libbdkffi.a -create -output target/lipo-ios-sim/release-smaller/libbdkffi.a
|
||||
mkdir -p target/lipo-macos/release-smaller
|
||||
lipo target/aarch64-apple-darwin/release-smaller/libbdkffi.a target/x86_64-apple-darwin/release-smaller/libbdkffi.a -create -output target/lipo-macos/release-smaller/libbdkffi.a
|
||||
|
||||
|
||||
Reference in New Issue
Block a user