├── downloads └── .gitignore ├── src ├── version.h.in ├── swig_python │ ├── README.md │ ├── dev-mode-setup.py.in │ ├── pyproject.toml.in │ ├── setup.py.in │ └── mac-setup.py.in ├── swift │ ├── GreenGDK │ │ ├── .gitignore │ │ └── Package.swift │ └── CMakeLists.txt ├── swig_java │ └── jni_extra.java_in ├── gsl_wrapper.hpp ├── containers.hpp ├── validate.hpp ├── assertion.cpp ├── redeposit_auth_handlers.hpp ├── bcur_auth_handlers.hpp ├── threading.hpp ├── io_runner.hpp ├── io_container.cpp ├── swap_auth_handlers.hpp ├── autobahn_wrapper.hpp ├── ga_tor.hpp ├── exception.hpp ├── memory.hpp ├── exception.cpp ├── validate.cpp ├── ga_psbt.hpp └── socks_client.hpp ├── subprojects └── gdk_rust │ ├── libgcc │ └── libgcc.a │ ├── .rustfmt.toml │ ├── gdk_registry │ ├── src │ │ ├── hard_coded │ │ │ ├── elements-regtest_icons.json │ │ │ ├── liquid-testnet_icons.json │ │ │ ├── elements-regtest_assets.json │ │ │ └── liquid-testnet_assets.json │ │ ├── params │ │ │ └── mod.rs │ │ ├── data │ │ │ └── test │ │ │ │ ├── extra_icons.json │ │ │ │ ├── result.json │ │ │ │ └── extra_assets.json │ │ ├── last_modified.rs │ │ └── file.rs │ ├── Cargo.toml │ └── README.md │ ├── .gitignore │ ├── gdk_test │ ├── src │ │ ├── error.rs │ │ ├── lib.rs │ │ ├── env.rs │ │ └── utils.rs │ └── Cargo.toml │ ├── gdk_common │ ├── src │ │ ├── data │ │ │ └── test │ │ │ │ └── encrypted │ │ ├── be │ │ │ ├── mod.rs │ │ │ ├── blockhash.rs │ │ │ ├── address.rs │ │ │ ├── outpoint.rs │ │ │ └── blockheader.rs │ │ ├── state.rs │ │ ├── lib.rs │ │ ├── password.rs │ │ ├── session.rs │ │ ├── util │ │ │ └── strser.rs │ │ └── scripts.rs │ └── Cargo.toml │ ├── gdk_electrum │ ├── test_data │ │ └── store │ │ │ ├── cache │ │ │ └── store │ ├── src │ │ ├── servers-testnet.txt │ │ └── headers │ │ │ └── mod.rs │ ├── Cargo.toml │ └── scripts │ │ └── update-server-list.sh │ ├── exported-symbols │ ├── apple-exported-symbols │ ├── gdk_pin_client │ ├── src │ │ ├── lib.rs │ │ ├── pin.rs │ │ └── error.rs │ ├── Cargo.toml │ └── README.md │ ├── .cargo │ └── config.toml │ ├── .config │ └── nextest.toml │ ├── Cargo.toml │ ├── gdk_rust │ ├── Cargo.toml │ └── src │ │ └── error.rs │ ├── gdk_rust.h │ └── weaken-symbols ├── docs ├── requirements.txt └── source │ ├── examples │ ├── twofactor_change_limits_btc.json │ ├── bcur_decode_crypto_psbt.json │ ├── bcur_decode_bytes.json │ ├── bcur_decode_custom.json │ ├── twofactor_change_limits_fiat.json │ ├── twofactor_change_limits_fiat_multisig.json │ ├── bcur_decode_crypto_output.json │ ├── login_user.json │ ├── get_settings_singlesig.json │ ├── get_settings_singlesig_liquid.json │ ├── get_subaccount_multisig.json │ ├── get_subaccount_multisig_liquid.json │ ├── get_transaction_details_multisig_liquid.json │ ├── get_transaction_details_singlesig_liquid.json │ ├── get_transactions_input_multisig_liquid.json │ ├── get_transactions_input_singlesig_liquid.json │ ├── get_transactions_output_multisig.json │ ├── get_transactions_input_multisig.json │ ├── twofactor_change_limits_btc_multisig.json │ ├── get_receive_address_singlesig.json │ ├── get_settings_multisig.json │ ├── get_settings_multisig_liquid.json │ ├── get_transactions_input_singlesig.json │ ├── get_transactions_output_singlesig.json │ ├── bcur_decode_crypto_account.json │ ├── get_twofactor_config_singlesig.json │ ├── get_receive_address_multisig.json │ ├── get_receive_address_singlesig_liquid.json │ ├── get_unspent_outputs_multisig.json │ ├── get_transaction_details_multisig.json │ ├── get_transaction_details_singlesig.json │ ├── get_unspent_outputs_singlesig.json │ ├── get_subaccount_singlesig.json │ ├── get_subaccount_singlesig_liquid.json │ ├── get_receive_address_multisig_liquid.json │ ├── get_transactions_output_singlesig_liquid.json │ ├── get_previous_addresses_singlesig.json │ ├── get_transactions_output_multisig_liquid.json │ ├── get_twofactor_config_all_multisig.json │ ├── get_twofactor_config_none_multisig.json │ ├── get_unspent_outputs_multisig_liquid.json │ ├── get_previous_addresses_multisig.json │ ├── get_unspent_outputs_singlesig_liquid.json │ ├── get_available_currencies_multisig.json │ ├── get_available_currencies_singlesig.json │ ├── get_previous_addresses_singlesig_liquid.json │ ├── network.json │ ├── get_previous_addresses_multisig_liquid.json │ ├── get_transactions_multisig.json │ └── get_transactions_singlesig.json │ └── index.rst ├── tools ├── lint.sh ├── run_pvs_studio_analyzer.sh ├── buildtinycbor.sh ├── zlib-1.3.patch ├── buildbcur.sh ├── clang-tidy.sh ├── requirements.txt ├── macos_env.sh ├── format.sh ├── archiver.sh.gen ├── buildlibwally-core.sh ├── libevent-2.1.12.patch ├── make_txt.sh ├── buildtor.sh ├── buildsqlite3.sh ├── bc-ur.patch └── buildopenssl.sh ├── include ├── module.modulemap └── wally_wrapper.h ├── cmake ├── profiles │ ├── android-x86.cmake │ ├── android-x86_64.cmake │ ├── android-arm64-v8a.cmake │ ├── android-armeabi-v7a.cmake │ ├── macOS.cmake │ ├── gcc.cmake │ ├── clang.cmake │ ├── common.cmake │ ├── windows-mingw-w64.cmake │ ├── iphoneos.cmake │ ├── iphonesimulator.cmake │ └── android-helpers.cmake ├── modules │ ├── Findautobahn.cmake │ ├── Findbcur.cmake │ ├── Findsqlite3.cmake │ └── Findtor.cmake └── exports │ └── gdk-config.cmake.in ├── docker ├── debian │ ├── install_rust_tools.sh │ └── install_deps.sh ├── fedora │ ├── install_deps.sh │ └── Dockerfile ├── aws_lambda │ ├── install_deps.sh │ └── Dockerfile ├── ubuntu │ ├── install_deps.sh │ └── Dockerfile ├── ubuntu-arm64 │ ├── install_deps.sh │ └── Dockerfile ├── android │ ├── install_deps.sh │ └── Dockerfile ├── android-bookworm │ ├── install_deps.sh │ └── Dockerfile └── python │ ├── install_deps.sh │ └── Dockerfile ├── .gitignore ├── .readthedocs.yaml ├── .clang-tidy ├── tests ├── test_gdk_commit.cpp ├── CMakeLists.txt └── test_aes_gcm.cpp ├── .dockerignore ├── LICENSE └── gitlab ├── android.yml ├── python.yml ├── ios.yml └── common.yml /downloads/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /src/version.h.in: -------------------------------------------------------------------------------- 1 | #define GDK_COMMIT "@VCS_SHA@" 2 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/libgcc/libgcc.a: -------------------------------------------------------------------------------- 1 | INPUT(-lunwind) 2 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/.rustfmt.toml: -------------------------------------------------------------------------------- 1 | use_small_heuristics = "Off" 2 | -------------------------------------------------------------------------------- /src/swig_python/README.md: -------------------------------------------------------------------------------- 1 | Python bindings for the gdk Bitcoin library 2 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_registry/src/hard_coded/elements-regtest_icons.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_registry/src/hard_coded/liquid-testnet_icons.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /src/swift/GreenGDK/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | */test 3 | !data/test 4 | /bld 5 | /tests/c-test 6 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx 2 | sphinx-rtd-theme 3 | readthedocs-sphinx-ext 4 | docutils 5 | mkdocs 6 | jinja2 7 | snowballstemmer==2.2.0 8 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_test/src/error.rs: -------------------------------------------------------------------------------- 1 | pub type Result = std::result::Result; 2 | 3 | pub type Error = Box; 4 | -------------------------------------------------------------------------------- /src/swig_java/jni_extra.java_in: -------------------------------------------------------------------------------- 1 | 2 | public final static byte[] get_random_bytes(long jarg1) { 3 | return get_random_bytes(jarg1, 0, 0); 4 | } 5 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_registry/src/params/mod.rs: -------------------------------------------------------------------------------- 1 | mod get_assets; 2 | mod refresh_assets; 3 | 4 | pub use get_assets::*; 5 | pub use refresh_assets::*; 6 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_common/src/data/test/encrypted: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blockstream/gdk/HEAD/subprojects/gdk_rust/gdk_common/src/data/test/encrypted -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_electrum/test_data/store/cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blockstream/gdk/HEAD/subprojects/gdk_rust/gdk_electrum/test_data/store/cache -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_electrum/test_data/store/store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blockstream/gdk/HEAD/subprojects/gdk_rust/gdk_electrum/test_data/store/store -------------------------------------------------------------------------------- /tools/lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | if [ $(command -v cargo) ]; then 5 | pushd subprojects/gdk_rust 6 | cargo clippy --all 7 | popd 8 | fi 9 | -------------------------------------------------------------------------------- /tools/run_pvs_studio_analyzer.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | pvs-studio-analyzer analyze -o $1/gdk.log -j 4 5 | plog-converter -a GA:1,2 -t tasklist -o $1/gdk.tasks $1/gdk.log 6 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/exported-symbols: -------------------------------------------------------------------------------- 1 | GDKRUST_create_session 2 | GDKRUST_call_session 3 | GDKRUST_destroy_string 4 | GDKRUST_destroy_session 5 | GDKRUST_set_notification_handler 6 | GDKRUST_call 7 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/apple-exported-symbols: -------------------------------------------------------------------------------- 1 | _GDKRUST_create_session 2 | _GDKRUST_call_session 3 | _GDKRUST_destroy_string 4 | _GDKRUST_destroy_session 5 | _GDKRUST_set_notification_handler 6 | _GDKRUST_call 7 | _rust_eh_personality 8 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_test/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod env; 2 | mod error; 3 | mod rpc_node_ext; 4 | mod test_session; 5 | pub mod utils; 6 | 7 | pub use error::{Error, Result}; 8 | pub use rpc_node_ext::RpcNodeExt; 9 | pub use test_session::TestSession; 10 | -------------------------------------------------------------------------------- /include/module.modulemap: -------------------------------------------------------------------------------- 1 | module green [extern_c] { 2 | module gdk { 3 | header "gdk.h" 4 | export * 5 | } 6 | module wally { 7 | header "wally_wrapper.h" 8 | export * 9 | } 10 | 11 | link "green_gdk" 12 | } 13 | -------------------------------------------------------------------------------- /docs/source/examples/twofactor_change_limits_btc.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Set BTC limit example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "is_fiat": false, 10 | "satoshi": 50000 11 | } 12 | 13 | .. raw:: html 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /cmake/profiles/android-x86.cmake: -------------------------------------------------------------------------------- 1 | include (${CMAKE_CURRENT_LIST_DIR}/common.cmake) 2 | include(${CMAKE_CURRENT_LIST_DIR}/android-helpers.cmake) 3 | 4 | 5 | ######## 6 | set(ANDROID_ABI "x86") 7 | set(ANDROID_PLATFORM "android-23") 8 | initialize_android_environment() 9 | set(_rustTriple "i686-linux-android") 10 | -------------------------------------------------------------------------------- /cmake/profiles/android-x86_64.cmake: -------------------------------------------------------------------------------- 1 | include (${CMAKE_CURRENT_LIST_DIR}/common.cmake) 2 | include(${CMAKE_CURRENT_LIST_DIR}/android-helpers.cmake) 3 | 4 | 5 | ######## 6 | set(ANDROID_ABI "x86_64") 7 | set(ANDROID_PLATFORM "android-23") 8 | initialize_android_environment() 9 | set(_rustTriple "x86_64-linux-android") 10 | -------------------------------------------------------------------------------- /docs/source/examples/bcur_decode_crypto_psbt.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "psbt": "cHNidP8BAJoCAAAAAljoeiG1ba8MI74=", 10 | "ur_type": "crypto-psbt" 11 | } 12 | 13 | .. raw:: html 14 | 15 |
16 | 17 | -------------------------------------------------------------------------------- /src/swift/GreenGDK/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "GreenGDK", 6 | products: [ 7 | .library(name: "GreenGDK", targets: ["GreenGDK"]) 8 | ], 9 | targets: [ 10 | .target(name: "GreenGDK") 11 | ] 12 | ) 13 | -------------------------------------------------------------------------------- /docs/source/examples/bcur_decode_bytes.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "data": "581770736274ff01009a020000000258e87a21b56daf0c23be", 10 | "ur_type": "bytes" 11 | } 12 | 13 | .. raw:: html 14 | 15 |
16 | 17 | -------------------------------------------------------------------------------- /cmake/profiles/android-arm64-v8a.cmake: -------------------------------------------------------------------------------- 1 | include (${CMAKE_CURRENT_LIST_DIR}/common.cmake) 2 | include(${CMAKE_CURRENT_LIST_DIR}/android-helpers.cmake) 3 | 4 | 5 | ######## 6 | set(ANDROID_ABI "arm64-v8a") 7 | set(ANDROID_PLATFORM "android-23") 8 | initialize_android_environment() 9 | set(_rustTriple "aarch64-linux-android") 10 | -------------------------------------------------------------------------------- /docs/source/examples/bcur_decode_custom.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "data": "581770736274ff01009a020000000258e87a21b56daf0c23be", 10 | "ur_type": "custom" 11 | } 12 | 13 | .. raw:: html 14 | 15 |
16 | 17 | -------------------------------------------------------------------------------- /tools/buildtinycbor.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | cd "${PRJ_SUBDIR}" 5 | 6 | make \ 7 | prefix=${GDK_BUILD_ROOT} \ 8 | BUILD_SHARED=0 BUILD_STATIC=1 \ 9 | CC=${CC} CXX=${CXX} \ 10 | CFLAGS="${CFLAGS} -DWITHOUT_OPEN_MEMSTREAM" LDFLAGS="${LDFLAGS}" \ 11 | lib/libtinycbor.a \ 12 | install 13 | -------------------------------------------------------------------------------- /cmake/profiles/android-armeabi-v7a.cmake: -------------------------------------------------------------------------------- 1 | include (${CMAKE_CURRENT_LIST_DIR}/common.cmake) 2 | include(${CMAKE_CURRENT_LIST_DIR}/android-helpers.cmake) 3 | 4 | 5 | ######## 6 | set(ANDROID_ABI "armeabi-v7a") 7 | set(ANDROID_PLATFORM "android-23") 8 | initialize_android_environment() 9 | set(_rustTriple "armv7-linux-androideabi") 10 | -------------------------------------------------------------------------------- /cmake/profiles/macOS.cmake: -------------------------------------------------------------------------------- 1 | include (${CMAKE_CURRENT_LIST_DIR}/common.cmake) 2 | include(${CMAKE_CURRENT_LIST_DIR}/ios-helpers.cmake) 3 | 4 | 5 | ######## 6 | init_apple_environment() 7 | 8 | set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15 CACHE INTERNAL "") 9 | 10 | set(CMAKE_LIBRARY_ARCHITECTURE "${CMAKE_HOST_SYSTEM_PROCESSOR}-apple-darwin") 11 | -------------------------------------------------------------------------------- /docs/source/examples/twofactor_change_limits_fiat.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Set fiat limit example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "fiat": "1.50", 10 | "fiat_currency": "USD", 11 | "is_fiat": true 12 | } 13 | 14 | .. raw:: html 15 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_pin_client/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod crypto; 2 | mod error; 3 | mod pin; 4 | mod pin_client; 5 | mod pin_data; 6 | mod pin_request; 7 | 8 | pub use error::Error; 9 | pub use pin::Pin; 10 | pub use pin_client::PinClient; 11 | pub use pin_data::PinData; 12 | 13 | pub(crate) type Result = std::result::Result; 14 | -------------------------------------------------------------------------------- /docs/source/examples/twofactor_change_limits_fiat_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example (returned fiat limit) 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "fiat": "1.50", 10 | "fiat_currency": "USD", 11 | "is_fiat": true 12 | } 13 | 14 | .. raw:: html 15 | 16 |
17 | 18 | -------------------------------------------------------------------------------- /docs/source/examples/bcur_decode_crypto_output.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "descriptor": "pkh(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)", 10 | "ur_type": "crypto-output" 11 | } 12 | 13 | .. raw:: html 14 | 15 |
16 | 17 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_registry/src/data/test/extra_icons.json: -------------------------------------------------------------------------------- 1 | { 2 | "223465c803ae336c62180e52d94ee80d80828db54df9bedbb9860060f49de2eb": "a", 3 | "de091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2": "b", 4 | "6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d": "c", 5 | "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2": "d" 6 | } 7 | -------------------------------------------------------------------------------- /tools/zlib-1.3.patch: -------------------------------------------------------------------------------- 1 | diff --color -ru a/zlib-1.3/gzlib.c b/zlib-1.3/gzlib.c 2 | --- a/zlib-1.3/gzlib.c 2023-08-18 10:45:36.000000000 +0200 3 | +++ b/zlib-1.3/gzlib.c 2024-01-12 09:15:47.420050757 +0100 4 | @@ -579,4 +579,9 @@ 5 | } while (p > q); 6 | return q >> 1; 7 | } 8 | +#else 9 | +unsigned ZLIB_INTERNAL gz_intmax() 10 | +{ 11 | + return INT_MAX; 12 | +} 13 | #endif 14 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_electrum/src/servers-testnet.txt: -------------------------------------------------------------------------------- 1 | blackie.c3-soft.com:57006:s:noverify 2 | blockstream.info:993:s:noverify 3 | electrum.blockstream.info:60002:s:noverify 4 | explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion:143:t 5 | testnet.aranguren.org:51002:s:noverify 6 | testnet.hsmiths.com:53012:s:noverify 7 | testnet.qtornado.com:51002:s:noverify 8 | tn.not.fyi:55002:s:noverify 9 | -------------------------------------------------------------------------------- /docker/debian/install_rust_tools.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | rustup component add rustfmt clippy llvm-tools-preview 5 | rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android x86_64-pc-windows-gnu 6 | cargo install --locked --version 0.20.1 cargo-audit 7 | cargo install --locked --version 0.8.24 grcov 8 | cargo install --locked --version 0.9.55 cargo-nextest 9 | -------------------------------------------------------------------------------- /cmake/profiles/gcc.cmake: -------------------------------------------------------------------------------- 1 | include (${CMAKE_CURRENT_LIST_DIR}/common.cmake) 2 | 3 | set(CMAKE_C_COMPILER gcc) 4 | set(CMAKE_CXX_COMPILER g++) 5 | 6 | list(APPEND GDK_LINK_OPTIONS 7 | "-static-libstdc++" 8 | ) 9 | if( CMAKE_BUILD_TYPE STREQUAL "Debug") 10 | add_compile_options("-ggdb3" "-fno-omit-frame-pointer") 11 | endif() 12 | 13 | set(CMAKE_LIBRARY_ARCHITECTURE "${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu") 14 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_common/src/be/mod.rs: -------------------------------------------------------------------------------- 1 | mod address; 2 | mod blockhash; 3 | mod blockheader; 4 | mod outpoint; 5 | mod script; 6 | mod transaction; 7 | mod txid; 8 | 9 | pub use address::*; 10 | use bitcoin::bip32::DerivationPath; 11 | pub use blockhash::*; 12 | pub use blockheader::*; 13 | pub use outpoint::*; 14 | pub use script::*; 15 | use std::fmt::Debug; 16 | pub use transaction::*; 17 | pub use txid::*; 18 | -------------------------------------------------------------------------------- /docs/source/examples/login_user.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "wallet_hash_id": "3cc371810dfa275a8654d4d70986c2d92ce229d611c9ab2da0ab40ea9a0da1bb", 10 | "warnings": [], 11 | "xpub_hash_id": "cd2474f9b6bffbbbac45179c6bce45436370264a1607880f5a56e70a016ba08a" 12 | } 13 | 14 | .. raw:: html 15 | 16 |
17 | 18 | -------------------------------------------------------------------------------- /cmake/profiles/clang.cmake: -------------------------------------------------------------------------------- 1 | include (${CMAKE_CURRENT_LIST_DIR}/common.cmake) 2 | 3 | set(CMAKE_C_COMPILER clang) 4 | set(CMAKE_CXX_COMPILER clang++) 5 | 6 | list(APPEND GDK_LINK_OPTIONS 7 | "SHELL:-static-libstdc++" 8 | ) 9 | if( CMAKE_BUILD_TYPE STREQUAL "Debug") 10 | add_compile_options("-ggdb3" "-fno-omit-frame-pointer") 11 | endif() 12 | 13 | set(CMAKE_LIBRARY_ARCHITECTURE "${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu") 14 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | GDK documentation 2 | =========================== 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | :caption: Contents: 7 | 8 | gdk 9 | gdk-json 10 | gdk-create-tx 11 | gdk-ntf 12 | gdk-hw 13 | 14 | .. toctree:: 15 | :maxdepth: 1 16 | :caption: Developer Guides 17 | 18 | gdk-swap 19 | 20 | Indices and tables 21 | ================== 22 | 23 | * :ref:`genindex` 24 | * :ref:`search` 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # 4 | 5 | !.gitignore 6 | /build-gcc*/ 7 | /build-clang*/ 8 | /subprojects/gdk_rust/gdk_electrum/target 9 | /subprojects/gdk_rust/gdk_rpc/target 10 | *.orig 11 | *.rej 12 | *.swp 13 | *.class 14 | *.so 15 | *.dylib 16 | *.tar 17 | *.pyc 18 | Package.resolved 19 | .idea/ 20 | .vscode/ 21 | docs/source/gdk.rst 22 | docs/build 23 | .pytest_cache/ 24 | *.pyc 25 | *PVS-Studio* 26 | /TAGS 27 | /tor 28 | *~ 29 | gdk-python/ 30 | -------------------------------------------------------------------------------- /src/gsl_wrapper.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_GSL_WRAPPER_HPP 2 | #define GDK_GSL_WRAPPER_HPP 3 | #pragma once 4 | 5 | #if __clang__ 6 | #pragma clang diagnostic push 7 | #if __clang_major__ < 6 8 | #pragma clang diagnostic ignored "-Wunknown-attributes" 9 | #endif 10 | #endif 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #if __clang__ 17 | #pragma clang diagnostic pop 18 | #endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /docs/source/examples/get_settings_singlesig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "altimeout": 5, 10 | "pricing": { 11 | "currency": "USD", 12 | "exchange": "BITFINEX" 13 | }, 14 | "required_num_blocks": 12, 15 | "sound": true, 16 | "unit": "BTC" 17 | } 18 | 19 | .. raw:: html 20 | 21 |
22 | 23 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yaml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | version: 2 6 | 7 | build: 8 | os: ubuntu-22.04 9 | tools: 10 | python: "3.11" 11 | 12 | # Build documentation in the docs/ directory with Sphinx 13 | sphinx: 14 | configuration: docs/source/conf.py 15 | 16 | python: 17 | install: 18 | - requirements: docs/requirements.txt 19 | -------------------------------------------------------------------------------- /docs/source/examples/get_settings_singlesig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "altimeout": 5, 10 | "pricing": { 11 | "currency": "USD", 12 | "exchange": "BITFINEX" 13 | }, 14 | "required_num_blocks": 12, 15 | "sound": true, 16 | "unit": "BTC" 17 | } 18 | 19 | .. raw:: html 20 | 21 |
22 | 23 | -------------------------------------------------------------------------------- /docker/fedora/install_deps.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | dnf update -yq 5 | dnf install -yq @development-tools autoconf pkg-config libtool clang which python python3-pip libatomic curl perl-core cmake libstdc++-static xz 6 | 7 | pip install --require-hashes -r tools/requirements.txt 8 | 9 | curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.81.0 10 | source /root/.cargo/env 11 | 12 | 13 | dnf clean all 14 | rm -fr /var/cache/dnf /tmp/* 15 | -------------------------------------------------------------------------------- /tools/buildbcur.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | cp tools/bc-ur.patch ${PRJ_SUBDIR} 5 | cd "${PRJ_SUBDIR}" 6 | 7 | # fixes to the src files 8 | patch -p1 < bc-ur.patch 9 | 10 | CONFIGURE_ARGS="--prefix=${GDK_BUILD_ROOT} --host=${target_triple}" 11 | 12 | export CFLAGS="$CFLAGS $EXTRA_CFLAGS" 13 | export CXXFLAGS="$CXXFLAGS $EXTRA_CXXFLAGS" 14 | export LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS" 15 | ./configure ${CONFIGURE_ARGS} 16 | 17 | make lib 18 | make install 19 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gdk-test" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | electrsd = { version = "0.29.0", features = ["legacy"] } 8 | env_logger = "0.10.0" 9 | gdk-common = { path = "../gdk_common" } 10 | gdk-electrum = { path = "../gdk_electrum", features = ["testing"] } 11 | serde = { version = "1.0", features = ["derive"] } 12 | serde_json = "1.0" 13 | tempfile = "3.2.0" 14 | bip39 = {version = "2.0"} 15 | -------------------------------------------------------------------------------- /docs/source/examples/get_subaccount_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "hidden": false, 10 | "name": "Example subaccount name", 11 | "pointer": 0, 12 | "receiving_id": "GA2d1AMZojZ3TtoTsYw1JjFUeZQrfT", 13 | "recovery_xpub": "", 14 | "required_ca": 0, 15 | "type": "2of2", 16 | "user_path": [] 17 | } 18 | 19 | .. raw:: html 20 | 21 |
22 | 23 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_registry/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gdk-registry" 3 | version = "0.1.0" 4 | edition = "2021" 5 | autobins = false 6 | 7 | # [[bin]] 8 | # name = "make_hard_coded" 9 | 10 | [dependencies] 11 | gdk-common = { path = "../gdk_common" } 12 | serde = { version = "1.0", features = ["derive"] } 13 | serde_json = "1.0" 14 | thiserror = "1.0" 15 | 16 | [dev-dependencies] 17 | env_logger = "0.10.0" 18 | httptest = "0.16" 19 | rusty-fork = "0.3.0" 20 | tempfile = "3.2.0" 21 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | --- 2 | Checks: '-*,-clang-*,bugprone-*,-bugprone-easily-swappable-parameters,-bugprone-reserved-identifier,-bugprone-assignment-in-if-condition,-bugprone-unused-return-value,-bugprone-exception-escape' 3 | FormatStyle: none 4 | HeaderFilterRegex: 'include/*.h,subprojects/*/*.h' 5 | WarningsAsErrors: '-*,-clang-*,bugprone-*,-bugprone-easily-swappable-parameters,-bugprone-reserved-identifier,-bugprone-assignment-in-if-condition,-bugprone-unused-return-value,-bugprone-exception-escape' 6 | --- 7 | -------------------------------------------------------------------------------- /tests/test_gdk_commit.cpp: -------------------------------------------------------------------------------- 1 | #include "assertion.hpp" 2 | #include "version.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | std::string sha = GDK_COMMIT; 12 | GDK_RUNTIME_ASSERT(sha.length() == 40); 13 | std::locale loc; 14 | std::function isalnum = std::bind(std::isalnum, std::placeholders::_1, loc); 15 | GDK_RUNTIME_ASSERT(std::all_of(sha.cbegin(), sha.cend(), isalnum)); 16 | } 17 | -------------------------------------------------------------------------------- /docs/source/examples/get_subaccount_multisig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "hidden": false, 10 | "name": "Example subaccount name", 11 | "pointer": 0, 12 | "receiving_id": "GA2G8fjDNWvZiJP8Y5iV2ywTAQeZeo", 13 | "recovery_xpub": "", 14 | "required_ca": 0, 15 | "type": "2of2", 16 | "user_path": [] 17 | } 18 | 19 | .. raw:: html 20 | 21 |
22 | 23 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.aarch64-linux-android] 2 | ar = "arch64-linux-android-ar" 3 | linker = "aarch64-linux-android21-clang" 4 | 5 | [target.armv7-linux-androideabi] 6 | ar = "arm-linux-androideabi-ar" 7 | linker = "armv7a-linux-androideabi19-clang" 8 | 9 | [target.i686-linux-android] 10 | ar = "i686-linux-android-ar" 11 | linker = "i686-linux-android19-clang" 12 | 13 | [target.x86_64-linux-android] 14 | ar = "x86_64-linux-android-ar" 15 | linker = "x86_64-linux-android21-clang" 16 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_pin_client/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gdk-pin-client" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | aes = "0.7.0" 8 | bitcoin = { version = "0.32", features = ["rand", "serde"] } 9 | block-modes = "0.8.0" 10 | once_cell = "1.12" 11 | rand = { version = "0.8", features = ["min_const_gen"] } 12 | serde = { version = "1.0", features = ["derive"] } 13 | serde_json = "1.0" 14 | thiserror = "1.0" 15 | ureq = { version = "2.12", features = ["json", "socks-proxy", "gzip", "brotli"] } 16 | url = "2.2.2" 17 | -------------------------------------------------------------------------------- /tools/clang-tidy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | PREBUILT_DIR=$1 5 | 6 | have_cmd() 7 | { 8 | command -v "$1" >/dev/null 2>&1 9 | } 10 | 11 | if have_cmd clang-tidy; then 12 | CLANG_TIDY=$(command -v clang-tidy) 13 | files=$(echo src/*.{c,h}pp) 14 | files=$(echo $files | tr ' ' '\n' | grep -v generated | tr '\n' ' ') 15 | $CLANG_TIDY --quiet $files -- -std=c++17 -Iinclude/ -Isubprojects/gdk_rust/ -I$1/include/ 2>/dev/null 16 | else 17 | echo "ERROR: clang-tidy not found, C++ code not analyzed" 18 | exit 1 19 | fi 20 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_test/src/env.rs: -------------------------------------------------------------------------------- 1 | //! Contains the bindings to the various environment variables needed to run 2 | //! the integration tests. 3 | 4 | use gdk_common::once_cell::sync::Lazy; 5 | use std::env; 6 | 7 | /// Environment variable pointing to the `bitcoind` executable. 8 | pub(crate) const BITCOIND_EXEC: Lazy = Lazy::new(|| env::var("BITCOIND_EXEC").unwrap()); 9 | 10 | /// Environment variable pointing to the `electrs` executable. 11 | pub(crate) const ELECTRS_EXEC: Lazy = Lazy::new(|| env::var("ELECTRS_EXEC").unwrap()); 12 | -------------------------------------------------------------------------------- /docs/source/examples/get_transaction_details_multisig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "transaction": "Transaction Hex, abbreviated here for length", 10 | "transaction_locktime": 200, 11 | "transaction_version": 2, 12 | "transaction_vsize": 2492, 13 | "transaction_weight": 9966, 14 | "txhash": "46dd2e84591e3a27c85d3ead917a1469dd09458fb1d76bce6b58885bf5d6ebbc" 15 | } 16 | 17 | .. raw:: html 18 | 19 |
20 | 21 | -------------------------------------------------------------------------------- /docs/source/examples/get_transaction_details_singlesig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "transaction": "Transaction Hex, abbreviated here for length", 10 | "transaction_locktime": 200, 11 | "transaction_version": 2, 12 | "transaction_vsize": 2492, 13 | "transaction_weight": 9966, 14 | "txhash": "eea0ccc14f823dfcf6afcaf9f57db43aac294d675dd19bb3b563fc11ee169864" 15 | } 16 | 17 | .. raw:: html 18 | 19 |
20 | 21 | -------------------------------------------------------------------------------- /docs/source/examples/get_transactions_input_multisig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "address": "ert1qer759naur22vw6tnssc2ey3eqg974um62nh0cq", 10 | "address_type": "", 11 | "is_internal": false, 12 | "is_output": false, 13 | "is_relevant": false, 14 | "is_spent": true, 15 | "pointer": 0, 16 | "pt_idx": 0, 17 | "subaccount": 0, 18 | "subtype": 0 19 | } 20 | 21 | .. raw:: html 22 | 23 |
24 | 25 | -------------------------------------------------------------------------------- /docs/source/examples/get_transactions_input_singlesig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "address": "", 10 | "address_type": "", 11 | "is_internal": false, 12 | "is_output": false, 13 | "is_relevant": false, 14 | "is_spent": true, 15 | "pointer": 0, 16 | "pt_idx": 0, 17 | "satoshi": 0, 18 | "script": "", 19 | "subaccount": 0, 20 | "subtype": 0 21 | } 22 | 23 | .. raw:: html 24 | 25 |
26 | 27 | -------------------------------------------------------------------------------- /docs/source/examples/get_transactions_output_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "address": "2N2zyKJEcAtqgHRdYFqCQDKZozDi5GY9wi5", 10 | "address_type": "csv", 11 | "is_internal": false, 12 | "is_output": true, 13 | "is_relevant": true, 14 | "is_spent": false, 15 | "pointer": 1, 16 | "pt_idx": 0, 17 | "satoshi": 12340, 18 | "subaccount": 0, 19 | "subtype": 51840 20 | } 21 | 22 | .. raw:: html 23 | 24 |
25 | 26 | -------------------------------------------------------------------------------- /docs/source/examples/get_transactions_input_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "address": "bcrt1qsjtt6hv699fulumf0ravymecm8792shd6hz4kz", 10 | "address_type": "", 11 | "is_internal": false, 12 | "is_output": false, 13 | "is_relevant": false, 14 | "is_spent": true, 15 | "pointer": 0, 16 | "pt_idx": 0, 17 | "satoshi": 5000000000, 18 | "subaccount": 0, 19 | "subtype": 0 20 | } 21 | 22 | .. raw:: html 23 | 24 |
25 | 26 | -------------------------------------------------------------------------------- /docs/source/examples/twofactor_change_limits_btc_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example (returned BTC limit) 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "bits": "500.00", 10 | "btc": "0.00050000", 11 | "fiat": "0.00", 12 | "fiat_currency": "USD", 13 | "fiat_rate": "1.10000000", 14 | "is_current": true, 15 | "is_fiat": false, 16 | "mbtc": "0.50000", 17 | "satoshi": 50000, 18 | "sats": "50000", 19 | "ubtc": "500.00" 20 | } 21 | 22 | .. raw:: html 23 | 24 |
25 | 26 | -------------------------------------------------------------------------------- /tools/requirements.txt: -------------------------------------------------------------------------------- 1 | build==0.10.0 --hash=sha256:af266720050a66c893a6096a2f410989eeac74ff9a68ba194b3f6473e8e26171 2 | pyproject_hooks==1.0.0 --hash=sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8 3 | packaging==23.0 --hash=sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2 4 | tomli==2.0.1 --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc 5 | auditwheel==5.3.0 --hash=sha256:1da1af54de5badd10149250c257a799be003fd976794716f17914e3d4b4a9fc9 6 | pyelftools==0.29 --hash=sha256:519f38cf412f073b2d7393aa4682b0190fa901f7c3fa0bff2b82d537690c7fc1 7 | -------------------------------------------------------------------------------- /docs/source/examples/get_receive_address_singlesig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "address": "2MsHqxhz5fHt2QyvE8TgT1MvzDY9kdMH5Rz", 10 | "address_type": "p2sh-p2wpkh", 11 | "is_internal": false, 12 | "pointer": 1, 13 | "scriptpubkey": "a914007edc4b1153a320e490b5fe29a33e95af2d3c7387", 14 | "subaccount": 0, 15 | "user_path": [ 16 | 2147483697, 17 | 2147483649, 18 | 2147483648, 19 | 0, 20 | 1 21 | ] 22 | } 23 | 24 | .. raw:: html 25 | 26 |
27 | 28 | -------------------------------------------------------------------------------- /docs/source/examples/get_settings_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "altimeout": 5, 10 | "csvtime": 51840, 11 | "nlocktime": 12960, 12 | "notifications": { 13 | "email_incoming": false, 14 | "email_login": false, 15 | "email_outgoing": false 16 | }, 17 | "pricing": { 18 | "currency": "USD", 19 | "exchange": "BITSTAMP" 20 | }, 21 | "required_num_blocks": 12, 22 | "sound": true, 23 | "unit": "BTC" 24 | } 25 | 26 | .. raw:: html 27 | 28 |
29 | 30 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/.config/nextest.toml: -------------------------------------------------------------------------------- 1 | 2 | [profile.ci] 3 | retries = 3 4 | test-threads = 6 5 | failure-output = "immediate-final" # Print out output for failing tests as soon as they fail, and also at the end of the run (for easy scrollability). 6 | fail-fast = false # Do not cancel the test run on the first failure. 7 | slow-timeout = {period = "60s", terminate-after = 3} # test tagged as slow after X seconds, hard-terminated after 3 periods 8 | leak-timeout = "5s" # test is leaky if after termination, test still has stdout or stderr open (subprocess probably still running) 9 | 10 | [profile.ci.junit] 11 | path = "junit.xml" 12 | -------------------------------------------------------------------------------- /docs/source/examples/get_settings_multisig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "altimeout": 5, 10 | "csvtime": 65535, 11 | "nlocktime": 12960, 12 | "notifications": { 13 | "email_incoming": false, 14 | "email_login": false, 15 | "email_outgoing": false 16 | }, 17 | "pricing": { 18 | "currency": "USD", 19 | "exchange": "BITSTAMP" 20 | }, 21 | "required_num_blocks": 12, 22 | "sound": true, 23 | "unit": "BTC" 24 | } 25 | 26 | .. raw:: html 27 | 28 |
29 | 30 | -------------------------------------------------------------------------------- /docs/source/examples/get_transactions_input_singlesig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "address": "bcrt1qsjtt6hv699fulumf0ravymecm8792shd6hz4kz", 10 | "address_type": "", 11 | "is_internal": false, 12 | "is_output": false, 13 | "is_relevant": false, 14 | "is_spent": true, 15 | "pointer": 0, 16 | "pt_idx": 0, 17 | "satoshi": 5000000000, 18 | "script": "00148496bd5d9a2953cff36978fac26f38d9fc5542ed", 19 | "subaccount": 0, 20 | "subtype": 0 21 | } 22 | 23 | .. raw:: html 24 | 25 |
26 | 27 | -------------------------------------------------------------------------------- /docs/source/examples/get_transactions_output_singlesig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "address": "2MsHqxhz5fHt2QyvE8TgT1MvzDY9kdMH5Rz", 10 | "address_type": "p2sh-p2wpkh", 11 | "is_internal": false, 12 | "is_output": true, 13 | "is_relevant": true, 14 | "is_spent": false, 15 | "pointer": 1, 16 | "pt_idx": 1, 17 | "satoshi": 12340, 18 | "script": "a914007edc4b1153a320e490b5fe29a33e95af2d3c7387", 19 | "subaccount": 0, 20 | "subtype": 0 21 | } 22 | 23 | .. raw:: html 24 | 25 |
26 | 27 | -------------------------------------------------------------------------------- /docs/source/examples/bcur_decode_crypto_account.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "descriptors": [ 10 | "pkh([37b5eed4/44'/0'/0']xpub6CnQkivUEH9bSbWVWfDLCtigKKgnSWGaVSRyCbN2QNBJzuvHT1vUQpgSpY1NiVvoeNEuVwk748Cn9G3NtbQB1aGGsEL7aYEnjVWgjj9tefu/0/*)", 11 | "sh(wpkh([37b5eed4/49'/0'/0']xpub6CtR1iF4dZPkEyXDwVf3HE74tSwXNMcHtBzX4gwz2UnPhJ54Jz5unHx2syYCCDkvVUmsmoYTmcaHXe1wJppvct4GMMaN5XAbRk7yGScRSte/0/*))" 12 | ], 13 | "master_fingerprint": "37b5eed4", 14 | "ur_type": "crypto-account" 15 | } 16 | 17 | .. raw:: html 18 | 19 |
20 | 21 | -------------------------------------------------------------------------------- /src/swig_python/dev-mode-setup.py.in: -------------------------------------------------------------------------------- 1 | """setuptools config for gdk """ 2 | 3 | from setuptools import Extension, setup 4 | 5 | 6 | setup( 7 | ext_modules=[Extension( 8 | name="green_gdk._green_gdk", 9 | sources=["swig_green_gdk.i"], 10 | include_dirs=["${CMAKE_BINARY_DIR}/src", "${CMAKE_SOURCE_DIR}/include"], 11 | swig_opts=["-threads", "-I${CMAKE_SOURCE_DIR}/include", "-DGDK_API= "], 12 | libraries=["green_gdk"], 13 | runtime_library_dirs=["${CMAKE_BINARY_DIR}/src"], 14 | library_dirs=["${CMAKE_BINARY_DIR}/src"], 15 | extra_link_args=["-shared"], 16 | language="c++", 17 | )], 18 | ) 19 | 20 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_electrum/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gdk-electrum" 3 | version = "0.1.0" 4 | authors = ["Riccardo Casatta "] 5 | edition = "2018" 6 | 7 | [features] 8 | testing = ["gdk-common/testing"] 9 | 10 | [dependencies] 11 | base64 = "0.13" 12 | block-modes = "0.8.0" 13 | gdk-common = { path = "../gdk_common" } 14 | gdk-pin-client = { path = "../gdk_pin_client" } 15 | libc = "0.2" 16 | serde = { version = "1.0", features = ["derive"] } 17 | serde_json = "1.0" 18 | thiserror = "1.0" 19 | bitcoin_29 = { package = "bitcoin", version = "0.29", features = ["serde"] } 20 | 21 | [dev-dependencies] 22 | env_logger = "0.10.0" 23 | tempfile = "3.2.0" 24 | -------------------------------------------------------------------------------- /cmake/profiles/common.cmake: -------------------------------------------------------------------------------- 1 | if(NOT DEFINED CMAKE_BUILD_TYPE) 2 | set(CMAKE_BUILD_TYPE "Release" CACHE INTERNAL "") 3 | endif() 4 | 5 | 6 | set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) 7 | if(CMAKE_BUILD_TYPE STREQUAL "Release") 8 | set(GDK_LINK_OPTIONS 9 | "LINKER:-z,now" 10 | "LINKER:-z,relro" 11 | "LINKER:-z,noexecstack" 12 | "LINKER:-z,undefs" 13 | ) 14 | set(CMAKE_CXX_VISIBILITY_PRESET hidden) 15 | set(CMAKE_C_VISIBILITY_PRESET hidden) 16 | set(CMAKE_VISIBILITY_INLINES_HIDDEN YES) 17 | elseif( CMAKE_BUILD_TYPE STREQUAL "Debug") 18 | add_compile_definitions("_GLIBCXX_ASSERTIONS" "_GLIBCXX_DEBUG" "_GLIBCXX_DEBUG_PEDANTIC") 19 | endif() 20 | -------------------------------------------------------------------------------- /tools/macos_env.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | if [ \( "$(uname)" = "Darwin" \) ]; then 5 | export XCODE_PATH=$(xcode-select --print-path 2>/dev/null) 6 | export PLATFORM="MacOSX" 7 | export SDK_PATH="$XCODE_PATH/Platforms/$PLATFORM.platform/Developer/SDKs/$PLATFORM.sdk" 8 | export SDK_CFLAGS="$SDK_CFLAGS -isysroot ${SDK_PATH} -mmacosx-version-min=10.13" 9 | export SDK_CXXFLAGS="$SDK_CXXFLAGS -isysroot ${SDK_PATH} -mmacosx-version-min=10.13" 10 | export SDK_LDFLAGS="$SDK_LDFLAGS -isysroot ${SDK_PATH} -mmacosx-version-min=10.13" 11 | export CFLAGS="${SDK_CFLAGS} -O2" 12 | export CXXFLAGS="${SDK_CXXFLAGS} -O2" 13 | export LDFLAGS="${SDK_LDFLAGS}" 14 | fi 15 | -------------------------------------------------------------------------------- /include/wally_wrapper.h: -------------------------------------------------------------------------------- 1 | #ifndef GDK_WALLY_WRAPPER_H 2 | #define GDK_WALLY_WRAPPER_H 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_test/src/utils.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | use std::time::Duration; 3 | 4 | use serde_json::Value; 5 | 6 | use gdk_common::model::*; 7 | use gdk_common::{NetworkId, NetworkParameters, State}; 8 | use gdk_electrum::headers; 9 | use gdk_electrum::{Notification, TransactionNotification}; 10 | 11 | /// Json of network notification 12 | pub fn ntf_network(current: State, desired: State) -> Value { 13 | serde_json::to_value(&Notification::new_network(current, desired)).unwrap() 14 | } 15 | 16 | /// Json of transaction notification 17 | pub fn ntf_transaction(ntf: &TransactionNotification) -> Value { 18 | serde_json::to_value(&Notification::new_transaction(ntf)).unwrap() 19 | } 20 | -------------------------------------------------------------------------------- /docker/debian/install_deps.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | apt update -qq 5 | 6 | apt install --no-install-recommends autoconf automake autotools-dev pkg-config build-essential libtool python3{,-dev,-pip,-virtualenv} python{,-dev}-is-python3 clang{,-format,-tidy} git swig g++-mingw-w64-x86-64 curl cmake libssl-dev libtool-bin openjdk-11-jdk openjdk-11-jre -yqq 7 | pip3 install --require-hashes -r tools/requirements.txt 8 | 9 | 10 | if [ -f /.dockerenv ]; then 11 | apt remove --purge unzip -yqq 12 | apt -yqq autoremove 13 | apt -yqq clean 14 | rm -rf /var/lib/apt/lists/* /var/cache/* /tmp/* /usr/share/locale/* /usr/share/man /usr/share/doc /lib/xtables/libip6* /root/.cache 15 | fi 16 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_registry/src/hard_coded/elements-regtest_assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225": { 3 | "asset_id": "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225", 4 | "contract": null, 5 | "entity": null, 6 | "issuance_prevout": { 7 | "txid": "0000000000000000000000000000000000000000000000000000000000000000", 8 | "vout": 0 9 | }, 10 | "issuance_txin": { 11 | "txid": "0000000000000000000000000000000000000000000000000000000000000000", 12 | "vin": 0 13 | }, 14 | "issuer_pubkey": "", 15 | "name": "btc", 16 | "precision": 8, 17 | "ticker": "L-TEST", 18 | "version": 0 19 | } 20 | } -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_registry/src/hard_coded/liquid-testnet_assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49": { 3 | "asset_id": "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49", 4 | "contract": null, 5 | "entity": null, 6 | "issuance_prevout": { 7 | "txid": "0000000000000000000000000000000000000000000000000000000000000000", 8 | "vout": 0 9 | }, 10 | "issuance_txin": { 11 | "txid": "0000000000000000000000000000000000000000000000000000000000000000", 12 | "vin": 0 13 | }, 14 | "issuer_pubkey": "", 15 | "name": "btc", 16 | "precision": 8, 17 | "ticker": "L-TEST", 18 | "version": 0 19 | } 20 | } -------------------------------------------------------------------------------- /docker/aws_lambda/install_deps.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | yum update -y -q 5 | yum install -y -q @development-tools autoconf pkgconfig libtool clang which python python3-pip libatomic curl perl-core libstdc++-static xz gzip git make patch swig 6 | 7 | # We need a more recent cmake than the one in the distro repos 8 | curl -sL --retry 3 https://github.com/Kitware/CMake/releases/download/v3.18.5/cmake-3.18.5-Linux-x86_64.sh --output cmake.sh 9 | chmod +x cmake.sh 10 | ./cmake.sh --skip-license --exclude-subdir --prefix=/usr/local/ 11 | 12 | pip install --require-hashes -r tools/requirements.txt 13 | 14 | curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.81.0 15 | source /root/.cargo/env 16 | -------------------------------------------------------------------------------- /src/containers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_CONTAINERS_HPP 2 | #define GDK_CONTAINERS_HPP 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace green { 9 | 10 | class amount; 11 | 12 | // Add a value to a JSON object if one is not already present under the given key 13 | template 14 | T json_add_if_missing(nlohmann::json& data, const std::string& key, const T& value, bool or_null = false) 15 | { 16 | const auto p = data.find(key); 17 | if (p == data.end() || (or_null && p->is_null())) { 18 | data[key] = value; 19 | return value; 20 | } 21 | return *p; 22 | } 23 | 24 | } // namespace green 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/validate.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_VALIDATE_HPP 2 | #define GDK_VALIDATE_HPP 3 | #pragma once 4 | 5 | #include "auth_handler.hpp" 6 | #include "ga_wally.hpp" 7 | 8 | namespace green { 9 | 10 | class validate_call : public auth_handler_impl { 11 | public: 12 | validate_call(session& session, nlohmann::json details); 13 | 14 | private: 15 | state_type call_impl() override; 16 | 17 | bool is_addressees() const; 18 | void addressees_impl(); 19 | 20 | bool is_liquidex() const; // in swap_auth_handlers.cpp 21 | void liquidex_impl(); // in swap_auth_handlers.cpp 22 | 23 | nlohmann::json m_details; 24 | }; 25 | 26 | } // namespace green 27 | #endif // GDK_VALIDATE_HPP 28 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | 3 | members = [ 4 | "gdk_common", 5 | "gdk_electrum", 6 | "gdk_pin_client", 7 | "gdk_registry", 8 | "gdk_rust", 9 | ] 10 | 11 | exclude = [ "gdk_test" ] 12 | resolver = "2" 13 | 14 | [profile.release] 15 | lto = true 16 | panic = 'abort' 17 | opt-level = 'z' 18 | codegen-units = 1 19 | incremental = false 20 | 21 | [profile.dev] 22 | 23 | ## Link time optimizations are required for debug builds on iphone and iphonesim 24 | ## If we set lto to true here we increase rust development build time. 25 | ## CI builds overwrite this field by setting `CARGO_PROFILE_DEV_LTO=true` 26 | # lto = true 27 | 28 | debug = true 29 | debug-assertions = true 30 | panic = 'abort' 31 | lto = true 32 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_registry/README.md: -------------------------------------------------------------------------------- 1 | # Updating Hardcoded data 2 | 3 | - uncomment the `[[bin]]` section in the `Cargo.toml` file; 4 | 5 | - make a backup copy of the assets and icons: 6 | 7 | ``` 8 | cp liquid_assets.json liquid_assets_.json 9 | cp liquid_icons.json liquid_icons_.json 10 | ``` 11 | 12 | - launch the executable: 13 | 14 | ``` 15 | cargo run --bin make_hard_coded 16 | ``` 17 | 18 | - manually check changes: 19 | 20 | ``` 21 | diff <(jq --sort-keys . liquid_assets.json) <(jq --sort-keys . liquid_assets_.json) 22 | diff <(jq --sort-keys . liquid_icons.json) <(jq --sort-keys . liquid_icons_.json) 23 | ``` 24 | 25 | - run the tests to make sure the new values have been serialized correctly and 26 | can be deserialized. 27 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_pin_client/README.md: -------------------------------------------------------------------------------- 1 | # Testing using a local PIN server 2 | 3 | It's possible to run the tests by spinning up a local copy of the PIN server 4 | and setting a couple of environment variables: 5 | 6 | 1) generate the public key of the PIN server by following [these instructions](https://github.com/Blockstream/blind_pin_server#to-generate-a-new-key); 7 | 8 | 2) set the `$PIN_SERVER_PUBLIC_KEY` environment variable to the value of the 9 | public key generated in the previous step; 10 | 11 | 3) spin un the server by building and running its docker image; 12 | 13 | 4) set the `$PIN_SERVER_URL` to the URL of the locally running PIN server. 14 | For example if it was launched on port `8096` this would be 15 | `http://127.0.0.1:8096`. 16 | -------------------------------------------------------------------------------- /cmake/profiles/windows-mingw-w64.cmake: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) 2 | 3 | # 4 | set(CMAKE_SYSTEM_NAME Windows) 5 | set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) 6 | set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc-posix) 7 | set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++-posix) 8 | set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) 9 | set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) 10 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) 11 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) 12 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) 13 | 14 | set(_rustTriple "x86_64-pc-windows-gnu") 15 | 16 | set(GDK_LINK_OPTIONS "-static" "-static-libgcc") 17 | if(CMAKE_BUILD_TYPE STREQUAL "Debug") 18 | # when debugging in windows try dwarf-2 or stabs formats 19 | add_compile_options("-gdwarf-2" "-fno-omit-frame-pointer") # winedbg flag 20 | endif() 21 | -------------------------------------------------------------------------------- /docs/source/examples/get_twofactor_config_singlesig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig example (two-factor and limits not available) 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "all_methods": [], 10 | "any_enabled": false, 11 | "enabled_methods": [], 12 | "limits": { 13 | "bits": "0.00", 14 | "btc": "0.00000000", 15 | "fiat": "0.00", 16 | "fiat_currency": "USD", 17 | "fiat_rate": "1.10000000", 18 | "is_current": true, 19 | "is_fiat": false, 20 | "mbtc": "0.00000", 21 | "satoshi": 0, 22 | "sats": "0", 23 | "ubtc": "0.00" 24 | }, 25 | "twofactor_reset": { 26 | "days_remaining": -1, 27 | "is_active": false, 28 | "is_disputed": false 29 | } 30 | } 31 | 32 | .. raw:: html 33 | 34 |
35 | 36 | -------------------------------------------------------------------------------- /docker/ubuntu/install_deps.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | apt update -qq 5 | DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata 6 | 7 | apt install --no-install-recommends unzip autoconf automake autotools-dev pkg-config build-essential libtool python3{,-dev,-pip,-virtualenv,-venv} python{,-dev}-is-python3 clang git swig cmake libssl-dev libtool-bin curl -yqq 8 | pip3 install --require-hashes -r ./tools/requirements.txt 9 | pip3 install build 10 | 11 | curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.81.0 12 | source /root/.cargo/env 13 | 14 | 15 | if [ -f /.dockerenv ]; then 16 | apt remove --purge unzip -yqq 17 | apt -yqq autoremove 18 | apt -yqq clean 19 | rm -rf /var/lib/apt/lists/* /var/cache/* /tmp/* /usr/share/locale/* /usr/share/man /usr/share/doc /lib/xtables/libip6* /root/.cache 20 | fi 21 | -------------------------------------------------------------------------------- /tools/format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | have_cmd() 5 | { 6 | command -v "$1" >/dev/null 2>&1 7 | } 8 | 9 | if have_cmd clang-format; then 10 | CLANG_FORMAT=$(command -v clang-format) 11 | files=$(echo src/*.{c,h}pp include/*.h tests/*cpp) 12 | files=$(echo $files | tr ' ' '\n' | grep -v generated | tr '\n' ' ') 13 | $CLANG_FORMAT -i $files 14 | else 15 | echo "WARNING: clang-format not found, C++ code not formatted" 16 | fi 17 | 18 | if ! have_cmd cargo; then 19 | if [ -f "/root/.cargo/env" ]; then 20 | # Docker CI 21 | source /root/.cargo/env 22 | fi 23 | fi 24 | 25 | if have_cmd cargo; then 26 | CARGO=$(command -v cargo) 27 | pushd subprojects/gdk_rust >/dev/null 28 | $CARGO fmt 29 | popd >/dev/null 30 | else 31 | echo "WARNING: cargo not found, Rust code not formatted" 32 | fi 33 | -------------------------------------------------------------------------------- /docs/source/examples/get_receive_address_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "address": "2N2zyKJEcAtqgHRdYFqCQDKZozDi5GY9wi5", 10 | "address_type": "csv", 11 | "branch": 1, 12 | "pointer": 1, 13 | "script": "2102ea2fe5fcee6e1ada9ee3f4228ac1b83554cff618c8bc6ef64d9988e2f4bb13a1ad21023cebb0d3a3434d1df033c3c41e3d02f2e0b44a64c3d58519ca656b4f5363f591ac73640380ca00b268", 14 | "scriptpubkey": "a9146aff2fc8f5ec359f809b3355d6bdc5d30f8e105487", 15 | "service_xpub": "tpubEAUTpVqYYmDa5DQdXdJhaMyrvycVbpuCRdUTVifuG3ML5kbwujP3CdxGT1rVoDnFnxsxEv1aiVaEtuJzDBu1bNJk9mADeeR2rZ1HcCCzdyG", 16 | "subaccount": 0, 17 | "subtype": 51840, 18 | "user_path": [ 19 | 1, 20 | 1 21 | ] 22 | } 23 | 24 | .. raw:: html 25 | 26 |
27 | 28 | -------------------------------------------------------------------------------- /docker/ubuntu-arm64/install_deps.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | apt update -qq 5 | DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata 6 | 7 | apt install --no-install-recommends unzip autoconf automake autotools-dev pkg-config build-essential libtool python3{,-dev,-pip,-virtualenv,-venv} python{,-dev}-is-python3 git swig openjdk-11-jdk cmake libssl-dev libtool-bin curl -yqq 8 | pip3 install --require-hashes -r ./tools/requirements.txt 9 | pip3 install build 10 | 11 | curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.81.0 12 | source /root/.cargo/env 13 | 14 | 15 | if [ -f /.dockerenv ]; then 16 | apt remove --purge unzip -yqq 17 | apt -yqq autoremove 18 | apt -yqq clean 19 | rm -rf /var/lib/apt/lists/* /var/cache/* /tmp/* /usr/share/locale/* /usr/share/man /usr/share/doc /lib/xtables/libip6* /root/.cache 20 | fi 21 | -------------------------------------------------------------------------------- /docs/source/examples/get_receive_address_singlesig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "address": "AzpjM6F3vhwPK3U5p8u79osjbhsduwdGCrbt1Cahy8nD3d7SbQJte99KiMkxWZLBrmUnWPrU3eLtUbVU", 10 | "address_type": "p2sh-p2wpkh", 11 | "blinding_key": "020de79e60d9d17b22c9f803455eb2fc48becc50fe76d32508bde357bf10c28a8a", 12 | "is_confidential": true, 13 | "is_internal": false, 14 | "pointer": 1, 15 | "scriptpubkey": "a914007edc4b1153a320e490b5fe29a33e95af2d3c7387", 16 | "subaccount": 0, 17 | "unconfidential_address": "XBPrpZvDkTp1TY3kAhNtLBzo4Vycb9BsQt", 18 | "user_path": [ 19 | 2147483697, 20 | 2147483649, 21 | 2147483648, 22 | 0, 23 | 1 24 | ] 25 | } 26 | 27 | .. raw:: html 28 | 29 |
30 | 31 | -------------------------------------------------------------------------------- /src/assertion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "assertion.hpp" 4 | #include "exception.hpp" 5 | #include "logging.hpp" 6 | 7 | namespace green { 8 | 9 | void runtime_assert_message(const std::string& error_message, const char* file, unsigned int line) 10 | { 11 | #ifndef __FILE_NAME__ 12 | // Strip path from the file name 13 | const char* base = strrchr(file, '/'); 14 | file = base ? base + 1 : file; 15 | #endif 16 | const char* sep = error_message.empty() ? "" : ":"; 17 | const std::string msg 18 | = std::string("assertion failure: ") + file + ":" + std::to_string(line) + sep + error_message; 19 | GDK_LOG(error) << msg; 20 | throw assertion_error(msg); 21 | } 22 | 23 | void throw_user_error(const std::string& error_message) { throw user_error(error_message); } 24 | 25 | } // namespace green 26 | -------------------------------------------------------------------------------- /cmake/modules/Findautobahn.cmake: -------------------------------------------------------------------------------- 1 | # * Try to find the autobahn library 2 | # 3 | # optional hint: autobahn_ROOT_DIR 4 | # 5 | # once done this will define 6 | # - autobahn_FOUND 7 | # - autobahn_INCLUDE_DIRS 8 | # - autobahn_LINK_LIBRARIES 9 | # 10 | # and the imported target 11 | # - extern::autobahn-cpp 12 | 13 | include(FindPackageHandleStandardArgs) 14 | 15 | set(autobahn_ROOT_DIR 16 | "" 17 | CACHE PATH "Folder contains autobahn install dir" 18 | ) 19 | find_path(autobahn_INCLUDE_DIR autobahn/autobahn.hpp PATHS ${autobahn_ROOT_DIR}) 20 | 21 | find_package_handle_standard_args(autobahn DEFAULT_MSG autobahn_INCLUDE_DIR) 22 | if(autobahn_FOUND) 23 | set(autobahn_INCLUDE_DIRS ${autobahn_INCLUDE_DIR}) 24 | add_library(extern::autobahn-cpp INTERFACE IMPORTED) 25 | set_target_properties(extern::autobahn-cpp PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${autobahn_INCLUDE_DIRS}) 26 | endif() 27 | -------------------------------------------------------------------------------- /docker/android/install_deps.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | apt update -qq 5 | apt upgrade -yqq 6 | 7 | apt install --no-install-recommends unzip autoconf automake autotools-dev pkg-config build-essential libtool python3{,-dev} python{,-dev}-is-python3 clang git swig openjdk-11-jdk curl cmake libssl-dev libtool-bin -yqq 8 | update-java-alternatives -s java-1.11.0-openjdk-amd64 9 | 10 | curl -L -o ndk.zip https://dl.google.com/android/repository/android-ndk-r26b-linux.zip 11 | echo "ad73c0370f0b0a87d1671ed2fd5a9ac9acfd1eb5c43a7fbfbd330f85d19dd632 ndk.zip" | shasum -a 256 -c 12 | unzip ndk.zip 13 | rm ndk.zip 14 | 15 | 16 | if [ -f /.dockerenv ]; then 17 | apt remove --purge unzip -yqq 18 | apt -yqq autoremove 19 | apt -yqq clean 20 | rm -rf /var/lib/apt/lists/* /var/cache/* /tmp/* /usr/share/locale/* /usr/share/man /usr/share/doc /lib/xtables/libip6* /root/.cache 21 | fi 22 | -------------------------------------------------------------------------------- /docker/android-bookworm/install_deps.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | apt update -qq 5 | apt upgrade -yqq 6 | 7 | apt install --no-install-recommends unzip autoconf automake autotools-dev pkg-config build-essential libtool python3{,-dev} python{,-dev}-is-python3 clang git swig openjdk-17-jdk curl cmake libssl-dev libtool-bin -yqq 8 | update-java-alternatives -s java-1.17.0-openjdk-amd64 9 | 10 | curl -L -o ndk.zip https://dl.google.com/android/repository/android-ndk-r26b-linux.zip 11 | echo "ad73c0370f0b0a87d1671ed2fd5a9ac9acfd1eb5c43a7fbfbd330f85d19dd632 ndk.zip" | shasum -a 256 -c 12 | unzip ndk.zip 13 | rm ndk.zip 14 | 15 | 16 | if [ -f /.dockerenv ]; then 17 | apt remove --purge unzip -yqq 18 | apt -yqq autoremove 19 | apt -yqq clean 20 | rm -rf /var/lib/apt/lists/* /var/cache/* /tmp/* /usr/share/locale/* /usr/share/man /usr/share/doc /lib/xtables/libip6* /root/.cache 21 | fi 22 | -------------------------------------------------------------------------------- /docs/source/examples/get_unspent_outputs_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "unspent_outputs": { 10 | "btc": [ 11 | { 12 | "address_type": "csv", 13 | "block_height": 0, 14 | "is_internal": false, 15 | "pointer": 1, 16 | "prevout_script": "2102ea2fe5fcee6e1ada9ee3f4228ac1b83554cff618c8bc6ef64d9988e2f4bb13a1ad21023cebb0d3a3434d1df033c3c41e3d02f2e0b44a64c3d58519ca656b4f5363f591ac73640380ca00b268", 17 | "pt_idx": 0, 18 | "satoshi": 12340, 19 | "subaccount": 0, 20 | "subtype": 51840, 21 | "txhash": "1a45e3a1140b17b45277e7e1189ff8385c7e0fd4cd88a5840b15ee600d5dbc30", 22 | "user_status": 0 23 | } 24 | ] 25 | } 26 | } 27 | 28 | .. raw:: html 29 | 30 |
31 | 32 | -------------------------------------------------------------------------------- /docs/source/examples/get_transaction_details_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "transaction": "020000000001019b763a75636ba2deaefc5cc5cbb7dc201f45de5d2aa1ffcda6636ecc4528f5ca0000000000feffffff02343000000000000017a9146aff2fc8f5ec359f809b3355d6bdc5d30f8e10548736bc052a0100000017a9141aeb565e55f84835c5815bee5b7b2b31b3f6029c8702473044022057c4218260f4dc944a5a25fd3113890e0dca4222f3aff5915f3383fd7c63bc4102203f4c29cf40f3ae0ac3cb5cce92713d3613df237a4dc8520ed2fc40617ff600760121022dcbac960c21f79c69e0374669b609ada9a6b38d7bd5171d064e32da4c2b0aafc8000000", 10 | "transaction_locktime": 200, 11 | "transaction_version": 2, 12 | "transaction_vsize": 143, 13 | "transaction_weight": 569, 14 | "txhash": "1a45e3a1140b17b45277e7e1189ff8385c7e0fd4cd88a5840b15ee600d5dbc30" 15 | } 16 | 17 | .. raw:: html 18 | 19 |
20 | 21 | -------------------------------------------------------------------------------- /docs/source/examples/get_transaction_details_singlesig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "transaction": "02000000000101c7fc89a3a6b1568916f64c9e9abd77bd53d16daa4de758af8d8a54d19c45b9950000000000feffffff0236bc052a0100000017a9146a60f8f6cd77c44582c04b8912dcba06601503e087343000000000000017a914007edc4b1153a320e490b5fe29a33e95af2d3c73870247304402202023cd3653263959583686168b48cc5f570f34af06a36aef625ffaf50d15b4f102203e4e0d54fa9f6d7d2aef2886adfe57d4ecc7f679b09e12ed4c085cab923fc78a0121022dcbac960c21f79c69e0374669b609ada9a6b38d7bd5171d064e32da4c2b0aafc8000000", 10 | "transaction_locktime": 200, 11 | "transaction_version": 2, 12 | "transaction_vsize": 143, 13 | "transaction_weight": 569, 14 | "txhash": "8a3974692b29237cb81f545a7891be89d73aed7d0038879da437623b0fd57584" 15 | } 16 | 17 | .. raw:: html 18 | 19 |
20 | 21 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_registry/src/last_modified.rs: -------------------------------------------------------------------------------- 1 | use std::ops::{Index, IndexMut}; 2 | 3 | use crate::AssetsOrIcons; 4 | use serde::{Deserialize, Serialize}; 5 | 6 | #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] 7 | pub(crate) struct LastModified { 8 | assets: String, 9 | icons: String, 10 | } 11 | 12 | impl Index for LastModified { 13 | type Output = String; 14 | 15 | fn index(&self, what: AssetsOrIcons) -> &Self::Output { 16 | match what { 17 | AssetsOrIcons::Assets => &self.assets, 18 | AssetsOrIcons::Icons => &self.icons, 19 | } 20 | } 21 | } 22 | 23 | impl IndexMut for LastModified { 24 | fn index_mut(&mut self, what: AssetsOrIcons) -> &mut String { 25 | match what { 26 | AssetsOrIcons::Assets => &mut self.assets, 27 | AssetsOrIcons::Icons => &mut self.icons, 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/redeposit_auth_handlers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_REDEPOSIT_AUTH_HANDLERS_HPP 2 | #define GDK_REDEPOSIT_AUTH_HANDLERS_HPP 3 | #pragma once 4 | 5 | #include "auth_handler.hpp" 6 | #include 7 | 8 | namespace green { 9 | 10 | class create_redeposit_transaction_call : public auth_handler_impl { 11 | public: 12 | create_redeposit_transaction_call(session& session, nlohmann::json details); 13 | 14 | private: 15 | state_type call_impl() override; 16 | void on_next_handler_complete(auth_handler* next_handler) override; 17 | 18 | void initialize(); 19 | std::string get_nth_asset_id(size_t n) const; 20 | void add_fee_utxo(nlohmann::json& to); 21 | 22 | nlohmann::json m_details; 23 | nlohmann::json::array_t m_fee_utxos; 24 | std::optional m_subaccount; 25 | std::optional m_fee_subaccount; 26 | }; 27 | } // namespace green 28 | #endif // GDK_REDEPOSIT_AUTH_HANDLERS_HPP 29 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_common/src/state.rs: -------------------------------------------------------------------------------- 1 | use core::fmt; 2 | 3 | #[derive(Debug, PartialEq, Clone, Copy, serde::Serialize, serde::Deserialize)] 4 | #[serde(rename_all = "snake_case")] 5 | pub enum State { 6 | Disconnected, 7 | Connected, 8 | } 9 | 10 | impl From for State { 11 | fn from(b: bool) -> Self { 12 | if b { 13 | State::Connected 14 | } else { 15 | State::Disconnected 16 | } 17 | } 18 | } 19 | 20 | impl From for bool { 21 | fn from(s: State) -> Self { 22 | match s { 23 | State::Connected => true, 24 | State::Disconnected => false, 25 | } 26 | } 27 | } 28 | 29 | impl fmt::Display for State { 30 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { 31 | match self { 32 | State::Disconnected => write!(f, "disconnected"), 33 | State::Connected => write!(f, "connected"), 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_registry/src/data/test/result.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets": { 3 | "0000000000000000000000000000000000000000000000000000000000000000": { 4 | "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", 5 | "contract": null, 6 | "issuance_txin": { 7 | "txid": "0000000000000000000000000000000000000000000000000000000000000000", 8 | "vin": 0 9 | }, 10 | "issuance_prevout": { 11 | "txid": "0000000000000000000000000000000000000000000000000000000000000000", 12 | "vout": 0 13 | }, 14 | "version": 0, 15 | "issuer_pubkey": "", 16 | "name": "", 17 | "ticker": null, 18 | "precision": 0, 19 | "entity": null 20 | } 21 | }, 22 | "icons": { 23 | "0000000000000000000000000000000000000000000000000000000000000000": "BASE64" 24 | } 25 | } -------------------------------------------------------------------------------- /src/bcur_auth_handlers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_BCUR_AUTH_HANDLERS_HPP 2 | #define GDK_BCUR_AUTH_HANDLERS_HPP 3 | #pragma once 4 | 5 | #include "auth_handler.hpp" 6 | 7 | namespace ur { 8 | class UREncoder; 9 | class URDecoder; 10 | } // namespace ur 11 | 12 | namespace green { 13 | 14 | class bcur_encoder_call : public auth_handler_impl { 15 | public: 16 | explicit bcur_encoder_call(session& session, nlohmann::json details); 17 | 18 | private: 19 | state_type call_impl() override; 20 | 21 | nlohmann::json m_details; 22 | std::unique_ptr m_encoder; 23 | }; 24 | 25 | class bcur_decoder_call : public auth_handler_impl { 26 | public: 27 | explicit bcur_decoder_call(session& session, nlohmann::json details); 28 | 29 | private: 30 | state_type call_impl() override; 31 | 32 | nlohmann::json m_details; 33 | std::unique_ptr m_decoder; 34 | }; 35 | 36 | } // namespace green 37 | #endif 38 | -------------------------------------------------------------------------------- /docs/source/examples/get_unspent_outputs_singlesig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "unspent_outputs": { 10 | "btc": [ 11 | { 12 | "address_type": "p2sh-p2wpkh", 13 | "block_height": 0, 14 | "is_internal": false, 15 | "pointer": 1, 16 | "prevout_script": "76a9144d2af219985cd7e523cf1be0421636fe4f38f4b788ac", 17 | "pt_idx": 1, 18 | "public_key": "030e18cc1d6474e092264aa44e7b81ce1068f2b12ec748c96f217d8de5cb2555dc", 19 | "satoshi": 12340, 20 | "subaccount": 0, 21 | "txhash": "8a3974692b29237cb81f545a7891be89d73aed7d0038879da437623b0fd57584", 22 | "user_path": [ 23 | 2147483697, 24 | 2147483649, 25 | 2147483648, 26 | 0, 27 | 1 28 | ] 29 | } 30 | ] 31 | } 32 | } 33 | 34 | .. raw:: html 35 | 36 |
37 | 38 | -------------------------------------------------------------------------------- /cmake/modules/Findbcur.cmake: -------------------------------------------------------------------------------- 1 | # * Try to find the bcur library 2 | # 3 | # optional hint: bcur_ROOT_DIR 4 | # 5 | # once done this will define 6 | # - bcur_FOUND 7 | # - bcur_INCLUDE_DIRS 8 | # - bcur_LINK_LIBRARIES 9 | # 10 | # and the imported target 11 | # - extern::bcur 12 | 13 | include(FindPackageHandleStandardArgs) 14 | 15 | set(bcur_ROOT_DIR 16 | "" 17 | CACHE PATH "Folder contains bcur install dir" 18 | ) 19 | find_path(bcur_INCLUDE_DIR bc-ur/bc-ur.hpp PATHS ${bcur_ROOT_DIR}) 20 | find_library( 21 | bcur_LIBRARIES 22 | NAMES bc-ur 23 | PATHS ${bcur_ROOT_DIR}/lib 24 | ) 25 | 26 | find_package_handle_standard_args(bcur DEFAULT_MSG bcur_LIBRARIES bcur_INCLUDE_DIR) 27 | if(bcur_FOUND) 28 | set(bcur_LINK_LIBRARIES ${bcur_LIBRARIES}) 29 | set(bcur_INCLUDE_DIRS ${bcur_INCLUDE_DIR}) 30 | add_library(extern::bc-ur STATIC IMPORTED) 31 | set_target_properties( 32 | extern::bc-ur PROPERTIES IMPORTED_LOCATION ${bcur_LIBRARIES} INTERFACE_INCLUDE_DIRECTORIES ${bcur_INCLUDE_DIR} 33 | ) 34 | 35 | endif() 36 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_common/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod be; 2 | pub mod descriptor; 3 | pub mod error; 4 | pub mod exchange_rates; 5 | pub mod model; 6 | pub mod network; 7 | pub mod notification; 8 | pub mod password; 9 | pub mod scripts; 10 | pub mod session; 11 | pub mod slip132; 12 | pub mod state; 13 | pub mod store; 14 | pub mod util; 15 | pub mod aes { 16 | pub use aes::*; 17 | pub use aes_gcm_siv::*; 18 | } 19 | 20 | pub use bitcoin; 21 | pub use electrum_client; 22 | pub use elements; 23 | pub use elements_miniscript; 24 | pub use error::*; 25 | pub use log; 26 | pub use miniscript; 27 | pub use network::*; 28 | pub use once_cell; 29 | pub use rand; 30 | pub use serde_cbor; 31 | pub use state::State; 32 | pub use ureq; 33 | 34 | pub static EC: once_cell::sync::Lazy> = 35 | once_cell::sync::Lazy::new(|| { 36 | let mut ctx = bitcoin::secp256k1::Secp256k1::new(); 37 | let mut rng = rand::thread_rng(); 38 | ctx.randomize(&mut rng); 39 | ctx 40 | }); 41 | -------------------------------------------------------------------------------- /docker/python/install_deps.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | dnf upgrade almalinux-release -y 5 | yum update -yqq 6 | yum install -yqq swig perl-core autoconf libstdc++-static clang 7 | 8 | python_versions=(cp39-cp39 cp310-cp310 cp311-cp311 cp312-cp312 cp313-cp313) 9 | 10 | 11 | /opt/python/${python_versions[0]}/bin/python -m venv /root/tmp-python-env 12 | source /root/tmp-python-env/bin/activate 13 | pip install virtualenv 14 | for python_version in "${python_versions[@]}"; 15 | do 16 | echo "building python environment for ${python_version}" 17 | virtualenv -p /opt/python/$python_version/bin/python /root/python-${python_version}-venv 18 | done 19 | deactivate 20 | rm -rf /root/tmp-python-env 21 | 22 | for python_version in "${python_versions[@]}"; 23 | do 24 | source /root/python-${python_version}-venv/bin/activate 25 | pip install -r tools/requirements.txt 26 | pip install setuptools 27 | deactivate 28 | done 29 | 30 | ln -s /root/python-${python_versions[0]}-venv /opt/python/default 31 | 32 | yum autoremove -yqq 33 | -------------------------------------------------------------------------------- /docker/ubuntu-arm64/Dockerfile: -------------------------------------------------------------------------------- 1 | # Ubuntu for arm64 image. Build with: 2 | # DOCKER_BUILDKIT=1 docker build . -t blockstream/gdk-ubuntu-builder -f docker/ubuntu/Dockerfile 3 | # 4 | FROM ubuntu:20.04@sha256:71201a4c55f72ec33671cfcbf007689df61a13a35f028f94f8c510967dfb52e1 AS base 5 | WORKDIR /root 6 | COPY ./tools ./tools 7 | COPY ./cmake/profiles ./cmake/profiles 8 | # Optionally copy dependency sources from the build directory if present 9 | COPY ./downloads ./downloads 10 | COPY ./docker/ubuntu-arm64/install_deps.sh ./docker/ubuntu-arm64/install_deps.sh 11 | RUN ./docker/ubuntu-arm64/install_deps.sh 12 | ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-arm64 13 | 14 | FROM base AS buildergcc 15 | ENV GDK_KEEP_DOWNLOADS=1 16 | RUN mkdir -p /prebuild/gcc 17 | RUN ./tools/builddeps.sh --gcc --prefix /prebuild/gcc 18 | 19 | FROM base 20 | # Remove copied/downloaded dependency sources 21 | RUN rm -rf ./tools ./downloads ./cmake ./docker 22 | 23 | COPY --from=buildergcc /prebuild/gcc /prebuild/gcc 24 | 25 | RUN chmod +xr /root 26 | WORKDIR /root/gdk 27 | VOLUME /root/gdk 28 | -------------------------------------------------------------------------------- /cmake/exports/gdk-config.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | 4 | set_and_check(GDK_LIB_DIR "@PACKAGE_LIB_CMAKE_INSTALL_DIR@") 5 | 6 | if("green_gdk" IN_LIST gdk_FIND_COMPONENTS) 7 | include("${GDK_LIB_DIR}/cmake/green_gdk-targets.cmake") 8 | foreach(_target IN LISTS _IMPORT_CHECK_FILES_FOR_gdk::green_gdk) 9 | if(NOT EXIST ${_target}) 10 | message(FATAL_ERROR "missing library ${_target}, please ``cmake install --component gdk-runtime") 11 | endif() 12 | endforeach() 13 | set(gdk_green_gdk_FOUND TRUE) 14 | endif() 15 | 16 | if("green_gdk_full" IN_LIST gdk_FIND_COMPONENTS) 17 | include("${GDK_LIB_DIR}/cmake/green_gdk_full-targets.cmake") 18 | foreach(_target IN LISTS _IMPORT_CHECK_FILES_FOR_gdk::green_gdk_full) 19 | if(NOT EXIST ${_target}) 20 | message(FATAL_ERROR "missing library ${_target}, please ``cmake install --component gdk-dev") 21 | endif() 22 | endforeach() 23 | set(gdk_green_gdk_full_FOUND TRUE) 24 | endif() 25 | set(gdk_COMPONENT_FOUND TRUE) 26 | check_required_components(gdk) 27 | -------------------------------------------------------------------------------- /docs/source/examples/get_subaccount_singlesig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "bip44_discovered": false, 10 | "core_descriptors": [ 11 | "sh(wpkh([386e8558/49'/1'/0']tpubDC2Q4xK4XH72GCMj4pLC95ZyDaset6YG6wtEpo6avjWg3uP25RskxXYt9WeNbCEWrd183N6hb5dGhsrsg9y8f9JFXx3VKTtxBmEpgLWMcHh/0/*))#fl5guxrs", 12 | "sh(wpkh([386e8558/49'/1'/0']tpubDC2Q4xK4XH72GCMj4pLC95ZyDaset6YG6wtEpo6avjWg3uP25RskxXYt9WeNbCEWrd183N6hb5dGhsrsg9y8f9JFXx3VKTtxBmEpgLWMcHh/1/*))#u767yek0" 13 | ], 14 | "hidden": false, 15 | "name": "Example subaccount name", 16 | "pointer": 0, 17 | "receiving_id": "", 18 | "required_ca": 0, 19 | "slip132_extended_pubkey": "upub5D9ydiUdMxX8SWbX7YzEJtx6NZLf4r4hoyjH84MnSod99KGdFEXywtudqrgq4yKWqo7oBMo9fzjaMqXa8CsrNzo9sLCutCnFndTUkZddR3v", 20 | "type": "p2sh-p2wpkh", 21 | "user_path": [ 22 | 2147483697, 23 | 2147483649, 24 | 2147483648 25 | ] 26 | } 27 | 28 | .. raw:: html 29 | 30 |
31 | 32 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gdk-rust" 3 | version = "0.1.0" 4 | authors = [ 5 | "Riccardo Casatta ", 6 | "Nadav Ivgi ", 7 | ] 8 | license = "(MIT)" 9 | edition = "2018" 10 | 11 | [lib] 12 | crate-type = ["staticlib"] 13 | 14 | 15 | [dependencies] 16 | gdk-common = { path = "../gdk_common" } 17 | gdk-electrum = { path = "../gdk_electrum", features = ["testing"] } 18 | gdk-registry = { path = "../gdk_registry" } 19 | libc = "0.2" 20 | serde = { version = "1.0", features = ["derive"] } 21 | serde_json = "1.0" 22 | thiserror = "1.0" 23 | 24 | [target.'cfg(target_os = "android")'.dependencies] 25 | android_logger = "0.8.6" 26 | 27 | [dev-dependencies] 28 | gdk-test = { path = "../gdk_test" } 29 | tempfile = "3.2.0" 30 | bitcoin = { version = "0.32", features = ["serde"] } 31 | elements = { version = "0.25", features = ["serde"] } 32 | # TODO: remove "legacy" feature when upgrading electrs binaries 33 | electrsd = { version = "0.29.0", features = ["legacy"] } 34 | env_logger = "0.10.0" 35 | base64 = "0.13" 36 | -------------------------------------------------------------------------------- /docs/source/examples/get_subaccount_singlesig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "bip44_discovered": false, 10 | "core_descriptors": [ 11 | "ct(slip77(55fa38cb2b21bcbb038260c045edbdad73d733114f44e598cadbf9d21599e959),elsh(wpkh([386e8558/49'/1'/0']tpubDC2Q4xK4XH72GCMj4pLC95ZyDaset6YG6wtEpo6avjWg3uP25RskxXYt9WeNbCEWrd183N6hb5dGhsrsg9y8f9JFXx3VKTtxBmEpgLWMcHh/0/*)))#kqd9xf5d", 12 | "ct(slip77(55fa38cb2b21bcbb038260c045edbdad73d733114f44e598cadbf9d21599e959),elsh(wpkh([386e8558/49'/1'/0']tpubDC2Q4xK4XH72GCMj4pLC95ZyDaset6YG6wtEpo6avjWg3uP25RskxXYt9WeNbCEWrd183N6hb5dGhsrsg9y8f9JFXx3VKTtxBmEpgLWMcHh/1/*)))#xx85kep5" 13 | ], 14 | "hidden": false, 15 | "name": "Example subaccount name", 16 | "pointer": 0, 17 | "receiving_id": "", 18 | "required_ca": 0, 19 | "type": "p2sh-p2wpkh", 20 | "user_path": [ 21 | 2147483697, 22 | 2147483649, 23 | 2147483648 24 | ] 25 | } 26 | 27 | .. raw:: html 28 | 29 |
30 | 31 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gdk-common" 3 | version = "0.1.0" 4 | authors = ["Riccardo Casatta ", "William Casarin "] 5 | edition = "2018" 6 | 7 | [features] 8 | testing = [] 9 | 10 | [dependencies] 11 | aes = "0.7.0" 12 | aes-gcm-siv = "0.10" 13 | bitcoin = { version = "0.32", features = ["serde"] } 14 | serde_cbor = "0.11.1" 15 | elements = { version = "0.25", features = ["serde"] } 16 | libc = "0.2" 17 | log = "0.4.8" 18 | miniscript = "12.2" 19 | once_cell = "1.12" 20 | electrum-client = { version = "0.21", default-features = false, features = [ "proxy", "use-openssl" ] } 21 | rand = "0.8" 22 | serde = { version = "1.0", features = ["derive"] } 23 | serde_json = "1.0" 24 | thiserror = "1.0" 25 | ureq = { version = "2.12", features = ["json", "socks-proxy", "gzip", "brotli"] } 26 | url = "2.2.2" 27 | elements-miniscript = "0.4.0" 28 | pbkdf2 = {version = "0.12"} 29 | sha2 = { version = "0.10"} 30 | 31 | [dev-dependencies] 32 | strum = "0.24" 33 | strum_macros = "0.24" 34 | tempfile = "3.2" 35 | bip39 = {version = "2.0"} 36 | -------------------------------------------------------------------------------- /docs/source/examples/get_receive_address_multisig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "address": "AzpsXif2CBq9WEtyZW5JR85LUEBXjvZXi2wx5EaKqXQ1cQh8Jo35fGva7MWcfQmkNZ3D2hZbXD3U16eF", 10 | "address_type": "csv", 11 | "blinding_key": "033c13b87298d77941d6e4ec5c754a03a41a7c48ad4196e1e97a734d8646daa231", 12 | "branch": 1, 13 | "is_confidential": true, 14 | "pointer": 1, 15 | "script": "748c6321023cebb0d3a3434d1df033c3c41e3d02f2e0b44a64c3d58519ca656b4f5363f591ad6703ffff00b275682102ea2fe5fcee6e1ada9ee3f4228ac1b83554cff618c8bc6ef64d9988e2f4bb13a1ac", 16 | "scriptpubkey": "a91469a22b9f6314c0fe6db92286592ec287ac52c03587", 17 | "service_xpub": "tpubEAUTpVqYYmDa5DQdXdJhaMyrvycVbpuCRdUTVifuG3ML5kbwujP3CdxGT1rVoDnFnxsxEv1aiVaEtuJzDBu1bNJk9mADeeR2rZ1HcCCzdyG", 18 | "subaccount": 0, 19 | "subtype": 65535, 20 | "unconfidential_address": "XLyn55q1TtektRH3YrDTT8vMTMkjrcT38u", 21 | "user_path": [ 22 | 1, 23 | 1 24 | ] 25 | } 26 | 27 | .. raw:: html 28 | 29 |
30 | 31 | -------------------------------------------------------------------------------- /src/threading.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_THREADING_HPP 2 | #define GDK_THREADING_HPP 3 | #pragma once 4 | 5 | #include "assertion.hpp" 6 | #include 7 | 8 | namespace green { 9 | 10 | // Scoped unlocker 11 | struct unique_unlock { 12 | explicit unique_unlock(std::unique_lock& locker) 13 | : m_locker(locker) 14 | { 15 | unlock(); 16 | } 17 | 18 | ~unique_unlock() { lock(); } 19 | 20 | unique_unlock(const unique_unlock&) = delete; 21 | unique_unlock(unique_unlock&&) = delete; 22 | unique_unlock& operator=(const unique_unlock&) = delete; 23 | unique_unlock& operator=(unique_unlock&&) = delete; 24 | 25 | private: 26 | void lock() 27 | { 28 | GDK_RUNTIME_ASSERT(!m_locker.owns_lock()); 29 | m_locker.lock(); 30 | } 31 | 32 | void unlock() 33 | { 34 | GDK_RUNTIME_ASSERT(m_locker.owns_lock()); 35 | m_locker.unlock(); 36 | } 37 | 38 | std::unique_lock& m_locker; 39 | }; 40 | 41 | } // namespace green 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/swig_python/pyproject.toml.in: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "green_gdk" 7 | description = "Blockstream Green Development Kit" 8 | readme = "README.md" 9 | authors = [{name = "Blockstream", email = "inquiries@blockstream.com"}] 10 | license = "MIT" 11 | classifiers = [ 12 | "Development Status :: 5 - Production/Stable", 13 | "Intended Audience :: Developers", 14 | "Topic :: Software Development :: Libraries", 15 | "Programming Language :: Python :: 3.5", 16 | "Programming Language :: Python :: 3.6", 17 | "Programming Language :: Python :: 3.7", 18 | "Programming Language :: Python :: 3.9", 19 | ] 20 | keywords = ["Bitcoin", "wallet", "library", "BIP32", "BIP38", "BIP39", "secp256k1"] 21 | version = "${PROJECT_VERSION}" 22 | dependencies = [] 23 | 24 | [project.urls] 25 | repository = "https://github.com/blockstream/gdk" 26 | documentation = "https://gdk.readthedocs.io/en/release_${PROJECT_VERSION}" 27 | tracker = "https://github.com/blockstream/gdk/issues" 28 | 29 | [tool.setuptools] 30 | zip-safe = false 31 | packages = ["green_gdk"] 32 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_common/src/be/blockhash.rs: -------------------------------------------------------------------------------- 1 | use bitcoin::{hashes::Hash, BlockHash}; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)] 5 | pub enum BEBlockHash { 6 | Bitcoin(bitcoin::BlockHash), 7 | Elements(elements::BlockHash), 8 | } 9 | 10 | impl BEBlockHash { 11 | pub fn into_bitcoin(&self) -> bitcoin::BlockHash { 12 | match self { 13 | Self::Bitcoin(h) => *h, 14 | Self::Elements(h) => bitcoin::BlockHash::from_raw_hash(h.to_raw_hash()), 15 | } 16 | } 17 | } 18 | 19 | impl ToString for BEBlockHash { 20 | fn to_string(&self) -> String { 21 | match self { 22 | Self::Bitcoin(blockhash) => blockhash.to_string(), 23 | Self::Elements(blockhash) => blockhash.to_string(), 24 | } 25 | } 26 | } 27 | 28 | // We must have a default for Store, so we use bitcoin::BlockHash which 29 | // will be replaced with the proper type after the first sync. 30 | impl Default for BEBlockHash { 31 | fn default() -> Self { 32 | Self::Bitcoin(BlockHash::all_zeros()) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | ** 2 | !./tools/buildbcur.sh 3 | !./tools/bc-ur.patch 4 | !./tools/buildboost.sh 5 | !./tools/builddeps.sh 6 | !./tools/buildlibwally-core.sh 7 | !./tools/buildsqlite3.sh 8 | !./tools/buildopenssl.sh 9 | !./tools/buildtinycbor.sh 10 | !./tools/buildtor.sh 11 | !./tools/zlib-1.3.patch 12 | !./tools/libevent-2.1.12.patch 13 | !./docker/android-bookworm/install_deps.sh 14 | !./docker/android/install_deps.sh 15 | !./docker/aws_lambda/install_deps.sh 16 | !./docker/debian/install_deps.sh 17 | !./docker/debian/install_rust_tools.sh 18 | !./docker/fedora/install_deps.sh 19 | !./docker/python/install_deps.sh 20 | !./docker/ubuntu-arm64/install_deps.sh 21 | !./docker/ubuntu/install_deps.sh 22 | !./tools/environment_setup.sh 23 | !./tools/requirements.txt 24 | !./cmake/profiles/ 25 | !./downloads/** 26 | !./downloads 27 | !./subprojects/gdk_rust/Cargo.* 28 | !./subprojects/gdk_rust/gdk_common/Cargo.* 29 | !./subprojects/gdk_rust/gdk_common/Cargo.* 30 | !./subprojects/gdk_rust/gdk_electrum/Cargo.* 31 | !./subprojects/gdk_rust/gdk_electrum/Cargo.* 32 | !./subprojects/gdk_rust/gdk_pin_client/Cargo.* 33 | !./subprojects/gdk_rust/gdk_registry/Cargo.* 34 | !./subprojects/gdk_rust/gdk_rust/Cargo.* 35 | -------------------------------------------------------------------------------- /docker/fedora/Dockerfile: -------------------------------------------------------------------------------- 1 | # Fedora image. Build with: 2 | # DOCKER_BUILDKIT=1 docker build . -t blockstream/gdk-fedora-builder -f docker/fedora/Dockerfile 3 | # 4 | FROM fedora:32@sha256:7afb459893c1c5defb714d7e0a2aae4a5c2a12f24aa5b26ff5f8f8e7dd8b2317 AS base 5 | WORKDIR /root 6 | COPY ./tools ./tools 7 | COPY ./cmake/profiles ./cmake/profiles 8 | # Optionally copy dependency sources from the build directory if present 9 | COPY ./downloads ./downloads 10 | COPY ./docker/fedora/install_deps.sh ./docker/fedora/install_deps.sh 11 | RUN ./docker/fedora/install_deps.sh 12 | 13 | FROM base AS buildergcc 14 | ENV GDK_KEEP_DOWNLOADS=1 15 | RUN mkdir -p /prebuild/gcc 16 | RUN ./tools/builddeps.sh --gcc --prefix /prebuild/gcc 17 | 18 | FROM base AS builderclang 19 | ENV GDK_KEEP_DOWNLOADS=1 20 | RUN mkdir -p /prebuild/clang 21 | RUN ./tools/builddeps.sh --clang --prefix /prebuild/clang 22 | 23 | FROM base AS final 24 | # Remove copied/downloaded dependency sources 25 | RUN rm -rf ./tools ./downloads ./cmake ./docker 26 | 27 | COPY --from=buildergcc /prebuild/gcc /prebuild/gcc 28 | COPY --from=builderclang /prebuild/clang /prebuild/clang 29 | 30 | RUN chmod +xr /root 31 | WORKDIR /root/gdk 32 | VOLUME /root/gdk 33 | -------------------------------------------------------------------------------- /docs/source/examples/get_transactions_output_singlesig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "address": "AzpjM6F3vhwPK3U5p8u79osjbhsduwdGCrbt1Cahy8nD3d7SbQJte99KiMkxWZLBrmUnWPrU3eLtUbVU", 10 | "address_type": "p2sh-p2wpkh", 11 | "amountblinder": "8efb0d0b21e6f14960f4c2affc166e50555f03bfc5ece3f2992b6ab4fd975caf", 12 | "asset_id": "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225", 13 | "assetblinder": "a986f588d8f05e337627bc780732efde594ad3cf32cb17e994dc7dcb25bc72fd", 14 | "blinding_key": "020de79e60d9d17b22c9f803455eb2fc48becc50fe76d32508bde357bf10c28a8a", 15 | "is_blinded": true, 16 | "is_confidential": true, 17 | "is_internal": false, 18 | "is_output": true, 19 | "is_relevant": true, 20 | "is_spent": false, 21 | "pointer": 1, 22 | "pt_idx": 1, 23 | "satoshi": 12340, 24 | "script": "a914007edc4b1153a320e490b5fe29a33e95af2d3c7387", 25 | "subaccount": 0, 26 | "subtype": 0, 27 | "unconfidential_address": "XBPrpZvDkTp1TY3kAhNtLBzo4Vycb9BsQt" 28 | } 29 | 30 | .. raw:: html 31 | 32 |
33 | 34 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_common/src/be/address.rs: -------------------------------------------------------------------------------- 1 | use super::BEScript; 2 | 3 | #[derive(Debug)] 4 | pub enum BEAddress { 5 | Bitcoin(bitcoin::Address), 6 | Elements(elements::Address), 7 | } 8 | 9 | impl BEAddress { 10 | pub fn script_pubkey(&self) -> BEScript { 11 | match self { 12 | BEAddress::Bitcoin(addr) => addr.script_pubkey().into(), 13 | BEAddress::Elements(addr) => addr.script_pubkey().into(), 14 | } 15 | } 16 | pub fn blinding_pubkey(&self) -> Option { 17 | match self { 18 | BEAddress::Bitcoin(_) => None, 19 | BEAddress::Elements(addr) => addr.blinding_pubkey, 20 | } 21 | } 22 | pub fn elements(&self) -> Option<&elements::Address> { 23 | match self { 24 | BEAddress::Bitcoin(_) => None, 25 | BEAddress::Elements(addr) => Some(addr), 26 | } 27 | } 28 | } 29 | 30 | impl ToString for BEAddress { 31 | fn to_string(&self) -> String { 32 | match self { 33 | BEAddress::Bitcoin(addr) => addr.to_string(), 34 | BEAddress::Elements(addr) => addr.to_string(), 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /cmake/modules/Findsqlite3.cmake: -------------------------------------------------------------------------------- 1 | # * Try to find the sqlite3 library 2 | # 3 | # optional hint: sqlite3_ROOT_DIR 4 | # 5 | # once done this will define 6 | # - sqlite3_FOUND 7 | # - sqlite3_INCLUDE_DIRS 8 | # - sqlite3_LINK_LIBRARIES 9 | # 10 | # and the imported target 11 | # - extern::sqlite3 12 | 13 | include(FindPackageHandleStandardArgs) 14 | 15 | set(sqlite3_ROOT_DIR 16 | "" 17 | CACHE PATH "Folder contains sqlite3 install dir" 18 | ) 19 | find_path(sqlite3_INCLUDE_DIR sqlite3.h PATHS ${sqlite3_ROOT_DIR}) 20 | find_library( 21 | sqlite3_LIBRARIES 22 | NAMES sqlite3 23 | PATHS ${sqlite3_ROOT_DIR}/lib NO_CMAKE_SYSTEM_PATH 24 | ) 25 | 26 | find_package_handle_standard_args(sqlite3 DEFAULT_MSG sqlite3_LIBRARIES sqlite3_INCLUDE_DIR) 27 | if(sqlite3_FOUND) 28 | set(sqlite3_LINK_LIBRARIES ${sqlite3_LIBRARIES}) 29 | set(sqlite3_INCLUDE_DIRS ${sqlite3_INCLUDE_DIR}) 30 | add_library(extern::sqlite3 STATIC IMPORTED) 31 | set_target_properties( 32 | extern::sqlite3 PROPERTIES IMPORTED_LOCATION ${sqlite3_LIBRARIES} INTERFACE_INCLUDE_DIRECTORIES 33 | ${sqlite3_INCLUDE_DIR} 34 | ) 35 | endif() 36 | -------------------------------------------------------------------------------- /src/io_runner.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_IO_RUNNER_HPP 2 | #define GDK_IO_RUNNER_HPP 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "utils.hpp" 13 | 14 | namespace green { 15 | 16 | class io_container { 17 | std::unique_ptr m_io; 18 | boost::asio::executor_work_guard m_work_guard; 19 | 20 | public: 21 | io_container(); 22 | ~io_container(); 23 | boost::asio::io_context& get_io_context(); 24 | void start(gsl::span pool); 25 | void shutdown(gsl::span pool) noexcept; 26 | }; 27 | 28 | template class io_runner { 29 | public: 30 | io_runner() { m_io.start(m_pool); } 31 | 32 | ~io_runner() { m_io.shutdown(m_pool); } 33 | boost::asio::io_context& get_io_context() { return m_io.get_io_context(); } 34 | 35 | private: 36 | io_container m_io; 37 | std::array m_pool; 38 | }; 39 | 40 | } // namespace green 41 | // 42 | #endif 43 | -------------------------------------------------------------------------------- /docker/ubuntu/Dockerfile: -------------------------------------------------------------------------------- 1 | # Ubuntu image. Build with: 2 | # DOCKER_BUILDKIT=1 docker build . -t blockstream/gdk-ubuntu-builder -f docker/ubuntu-arm64/Dockerfile 3 | # 4 | FROM ubuntu:20.04@sha256:3626dff0d616e8ee7065a9ac8c7117e904a4178725385910eeecd7f1872fc12d AS base 5 | WORKDIR /root 6 | COPY ./tools ./tools 7 | COPY ./cmake/profiles ./cmake/profiles 8 | # Optionally copy dependency sources from the build directory if present 9 | COPY ./downloads ./downloads 10 | COPY ./docker/ubuntu/install_deps.sh ./docker/ubuntu/install_deps.sh 11 | RUN ./docker/ubuntu/install_deps.sh 12 | 13 | FROM base AS buildergcc 14 | ENV GDK_KEEP_DOWNLOADS=1 15 | RUN mkdir -p /prebuild/gcc 16 | RUN ./tools/builddeps.sh --gcc --prefix /prebuild/gcc 17 | 18 | FROM base AS builderclang 19 | ENV GDK_KEEP_DOWNLOADS=1 20 | RUN mkdir -p /prebuild/clang 21 | RUN ./tools/builddeps.sh --clang --prefix /prebuild/clang 22 | 23 | FROM base AS final 24 | # Remove copied/downloaded dependency sources 25 | RUN rm -rf ./tools ./downloads ./cmake ./docker 26 | 27 | COPY --from=buildergcc /prebuild/gcc /prebuild/gcc 28 | COPY --from=builderclang /prebuild/clang /prebuild/clang 29 | 30 | RUN chmod +xr /root 31 | WORKDIR /root/gdk 32 | VOLUME /root/gdk 33 | -------------------------------------------------------------------------------- /cmake/profiles/iphoneos.cmake: -------------------------------------------------------------------------------- 1 | include (${CMAKE_CURRENT_LIST_DIR}/common.cmake) 2 | include (${CMAKE_CURRENT_LIST_DIR}/ios-helpers.cmake) 3 | 4 | 5 | ######## 6 | init_apple_environment() 7 | set(CMAKE_SYSTEM_NAME iOS) 8 | set(CMAKE_OSX_DEPLOYMENT_TARGET 13.00 CACHE INTERNAL "") 9 | set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE INTERNAL "") 10 | set(CMAKE_IOS_INSTALL_COMBINED FALSE) 11 | set(SDK_NAME iphoneos) 12 | set(CMAKE_C_COMPILER_TARGET arm64-apple-ios${CMAKE_OSX_DEPLOYMENT_TARGET}) 13 | set(CMAKE_CXX_COMPILER_TARGET arm64-apple-ios${CMAKE_OSX_DEPLOYMENT_TARGET}) 14 | set(CMAKE_LIBRARY_ARCHITECTURE arm64-apple-ios${CMAKE_OSX_DEPLOYMENT_TARGET}) 15 | execute_process(COMMAND xcodebuild -version -sdk iphone Path 16 | OUTPUT_VARIABLE CMAKE_OSX_SYSROOT 17 | OUTPUT_STRIP_TRAILING_WHITESPACE 18 | ERROR_VARIABLE _execError 19 | ERROR_QUIET 20 | ) 21 | if(_execError) 22 | message(FATAL_ERROR "seeking CMAKE_OSX_SYSROOT for iphone failed with error ${_execError}") 23 | endif() 24 | 25 | 26 | # Fix for PThread library not in path 27 | set(CMAKE_THREAD_LIBS_INIT "-lpthread") 28 | set(CMAKE_HAVE_THREADS_LIBRARY YES) 29 | set(CMAKE_USE_WIN32_THREADS_INIT NO) 30 | set(CMAKE_USE_PTHREADS_INIT YES) 31 | 32 | set(_rustTriple "aarch64-apple-ios") 33 | -------------------------------------------------------------------------------- /src/io_container.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "io_runner.hpp" 3 | 4 | namespace green { 5 | 6 | io_container::io_container() 7 | : m_io(std::make_unique()) 8 | , m_work_guard(boost::asio::make_work_guard(m_io->get_executor())) 9 | { 10 | } 11 | io_container::~io_container() { shutdown(gsl::span()); } 12 | 13 | boost::asio::io_context& io_container::get_io_context() { return *m_io; } 14 | void io_container::start(gsl::span pool) 15 | { 16 | auto thread_generator 17 | = [this]() { return std::thread([ioctx = std::ref(*this->m_io)]() { ioctx.get().run(); }); }; 18 | std::generate(pool.begin(), pool.end(), thread_generator); 19 | } 20 | void io_container::shutdown(gsl::span pool) noexcept 21 | { 22 | no_std_exception_escape([wg = std::ref(m_work_guard)] { wg.get().reset(); }, "io_context m_work_guard"); 23 | no_std_exception_escape( 24 | [pool = std::ref(pool)] { 25 | std::for_each(pool.get().begin(), pool.get().end(), [](auto& thread) { thread.join(); }); 26 | ; 27 | }, 28 | "io_context pool"); 29 | } 30 | 31 | } // namespace green 32 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_pin_client/src/pin.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | /// A PIN used to encrypt and decrypt 4 | #[derive(Clone, Serialize, Deserialize)] 5 | #[serde(transparent)] 6 | pub struct Pin { 7 | /// The PIN doesn't actually have to be a sequence of 6 digits, it can be 8 | /// of any length and can also contain alphanumeric characters. 9 | data: String, 10 | } 11 | 12 | impl std::fmt::Debug for Pin { 13 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 14 | f.debug_tuple("Pin").field(&self.data).finish() 15 | } 16 | } 17 | 18 | impl From<&str> for Pin { 19 | #[inline] 20 | fn from(s: &str) -> Self { 21 | s.to_owned().into() 22 | } 23 | } 24 | 25 | impl From for Pin { 26 | #[inline] 27 | fn from(s: String) -> Self { 28 | Self { 29 | data: s, 30 | } 31 | } 32 | } 33 | 34 | impl std::str::FromStr for Pin { 35 | type Err = std::convert::Infallible; 36 | 37 | #[inline] 38 | fn from_str(s: &str) -> Result { 39 | Ok(s.into()) 40 | } 41 | } 42 | 43 | impl Pin { 44 | #[inline] 45 | pub(crate) fn as_bytes(&self) -> &[u8] { 46 | self.data.as_bytes() 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /cmake/modules/Findtor.cmake: -------------------------------------------------------------------------------- 1 | # * Try to find the tor library 2 | # 3 | # optional hint: tor_ROOT_DIR 4 | # 5 | # once done this will define 6 | # - tor_FOUND 7 | # - tor_INCLUDE_DIRS 8 | # - tor_LINK_LIBRARIES 9 | # 10 | # and the imported target 11 | # - extern::tor 12 | 13 | include(FindPackageHandleStandardArgs) 14 | 15 | set(tor_ROOT_DIR 16 | "" 17 | CACHE PATH "Folder contains tor install dir" 18 | ) 19 | find_path(tor_INCLUDE_DIR tor_api.h PATHS ${tor_ROOT_DIR}) 20 | find_library( 21 | tor_LIBRARIES 22 | NAMES tor 23 | PATHS ${tor_ROOT_DIR}/lib 24 | ) 25 | 26 | find_package_handle_standard_args(tor DEFAULT_MSG tor_LIBRARIES tor_INCLUDE_DIR) 27 | if(tor_FOUND) 28 | set(tor_LINK_LIBRARIES ${tor_LIBRARIES}) 29 | set(tor_INCLUDE_DIRS ${tor_INCLUDE_DIR}) 30 | add_library(extern::tor STATIC IMPORTED) 31 | set_target_properties( 32 | extern::tor PROPERTIES IMPORTED_LOCATION ${tor_LIBRARIES} INTERFACE_INCLUDE_DIRECTORIES ${tor_INCLUDE_DIR} 33 | ) 34 | 35 | target_link_libraries( 36 | extern::tor INTERFACE libevent::extra $<$:ssp> $<$:iphlpapi> 37 | $<$:shlwapi> $ 38 | ) 39 | 40 | endif() 41 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_electrum/src/headers/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::error::Error; 2 | use crate::headers::bitcoin::HeadersChain; 3 | use crate::headers::liquid::Verifier; 4 | use electrum_client::GetMerkleRes; 5 | use gdk_common::bitcoin::hashes::{sha256d, Hash}; 6 | use gdk_common::electrum_client; 7 | use std::io::Write; 8 | 9 | pub mod bitcoin; 10 | pub mod liquid; 11 | 12 | pub enum ChainOrVerifier { 13 | /// used for bitcoin networks 14 | Chain(HeadersChain), 15 | 16 | /// used for elements networks 17 | Verifier(Verifier), 18 | } 19 | 20 | /// compute the merkle root from the merkle path of a tx in electrum format (note the hash.reverse()) 21 | fn compute_merkle_root(txid: [u8; 32], merkle: GetMerkleRes) -> Result<[u8; 32], Error> { 22 | let mut pos = merkle.pos; 23 | let mut current = txid; 24 | 25 | for mut hash in merkle.merkle { 26 | let mut engine = sha256d::Hash::engine(); 27 | hash.reverse(); 28 | if pos % 2 == 0 { 29 | engine.write(¤t)?; 30 | engine.write(&hash)?; 31 | } else { 32 | engine.write(&hash)?; 33 | engine.write(¤t)?; 34 | } 35 | current = sha256d::Hash::from_engine(engine).to_byte_array(); 36 | pos /= 2; 37 | } 38 | 39 | Ok(current) 40 | } 41 | -------------------------------------------------------------------------------- /src/swift/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(NOT APPLE) 2 | message("not on apple, skipping swift bindings") 3 | return() 4 | endif() 5 | 6 | if(NOT ENABLE_SWIFT) 7 | message("swift build disabled, skipping") 8 | return() 9 | endif() 10 | 11 | find_program(SWIFT "swift") 12 | if(SWIFT-NOTFOUND) 13 | message("swift exec not found, skipping swift bindings") 14 | return() 15 | endif() 16 | 17 | join_path(_packagePath ${CMAKE_CURRENT_LIST_DIR} "GreenGDK") 18 | get_target_property(_gdkSrcPath green_gdk SOURCE_DIR) 19 | join_path(_gdkIncPath ${CMAKE_SOURCE_DIR} "include") 20 | get_target_property(_gdkBinPath green_gdk BINARY_DIR) 21 | 22 | add_custom_command(OUTPUT GreenGDK.swiftmodule 23 | COMMAND ${SWIFT} build --package-path ${_packagePath} 24 | --build-path ${CMAKE_CURRENT_BINARY_DIR} 25 | -Xswiftc -I${_gdkSrcPath} 26 | -Xswiftc -I${_gdkIncPath} 27 | -Xswiftc -I${_gdkBinPath} 28 | -Xswiftc -L${_gdkBinPath} 29 | -Xswiftc -I${wallycore_INCLUDE_DIRS} 30 | DEPENDS green_gdk_full 31 | ) 32 | add_custom_target(swift-cmd ALL 33 | DEPENDS GreenGDK.swiftmodule 34 | ) 35 | INSTALL( 36 | FILES 37 | GreenGDK/Sources/GreenGDK/GreenGDK.swift 38 | DESTINATION 39 | ${CMAKE_INSTALL_DATADIR}/gdk/ 40 | COMPONENT 41 | gdk-dev 42 | ) 43 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_common/src/password.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | // This doesn't do validation, but we could? 4 | #[derive(Clone)] 5 | pub struct Password(String); 6 | 7 | impl Password { 8 | // to_string would display REDACTED from the Display trait 9 | pub fn get_password_str(self) -> String { 10 | self.0 11 | } 12 | } 13 | 14 | impl serde::ser::Serialize for Password { 15 | fn serialize(&self, serializer: S) -> Result 16 | where 17 | S: serde::Serializer, 18 | { 19 | serializer.serialize_str("Password(REDACTED)") 20 | } 21 | } 22 | 23 | impl fmt::Debug for Password { 24 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 25 | write!(f, "Password(REDACTED)") 26 | } 27 | } 28 | 29 | impl fmt::Display for Password { 30 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 31 | fmt::Debug::fmt(self, f) 32 | } 33 | } 34 | 35 | impl From for Password { 36 | fn from(s: String) -> Self { 37 | Password(s) 38 | } 39 | } 40 | 41 | #[test] 42 | fn password_show_redacted() { 43 | let mnemonic = Password("secret sauce".into()); 44 | let format = format!("{}", mnemonic); 45 | 46 | assert_eq!(format, "Password(REDACTED)"); 47 | assert_eq!(mnemonic.get_password_str(), "secret sauce"); 48 | } 49 | -------------------------------------------------------------------------------- /docs/source/examples/get_previous_addresses_singlesig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "list": [ 10 | { 11 | "address": "2MsHqxhz5fHt2QyvE8TgT1MvzDY9kdMH5Rz", 12 | "address_type": "p2sh-p2wpkh", 13 | "is_internal": false, 14 | "pointer": 1, 15 | "script": "a914007edc4b1153a320e490b5fe29a33e95af2d3c7387", 16 | "scriptpubkey": "a914007edc4b1153a320e490b5fe29a33e95af2d3c7387", 17 | "subaccount": 0, 18 | "tx_count": 0, 19 | "user_path": [ 20 | 2147483697, 21 | 2147483649, 22 | 2147483648, 23 | 0, 24 | 1 25 | ] 26 | }, 27 | { 28 | "address": "2N4uHLYgfrtRTPQYJe8DHT69WgsUTYe6WSo", 29 | "address_type": "p2sh-p2wpkh", 30 | "is_internal": false, 31 | "pointer": 0, 32 | "script": "a9147fdbfc6f9f1ecd1d66f43a586af08330a73e3cf487", 33 | "scriptpubkey": "a9147fdbfc6f9f1ecd1d66f43a586af08330a73e3cf487", 34 | "subaccount": 0, 35 | "tx_count": 0, 36 | "user_path": [ 37 | 2147483697, 38 | 2147483649, 39 | 2147483648, 40 | 0, 41 | 0 42 | ] 43 | } 44 | ] 45 | } 46 | 47 | .. raw:: html 48 | 49 |
50 | 51 | -------------------------------------------------------------------------------- /src/swap_auth_handlers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_SWAP_AUTH_HANDLERS_HPP 2 | #define GDK_SWAP_AUTH_HANDLERS_HPP 3 | #pragma once 4 | 5 | #include "auth_handler.hpp" 6 | 7 | namespace green { 8 | 9 | class Tx; 10 | 11 | class create_swap_transaction_call : public auth_handler_impl { 12 | public: 13 | create_swap_transaction_call(session& session, const nlohmann::json& details); 14 | 15 | private: 16 | state_type call_impl() override; 17 | void on_next_handler_complete(auth_handler* next_handler) override; 18 | 19 | state_type liquidex_impl(); 20 | 21 | nlohmann::json m_details; 22 | nlohmann::json m_receive_address; 23 | nlohmann::json m_create_details; 24 | bool m_is_signed; 25 | }; 26 | 27 | class complete_swap_transaction_call : public auth_handler_impl { 28 | public: 29 | complete_swap_transaction_call(session& session, const nlohmann::json& details); 30 | 31 | private: 32 | state_type call_impl() override; 33 | void on_next_handler_complete(auth_handler* next_handler) override; 34 | 35 | state_type liquidex_impl(); 36 | 37 | nlohmann::json m_details; 38 | nlohmann::json m_receive_address; 39 | nlohmann::json m_create_details; 40 | std::unique_ptr m_tx; 41 | }; 42 | 43 | } // namespace green 44 | #endif // GDK_SWAP_AUTH_HANDLERS_HPP 45 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_common/src/be/outpoint.rs: -------------------------------------------------------------------------------- 1 | use super::BETxid; 2 | 3 | #[derive(Debug, PartialEq, Eq, Hash, Clone)] 4 | pub enum BEOutPoint { 5 | Bitcoin(bitcoin::OutPoint), 6 | Elements(elements::OutPoint), 7 | } 8 | 9 | impl From for BEOutPoint { 10 | fn from(o: bitcoin::OutPoint) -> Self { 11 | BEOutPoint::new_bitcoin(o.txid, o.vout) 12 | } 13 | } 14 | 15 | impl From for BEOutPoint { 16 | fn from(o: elements::OutPoint) -> Self { 17 | BEOutPoint::new_elements(o.txid, o.vout) 18 | } 19 | } 20 | 21 | impl BEOutPoint { 22 | pub fn new_bitcoin(txid: bitcoin::Txid, vout: u32) -> Self { 23 | BEOutPoint::Bitcoin(bitcoin::OutPoint { 24 | txid, 25 | vout, 26 | }) 27 | } 28 | 29 | pub fn new_elements(txid: elements::Txid, vout: u32) -> Self { 30 | BEOutPoint::Elements(elements::OutPoint { 31 | txid, 32 | vout, 33 | }) 34 | } 35 | 36 | pub fn txid(&self) -> BETxid { 37 | match self { 38 | Self::Bitcoin(outpoint) => outpoint.txid.into(), 39 | Self::Elements(outpoint) => outpoint.txid.into(), 40 | } 41 | } 42 | 43 | pub fn vout(&self) -> u32 { 44 | match self { 45 | Self::Bitcoin(outpoint) => outpoint.vout, 46 | Self::Elements(outpoint) => outpoint.vout, 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/swig_python/setup.py.in: -------------------------------------------------------------------------------- 1 | """setuptools config for gdk """ 2 | 3 | from setuptools import Extension, setup 4 | 5 | 6 | extra_objects = [ 7 | "${CMAKE_BINARY_DIR}/src/libgreen_gdk.a", 8 | "@_gdk_rust_LINK_LIBRARIES@", 9 | "@wallycore_LINK_LIBRARIES@", 10 | "@libsecp256k1_LINK_LIBRARIES@", 11 | "@sqlite3_LINK_LIBRARIES@", 12 | "@tor_LINK_LIBRARIES@", 13 | "@_libevent_core_LINK_LIBRARIES@", 14 | "@_libevent_extra_LINK_LIBRARIES@", 15 | "@_libevent_pthreads_LINK_LIBRARIES@", 16 | "@Boost_LIBRARY_DIRS@/libboost_log.a", 17 | "@Boost_LIBRARY_DIRS@/libboost_filesystem.a", 18 | "@Boost_LIBRARY_DIRS@/libboost_chrono.a", 19 | "@Boost_LIBRARY_DIRS@/libboost_date_time.a", 20 | "@Boost_LIBRARY_DIRS@/libboost_system.a", 21 | "@Boost_LIBRARY_DIRS@/libboost_thread.a", 22 | "@bcur_LINK_LIBRARIES@", 23 | "@URC_LINK_LIBRARIES@", 24 | "@TinyCBOR_LINK_LIBRARIES@", 25 | "@OPENSSL_SSL_LIBRARY@", 26 | "@OPENSSL_CRYPTO_LIBRARY@", 27 | "@ZLIB_LIBRARIES@", 28 | ] 29 | 30 | 31 | setup( 32 | ext_modules=[Extension( 33 | name="green_gdk._green_gdk", 34 | sources=["swig_green_gdk.i"], 35 | include_dirs=["${CMAKE_BINARY_DIR}/src", "${CMAKE_SOURCE_DIR}/include"], 36 | swig_opts=["-threads", "-I${CMAKE_SOURCE_DIR}/include", "-DGDK_API= "], 37 | extra_objects=extra_objects, 38 | extra_link_args=["-shared"], 39 | language="c++", 40 | )], 41 | ) 42 | -------------------------------------------------------------------------------- /docs/source/examples/get_transactions_output_multisig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "address": "AzpsXif2CBq9WEtyZW5JR85LUEBXjvZXi2wx5EaKqXQ1cQh8Jo35fGva7MWcfQmkNZ3D2hZbXD3U16eF", 10 | "address_type": "csv", 11 | "amountblinder": "337fbb7a7c554a1a11a1fd58524a650811e6a2e655966e5e8870c6aa5bc220c3", 12 | "asset_id": "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225", 13 | "asset_tag": "0aec3e557312bbe41d1ead85eb9e2a741965f5fb7426a398c882c8bb9b6eb0a1d9", 14 | "assetblinder": "0ea4abfc0c7c36929a6d051d9694ac58a5c57a571af89bf34337a02e29552b7a", 15 | "blinding_key": "033c13b87298d77941d6e4ec5c754a03a41a7c48ad4196e1e97a734d8646daa231", 16 | "commitment": "09f9d304ce60ad52731ea60b64e069623c4df719062cc49f8d3a9e3ca06ef411b2", 17 | "is_blinded": true, 18 | "is_confidential": true, 19 | "is_internal": false, 20 | "is_output": true, 21 | "is_relevant": true, 22 | "is_spent": false, 23 | "nonce_commitment": "03b4ff371f4545ba5f1f9b58c6fea3ea99939c86f206ca594277a8d24d2d7333ed", 24 | "pointer": 1, 25 | "pt_idx": 0, 26 | "satoshi": 12340, 27 | "script": "a91469a22b9f6314c0fe6db92286592ec287ac52c03587", 28 | "subaccount": 0, 29 | "subtype": 65535, 30 | "unconfidential_address": "XLyn55q1TtektRH3YrDTT8vMTMkjrcT38u" 31 | } 32 | 33 | .. raw:: html 34 | 35 |
36 | 37 | -------------------------------------------------------------------------------- /src/swig_python/mac-setup.py.in: -------------------------------------------------------------------------------- 1 | """setuptools config for gdk """ 2 | 3 | from setuptools import Extension, setup 4 | 5 | 6 | extra_objects = [ 7 | "${CMAKE_BINARY_DIR}/src/libgreen_gdk.a", 8 | "@_gdk_rust_LINK_LIBRARIES@", 9 | "@wallycore_LINK_LIBRARIES@", 10 | "@libsecp256k1_LINK_LIBRARIES@", 11 | "@sqlite3_LINK_LIBRARIES@", 12 | "@tor_LINK_LIBRARIES@", 13 | "@_libevent_core_LINK_LIBRARIES@", 14 | "@_libevent_extra_LINK_LIBRARIES@", 15 | "@_libevent_pthreads_LINK_LIBRARIES@", 16 | "@Boost_LIBRARY_DIRS@/libboost_log.a", 17 | "@Boost_LIBRARY_DIRS@/libboost_filesystem.a", 18 | "@Boost_LIBRARY_DIRS@/libboost_chrono.a", 19 | "@Boost_LIBRARY_DIRS@/libboost_date_time.a", 20 | "@Boost_LIBRARY_DIRS@/libboost_system.a", 21 | "@Boost_LIBRARY_DIRS@/libboost_thread.a", 22 | "@bcur_LINK_LIBRARIES@", 23 | "@URC_LINK_LIBRARIES@", 24 | "@TinyCBOR_LINK_LIBRARIES@", 25 | "@OPENSSL_SSL_LIBRARY@", 26 | "@OPENSSL_CRYPTO_LIBRARY@", 27 | "@ZLIB_LIBRARIES@", 28 | "${Python_LIBRARIES}", 29 | ] 30 | 31 | 32 | setup( 33 | ext_modules=[Extension( 34 | name="green_gdk._green_gdk", 35 | sources=["swig_green_gdk.i"], 36 | include_dirs=["${CMAKE_BINARY_DIR}/src", "${CMAKE_SOURCE_DIR}/include"], 37 | swig_opts=["-threads", "-I${CMAKE_SOURCE_DIR}/include", "-DGDK_API="], 38 | extra_objects=extra_objects, 39 | extra_link_args=["-framework", "Security"], 40 | language="c++", 41 | )], 42 | ) 43 | -------------------------------------------------------------------------------- /docs/source/examples/get_twofactor_config_all_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example (all two-factor methods enabled) 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "all_methods": [ 10 | "email", 11 | "sms", 12 | "phone", 13 | "gauth" 14 | ], 15 | "any_enabled": true, 16 | "email": { 17 | "confirmed": true, 18 | "data": "sa***@my***", 19 | "enabled": true 20 | }, 21 | "enabled_methods": [ 22 | "email", 23 | "sms", 24 | "phone", 25 | "gauth", 26 | "telegram" 27 | ], 28 | "gauth": { 29 | "confirmed": true, 30 | "data": "***", 31 | "enabled": true 32 | }, 33 | "limits": { 34 | "bits": "0.00", 35 | "btc": "0.00000000", 36 | "fiat": "0.00", 37 | "fiat_currency": "USD", 38 | "fiat_rate": "1.10000000", 39 | "is_current": true, 40 | "is_fiat": false, 41 | "mbtc": "0.00000", 42 | "satoshi": 0, 43 | "sats": "0", 44 | "ubtc": "0.00" 45 | }, 46 | "phone": { 47 | "confirmed": true, 48 | "data": "*** *** *89", 49 | "enabled": true 50 | }, 51 | "sms": { 52 | "confirmed": true, 53 | "data": "*** *** *89", 54 | "enabled": true 55 | }, 56 | "twofactor_reset": { 57 | "days_remaining": -1, 58 | "is_active": false, 59 | "is_disputed": false 60 | } 61 | } 62 | 63 | .. raw:: html 64 | 65 |
66 | 67 | -------------------------------------------------------------------------------- /cmake/profiles/iphonesimulator.cmake: -------------------------------------------------------------------------------- 1 | include (${CMAKE_CURRENT_LIST_DIR}/common.cmake) 2 | include (${CMAKE_CURRENT_LIST_DIR}/ios-helpers.cmake) 3 | 4 | 5 | ######## 6 | init_apple_environment() 7 | set(CMAKE_SYSTEM_NAME iOS) 8 | set(CMAKE_OSX_DEPLOYMENT_TARGET 13.00 CACHE INTERNAL "") 9 | set(CMAKE_OSX_ARCHITECTURES ${CMAKE_HOST_SYSTEM_PROCESSOR} CACHE INTERNAL "") 10 | set(CMAKE_IOS_INSTALL_COMBINED FALSE) 11 | set(SDK_NAME iphonesimulator) 12 | set(CMAKE_C_COMPILER_TARGET ${CMAKE_HOST_SYSTEM_PROCESSOR}-apple-ios${CMAKE_OSX_DEPLOYMENT_TARGET}-simulator) 13 | set(CMAKE_CXX_COMPILER_TARGET ${CMAKE_HOST_SYSTEM_PROCESSOR}-apple-ios${CMAKE_OSX_DEPLOYMENT_TARGET}-simulator) 14 | set(CMAKE_LIBRARY_ARCHITECTURE ${CMAKE_HOST_SYSTEM_PROCESSOR}-apple-ios${CMAKE_OSX_DEPLOYMENT_TARGET}) 15 | execute_process(COMMAND xcodebuild -version -sdk iphonesimulator Path 16 | OUTPUT_VARIABLE CMAKE_OSX_SYSROOT 17 | OUTPUT_STRIP_TRAILING_WHITESPACE 18 | ERROR_VARIABLE _execError 19 | ERROR_QUIET 20 | ) 21 | if(_execError) 22 | message(FATAL_ERROR "seeking CMAKE_OSX_SYSROOT for iphonesimulator failed with error ${_execError}") 23 | endif() 24 | 25 | 26 | # Fix for PThread library not in path 27 | set(CMAKE_THREAD_LIBS_INIT "-lpthread") 28 | set(CMAKE_HAVE_THREADS_LIBRARY YES) 29 | set(CMAKE_USE_WIN32_THREADS_INIT NO) 30 | set(CMAKE_USE_PTHREADS_INIT YES) 31 | 32 | if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64") 33 | set(_rustTriple "aarch64-apple-ios-sim") 34 | else() 35 | set(_rustTriple "x86_64-apple-ios") 36 | endif() 37 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_electrum/scripts/update-server-list.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eo pipefail 3 | set -x 4 | 5 | (command -v gpg && command -v curl && command -v jq) > /dev/null \ 6 | || { echo >&2 "This script requires gpg, curl and jq"; exit 1; } 7 | 8 | # ThomasV's release signing key 9 | PGPID=6694D8DE7BE8EE5631BED9502BD5824B7F9470E6 10 | gpg --list-keys $PGPID > /dev/null || gpg --keyserver keyserver.ubuntu.com --recv-keys $PGPID 11 | 12 | # Grab the latest release and verify it 13 | version=`curl -s 'https://download.electrum.org/?C=M;O=D' | grep -o -E 'alt="\[DIR\]"> $target/servers-mainnet.txt 31 | serverlist servers_testnet.json > $target/servers-testnet.txt 32 | 33 | rm -r $dir 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Except where noted in an individual source file, for sub-projects under the 2 | subprojects/ directory, and noted below, this code is covered by the following 3 | (BSD-MIT) license: 4 | 5 | Copyright (c) Blockstream, Inc 2019 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | 25 | 26 | This product includes software developed by the OpenSSL Project for use in the 27 | OpenSSL Toolkit. (http://www.openssl.org/). 28 | 29 | This product includes cryptographic software written by Eric Young 30 | (eay@cryptsoft.com). 31 | -------------------------------------------------------------------------------- /docs/source/examples/get_twofactor_config_none_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example (no two-factor methods enabled) 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "all_methods": [ 10 | "email", 11 | "sms", 12 | "phone", 13 | "gauth", 14 | "telegram" 15 | ], 16 | "any_enabled": false, 17 | "email": { 18 | "confirmed": false, 19 | "data": "", 20 | "enabled": false 21 | }, 22 | "enabled_methods": [], 23 | "gauth": { 24 | "confirmed": false, 25 | "data": "otpauth://totp/Green%20Testnet%20Dev?secret=MKPZQAYYAPZ6UGMIZSISDCPZK2ML6MNS", 26 | "enabled": false 27 | }, 28 | "limits": { 29 | "bits": "0.00", 30 | "btc": "0.00000000", 31 | "fiat": "0.00", 32 | "fiat_currency": "USD", 33 | "fiat_rate": "1.10000000", 34 | "is_current": true, 35 | "is_fiat": false, 36 | "mbtc": "0.00000", 37 | "satoshi": 0, 38 | "sats": "0", 39 | "ubtc": "0.00" 40 | }, 41 | "phone": { 42 | "confirmed": false, 43 | "data": "", 44 | "enabled": false 45 | }, 46 | "sms": { 47 | "confirmed": false, 48 | "data": "", 49 | "enabled": false 50 | }, 51 | "telegram": { 52 | "confirmed": false, 53 | "data": "", 54 | "enabled": false 55 | }, 56 | "twofactor_reset": { 57 | "days_remaining": -1, 58 | "is_active": false, 59 | "is_disputed": false 60 | } 61 | } 62 | 63 | .. raw:: html 64 | 65 |
66 | 67 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_rust.h: -------------------------------------------------------------------------------- 1 | #ifndef GDK_GDK_RUST_H 2 | #define GDK_GDK_RUST_H 3 | #pragma once 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | /** A notification handler */ 10 | typedef void (*GDKRUST_notification_handler)(void *self_context, char *details); 11 | 12 | /** 13 | * Create a new session. 14 | * 15 | * :param session: Destination for the resulting session. 16 | *| Returned session should be freed using `GDKRUST_destroy_session`. 17 | */ 18 | int GDKRUST_create_session(void* session, const char* network); 19 | 20 | int GDKRUST_call_session(void* session, const char *method, const char *input, char** output); 21 | 22 | /** 23 | * A collection of stateless functions 24 | * 25 | * :param method: The function name. 26 | * :param input: The json input to pass to the function. 27 | * :param output: The json output, should be freed using `GDKRUST_destroy_string`. 28 | */ 29 | int GDKRUST_call(const char *method, const char *input, char** output); 30 | 31 | /** 32 | * Set a handler to be called when notifications arrive. 33 | */ 34 | int GDKRUST_set_notification_handler(void* session, GDKRUST_notification_handler handler, void *self_context); 35 | 36 | /** 37 | * Free a string returned by the api. 38 | * 39 | * :param str: The string to free. 40 | */ 41 | void GDKRUST_destroy_string(char* str); 42 | 43 | /** 44 | * Free a session created by the api. 45 | * 46 | * :param session: The session to free. 47 | */ 48 | void GDKRUST_destroy_session(void* session); 49 | 50 | #ifdef __cplusplus 51 | } /* extern "C" */ 52 | #endif 53 | 54 | #endif /* GDK_GDK_RUST_H */ 55 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_registry/src/file.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::io::{self, BufReader, BufWriter, Seek}; 3 | 4 | use gdk_common::log::{info, log_enabled, Level}; 5 | use serde::{de::DeserializeOwned, Serialize}; 6 | 7 | use crate::Result; 8 | 9 | pub(crate) fn read(file: &mut File) -> Result { 10 | file.seek(io::SeekFrom::Start(0))?; 11 | if log_enabled!(Level::Info) { 12 | info!("file {:?} size {}", &file, file.metadata()?.len()); 13 | } 14 | let buffered = BufReader::new(file); 15 | Ok(gdk_common::serde_cbor::from_reader(buffered)?) 16 | } 17 | 18 | pub(crate) fn write(value: &V, file: &mut File) -> Result<()> { 19 | // Empty the file before writing to avoid having leftover trailing bytes if 20 | // the new contents are shorter than the old ones (e.g. old file was 21 | // `foobar`, we write `baz`, new contents should be `baz` and not 22 | // `bazbar`). 23 | file.set_len(0)?; 24 | 25 | file.seek(std::io::SeekFrom::Start(0))?; 26 | let buffered = BufWriter::new(file); 27 | Ok(gdk_common::serde_cbor::to_writer(buffered, value)?) 28 | } 29 | 30 | #[cfg(test)] 31 | mod test { 32 | use super::*; 33 | use serde_json::Value; 34 | 35 | #[test] 36 | fn test_roundtrip() { 37 | let mut tempfile = tempfile::tempfile().unwrap(); 38 | let content = Value::String(format!("{:?}", (1..100).collect::>())); 39 | write(&content, &mut tempfile).unwrap(); 40 | let value = read::(&mut tempfile).unwrap(); 41 | assert_eq!(content, value, "roundtrip failing"); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/autobahn_wrapper.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_AUTOBAHN_WRAPPER_HPP 2 | #define GDK_AUTOBAHN_WRAPPER_HPP 3 | #pragma once 4 | 5 | #ifdef __ANDROID__ 6 | #include 7 | #undef EPOLL_CLOEXEC 8 | #endif 9 | 10 | #if __clang__ 11 | #pragma clang diagnostic push 12 | #if !defined __APPLE__ && __clang_major__ >= 6 13 | #pragma clang diagnostic ignored "-Wenum-compare" 14 | #endif 15 | #pragma clang diagnostic ignored "-Wunknown-warning-option" 16 | #pragma clang diagnostic ignored "-Wignored-qualifiers" 17 | #pragma clang diagnostic ignored "-Wnon-virtual-dtor" 18 | #pragma clang diagnostic ignored "-Wunused-parameter" 19 | #pragma clang diagnostic ignored "-Wnull-pointer-subtraction" 20 | #pragma clang diagnostic ignored "-Wdeprecated-copy" 21 | #endif 22 | 23 | #pragma GCC diagnostic push 24 | #pragma GCC diagnostic ignored "-Wattributes" 25 | #pragma GCC diagnostic ignored "-Wignored-qualifiers" 26 | #pragma GCC diagnostic ignored "-Wparentheses" 27 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 28 | #pragma GCC diagnostic ignored "-Wunused-parameter" 29 | #if __GNUC__ > 7 30 | #pragma GCC diagnostic ignored "-Wclass-memaccess" 31 | #endif 32 | #if __GNUC__ >= 9 33 | #pragma GCC diagnostic ignored "-Wdeprecated-copy" 34 | #endif 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #pragma GCC diagnostic pop 42 | 43 | #if __clang__ 44 | #pragma clang diagnostic pop 45 | #endif 46 | 47 | #include 48 | #include 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_rust/src/error.rs: -------------------------------------------------------------------------------- 1 | use gdk_common::error::Error as CommonError; 2 | use gdk_common::exchange_rates; 3 | use gdk_common::model::ExchangeRateError; 4 | use gdk_common::ureq; 5 | use gdk_electrum as electrum; 6 | 7 | #[derive(thiserror::Error, Debug)] 8 | pub enum Error { 9 | #[error("{0}")] 10 | Other(String), 11 | 12 | #[error(transparent)] 13 | JsonFrom(#[from] serde_json::Error), 14 | 15 | #[error(transparent)] 16 | Electrum(#[from] electrum::error::Error), 17 | 18 | #[error(transparent)] 19 | Rates(#[from] ExchangeRateError), 20 | 21 | #[error(transparent)] 22 | Common(#[from] CommonError), 23 | 24 | #[error(transparent)] 25 | Registry(#[from] gdk_registry::Error), 26 | 27 | #[error( 28 | "{}method not found: {method:?}", 29 | if *.in_session { "session " } else {""} 30 | )] 31 | MethodNotFound { 32 | method: String, 33 | in_session: bool, 34 | }, 35 | 36 | #[error("The {0} currency pair is not currently supported")] 37 | UnsupportedCurrencyPair(exchange_rates::Pair), 38 | 39 | #[error(transparent)] 40 | Io(#[from] std::io::Error), 41 | 42 | #[error(transparent)] 43 | Ureq(#[from] ureq::Error), 44 | } 45 | 46 | impl Error { 47 | /// Convert the error to a GDK-compatible code. 48 | pub fn to_gdk_code(&self) -> String { 49 | match self { 50 | Error::Electrum(err) => err.to_gdk_code(), 51 | _ => "id_unknown".to_string(), 52 | } 53 | } 54 | } 55 | 56 | impl From for Error { 57 | fn from(e: String) -> Error { 58 | Error::Other(e) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/ga_tor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_GA_TOR_HPP 2 | #define GDK_GA_TOR_HPP 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace green { 12 | 13 | static constexpr uint32_t DEFAULT_TOR_SOCKS_WAIT = 120; // maximum timeout for the tor socks to get ready 14 | 15 | struct tor_bootstrap_phase { 16 | tor_bootstrap_phase(); 17 | tor_bootstrap_phase(const tor_bootstrap_phase&) = delete; 18 | tor_bootstrap_phase& operator=(const tor_bootstrap_phase&) = delete; 19 | tor_bootstrap_phase(tor_bootstrap_phase&&) = default; 20 | tor_bootstrap_phase& operator=(tor_bootstrap_phase&&) = default; 21 | 22 | void clear(); 23 | 24 | std::string tag; 25 | std::string summary; 26 | std::string control_port; 27 | uint32_t progress; 28 | }; 29 | 30 | struct tor_controller_impl; 31 | 32 | struct tor_controller { 33 | tor_controller(); 34 | ~tor_controller(); 35 | 36 | void sleep(); 37 | void wakeup(); 38 | 39 | static std::shared_ptr get_shared_ref(); 40 | 41 | std::string wait_for_socks5(std::function)> phase_cb, 42 | uint32_t timeout = DEFAULT_TOR_SOCKS_WAIT); 43 | 44 | private: 45 | static std::mutex s_inst_mutex; 46 | static std::weak_ptr s_inst; 47 | std::unique_ptr m_ctrl; 48 | std::mutex m_ctrl_mutex; 49 | 50 | std::string m_socks5_port; 51 | }; 52 | 53 | } // namespace green 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_pin_client/src/error.rs: -------------------------------------------------------------------------------- 1 | use bitcoin; 2 | use thiserror::Error as ThisError; 3 | 4 | #[derive(Debug, ThisError)] 5 | pub enum Error { 6 | #[error(transparent)] 7 | BitcoinHexToBytesError(#[from] bitcoin::hashes::hex::HexToBytesError), 8 | 9 | #[error("Invalid HMAC")] 10 | InvalidHmac, 11 | 12 | #[error("Couldn't decrypt data: {0}")] 13 | Decryption(#[from] block_modes::BlockModeError), 14 | 15 | #[error("Failed handshake with PIN server")] 16 | HandshakeFailed, 17 | 18 | #[error(transparent)] 19 | Json(#[from] serde_json::Error), 20 | 21 | #[error("The PIN is not valid")] 22 | InvalidPin, 23 | 24 | #[error("Received an invalid response from the PIN server")] 25 | InvalidResponse, 26 | 27 | #[error(transparent)] 28 | Secp256k1(#[from] bitcoin::secp256k1::Error), 29 | 30 | #[error("Failed calling the PIN server")] 31 | ServerCallFailed, 32 | } 33 | 34 | // Implementing `PartialEq` by hand because `serde_json::Error` and 35 | // `block_modes::BlockModeError` don't implement this trait. 36 | impl PartialEq for Error { 37 | #[inline] 38 | fn eq(&self, other: &Self) -> bool { 39 | match (self, other) { 40 | (Self::BitcoinHexToBytesError(a), Self::BitcoinHexToBytesError(b)) => a == b, 41 | 42 | (Self::Secp256k1(a), Self::Secp256k1(b)) => a == b, 43 | 44 | (Self::HandshakeFailed, Self::HandshakeFailed) 45 | | (Self::InvalidPin, Self::InvalidPin) 46 | | (Self::InvalidResponse, Self::InvalidResponse) 47 | | (Self::ServerCallFailed, Self::ServerCallFailed) => true, 48 | 49 | _ => false, 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #test json 2 | add_executable(test_json test_json.cpp) 3 | target_include_directories(test_json PRIVATE ${CMAKE_SOURCE_DIR}) 4 | target_link_libraries(test_json PRIVATE green_gdk nlohmann_json::nlohmann_json) 5 | 6 | # test networks 7 | add_executable(test_networks test_networks.cpp) 8 | target_include_directories(test_networks PRIVATE ${CMAKE_SOURCE_DIR}) 9 | target_link_libraries(test_networks PRIVATE green_gdk nlohmann_json::nlohmann_json) 10 | 11 | # test session 12 | add_executable(test_session test_session.cpp) 13 | target_include_directories(test_session PRIVATE ${CMAKE_SOURCE_DIR}) 14 | target_link_libraries(test_session PRIVATE green_gdk nlohmann_json::nlohmann_json) 15 | 16 | # test multisession 17 | add_executable(test_multi_session test_multi_session.cpp) 18 | target_include_directories(test_multi_session PRIVATE ${CMAKE_SOURCE_DIR}) 19 | target_link_libraries(test_multi_session PRIVATE green_gdk nlohmann_json::nlohmann_json pthread) 20 | 21 | # test aes gcm 22 | add_executable(test_aes_gcm test_aes_gcm.cpp) 23 | target_include_directories(test_aes_gcm PRIVATE ${CMAKE_SOURCE_DIR}) 24 | target_link_libraries(test_aes_gcm PRIVATE green_gdk nlohmann_json::nlohmann_json) 25 | 26 | # test gdk commit 27 | add_executable(test_gdk_commit test_gdk_commit.cpp) 28 | get_target_property(ga_build_dir green_gdk BINARY_DIR) 29 | get_target_property(ga_src_dir green_gdk SOURCE_DIR) 30 | target_include_directories(test_gdk_commit PRIVATE ${ga_build_dir} ${ga_src_dir}) 31 | target_link_libraries(test_gdk_commit PRIVATE green_gdk) 32 | 33 | add_test(NAME test_json COMMAND test_json) 34 | add_test(NAME test_networks COMMAND test_networks) 35 | add_test(NAME test_gdk_commit COMMAND test_gdk_commit) 36 | -------------------------------------------------------------------------------- /docs/source/examples/get_unspent_outputs_multisig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "unspent_outputs": { 10 | "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225": [ 11 | { 12 | "address_type": "csv", 13 | "amountblinder": "337fbb7a7c554a1a11a1fd58524a650811e6a2e655966e5e8870c6aa5bc220c3", 14 | "asset_id": "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225", 15 | "asset_tag": "0aec3e557312bbe41d1ead85eb9e2a741965f5fb7426a398c882c8bb9b6eb0a1d9", 16 | "assetblinder": "0ea4abfc0c7c36929a6d051d9694ac58a5c57a571af89bf34337a02e29552b7a", 17 | "block_height": 0, 18 | "commitment": "09f9d304ce60ad52731ea60b64e069623c4df719062cc49f8d3a9e3ca06ef411b2", 19 | "is_blinded": true, 20 | "is_confidential": false, 21 | "is_internal": false, 22 | "nonce_commitment": "03b4ff371f4545ba5f1f9b58c6fea3ea99939c86f206ca594277a8d24d2d7333ed", 23 | "pointer": 1, 24 | "prevout_script": "748c6321023cebb0d3a3434d1df033c3c41e3d02f2e0b44a64c3d58519ca656b4f5363f591ad6703ffff00b275682102ea2fe5fcee6e1ada9ee3f4228ac1b83554cff618c8bc6ef64d9988e2f4bb13a1ac", 25 | "pt_idx": 0, 26 | "satoshi": 12340, 27 | "script": "a91469a22b9f6314c0fe6db92286592ec287ac52c03587", 28 | "subaccount": 0, 29 | "subtype": 65535, 30 | "txhash": "46dd2e84591e3a27c85d3ead917a1469dd09458fb1d76bce6b58885bf5d6ebbc", 31 | "user_status": 0 32 | } 33 | ] 34 | } 35 | } 36 | 37 | .. raw:: html 38 | 39 |
40 | 41 | -------------------------------------------------------------------------------- /gitlab/android.yml: -------------------------------------------------------------------------------- 1 | 2 | include: 3 | - local: "gitlab/common.yml" 4 | 5 | 6 | build-android: 7 | extends: .android-image 8 | stage: build 9 | variables: 10 | INSTALL_PATH: "gdk-android-jni" 11 | parallel: 12 | matrix: 13 | - PLATFORM: [android] 14 | ARCH: [armeabi-v7a, arm64-v8a, x86, x86_64] 15 | script: 16 | - ./tools/build.sh --ndk $ARCH --buildtype release --no-deps-rebuild --external-deps-dir /prebuild/$PLATFORM-$ARCH --parallel 16 --install $INSTALL_PATH 17 | artifacts: 18 | name: "$CI_JOB_NAME-$CI_COMMIT_SHORT_SHA" 19 | expire_in: 1 day 20 | when: on_success 21 | paths: 22 | - $INSTALL_PATH 23 | 24 | 25 | release-android: 26 | tags: 27 | - garelease 28 | stage: release 29 | needs: [ build-android ] 30 | script: 31 | - mkdir gdk-android-symbols 32 | - mkdir -p gdk_dist/ 33 | - find gdk-android-jni -name "*.syms" -type f -exec cp --parents {} gdk-android-symbols \; 34 | - tar -czf gdk_dist/gdk-android-symbols.tar.gz gdk-android-symbols --remove-files 35 | - find gdk-android-jni -name "*.a" -type f -delete 36 | - find gdk-android-jni -name "*.syms" -type f -delete 37 | - tar -czf gdk_dist/gdk-android-jni.tar.gz gdk-android-jni --remove-files 38 | - cd gdk_dist 39 | - /opt/process_release 40 | artifacts: 41 | name: "android-$CI_PROJECT_NAME-$CI_COMMIT_SHORT_SHA" 42 | expire_in: 3 days 43 | paths: 44 | - $CI_PROJECT_DIR/gdk_dist 45 | when: on_success 46 | 47 | 48 | upload-android-gcloud: 49 | extends: .gcloud-publish 50 | needs: [ release-android ] 51 | script: 52 | - url=${GCLOUD_URL}/${subfolder}/android 53 | - echo ${url} 54 | - gsutil cp -r $CI_PROJECT_DIR/gdk_dist/* ${url} 55 | -------------------------------------------------------------------------------- /docs/source/examples/get_previous_addresses_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "list": [ 10 | { 11 | "address": "2N5oBDdNp9i3dyYXCEfimg4YE1d9hcWYc2T", 12 | "address_type": "csv", 13 | "branch": 1, 14 | "pointer": 2, 15 | "script": "210251b4473cc52200be514994986927632cfe04b2fbe6fba1a69a0ea835dc1fe2cead210325d8aed10e04b73aab80b9e738e3f3933d49de0238a4ff0a3395cd7f3e5ba65fac73640380ca00b268", 16 | "scriptpubkey": "a91489ac8209bdfdd8229d3123215e5eac3f859a6e4f87", 17 | "service_xpub": "tpubEAUTpVqYYmDa5DQdXdJhaMyrvycVbpuCRdUTVifuG3ML5kbwujP3CdxGT1rVoDnFnxsxEv1aiVaEtuJzDBu1bNJk9mADeeR2rZ1HcCCzdyG", 18 | "subaccount": 0, 19 | "subtype": 51840, 20 | "tx_count": 0, 21 | "user_path": [ 22 | 1, 23 | 2 24 | ] 25 | }, 26 | { 27 | "address": "2N2zyKJEcAtqgHRdYFqCQDKZozDi5GY9wi5", 28 | "address_type": "csv", 29 | "branch": 1, 30 | "pointer": 1, 31 | "script": "2102ea2fe5fcee6e1ada9ee3f4228ac1b83554cff618c8bc6ef64d9988e2f4bb13a1ad21023cebb0d3a3434d1df033c3c41e3d02f2e0b44a64c3d58519ca656b4f5363f591ac73640380ca00b268", 32 | "scriptpubkey": "a9146aff2fc8f5ec359f809b3355d6bdc5d30f8e105487", 33 | "service_xpub": "tpubEAUTpVqYYmDa5DQdXdJhaMyrvycVbpuCRdUTVifuG3ML5kbwujP3CdxGT1rVoDnFnxsxEv1aiVaEtuJzDBu1bNJk9mADeeR2rZ1HcCCzdyG", 34 | "subaccount": 0, 35 | "subtype": 51840, 36 | "tx_count": 0, 37 | "user_path": [ 38 | 1, 39 | 1 40 | ] 41 | } 42 | ] 43 | } 44 | 45 | .. raw:: html 46 | 47 |
48 | 49 | -------------------------------------------------------------------------------- /docs/source/examples/get_unspent_outputs_singlesig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "unspent_outputs": { 10 | "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225": [ 11 | { 12 | "address_type": "p2sh-p2wpkh", 13 | "amountblinder": "8efb0d0b21e6f14960f4c2affc166e50555f03bfc5ece3f2992b6ab4fd975caf", 14 | "asset_id": "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225", 15 | "asset_tag": "0a552d971ca55f71e25de1f4961f0646445ec7233f060af79db1ed5d1b7944adc1", 16 | "assetblinder": "a986f588d8f05e337627bc780732efde594ad3cf32cb17e994dc7dcb25bc72fd", 17 | "block_height": 0, 18 | "commitment": "091a8f5a5542d635303eaa52cf6ed0cf32d084be85fe292266427dfb7e97277111", 19 | "is_blinded": true, 20 | "is_confidential": false, 21 | "is_internal": false, 22 | "nonce_commitment": "026500ef0c14658df948d9f99d76c37724377f9f66860c2d3b67bc47be4e763a3f", 23 | "pointer": 1, 24 | "prevout_script": "76a9144d2af219985cd7e523cf1be0421636fe4f38f4b788ac", 25 | "pt_idx": 1, 26 | "public_key": "030e18cc1d6474e092264aa44e7b81ce1068f2b12ec748c96f217d8de5cb2555dc", 27 | "satoshi": 12340, 28 | "subaccount": 0, 29 | "txhash": "eea0ccc14f823dfcf6afcaf9f57db43aac294d675dd19bb3b563fc11ee169864", 30 | "user_path": [ 31 | 2147483697, 32 | 2147483649, 33 | 2147483648, 34 | 0, 35 | 1 36 | ] 37 | } 38 | ] 39 | } 40 | } 41 | 42 | .. raw:: html 43 | 44 |
45 | 46 | -------------------------------------------------------------------------------- /src/exception.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_EXCEPTION_HPP 2 | #define GDK_EXCEPTION_HPP 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | namespace autobahn { 9 | class call_error; 10 | } 11 | 12 | namespace green { 13 | 14 | class login_error : public std::runtime_error { 15 | public: 16 | explicit login_error(const std::string& what) 17 | : std::runtime_error(what) 18 | { 19 | } 20 | }; 21 | 22 | class connection_error : public std::runtime_error { 23 | public: 24 | connection_error(const char* what_str) 25 | : std::runtime_error(what_str) 26 | { 27 | } 28 | }; 29 | 30 | class reconnect_error : public connection_error { 31 | public: 32 | reconnect_error() 33 | : connection_error("reconnect required") 34 | { 35 | } 36 | }; 37 | 38 | class timeout_error : public connection_error { 39 | public: 40 | timeout_error() 41 | : connection_error("timeout error") 42 | { 43 | } 44 | }; 45 | 46 | class assertion_error : public std::runtime_error { 47 | public: 48 | explicit assertion_error(const std::string& what) 49 | : std::runtime_error(what) 50 | { 51 | } 52 | }; 53 | 54 | class user_error : public std::runtime_error { 55 | public: 56 | explicit user_error(const std::string& what) 57 | : std::runtime_error(what) 58 | { 59 | } 60 | }; 61 | 62 | std::pair get_error_details(const autobahn::call_error& e); 63 | std::pair remap_ga_server_error(const std::pair& details); 64 | 65 | } // namespace green 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /docs/source/examples/get_available_currencies_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "all": [ 10 | "AUD", 11 | "BRL", 12 | "CAD", 13 | "CHF", 14 | "CNY", 15 | "CZK", 16 | "DKK", 17 | "EUR", 18 | "GBP", 19 | "HKD", 20 | "IDR", 21 | "ILS", 22 | "INR", 23 | "JPY", 24 | "MXN", 25 | "MYR", 26 | "NGN", 27 | "NOK", 28 | "NZD", 29 | "PLN", 30 | "RUB", 31 | "SEK", 32 | "SGD", 33 | "THB", 34 | "TRY", 35 | "USD", 36 | "VND", 37 | "ZAR" 38 | ], 39 | "per_exchange": { 40 | "BITFINEX": [ 41 | "USD" 42 | ], 43 | "BITSTAMP": [ 44 | "USD" 45 | ], 46 | "BULLBITCOIN": [ 47 | "CAD" 48 | ], 49 | "COINGECKO": [ 50 | "AUD", 51 | "BRL", 52 | "CAD", 53 | "CHF", 54 | "CNY", 55 | "CZK", 56 | "DKK", 57 | "EUR", 58 | "GBP", 59 | "HKD", 60 | "IDR", 61 | "ILS", 62 | "INR", 63 | "JPY", 64 | "MXN", 65 | "MYR", 66 | "NGN", 67 | "NOK", 68 | "NZD", 69 | "PLN", 70 | "RUB", 71 | "SEK", 72 | "SGD", 73 | "THB", 74 | "TRY", 75 | "USD", 76 | "VND", 77 | "ZAR" 78 | ], 79 | "KIWICOIN": [ 80 | "NZD" 81 | ], 82 | "KRAKEN": [ 83 | "EUR", 84 | "USD" 85 | ], 86 | "LUNO": [ 87 | "IDR", 88 | "MYR", 89 | "NGN", 90 | "ZAR" 91 | ] 92 | } 93 | } 94 | 95 | .. raw:: html 96 | 97 |
98 | -------------------------------------------------------------------------------- /docs/source/examples/get_available_currencies_singlesig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "all": [ 10 | "CZK", 11 | "EUR", 12 | "AUD", 13 | "HKD", 14 | "MXN", 15 | "NGN", 16 | "CAD", 17 | "THB", 18 | "TRY", 19 | "IDR", 20 | "JPY", 21 | "VND", 22 | "SEK", 23 | "CHF", 24 | "INR", 25 | "USD", 26 | "BRL", 27 | "DKK", 28 | "GBP", 29 | "RUB", 30 | "NZD", 31 | "SGD", 32 | "ZAR", 33 | "MYR", 34 | "CNY", 35 | "NOK", 36 | "PLN", 37 | "ILS" 38 | ], 39 | "per_exchange": { 40 | "BITFINEX": [ 41 | "USD" 42 | ], 43 | "BITSTAMP": [ 44 | "USD" 45 | ], 46 | "BULLBITCOIN": [ 47 | "CAD" 48 | ], 49 | "COINGECKO": [ 50 | "AUD", 51 | "BRL", 52 | "CAD", 53 | "CHF", 54 | "CNY", 55 | "CZK", 56 | "DKK", 57 | "EUR", 58 | "GBP", 59 | "HKD", 60 | "IDR", 61 | "ILS", 62 | "INR", 63 | "JPY", 64 | "MXN", 65 | "MYR", 66 | "NGN", 67 | "NOK", 68 | "NZD", 69 | "PLN", 70 | "RUB", 71 | "SEK", 72 | "SGD", 73 | "THB", 74 | "TRY", 75 | "USD", 76 | "VND", 77 | "ZAR" 78 | ], 79 | "KIWICOIN": [ 80 | "NZD" 81 | ], 82 | "KRAKEN": [ 83 | "EUR", 84 | "USD" 85 | ], 86 | "LUNO": [ 87 | "IDR", 88 | "MYR", 89 | "NGN", 90 | "ZAR" 91 | ] 92 | } 93 | } 94 | 95 | .. raw:: html 96 | 97 |
98 | -------------------------------------------------------------------------------- /docker/aws_lambda/Dockerfile: -------------------------------------------------------------------------------- 1 | # AWS lambda deployments. 2 | # These use a custom Amazon Linux distro based on Fedora. 3 | # This example is for the Python 3.10 image, adjust as needed. 4 | # Build with: 5 | # DOCKER_BUILDKIT=1 docker build . -t blockstream/gdk-aws-lambda-builder -f docker/aws_lambda/Dockerfile 6 | # 7 | # Once the image is built, you can build gdk inside of it with: 8 | # $ git clone git clone https://github.com/Blockstream/gdk.git 9 | # $ cd gdk 10 | # $ ./tools/build.sh --gcc --python-version=3.10 --external-deps-dir=/prebuild/gcc --no-deps-rebuild 11 | # $ The resulting wheel file will be in build-gcc/src/swig_python/green_gdk/dist/ 12 | # 13 | FROM public.ecr.aws/lambda/python:3.10@sha256:c13bdddd001502be3ac79c3a80937332c998c96cb1894fe936f311b443eb6443 AS base 14 | 15 | WORKDIR /root 16 | COPY ./tools ./tools 17 | COPY ./cmake/profiles ./cmake/profiles 18 | # Optionally copy dependency sources from the build directory if present 19 | COPY ./downloads ./downloads 20 | COPY ./docker/aws_lambda/install_deps.sh ./docker/aws_lambda/install_deps.sh 21 | RUN ./docker/aws_lambda/install_deps.sh 22 | 23 | FROM base AS builderaws 24 | ENV GDK_KEEP_DOWNLOADS=1 25 | RUN mkdir -p /prebuild/gcc 26 | RUN ./tools/builddeps.sh --gcc --prefix /prebuild/gcc 27 | 28 | FROM base AS final 29 | # Remove copied/downloaded dependency sources 30 | RUN rm -rf ./tools ./downloads ./cmake ./docker 31 | 32 | COPY --from=builderaws /prebuild/gcc /prebuild/gcc 33 | 34 | RUN chmod +xr /root 35 | WORKDIR /root/gdk 36 | VOLUME /root/gdk 37 | 38 | # The following line allows the image to be used in CI configurations, but will 39 | # cause the resulting image to not work in the lambda environment. This 40 | # Dockerfile is for creating an image to build gdk with, not for deploying! 41 | ENTRYPOINT ["/bin/bash", "-l", "-c"] 42 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_registry/src/data/test/extra_assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "223465c803ae336c62180e52d94ee80d80828db54df9bedbb9860060f49de2eb":{ 3 | "asset_id":"123465c803ae336c62180e52d94ee80d80828db54df9bedbb9860060f49de2eb", 4 | "contract":{"entity":{"domain":"scamcoinbot.com"},"issuer_pubkey":"035d0f7b0207d9cc68870abfef621692bce082084ed3ca0c1ae432dd12d889be01","name":"Scamcoinbot token","nonce":"57258","precision":0,"ticker":"SCAM","version":0}, 5 | "issuance_txin":{"txid":"27e6bd36daef786775768a6b106053d0f2f10e03b6f278715931caa00662138d","vin":0}, 6 | "issuance_prevout":{"txid":"fc2535f2e4fc2ef1d19b832248e3edc2c3f4c4e3ee9c2bc51777bd738a6f9582","vout":10}, 7 | "name":"Scamcoinbot token", 8 | "ticker":"SCAM", 9 | "precision":0, 10 | "entity":{"domain":"scamcoinbot.com"}, 11 | "version":0, 12 | "issuer_pubkey":"035d0f7b0207d9cc68870abfef621692bce082084ed3ca0c1ae432dd12d889be01" 13 | }, 14 | "5d4354944366ea1e33f27c37fec97504025d6062c551208f68597d1ed40ec53e":{ 15 | "asset_id":"4d4354944366ea1e33f27c37fec97504025d6062c551208f68597d1ed40ec53e", 16 | "contract":{"entity":{"domain":"magicalcryptofriends.com"},"issuer_pubkey":"02d2b29fe8ffef6acb5e75d0cd7f9c55d502bd876434b87c39ae209fc57c57f52a","name":"Magical Crypto Token","nonce":"13158145","precision":0,"ticker":"MCT","version":0}, 17 | "issuance_txin":{"txid":"d535ded7ce07a0bb9c61d0fefff8127da3fc4833302b05e2b8a0cf9e04446af1","vin":0}, 18 | "issuance_prevout":{"txid":"839e819d74ac98110fce63a3dab3a1075bbddcad811e0e125641989581919ab0","vout":1}, 19 | "name":"Magical Crypto Token", 20 | "ticker":"MCT", 21 | "precision":0, 22 | "entity":{"domain":"magicalcryptofriends.com"}, 23 | "version":0, 24 | "issuer_pubkey":"02d2b29fe8ffef6acb5e75d0cd7f9c55d502bd876434b87c39ae209fc57c57f52a" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tools/archiver.sh.gen: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | sqlite3=$ 5 | gdk_rust=$ 6 | wally=$ 7 | secp256k1=$ 8 | libevent_core=$ 9 | libevent_extra=$ 10 | libeventpthreads=$<$:$> 11 | boost_log=$ 12 | boost_chrono=$ 13 | boost_filesystem=$ 14 | boost_date_time=$ 15 | boost_system=$ 16 | boost_thread=$ 17 | openssl_ssl=$ 18 | openssl_crypto=$ 19 | zlib=$ 20 | tor=$ 21 | bc_ur=$ 22 | tinycbor=$ 23 | urc=$ 24 | 25 | 26 | libraries="libgreen_gdk_partial.a $gdk_rust $sqlite3 $wally $secp256k1 $libevent_core $libevent_extra $libeventpthreads $boost_log $boost_log $boost_filesystem $boost_chrono $boost_date_time $boost_system $boost_thread $openssl_ssl $openssl_crypto $zlib $tor $bc_ur $tinycbor $urc" 27 | 28 | 29 | if [ "$(uname)" = "Darwin" ]; then 30 | libtool -static -o $ $libraries 31 | exit 0 32 | fi 33 | 34 | echo "create $" > libgreen_gdk.mri 35 | for lib in $libraries; do 36 | if [ ! -d "$obj_dir" ]; then 37 | echo "addlib $lib" >> libgreen_gdk.mri 38 | fi 39 | done 40 | echo "save" >> libgreen_gdk.mri 41 | echo "end" >> libgreen_gdk.mri 42 | ar -M < libgreen_gdk.mri 43 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_common/src/session.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | use serde_json::Value; 4 | 5 | use crate::{ 6 | exchange_rates::ExchangeRatesCacher, 7 | notification::{NativeNotif, NativeType}, 8 | NetworkParameters, 9 | }; 10 | 11 | pub trait Session: Sized + ExchangeRatesCacher { 12 | fn new(network_parameters: NetworkParameters) -> Result; 13 | fn handle_call(&mut self, method: &str, params: Value) -> Result; 14 | fn native_notification(&mut self) -> &mut NativeNotif; 15 | fn network_parameters(&self) -> &NetworkParameters; 16 | 17 | fn build_request_agent(&self) -> Result; 18 | 19 | fn set_native_notification(&mut self, native_type: NativeType) { 20 | self.native_notification().set_native(native_type) 21 | } 22 | 23 | fn is_mainnet(&self) -> bool { 24 | self.network_parameters().mainnet 25 | } 26 | } 27 | 28 | #[derive(serde::Serialize, Debug)] 29 | pub struct JsonError { 30 | pub message: String, 31 | pub error: String, 32 | } 33 | 34 | impl fmt::Display for JsonError { 35 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 36 | fmt::Debug::fmt(self, f) 37 | } 38 | } 39 | 40 | impl std::error::Error for JsonError {} 41 | 42 | impl JsonError { 43 | pub fn new>(message: S) -> Self { 44 | JsonError { 45 | message: message.into(), 46 | error: "id_unknown".to_string(), 47 | } 48 | } 49 | } 50 | 51 | impl From for JsonError { 52 | fn from(e: serde_json::Error) -> Self { 53 | JsonError::new(e.to_string()) 54 | } 55 | } 56 | 57 | impl From for Value { 58 | fn from(e: JsonError) -> Self { 59 | serde_json::to_value(&e).expect("standard serialize without maps") 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /docs/source/examples/get_previous_addresses_singlesig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "list": [ 10 | { 11 | "address": "AzpjM6F3vhwPK3U5p8u79osjbhsduwdGCrbt1Cahy8nD3d7SbQJte99KiMkxWZLBrmUnWPrU3eLtUbVU", 12 | "address_type": "p2sh-p2wpkh", 13 | "blinding_key": "020de79e60d9d17b22c9f803455eb2fc48becc50fe76d32508bde357bf10c28a8a", 14 | "is_confidential": true, 15 | "is_internal": false, 16 | "pointer": 1, 17 | "script": "a914007edc4b1153a320e490b5fe29a33e95af2d3c7387", 18 | "scriptpubkey": "a914007edc4b1153a320e490b5fe29a33e95af2d3c7387", 19 | "subaccount": 0, 20 | "tx_count": 0, 21 | "unconfidential_address": "XBPrpZvDkTp1TY3kAhNtLBzo4Vycb9BsQt", 22 | "user_path": [ 23 | 2147483697, 24 | 2147483649, 25 | 2147483648, 26 | 0, 27 | 1 28 | ] 29 | }, 30 | { 31 | "address": "AzprjS3xmCowJRJrZQtqufRjLtsHztgVAAE3Z2ChTLrDb8jWEK3RX2yWLZnFZyvDHfYJVqtaMhQYfyCE", 32 | "address_type": "p2sh-p2wpkh", 33 | "blinding_key": "031e9bdbe8710e94a18193f91a5bb9f22e13f84581a7b6d51db340b421907ee546", 34 | "is_confidential": true, 35 | "is_internal": false, 36 | "pointer": 0, 37 | "script": "a9147fdbfc6f9f1ecd1d66f43a586af08330a73e3cf487", 38 | "scriptpubkey": "a9147fdbfc6f9f1ecd1d66f43a586af08330a73e3cf487", 39 | "subaccount": 0, 40 | "tx_count": 0, 41 | "unconfidential_address": "XP1JCQcox4MSRxfpgMuimvDKXqJKWSxxWv", 42 | "user_path": [ 43 | 2147483697, 44 | 2147483649, 45 | 2147483648, 46 | 0, 47 | 0 48 | ] 49 | } 50 | ] 51 | } 52 | 53 | .. raw:: html 54 | 55 |
56 | 57 | -------------------------------------------------------------------------------- /tools/buildlibwally-core.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | cd ${WALLYCORE_SRCDIR} 5 | rm -rf src/secp256k1 6 | git clone ${SECP_URL} src/secp256k1 7 | cd src/secp256k1 8 | git checkout ${SECP_COMMIT} 9 | cd ${WALLYCORE_SRCDIR} 10 | touch .${SECP_COMMIT} 11 | 12 | ./tools/cleanup.sh 13 | ./tools/autogen.sh 14 | 15 | ${SED} -i 's/\"wallycore\"/\"green_gdk\"/' src/swig_java/swig.i 16 | 17 | CONFIGURE_ARGS="--prefix=${GDK_BUILD_ROOT} --enable-static --disable-shared --disable-tests --disable-swig-python" 18 | 19 | if [ "${BUILDTYPE}" = "debug" ]; then 20 | CONFIGURE_ARGS+=" --enable-debug" 21 | fi 22 | 23 | case ${target_triple} in 24 | *-apple-ios | *-apple-iossimulator) 25 | CONFIGURE_ARGS+=" --disable-swig-java --with-sysroot=${SDK_SYSROOT} --host=${target_triple} --build=${host_triple}" 26 | ;; 27 | 28 | *-linux-android) 29 | CONFIGURE_ARGS+=" --with-sysroot=${SDK_SYSROOT} --enable-swig-java --host=${target_triple} --build=${host_triple}" 30 | ;; 31 | 32 | *-w64-mingw32) 33 | CONFIGURE_ARGS+=" --disable-swig-java --host=${target_triple} --build=${host_triple}" 34 | ;; 35 | *-apple-darwin) 36 | CFLAGS+=" -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin" 37 | ;& 38 | *) 39 | if [ -n "${JAVA_HOME}" ]; then 40 | CONFIGURE_ARGS+=" --enable-swig-java" 41 | else 42 | CONFIGURE_ARGS+=" --disable-swig-java" 43 | fi 44 | ;; 45 | esac 46 | 47 | 48 | ./configure ${CONFIGURE_ARGS} 49 | make clean -k || echo >/dev/null 50 | make -j${NUM_JOBS} 51 | make -o configure install -j${NUM_JOBS} 52 | 53 | 54 | # FIXME: work around wally not installing its Java wrapper 55 | java_wally="src/swig_java/src/com/blockstream/libwally/Wally.java" 56 | if [[ -f ${java_wally} ]]; then 57 | dest_dir="${GDK_BUILD_ROOT}/share/java/com/blockstream/libwally" 58 | mkdir -p ${dest_dir} 59 | cp ${java_wally} ${dest_dir} 60 | fi 61 | -------------------------------------------------------------------------------- /cmake/profiles/android-helpers.cmake: -------------------------------------------------------------------------------- 1 | 2 | if( CMAKE_BUILD_TYPE STREQUAL "Debug") 3 | add_compile_options("-ggdb3" "-fno-omit-frame-pointer") 4 | endif() 5 | 6 | macro(initialize_android_environment) 7 | if(NOT ANDROID_ABI OR NOT ANDROID_PLATFORM) 8 | message(FATAL_ERROR "please, when including this file, be sure you have previously declared $ANDROID_ABI and $ANDROID_PLATFORM") 9 | endif() 10 | 11 | # unfortunately we can't apply what's described in 12 | #https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-android-with-the-ndk 13 | # as our cmake is lagging behind and it thus expects an android ndk file layout that no longer applies to latest ANDROID_NDKs 14 | set(ANDROID_NDK $ENV{ANDROID_NDK}) 15 | set(ANDROID_LD "lld") 16 | set(ANDROID_STL "c++_static") 17 | if(CMAKE_VERSION VERSION_LESS 3.19) 18 | set(ANDROID_USE_LEGACY_TOOLCHAIN_FILE TRUE) 19 | else() 20 | set(ANDROID_USE_LEGACY_TOOLCHAIN_FILE FALSE) 21 | endif() 22 | include(${ANDROID_NDK}/build/cmake/android.toolchain.cmake) 23 | # allow cmake to search outside of NDK sysroot 24 | # https://gitlab.kitware.com/cmake/cmake/-/issues/22183 25 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) 26 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) 27 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) 28 | 29 | # it's weird but it's necessary... can probably be removed when ANDROID_USE_LEGACY_TOOLCHAIN_FILE == False 30 | if(CMAKE_BUILD_TYPE STREQUAL Release AND ANDROID_USE_LEGACY_TOOLCHAIN_FILE) 31 | string(REPLACE "-g" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) 32 | string(REPLACE "-g" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) 33 | string(REPLACE "-g" "" CMAKE_ASM_FLAGS ${CMAKE_ASM_FLAGS}) 34 | endif() 35 | # ... another weird thing of the android.toolchain.cmake file... -O2 should be there but it isn't 36 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2") 37 | endmacro() 38 | -------------------------------------------------------------------------------- /src/memory.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_MEMORY_HPP 2 | #define GDK_MEMORY_HPP 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "assertion.hpp" 11 | #include "ga_wally.hpp" 12 | #include "gsl_wrapper.hpp" 13 | 14 | namespace green { 15 | 16 | template inline std::array make_byte_array(byte_span_t bytes) 17 | { 18 | GDK_RUNTIME_ASSERT(bytes.size() == N); 19 | std::array ret; 20 | std::copy(bytes.begin(), bytes.end(), ret.data()); 21 | return ret; 22 | } 23 | 24 | template inline std::vector make_vector(const std::array& src) 25 | { 26 | return { src.begin(), src.end() }; 27 | } 28 | template inline std::vector make_vector(const std::array& src) 29 | { 30 | return { src.begin(), src.end() }; 31 | } 32 | 33 | template void swap_with_default(T& obj) { T().swap(obj); } 34 | 35 | template void bzero_and_free(std::vector& data) 36 | { 37 | wally_bzero(data.data(), data.size()); 38 | swap_with_default(data); 39 | } 40 | 41 | template inline void init_container(T& dst, const U& arg1, const V& arg2) 42 | { 43 | GDK_RUNTIME_ASSERT(arg1.data() && arg2.data()); 44 | GDK_RUNTIME_ASSERT( 45 | dst.size() == gsl::narrow(arg1.size() + arg2.size())); // No partial fills supported 46 | std::copy(arg1.begin(), arg1.end(), dst.data()); 47 | std::copy(arg2.begin(), arg2.end(), dst.data() + arg1.size()); 48 | } 49 | 50 | // Make a byte span out of string input 51 | inline auto ustring_span(const std::string_view& str) 52 | { 53 | return gsl::make_span(reinterpret_cast(str.data()), str.size()); 54 | } 55 | 56 | } // namespace green 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_common/src/util/strser.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::{self, Display}; 2 | use std::ops::{Deref, DerefMut}; 3 | use std::str::FromStr; 4 | 5 | /// A wrapper for anything that implements FromStr to make it serde::Deserialize. Will turn 6 | /// Display to serde::Serialize. 7 | /// https://github.com/rs-ipfs/rust-ipfs/blob/4bce4679de6c4f206864de843f14e2c273560dcb/http/src/v0/support/serdesupport.rs 8 | 9 | #[derive(Clone, Copy)] 10 | pub struct StringSerialized(pub T); 11 | 12 | impl From for StringSerialized { 13 | fn from(t: T) -> Self { 14 | StringSerialized(t) 15 | } 16 | } 17 | 18 | impl Deref for StringSerialized { 19 | type Target = T; 20 | 21 | fn deref(&self) -> &T { 22 | &self.0 23 | } 24 | } 25 | 26 | impl DerefMut for StringSerialized { 27 | fn deref_mut(&mut self) -> &mut T { 28 | &mut self.0 29 | } 30 | } 31 | 32 | impl fmt::Debug for StringSerialized { 33 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 34 | self.0.fmt(fmt) 35 | } 36 | } 37 | 38 | impl fmt::Display for StringSerialized { 39 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 40 | self.0.fmt(fmt) 41 | } 42 | } 43 | 44 | impl serde::Serialize for StringSerialized { 45 | fn serialize(&self, serializer: S) -> Result 46 | where 47 | S: serde::Serializer, 48 | { 49 | serializer.collect_str(self) 50 | } 51 | } 52 | 53 | impl<'de, T: FromStr> serde::Deserialize<'de> for StringSerialized 54 | where 55 | //::Err: Display, 56 | T: Sized, 57 | { 58 | fn deserialize(deserializer: D) -> Result, D::Error> 59 | where 60 | D: serde::Deserializer<'de>, 61 | { 62 | String::deserialize(deserializer)? 63 | .parse() 64 | .map(StringSerialized) 65 | //.map_err(serde::de::Error::custom) 66 | .map_err(|_| serde::de::Error::custom("invalid value")) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/weaken-symbols: -------------------------------------------------------------------------------- 1 | CURVE_B 2 | ecdsa_signature_parse_der_lax 3 | __rbt_backtrace_alloc 4 | __rbt_backtrace_close 5 | __rbt_backtrace_create_state 6 | __rbt_backtrace_dwarf_add 7 | __rbt_backtrace_free 8 | __rbt_backtrace_get_view 9 | __rbt_backtrace_initialize 10 | __rbt_backtrace_open 11 | __rbt_backtrace_pcinfo 12 | __rbt_backtrace_qsort 13 | __rbt_backtrace_release_view 14 | __rbt_backtrace_syminfo 15 | __rbt_backtrace_uncompress_zdebug 16 | __rbt_backtrace_vector_finish 17 | __rbt_backtrace_vector_grow 18 | __rbt_backtrace_vector_release 19 | secp256k1_context_clone 20 | secp256k1_context_create 21 | secp256k1_context_destroy 22 | secp256k1_context_no_precomp 23 | secp256k1_context_preallocated_clone 24 | secp256k1_context_preallocated_clone_size 25 | secp256k1_context_preallocated_create 26 | secp256k1_context_preallocated_destroy 27 | secp256k1_context_preallocated_size 28 | secp256k1_context_randomize 29 | secp256k1_context_set_error_callback 30 | secp256k1_context_set_illegal_callback 31 | secp256k1_ecdh 32 | secp256k1_ecdh_hash_function_default 33 | secp256k1_ecdh_hash_function_sha256 34 | secp256k1_ecdsa_recover 35 | secp256k1_ecdsa_recoverable_signature_convert 36 | secp256k1_ecdsa_recoverable_signature_parse_compact 37 | secp256k1_ecdsa_recoverable_signature_serialize_compact 38 | secp256k1_ecdsa_sign 39 | secp256k1_ecdsa_signature_normalize 40 | secp256k1_ecdsa_signature_parse_compact 41 | secp256k1_ecdsa_signature_parse_der 42 | secp256k1_ecdsa_signature_serialize_compact 43 | secp256k1_ecdsa_signature_serialize_der 44 | secp256k1_ecdsa_sign_recoverable 45 | secp256k1_ecdsa_verify 46 | secp256k1_ec_privkey_negate 47 | secp256k1_ec_privkey_tweak_add 48 | secp256k1_ec_privkey_tweak_mul 49 | secp256k1_ec_pubkey_combine 50 | secp256k1_ec_pubkey_create 51 | secp256k1_ec_pubkey_negate 52 | secp256k1_ec_pubkey_parse 53 | secp256k1_ec_pubkey_serialize 54 | secp256k1_ec_pubkey_tweak_add 55 | secp256k1_ec_pubkey_tweak_mul 56 | secp256k1_ec_seckey_verify 57 | secp256k1_nonce_function_default 58 | secp256k1_nonce_function_rfc6979 59 | secp256k1_scratch_space_create 60 | secp256k1_scratch_space_destroy 61 | -------------------------------------------------------------------------------- /tests/test_aes_gcm.cpp: -------------------------------------------------------------------------------- 1 | #include "src/utils.hpp" 2 | 3 | using namespace green; 4 | 5 | // Verify AES GCM encryption/decryption 6 | 7 | int main() 8 | { 9 | unsigned char buff[32 * 32]; 10 | 11 | for (size_t i = 0; i < 32; ++i) { 12 | get_random_bytes(32, buff + i * 32, 32); 13 | } 14 | const auto key = sha256(gsl::make_span(buff, sizeof(buff))); 15 | const auto bad_key = sha256(key); 16 | 17 | // Verify all lengths up to 1024 encrypt and decrypt OK 18 | // Perform each test in new buffers so valgrind can find any overruns 19 | for (size_t i = 1; i <= 1024; ++i) { 20 | // Encrypt 21 | unsigned char* plaintext = reinterpret_cast(malloc(i)); 22 | const auto plaintext_span = gsl::make_span(plaintext, i); 23 | memcpy(plaintext, buff, i); 24 | const size_t encrypted_length = aes_gcm_encrypt_get_length(plaintext_span); 25 | unsigned char* cyphertext = reinterpret_cast(malloc(encrypted_length)); 26 | auto cyphertext_span = gsl::make_span(cyphertext, encrypted_length); 27 | size_t written = aes_gcm_encrypt(key, plaintext_span, cyphertext_span); 28 | GDK_RUNTIME_ASSERT(written == encrypted_length); 29 | 30 | // Decrypt 31 | const size_t decrypted_length = aes_gcm_decrypt_get_length(cyphertext_span); 32 | unsigned char* decrypted = reinterpret_cast(malloc(decrypted_length)); 33 | auto decrypted_span = gsl::make_span(decrypted, decrypted_length); 34 | written = aes_gcm_decrypt(key, cyphertext_span, decrypted_span); 35 | GDK_RUNTIME_ASSERT(written == i); 36 | GDK_RUNTIME_ASSERT(memcmp(decrypted, buff, i) == 0); 37 | 38 | // Bad Key 39 | bool failed = false; 40 | try { 41 | aes_gcm_decrypt(bad_key, cyphertext_span, decrypted_span); 42 | } catch (const std::exception&) { 43 | failed = true; 44 | } 45 | GDK_RUNTIME_ASSERT(failed); 46 | 47 | free(plaintext); 48 | free(cyphertext); 49 | free(decrypted); 50 | } 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /gitlab/python.yml: -------------------------------------------------------------------------------- 1 | 2 | include: 3 | - local: "gitlab/common.yml" 4 | 5 | 6 | 7 | .linux-wheel: 8 | extends: [.python-image, .py_release ] 9 | stage: prebuild 10 | needs: [ test_format ] 11 | script: 12 | - source /root/python-$PYTHON_VERSION-venv/bin/activate 13 | - ./tools/build.sh --clang --buildtype release --install $INSTALL_PATH --no-deps-rebuild --python-version venv --external-deps-dir /prebuild/clang --parallel 16 14 | - auditwheel repair -w wheelhouse $INSTALL_PATH/share/python/*.whl 15 | 16 | 17 | build-linux-wheel-cp39: 18 | extends: .linux-wheel 19 | variables: 20 | PYTHON_VERSION: cp39-cp39 21 | 22 | 23 | build-wheel-release: 24 | extends: .linux-wheel 25 | when: manual 26 | parallel: 27 | matrix: 28 | - PYTHON_VERSION: [cp310-cp310, cp311-cp311, cp312-cp312, cp313-cp313] # , cp39-cp39 included in the previous job 29 | 30 | 31 | release-python: 32 | tags: 33 | - garelease 34 | stage: release 35 | needs: [build-linux-wheel-cp39, build_clang_osx] 36 | script: 37 | - mkdir gdk_dist 38 | - find wheelhouse/ -name *.whl -exec mv {} gdk_dist/ \; 39 | - cd gdk_dist 40 | - /opt/process_release 41 | artifacts: 42 | name: "$CI_PROJECT_NAME-$CI_COMMIT_SHORT_SHA" 43 | expire_in: 3 days 44 | paths: 45 | - $CI_PROJECT_DIR/gdk_dist 46 | when: on_success 47 | 48 | 49 | jumbo-release-python: 50 | extends: .debian-image 51 | stage: release 52 | needs: [build-linux-wheel-cp39, build_clang_osx, build-wheel-release] 53 | script: 54 | - suffix=${CI_COMMIT_TAG} 55 | - if [ -z ${suffix} ]; then suffix=${CI_COMMIT_SHORT_SHA}; fi 56 | - mkdir gdk-${suffix} 57 | - find wheelhouse/ -name *.whl -exec mv {} gdk-${suffix}/ \; 58 | - tar -czf archive.tar.gz gdk-${suffix} --remove-files 59 | artifacts: 60 | expire_in: 7 days 61 | when: on_success 62 | paths: 63 | - archive.tar.gz 64 | 65 | 66 | upload-python-gcloud: 67 | extends: .gcloud-publish 68 | needs: [ release-python ] 69 | script: 70 | - url=${GCLOUD_URL}/${subfolder}/python 71 | - echo ${url} 72 | - gsutil cp -r $CI_PROJECT_DIR/gdk_dist/* ${url} 73 | -------------------------------------------------------------------------------- /tools/libevent-2.1.12.patch: -------------------------------------------------------------------------------- 1 | diff --git -ru a/libevent-release-2.1.12-stable/CMakeLists.txt b/libevent-release-2.1.12-stable/CMakeLists.txt 2 | --- a/libevent-release-2.1.12-stable/CMakeLists.txt 2020-07-05 14:02:46.000000000 +0200 3 | +++ b/libevent-release-2.1.12-stable/CMakeLists.txt 2024-03-28 11:23:45.190750519 +0100 4 | @@ -508,6 +508,28 @@ 5 | endif() 6 | endif() 7 | 8 | +if (NOT EVENT__DISABLE_THREAD_SUPPORT) 9 | + if(ANDROID) 10 | + # pthreads is built in to bionic 11 | + set(EVENT__HAVE_PTHREADS 1) 12 | + CHECK_TYPE_SIZE(pthread_t EVENT__SIZEOF_PTHREAD_T) 13 | + list(APPEND SYMBOLS_TO_CHECK pthread_mutexattr_setprotocol) 14 | + set(PTHREADS_AVAILABLE ON) 15 | + elseif(NOT WIN32) 16 | + find_package(Threads REQUIRED) 17 | + if (NOT CMAKE_USE_PTHREADS_INIT) 18 | + message(FATAL_ERROR 19 | + "Failed to find Pthreads, set EVENT__DISABLE_THREAD_SUPPORT to disable") 20 | + endif() 21 | + 22 | + set(EVENT__HAVE_PTHREADS 1) 23 | + list(APPEND LIB_APPS ${CMAKE_THREAD_LIBS_INIT}) 24 | + 25 | + CHECK_TYPE_SIZE(pthread_t EVENT__SIZEOF_PTHREAD_T) 26 | + list(APPEND SYMBOLS_TO_CHECK pthread_mutexattr_setprotocol) 27 | + endif() 28 | +endif() 29 | + 30 | # Add stdio.h for vasprintf 31 | set(EVENT_INCLUDES ${EVENT_INCLUDES} stdio.h) 32 | CHECK_SYMBOLS_EXIST("${SYMBOLS_TO_CHECK}" "${EVENT_INCLUDES}" "EVENT") 33 | @@ -855,19 +877,8 @@ 34 | list(APPEND LIB_APPS ${OPENSSL_LIBRARIES}) 35 | endif() 36 | 37 | -if (NOT EVENT__DISABLE_THREAD_SUPPORT) 38 | - if (WIN32) 39 | - list(APPEND SRC_CORE evthread_win32.c) 40 | - else() 41 | - find_package(Threads REQUIRED) 42 | - if (NOT CMAKE_USE_PTHREADS_INIT) 43 | - message(FATAL_ERROR 44 | - "Failed to find Pthreads, set EVENT__DISABLE_THREAD_SUPPORT to disable") 45 | - endif() 46 | - 47 | - set(EVENT__HAVE_PTHREADS 1) 48 | - list(APPEND LIB_APPS ${CMAKE_THREAD_LIBS_INIT}) 49 | - endif() 50 | +if (NOT EVENT__DISABLE_THREAD_SUPPORT AND WIN32) 51 | + list(APPEND SRC_CORE evthread_win32.c) 52 | endif() 53 | 54 | if (NOT EVENT__DISABLE_TESTS) 55 | -------------------------------------------------------------------------------- /docs/source/examples/network.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "address_explorer_onion_url": "http://explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion/address/", 10 | "address_explorer_url": "https://blockstream.info/address/", 11 | "bech32_prefix": "bc", 12 | "bip21_prefix": "bitcoin", 13 | "blob_server_onion_url": "", 14 | "blob_server_url": "", 15 | "csv_buckets": [ 16 | 25920, 17 | 51840, 18 | 65535 19 | ], 20 | "development": false, 21 | "electrum_onion_url": "btcmxqzlrigojf2sdp6ekwjibucdqifpw34yidjez3x7ecdtbkuzavid.onion:50001", 22 | "electrum_tls": true, 23 | "electrum_url": "bitcoin-mainnet.blockstream.info:50002", 24 | "liquid": false, 25 | "mainnet": true, 26 | "max_reorg_blocks": 144, 27 | "min_fee_rate": null, 28 | "name": "Bitcoin", 29 | "network": "mainnet", 30 | "p2pkh_version": 0, 31 | "p2sh_version": 5, 32 | "pin_server_onion_url": "http://mrrxtq6tjpbnbm7vh5jt6mpjctn7ggyfy5wegvbeff3x7jrznqawlmid.onion", 33 | "pin_server_public_key": "0332b7b1348bde8ca4b46b9dcc30320e140ca26428160a27bdbfc30b34ec87c547", 34 | "pin_server_url": "https://jadepin.blockstream.com", 35 | "price_onion_url": "http://greenv32e5p4rax6dmfgb4zzl7kq2fbmizd7miyava2actplmipyx2qd.onion/prices", 36 | "price_url": "https://green-bitcoin-mainnet.blockstream.com/prices", 37 | "server_type": "green", 38 | "service_chain_code": "e9a563d68686999af372a33157209c6860fe79197a4dafd9ec1dbaa49523351d", 39 | "service_pubkey": "0322c5f5c9c4b9d1c3e22ca995e200d724c2d7d8b6953f7b38fddf9296053c961f", 40 | "tx_explorer_onion_url": "http://explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion/tx/", 41 | "tx_explorer_url": "https://blockstream.info/tx/", 42 | "wamp_cert_pins": [ 43 | "default" 44 | ], 45 | "wamp_cert_roots": [ 46 | "default" 47 | ], 48 | "wamp_onion_url": "ws://greenv32e5p4rax6dmfgb4zzl7kq2fbmizd7miyava2actplmipyx2qd.onion:80/v2/ws", 49 | "wamp_url": "wss://green-bitcoin-mainnet.blockstream.com/v2/ws" 50 | } 51 | 52 | .. raw:: html 53 | 54 |
55 | 56 | -------------------------------------------------------------------------------- /src/exception.cpp: -------------------------------------------------------------------------------- 1 | #include "exception.hpp" 2 | #include "autobahn_wrapper.hpp" 3 | #include "ga_strings.hpp" 4 | #include "logging.hpp" 5 | #include 6 | #include 7 | #include 8 | 9 | namespace green { 10 | 11 | namespace { 12 | static bool is_prevout_missing(const std::string& msg) 13 | { 14 | return boost::algorithm::starts_with(msg, "Missing prevout:"); 15 | } 16 | } // namespace 17 | 18 | std::pair get_error_details(const autobahn::call_error& e) 19 | { 20 | std::string message; 21 | const auto& args = e.get_args(); 22 | if (args.size() >= 2) { 23 | std::string uri; 24 | args[0].convert(uri); 25 | if (boost::algorithm::starts_with(uri, "http://greenaddressit.com/error#")) { 26 | std::vector ss; 27 | boost::algorithm::split(ss, uri, boost::is_any_of("#")); 28 | args[1].convert(message); 29 | return std::make_pair(ss.at(1), message); 30 | } 31 | } 32 | return std::make_pair(std::string(), std::string()); 33 | } 34 | 35 | std::pair remap_ga_server_error(const std::pair& details) 36 | { 37 | if (is_prevout_missing(details.second)) { 38 | // Missing prevout indicates that a tx being bumped has been 39 | // confirmed and therefore the bump tx's previous output cannot 40 | // be found. Remap this to a more friendly error message. 41 | GDK_LOG(debug) << details.second; 42 | return std::make_pair(details.first, res::id_transaction_already_confirmed); 43 | } else if (details.second == "User not found or invalid password") { 44 | return std::make_pair(details.first, res::id_user_not_found_or_invalid); 45 | } else if (details.second == "Invalid PGP key") { 46 | return std::make_pair(details.first, res::id_invalid_pgp_key); 47 | } 48 | return details; 49 | } 50 | 51 | } // namespace green 52 | -------------------------------------------------------------------------------- /docker/python/Dockerfile: -------------------------------------------------------------------------------- 1 | # Manylinux (main build) image. Build with: 2 | # DOCKER_BUILDKIT=1 docker build . -t greenaddress/gdk-python-builder -f docker/python/Dockerfile 3 | # 4 | FROM quay.io/pypa/manylinux_2_28_x86_64@sha256:a0bac0e8aa5a77d4746ff0dc80cd3ea5208c0297f56201641dd139d93291759d AS base 5 | #FROM quay.io/pypa/manylinux_2_34_x86_64@sha256:fa538e6c36fe23e8334813c7586dfca3657907312784d2adbf420ec6367d27b7 AS base 6 | WORKDIR /root 7 | COPY ./tools ./tools 8 | COPY ./cmake/profiles ./cmake/profiles 9 | # Optionally copy dependency sources from the build directory if present 10 | COPY ./downloads ./downloads 11 | COPY ./docker/python/install_deps.sh ./docker/python/install_deps.sh 12 | RUN ./docker/python/install_deps.sh 13 | 14 | ENV GDK_KEEP_DOWNLOADS=1 15 | 16 | FROM base AS builderlinux 17 | #wally absolutely wants a running python -- it doesn't really matter the version here 18 | RUN source /opt/python/default/bin/activate && ./tools/builddeps.sh --clang --prefix /prebuild/clang 19 | 20 | FROM rust:1.81-bullseye AS builderrust 21 | 22 | FROM base AS final 23 | # Remove copied/downloaded dependency sources 24 | RUN rm -rf ./tools ./downloads ./cmake ./docker 25 | 26 | COPY --from=builderlinux /prebuild/clang /prebuild/clang 27 | 28 | COPY --from=builderrust /usr/local/cargo /usr/local/cargo 29 | COPY --from=builderrust /usr/local/rustup /usr/local/rustup 30 | 31 | ENV CARGO_HOME=/usr/local/cargo 32 | ENV RUSTUP_HOME=/usr/local/rustup 33 | ENV RUST_VERSION=1.81.0 34 | ENV PATH="/usr/local/cargo/bin:${PATH}" 35 | 36 | # predownloading rust dependencies 37 | COPY ./subprojects/gdk_rust/Cargo.* ./subprojects/gdk_rust/ 38 | COPY ./subprojects/gdk_rust/gdk_common/Cargo.* ./subprojects/gdk_rust/gdk_common 39 | COPY ./subprojects/gdk_rust/gdk_electrum/Cargo.* ./subprojects/gdk_rust/gdk_electrum 40 | COPY ./subprojects/gdk_rust/gdk_pin_client/Cargo.* ./subprojects/gdk_rust/gdk_pin_client 41 | COPY ./subprojects/gdk_rust/gdk_registry/Cargo.* ./subprojects/gdk_rust/gdk_registry 42 | COPY ./subprojects/gdk_rust/gdk_rust/Cargo.* ./subprojects/gdk_rust/gdk_rust 43 | RUN cargo fetch --manifest-path ./subprojects/gdk_rust/Cargo.toml 44 | RUN rm -rf ./subprojects 45 | 46 | RUN chmod +xr /root 47 | WORKDIR /root/gdk 48 | VOLUME /root/gdk 49 | -------------------------------------------------------------------------------- /docs/source/examples/get_previous_addresses_multisig_liquid.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig Liquid example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "list": [ 10 | { 11 | "address": "AzpxKzziQPVEFaqgoTEofLfbDoCYopCs5LisZhbr56wTmkiTxaq4Ue4K9E6wBx6L9BvNUYaW8vobchSZ", 12 | "address_type": "csv", 13 | "blinding_key": "03ed3ed04c8e522af02a760ca8feb42ac8c298ee25d16718efce95dd530c59161c", 14 | "branch": 1, 15 | "is_confidential": true, 16 | "pointer": 2, 17 | "script": "748c63210325d8aed10e04b73aab80b9e738e3f3933d49de0238a4ff0a3395cd7f3e5ba65fad6703ffff00b27568210251b4473cc52200be514994986927632cfe04b2fbe6fba1a69a0ea835dc1fe2ceac", 18 | "scriptpubkey": "a914e5c73e6d8119f62b31f8c1b7069e36088c2779f387", 19 | "service_xpub": "tpubEAUTpVqYYmDa5DQdXdJhaMyrvycVbpuCRdUTVifuG3ML5kbwujP3CdxGT1rVoDnFnxsxEv1aiVaEtuJzDBu1bNJk9mADeeR2rZ1HcCCzdyG", 20 | "subaccount": 0, 21 | "subtype": 65535, 22 | "tx_count": 0, 23 | "unconfidential_address": "XYJCGnCEYhRzPwPfFyk433jUHKzKhvwNiD", 24 | "user_path": [ 25 | 1, 26 | 2 27 | ] 28 | }, 29 | { 30 | "address": "AzpsXif2CBq9WEtyZW5JR85LUEBXjvZXi2wx5EaKqXQ1cQh8Jo35fGva7MWcfQmkNZ3D2hZbXD3U16eF", 31 | "address_type": "csv", 32 | "blinding_key": "033c13b87298d77941d6e4ec5c754a03a41a7c48ad4196e1e97a734d8646daa231", 33 | "branch": 1, 34 | "is_confidential": true, 35 | "pointer": 1, 36 | "script": "748c6321023cebb0d3a3434d1df033c3c41e3d02f2e0b44a64c3d58519ca656b4f5363f591ad6703ffff00b275682102ea2fe5fcee6e1ada9ee3f4228ac1b83554cff618c8bc6ef64d9988e2f4bb13a1ac", 37 | "scriptpubkey": "a91469a22b9f6314c0fe6db92286592ec287ac52c03587", 38 | "service_xpub": "tpubEAUTpVqYYmDa5DQdXdJhaMyrvycVbpuCRdUTVifuG3ML5kbwujP3CdxGT1rVoDnFnxsxEv1aiVaEtuJzDBu1bNJk9mADeeR2rZ1HcCCzdyG", 39 | "subaccount": 0, 40 | "subtype": 65535, 41 | "tx_count": 0, 42 | "unconfidential_address": "XLyn55q1TtektRH3YrDTT8vMTMkjrcT38u", 43 | "user_path": [ 44 | 1, 45 | 1 46 | ] 47 | } 48 | ] 49 | } 50 | 51 | .. raw:: html 52 | 53 |
54 | 55 | -------------------------------------------------------------------------------- /docs/source/examples/get_transactions_multisig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Multisig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "transactions": [ 10 | { 11 | "block_height": 0, 12 | "can_cpfp": true, 13 | "can_rbf": false, 14 | "created_at_ts": 1686640441208984, 15 | "fee": 1430, 16 | "fee_rate": 10000, 17 | "inputs": [ 18 | { 19 | "address": "bcrt1qsjtt6hv699fulumf0ravymecm8792shd6hz4kz", 20 | "address_type": "", 21 | "is_internal": false, 22 | "is_output": false, 23 | "is_relevant": false, 24 | "is_spent": true, 25 | "pointer": 0, 26 | "pt_idx": 0, 27 | "satoshi": 5000000000, 28 | "subaccount": 0, 29 | "subtype": 0 30 | } 31 | ], 32 | "memo": "", 33 | "outputs": [ 34 | { 35 | "address": "2N2zyKJEcAtqgHRdYFqCQDKZozDi5GY9wi5", 36 | "address_type": "csv", 37 | "is_internal": false, 38 | "is_output": true, 39 | "is_relevant": true, 40 | "is_spent": false, 41 | "pointer": 1, 42 | "pt_idx": 0, 43 | "satoshi": 12340, 44 | "subaccount": 0, 45 | "subtype": 51840 46 | }, 47 | { 48 | "address": "2MuhZUoJcSa2XwjejYmrBkA2x5WqM7UcZgg", 49 | "address_type": "", 50 | "is_internal": false, 51 | "is_output": true, 52 | "is_relevant": false, 53 | "is_spent": false, 54 | "pointer": 0, 55 | "pt_idx": 1, 56 | "satoshi": 4999986230, 57 | "subaccount": 0, 58 | "subtype": 0 59 | } 60 | ], 61 | "rbf_optin": true, 62 | "satoshi": { 63 | "btc": 12340 64 | }, 65 | "spv_verified": "disabled", 66 | "transaction_vsize": 143, 67 | "transaction_weight": 572, 68 | "txhash": "1a45e3a1140b17b45277e7e1189ff8385c7e0fd4cd88a5840b15ee600d5dbc30", 69 | "type": "incoming" 70 | } 71 | ] 72 | } 73 | 74 | .. raw:: html 75 | 76 |
77 | 78 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_common/src/scripts.rs: -------------------------------------------------------------------------------- 1 | use bitcoin::script::PushBytesBuf; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | use bitcoin::blockdata::script::Builder; 5 | use bitcoin::hashes::Hash; 6 | use bitcoin::PubkeyHash; 7 | use bitcoin::{Address, CompressedPublicKey, Network, ScriptBuf}; 8 | 9 | use std::convert::TryFrom; 10 | use std::fmt; 11 | 12 | #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] 13 | pub enum ScriptType { 14 | #[serde(rename = "p2sh-p2wpkh")] 15 | P2shP2wpkh = 0, 16 | #[serde(rename = "p2wpkh")] 17 | P2wpkh = 1, 18 | #[serde(rename = "p2pkh")] 19 | P2pkh = 2, 20 | #[serde(rename = "p2tr")] 21 | P2tr = 3, 22 | } 23 | 24 | impl fmt::Display for ScriptType { 25 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 26 | match self { 27 | Self::P2shP2wpkh => write!(f, "p2sh-p2wpkh"), 28 | Self::P2wpkh => write!(f, "p2wpkh"), 29 | Self::P2pkh => write!(f, "p2pkh"), 30 | Self::P2tr => write!(f, "p2tr"), 31 | } 32 | } 33 | } 34 | 35 | impl ScriptType { 36 | /// An integer associated to the scipt/account type to compute the GDK pointer (account_num) 37 | pub fn num(&self) -> u32 { 38 | match self { 39 | Self::P2shP2wpkh => 0, 40 | Self::P2wpkh => 1, 41 | Self::P2pkh => 2, 42 | Self::P2tr => 3, 43 | } 44 | } 45 | } 46 | 47 | // The following scripts are always using regtest network, 48 | // it is always ok because I am not interested in the address just in the script 49 | 50 | pub fn p2pkh_script(pk: impl Into) -> ScriptBuf { 51 | Address::p2pkh(pk, Network::Regtest).script_pubkey() 52 | } 53 | 54 | pub fn p2shwpkh_script_sig(public_key: &CompressedPublicKey) -> ScriptBuf { 55 | let mut vec = vec![0, 20]; 56 | vec.extend(PubkeyHash::hash(&public_key.to_bytes()).as_byte_array()); 57 | Builder::new().push_slice(&PushBytesBuf::try_from(vec).unwrap()).into_script() 58 | } 59 | 60 | impl ScriptType { 61 | pub fn first_account_num(self) -> u32 { 62 | self as u32 63 | } 64 | 65 | pub fn is_segwit(self) -> bool { 66 | matches!(self, ScriptType::P2wpkh | ScriptType::P2shP2wpkh | ScriptType::P2tr) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tools/make_txt.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | function comma_separate() { 5 | echo "`python -c "import sys; print('[' + ','.join(map(lambda x: '\'' + x + '\'', sys.argv[1:])) + ']')" $@`" 6 | } 7 | 8 | if [ \( "$3" = "android" \) ]; then 9 | C_COMPILER=$(ls $NDK_TOOLSDIR/bin/$clangarchname-linux-android*$ANDROID_VERSION-clang) 10 | CXX_COMPILER=$(ls $NDK_TOOLSDIR/bin/$clangarchname-linux-android*$ANDROID_VERSION-clang++) 11 | STRIP="$(ls $NDK_TOOLSDIR/bin/llvm-strip)" 12 | OBJCOPY="$(ls $NDK_TOOLSDIR/bin/llvm-objcopy)" 13 | CFLAGS=$(comma_separate "--sysroot=$NDK_TOOLSDIR/sysroot" $SDK_CFLAGS) 14 | LDFLAGS=$(comma_separate $SDK_LDFLAGS) 15 | ARCHS="[]" 16 | HOST_SYSTEM=$3 17 | elif [ \( "$3" = "iphone" \) -o \( "$3" = "iphonesim" \) ]; then 18 | C_COMPILER="clang" 19 | CXX_COMPILER="clang++" 20 | CFLAGS=$(comma_separate $IOS_CFLAGS "-stdlib=libc++") 21 | LDFLAGS=$(comma_separate $IOS_LDFLAGS "-stdlib=libc++") 22 | ARCHS=$(comma_separate $ARCHS) 23 | HOST_SYSTEM="darwin" 24 | elif [ \( "$3" = "windows" \) ]; then 25 | C_COMPILER="x86_64-w64-mingw32-gcc-posix" 26 | CXX_COMPILER="x86_64-w64-mingw32-g++-posix" 27 | STRIP="x86_64-w64-mingw32-strip" 28 | OBJCOPY="x86_64-w64-mingw32-objcopy" 29 | ARCHS="[]" 30 | else 31 | echo "cross build type not supported" && exit 1 32 | fi 33 | 34 | if [ \( "$HOST_SYSTEM" = "darwin" \) ]; then 35 | STRIP="$STRIP -x" 36 | fi 37 | 38 | if [ \( "$3" = "windows" \) ]; then 39 | cat > $2 << EOF 40 | 41 | [binaries] 42 | c = '$C_COMPILER' 43 | cpp = '$CXX_COMPILER' 44 | ar = '$AR' 45 | pkgconfig = 'pkg-config' 46 | strip = '$STRIP' 47 | objcopy = '$OBJCOPY' 48 | 49 | [properties] 50 | target_os = '$4' 51 | archs = $ARCHS 52 | 53 | [host_machine] 54 | system = 'windows' 55 | cpu_family = 'x86_64' 56 | cpu = 'x86_64' 57 | endian = 'little' 58 | EOF 59 | else 60 | cat > $2 << EOF 61 | 62 | [binaries] 63 | c = '$C_COMPILER' 64 | cpp = '$CXX_COMPILER' 65 | ar = '$AR' 66 | pkgconfig = 'pkg-config' 67 | strip = '$STRIP' 68 | objcopy = '$OBJCOPY' 69 | 70 | [properties] 71 | target_os = '$4' 72 | ndk_lib_dir = '$5' 73 | archs = $ARCHS 74 | c_args = $CFLAGS 75 | cpp_args = $CFLAGS 76 | c_link_args = $LDFLAGS 77 | cpp_link_args = $LDFLAGS 78 | 79 | [host_machine] 80 | system = '$HOST_SYSTEM' 81 | cpu_family = '$SDK_ARCH' 82 | cpu = '$SDK_CPU' 83 | endian = 'little' 84 | EOF 85 | fi 86 | -------------------------------------------------------------------------------- /gitlab/ios.yml: -------------------------------------------------------------------------------- 1 | 2 | include: 3 | - local: "gitlab/common.yml" 4 | 5 | 6 | .ios_release: 7 | extends: .osx_env 8 | script: 9 | - PREBUILT_DIR="$CI_BUILDS_DIR/$PREBUILT_SUBDIR/${PLATFORM}" 10 | - virtualenv venv && source venv/bin/activate && pip install -r ./tools/requirements.txt 11 | - if [[ ! -d "$PREBUILT_DIR" ]]; then ./tools/builddeps.sh --parallel 16 --${PLATFORM} static --prefix $PREBUILT_DIR; fi 12 | - touch $CI_BUILDS_DIR/$PREBUILT_SUBDIR/last_use # marking last use to help out during sweeping operations 13 | - ./tools/build.sh --${PLATFORM} static --buildtype release --no-deps-rebuild --external-deps-dir $PREBUILT_DIR --parallel 16 --install $INSTALL_PATH 14 | artifacts: 15 | name: "$CI_JOB_NAME-$CI_COMMIT_SHORT_SHA" 16 | expire_in: 1 day 17 | when: on_success 18 | paths: 19 | - $INSTALL_PATH 20 | 21 | 22 | build_osx_ios: 23 | extends: .ios_release 24 | tags: 25 | - osx-m1 26 | stage: build 27 | variables: 28 | INSTALL_PATH: "gdk-iphone" 29 | PLATFORM: "iphone" 30 | 31 | 32 | build_osx_ios_sim_arm64: 33 | extends: .ios_release 34 | tags: 35 | - osx-m1 36 | stage: build 37 | variables: 38 | INSTALL_PATH: "gdk-iphonesim-arm64" 39 | PLATFORM: "iphonesim" 40 | 41 | 42 | build_osx_ios_sim_x86_64: 43 | extends: .ios_release 44 | tags: 45 | - osx-ia 46 | stage: build 47 | variables: 48 | INSTALL_PATH: "gdk-iphonesim-x86_64" 49 | PLATFORM: "iphonesim" 50 | 51 | 52 | release-ios: 53 | tags: 54 | - garelease 55 | stage: release 56 | needs: [ build_osx_ios, build_osx_ios_sim_arm64, build_osx_ios_sim_x86_64 ] 57 | script: 58 | - cd $CI_PROJECT_DIR 59 | - mkdir -p gdk_dist/ 60 | - tar -czf gdk_dist/gdk-iphone.tar.gz gdk-iphone --remove-files 61 | - tar -czf gdk_dist/gdk-iphone-sim.tar.gz gdk-iphonesim-arm64 --remove-files 62 | - tar -czf gdk_dist/gdk-iphone-sim-x86_64.tar.gz gdk-iphonesim-x86_64 --remove-files 63 | - cd gdk_dist 64 | - /opt/process_release 65 | artifacts: 66 | name: "ios-$CI_PROJECT_NAME-$CI_COMMIT_SHORT_SHA" 67 | expire_in: 3 days 68 | paths: 69 | - $CI_PROJECT_DIR/gdk_dist 70 | when: on_success 71 | 72 | 73 | upload-ios-gcloud: 74 | extends: .gcloud-publish 75 | needs: [ release-ios ] 76 | script: 77 | - url=${GCLOUD_URL}/${subfolder}/ios 78 | - echo ${url} 79 | - gsutil cp -r $CI_PROJECT_DIR/gdk_dist/* ${url} 80 | -------------------------------------------------------------------------------- /tools/buildtor.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | TOR_NAME="$(basename ${PRJ_SUBDIR})" 5 | 6 | # fixes to code 7 | # TODO: convert this to a patch file 8 | cd ${TOR_SRCDIR} 9 | ${SED} -i 's/#include /#include /g' src/lib/crypt_ops/crypto_openssl_mgt.h 10 | # Remove warning string reference to openssl 1.1.1.b - Google play store 11 | # security scanning incorrectly assumes we have linked a vulnerable openssl 12 | # version if the string "OpenSSL 1.1.1b" is found in the final binary. 13 | # FIXME: remove when tor is upgraded to version tor-0.4.8.1 or later. 14 | ${SED} -i 's/"1\.1\.1b\."/"future connections."/g' src/lib/tls/tortls_openssl.c 15 | 16 | TOR_INSTALL_DIR=${GDK_BUILD_ROOT} 17 | #FIXME: enable zstd for tor compression 18 | CONFIGURE_ARGS="--prefix=${TOR_INSTALL_DIR} --enable-pic \ 19 | --enable-static-libevent --with-libevent-dir=${GDK_BUILD_ROOT} \ 20 | --enable-static-zlib --with-zlib-dir=${GDK_BUILD_ROOT} \ 21 | --enable-static-openssl --with-openssl-dir=${GDK_BUILD_ROOT} \ 22 | --disable-asciidoc --disable-manpage --disable-html-manual \ 23 | --disable-system-torrc --disable-systemd --disable-zstd --disable-lzma --disable-largefile \ 24 | --disable-unittests --disable-tool-name-check --disable-module-dirauth \ 25 | --disable-libscrypt --disable-gcc-hardening --disable-linker-hardening \ 26 | --disable-gcc-warnings-advisory ac_cv_c_bigendian=no" 27 | 28 | ## tor does not like -DNDEBUG 29 | CFLAGS=$(echo $CFLAGS | $SED 's/-DNDEBUG//') 30 | CXXFLAGS=$(echo $CXXFLAGS | $SED 's/-DNDEBUG//') 31 | 32 | case $target_triple in 33 | *-linux-android) 34 | CONFIGURE_ARGS+=" --enable-android --host=${target_triple} --build=${host_triple}" 35 | ;; 36 | *-apple-ios | *-apple-iossimulator) 37 | CONFIGURE_ARGS+=" ac_cv_func__NSGetEnviron=no --host=arm-apple-darwin" 38 | ;; 39 | *-w64-mingw32) 40 | CONFIGURE_ARGS+=" --host=${target_triple} --build=${host_triple}" 41 | ;; 42 | esac 43 | 44 | mkdir build 45 | cd build 46 | ../configure ${CONFIGURE_ARGS} 47 | 48 | make libtor.a -j ${NUM_JOBS} 49 | make install 50 | # manually installing libraries and header files 51 | mkdir -p ${TOR_INSTALL_DIR} 52 | cp libtor.a ${TOR_INSTALL_DIR}/lib 53 | mkdir -p ${TOR_INSTALL_DIR}/include 54 | 55 | cp ../src/feature/api/tor_api.h ${TOR_INSTALL_DIR}/include 56 | 57 | cd - 58 | -------------------------------------------------------------------------------- /docs/source/examples/get_transactions_singlesig.json: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | Singlesig example 5 | 6 | .. code-block:: json 7 | 8 | { 9 | "transactions": [ 10 | { 11 | "block_height": 0, 12 | "can_cpfp": false, 13 | "can_rbf": false, 14 | "created_at_ts": 1686597244463054, 15 | "fee": 1430, 16 | "fee_rate": 10052, 17 | "inputs": [ 18 | { 19 | "address": "bcrt1qsjtt6hv699fulumf0ravymecm8792shd6hz4kz", 20 | "address_type": "", 21 | "is_internal": false, 22 | "is_output": false, 23 | "is_relevant": false, 24 | "is_spent": true, 25 | "pointer": 0, 26 | "pt_idx": 0, 27 | "satoshi": 5000000000, 28 | "script": "00148496bd5d9a2953cff36978fac26f38d9fc5542ed", 29 | "subaccount": 0, 30 | "subtype": 0 31 | } 32 | ], 33 | "memo": "", 34 | "outputs": [ 35 | { 36 | "address": "2N2whnPNT4fYtntAYNTWoCshDVBphCRzyH7", 37 | "address_type": "", 38 | "is_internal": false, 39 | "is_output": true, 40 | "is_relevant": false, 41 | "is_spent": false, 42 | "pointer": 0, 43 | "pt_idx": 0, 44 | "satoshi": 4999986230, 45 | "script": "a9146a60f8f6cd77c44582c04b8912dcba06601503e087", 46 | "subaccount": 0, 47 | "subtype": 0 48 | }, 49 | { 50 | "address": "2MsHqxhz5fHt2QyvE8TgT1MvzDY9kdMH5Rz", 51 | "address_type": "p2sh-p2wpkh", 52 | "is_internal": false, 53 | "is_output": true, 54 | "is_relevant": true, 55 | "is_spent": false, 56 | "pointer": 1, 57 | "pt_idx": 1, 58 | "satoshi": 12340, 59 | "script": "a914007edc4b1153a320e490b5fe29a33e95af2d3c7387", 60 | "subaccount": 0, 61 | "subtype": 0 62 | } 63 | ], 64 | "rbf_optin": true, 65 | "satoshi": { 66 | "btc": 12340 67 | }, 68 | "spv_verified": "disabled", 69 | "transaction_vsize": 143, 70 | "transaction_weight": 569, 71 | "txhash": "8a3974692b29237cb81f545a7891be89d73aed7d0038879da437623b0fd57584", 72 | "type": "incoming" 73 | } 74 | ] 75 | } 76 | 77 | .. raw:: html 78 | 79 |
80 | 81 | -------------------------------------------------------------------------------- /tools/buildsqlite3.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | cd "${PRJ_SUBDIR}" 5 | 6 | CONFIGURE_ARGS="--prefix=${GDK_BUILD_ROOT} \ 7 | --enable-static --disable-shared --disable-static-shell \ 8 | --enable-threadsafe --disable-dynamic-extensions \ 9 | --disable-editline --disable-readline --with-pic \ 10 | --disable-fts3 --disable-fts4 --disable-fts5 \ 11 | --disable-rtree" 12 | EXTRA_FLAGS="-DSQLITE_OMIT_DEPRECATED=1 \ 13 | -DSQLITE_DQS=0 \ 14 | -DSQLITE_DEFAULT_MEMSTATUS=0 \ 15 | -DSQLITE_DEFAULT_AUTOVACUUM=0 \ 16 | -DSQLITE_OMIT_AUTOVACUUM=1 \ 17 | -DSQLITE_DEFAULT_SYNCHRONOUS=0 \ 18 | -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \ 19 | -DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 \ 20 | -DSQLITE_MAX_EXPR_DEPTH=0 \ 21 | -DSQLITE_OMIT_DECLTYPE=1 \ 22 | -DSQLITE_OMIT_PROGRESS_CALLBACK=1 \ 23 | -DSQLITE_OMIT_SHARED_CACHE=1 \ 24 | -DSQLITE_DEFAULT_AUTOMATIC_INDEX=0 \ 25 | -DSQLITE_OMIT_BLOB_LITERAL=1 \ 26 | -DSQLITE_OMIT_COMPLETE=1 \ 27 | -DSQLITE_OMIT_GET_TABLE=1 \ 28 | -DSQLITE_OMIT_INCRBLOB=1 \ 29 | -DSQLITE_OMIT_LIKE_OPTIMIZATION=1 \ 30 | -DSQLITE_OMIT_LOAD_EXTENSION=1 \ 31 | -DSQLITE_OMIT_OR_OPTIMIZATION=1 \ 32 | -DSQLITE_OMIT_TCL_VARIABLE=1 \ 33 | -DSQLITE_OMIT_TEMPDB=1 \ 34 | -DSQLITE_OMIT_TRACE=1 \ 35 | -DSQLITE_OMIT_UTF16=1 \ 36 | -DSQLITE_OMIT_WAL=1 \ 37 | -DSQLITE_TEMP_STORE=3 \ 38 | -DSQLITE_ENABLE_API_ARMOR=1 \ 39 | -DSQLITE_OMIT_AUTHORIZATION=1 \ 40 | -DSQLITE_OMIT_AUTOINCREMENT=1 \ 41 | -DSQLITE_OMIT_JSON=1 \ 42 | -DSQLITE_OMIT_DATETIME_FUNCS=1 \ 43 | -DSQLITE_OMIT_DECLTYPE=1 \ 44 | -DSQLITE_OMIT_CAST=1 \ 45 | -DSQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA=1 \ 46 | -DSQLITE_OMIT_BETWEEN_OPTIMIZATION=1" 47 | 48 | if [[ ${BUILDTYPE} == "debug" ]]; then 49 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --enable-debug" 50 | else 51 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-debug" 52 | fi 53 | 54 | case $target_triple in 55 | *-linux-android) 56 | CONFIGURE_ARGS+=" --host=${target_triple} --build=${host_triple}" 57 | ;; 58 | 59 | *-apple-ios | *-apple-iossimulator) 60 | CONFIGURE_ARGS+=" --host=${target_triple} --build=${host_triple}" 61 | ;; 62 | 63 | *-w64-mingw32) 64 | CONFIGURE_ARGS+=" --host=${target_triple} --build=${host_triple}" 65 | ;; 66 | 67 | esac 68 | 69 | 70 | CFLAGS+=" ${EXTRA_FLAGS}" 71 | LDFLAGS+=" ${EXTRA_FLAGS}" 72 | 73 | ./configure ${CONFIGURE_ARGS} 74 | make libsqlite3.la -j${NUM_JOBS} 75 | make install-data 76 | make install-libLTLIBRARIES 77 | -------------------------------------------------------------------------------- /src/validate.cpp: -------------------------------------------------------------------------------- 1 | #include "validate.hpp" 2 | 3 | #include "exception.hpp" 4 | #include "ga_auth_handlers.hpp" 5 | #include "network_parameters.hpp" 6 | #include "session_impl.hpp" 7 | #include "signer.hpp" 8 | #include "transaction_utils.hpp" 9 | #include 10 | 11 | namespace green { 12 | 13 | // 14 | // Validate 15 | // 16 | validate_call::validate_call(session& session, nlohmann::json details) 17 | : auth_handler_impl(session, "validate", {}) 18 | , m_details(std::move(details)) 19 | { 20 | } 21 | 22 | auth_handler::state_type validate_call::call_impl() 23 | { 24 | m_result["errors"] = nlohmann::json::array(); 25 | m_result["is_valid"] = false; 26 | try { 27 | if (is_addressees()) { 28 | addressees_impl(); 29 | } else if (is_liquidex()) { 30 | liquidex_impl(); 31 | } else { 32 | throw user_error("Unknown JSON type"); 33 | } 34 | m_result["is_valid"] = m_result["errors"].empty(); 35 | } catch (const std::exception& e) { 36 | m_result["errors"].emplace_back(e.what()); 37 | } 38 | return state_type::done; 39 | } 40 | 41 | bool validate_call::is_addressees() const { return m_details.contains("addressees"); } 42 | void validate_call::addressees_impl() 43 | { 44 | std::unique_ptr caller_net_params; 45 | const bool override_network = m_details.contains("network"); 46 | nlohmann::json::array_t errors; 47 | 48 | if (override_network) { 49 | // User wants to validate an address for another network 50 | auto defaults = network_parameters::get(m_details.at("network")); 51 | caller_net_params = std::make_unique(defaults); 52 | } 53 | const auto& net_params = override_network ? *caller_net_params : m_session->get_network_parameters(); 54 | for (auto& addressee : m_details["addressees"]) { 55 | nlohmann::json result; 56 | std::string error = validate_tx_addressee(*m_session, net_params, addressee); 57 | if (!error.empty()) { 58 | errors.emplace_back(std::move(error)); 59 | } 60 | } 61 | m_result["errors"] = std::move(errors); 62 | m_result["addressees"] = std::move(m_details["addressees"]); 63 | if (override_network) { 64 | m_result.emplace("network", std::move(m_details["network"])); 65 | } 66 | } 67 | 68 | } // namespace green 69 | -------------------------------------------------------------------------------- /tools/bc-ur.patch: -------------------------------------------------------------------------------- 1 | diff --git -ru a/src/cbor-lite.hpp b/src/cbor-lite.hpp 2 | --- a/src/cbor-lite.hpp 2021-01-20 00:19:17.000000000 +0100 3 | +++ b/src/cbor-lite.hpp 2023-12-12 15:49:34.523285843 +0100 4 | @@ -8,6 +8,7 @@ 5 | // COPYRIGHT.md file in the top-level folder of the CBOR-lite software 6 | // distribution. 7 | 8 | +#include 9 | #include 10 | #include 11 | #include 12 | diff --git -ru a/src/Makefile.in b/src/Makefile.in 13 | --- a/src/Makefile.in 2021-01-20 00:19:17.000000000 +0100 14 | +++ b/src/Makefile.in 2023-12-12 15:48:42.308731733 +0100 15 | @@ -28,8 +28,8 @@ 16 | RESET=`tput sgr0` 17 | 18 | COMPILER = g++ 19 | -CFLAGS += --debug -O0 20 | -CXXFLAGS += -std=c++17 -stdlib=libc++ --debug -O0 21 | +CFLAGS += 22 | +CXXFLAGS += -std=c++17 23 | 24 | ARFLAGS = rcs 25 | 26 | diff --git -ru a/src/memzero.c b/src/memzero.c 27 | --- a/src/memzero.c 2021-01-20 00:19:17.000000000 +0100 28 | +++ b/src/memzero.c 2023-12-12 15:47:38.457606865 +0100 29 | @@ -6,7 +6,7 @@ 30 | #include 31 | 32 | #ifdef _WIN32 33 | -#include 34 | +#include 35 | #endif 36 | 37 | #ifdef __unix__ 38 | diff --git -ru a/src/xoshiro256.cpp b/src/xoshiro256.cpp 39 | --- a/src/xoshiro256.cpp 2021-01-20 00:19:17.000000000 +0100 40 | +++ b/src/xoshiro256.cpp 2023-12-12 15:47:18.376623718 +0100 41 | @@ -7,6 +7,7 @@ 42 | 43 | #include "xoshiro256.hpp" 44 | #include 45 | +#include 46 | 47 | /* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org) 48 | 49 | diff --git a/src/utils.hpp b/src/utils.hpp 50 | --- a/src/utils.hpp 51 | +++ b/src/utils.hpp 52 | @@ -60,11 +60,8 @@ std::vector join(const std::vector>& parts) { 53 | template 54 | std::pair, std::vector> split(const std::vector& buf, size_t count) { 55 | auto first = buf.begin(); 56 | - auto c = std::min(buf.size(), count); 57 | - auto last = first + c; 58 | - auto a = std::vector(first, last); 59 | - auto b = std::vector(last, buf.end()); 60 | - return std::make_pair(a, b); 61 | + auto last = first + std::min(buf.size(), count); 62 | + return { {first, last}, {last, buf.end()} }; 63 | } 64 | 65 | template 66 | @@ -72,7 +69,7 @@ std::vector take_first(const std::vector &buf, size_t count) { 67 | auto first = buf.begin(); 68 | auto c = std::min(buf.size(), count); 69 | auto last = first + c; 70 | - return std::vector(first, last); 71 | + return {first, last}; 72 | } 73 | 74 | void xor_into(ByteVector& target, const ByteVector& source); 75 | -------------------------------------------------------------------------------- /gitlab/common.yml: -------------------------------------------------------------------------------- 1 | 2 | ####### DOCKER IMAGES 3 | .debian-image: 4 | image: blockstream/gdk-debian-ci@sha256:e85ff89aeb745e320ed80b101b06bce41cf32f13fdaecd4e9fa1a672023e1035 5 | tags: [ ga ] 6 | 7 | .android-image: 8 | image: blockstream/gdk-android-builder@sha256:5d02e06d32f580992083f73dccdf143137702a4f835f23117dfe71e0fac1ec2c 9 | tags: [ ga ] 10 | 11 | .python-image: 12 | image: blockstream/gdk-python-builder@sha256:3ce83469b8ede594a25f99a7b89225960a40164168d1603559d47b339c7f7098 13 | tags: [ ga ] 14 | 15 | .ubuntu-image: 16 | image: blockstream/gdk-ubuntu-builder@sha256:f3e4384359ec75eef1782ac8be943577a3a91b9116f9c6a9086a46c6b36de1c0 17 | tags: [ ga ] 18 | 19 | .ubuntu-arm64-image: 20 | image: blockstream/gdk-ubuntu-builder@sha256:380707f1beab151bfa0af8707c37fa57a3d4327350a67c22e342143f0c0e77b2 21 | tags: [ arm64_docker ] 22 | 23 | .fedora-image: 24 | image: blockstream/gdk-fedora-builder@sha256:e10f268aa58d12495ea8cb0d6c94daf4a7c18588b6e226ca4b8d63b8ffb75dfd 25 | tags: [ ga ] 26 | 27 | .aws-lambda-image: 28 | image: blockstream/gdk-aws-lambda-builder@sha256:0171050d957d749eb6fc0bc6ff0bdd388be91eb60a692f4ec609daf9479c5e69 29 | tags: [ ga ] 30 | 31 | 32 | .py_release: 33 | variables: 34 | INSTALL_PATH: "gdk-python" 35 | artifacts: 36 | name: "$CI_JOB_NAME-$CI_COMMIT_SHORT_SHA" 37 | expire_in: 1 day 38 | when: on_success 39 | paths: 40 | - wheelhouse 41 | 42 | 43 | .gcloud-publish: 44 | image: blockstream/gcloud-docker-tf:1.1.7 45 | tags: 46 | - ga 47 | stage: publish 48 | variables: 49 | GCLOUD_URL: "gs://green-gdk-builds" 50 | before_script: 51 | - subfolder=$CI_PROJECT_NAME-$CI_COMMIT_SHA 52 | - TMPF=$(mktemp) || exit 1 53 | - echo $GCLOUD_PUSH_KEY > $TMPF 54 | - export GOOGLE_APPLICATION_CREDENTIALS=$TMPF 55 | - gcloud auth activate-service-account --key-file=$TMPF 56 | - rm -f $TMPF 57 | 58 | 59 | ##### WARNING!!!! 60 | # $PREBUILT_SUBDIR is the folder for the DIY caching system we have in place in mac machines 61 | # BUILD_IDX is your life belt in case you messed the CI up during the prebuild phase and the PREBUILT_DIR folder 62 | # is left in an unconsistent state, just change the BUILD_IDX and you are good to go. 63 | .osx_env: 64 | variables: 65 | BUILD_IDX: "0" 66 | GDK_KEEP_DOWNLOADS: "1" 67 | PYTHON_VERSION: "3.9" 68 | before_script: 69 | - idx=($(shasum tools/* cmake/profiles/* | shasum)) 70 | - export PREBUILT_SUBDIR="prebuilt-${idx}-${BUILD_IDX}" 71 | - echo "prebuild subdir is ${PREBUILT_SUBDIR}" 72 | - mkdir -p $CI_BUILDS_DIR/downloads # Global shared download directory 73 | - ln -s $CI_BUILDS_DIR/downloads downloads 74 | -------------------------------------------------------------------------------- /subprojects/gdk_rust/gdk_common/src/be/blockheader.rs: -------------------------------------------------------------------------------- 1 | use crate::NetworkId; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | use super::BEBlockHash; 5 | 6 | #[allow(clippy::large_enum_variant)] 7 | #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] 8 | pub enum BEBlockHeader { 9 | Bitcoin(bitcoin::block::Header), 10 | Elements(elements::BlockHeader), 11 | } 12 | 13 | impl BEBlockHeader { 14 | pub fn deserialize(bytes: &[u8], id: NetworkId) -> Result { 15 | Ok(match id { 16 | NetworkId::Bitcoin(_) => Self::Bitcoin(bitcoin::consensus::encode::deserialize(bytes)?), 17 | NetworkId::Elements(_) => Self::Elements(elements::encode::deserialize(bytes)?), 18 | }) 19 | } 20 | 21 | pub fn time(&self) -> u32 { 22 | match self { 23 | Self::Bitcoin(header) => header.time, 24 | Self::Elements(header) => header.time, 25 | } 26 | } 27 | 28 | pub fn block_hash(&self) -> BEBlockHash { 29 | match self { 30 | Self::Bitcoin(header) => BEBlockHash::Bitcoin(header.block_hash()), 31 | Self::Elements(header) => BEBlockHash::Elements(header.block_hash()), 32 | } 33 | } 34 | 35 | pub fn prev_block_hash(&self) -> BEBlockHash { 36 | match self { 37 | Self::Bitcoin(header) => BEBlockHash::Bitcoin(header.prev_blockhash), 38 | Self::Elements(header) => BEBlockHash::Elements(header.prev_blockhash), 39 | } 40 | } 41 | } 42 | 43 | #[cfg(test)] 44 | mod test { 45 | use bitcoin::hashes::hex::FromHex; 46 | use elements::encode::deserialize; 47 | use elements::BlockHeader; 48 | 49 | #[test] 50 | fn test_json_header() { 51 | let header = block_header_dynafed(); 52 | let json = serde_json::to_value(&header).unwrap(); 53 | let back: BlockHeader = serde_json::from_value(json).unwrap(); 54 | assert_eq!(header, back); 55 | } 56 | 57 | #[test] 58 | fn test_cbor_header() { 59 | let header = block_header_dynafed(); 60 | let vec = serde_cbor::to_vec(&header).unwrap(); 61 | let back: BlockHeader = serde_cbor::from_slice(&vec).unwrap(); 62 | assert_eq!(header, back); 63 | } 64 | 65 | fn block_header_dynafed() -> BlockHeader { 66 | deserialize( &Vec::::from_hex("000000a013d3fd2bf9e58616f0a283ea6f8d4674bf071f01eb7c1b5916c6168cf048dc1a5123137f8e22e2ef372734506a22adc8769e2dee5da60f5cd0b69e074c0f6dff1c7b855f67000000012200204ae81572f06e1b88fd5ced7a1a000945432e83e1551e6f721ee9c00b8cc332604a000000fbee9cea00d8efdc49cfbec328537e0d7032194de6ebf3cf42e5c05bb89a08b100010151").unwrap()).unwrap() 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/ga_psbt.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_GA_PSBT_HPP 2 | #define GDK_GA_PSBT_HPP 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | struct wally_psbt; 12 | struct wally_psbt_input; 13 | struct wally_psbt_output; 14 | 15 | namespace green { 16 | 17 | class session_impl; 18 | class Tx; 19 | 20 | class Psbt { 21 | public: 22 | Psbt(const std::string& psbt_base64, bool is_liquid); 23 | Psbt(session_impl& session, const nlohmann::json& details, bool is_liquid); 24 | ~Psbt(); 25 | 26 | Psbt(Psbt&& rhs) = default; 27 | Psbt(Psbt& rhs) = delete; 28 | Psbt(const Psbt& rhs) = delete; 29 | 30 | void swap(Psbt& rhs); 31 | 32 | std::string to_base64(bool include_redundant) const; 33 | nlohmann::json to_json(session_impl& session, nlohmann::json utxos) const; 34 | 35 | std::vector get_genesis_blockhash() const; 36 | 37 | // Finalize the PSBT for extraction. 38 | // if allow_partial is false, throws if any finalization data is 39 | // missing and/or the PSBT cannot be fully finalized. 40 | void finalize(bool allow_partial = false); 41 | 42 | Tx extract() const; 43 | 44 | nlohmann::json get_details(session_impl& session, nlohmann::json details) const; 45 | 46 | // Inputs 47 | size_t get_num_inputs() const; 48 | struct wally_psbt_input& get_input(size_t index); 49 | const struct wally_psbt_input& get_input(size_t index) const; 50 | 51 | // Add any valid signatures from the tx input at 'index' to the PSBT 52 | void set_input_signatures(session_impl& session, const nlohmann::json& utxo, const Tx& tx, size_t index); 53 | 54 | // Outputs 55 | size_t get_num_outputs() const; 56 | struct wally_psbt_output& get_output(size_t index); 57 | const struct wally_psbt_output& get_output(size_t index) const; 58 | 59 | private: 60 | std::pair> inputs_to_json( 61 | session_impl& session, Tx& tx, nlohmann::json utxos) const; 62 | nlohmann::json outputs_to_json( 63 | session_impl& session, const Tx& tx, const std::set& wallet_assets) const; 64 | void from_json(session_impl& session, const nlohmann::json& details); 65 | 66 | struct psbt_deleter { 67 | void operator()(struct wally_psbt* p); 68 | }; 69 | std::unique_ptr m_psbt; 70 | uint32_t m_original_version; 71 | bool m_is_liquid; 72 | }; 73 | 74 | } // namespace green 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /src/socks_client.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GDK_SOCKS_CLIENT_HPP 2 | #define GDK_SOCKS_CLIENT_HPP 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace green { 13 | 14 | class socks_client final : public std::enable_shared_from_this { 15 | public: 16 | explicit socks_client(boost::asio::io_context& io, boost::beast::tcp_stream& stream); 17 | 18 | socks_client(const socks_client&) = delete; 19 | socks_client(socks_client&&) = delete; 20 | socks_client& operator=(const socks_client&) = delete; 21 | socks_client& operator=(socks_client&&) = delete; 22 | ~socks_client() = default; 23 | 24 | std::future run(const std::string& endpoint, const std::string& proxy_uri); 25 | void shutdown(); 26 | 27 | private: 28 | enum class reply_code { 29 | success, 30 | general_failure, 31 | connection_not_allowed, 32 | network_unreachable, 33 | host_unreachable, 34 | connection_refused, 35 | ttl_expired, 36 | not_supported, 37 | addr_type_not_supported 38 | }; 39 | 40 | enum class negotiation_phase { method_selection, connect }; 41 | 42 | void on_resolve(boost::beast::error_code ec, const boost::asio::ip::tcp::resolver::results_type& results); 43 | void on_connect( 44 | boost::beast::error_code ec, const boost::asio::ip::tcp::resolver::results_type::endpoint_type& type); 45 | void on_write(boost::beast::error_code ec, size_t bytes_transferred); 46 | void on_read(boost::beast::error_code ec, size_t bytes_transferred); 47 | void on_connect_read(boost::beast::error_code ec, size_t bytes_transferred); 48 | void on_domain_name_read(boost::beast::error_code ec, size_t bytes_transferred); 49 | 50 | std::string get_error_string(uint8_t response); 51 | void set_exception(const std::string& what); 52 | 53 | // SOCKS5 request. TODO: this is a simplified version of the code PR'd to websocketpp 54 | boost::asio::const_buffer method_selection_request(); 55 | boost::asio::const_buffer connect_request(const std::string& url); 56 | 57 | boost::asio::ip::tcp::resolver m_resolver; 58 | boost::beast::tcp_stream& m_stream; 59 | std::string m_endpoint; 60 | 61 | std::vector m_request; 62 | std::vector m_response; 63 | negotiation_phase m_negotiation_phase{ negotiation_phase::method_selection }; 64 | 65 | std::promise m_promise; 66 | }; 67 | 68 | } // namespace green 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /docker/android/Dockerfile: -------------------------------------------------------------------------------- 1 | # Android (main build) image. Build with: 2 | # DOCKER_BUILDKIT=1 docker build . -t blockstream/gdk-android-builder -f docker/android/Dockerfile 3 | # 4 | FROM debian:bullseye@sha256:25c0cab214b810db1b3c8adef5a12a92596979abddf86bb364e8d9c9d111df9f AS base 5 | WORKDIR /root 6 | COPY ./tools ./tools 7 | COPY ./cmake/profiles ./cmake/profiles 8 | # Optionally copy dependency sources from the build directory if present 9 | COPY ./downloads ./downloads 10 | COPY ./docker/android/install_deps.sh ./docker/android/install_deps.sh 11 | RUN ./docker/android/install_deps.sh 12 | 13 | ENV ANDROID_NDK=/root/android-ndk-r26b 14 | ENV JAVA_HOME=/usr/lib/jvm/java-1.11.0-openjdk-amd64 15 | ENV GDK_KEEP_DOWNLOADS=1 16 | 17 | 18 | FROM base AS builderandroid 19 | RUN ./tools/builddeps.sh --ndk armeabi-v7a --prefix /prebuild/android-armeabi-v7a && \ 20 | ./tools/builddeps.sh --ndk arm64-v8a --prefix /prebuild/android-arm64-v8a && \ 21 | ./tools/builddeps.sh --ndk x86 --prefix /prebuild/android-x86 && \ 22 | ./tools/builddeps.sh --ndk x86_64 --prefix /prebuild/android-x86_64 23 | 24 | 25 | FROM rust:1.81-bullseye AS builderrust 26 | RUN rustup component add rustfmt clippy llvm-tools-preview 27 | RUN rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android 28 | 29 | 30 | FROM base AS final 31 | # Remove copied/downloaded dependency sources 32 | RUN rm -rf ./tools ./downloads ./cmake ./docker 33 | 34 | 35 | COPY --from=builderandroid /prebuild/android-armeabi-v7a /prebuild/android-armeabi-v7a 36 | COPY --from=builderandroid /prebuild/android-arm64-v8a /prebuild/android-arm64-v8a 37 | COPY --from=builderandroid /prebuild/android-x86 /prebuild/android-x86 38 | COPY --from=builderandroid /prebuild/android-x86_64 /prebuild/android-x86_64 39 | 40 | 41 | COPY --from=builderrust /usr/local/cargo /usr/local/cargo 42 | COPY --from=builderrust /usr/local/rustup /usr/local/rustup 43 | 44 | ENV CARGO_HOME=/usr/local/cargo 45 | ENV RUSTUP_HOME=/usr/local/rustup 46 | ENV RUST_VERSION=1.81.0 47 | ENV PATH="/usr/local/cargo/bin:${PATH}" 48 | 49 | # predownloading rust dependencies 50 | COPY ./subprojects/gdk_rust/Cargo.* ./subprojects/gdk_rust/ 51 | COPY ./subprojects/gdk_rust/gdk_common/Cargo.* ./subprojects/gdk_rust/gdk_common 52 | COPY ./subprojects/gdk_rust/gdk_electrum/Cargo.* ./subprojects/gdk_rust/gdk_electrum 53 | COPY ./subprojects/gdk_rust/gdk_pin_client/Cargo.* ./subprojects/gdk_rust/gdk_pin_client 54 | COPY ./subprojects/gdk_rust/gdk_registry/Cargo.* ./subprojects/gdk_rust/gdk_registry 55 | COPY ./subprojects/gdk_rust/gdk_rust/Cargo.* ./subprojects/gdk_rust/gdk_rust 56 | RUN cargo fetch --manifest-path ./subprojects/gdk_rust/Cargo.toml 57 | RUN rm -rf ./subprojects 58 | 59 | RUN chmod +xr /root 60 | WORKDIR /root/gdk 61 | VOLUME /root/gdk 62 | -------------------------------------------------------------------------------- /docker/android-bookworm/Dockerfile: -------------------------------------------------------------------------------- 1 | # Android (main build) image. Build with: 2 | # DOCKER_BUILDKIT=1 docker build . -t blockstream/gdk-android-build -f docker/android/Dockerfile 3 | # 4 | FROM debian:bookworm@sha256:b6507e340c43553136f5078284c8c68d86ec8262b1724dde73c325e8d3dcdeba AS base 5 | WORKDIR /root 6 | COPY ./tools ./tools 7 | COPY ./cmake/profiles ./cmake/profiles 8 | # Optionally copy dependency sources from the build directory if present 9 | COPY ./downloads ./downloads 10 | COPY ./docker/android-bookworm/install_deps.sh ./docker/android/install_deps.sh 11 | RUN ./docker/android/install_deps.sh 12 | 13 | ENV ANDROID_NDK=/root/android-ndk-r26b 14 | ENV JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64 15 | ENV GDK_KEEP_DOWNLOADS=1 16 | 17 | 18 | FROM base AS builderandroid 19 | RUN ./tools/builddeps.sh --ndk armeabi-v7a --prefix /prebuild/android-armeabi-v7a && \ 20 | ./tools/builddeps.sh --ndk arm64-v8a --prefix /prebuild/android-arm64-v8a && \ 21 | ./tools/builddeps.sh --ndk x86 --prefix /prebuild/android-x86 && \ 22 | ./tools/builddeps.sh --ndk x86_64 --prefix /prebuild/android-x86_64 23 | 24 | 25 | FROM rust:1.81-bullseye AS builderrust 26 | RUN rustup component add rustfmt clippy llvm-tools-preview 27 | RUN rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android 28 | 29 | 30 | FROM base AS final 31 | # Remove copied/downloaded dependency sources 32 | RUN rm -rf ./tools ./downloads ./cmake ./docker 33 | 34 | 35 | COPY --from=builderandroid /prebuild/android-armeabi-v7a /prebuild/android-armeabi-v7a 36 | COPY --from=builderandroid /prebuild/android-arm64-v8a /prebuild/android-arm64-v8a 37 | COPY --from=builderandroid /prebuild/android-x86 /prebuild/android-x86 38 | COPY --from=builderandroid /prebuild/android-x86_64 /prebuild/android-x86_64 39 | 40 | 41 | COPY --from=builderrust /usr/local/cargo /usr/local/cargo 42 | COPY --from=builderrust /usr/local/rustup /usr/local/rustup 43 | 44 | ENV CARGO_HOME=/usr/local/cargo 45 | ENV RUSTUP_HOME=/usr/local/rustup 46 | ENV RUST_VERSION=1.81.0 47 | ENV PATH="/usr/local/cargo/bin:${PATH}" 48 | 49 | # predownloading rust dependencies 50 | COPY ./subprojects/gdk_rust/Cargo.* ./subprojects/gdk_rust/ 51 | COPY ./subprojects/gdk_rust/gdk_common/Cargo.* ./subprojects/gdk_rust/gdk_common 52 | COPY ./subprojects/gdk_rust/gdk_electrum/Cargo.* ./subprojects/gdk_rust/gdk_electrum 53 | COPY ./subprojects/gdk_rust/gdk_pin_client/Cargo.* ./subprojects/gdk_rust/gdk_pin_client 54 | COPY ./subprojects/gdk_rust/gdk_registry/Cargo.* ./subprojects/gdk_rust/gdk_registry 55 | COPY ./subprojects/gdk_rust/gdk_rust/Cargo.* ./subprojects/gdk_rust/gdk_rust 56 | RUN cargo fetch --manifest-path ./subprojects/gdk_rust/Cargo.toml 57 | RUN rm -rf ./subprojects 58 | 59 | RUN chmod +xr /root 60 | WORKDIR /root/gdk 61 | VOLUME /root/gdk 62 | -------------------------------------------------------------------------------- /tools/buildopenssl.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -e 3 | 4 | 5 | # FIXME: Change no-tests to no-apps when openssl is updated to 3.x 6 | OPENSSL_NAME="$(basename ${PRJ_SUBDIR})" 7 | CONFIGURE_ARGS="no-gost no-shared no-dso no-ssl2 no-ssl3 no-idea no-dtls no-dtls1 no-weak-ssl-ciphers no-comp -fvisibility=hidden no-err no-srp no-tests no-ui-console" 8 | 9 | case $target_triple in 10 | *-linux-gnu) 11 | CONFIGURE_ARGS+=" enable-ec_nistp_64_gcc_128" 12 | openssl_triple="linux-${HOST_ARCH}" 13 | if [ "${CC}" == "clang" ]; then 14 | openssl_triple+="-clang" 15 | fi 16 | ;; 17 | 18 | *-apple-darwin) 19 | CONFIGURE_ARGS+="" 20 | openssl_triple="darwin64-${HOST_ARCH}-cc" 21 | ;; 22 | 23 | armv7a-linux-android) 24 | CONFIGURE_ARGS+=" no-asm no-hw no-engine -D__ANDROID_API__=${ANDROID_VERSION}" 25 | openssl_triple="android-arm" 26 | export ANDROID_NDK_HOME=${ANDROID_NDK} 27 | export PATH="${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-${HOST_ARCH}/bin:$PATH" 28 | ;; 29 | 30 | aarch64-linux-android) 31 | CONFIGURE_ARGS+=" enable-ec_nistp_64_gcc_128 no-hw no-engine -D__ANDROID_API__=${ANDROID_VERSION}" 32 | openssl_triple="android-arm64" 33 | export ANDROID_NDK_HOME=${ANDROID_NDK} 34 | export PATH="${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-${HOST_ARCH}/bin:$PATH" 35 | ;; 36 | 37 | x86_64-linux-android) 38 | CONFIGURE_ARGS+=" enable-ec_nistp_64_gcc_128 no-hw no-engine -D__ANDROID_API__=${ANDROID_VERSION}" 39 | openssl_triple="android-x86_64" 40 | export ANDROID_NDK_HOME=${ANDROID_NDK} 41 | export PATH="${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-${HOST_ARCH}/bin:$PATH" 42 | ;; 43 | 44 | i686-linux-android) 45 | CONFIGURE_ARGS+=" no-hw no-engine -D__ANDROID_API__=${ANDROID_VERSION}" 46 | openssl_triple="android-x86" 47 | export ANDROID_NDK_HOME=${ANDROID_NDK} 48 | export PATH="${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-${HOST_ARCH}/bin:$PATH" 49 | ;; 50 | 51 | arm-apple-ios) 52 | CONFIGURE_ARGS+=" no-hw no-engine" 53 | openssl_triple="ios64-cross" 54 | export CROSS_TOP=${IOS_SDK_PLATFORM_PATH}/Developer 55 | export CROSS_SDK=${SDK_SYSROOT} 56 | ;; 57 | 58 | *-apple-iossimulator) 59 | CONFIGURE_ARGS+=" no-asm no-hw no-engine" 60 | openssl_triple="iossimulator-xcrun" 61 | export CROSS_TOP=${IOS_SDK_PLATFORM_PATH}/Developer 62 | export CROSS_SDK=${SDK_SYSROOT} 63 | ;; 64 | 65 | *-w64-mingw32) 66 | openssl_triple="mingw64" 67 | ;; 68 | 69 | esac 70 | 71 | openssl_prefix="${GDK_BUILD_ROOT}" 72 | cd "${PRJ_SUBDIR}" 73 | 74 | ./Configure $openssl_triple --prefix=${openssl_prefix} ${CONFIGURE_ARGS} 75 | make -j${NUM_JOBS} 2>/dev/null 76 | make -j${NUM_JOBS} install_sw 77 | --------------------------------------------------------------------------------