Merge bitcoindevkit/bdk-ffi#307: Expose more of the Transaction type

cba69e681a2116c98895d021723617f71db1d0ca Clean up of From traits implementations (thunderbiscuit)
35d8fb3139e1de645e0299c27762f2fb938a99f6 Clean up extract_tx method on PSBT (thunderbiscuit)
f003a6275ec8b00d0bb3276722c6c6a260056aa4 Clean up conversion between BDK TransactionDetails to ffi TransactionDetails (thunderbiscuit)
2f62377eec547e0654899a19771ba44add7066ae Add Eq and PartialEq traits on the Transaction type (thunderbiscuit)
81e208222ad954f4df0402cad3276556a8dd676d Add uniffi/cli as default feature to cargo (thunderbiscuit)
3dc6596aa250430940c6946ce4b0b3146e717184 Add include_raw boolean parameter on wallet list_transactions method (thunderbiscuit)
2342265c26a158c38fa04bd837daefdd6a269f5f Remove unused NetworkLocalUtxo type (thunderbiscuit)
6c561228c2873398729c9f4dce49cd6f33ba4c9f Use the latest version of the Android NDK (thunderbiscuit)
e86909ab3d24ec5bd8aba983d792f7d191312885 Clean up input and output methods on Transaction type (thunderbiscuit)
8e51756a3ae770d0e271c39839765c9c8a2de733 Fix clippy errors (thunderbiscuit)
40263b425e49d979216a42ab78a42e8522ba1088 Remove deprecated bdk-ffi-bindgen tool (thunderbiscuit)
9437051668609a9809651e8fd7982510ef873148 Fix fmt and clippy errors (thunderbiscuit)
7557e214c86bd6ea96a224aae78d957746d9645e Add optional transaction field on the TransactionDetails type (thunderbiscuit)
40ca62086c3a15a014303659ea4d3f3794a0a088 Expose all fields on the Transaction type (thunderbiscuit)
e0506deffa155ed2bd9794e904bd10e42a523578 Add new utility methods on Transaction type (thunderbiscuit)
d3e183a498dcf0764544adeb0c8d2232b0f00df0 Add Kotlin API docs for new Transaction methods (thunderbiscuit)
1e9ecfbe52a254c0ac529d34fc3c84aefa43740c Add weight, size, and vsize methods on the Transaction type (thunderbiscuit)

