Compare commits
30 Commits
release/0.
...
release/0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
634d7db36e | ||
|
|
2233517495 | ||
|
|
49716471d4 | ||
|
|
ced11cb1ee | ||
|
|
5f7d8a9077 | ||
|
|
d77f5b84c3 | ||
|
|
6555170d28 | ||
|
|
c763609b8b | ||
|
|
340fa19bb8 | ||
|
|
ff2734663e | ||
|
|
f399b799e4 | ||
|
|
cdde26a8ea | ||
|
|
34af88df6f | ||
|
|
12e9a18357 | ||
|
|
bada9b82e0 | ||
|
|
41f15fe80f | ||
|
|
54953fa208 | ||
|
|
b7ccf81c7a | ||
|
|
3792a98426 | ||
|
|
5dd79e9632 | ||
|
|
9ae938ca8c | ||
|
|
05aa7157df | ||
|
|
275bd94148 | ||
|
|
146cb039c3 | ||
|
|
41fdadb09c | ||
|
|
4ed6e364e6 | ||
|
|
d0cd3b0f38 | ||
|
|
f216417fd2 | ||
|
|
7d1a4500ef | ||
|
|
a408387bff |
4
.github/workflows/build-python-wheels.yaml
vendored
4
.github/workflows/build-python-wheels.yaml
vendored
@@ -90,7 +90,7 @@ jobs:
|
|||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: bdkpython-macos-${{ matrix.python }}
|
name: bdkpython-macos-${{ matrix.python }}
|
||||||
path: dist/*.whl
|
path: /Users/runner/work/bdk-ffi/bdk-ffi/bdk-python/dist/*.whl
|
||||||
|
|
||||||
build-windows-wheel:
|
build-windows-wheel:
|
||||||
name: 'Build windows wheel'
|
name: 'Build windows wheel'
|
||||||
@@ -123,4 +123,4 @@ jobs:
|
|||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: bdkpython-win-${{ matrix.python }}
|
name: bdkpython-win-${{ matrix.python }}
|
||||||
path: dist/*.whl
|
path: D:\a\bdk-ffi\bdk-ffi\bdk-python\dist\*.whl
|
||||||
|
|||||||
4
.github/workflows/publish-python.yaml
vendored
4
.github/workflows/publish-python.yaml
vendored
@@ -82,7 +82,7 @@ jobs:
|
|||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: bdkpython-macos-${{ matrix.python }}
|
name: bdkpython-macos-${{ matrix.python }}
|
||||||
path: dist/*.whl
|
path: /Users/runner/work/bdk-ffi/bdk-ffi/bdk-python/dist/*.whl
|
||||||
|
|
||||||
build-windows-wheel:
|
build-windows-wheel:
|
||||||
name: 'Build windows wheel'
|
name: 'Build windows wheel'
|
||||||
@@ -115,7 +115,7 @@ jobs:
|
|||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: bdkpython-win-${{ matrix.python }}
|
name: bdkpython-win-${{ matrix.python }}
|
||||||
path: dist/*.whl
|
path: D:\a\bdk-ffi\bdk-ffi\bdk-python\dist\*.whl
|
||||||
|
|
||||||
publish-pypi:
|
publish-pypi:
|
||||||
name: 'Publish on PyPI'
|
name: 'Publish on PyPI'
|
||||||
|
|||||||
5
.github/workflows/test-android.yaml
vendored
5
.github/workflows/test-android.yaml
vendored
@@ -46,11 +46,6 @@ jobs:
|
|||||||
- name: Install rust android targets
|
- name: Install rust android targets
|
||||||
run: rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabi
|
run: rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabi
|
||||||
|
|
||||||
- name: Build bdk-android library
|
|
||||||
run: |
|
|
||||||
cd bdk-android
|
|
||||||
./gradlew buildAndroidLib
|
|
||||||
|
|
||||||
- name: Run Android tests
|
- name: Run Android tests
|
||||||
run: |
|
run: |
|
||||||
cd bdk-android
|
cd bdk-android
|
||||||
|
|||||||
5
.github/workflows/test-jvm.yaml
vendored
5
.github/workflows/test-jvm.yaml
vendored
@@ -31,11 +31,6 @@ jobs:
|
|||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: 11
|
java-version: 11
|
||||||
|
|
||||||
- name: Build bdk-jvm library
|
|
||||||
run: |
|
|
||||||
cd bdk-jvm
|
|
||||||
./gradlew buildJvmLib
|
|
||||||
|
|
||||||
- name: Run JVM tests
|
- name: Run JVM tests
|
||||||
run: |
|
run: |
|
||||||
cd bdk-jvm
|
cd bdk-jvm
|
||||||
|
|||||||
290
Cargo.lock
generated
290
Cargo.lock
generated
@@ -2,6 +2,12 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ahash"
|
name = "ahash"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
@@ -24,9 +30,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.66"
|
version = "1.0.68"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
|
checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "askama"
|
name = "askama"
|
||||||
@@ -74,10 +80,16 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "assert_matches"
|
||||||
version = "0.1.59"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364"
|
checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-trait"
|
||||||
|
version = "0.1.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "677d1d8ab452a3936018a687b20e6f7cf5363d713b732b8884001317b0e48aa3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -108,16 +120,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bdk"
|
name = "base64-compat"
|
||||||
version = "0.25.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c1e7eb54c6288eca1b698e6e33dd82ebe6c08a93ec1a96bb6926ddceed22c703"
|
checksum = "5a8d4d2746f89841e49230dd26917df1876050f95abafafbe34f47cb534b88d7"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bdk"
|
||||||
|
version = "0.26.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b238a07736baee43ba9663933e44b1c6c27b43ef871b9486e175902335d83880"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bdk-macros",
|
"bdk-macros",
|
||||||
"bip39",
|
"bip39",
|
||||||
"bitcoin",
|
"bitcoin",
|
||||||
|
"bitcoincore-rpc",
|
||||||
"electrum-client",
|
"electrum-client",
|
||||||
"esplora-client",
|
"esplora-client",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
@@ -134,8 +156,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bdk-ffi"
|
name = "bdk-ffi"
|
||||||
version = "0.25.0"
|
version = "0.26.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"assert_matches",
|
||||||
"bdk",
|
"bdk",
|
||||||
"uniffi",
|
"uniffi",
|
||||||
"uniffi_build",
|
"uniffi_build",
|
||||||
@@ -218,6 +241,30 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitcoincore-rpc"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0261b2bb7617e0c91b452a837bbd1291fd34ad6990cb8e3ffc28239cc045b5ca"
|
||||||
|
dependencies = [
|
||||||
|
"bitcoincore-rpc-json",
|
||||||
|
"jsonrpc",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitcoincore-rpc-json"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c231bea28e314879c5aef240f6052e8a72a369e3c9f9b20d9bfbb33ad18029b2"
|
||||||
|
dependencies = [
|
||||||
|
"bitcoin",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
@@ -275,9 +322,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.77"
|
version = "1.0.78"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
|
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@@ -285,12 +332,6 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chunked_transfer"
|
|
||||||
version = "1.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.34.0"
|
version = "2.34.0"
|
||||||
@@ -386,19 +427,19 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"rustls 0.20.7",
|
"rustls",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"webpki 0.22.0",
|
"webpki",
|
||||||
"webpki-roots 0.22.5",
|
"webpki-roots",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "esplora-client"
|
name = "esplora-client"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4b94400573de17e346ab91ec08ad13d37e871e400b9930d4cb2b6b02253e760e"
|
checksum = "38bbba572d03ca4d628b653f01e60ba6947c67df65ee8910c79daaf252897924"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitcoin",
|
"bitcoin",
|
||||||
"log",
|
"log",
|
||||||
@@ -418,6 +459,16 @@ version = "0.1.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flate2"
|
||||||
|
version = "1.0.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
|
||||||
|
dependencies = [
|
||||||
|
"crc32fast",
|
||||||
|
"miniz_oxide",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "form_urlencoded"
|
name = "form_urlencoded"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -554,9 +605,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.4"
|
version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
@@ -567,6 +618,18 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jsonrpc"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f8423b78fc94d12ef1a4a9d13c348c9a78766dda0cc18817adf0faf77e670c8"
|
||||||
|
dependencies = [
|
||||||
|
"base64-compat",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -575,9 +638,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.138"
|
version = "0.2.139"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
|
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libsqlite3-sys"
|
name = "libsqlite3-sys"
|
||||||
@@ -669,10 +732,19 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "miniz_oxide"
|
||||||
version = "7.1.1"
|
version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
|
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
|
||||||
|
dependencies = [
|
||||||
|
"adler",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5507769c4919c998e69e49c839d9dc6e693ede4cc4290d6ad8b41d4f09c548c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
"minimal-lexical",
|
"minimal-lexical",
|
||||||
@@ -680,9 +752,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.16.0"
|
version = "1.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_str_bytes"
|
name = "os_str_bytes"
|
||||||
@@ -703,9 +775,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot_core"
|
name = "parking_lot_core"
|
||||||
version = "0.8.5"
|
version = "0.8.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"instant",
|
"instant",
|
||||||
@@ -717,9 +789,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "paste"
|
||||||
version = "1.0.9"
|
version = "1.0.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
|
checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
@@ -777,18 +849,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.47"
|
version = "1.0.49"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
|
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.21"
|
version = "1.0.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@@ -868,19 +940,6 @@ dependencies = [
|
|||||||
"smallvec 1.10.0",
|
"smallvec 1.10.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustls"
|
|
||||||
version = "0.19.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
|
|
||||||
dependencies = [
|
|
||||||
"base64",
|
|
||||||
"log",
|
|
||||||
"ring",
|
|
||||||
"sct 0.6.1",
|
|
||||||
"webpki 0.21.4",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.20.7"
|
version = "0.20.7"
|
||||||
@@ -889,15 +948,15 @@ checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ring",
|
"ring",
|
||||||
"sct 0.7.0",
|
"sct",
|
||||||
"webpki 0.22.0",
|
"webpki",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.11"
|
version = "1.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
@@ -925,16 +984,6 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sct"
|
|
||||||
version = "0.6.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
|
|
||||||
dependencies = [
|
|
||||||
"ring",
|
|
||||||
"untrusted",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sct"
|
name = "sct"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@@ -947,9 +996,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "secp256k1"
|
name = "secp256k1"
|
||||||
version = "0.24.1"
|
version = "0.24.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ff55dc09d460954e9ef2fa8a7ced735a964be9981fd50e870b2b3b0705e14964"
|
checksum = "d9512ffd81e3a3503ed401f79c33168b9148c75038956039166cd750eaa037c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitcoin_hashes 0.11.0",
|
"bitcoin_hashes 0.11.0",
|
||||||
"rand",
|
"rand",
|
||||||
@@ -968,27 +1017,27 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.14"
|
version = "1.0.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
|
checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.149"
|
version = "1.0.152"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055"
|
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.149"
|
version = "1.0.152"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4"
|
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -997,15 +1046,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.89"
|
version = "1.0.91"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
|
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "siphasher"
|
||||||
|
version = "0.3.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sled"
|
name = "sled"
|
||||||
version = "0.34.7"
|
version = "0.34.7"
|
||||||
@@ -1098,9 +1153,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.105"
|
version = "1.0.107"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
|
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -1156,9 +1211,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.5.9"
|
version = "0.5.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
|
checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
@@ -1180,9 +1235,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.5"
|
version = "1.0.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
@@ -1207,9 +1262,9 @@ checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uniffi"
|
name = "uniffi"
|
||||||
version = "0.21.0"
|
version = "0.21.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f54af5ada67d1173457a99a7bb44a7917f63e7466764cb4714865c7a6678b830"
|
checksum = "b983553c0d1ad73547c65fa0c399aa800bee4a70ad330198e1c7a523212da5ee"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -1225,9 +1280,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uniffi_bindgen"
|
name = "uniffi_bindgen"
|
||||||
version = "0.21.0"
|
version = "0.21.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12cc4af3c0180c7e86c4a3acf2b6587af04ba2567b1e948993df10f421796621"
|
checksum = "5d46080a4840abccf7c0cce21931dae53215cbd7dd969b5e63c486235ce91a2a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"askama",
|
"askama",
|
||||||
@@ -1248,9 +1303,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uniffi_build"
|
name = "uniffi_build"
|
||||||
version = "0.21.0"
|
version = "0.21.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "510287c368a9386eb731ebe824a6fc6c82a105e20d020af1aa20519c1c1561db"
|
checksum = "d035e50433ee3d52ab0dcdcf3b9b26f2cc2ec39294b3c07d95865a518709455f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"camino",
|
"camino",
|
||||||
@@ -1258,10 +1313,20 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uniffi_macros"
|
name = "uniffi_checksum_derive"
|
||||||
version = "0.21.0"
|
version = "0.21.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c8604503caa2cbcf271578dc51ca236d40e3b22e1514ffa2e638e2c39f6ad10"
|
checksum = "78b6e16d46caf942016997af8bbdf4b163bf8ae3deb0b667d9643de7b7ffd4c9"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uniffi_macros"
|
||||||
|
version = "0.21.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c96a574677566f83ea8458dac1dd7792fd63e7c3f9dbcd865f0e8d6f8057b127"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"camino",
|
"camino",
|
||||||
@@ -1278,11 +1343,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uniffi_meta"
|
name = "uniffi_meta"
|
||||||
version = "0.21.0"
|
version = "0.21.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cd9417cc653937681436b93838d8c5f97a5b8c58697813982ee8810bd1dc3b57"
|
checksum = "729835442da829c9b6f7c111c76cf87b2498e129101203bec94f0c39a3296a38"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
|
"siphasher",
|
||||||
|
"uniffi_checksum_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1293,21 +1360,21 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ureq"
|
name = "ureq"
|
||||||
version = "2.2.0"
|
version = "2.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3131cd6cb18488da91da1d10ed31e966f453c06b65bf010d35638456976a3fd7"
|
checksum = "733b5ad78377302af52c0dbcb2623d78fe50e4b3bf215948ff29e9ee031d8566"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"chunked_transfer",
|
"flate2",
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustls 0.19.1",
|
"rustls",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"socks",
|
"socks",
|
||||||
"url",
|
"url",
|
||||||
"webpki 0.21.4",
|
"webpki",
|
||||||
"webpki-roots 0.21.1",
|
"webpki-roots",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1409,16 +1476,6 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "webpki"
|
|
||||||
version = "0.21.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
|
|
||||||
dependencies = [
|
|
||||||
"ring",
|
|
||||||
"untrusted",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki"
|
name = "webpki"
|
||||||
version = "0.22.0"
|
version = "0.22.0"
|
||||||
@@ -1431,20 +1488,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-roots"
|
name = "webpki-roots"
|
||||||
version = "0.21.1"
|
version = "0.22.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
|
checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"webpki 0.21.4",
|
"webpki",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "webpki-roots"
|
|
||||||
version = "0.22.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be"
|
|
||||||
dependencies = [
|
|
||||||
"webpki 0.22.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
6
api-docs/README.md
Normal file
6
api-docs/README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# API documentation
|
||||||
|
The Bitcoin Dev Kit language bindings make use of the [uniffi-rs](https://github.com/mozilla/uniffi-rs) library to produce their bindings. While efforts are ongoing to allow inline documentation on the Rust side to be ported to the bindings code, this is not currently possible.
|
||||||
|
|
||||||
|
This directory contains our temporary solution to this problem. A set of files mimicking the bindings libraries in their function signatures, but without any implementation. This allows for documentation build tools to produce API docs similarly to how we would like them to be if they could be inlined.
|
||||||
|
|
||||||
|
You can find the resulting API documentation websites in the ["API Reference" section of the sidebar](https://bitcoindevkit.org/getting-started/) under the "Docs" tab on the bitcoindevkit official website.
|
||||||
@@ -120,15 +120,17 @@ data class SledDbConfiguration(
|
|||||||
* @property retry Request retry count.
|
* @property retry Request retry count.
|
||||||
* @property timeout Request timeout (seconds).
|
* @property timeout Request timeout (seconds).
|
||||||
* @property stopGap Stop searching addresses for transactions after finding an unused gap of this length.
|
* @property stopGap Stop searching addresses for transactions after finding an unused gap of this length.
|
||||||
|
* @property validateDomain Validate the domain when using SSL.
|
||||||
*
|
*
|
||||||
* @sample org.bitcoindevkit.electrumBlockchainConfigSample
|
* @sample org.bitcoindevkit.electrumBlockchainConfigSample
|
||||||
*/
|
*/
|
||||||
data class ElectrumConfig (
|
data class ElectrumConfig(
|
||||||
var url: String,
|
var url: String,
|
||||||
var socks5: String?,
|
var socks5: String?,
|
||||||
var retry: UByte,
|
var retry: UByte,
|
||||||
var timeout: UByte?,
|
var timeout: UByte?,
|
||||||
var stopGap: ULong
|
var stopGap: ULong,
|
||||||
|
var validateDomain: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -142,7 +144,7 @@ data class ElectrumConfig (
|
|||||||
*
|
*
|
||||||
* @sample org.bitcoindevkit.esploraBlockchainConfigSample
|
* @sample org.bitcoindevkit.esploraBlockchainConfigSample
|
||||||
*/
|
*/
|
||||||
data class EsploraConfig (
|
data class EsploraConfig(
|
||||||
var baseUrl: String,
|
var baseUrl: String,
|
||||||
var proxy: String?,
|
var proxy: String?,
|
||||||
var concurrency: UByte?,
|
var concurrency: UByte?,
|
||||||
@@ -150,6 +152,56 @@ data class EsploraConfig (
|
|||||||
var timeout: ULong?
|
var timeout: ULong?
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authentication mechanism for RPC connection to full node.
|
||||||
|
*/
|
||||||
|
sealed class Auth {
|
||||||
|
/** No authentication */
|
||||||
|
object None: Auth()
|
||||||
|
|
||||||
|
/** Authentication with username and password, usually [Auth.Cookie] should be preferred */
|
||||||
|
data class UserPass(val username: String, val password: String): Auth()
|
||||||
|
|
||||||
|
/** Authentication with a cookie file */
|
||||||
|
data class Cookie(val file: String): Auth()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sync parameters for Bitcoin Core RPC.
|
||||||
|
*
|
||||||
|
* In general, BDK tries to sync `scriptPubKey`s cached in `Database` with
|
||||||
|
* `scriptPubKey`s imported in the Bitcoin Core Wallet. These parameters are used for determining
|
||||||
|
* how the `importdescriptors` RPC calls are to be made.
|
||||||
|
*
|
||||||
|
* @property startScriptCount The minimum number of scripts to scan for on initial sync.
|
||||||
|
* @property startTime Time in unix seconds in which initial sync will start scanning from (0 to start from genesis).
|
||||||
|
* @property forceStartTime Forces every sync to use `start_time` as import timestamp.
|
||||||
|
* @property pollRateSec RPC poll rate (in seconds) to get state updates.
|
||||||
|
*/
|
||||||
|
data class RcpSyncParams(
|
||||||
|
val startScriptCount: ULong,
|
||||||
|
val startTime: Ulong,
|
||||||
|
val forceStartTime: Boolean,
|
||||||
|
val pollRateSec: ULong,
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RpcBlockchain configuration options
|
||||||
|
*
|
||||||
|
* @property url The bitcoin node url.
|
||||||
|
* @property auth The bicoin node authentication mechanism.
|
||||||
|
* @property network The network we are using (it will be checked the bitcoin node network matches this).
|
||||||
|
* @property walletName The wallet name in the bitcoin node.
|
||||||
|
* @property syncParams Sync parameters.
|
||||||
|
*/
|
||||||
|
data class RpcConfig(
|
||||||
|
val url: String,
|
||||||
|
val auth: Auth,
|
||||||
|
val network: Network,
|
||||||
|
val walletName: String,
|
||||||
|
val syncParams: RcpSyncParams?,
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type that can contain any of the blockchain configurations defined by the library.
|
* Type that can contain any of the blockchain configurations defined by the library.
|
||||||
*
|
*
|
||||||
@@ -161,6 +213,9 @@ sealed class BlockchainConfig {
|
|||||||
|
|
||||||
/** Esplora client. */
|
/** Esplora client. */
|
||||||
data class Esplora(val config: EsploraConfig) : BlockchainConfig()
|
data class Esplora(val config: EsploraConfig) : BlockchainConfig()
|
||||||
|
|
||||||
|
/** Bitcoin Core RPC client. */
|
||||||
|
data class Rpc(val config: RpcConfig) : BlockchainConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -193,7 +248,7 @@ class Blockchain(
|
|||||||
config: BlockchainConfig
|
config: BlockchainConfig
|
||||||
) {
|
) {
|
||||||
/** Broadcast a transaction. */
|
/** Broadcast a transaction. */
|
||||||
fun broadcast(psbt: PartiallySignedBitcoinTransaction): String {}
|
fun broadcast(psbt: PartiallySignedBitcoinTransaction) {}
|
||||||
|
|
||||||
/** Get the current height of the blockchain. */
|
/** Get the current height of the blockchain. */
|
||||||
fun getHeight(): UInt {}
|
fun getHeight(): UInt {}
|
||||||
@@ -295,15 +350,15 @@ data class BlockTime (
|
|||||||
* @constructor Create a BDK wallet.
|
* @constructor Create a BDK wallet.
|
||||||
*
|
*
|
||||||
* @param descriptor The main (or "external") descriptor.
|
* @param descriptor The main (or "external") descriptor.
|
||||||
* @param changeDescriptor The change (or "internal") descriptor.
|
* @param changeDescriptor? The change (or "internal") descriptor.
|
||||||
* @param network The network to act on.
|
* @param network The network to act on.
|
||||||
* @param databaseConfig The database configuration.
|
* @param databaseConfig The database configuration.
|
||||||
*
|
*
|
||||||
* @sample org.bitcoindevkit.walletSample
|
* @sample org.bitcoindevkit.walletSample
|
||||||
*/
|
*/
|
||||||
class Wallet(
|
class Wallet(
|
||||||
descriptor: String,
|
descriptor: Descriptor,
|
||||||
changeDescriptor: String,
|
changeDescriptor: Descriptor?,
|
||||||
network: Network,
|
network: Network,
|
||||||
databaseConfig: DatabaseConfig,
|
databaseConfig: DatabaseConfig,
|
||||||
) {
|
) {
|
||||||
@@ -314,8 +369,8 @@ class Wallet(
|
|||||||
*/
|
*/
|
||||||
fun getAddress(addressIndex: AddressIndex): AddressInfo {}
|
fun getAddress(addressIndex: AddressIndex): AddressInfo {}
|
||||||
|
|
||||||
/** Return the balance, meaning the sum of this wallet’s unspent outputs’ values. Note that this method only operates on the internal database, which first needs to be [Wallet.sync] manually. */
|
/** 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(): ULong {}
|
fun getBalance(): Balance {}
|
||||||
|
|
||||||
/** Sign a transaction with all the wallet’s signers. */
|
/** Sign a transaction with all the wallet’s signers. */
|
||||||
fun sign(psbt: PartiallySignedBitcoinTransaction): Boolean {}
|
fun sign(psbt: PartiallySignedBitcoinTransaction): Boolean {}
|
||||||
@@ -410,7 +465,7 @@ class TxBuilder() {
|
|||||||
* [drainWallet] to spend all of them. When bumping the fees of a transaction made with this option,
|
* [drainWallet] to spend all of them. When bumping the fees of a transaction made with this option,
|
||||||
* you probably want to use [BumpFeeTxBuilder.allowShrinking] to allow this output to be reduced to pay for the extra fees.
|
* you probably want to use [BumpFeeTxBuilder.allowShrinking] to allow this output to be reduced to pay for the extra fees.
|
||||||
*/
|
*/
|
||||||
fun drainTo(address: String): TxBuilder {}
|
fun drainTo(script: Script): TxBuilder {}
|
||||||
|
|
||||||
/** Enable signaling RBF. This will use the default `nsequence` value of `0xFFFFFFFD`. */
|
/** Enable signaling RBF. This will use the default `nsequence` value of `0xFFFFFFFD`. */
|
||||||
fun enableRbf(): TxBuilder {}
|
fun enableRbf(): TxBuilder {}
|
||||||
@@ -495,7 +550,7 @@ class DescriptorSecretKey(network: Network, mnemonic: Mnemonic, password: String
|
|||||||
/** Return the public version of the descriptor. */
|
/** Return the public version of the descriptor. */
|
||||||
fun asPublic(): DescriptorPublicKey {}
|
fun asPublic(): DescriptorPublicKey {}
|
||||||
|
|
||||||
/* Return the raw private key as bytes. */
|
/** Return the raw private key as bytes. */
|
||||||
fun secretBytes(): List<UByte>
|
fun secretBytes(): List<UByte>
|
||||||
|
|
||||||
/** Return the private descriptor as a string. */
|
/** Return the private descriptor as a string. */
|
||||||
@@ -523,6 +578,62 @@ class DescriptorPublicKey(network: Network, mnemonic: String, password: String?)
|
|||||||
fun asString(): String
|
fun asString(): String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A output descriptor.
|
||||||
|
*
|
||||||
|
* @param descriptor The descriptor in string format.
|
||||||
|
* @param network The network this descriptor is to be used on.
|
||||||
|
*
|
||||||
|
* @sample org.bitcoindevkit.descriptorTemplates1
|
||||||
|
* @sample org.bitcoindevkit.descriptorTemplates2
|
||||||
|
*/
|
||||||
|
class Descriptor(descriptor: String, network: Network) {
|
||||||
|
/**
|
||||||
|
* BIP44 template. Expands to pkh(key/44'/{0,1}'/0'/{0,1}/\*)
|
||||||
|
* Since there are hardened derivation steps, this template requires a private derivable key (generally a xprv/tprv).
|
||||||
|
*/
|
||||||
|
fun newBip44(secretKey: DescriptorSecretKey, keychain: KeychainKind, network: Network) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BIP44 public template. Expands to pkh(key/{0,1}/\*)
|
||||||
|
* This assumes that the key used has already been derived with m/44'/0'/0' for Mainnet or m/44'/1'/0' for Testnet.
|
||||||
|
* This template requires the parent fingerprint to populate correctly the metadata of PSBTs.
|
||||||
|
*/
|
||||||
|
fun newBip44Public(publicKey: DescriptorPublicKey, fingerprint: String, keychain: KeychainKind, network: Network) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BIP49 template. Expands to sh(wpkh(key/49'/{0,1}'/0'/{0,1}/\*))
|
||||||
|
* Since there are hardened derivation steps, this template requires a private derivable key (generally a xprv/tprv).
|
||||||
|
*/
|
||||||
|
fun newBip49(secretKey: DescriptorSecretKey, keychain: KeychainKind, network: Network) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BIP49 public template. Expands to sh(wpkh(key/{0,1}/\*))
|
||||||
|
* This assumes that the key used has already been derived with m/49'/0'/0' for Mainnet or m/49'/1'/0' for Testnet.
|
||||||
|
* This template requires the parent fingerprint to populate correctly the metadata of PSBTs.
|
||||||
|
*/
|
||||||
|
fun newBip49Public(publicKey: DescriptorPublicKey, fingerprint: String, keychain: KeychainKind, network: Network) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BIP84 template. Expands to wpkh(key/84'/{0,1}'/0'/{0,1}/\*)
|
||||||
|
* Since there are hardened derivation steps, this template requires a private derivable key (generally a xprv/tprv).
|
||||||
|
*/
|
||||||
|
fun newBip84(secretKey: DescriptorSecretKey, keychain: KeychainKind, network: Network) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BIP84 public template. Expands to wpkh(key/{0,1}/\*)
|
||||||
|
* This assumes that the key used has already been derived with m/84'/0'/0' for Mainnet or m/84'/1'/0' for Testnet.
|
||||||
|
* This template requires the parent fingerprint to populate correctly the metadata of PSBTs.
|
||||||
|
*/
|
||||||
|
fun newBip84Public(publicKey: DescriptorPublicKey, fingerprint: String, keychain: KeychainKind, network: Network) {}
|
||||||
|
|
||||||
|
/** Return the public version of the output descriptor. */
|
||||||
|
fun asString(): String {}
|
||||||
|
|
||||||
|
/** Return the private version of the output descriptor if available, otherwise return the public version. */
|
||||||
|
fun asStringPrivate(): String {}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An enum describing entropy length (aka word count) in the mnemonic.
|
* An enum describing entropy length (aka word count) in the mnemonic.
|
||||||
*/
|
*/
|
||||||
@@ -568,7 +679,7 @@ class Script(rawOutputScript: List<UByte>)
|
|||||||
* @param address The address in string format.
|
* @param address The address in string format.
|
||||||
*/
|
*/
|
||||||
class Address(address: String) {
|
class Address(address: String) {
|
||||||
/* Return the ScriptPubKey. */
|
/** Return the ScriptPubKey. */
|
||||||
fun scriptPubkey(): Script
|
fun scriptPubkey(): Script
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -243,3 +243,34 @@ fun mnemonicSample() {
|
|||||||
|
|
||||||
println(mnemonic0.asString(), mnemonic1.asString(), mnemonic2.asString())
|
println(mnemonic0.asString(), mnemonic1.asString(), mnemonic2.asString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun descriptorTemplates1() {
|
||||||
|
// Bip84 private descriptor
|
||||||
|
val recoveryPhrase: String = "scene change clap smart together mind wheel knee clip normal trial unusual"
|
||||||
|
val mnemonic = Mnemonic.fromString(recoveryPhrase)
|
||||||
|
val bip32ExtendedRootKey: DescriptorSecretKey = DescriptorSecretKey(Network.TESTNET, mnemonic, null)
|
||||||
|
val bip84ExternalDescriptor: Descriptor = Descriptor.newBip84(bip32ExtendedRootKey, KeychainKind.EXTERNAL, Network.TESTNET)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun descriptorTemplates2() {
|
||||||
|
// Bip49 public descriptor
|
||||||
|
// assume we already have the xpub for m/49'/0'/1' created on an external device that only shared the xpub with the wallet
|
||||||
|
// using the template requires the parent fingerprint to populate correctly the metadata of PSBTs, which the external device would provide
|
||||||
|
// the xpub (tpub for testnet): tpubDC65ZRvk1NDddHrVAUAZrUPJ772QXzooNYmPywYF9tMyNLYKf5wpKE7ZJvK9kvfG3FV7rCsHBNXy1LVKW95jrmC7c7z4hq7a27aD2sRrAhR
|
||||||
|
// the fingerprint: d1d04177
|
||||||
|
val descriptorPublicKey: DescriptorPublicKey = DescriptorPublicKey.fromString("tpubDC65ZRvk1NDddHrVAUAZrUPJ772QXzooNYmPywYF9tMyNLYKf5wpKE7ZJvK9kvfG3FV7rCsHBNXy1LVKW95jrmC7c7z4hq7a27aD2sRrAhR")
|
||||||
|
val bip49PublicDescriptor: Descriptor = Descriptor.newBip49Public(
|
||||||
|
publicKey = descriptorPublicKey,
|
||||||
|
fingerprint = "d1d04177",
|
||||||
|
keychain = KeychainKind.EXTERNAL,
|
||||||
|
network = Network.TESTNET,
|
||||||
|
)
|
||||||
|
println(bip49PublicDescriptor.asString()) // sh(wpkh([d1d04177/49'/1'/0']tpubDC65ZRvk1NDddHrVAUAZrUPJ772QXzooNYmPywYF9tMyNLYKf5wpKE7ZJvK9kvfG3FV7rCsHBNXy1LVKW95jrmC7c7z4hq7a27aD2sRrAhR/0/*))#a7lxzefl
|
||||||
|
println(bip49PublicDescriptor.asStringPrivate()) // sh(wpkh([d1d04177/49'/1'/0']tpubDC65ZRvk1NDddHrVAUAZrUPJ772QXzooNYmPywYF9tMyNLYKf5wpKE7ZJvK9kvfG3FV7rCsHBNXy1LVKW95jrmC7c7z4hq7a27aD2sRrAhR/0/*))#a7lxzefl
|
||||||
|
|
||||||
|
// Creating it starting from the full xprv derived from a mnemonic will give you the same public descriptor
|
||||||
|
val mnemonic = Mnemonic.fromString("chaos fabric time speed sponsor all flat solution wisdom trophy crack object robot pave observe combine where aware bench orient secret primary cable detect")
|
||||||
|
val bip32ExtendedRootKey: DescriptorSecretKey = DescriptorSecretKey(Network.TESTNET, mnemonic, null)
|
||||||
|
val bip49PrivateDescriptor: Descriptor = Descriptor.newBip49(bip32ExtendedRootKey, KeychainKind.EXTERNAL, Network.TESTNET)
|
||||||
|
println(bip49PrivateDescriptor.asString()) // sh(wpkh([d1d04177/49'/1'/0']tpubDC65ZRvk1NDddHrVAUAZrUPJ772QXzooNYmPywYF9tMyNLYKf5wpKE7ZJvK9kvfG3FV7rCsHBNXy1LVKW95jrmC7c7z4hq7a27aD2sRrAhR/0/*))#a7lxzefl
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ val internalDescriptor = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEm
|
|||||||
val databaseConfig = DatabaseConfig.Memory
|
val databaseConfig = DatabaseConfig.Memory
|
||||||
|
|
||||||
val blockchainConfig = BlockchainConfig.Electrum(
|
val blockchainConfig = BlockchainConfig.Electrum(
|
||||||
ElectrumConfig("ssl://electrum.blockstream.info:60002", null, 5u, null, 10u)
|
ElectrumConfig("ssl://electrum.blockstream.info:60002", null, 5u, null, 10u, true)
|
||||||
)
|
)
|
||||||
val wallet = Wallet(externalDescriptor, internalDescriptor, Network.TESTNET, databaseConfig, blockchainConfig)
|
val wallet = Wallet(externalDescriptor, internalDescriptor, Network.TESTNET, databaseConfig, blockchainConfig)
|
||||||
val newAddress = wallet.getAddress(AddressIndex.LAST_UNUSED)
|
val newAddress = wallet.getAddress(AddressIndex.LAST_UNUSED)
|
||||||
@@ -95,5 +95,18 @@ and use the `publishToMavenLocal` task without excluding the signing task:
|
|||||||
./gradlew publishToMavenLocal
|
./gradlew publishToMavenLocal
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Known issues
|
||||||
|
Depending on the JVM version you use, you might not have the JNA dependency on your classpath. The exception thrown will be
|
||||||
|
```shell
|
||||||
|
class file for com.sun.jna.Pointer not found
|
||||||
|
```
|
||||||
|
The solution is to add JNA as a dependency like so:
|
||||||
|
```kotlin
|
||||||
|
dependencies {
|
||||||
|
// ...
|
||||||
|
implementation("net.java.dev.jna:jna:5.12.1")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
[`bdk`]: https://github.com/bitcoindevkit/bdk
|
[`bdk`]: https://github.com/bitcoindevkit/bdk
|
||||||
[`bdk-ffi`]: https://github.com/bitcoindevkit/bdk-ffi
|
[`bdk-ffi`]: https://github.com/bitcoindevkit/bdk-ffi
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ org.gradle.jvmargs=-Xmx1536m
|
|||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
libraryVersion=0.12.0-SNAPSHOT
|
libraryVersion=0.26.0
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
// library version is defined in gradle.properties
|
// library version is defined in gradle.properties
|
||||||
val libraryVersion: String by project
|
val libraryVersion: String by project
|
||||||
|
|
||||||
@@ -107,3 +109,9 @@ signing {
|
|||||||
useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword)
|
useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword)
|
||||||
sign(publishing.publications)
|
sign(publishing.publications)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This task dependency ensures that we build the bindings
|
||||||
|
// binaries before running the tests
|
||||||
|
tasks.withType<KotlinCompile> {
|
||||||
|
dependsOn("buildAndroidLib")
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,8 +36,7 @@ class AndroidLibTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val descriptor =
|
private val descriptor = Descriptor("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)", Network.TESTNET)
|
||||||
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"
|
|
||||||
|
|
||||||
private val databaseConfig = DatabaseConfig.Memory
|
private val databaseConfig = DatabaseConfig.Memory
|
||||||
|
|
||||||
@@ -47,7 +46,8 @@ class AndroidLibTest {
|
|||||||
null,
|
null,
|
||||||
5u,
|
5u,
|
||||||
null,
|
null,
|
||||||
100u
|
100u,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "bdk-ffi"
|
name = "bdk-ffi"
|
||||||
version = "0.25.0"
|
version = "0.26.0"
|
||||||
authors = ["Steve Myers <steve@notmandatory.org>", "Sudarsan Balaji <sudarsan.balaji@artfuldev.com>"]
|
authors = ["Steve Myers <steve@notmandatory.org>", "Sudarsan Balaji <sudarsan.balaji@artfuldev.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
@@ -10,10 +10,12 @@ crate-type = ["staticlib", "cdylib"]
|
|||||||
name = "bdkffi"
|
name = "bdkffi"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bdk = { version = "0.25", features = ["all-keys", "use-esplora-ureq", "sqlite-bundled"] }
|
bdk = { version = "0.26", features = ["all-keys", "use-esplora-ureq", "sqlite-bundled", "rpc"] }
|
||||||
|
|
||||||
uniffi_macros = { version = "0.21.0", features = ["builtin-bindgen"] }
|
uniffi_macros = { version = "0.21.0", features = ["builtin-bindgen"] }
|
||||||
uniffi = { version = "0.21.0", features = ["builtin-bindgen"] }
|
uniffi = { version = "0.21.0", features = ["builtin-bindgen"] }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
uniffi_build = { version = "0.21.0", features = ["builtin-bindgen"] }
|
uniffi_build = { version = "0.21.0", features = ["builtin-bindgen"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
assert_matches = "1.5.0"
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ enum BdkError {
|
|||||||
"Esplora",
|
"Esplora",
|
||||||
"Sled",
|
"Sled",
|
||||||
"Rusqlite",
|
"Rusqlite",
|
||||||
|
"Rpc",
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary AddressInfo {
|
dictionary AddressInfo {
|
||||||
@@ -116,6 +117,7 @@ dictionary ElectrumConfig {
|
|||||||
u8 retry;
|
u8 retry;
|
||||||
u8? timeout;
|
u8? timeout;
|
||||||
u64 stop_gap;
|
u64 stop_gap;
|
||||||
|
boolean validate_domain;
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary EsploraConfig {
|
dictionary EsploraConfig {
|
||||||
@@ -126,10 +128,33 @@ dictionary EsploraConfig {
|
|||||||
u64? timeout;
|
u64? timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[Enum]
|
||||||
|
interface Auth {
|
||||||
|
None();
|
||||||
|
UserPass(string username, string password);
|
||||||
|
Cookie(string file);
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary RpcSyncParams {
|
||||||
|
u64 start_script_count;
|
||||||
|
u64 start_time;
|
||||||
|
boolean force_start_time;
|
||||||
|
u64 poll_rate_sec;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary RpcConfig {
|
||||||
|
string url;
|
||||||
|
Auth auth;
|
||||||
|
Network network;
|
||||||
|
string wallet_name;
|
||||||
|
RpcSyncParams? sync_params;
|
||||||
|
};
|
||||||
|
|
||||||
[Enum]
|
[Enum]
|
||||||
interface BlockchainConfig {
|
interface BlockchainConfig {
|
||||||
Electrum(ElectrumConfig config);
|
Electrum(ElectrumConfig config);
|
||||||
Esplora(EsploraConfig config);
|
Esplora(EsploraConfig config);
|
||||||
|
Rpc(RpcConfig config);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface Blockchain {
|
interface Blockchain {
|
||||||
@@ -179,7 +204,7 @@ dictionary ScriptAmount {
|
|||||||
|
|
||||||
interface Wallet {
|
interface Wallet {
|
||||||
[Throws=BdkError]
|
[Throws=BdkError]
|
||||||
constructor(string descriptor, string? change_descriptor, Network network, DatabaseConfig database_config);
|
constructor(Descriptor descriptor, Descriptor? change_descriptor, Network network, DatabaseConfig database_config);
|
||||||
|
|
||||||
[Throws=BdkError]
|
[Throws=BdkError]
|
||||||
AddressInfo get_address(AddressIndex address_index);
|
AddressInfo get_address(AddressIndex address_index);
|
||||||
@@ -257,7 +282,7 @@ interface TxBuilder {
|
|||||||
|
|
||||||
TxBuilder drain_wallet();
|
TxBuilder drain_wallet();
|
||||||
|
|
||||||
TxBuilder drain_to(string address);
|
TxBuilder drain_to(Script script);
|
||||||
|
|
||||||
TxBuilder enable_rbf();
|
TxBuilder enable_rbf();
|
||||||
|
|
||||||
@@ -333,6 +358,33 @@ interface DescriptorPublicKey {
|
|||||||
string as_string();
|
string as_string();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface Descriptor {
|
||||||
|
[Throws=BdkError]
|
||||||
|
constructor(string descriptor, Network network);
|
||||||
|
|
||||||
|
[Name=new_bip44]
|
||||||
|
constructor(DescriptorSecretKey secret_key, KeychainKind keychain, Network network);
|
||||||
|
|
||||||
|
[Name=new_bip44_public]
|
||||||
|
constructor(DescriptorPublicKey public_key, string fingerprint, KeychainKind keychain, Network network);
|
||||||
|
|
||||||
|
[Name=new_bip49]
|
||||||
|
constructor(DescriptorSecretKey secret_key, KeychainKind keychain, Network network);
|
||||||
|
|
||||||
|
[Name=new_bip49_public]
|
||||||
|
constructor(DescriptorPublicKey public_key, string fingerprint, KeychainKind keychain, Network network);
|
||||||
|
|
||||||
|
[Name=new_bip84]
|
||||||
|
constructor(DescriptorSecretKey secret_key, KeychainKind keychain, Network network);
|
||||||
|
|
||||||
|
[Name=new_bip84_public]
|
||||||
|
constructor(DescriptorPublicKey public_key, string fingerprint, KeychainKind keychain, Network network);
|
||||||
|
|
||||||
|
string as_string();
|
||||||
|
|
||||||
|
string as_string_private();
|
||||||
|
};
|
||||||
|
|
||||||
interface Address {
|
interface Address {
|
||||||
[Throws=BdkError]
|
[Throws=BdkError]
|
||||||
constructor(string address);
|
constructor(string address);
|
||||||
|
|||||||
@@ -1,28 +1,34 @@
|
|||||||
use bdk::bitcoin::blockdata::script::Script as BdkScript;
|
use bdk::bitcoin::blockdata::script::Script as BdkScript;
|
||||||
use bdk::bitcoin::hashes::hex::ToHex;
|
use bdk::bitcoin::hashes::hex::ToHex;
|
||||||
use bdk::bitcoin::secp256k1::Secp256k1;
|
use bdk::bitcoin::secp256k1::Secp256k1;
|
||||||
use bdk::bitcoin::util::bip32::DerivationPath as BdkDerivationPath;
|
use bdk::bitcoin::util::bip32::{DerivationPath as BdkDerivationPath, Fingerprint};
|
||||||
use bdk::bitcoin::util::psbt::serialize::Serialize;
|
use bdk::bitcoin::util::psbt::serialize::Serialize;
|
||||||
use bdk::bitcoin::util::psbt::PartiallySignedTransaction as BdkPartiallySignedTransaction;
|
use bdk::bitcoin::util::psbt::PartiallySignedTransaction as BdkPartiallySignedTransaction;
|
||||||
use bdk::bitcoin::Sequence;
|
use bdk::bitcoin::Sequence;
|
||||||
use bdk::bitcoin::{Address as BdkAddress, Network, OutPoint as BdkOutPoint, Txid};
|
use bdk::bitcoin::{Address as BdkAddress, Network, OutPoint as BdkOutPoint, Txid};
|
||||||
use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig};
|
use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig};
|
||||||
|
use bdk::blockchain::rpc::Auth as BdkAuth;
|
||||||
use bdk::blockchain::GetBlockHash;
|
use bdk::blockchain::GetBlockHash;
|
||||||
use bdk::blockchain::GetHeight;
|
use bdk::blockchain::GetHeight;
|
||||||
use bdk::blockchain::{
|
use bdk::blockchain::{
|
||||||
electrum::ElectrumBlockchainConfig, esplora::EsploraBlockchainConfig, ConfigurableBlockchain,
|
electrum::ElectrumBlockchainConfig, esplora::EsploraBlockchainConfig,
|
||||||
|
rpc::RpcConfig as BdkRpcConfig, rpc::RpcSyncParams as BdkRpcSyncParams, ConfigurableBlockchain,
|
||||||
};
|
};
|
||||||
use bdk::blockchain::{Blockchain as BdkBlockchain, Progress as BdkProgress};
|
use bdk::blockchain::{Blockchain as BdkBlockchain, Progress as BdkProgress};
|
||||||
use bdk::database::any::{AnyDatabase, SledDbConfiguration, SqliteDbConfiguration};
|
use bdk::database::any::{AnyDatabase, SledDbConfiguration, SqliteDbConfiguration};
|
||||||
use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase};
|
use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase};
|
||||||
use bdk::descriptor::DescriptorXKey;
|
use bdk::descriptor::{DescriptorXKey, ExtendedDescriptor, IntoWalletDescriptor};
|
||||||
use bdk::keys::bip39::{Language, Mnemonic as BdkMnemonic, WordCount};
|
use bdk::keys::bip39::{Language, Mnemonic as BdkMnemonic, WordCount};
|
||||||
use bdk::keys::{
|
use bdk::keys::{
|
||||||
DerivableKey, DescriptorPublicKey as BdkDescriptorPublicKey,
|
DerivableKey, DescriptorPublicKey as BdkDescriptorPublicKey,
|
||||||
DescriptorSecretKey as BdkDescriptorSecretKey, ExtendedKey, GeneratableKey, GeneratedKey,
|
DescriptorSecretKey as BdkDescriptorSecretKey, ExtendedKey, GeneratableKey, GeneratedKey,
|
||||||
|
KeyMap,
|
||||||
};
|
};
|
||||||
use bdk::miniscript::BareCtx;
|
use bdk::miniscript::BareCtx;
|
||||||
use bdk::psbt::PsbtUtils;
|
use bdk::psbt::PsbtUtils;
|
||||||
|
use bdk::template::{
|
||||||
|
Bip44, Bip44Public, Bip49, Bip49Public, Bip84, Bip84Public, DescriptorTemplate,
|
||||||
|
};
|
||||||
use bdk::wallet::tx_builder::ChangeSpendPolicy;
|
use bdk::wallet::tx_builder::ChangeSpendPolicy;
|
||||||
use bdk::wallet::AddressIndex as BdkAddressIndex;
|
use bdk::wallet::AddressIndex as BdkAddressIndex;
|
||||||
use bdk::wallet::AddressInfo as BdkAddressInfo;
|
use bdk::wallet::AddressInfo as BdkAddressInfo;
|
||||||
@@ -34,6 +40,7 @@ use std::collections::HashSet;
|
|||||||
use std::convert::{From, TryFrom};
|
use std::convert::{From, TryFrom};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Mutex, MutexGuard};
|
use std::sync::{Arc, Mutex, MutexGuard};
|
||||||
|
|
||||||
@@ -111,6 +118,8 @@ pub struct ElectrumConfig {
|
|||||||
pub timeout: Option<u8>,
|
pub timeout: Option<u8>,
|
||||||
/// Stop searching addresses for transactions after finding an unused gap of this length
|
/// Stop searching addresses for transactions after finding an unused gap of this length
|
||||||
pub stop_gap: u64,
|
pub stop_gap: u64,
|
||||||
|
/// Validate the domain when using SSL
|
||||||
|
pub validate_domain: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configuration for an EsploraBlockchain
|
/// Configuration for an EsploraBlockchain
|
||||||
@@ -134,12 +143,84 @@ pub struct EsploraConfig {
|
|||||||
pub timeout: Option<u64>,
|
pub timeout: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum Auth {
|
||||||
|
/// No authentication
|
||||||
|
None,
|
||||||
|
/// Authentication with username and password, usually [Auth::Cookie] should be preferred
|
||||||
|
UserPass {
|
||||||
|
/// Username
|
||||||
|
username: String,
|
||||||
|
/// Password
|
||||||
|
password: String,
|
||||||
|
},
|
||||||
|
/// Authentication with a cookie file
|
||||||
|
Cookie {
|
||||||
|
/// Cookie file
|
||||||
|
file: String,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Auth> for BdkAuth {
|
||||||
|
fn from(auth: Auth) -> Self {
|
||||||
|
match auth {
|
||||||
|
Auth::None => BdkAuth::None,
|
||||||
|
Auth::UserPass { username, password } => BdkAuth::UserPass { username, password },
|
||||||
|
Auth::Cookie { file } => BdkAuth::Cookie {
|
||||||
|
file: PathBuf::from(file),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sync parameters for Bitcoin Core RPC.
|
||||||
|
///
|
||||||
|
/// In general, BDK tries to sync `scriptPubKey`s cached in `Database` with
|
||||||
|
/// `scriptPubKey`s imported in the Bitcoin Core Wallet. These parameters are used for determining
|
||||||
|
/// how the `importdescriptors` RPC calls are to be made.
|
||||||
|
pub struct RpcSyncParams {
|
||||||
|
/// The minimum number of scripts to scan for on initial sync.
|
||||||
|
pub start_script_count: u64,
|
||||||
|
/// Time in unix seconds in which initial sync will start scanning from (0 to start from genesis).
|
||||||
|
pub start_time: u64,
|
||||||
|
/// Forces every sync to use `start_time` as import timestamp.
|
||||||
|
pub force_start_time: bool,
|
||||||
|
/// RPC poll rate (in seconds) to get state updates.
|
||||||
|
pub poll_rate_sec: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<RpcSyncParams> for BdkRpcSyncParams {
|
||||||
|
fn from(params: RpcSyncParams) -> Self {
|
||||||
|
BdkRpcSyncParams {
|
||||||
|
start_script_count: params.start_script_count as usize,
|
||||||
|
start_time: params.start_time,
|
||||||
|
force_start_time: params.force_start_time,
|
||||||
|
poll_rate_sec: params.poll_rate_sec,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// RpcBlockchain configuration options
|
||||||
|
pub struct RpcConfig {
|
||||||
|
/// The bitcoin node url
|
||||||
|
pub url: String,
|
||||||
|
/// The bitcoin node authentication mechanism
|
||||||
|
pub auth: Auth,
|
||||||
|
/// The network we are using (it will be checked the bitcoin node network matches this)
|
||||||
|
pub network: Network,
|
||||||
|
/// The wallet name in the bitcoin node, consider using [crate::wallet::wallet_name_from_descriptor] for this
|
||||||
|
pub wallet_name: String,
|
||||||
|
/// Sync parameters
|
||||||
|
pub sync_params: Option<RpcSyncParams>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Type that can contain any of the blockchain configurations defined by the library.
|
/// Type that can contain any of the blockchain configurations defined by the library.
|
||||||
pub enum BlockchainConfig {
|
pub enum BlockchainConfig {
|
||||||
/// Electrum client
|
/// Electrum client
|
||||||
Electrum { config: ElectrumConfig },
|
Electrum { config: ElectrumConfig },
|
||||||
/// Esplora client
|
/// Esplora client
|
||||||
Esplora { config: EsploraConfig },
|
Esplora { config: EsploraConfig },
|
||||||
|
/// Bitcoin Core RPC client
|
||||||
|
Rpc { config: RpcConfig },
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wallet transaction
|
/// A wallet transaction
|
||||||
@@ -189,6 +270,7 @@ impl Blockchain {
|
|||||||
timeout: config.timeout,
|
timeout: config.timeout,
|
||||||
url: config.url,
|
url: config.url,
|
||||||
stop_gap: usize::try_from(config.stop_gap).unwrap(),
|
stop_gap: usize::try_from(config.stop_gap).unwrap(),
|
||||||
|
validate_domain: config.validate_domain,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
BlockchainConfig::Esplora { config } => {
|
BlockchainConfig::Esplora { config } => {
|
||||||
@@ -200,6 +282,13 @@ impl Blockchain {
|
|||||||
timeout: config.timeout,
|
timeout: config.timeout,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
BlockchainConfig::Rpc { config } => AnyBlockchainConfig::Rpc(BdkRpcConfig {
|
||||||
|
url: config.url,
|
||||||
|
auth: config.auth.into(),
|
||||||
|
network: config.network,
|
||||||
|
wallet_name: config.wallet_name,
|
||||||
|
sync_params: config.sync_params.map(|p| p.into()),
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
let blockchain = AnyBlockchain::from_config(&any_blockchain_config)?;
|
let blockchain = AnyBlockchain::from_config(&any_blockchain_config)?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -227,10 +316,6 @@ impl Blockchain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Wallet {
|
|
||||||
wallet_mutex: Mutex<BdkWallet<AnyDatabase>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A reference to a transaction output.
|
/// A reference to a transaction output.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct OutPoint {
|
pub struct OutPoint {
|
||||||
@@ -407,6 +492,11 @@ impl PartiallySignedTransaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Wallet {
|
||||||
|
wallet_mutex: Mutex<BdkWallet<AnyDatabase>>,
|
||||||
|
}
|
||||||
|
|
||||||
/// A Bitcoin wallet.
|
/// A Bitcoin wallet.
|
||||||
/// The Wallet acts as a way of coherently interfacing with output descriptors and related transactions. Its main components are:
|
/// The Wallet acts as a way of coherently interfacing with output descriptors and related transactions. Its main components are:
|
||||||
/// 1. Output descriptors from which it can derive addresses.
|
/// 1. Output descriptors from which it can derive addresses.
|
||||||
@@ -414,8 +504,8 @@ impl PartiallySignedTransaction {
|
|||||||
/// 3. Signers that can contribute signatures to addresses instantiated from the descriptors.
|
/// 3. Signers that can contribute signatures to addresses instantiated from the descriptors.
|
||||||
impl Wallet {
|
impl Wallet {
|
||||||
fn new(
|
fn new(
|
||||||
descriptor: String,
|
descriptor: Arc<Descriptor>,
|
||||||
change_descriptor: Option<String>,
|
change_descriptor: Option<Arc<Descriptor>>,
|
||||||
network: Network,
|
network: Network,
|
||||||
database_config: DatabaseConfig,
|
database_config: DatabaseConfig,
|
||||||
) -> Result<Self, BdkError> {
|
) -> Result<Self, BdkError> {
|
||||||
@@ -425,6 +515,9 @@ impl Wallet {
|
|||||||
DatabaseConfig::Sqlite { config } => AnyDatabaseConfig::Sqlite(config),
|
DatabaseConfig::Sqlite { config } => AnyDatabaseConfig::Sqlite(config),
|
||||||
};
|
};
|
||||||
let database = AnyDatabase::from_config(&any_database_config)?;
|
let database = AnyDatabase::from_config(&any_database_config)?;
|
||||||
|
let descriptor: String = descriptor.as_string_private();
|
||||||
|
let change_descriptor: Option<String> = change_descriptor.map(|d| d.as_string_private());
|
||||||
|
|
||||||
let wallet_mutex = Mutex::new(BdkWallet::new(
|
let wallet_mutex = Mutex::new(BdkWallet::new(
|
||||||
&descriptor,
|
&descriptor,
|
||||||
change_descriptor.as_ref(),
|
change_descriptor.as_ref(),
|
||||||
@@ -501,12 +594,6 @@ impl Wallet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_script_pubkey(address: &str) -> Result<BdkScript, BdkError> {
|
|
||||||
BdkAddress::from_str(address)
|
|
||||||
.map(|x| x.script_pubkey())
|
|
||||||
.map_err(|e| BdkError::Generic(e.to_string()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A Bitcoin address.
|
/// A Bitcoin address.
|
||||||
struct Address {
|
struct Address {
|
||||||
address: BdkAddress,
|
address: BdkAddress,
|
||||||
@@ -527,7 +614,7 @@ impl Address {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A Bitcoin script.
|
/// A Bitcoin script.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct Script {
|
pub struct Script {
|
||||||
script: BdkScript,
|
script: BdkScript,
|
||||||
}
|
}
|
||||||
@@ -565,7 +652,7 @@ struct TxBuilder {
|
|||||||
fee_rate: Option<f32>,
|
fee_rate: Option<f32>,
|
||||||
fee_absolute: Option<u64>,
|
fee_absolute: Option<u64>,
|
||||||
drain_wallet: bool,
|
drain_wallet: bool,
|
||||||
drain_to: Option<String>,
|
drain_to: Option<BdkScript>,
|
||||||
rbf: Option<RbfValue>,
|
rbf: Option<RbfValue>,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
}
|
}
|
||||||
@@ -703,9 +790,9 @@ impl TxBuilder {
|
|||||||
/// either provide the utxos that the transaction should spend via add_utxos, or set drain_wallet to spend all of them.
|
/// either provide the utxos that the transaction should spend via add_utxos, or set drain_wallet to spend all of them.
|
||||||
/// When bumping the fees of a transaction made with this option, you probably want to use BumpFeeTxBuilder.allow_shrinking
|
/// When bumping the fees of a transaction made with this option, you probably want to use BumpFeeTxBuilder.allow_shrinking
|
||||||
/// to allow this output to be reduced to pay for the extra fees.
|
/// to allow this output to be reduced to pay for the extra fees.
|
||||||
fn drain_to(&self, address: String) -> Arc<Self> {
|
fn drain_to(&self, script: Arc<Script>) -> Arc<Self> {
|
||||||
Arc::new(TxBuilder {
|
Arc::new(TxBuilder {
|
||||||
drain_to: Some(address),
|
drain_to: Some(script.script.clone()),
|
||||||
..self.clone()
|
..self.clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -766,8 +853,8 @@ impl TxBuilder {
|
|||||||
if self.drain_wallet {
|
if self.drain_wallet {
|
||||||
tx_builder.drain_wallet();
|
tx_builder.drain_wallet();
|
||||||
}
|
}
|
||||||
if let Some(address) = &self.drain_to {
|
if let Some(script) = &self.drain_to {
|
||||||
tx_builder.drain_to(to_script_pubkey(address)?);
|
tx_builder.drain_to(script.clone());
|
||||||
}
|
}
|
||||||
if let Some(rbf) = &self.rbf {
|
if let Some(rbf) = &self.rbf {
|
||||||
match *rbf {
|
match *rbf {
|
||||||
@@ -1103,6 +1190,186 @@ impl DescriptorPublicKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Descriptor {
|
||||||
|
pub extended_descriptor: ExtendedDescriptor,
|
||||||
|
pub key_map: KeyMap,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Descriptor {
|
||||||
|
fn new(descriptor: String, network: Network) -> Result<Self, BdkError> {
|
||||||
|
let secp = Secp256k1::new();
|
||||||
|
let (extended_descriptor, key_map) = descriptor.into_wallet_descriptor(&secp, network)?;
|
||||||
|
Ok(Self {
|
||||||
|
extended_descriptor,
|
||||||
|
key_map,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_bip44(
|
||||||
|
secret_key: Arc<DescriptorSecretKey>,
|
||||||
|
keychain_kind: KeychainKind,
|
||||||
|
network: Network,
|
||||||
|
) -> Self {
|
||||||
|
let derivable_key = secret_key.descriptor_secret_key_mutex.lock().unwrap();
|
||||||
|
|
||||||
|
match derivable_key.deref() {
|
||||||
|
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
|
||||||
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
|
let (extended_descriptor, key_map, _) =
|
||||||
|
Bip44(derivable_key, keychain_kind).build(network).unwrap();
|
||||||
|
Self {
|
||||||
|
extended_descriptor,
|
||||||
|
key_map,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BdkDescriptorSecretKey::Single(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_bip44_public(
|
||||||
|
public_key: Arc<DescriptorPublicKey>,
|
||||||
|
fingerprint: String,
|
||||||
|
keychain_kind: KeychainKind,
|
||||||
|
network: Network,
|
||||||
|
) -> Self {
|
||||||
|
let fingerprint = Fingerprint::from_str(fingerprint.as_str()).unwrap();
|
||||||
|
let derivable_key = public_key.descriptor_public_key_mutex.lock().unwrap();
|
||||||
|
|
||||||
|
match derivable_key.deref() {
|
||||||
|
BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
|
||||||
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
|
let (extended_descriptor, key_map, _) =
|
||||||
|
Bip44Public(derivable_key, fingerprint, keychain_kind)
|
||||||
|
.build(network)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
extended_descriptor,
|
||||||
|
key_map,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BdkDescriptorPublicKey::Single(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_bip49(
|
||||||
|
secret_key: Arc<DescriptorSecretKey>,
|
||||||
|
keychain_kind: KeychainKind,
|
||||||
|
network: Network,
|
||||||
|
) -> Self {
|
||||||
|
let derivable_key = secret_key.descriptor_secret_key_mutex.lock().unwrap();
|
||||||
|
|
||||||
|
match derivable_key.deref() {
|
||||||
|
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
|
||||||
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
|
let (extended_descriptor, key_map, _) =
|
||||||
|
Bip49(derivable_key, keychain_kind).build(network).unwrap();
|
||||||
|
Self {
|
||||||
|
extended_descriptor,
|
||||||
|
key_map,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BdkDescriptorSecretKey::Single(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_bip49_public(
|
||||||
|
public_key: Arc<DescriptorPublicKey>,
|
||||||
|
fingerprint: String,
|
||||||
|
keychain_kind: KeychainKind,
|
||||||
|
network: Network,
|
||||||
|
) -> Self {
|
||||||
|
let fingerprint = Fingerprint::from_str(fingerprint.as_str()).unwrap();
|
||||||
|
let derivable_key = public_key.descriptor_public_key_mutex.lock().unwrap();
|
||||||
|
|
||||||
|
match derivable_key.deref() {
|
||||||
|
BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
|
||||||
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
|
let (extended_descriptor, key_map, _) =
|
||||||
|
Bip49Public(derivable_key, fingerprint, keychain_kind)
|
||||||
|
.build(network)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
extended_descriptor,
|
||||||
|
key_map,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BdkDescriptorPublicKey::Single(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_bip84(
|
||||||
|
secret_key: Arc<DescriptorSecretKey>,
|
||||||
|
keychain_kind: KeychainKind,
|
||||||
|
network: Network,
|
||||||
|
) -> Self {
|
||||||
|
let derivable_key = secret_key.descriptor_secret_key_mutex.lock().unwrap();
|
||||||
|
|
||||||
|
match derivable_key.deref() {
|
||||||
|
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
|
||||||
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
|
let (extended_descriptor, key_map, _) =
|
||||||
|
Bip84(derivable_key, keychain_kind).build(network).unwrap();
|
||||||
|
Self {
|
||||||
|
extended_descriptor,
|
||||||
|
key_map,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BdkDescriptorSecretKey::Single(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_bip84_public(
|
||||||
|
public_key: Arc<DescriptorPublicKey>,
|
||||||
|
fingerprint: String,
|
||||||
|
keychain_kind: KeychainKind,
|
||||||
|
network: Network,
|
||||||
|
) -> Self {
|
||||||
|
let fingerprint = Fingerprint::from_str(fingerprint.as_str()).unwrap();
|
||||||
|
let derivable_key = public_key.descriptor_public_key_mutex.lock().unwrap();
|
||||||
|
|
||||||
|
match derivable_key.deref() {
|
||||||
|
BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
|
||||||
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
|
let (extended_descriptor, key_map, _) =
|
||||||
|
Bip84Public(derivable_key, fingerprint, keychain_kind)
|
||||||
|
.build(network)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
extended_descriptor,
|
||||||
|
key_map,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BdkDescriptorPublicKey::Single(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_string_private(&self) -> String {
|
||||||
|
let descriptor = &self.extended_descriptor;
|
||||||
|
let key_map = &self.key_map;
|
||||||
|
descriptor.to_string_with_secret(key_map)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_string(&self) -> String {
|
||||||
|
self.extended_descriptor.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uniffi::deps::static_assertions::assert_impl_all!(Wallet: Sync, Send);
|
uniffi::deps::static_assertions::assert_impl_all!(Wallet: Sync, Send);
|
||||||
|
|
||||||
// The goal of these tests to to ensure `bdk-ffi` intermediate code correctly calls `bdk` APIs.
|
// The goal of these tests to to ensure `bdk-ffi` intermediate code correctly calls `bdk` APIs.
|
||||||
@@ -1111,8 +1378,10 @@ uniffi::deps::static_assertions::assert_impl_all!(Wallet: Sync, Send);
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use assert_matches::assert_matches;
|
||||||
use bdk::bitcoin::Address;
|
use bdk::bitcoin::Address;
|
||||||
use bdk::bitcoin::Network::Testnet;
|
use bdk::descriptor::DescriptorError::Key;
|
||||||
|
use bdk::keys::KeyError::InvalidNetwork;
|
||||||
use bdk::wallet::get_funded_wallet;
|
use bdk::wallet::get_funded_wallet;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
@@ -1125,11 +1394,14 @@ mod test {
|
|||||||
wallet_mutex: Mutex::new(funded_wallet),
|
wallet_mutex: Mutex::new(funded_wallet),
|
||||||
};
|
};
|
||||||
let drain_to_address = "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt".to_string();
|
let drain_to_address = "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt".to_string();
|
||||||
|
let drain_to_script = crate::Address::new(drain_to_address)
|
||||||
|
.unwrap()
|
||||||
|
.script_pubkey();
|
||||||
let tx_builder = TxBuilder::new()
|
let tx_builder = TxBuilder::new()
|
||||||
.drain_wallet()
|
.drain_wallet()
|
||||||
.drain_to(drain_to_address.clone());
|
.drain_to(drain_to_script.clone());
|
||||||
assert!(tx_builder.drain_wallet);
|
assert!(tx_builder.drain_wallet);
|
||||||
assert_eq!(tx_builder.drain_to, Some(drain_to_address));
|
assert_eq!(tx_builder.drain_to, Some(drain_to_script.script.clone()));
|
||||||
|
|
||||||
let tx_builder_result = tx_builder.finish(&test_wallet).unwrap();
|
let tx_builder_result = tx_builder.finish(&test_wallet).unwrap();
|
||||||
let psbt = tx_builder_result.psbt.internal.lock().unwrap().clone();
|
let psbt = tx_builder_result.psbt.internal.lock().unwrap().clone();
|
||||||
@@ -1160,7 +1432,7 @@ mod test {
|
|||||||
.cloned()
|
.cloned()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.script_pubkey,
|
.script_pubkey,
|
||||||
Testnet,
|
Network::Testnet,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -1183,7 +1455,7 @@ mod test {
|
|||||||
|
|
||||||
fn get_descriptor_secret_key() -> DescriptorSecretKey {
|
fn get_descriptor_secret_key() -> DescriptorSecretKey {
|
||||||
let 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 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();
|
||||||
DescriptorSecretKey::new(Testnet, Arc::new(mnemonic), None)
|
DescriptorSecretKey::new(Network::Testnet, Arc::new(mnemonic), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_dsk(
|
fn derive_dsk(
|
||||||
@@ -1317,13 +1589,17 @@ mod test {
|
|||||||
wallet_mutex: Mutex::new(funded_wallet),
|
wallet_mutex: Mutex::new(funded_wallet),
|
||||||
};
|
};
|
||||||
let drain_to_address = "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt".to_string();
|
let drain_to_address = "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt".to_string();
|
||||||
|
let drain_to_script = crate::Address::new(drain_to_address)
|
||||||
|
.unwrap()
|
||||||
|
.script_pubkey();
|
||||||
|
|
||||||
let tx_builder = TxBuilder::new()
|
let tx_builder = TxBuilder::new()
|
||||||
.fee_rate(2.0)
|
.fee_rate(2.0)
|
||||||
.drain_wallet()
|
.drain_wallet()
|
||||||
.drain_to(drain_to_address.clone());
|
.drain_to(drain_to_script.clone());
|
||||||
//dbg!(&tx_builder);
|
//dbg!(&tx_builder);
|
||||||
assert!(tx_builder.drain_wallet);
|
assert!(tx_builder.drain_wallet);
|
||||||
assert_eq!(tx_builder.drain_to, Some(drain_to_address));
|
assert_eq!(tx_builder.drain_to, Some(drain_to_script.script.clone()));
|
||||||
|
|
||||||
let tx_builder_result = tx_builder.finish(&test_wallet).unwrap();
|
let tx_builder_result = tx_builder.finish(&test_wallet).unwrap();
|
||||||
|
|
||||||
@@ -1336,4 +1612,141 @@ mod test {
|
|||||||
assert!(tx_builder_result.psbt.fee_amount().is_some());
|
assert!(tx_builder_result.psbt.fee_amount().is_some());
|
||||||
assert_eq!(tx_builder_result.psbt.fee_amount().unwrap(), 220);
|
assert_eq!(tx_builder_result.psbt.fee_amount().unwrap(), 220);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_descriptor_templates() {
|
||||||
|
let master: Arc<DescriptorSecretKey> = Arc::new(get_descriptor_secret_key());
|
||||||
|
println!("Master: {:?}", master.as_string());
|
||||||
|
// tprv8ZgxMBicQKsPdWuqM1t1CDRvQtQuBPyfL6GbhQwtxDKgUAVPbxmj71pRA8raTqLrec5LyTs5TqCxdABcZr77bt2KyWA5bizJHnC4g4ysm4h
|
||||||
|
|
||||||
|
let handmade_public_44 = master
|
||||||
|
.derive(Arc::new(
|
||||||
|
DerivationPath::new("m/44h/1h/0h".to_string()).unwrap(),
|
||||||
|
))
|
||||||
|
.unwrap()
|
||||||
|
.as_public();
|
||||||
|
println!("Public 44: {}", handmade_public_44.as_string());
|
||||||
|
// Public 44: [d1d04177/44'/1'/0']tpubDCoPjomfTqh1e7o1WgGpQtARWtkueXQAepTeNpWiitS3Sdv8RKJ1yvTrGHcwjDXp2SKyMrTEca4LoN7gEUiGCWboyWe2rz99Kf4jK4m2Zmx/*
|
||||||
|
|
||||||
|
let handmade_public_49 = master
|
||||||
|
.derive(Arc::new(
|
||||||
|
DerivationPath::new("m/49h/1h/0h".to_string()).unwrap(),
|
||||||
|
))
|
||||||
|
.unwrap()
|
||||||
|
.as_public();
|
||||||
|
println!("Public 49: {}", handmade_public_49.as_string());
|
||||||
|
// Public 49: [d1d04177/49'/1'/0']tpubDC65ZRvk1NDddHrVAUAZrUPJ772QXzooNYmPywYF9tMyNLYKf5wpKE7ZJvK9kvfG3FV7rCsHBNXy1LVKW95jrmC7c7z4hq7a27aD2sRrAhR/*
|
||||||
|
|
||||||
|
let handmade_public_84 = master
|
||||||
|
.derive(Arc::new(
|
||||||
|
DerivationPath::new("m/84h/1h/0h".to_string()).unwrap(),
|
||||||
|
))
|
||||||
|
.unwrap()
|
||||||
|
.as_public();
|
||||||
|
println!("Public 84: {}", handmade_public_84.as_string());
|
||||||
|
// Public 84: [d1d04177/84'/1'/0']tpubDDNxbq17egjFk2edjv8oLnzxk52zny9aAYNv9CMqTzA4mQDiQq818sEkNe9Gzmd4QU8558zftqbfoVBDQorG3E4Wq26tB2JeE4KUoahLkx6/*
|
||||||
|
|
||||||
|
let template_private_44 =
|
||||||
|
Descriptor::new_bip44(master.clone(), KeychainKind::External, Network::Testnet);
|
||||||
|
let template_private_49 =
|
||||||
|
Descriptor::new_bip49(master.clone(), KeychainKind::External, Network::Testnet);
|
||||||
|
let template_private_84 =
|
||||||
|
Descriptor::new_bip84(master, KeychainKind::External, Network::Testnet);
|
||||||
|
|
||||||
|
// the extended public keys are the same when creating them manually as they are with the templates
|
||||||
|
println!("Template 49: {}", template_private_49.as_string());
|
||||||
|
println!("Template 44: {}", template_private_44.as_string());
|
||||||
|
println!("Template 84: {}", template_private_84.as_string());
|
||||||
|
|
||||||
|
// for the public versions of the templates these are incorrect, bug report and fix in bitcoindevkit/bdk#817 and bitcoindevkit/bdk#818
|
||||||
|
let template_public_44 = Descriptor::new_bip44_public(
|
||||||
|
handmade_public_44,
|
||||||
|
"d1d04177".to_string(),
|
||||||
|
KeychainKind::External,
|
||||||
|
Network::Testnet,
|
||||||
|
);
|
||||||
|
let template_public_49 = Descriptor::new_bip49_public(
|
||||||
|
handmade_public_49,
|
||||||
|
"d1d04177".to_string(),
|
||||||
|
KeychainKind::External,
|
||||||
|
Network::Testnet,
|
||||||
|
);
|
||||||
|
let template_public_84 = Descriptor::new_bip84_public(
|
||||||
|
handmade_public_84,
|
||||||
|
"d1d04177".to_string(),
|
||||||
|
KeychainKind::External,
|
||||||
|
Network::Testnet,
|
||||||
|
);
|
||||||
|
|
||||||
|
println!("Template public 49: {}", template_public_49.as_string());
|
||||||
|
println!("Template public 44: {}", template_public_44.as_string());
|
||||||
|
println!("Template public 84: {}", template_public_84.as_string());
|
||||||
|
|
||||||
|
// when using a public key, both as_string and as_string_private return the same string
|
||||||
|
assert_eq!(
|
||||||
|
template_public_44.as_string_private(),
|
||||||
|
template_public_44.as_string()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
template_public_49.as_string_private(),
|
||||||
|
template_public_49.as_string()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
template_public_84.as_string_private(),
|
||||||
|
template_public_84.as_string()
|
||||||
|
);
|
||||||
|
|
||||||
|
// when using as_string on a private key, we get the same result as when using it on a public key
|
||||||
|
assert_eq!(
|
||||||
|
template_private_44.as_string(),
|
||||||
|
template_public_44.as_string()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
template_private_49.as_string(),
|
||||||
|
template_public_49.as_string()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
template_private_84.as_string(),
|
||||||
|
template_public_84.as_string()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_descriptor_from_string() {
|
||||||
|
let descriptor1 = Descriptor::new("wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)".to_string(), Network::Testnet);
|
||||||
|
let descriptor2 = Descriptor::new("wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)".to_string(), Network::Bitcoin);
|
||||||
|
|
||||||
|
// Creating a Descriptor using an extended key that doesn't match the network provided will throw and InvalidNetwork Error
|
||||||
|
assert!(descriptor1.is_ok());
|
||||||
|
assert_matches!(
|
||||||
|
descriptor2.unwrap_err(),
|
||||||
|
bdk::Error::Descriptor(Key(InvalidNetwork))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_wallet_from_descriptor() {
|
||||||
|
let descriptor1 = Descriptor::new("wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)".to_string(), Network::Testnet).unwrap();
|
||||||
|
|
||||||
|
let wallet1 = Wallet::new(
|
||||||
|
Arc::new(Descriptor::new("wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)".to_string(), Network::Testnet).unwrap()),
|
||||||
|
None,
|
||||||
|
Network::Testnet,
|
||||||
|
DatabaseConfig::Memory
|
||||||
|
);
|
||||||
|
|
||||||
|
let wallet2 = Wallet::new(
|
||||||
|
Arc::new(descriptor1),
|
||||||
|
None,
|
||||||
|
Network::Bitcoin,
|
||||||
|
DatabaseConfig::Memory,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Creating a wallet using a Descriptor with an extended key that doesn't match the network provided in the wallet constructor will throw and InvalidNetwork Error
|
||||||
|
assert!(wallet1.is_ok());
|
||||||
|
assert_matches!(
|
||||||
|
wallet2.unwrap_err(),
|
||||||
|
bdk::Error::Descriptor(Key(InvalidNetwork))
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ val internalDescriptor = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEm
|
|||||||
val databaseConfig = DatabaseConfig.Memory
|
val databaseConfig = DatabaseConfig.Memory
|
||||||
|
|
||||||
val blockchainConfig = BlockchainConfig.Electrum(
|
val blockchainConfig = BlockchainConfig.Electrum(
|
||||||
ElectrumConfig("ssl://electrum.blockstream.info:60002", null, 5u, null, 10u)
|
ElectrumConfig("ssl://electrum.blockstream.info:60002", null, 5u, null, 10u, true)
|
||||||
)
|
)
|
||||||
val wallet = Wallet(externalDescriptor, internalDescriptor, Network.TESTNET, databaseConfig, blockchainConfig)
|
val wallet = Wallet(externalDescriptor, internalDescriptor, Network.TESTNET, databaseConfig, blockchainConfig)
|
||||||
val newAddress = wallet.getAddress(AddressIndex.LAST_UNUSED)
|
val newAddress = wallet.getAddress(AddressIndex.LAST_UNUSED)
|
||||||
@@ -82,5 +82,18 @@ and use the `publishToMavenLocal` task without excluding the signing task:
|
|||||||
./gradlew publishToMavenLocal
|
./gradlew publishToMavenLocal
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Known issues
|
||||||
|
Depending on the JVM version you use, you might not have the JNA dependency on your classpath. The exception thrown will be
|
||||||
|
```shell
|
||||||
|
class file for com.sun.jna.Pointer not found
|
||||||
|
```
|
||||||
|
The solution is to add JNA as a dependency like so:
|
||||||
|
```kotlin
|
||||||
|
dependencies {
|
||||||
|
// ...
|
||||||
|
implementation("net.java.dev.jna:jna:5.12.1")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
[`bdk`]: https://github.com/bitcoindevkit/bdk
|
[`bdk`]: https://github.com/bitcoindevkit/bdk
|
||||||
[`bdk-ffi`]: https://github.com/bitcoindevkit/bdk-ffi
|
[`bdk-ffi`]: https://github.com/bitcoindevkit/bdk-ffi
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
org.gradle.jvmargs=-Xmx1536m
|
org.gradle.jvmargs=-Xmx1536m
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
libraryVersion=0.12.0-SNAPSHOT
|
libraryVersion=0.26.0
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import org.gradle.api.tasks.testing.logging.TestExceptionFormat.*
|
import org.gradle.api.tasks.testing.logging.TestExceptionFormat.*
|
||||||
import org.gradle.api.tasks.testing.logging.TestLogEvent.*
|
import org.gradle.api.tasks.testing.logging.TestLogEvent.*
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
// library version is defined in gradle.properties
|
// library version is defined in gradle.properties
|
||||||
val libraryVersion: String by project
|
val libraryVersion: String by project
|
||||||
@@ -101,3 +102,9 @@ signing {
|
|||||||
useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword)
|
useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword)
|
||||||
sign(publishing.publications)
|
sign(publishing.publications)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This task dependency ensures that we build the bindings
|
||||||
|
// binaries before running the tests
|
||||||
|
tasks.withType<KotlinCompile> {
|
||||||
|
dependsOn("buildJvmLib")
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ class JvmLibTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val descriptor =
|
private val descriptor = Descriptor("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)", Network.TESTNET)
|
||||||
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"
|
|
||||||
|
|
||||||
private val databaseConfig = DatabaseConfig.Memory
|
private val databaseConfig = DatabaseConfig.Memory
|
||||||
|
|
||||||
@@ -39,7 +38,8 @@ class JvmLibTest {
|
|||||||
null,
|
null,
|
||||||
5u,
|
5u,
|
||||||
null,
|
null,
|
||||||
100u
|
100u,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ pip install bdkpython
|
|||||||
import bdkpython as bdk
|
import bdkpython as bdk
|
||||||
|
|
||||||
|
|
||||||
descriptor = "wpkh(tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy/84h/0h/0h/0/*)"
|
descriptor = bdk.Descriptor("wpkh(tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy/84h/0h/0h/0/*)", bdk.Network.TESTNET)
|
||||||
db_config = bdk.DatabaseConfig.MEMORY()
|
db_config = bdk.DatabaseConfig.MEMORY()
|
||||||
blockchain_config = bdk.BlockchainConfig.ELECTRUM(
|
blockchain_config = bdk.BlockchainConfig.ELECTRUM(
|
||||||
bdk.ElectrumConfig(
|
bdk.ElectrumConfig(
|
||||||
@@ -26,7 +26,8 @@ blockchain_config = bdk.BlockchainConfig.ELECTRUM(
|
|||||||
None,
|
None,
|
||||||
5,
|
5,
|
||||||
None,
|
None,
|
||||||
100
|
100,
|
||||||
|
True,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
blockchain = bdk.Blockchain(blockchain_config)
|
blockchain = bdk.Blockchain(blockchain_config)
|
||||||
@@ -59,7 +60,7 @@ rust_ext = RustExtension(
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='bdkpython',
|
name='bdkpython',
|
||||||
version='0.6.0.dev0',
|
version='0.26.2',
|
||||||
description="The Python language bindings for the Bitcoin Development Kit",
|
description="The Python language bindings for the Bitcoin Development Kit",
|
||||||
long_description=LONG_DESCRIPTION,
|
long_description=LONG_DESCRIPTION,
|
||||||
long_description_content_type='text/markdown',
|
long_description_content_type='text/markdown',
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import bdkpython as bdk
|
import bdkpython as bdk
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
descriptor = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"
|
|
||||||
|
descriptor = bdk.Descriptor("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)", bdk.Network.TESTNET)
|
||||||
db_config = bdk.DatabaseConfig.MEMORY()
|
db_config = bdk.DatabaseConfig.MEMORY()
|
||||||
blockchain_config = bdk.BlockchainConfig.ELECTRUM(
|
blockchain_config = bdk.BlockchainConfig.ELECTRUM(
|
||||||
bdk.ElectrumConfig(
|
bdk.ElectrumConfig(
|
||||||
@@ -9,7 +10,8 @@ blockchain_config = bdk.BlockchainConfig.ELECTRUM(
|
|||||||
None,
|
None,
|
||||||
5,
|
5,
|
||||||
None,
|
None,
|
||||||
100
|
100,
|
||||||
|
True,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
blockchain = bdk.Blockchain(blockchain_config)
|
blockchain = bdk.Blockchain(blockchain_config)
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ This project builds a Swift package that provides [Swift] language bindings for
|
|||||||
|
|
||||||
Supported target platforms are:
|
Supported target platforms are:
|
||||||
|
|
||||||
- MacOS, X86_64 and M1 (aarch64)
|
- macOS, X86_64 and M1 (aarch64)
|
||||||
- iOS, iPhones (aarch64)
|
- iOS, iPhones (aarch64)
|
||||||
- iOS simulator, X86_64 and M1 (aarch64)
|
- iOS simulator, X86_64 and M1 (aarch64)
|
||||||
|
|
||||||
## How to Use
|
## How to Use
|
||||||
|
|
||||||
To use the Swift language bindings for [`bdk`] in your [Xcode] iOS or MacOS project add
|
To use the Swift language bindings for [`bdk`] in your [Xcode] iOS or macOS project add
|
||||||
the github repository https://github.com/bitcoindevkit/bdk-swift and select one of the
|
the GitHub repository https://github.com/bitcoindevkit/bdk-swift and select one of the
|
||||||
release versions. You may then import and use the `BitcoinDevKit` library in your Swift
|
release versions. You may then import and use the `BitcoinDevKit` library in your Swift
|
||||||
code. For example:
|
code. For example:
|
||||||
|
|
||||||
@@ -40,11 +40,11 @@ swift test
|
|||||||
## How to Build and Publish
|
## How to Build and Publish
|
||||||
|
|
||||||
If you are a maintainer of this project or want to build and publish this project to your
|
If you are a maintainer of this project or want to build and publish this project to your
|
||||||
own Github repository use the following steps:
|
own GitHub repository use the following steps:
|
||||||
|
|
||||||
1. If it doesn't already exist, create a new `release/0.MINOR` branch from the `master` branch.
|
1. If it doesn't already exist, create a new `release/0.MINOR` branch from the `master` branch.
|
||||||
2. Add a tag `v0.MINOR.PATCH`.
|
2. Add a tag `v0.MINOR.PATCH`.
|
||||||
3. Run the `publish-spm` workflow on Github from the `bdk-swift` repo for version `0.MINOR.PATCH`.
|
3. Run the `publish-spm` workflow on GitHub from the `bdk-swift` repo for version `0.MINOR.PATCH`.
|
||||||
|
|
||||||
[Swift]: https://developer.apple.com/swift/
|
[Swift]: https://developer.apple.com/swift/
|
||||||
[Xcode]: https://developer.apple.com/documentation/Xcode
|
[Xcode]: https://developer.apple.com/documentation/Xcode
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ import XCTest
|
|||||||
|
|
||||||
final class BitcoinDevKitTests: XCTestCase {
|
final class BitcoinDevKitTests: XCTestCase {
|
||||||
func testMemoryWalletNewAddress() throws {
|
func testMemoryWalletNewAddress() throws {
|
||||||
let desc = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"
|
let desc = try Descriptor(
|
||||||
|
descriptor: "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
||||||
|
network: Network.regtest
|
||||||
|
)
|
||||||
let databaseConfig = DatabaseConfig.memory
|
let databaseConfig = DatabaseConfig.memory
|
||||||
let wallet = try Wallet.init(descriptor: desc, changeDescriptor: nil, network: Network.regtest, databaseConfig: databaseConfig)
|
let wallet = try Wallet.init(descriptor: desc, changeDescriptor: nil, network: Network.regtest, databaseConfig: databaseConfig)
|
||||||
let addressInfo = try wallet.getAddress(addressIndex: AddressIndex.new)
|
let addressInfo = try wallet.getAddress(addressIndex: AddressIndex.new)
|
||||||
|
|||||||
Reference in New Issue
Block a user