Pull request description:

  ## Description
  We've recently exposed the `Transaction` type, and I think a few methods on it would be useful. ~This is a draft PR with the first 3: `weight()`, `size()`, and `vsize()`~ _Edit: it's now much more_. I think there might be other methods we might want to expose as well. [Take a look at the docs to see them all](https://docs.rs/bitcoin/0.29.2/bitcoin/blockdata/transaction/struct.Transaction.html).

  Other candidates have now been added:
  1. [is_explicitly_rbf](https://docs.rs/bitcoin/0.29.2/bitcoin/blockdata/transaction/struct.Transaction.html#method.is_explicitly_rbf)
  2. [is_lock_time_enabled](https://docs.rs/bitcoin/0.29.2/bitcoin/blockdata/transaction/struct.Transaction.html#method.is_lock_time_enabled)
  3. [is_absolute_timelock_satisfied](https://docs.rs/bitcoin/0.29.2/bitcoin/blockdata/transaction/struct.Transaction.html#method.is_absolute_timelock_satisfied)
  4. [is_coin_base](https://docs.rs/bitcoin/0.29.2/bitcoin/blockdata/transaction/struct.Transaction.html#method.is_coin_base)
  5. [txid](https://docs.rs/bitcoin/0.29.2/bitcoin/blockdata/transaction/struct.Transaction.html#method.txid)

  This PR is growing in size but I decided to add all 4 fields on the `Transaction` type. This is useful because it means we can now add the `transaction` field on the `TransactionDetails` type (also added in this PR).

  I still have a few questions regarding all the translation between the ffi and bdk/rust types, some of the traits I had to remove (Eq and PartialEq on the TransactionDetails type) as well as the usage of `Option<Arc<T>>` vs `Arc<Option<T>>`. Will outline those tomorrow.

  Closes #303
  Closes #187

  ## Changelog notice
  ```md
  APIs Added
  - `Transaction` type now exposes the `.weight()`, `.size()`, `.vsize()`, `is_explicitly_rbf()`, `is_lock_time_enabled()`, `is_coin_base(), and `txid()` methods [#307]

  [#307]: https://github.com/bitcoindevkit/bdk-ffi/pull/307
  ```

  ## Checklists

  #### All Submissions:
  * [x] I've signed all my commits
  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
  * [x] I ran `cargo fmt` and `cargo clippy` before committing

  #### New Features:
  * [ ] I've added tests for the new feature
  * [x] I've added docs for the new feature

ACKs for top commit:
  notmandatory:
    ACK cba69e681a2116c98895d021723617f71db1d0ca

Tree-SHA512: 83e860407b230b6cdca59c0d74a486e52e7ea34d655d418ddc115418551a61665cad8f1d6182858d8ed6d7d72a8558e595e61644efed6c704de8a0b6960a0df2
This commit is contained in:
Steve Myers 2023-03-23 15:38:57 -05:00
commit d3a6453eda
No known key found for this signature in database
GPG Key ID: 8105A46B22C2D051
17 changed files with 314 additions and 444 deletions

View File

@ -47,14 +47,14 @@ jobs:
run: rustup update
- name: Build
run: cargo build --features uniffi/cli
run: cargo build
- name: Clippy
if: ${{ matrix.rust.clippy }}
run: cargo clippy --all-targets --features "uniffi/bindgen-tests uniffi/cli" -- -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 --features uniffi/bindgen-tests,uniffi/cli
run: CLASSPATH=./tests/jna/jna-5.8.0.jar cargo test --features uniffi/bindgen-tests
fmt:
name: Rust fmt

View File

@ -9,22 +9,10 @@ on:
- "bdk-ffi/**"
- "bdk-android/**"
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"
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"
uses: actions/checkout@v2

View File

@ -24,13 +24,13 @@ jobs:
- name: Run bdk-ffi-bindgen
working-directory: bdk-ffi
run: cargo run --features uniffi/cli --bin uniffi-bindgen generate src/bdk.udl --language swift --out-dir ../bdk-swift/Sources/BitcoinDevKit --no-format
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 --package bdk-ffi --features uniffi/cli --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 --package bdk-ffi --features uniffi/cli --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
run: |

195
Cargo.lock generated
View File

@ -19,15 +19,6 @@ dependencies = [
"version_check",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.69"
@ -163,16 +154,6 @@ dependencies = [
"uniffi",
]
[[package]]
name = "bdk-ffi-bindgen"
version = "0.2.0"
dependencies = [
"anyhow",
"camino",
"structopt",
"uniffi_bindgen 0.21.1",
]
[[package]]
name = "bdk-macros"
version = "0.6.0"
@ -331,21 +312,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim 0.8.0",
"textwrap 0.11.0",
"unicode-width",
"vec_map",
]
[[package]]
name = "clap"
version = "3.2.23"
@ -358,9 +324,9 @@ dependencies = [
"clap_lex",
"indexmap",
"once_cell",
"strsim 0.10.0",
"strsim",
"termcolor",
"textwrap 0.16.0",
"textwrap",
]
[[package]]
@ -369,7 +335,7 @@ version = "3.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
dependencies = [
"heck 0.4.1",
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
@ -519,17 +485,6 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "goblin"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7666983ed0dd8d21a6f6576ee00053ca0926fb281a5522577a4dbd0f1b54143"
dependencies = [
"log",
"plain",
"scroll",
]
[[package]]
name = "goblin"
version = "0.6.1"
@ -559,15 +514,6 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "heck"
version = "0.4.1"
@ -640,12 +586,6 @@ dependencies = [
"serde_json",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.139"
@ -768,9 +708,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "os_str_bytes"
version = "6.4.1"
version = "6.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267"
[[package]]
name = "parking_lot"
@ -1124,42 +1064,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "structopt"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
dependencies = [
"clap 2.34.0",
"lazy_static",
"structopt-derive",
]
[[package]]
name = "structopt-derive"
version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
dependencies = [
"heck 0.3.3",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "1.0.107"
@ -1180,15 +1090,6 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "textwrap"
version = "0.16.0"
@ -1197,18 +1098,18 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
[[package]]
name = "thiserror"
version = "1.0.38"
version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.38"
version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
dependencies = [
"proc-macro2",
"quote",
@ -1277,18 +1178,6 @@ dependencies = [
"smallvec 0.6.14",
]
[[package]]
name = "unicode-segmentation"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "uniffi"
version = "0.23.0"
@ -1296,35 +1185,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f71cc01459bc34cfe43fabf32b39f1228709bc6db1b3a664a92940af3d062376"
dependencies = [
"anyhow",
"uniffi_bindgen 0.23.0",
"camino",
"clap",
"uniffi_bindgen",
"uniffi_build",
"uniffi_core",
"uniffi_macros",
]
[[package]]
name = "uniffi_bindgen"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d46080a4840abccf7c0cce21931dae53215cbd7dd969b5e63c486235ce91a2a"
dependencies = [
"anyhow",
"askama",
"bincode",
"camino",
"clap 3.2.23",
"fs-err",
"goblin 0.5.4",
"heck 0.4.1",
"once_cell",
"paste",
"serde",
"serde_json",
"toml",
"uniffi_meta 0.21.1",
"weedle2",
]
[[package]]
name = "uniffi_bindgen"
version = "0.23.0"
@ -1337,14 +1205,14 @@ dependencies = [
"camino",
"fs-err",
"glob",
"goblin 0.6.1",
"heck 0.4.1",
"goblin",
"heck",
"once_cell",
"paste",
"serde",
"serde_json",
"toml",
"uniffi_meta 0.23.0",
"uniffi_meta",
"uniffi_testing",
"weedle2",
]
@ -1357,17 +1225,7 @@ checksum = "0ee1a28368ff3d83717e3d3e2e15a66269c43488c3f036914131bb68892f29fb"
dependencies = [
"anyhow",
"camino",
"uniffi_bindgen 0.23.0",
]
[[package]]
name = "uniffi_checksum_derive"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b6e16d46caf942016997af8bbdf4b163bf8ae3deb0b667d9643de7b7ffd4c9"
dependencies = [
"quote",
"syn",
"uniffi_bindgen",
]
[[package]]
@ -1412,18 +1270,7 @@ dependencies = [
"syn",
"toml",
"uniffi_build",
"uniffi_meta 0.23.0",
]
[[package]]
name = "uniffi_meta"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "729835442da829c9b6f7c111c76cf87b2498e129101203bec94f0c39a3296a38"
dependencies = [
"serde",
"siphasher",
"uniffi_checksum_derive 0.21.1",
"uniffi_meta",
]
[[package]]
@ -1434,7 +1281,7 @@ checksum = "66fdab2c436aed7a6391bec64204ec33948bfed9b11b303235740771f85c4ea6"
dependencies = [
"serde",
"siphasher",
"uniffi_checksum_derive 0.23.0",
"uniffi_checksum_derive",
]
[[package]]
@ -1494,12 +1341,6 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.9.4"

View File

@ -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*

View File

@ -248,6 +248,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 +289,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> {}
}
/**
@ -331,11 +384,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 transactions 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 outputs 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>>
)
/**
@ -420,7 +491,7 @@ class Wallet(
fun sign(psbt: PartiallySignedTransaction): 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 {}

View File

@ -21,7 +21,7 @@ internal class UniFfiAndroidPlugin : Plugin<Project> {
val buildAndroidAarch64Binary by tasks.register<Exec>("buildAndroidAarch64Binary") {
workingDir("${projectDir}/../../bdk-ffi")
val cargoArgs: List<String> = listOf("build", "--features", "uniffi/cli", "--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,7 +36,8 @@ 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("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")
)
@ -50,7 +51,7 @@ internal class UniFfiAndroidPlugin : Plugin<Project> {
val buildAndroidX86_64Binary by tasks.register<Exec>("buildAndroidX86_64Binary") {
workingDir("${project.projectDir}/../../bdk-ffi")
val cargoArgs: List<String> = listOf("build", "--features", "uniffi/cli", "--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)
@ -65,7 +66,8 @@ 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("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")
)
@ -79,7 +81,7 @@ internal class UniFfiAndroidPlugin : Plugin<Project> {
val buildAndroidArmv7Binary by tasks.register<Exec>("buildAndroidArmv7Binary") {
workingDir("${project.projectDir}/../../bdk-ffi")
val cargoArgs: List<String> = listOf("build", "--features", "uniffi/cli", "--profile", "release-smaller", "--target", "armv7-linux-androideabi")
val cargoArgs: List<String> = listOf("build", "--profile", "release-smaller", "--target", "armv7-linux-androideabi")
executable("cargo")
args(cargoArgs)
@ -94,7 +96,8 @@ 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("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")
)
@ -135,7 +138,7 @@ internal class UniFfiAndroidPlugin : Plugin<Project> {
dependsOn(moveNativeAndroidLibs)
workingDir("${project.projectDir}/../../bdk-ffi")
val cargoArgs: List<String> = listOf("run", "--features", "uniffi/cli", "--bin", "uniffi-bindgen", "generate", "src/bdk.udl", "--language", "kotlin", "--out-dir", "../bdk-android/lib/src/main/kotlin", "--no-format")
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(cargoArgs)

View File

@ -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"

View File

@ -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(())
}

View File

@ -15,6 +15,9 @@ name = "bdkffi"
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 = { version = "0.23.0" }

View File

@ -94,6 +94,7 @@ interface DatabaseConfig {
};
dictionary TransactionDetails {
Transaction? transaction;
u64? fee;
u64 received;
u64 sent;
@ -186,9 +187,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 {
@ -225,7 +233,7 @@ interface Wallet {
boolean sign([ByRef] PartiallySignedTransaction psbt);
[Throws=BdkError]
sequence<TransactionDetails> list_transactions();
sequence<TransactionDetails> list_transactions(boolean include_raw);
Network network();
@ -244,10 +252,32 @@ interface FeeRate {
};
interface Transaction {
[Throws=BdkError]
constructor(sequence<u8> transaction_bytes);
[Throws=BdkError]
constructor(sequence<u8> transaction_bytes);
sequence<u8> serialize();
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 {

View File

@ -15,6 +15,8 @@ use crate::keys::{DescriptorPublicKey, DescriptorSecretKey, Mnemonic};
use crate::psbt::PartiallySignedTransaction;
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::{
@ -25,6 +27,7 @@ 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::{Balance as BdkBalance, BlockTime, Error as BdkError, FeeRate, KeychainKind};
use std::convert::From;
use std::fmt;
@ -49,7 +52,7 @@ pub struct AddressInfo {
}
impl From<BdkAddressInfo> for AddressInfo {
fn from(x: bdk::wallet::AddressInfo) -> AddressInfo {
fn from(x: bdk::wallet::AddressInfo) -> Self {
AddressInfo {
index: x.index,
address: x.address.to_string(),
@ -79,13 +82,13 @@ 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 {
fn from(x: AddressIndex) -> Self {
match x {
AddressIndex::New => BdkAddressIndex::New,
AddressIndex::LastUnused => BdkAddressIndex::LastUnused,
@ -98,6 +101,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 +120,18 @@ pub struct TransactionDetails {
pub confirmation_time: Option<BlockTime>,
}
impl From<&bdk::TransactionDetails> for TransactionDetails {
fn from(x: &bdk::TransactionDetails) -> TransactionDetails {
impl From<bdk::TransactionDetails> for TransactionDetails {
fn from(tx_details: bdk::TransactionDetails) -> 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,7 +146,7 @@ pub struct OutPoint {
}
impl From<&OutPoint> for BdkOutPoint {
fn from(x: &OutPoint) -> BdkOutPoint {
fn from(x: &OutPoint) -> Self {
BdkOutPoint {
txid: Txid::from_str(&x.txid).unwrap(),
vout: x.vout,
@ -175,11 +183,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(x: &BdkTxOut) -> Self {
TxOut {
value: x.value,
script_pubkey: Arc::new(Script {
script: x.script_pubkey.clone(),
}),
}
}
}
pub struct LocalUtxo {
@ -189,27 +209,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,
}
}
}
@ -238,8 +252,32 @@ impl fmt::Debug for ProgressHolder {
}
}
#[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(x: &BdkTxIn) -> Self {
TxIn {
previous_output: OutPoint {
txid: x.previous_output.txid.to_string(),
vout: x.previous_output.vout,
},
script_sig: Arc::new(Script {
script: x.script_sig.clone(),
}),
sequence: x.sequence.0,
witness: x.witness.to_vec(),
}
}
}
/// A Bitcoin transaction.
#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Transaction {
internal: BdkTransaction,
}
@ -251,9 +289,59 @@ 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<bdk::bitcoin::Transaction> for Transaction {
fn from(tx: bdk::bitcoin::Transaction) -> Self {
Transaction { internal: tx }
}
}
/// A Bitcoin address.
@ -288,6 +376,12 @@ impl Script {
}
}
impl From<BdkScript> for Script {
fn from(bdk_script: BdkScript) -> Self {
Script { script: bdk_script }
}
}
#[derive(Clone, Debug)]
enum RbfValue {
Default,

View File

@ -34,7 +34,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.

View File

@ -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, 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)]
@ -117,10 +120,13 @@ impl Wallet {
}
/// 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 +134,8 @@ 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())
}
}
@ -373,7 +376,7 @@ impl TxBuilder {
psbt: Arc::new(PartiallySignedTransaction {
internal: Mutex::new(psbt),
}),
transaction_details: TransactionDetails::from(&tx_details),
transaction_details: TransactionDetails::from(tx_details),
})
}
}
@ -577,28 +580,19 @@ mod test {
// new index still 0
assert_eq!(
wallet
.get_address(crate::AddressIndex::New)
.unwrap()
.address,
wallet.get_address(AddressIndex::New).unwrap().address,
"bcrt1qqjn9gky9mkrm3c28e5e87t5akd3twg6xezp0tv"
);
// new index now 1
assert_eq!(
wallet
.get_address(crate::AddressIndex::New)
.unwrap()
.address,
wallet.get_address(AddressIndex::New).unwrap().address,
"bcrt1q0xs7dau8af22rspp4klya4f7lhggcnqfun2y3a"
);
// new index now 2
assert_eq!(
wallet
.get_address(crate::AddressIndex::New)
.unwrap()
.address,
wallet.get_address(AddressIndex::New).unwrap().address,
"bcrt1q5g0mq6dkmwzvxscqwgc932jhgcxuqqkjv09tkj"
);
@ -646,16 +640,18 @@ mod test {
.unwrap();
assert_eq!(
wallet
.get_address(crate::AddressIndex::New)
.unwrap()
.address,
wallet.get_address(AddressIndex::New).unwrap().address,
"bcrt1qqjn9gky9mkrm3c28e5e87t5akd3twg6xezp0tv"
);
assert_eq!(
wallet.get_address(AddressIndex::New).unwrap().address,
"bcrt1q0xs7dau8af22rspp4klya4f7lhggcnqfun2y3a"
);
assert_eq!(
wallet
.get_address(crate::AddressIndex::New)
.get_address(AddressIndex::LastUnused)
.unwrap()
.address,
"bcrt1q0xs7dau8af22rspp4klya4f7lhggcnqfun2y3a"
@ -663,15 +659,7 @@ mod test {
assert_eq!(
wallet
.get_address(crate::AddressIndex::LastUnused)
.unwrap()
.address,
"bcrt1q0xs7dau8af22rspp4klya4f7lhggcnqfun2y3a"
);
assert_eq!(
wallet
.get_internal_address(crate::AddressIndex::New)
.get_internal_address(AddressIndex::New)
.unwrap()
.address,
"bcrt1qpmz73cyx00r4a5dea469j40ax6d6kqyd67nnpj"
@ -679,7 +667,7 @@ mod test {
assert_eq!(
wallet
.get_internal_address(crate::AddressIndex::New)
.get_internal_address(AddressIndex::New)
.unwrap()
.address,
"bcrt1qaux734vuhykww9632v8cmdnk7z2mw5lsf74v6k"
@ -687,7 +675,7 @@ mod test {
assert_eq!(
wallet
.get_internal_address(crate::AddressIndex::LastUnused)
.get_internal_address(AddressIndex::LastUnused)
.unwrap()
.address,
"bcrt1qaux734vuhykww9632v8cmdnk7z2mw5lsf74v6k"

View File

@ -12,26 +12,26 @@ internal class UniFfiJvmPlugin : Plugin<Project> {
override fun apply(target: Project): Unit = target.run {
// register a task called buildJvmBinaries which will run something like
// cargo build --features uniffi/cli --release --target aarch64-apple-darwin
// cargo build --release --target aarch64-apple-darwin
val buildJvmBinaries by tasks.register<DefaultTask>("buildJvmBinaries") {
if (operatingSystem == OS.MAC) {
exec {
workingDir("${project.projectDir}/../../bdk-ffi")
executable("cargo")
val cargoArgs: List<String> = listOf("build", "--features", "uniffi/cli", "--profile", "release-smaller", "--target", "x86_64-apple-darwin")
val cargoArgs: List<String> = listOf("build", "--profile", "release-smaller", "--target", "x86_64-apple-darwin")
args(cargoArgs)
}
exec {
workingDir("${project.projectDir}/../../bdk-ffi")
executable("cargo")
val cargoArgs: List<String> = listOf("build", "--features", "uniffi/cli", "--profile", "release-smaller", "--target", "aarch64-apple-darwin")
val cargoArgs: List<String> = listOf("build", "--profile", "release-smaller", "--target", "aarch64-apple-darwin")
args(cargoArgs)
}
} else if(operatingSystem == OS.LINUX) {
exec {
workingDir("${project.projectDir}/../../bdk-ffi")
executable("cargo")
val cargoArgs: List<String> = listOf("build", "--features", "uniffi/cli", "--profile", "release-smaller", "--target", "x86_64-unknown-linux-gnu")
val cargoArgs: List<String> = listOf("build", "--profile", "release-smaller", "--target", "x86_64-unknown-linux-gnu")
args(cargoArgs)
}
}
@ -90,7 +90,7 @@ internal class UniFfiJvmPlugin : Plugin<Project> {
dependsOn(moveNativeJvmLibs)
workingDir("${project.projectDir}/../../bdk-ffi")
val cargoArgs: List<String> = listOf("run", "--features", "uniffi/cli", "--bin", "uniffi-bindgen", "generate", "src/bdk.udl", "--language", "kotlin", "--out-dir", "../bdk-jvm/lib/src/main/kotlin", "--no-format")
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(cargoArgs)

View File

@ -5,10 +5,10 @@ OS=$(uname -s)
echo "Generating bdk.py..."
cd ../bdk-ffi/
cargo run --features uniffi/cli --bin uniffi-bindgen generate src/bdk.udl --language python --out-dir ../bdk-python/src/bdkpython/ --no-format
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 --features uniffi/cli --profile release-smaller
cargo build --profile release-smaller
case $OS in
"Darwin")
echo "Copying macOS libbdkffi.dylib..."

View File

@ -13,14 +13,14 @@ rustup target add aarch64-apple-darwin x86_64-apple-darwin
pushd bdk-ffi
mkdir -p Sources/BitcoinDevKit
cargo run --features uniffi/cli --bin uniffi-bindgen generate src/bdk.udl --language swift --out-dir ../bdk-swift/Sources/BitcoinDevKit --no-format
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 --features uniffi/cli --profile release-smaller --target x86_64-apple-darwin
cargo build --package bdk-ffi --features uniffi/cli --profile release-smaller --target aarch64-apple-darwin
cargo build --package bdk-ffi --features uniffi/cli --profile release-smaller --target x86_64-apple-ios
cargo build --package bdk-ffi --features uniffi/cli --profile release-smaller --target aarch64-apple-ios
cargo +nightly build --package bdk-ffi --features uniffi/cli --release -Z build-std --target aarch64-apple-ios-sim
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
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