diff --git a/.github/workflows/swift-sdk-build.yml b/.github/workflows/swift-sdk-build.yml index b95fe4aac3b..e04d3278c6c 100644 --- a/.github/workflows/swift-sdk-build.yml +++ b/.github/workflows/swift-sdk-build.yml @@ -102,68 +102,6 @@ jobs: echo "PROTOC=$HOME/.local/protoc-32.0/bin/protoc" >> "$GITHUB_ENV" "$HOME/.local/protoc-32.0/bin/protoc" --version - - name: Determine rust-dashcore revision (from workspace Cargo.toml) - id: dashcore_rev - shell: bash - run: | - set -euo pipefail - # Use the same rust-dashcore revision/tag as rs-dpp - # Try to find tag first (preferred format) - REV=$(grep -E '^[[:space:]]*dashcore[[:space:]]*=[[:space:]]*\{.*tag[[:space:]]*=' Cargo.toml \ - | sed -E 's/.*tag[[:space:]]*=[[:space:]]*"([^"]+)".*/\1/' \ - | head -n1 || true) - # If no tag found, try rev format - if [ -z "${REV:-}" ]; then - REV=$(grep -E '^[[:space:]]*dashcore[[:space:]]*=[[:space:]]*\{.*rev[[:space:]]*=' Cargo.toml \ - | sed -E 's/.*rev[[:space:]]*=[[:space:]]*"([^"]+)".*/\1/' \ - | head -n1 || true) - fi - if [ -z "${REV:-}" ]; then - echo "Failed to determine rust-dashcore revision or tag from workspace Cargo.toml" >&2 - exit 1 - fi - echo "rev=$REV" >> "$GITHUB_OUTPUT" - - - name: Checkout rust-dashcore at required revision - shell: bash - run: | - set -euxo pipefail - BASE_DIR="$(dirname "$GITHUB_WORKSPACE")" - cd "$BASE_DIR" - if [ -d rust-dashcore/.git ]; then - echo "Updating existing rust-dashcore checkout" - cd rust-dashcore - git fetch --all --tags --prune - else - git clone --filter=blob:none https://github.com/dashpay/rust-dashcore.git rust-dashcore - cd rust-dashcore - fi - git reset --hard # clean any local changes from previous runs, possibly with another branch - git checkout "${{ steps.dashcore_rev.outputs.rev }}" - - - name: Determine rust-dashcore toolchain channel - id: dashcore_toolchain - shell: bash - run: | - set -euo pipefail - FILE="$(dirname "$GITHUB_WORKSPACE")/rust-dashcore/rust-toolchain.toml" - if [ -f "$FILE" ]; then - CHANNEL=$(grep -E '^[[:space:]]*channel[[:space:]]*=' "$FILE" | sed -E 's/.*"([^"]+)".*/\1/' | head -n1 || true) - fi - CHANNEL=${CHANNEL:-stable} - echo "channel=$CHANNEL" >> "$GITHUB_OUTPUT" - echo "RUST_DASHCORE_TOOLCHAIN=$CHANNEL" >> "$GITHUB_ENV" - - - name: Ensure rust-dashcore toolchain has iOS targets - shell: bash - run: | - set -euxo pipefail - RUST_DASHCORE_DIR="$(dirname "$GITHUB_WORKSPACE")/rust-dashcore" - cd "$RUST_DASHCORE_DIR" - TOOLCHAIN="${{ steps.dashcore_toolchain.outputs.channel }}" - rustup toolchain install "$TOOLCHAIN" --profile minimal --no-self-update - rustup target add --toolchain "$TOOLCHAIN" aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios - - name: Clean Xcode derived data and Swift package caches run: | rm -rf ~/Library/Developer/Xcode/DerivedData/* || true @@ -172,7 +110,7 @@ jobs: - name: Build DashSDKFFI.xcframework and install into Swift package run: | - bash packages/swift-sdk/build_ios.sh + bash packages/swift-sdk/build_ios.sh --target all --profile release - name: Zip XCFramework and compute checksum run: | diff --git a/.github/workflows/swift-sdk-release.yml b/.github/workflows/swift-sdk-release.yml index 64857a1d349..ac4dba5d991 100644 --- a/.github/workflows/swift-sdk-release.yml +++ b/.github/workflows/swift-sdk-release.yml @@ -59,7 +59,7 @@ jobs: - name: Build DashSDKFFI.xcframework and install into Swift package run: | - bash packages/swift-sdk/build_ios.sh + bash packages/swift-sdk/build_ios.sh --target all --profile release - name: Zip XCFramework and compute checksum id: zip diff --git a/Cargo.lock b/Cargo.lock index d3c96c19244..a6bcdc931dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,21 +84,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" -[[package]] -name = "anstream" -version = "0.6.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" -dependencies = [ - "anstyle", - "anstyle-parse 0.2.7", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - [[package]] name = "anstream" version = "1.0.0" @@ -106,7 +91,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", - "anstyle-parse 1.0.0", + "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", @@ -120,15 +105,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" -[[package]] -name = "anstyle-parse" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" -dependencies = [ - "utf8parse", -] - [[package]] name = "anstyle-parse" version = "1.0.0" @@ -175,9 +151,9 @@ dependencies = [ [[package]] name = "arc-swap" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9f3647c145568cec02c42054e07bdf9a5a698e15b466fb2341bfc393cd24aa5" +checksum = "a07d1f37ff60921c83bdfc7407723bdefe89b44b98a9b772f225c8f9d67141a6" dependencies = [ "rustversion", ] @@ -271,9 +247,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.16.1" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf" +checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" dependencies = [ "aws-lc-sys", "zeroize", @@ -281,9 +257,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.38.0" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e" +checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399" dependencies = [ "cc", "cmake", @@ -535,7 +511,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "shlex", "syn 2.0.117", ] @@ -638,16 +614,16 @@ dependencies = [ [[package]] name = "blake3" -version = "1.8.3" +version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2468ef7d57b3fb7e16b576e8377cdbde2320c60e1491e961d11da40fc4f02a2d" +checksum = "4d2d5991425dfd0785aed03aedcf0b321d61975c9b5b3689c774a2610ae0b51e" dependencies = [ "arrayref", "arrayvec", "cc", "cfg-if", "constant_time_eq 0.4.2", - "cpufeatures 0.2.17", + "cpufeatures 0.3.0", ] [[package]] @@ -757,19 +733,20 @@ dependencies = [ [[package]] name = "borsh" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" +checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" dependencies = [ "borsh-derive", + "bytes", "cfg_aliases", ] [[package]] name = "borsh-derive" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" +checksum = "bfcfdc083699101d5a7965e49925975f2f55060f94f9a05e7187be95d530ca59" dependencies = [ "once_cell", "proc-macro-crate 3.5.0", @@ -912,9 +889,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.57" +version = "1.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" +checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" dependencies = [ "find-msvc-tools", "jobserver", @@ -1092,7 +1069,7 @@ version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ - "anstream 1.0.0", + "anstream", "anstyle", "clap_lex", "strsim", @@ -1118,9 +1095,9 @@ checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "cmake" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" dependencies = [ "cc", ] @@ -1630,7 +1607,7 @@ dependencies = [ [[package]] name = "dash-spv" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=f92f114b83f6e442af8290611a10f2246ee58d3a#f92f114b83f6e442af8290611a10f2246ee58d3a" +source = "git+https://github.com/dashpay/rust-dashcore?rev=5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a#5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" dependencies = [ "anyhow", "async-trait", @@ -1663,7 +1640,7 @@ dependencies = [ [[package]] name = "dash-spv-ffi" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=f92f114b83f6e442af8290611a10f2246ee58d3a#f92f114b83f6e442af8290611a10f2246ee58d3a" +source = "git+https://github.com/dashpay/rust-dashcore?rev=5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a#5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" dependencies = [ "cbindgen 0.29.2", "clap", @@ -1688,7 +1665,7 @@ dependencies = [ [[package]] name = "dashcore" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=f92f114b83f6e442af8290611a10f2246ee58d3a#f92f114b83f6e442af8290611a10f2246ee58d3a" +source = "git+https://github.com/dashpay/rust-dashcore?rev=5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a#5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" dependencies = [ "anyhow", "base64-compat", @@ -1713,12 +1690,12 @@ dependencies = [ [[package]] name = "dashcore-private" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=f92f114b83f6e442af8290611a10f2246ee58d3a#f92f114b83f6e442af8290611a10f2246ee58d3a" +source = "git+https://github.com/dashpay/rust-dashcore?rev=5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a#5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" [[package]] name = "dashcore-rpc" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=f92f114b83f6e442af8290611a10f2246ee58d3a#f92f114b83f6e442af8290611a10f2246ee58d3a" +source = "git+https://github.com/dashpay/rust-dashcore?rev=5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a#5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" dependencies = [ "dashcore-rpc-json", "hex", @@ -1731,7 +1708,7 @@ dependencies = [ [[package]] name = "dashcore-rpc-json" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=f92f114b83f6e442af8290611a10f2246ee58d3a#f92f114b83f6e442af8290611a10f2246ee58d3a" +source = "git+https://github.com/dashpay/rust-dashcore?rev=5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a#5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" dependencies = [ "bincode", "dashcore", @@ -1746,7 +1723,7 @@ dependencies = [ [[package]] name = "dashcore_hashes" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=f92f114b83f6e442af8290611a10f2246ee58d3a#f92f114b83f6e442af8290611a10f2246ee58d3a" +source = "git+https://github.com/dashpay/rust-dashcore?rev=5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a#5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" dependencies = [ "bincode", "dashcore-private", @@ -1946,7 +1923,7 @@ dependencies = [ "derive_more 1.0.0", "dpp", "dpp-json-convertible-derive", - "env_logger 0.11.9", + "env_logger 0.11.10", "getrandom 0.2.17", "grovedb-commitment-tree", "hex", @@ -2252,9 +2229,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" +checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" dependencies = [ "log", "regex", @@ -2275,11 +2252,11 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" +checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" dependencies = [ - "anstream 0.6.21", + "anstream", "anstyle", "env_filter", "jiff", @@ -3370,7 +3347,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.3", + "socket2 0.5.10", "system-configuration", "tokio", "tower-service", @@ -3591,14 +3568,15 @@ dependencies = [ [[package]] name = "ipconfig" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +checksum = "4d40460c0ce33d6ce4b0630ad68ff63d6661961c48b6dba35e5a4d81cfb48222" dependencies = [ - "socket2 0.5.10", + "socket2 0.6.3", "widestring", - "windows-sys 0.48.0", - "winreg", + "windows-registry", + "windows-result", + "windows-sys 0.61.2", ] [[package]] @@ -3609,9 +3587,9 @@ checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" dependencies = [ "memchr", "serde", @@ -3672,9 +3650,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" @@ -3709,7 +3687,7 @@ dependencies = [ "cesu8", "cfg-if", "combine", - "jni-sys", + "jni-sys 0.3.1", "log", "thiserror 1.0.69", "walkdir", @@ -3718,9 +3696,31 @@ dependencies = [ [[package]] name = "jni-sys" -version = "0.3.0" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.117", +] [[package]] name = "jobserver" @@ -3829,7 +3829,7 @@ dependencies = [ [[package]] name = "key-wallet" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=f92f114b83f6e442af8290611a10f2246ee58d3a#f92f114b83f6e442af8290611a10f2246ee58d3a" +source = "git+https://github.com/dashpay/rust-dashcore?rev=5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a#5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" dependencies = [ "aes", "async-trait", @@ -3857,7 +3857,7 @@ dependencies = [ [[package]] name = "key-wallet-ffi" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=f92f114b83f6e442af8290611a10f2246ee58d3a#f92f114b83f6e442af8290611a10f2246ee58d3a" +source = "git+https://github.com/dashpay/rust-dashcore?rev=5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a#5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" dependencies = [ "cbindgen 0.29.2", "dashcore", @@ -3872,7 +3872,7 @@ dependencies = [ [[package]] name = "key-wallet-manager" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=f92f114b83f6e442af8290611a10f2246ee58d3a#f92f114b83f6e442af8290611a10f2246ee58d3a" +source = "git+https://github.com/dashpay/rust-dashcore?rev=5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a#5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" dependencies = [ "async-trait", "bincode", @@ -4202,9 +4202,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "wasi", @@ -4385,9 +4385,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" [[package]] name = "num-derive" @@ -5034,7 +5034,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.25.4+spec-1.1.0", + "toml_edit 0.25.8+spec-1.1.0", ] [[package]] @@ -5210,9 +5210,9 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c41efbf8f90ac44de7f3a868f0867851d261b56291732d0cbf7cceaaeb55a6" +checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad" dependencies = [ "bitflags 2.11.0", "memchr", @@ -5245,9 +5245,9 @@ dependencies = [ [[package]] name = "quick_cache" -version = "0.6.19" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "530e84778a55de0f52645a51d4e3b9554978acd6a1e7cd50b6a6784692b3029e" +checksum = "5a70b1b8b47e31d0498ecbc3c5470bb931399a8bfed1fd79d1717a61ce7f96e3" dependencies = [ "ahash 0.8.12", "equivalent", @@ -5266,9 +5266,9 @@ dependencies = [ "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "rustls", - "socket2 0.6.3", + "socket2 0.5.10", "thiserror 2.0.18", "tokio", "tracing", @@ -5287,7 +5287,7 @@ dependencies = [ "lru-slab", "rand 0.9.2", "ring", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "rustls", "rustls-pki-types", "slab", @@ -5306,7 +5306,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.3", + "socket2 0.5.10", "tracing", "windows-sys 0.60.2", ] @@ -5850,10 +5850,9 @@ dependencies = [ "bs58", "cbindgen 0.27.0", "dash-sdk", - "dash-spv-ffi", "dotenvy", "drive-proof-verifier", - "env_logger 0.11.9", + "env_logger 0.11.10", "envy", "getrandom 0.2.17", "hex", @@ -5892,6 +5891,15 @@ dependencies = [ "url", ] +[[package]] +name = "rs-unified-sdk-ffi" +version = "3.1.0-dev.1" +dependencies = [ + "dash-spv-ffi", + "key-wallet-ffi", + "rs-sdk-ffi", +] + [[package]] name = "rs-x11-hash" version = "0.1.8" @@ -5940,9 +5948,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61f703d19852dbf87cbc513643fa81428361eb6940f1ac14fd58155d295a3eb0" +checksum = "2ce901f9a19d251159075a4c37af514c3b8ef99c22e02dd8c19161cf397ee94a" dependencies = [ "arrayvec", "borsh", @@ -5952,6 +5960,7 @@ dependencies = [ "rkyv", "serde", "serde_json", + "wasm-bindgen", ] [[package]] @@ -5972,9 +5981,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] name = "rustc_version" @@ -6078,9 +6087,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" dependencies = [ "aws-lc-rs", "ring", @@ -6389,9 +6398,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +checksum = "876ac351060d4f882bb1032b6369eb0aef79ad9df1ea8bc404874d8cc3d0cd98" dependencies = [ "serde_core", ] @@ -6583,9 +6592,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "simdutf8" @@ -7249,7 +7258,7 @@ checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ "indexmap 2.13.0", "serde_core", - "serde_spanned 1.0.4", + "serde_spanned 1.1.0", "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", @@ -7276,9 +7285,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "1.0.0+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e" +checksum = "97251a7c317e03ad83774a8752a7e81fb6067740609f75ea2b585b569a59198f" dependencies = [ "serde_core", ] @@ -7310,23 +7319,23 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.4+spec-1.1.0" +version = "0.25.8+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7193cbd0ce53dc966037f54351dbbcf0d5a642c7f0038c382ef9e677ce8c13f2" +checksum = "16bff38f1d86c47f9ff0647e6838d7bb362522bdf44006c7068c2b1e606f1f3c" dependencies = [ "indexmap 2.13.0", - "toml_datetime 1.0.0+spec-1.1.0", + "toml_datetime 1.1.0+spec-1.1.0", "toml_parser", - "winnow 0.7.15", + "winnow 1.0.1", ] [[package]] name = "toml_parser" -version = "1.0.9+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +checksum = "2334f11ee363607eb04df9b8fc8a13ca1715a72ba8662a26ac285c98aabb4011" dependencies = [ - "winnow 0.7.15", + "winnow 1.0.1", ] [[package]] @@ -7337,9 +7346,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "toml_writer" -version = "1.0.6+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" +checksum = "d282ade6016312faf3e41e57ebbba0c073e4056dab1232ab1cb624199648f8ed" [[package]] name = "tonic" @@ -7732,9 +7741,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" [[package]] name = "unicode-xid" @@ -7766,9 +7775,9 @@ checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" [[package]] name = "ureq" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc97a28575b85cfedf2a7e7d3cc64b3e11bd8ac766666318003abbacc7a21fc" +checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" dependencies = [ "base64 0.22.1", "flate2", @@ -7777,15 +7786,15 @@ dependencies = [ "rustls", "rustls-pki-types", "ureq-proto", - "utf-8", + "utf8-zero", "webpki-roots", ] [[package]] name = "ureq-proto" -version = "0.5.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d81f9efa9df032be5934a46a068815a10a042b494b6a58cb0a1a97bb5467ed6f" +checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c" dependencies = [ "base64 0.22.1", "http", @@ -7811,6 +7820,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8-zero" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -7825,9 +7840,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.22.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ "getrandom 0.4.2", "js-sys", @@ -8382,15 +8397,6 @@ dependencies = [ "windows-targets 0.42.2", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -8442,21 +8448,6 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -8496,12 +8487,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -8520,12 +8505,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -8544,12 +8523,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -8580,12 +8553,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -8604,12 +8571,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -8628,12 +8589,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -8652,12 +8607,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -8689,13 +8638,12 @@ dependencies = [ ] [[package]] -name = "winreg" -version = "0.50.0" +name = "winnow" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" dependencies = [ - "cfg-if", - "windows-sys 0.48.0", + "memchr", ] [[package]] @@ -8872,18 +8820,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.42" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.42" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index bb5f1885824..2a27563d527 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,16 +43,17 @@ members = [ "packages/rs-platform-wallet", "packages/rs-platform-wallet-ffi", "packages/rs-platform-encryption", - "packages/wasm-sdk", + "packages/wasm-sdk", "packages/rs-unified-sdk-ffi", ] [workspace.dependencies] -dashcore = { git = "https://github.com/dashpay/rust-dashcore", rev = "f92f114b83f6e442af8290611a10f2246ee58d3a" } -dash-spv = { git = "https://github.com/dashpay/rust-dashcore", rev = "f92f114b83f6e442af8290611a10f2246ee58d3a" } -dash-spv-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "f92f114b83f6e442af8290611a10f2246ee58d3a" } -key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "f92f114b83f6e442af8290611a10f2246ee58d3a" } -key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "f92f114b83f6e442af8290611a10f2246ee58d3a" } -dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "f92f114b83f6e442af8290611a10f2246ee58d3a" } +dashcore = { git = "https://github.com/dashpay/rust-dashcore", rev = "5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" } +dash-spv = { git = "https://github.com/dashpay/rust-dashcore", rev = "5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" } +dash-spv-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" } +key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" } +key-wallet-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" } +key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" } +dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "5db46b4d2bdc50b0fbc8d9acbebe72775bb4132a" } # Optimize heavy crypto crates even in dev/test builds so that # Halo 2 proof generation and verification run at near-release speed. diff --git a/packages/rs-sdk-ffi/Cargo.toml b/packages/rs-sdk-ffi/Cargo.toml index 7fa859017e6..0f70507bcc2 100644 --- a/packages/rs-sdk-ffi/Cargo.toml +++ b/packages/rs-sdk-ffi/Cargo.toml @@ -22,10 +22,6 @@ rs-sdk-trusted-context-provider = { path = "../rs-sdk-trusted-context-provider", ] } simple-signer = { path = "../simple-signer" } - -# Core SDK integration (always included for unified SDK) -dash-spv-ffi = { workspace = true, optional = true } - # Platform Wallet integration for DashPay support platform-wallet-ffi = { path = "../rs-platform-wallet-ffi" } @@ -82,10 +78,7 @@ serde_json = "1.0" log = "0.4" [features] -default = ["dash_spv"] - -# Enable linking with dash-spv-ffi (Core SDK integration) -dash_spv = ["dep:dash-spv-ffi"] +default = [] # Optional mocks for development/testing; maps to dash-sdk's mocks mocks = ["dash-sdk/mocks"] diff --git a/packages/rs-sdk-ffi/build.rs b/packages/rs-sdk-ffi/build.rs index 0564b587eef..29549edbb55 100644 --- a/packages/rs-sdk-ffi/build.rs +++ b/packages/rs-sdk-ffi/build.rs @@ -1,97 +1,32 @@ -use std::env; use std::path::Path; +use std::{env, fs}; fn main() { + let crate_name = env::var("CARGO_PKG_NAME").unwrap(); let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); let out_dir = env::var("OUT_DIR").unwrap(); - // Only generate bindings when explicitly requested - println!( - "cargo:warning=Build script running, GENERATE_BINDINGS={:?}", - env::var("GENERATE_BINDINGS") - ); - if env::var("GENERATE_BINDINGS").is_ok() { - println!("cargo:warning=Generating unified SDK bindings with cbindgen"); - println!("cargo:warning=OUT_DIR={}", out_dir); + println!("cargo:rerun-if-changed=cbindgen.toml"); + println!("cargo:rerun-if-changed=src/"); - // Enhanced cbindgen configuration for unified SDK - let config = cbindgen::Config { - language: cbindgen::Language::C, - pragma_once: true, - include_guard: Some("DASH_SDK_FFI_H".to_string()), - autogen_warning: Some( - "/* This file is auto-generated. Do not modify manually. */\n/* Unified Dash SDK - includes both Core (SPV) and Platform functionality */".to_string(), - ), - after_includes: Some( - "/* Forward declarations for opaque types */\nstruct ShieldedPoolClient;\n".to_string(), - ), - includes: vec![], - sys_includes: vec!["stdint.h".to_string(), "stdbool.h".to_string()], - no_includes: false, - cpp_compat: true, - documentation: true, - documentation_style: cbindgen::DocumentationStyle::C99, - // Enhanced export configuration from dash-unified-ffi-old - export: cbindgen::ExportConfig { - include: vec![ - "dash_sdk_*".to_string(), // Platform SDK functions - "dash_core_*".to_string(), // Core SDK wrapper functions - "dash_spv_*".to_string(), // Core SDK direct functions - "dash_unified_*".to_string(), // Unified SDK functions - "FFI*".to_string(), // All FFI types - "DashSDK*".to_string(), // Platform SDK types - "CoreSDK*".to_string(), // Core SDK wrapper types - ], - exclude: vec![ - "*_internal_*".to_string(), // Exclude internal functions - ], - item_types: vec![ - cbindgen::ItemType::Functions, - cbindgen::ItemType::Structs, - cbindgen::ItemType::Enums, - cbindgen::ItemType::Constants, - cbindgen::ItemType::Globals, - cbindgen::ItemType::Typedefs, - ], - ..Default::default() - }, - ..Default::default() - }; + let target_dir = Path::new(&out_dir) + .ancestors() + .nth(3) // This line moves up to the target/ directory + .expect("Failed to find target dir"); - // Build unified header with dependency parsing always enabled - let builder = cbindgen::Builder::new() - .with_crate(&crate_dir) - .with_parse_deps(true) // Always parse dependencies for complete type definitions - .with_config(config); + let include_dir = target_dir.join("include").join(&crate_name); - builder - .generate() - .expect("Unable to generate unified bindings") - .write_to_file(Path::new(&out_dir).join("dash_sdk_ffi.h")); + fs::create_dir_all(&include_dir).unwrap(); - println!( - "cargo:warning=Unified header generated successfully at {}/dash_sdk_ffi.h", - out_dir - ); + let output_path = include_dir.join(format!("{}.h", &crate_name)); - // Run header combination script to include missing Core SDK types - let combine_script = Path::new(&crate_dir).join("combine_headers.sh"); - if combine_script.exists() { - println!("cargo:warning=Running header combination script..."); - let output = std::process::Command::new("bash") - .arg(&combine_script) - .current_dir(&crate_dir) - .output() - .expect("Failed to run header combination script"); + let config_path = Path::new(&crate_dir).join("cbindgen.toml"); + let config = cbindgen::Config::from_file(&config_path).expect("Failed to read cbindgen.toml"); - if output.status.success() { - println!("cargo:warning=Header combination completed successfully"); - } else { - println!( - "cargo:warning=Header combination failed: {}", - String::from_utf8_lossy(&output.stderr) - ); - } - } - } + cbindgen::Builder::new() + .with_crate(&crate_dir) + .with_config(config) + .generate() + .expect("Unable to generate bindings") + .write_to_file(&output_path); } diff --git a/packages/rs-sdk-ffi/build_ios.sh b/packages/rs-sdk-ffi/build_ios.sh deleted file mode 100755 index a72884a9eeb..00000000000 --- a/packages/rs-sdk-ffi/build_ios.sh +++ /dev/null @@ -1,546 +0,0 @@ -#!/bin/bash -set -e - -# Build script for Dash SDK FFI (iOS targets) -# This script builds the Rust library for iOS targets and creates an XCFramework -# Usage: ./build_ios.sh [arm|x86|universal] -# Default: arm -# Note: This builds rs-sdk-ffi with unified SDK functions that wrap both Core and Platform - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -PROJECT_ROOT="$SCRIPT_DIR/../.." -PROJECT_NAME="rs_sdk_ffi" - -# Parse arguments -BUILD_ARCH="${1:-arm}" -CLEAN_BUILD=0 - -# Parse command line arguments -for arg in "$@"; do - case $arg in - arm|x86|universal) - BUILD_ARCH="$arg" - ;; - --clean) - CLEAN_BUILD=1 - ;; - esac -done - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# Build with unified SDK support -CARGO_FEATURES="" -FRAMEWORK_NAME="DashSDKFFI" - -# Set iOS deployment targets to match Xcode 16 SDKs and avoid 10.0 default -export IPHONEOS_DEPLOYMENT_TARGET="18.0" -export IPHONESIMULATOR_DEPLOYMENT_TARGET="18.0" -# Ensure linker uses the same min version when rustc links, but only for iOS targets -export CARGO_TARGET_AARCH64_APPLE_IOS_RUSTFLAGS="${CARGO_TARGET_AARCH64_APPLE_IOS_RUSTFLAGS:-} -C link-arg=-mios-version-min=${IPHONEOS_DEPLOYMENT_TARGET}" -export CARGO_TARGET_AARCH64_APPLE_IOS_SIM_RUSTFLAGS="${CARGO_TARGET_AARCH64_APPLE_IOS_SIM_RUSTFLAGS:-} -C link-arg=-mios-version-min=${IPHONESIMULATOR_DEPLOYMENT_TARGET}" -export CARGO_TARGET_X86_64_APPLE_IOS_RUSTFLAGS="${CARGO_TARGET_X86_64_APPLE_IOS_RUSTFLAGS:-} -C link-arg=-mios-version-min=${IPHONESIMULATOR_DEPLOYMENT_TARGET}" - -echo "Using IPHONEOS_DEPLOYMENT_TARGET=${IPHONEOS_DEPLOYMENT_TARGET}" -echo "Using IPHONESIMULATOR_DEPLOYMENT_TARGET=${IPHONESIMULATOR_DEPLOYMENT_TARGET}" -echo "CARGO_TARGET_AARCH64_APPLE_IOS_RUSTFLAGS=${CARGO_TARGET_AARCH64_APPLE_IOS_RUSTFLAGS}" -echo "CARGO_TARGET_AARCH64_APPLE_IOS_SIM_RUSTFLAGS=${CARGO_TARGET_AARCH64_APPLE_IOS_SIM_RUSTFLAGS}" -echo "CARGO_TARGET_X86_64_APPLE_IOS_RUSTFLAGS=${CARGO_TARGET_X86_64_APPLE_IOS_RUSTFLAGS}" - -echo -e "${GREEN}Building Dash SDK FFI for iOS ($BUILD_ARCH)${NC}" - -# Check if we have the required iOS targets installed -check_target() { - if ! rustup target list --installed | grep -q "$1"; then - echo -e "${YELLOW}Installing target $1...${NC}" - rustup target add "$1" > /tmp/rustup_target.log 2>&1 - fi -} - -# Install required targets based on architecture -if [ "$BUILD_ARCH" = "x86" ]; then - check_target "x86_64-apple-ios" -elif [ "$BUILD_ARCH" = "universal" ]; then - check_target "aarch64-apple-ios" - check_target "aarch64-apple-ios-sim" - check_target "x86_64-apple-ios" -else - # Default to ARM - check_target "aarch64-apple-ios" - check_target "aarch64-apple-ios-sim" -fi - -# Detect if rust-dashcore is a local path dependency and has changed since last iOS build -RUST_DASHCORE_DIR="$PROJECT_ROOT/../rust-dashcore" -HASHFILE="$PROJECT_ROOT/target/.rust_dashcore_ios_hash" -if [[ -d "$RUST_DASHCORE_DIR" ]] && grep -q 'path.*rust-dashcore' "$PROJECT_ROOT/packages/rs-sdk-ffi/Cargo.toml" "$PROJECT_ROOT/packages/rs-dpp/Cargo.toml" 2>/dev/null; then - CURRENT_HASH=$(find "$RUST_DASHCORE_DIR/dash/src" "$RUST_DASHCORE_DIR/key-wallet/src" "$RUST_DASHCORE_DIR/dash-spv/src" "$RUST_DASHCORE_DIR/dash-spv-ffi/src" "$RUST_DASHCORE_DIR/key-wallet-manager/src" -name '*.rs' 2>/dev/null | sort | xargs cat 2>/dev/null | shasum -a 256 | cut -d' ' -f1) - PREV_HASH="" - if [[ -f "$HASHFILE" ]]; then - PREV_HASH=$(cat "$HASHFILE") - fi - if [[ "$CURRENT_HASH" != "$PREV_HASH" ]]; then - echo -e "${YELLOW}Local rust-dashcore changes detected — cleaning cached iOS build artifacts${NC}" - CLEAN_BUILD=1 - fi -fi - -if [[ "$CLEAN_BUILD" -eq 1 ]]; then - echo -e "${GREEN}Cleaning rs-sdk-ffi and dependencies for iOS targets...${NC}" - cargo clean --release --target aarch64-apple-ios -p rs-sdk-ffi 2>/dev/null || true - cargo clean --release --target aarch64-apple-ios-sim -p rs-sdk-ffi 2>/dev/null || true - cargo clean --release --target x86_64-apple-ios -p rs-sdk-ffi 2>/dev/null || true - # Also clean path-dependency crates that cargo may cache - for pkg in dashcore key-wallet key-wallet-manager dash-spv dash-spv-ffi rs-platform-wallet rs-platform-wallet-ffi; do - cargo clean --release --target aarch64-apple-ios -p "$pkg" 2>/dev/null || true - cargo clean --release --target aarch64-apple-ios-sim -p "$pkg" 2>/dev/null || true - cargo clean --release --target x86_64-apple-ios -p "$pkg" 2>/dev/null || true - done -fi - -# Build for iOS device (arm64) - always needed -if [ "$BUILD_ARCH" != "x86" ]; then - echo -ne "${GREEN}Building for iOS device (arm64)...${NC}" - if cargo build --lib --target aarch64-apple-ios --release --package rs-sdk-ffi $CARGO_FEATURES > /tmp/cargo_build_device.log 2>&1; then - echo -e "\r${GREEN}✓ iOS device (arm64) build successful${NC} " - else - echo -e "\r${RED}✗ iOS device build failed${NC} " - cat /tmp/cargo_build_device.log - exit 1 - fi -fi - -# Build for iOS simulator based on architecture -if [ "$BUILD_ARCH" = "x86" ]; then - echo -ne "${GREEN}Building for iOS simulator (x86_64)...${NC}" - if cargo build --lib --target x86_64-apple-ios --release --package rs-sdk-ffi $CARGO_FEATURES > /tmp/cargo_build_sim_x86.log 2>&1; then - echo -e "\r${GREEN}✓ iOS simulator (x86_64) build successful${NC} " - else - echo -e "\r${RED}✗ iOS simulator (x86_64) build failed${NC} " - cat /tmp/cargo_build_sim_x86.log - exit 1 - fi -elif [ "$BUILD_ARCH" = "universal" ]; then - echo -ne "${GREEN}Building for iOS simulator (arm64)...${NC}" - if cargo build --lib --target aarch64-apple-ios-sim --release --package rs-sdk-ffi $CARGO_FEATURES > /tmp/cargo_build_sim_arm.log 2>&1; then - echo -e "\r${GREEN}✓ iOS simulator (arm64) build successful${NC} " - else - echo -e "\r${RED}✗ iOS simulator (arm64) build failed${NC} " - cat /tmp/cargo_build_sim_arm.log - exit 1 - fi - echo -ne "${GREEN}Building for iOS simulator (x86_64)...${NC}" - if cargo build --lib --target x86_64-apple-ios --release --package rs-sdk-ffi $CARGO_FEATURES > /tmp/cargo_build_sim_x86.log 2>&1; then - echo -e "\r${GREEN}✓ iOS simulator (x86_64) build successful${NC} " - else - echo -e "\r${RED}✗ iOS simulator (x86_64) build failed${NC} " - cat /tmp/cargo_build_sim_x86.log - exit 1 - fi -else - # Default to ARM - echo -ne "${GREEN}Building for iOS simulator (arm64)...${NC}" - if cargo build --lib --target aarch64-apple-ios-sim --release --package rs-sdk-ffi $CARGO_FEATURES > /tmp/cargo_build_sim_arm.log 2>&1; then - echo -e "\r${GREEN}✓ iOS simulator (arm64) build successful${NC} " - else - echo -e "\r${RED}✗ iOS simulator (arm64) build failed${NC} " - cat /tmp/cargo_build_sim_arm.log - exit 1 - fi -fi - -# Create output directory -OUTPUT_DIR="$SCRIPT_DIR/build" -mkdir -p "$OUTPUT_DIR" - -# Generate C headers -echo -ne "${GREEN}Generating C headers...${NC}" -cd "$PROJECT_ROOT" -if GENERATE_BINDINGS=1 cargo build --lib --release --package rs-sdk-ffi $CARGO_FEATURES > /tmp/cargo_build_headers.log 2>&1; then - if cp "$PROJECT_ROOT/target/release/build/"*"/out/dash_sdk_ffi.h" "$OUTPUT_DIR/" 2>/dev/null; then - echo -e "\r${GREEN}✓ Headers generated successfully${NC} " - else - echo -e "\r${YELLOW}⚠ Generated header not found, using cbindgen...${NC}" - cd "$SCRIPT_DIR" - if cbindgen --config cbindgen-ios.toml --crate rs-sdk-ffi --output "$OUTPUT_DIR/dash_sdk_ffi.h" > /tmp/cbindgen.log 2>&1; then - echo -e "${GREEN}✓ Headers generated with cbindgen${NC}" - else - echo -e "${RED}✗ Failed to generate headers${NC}" - cat /tmp/cbindgen.log - exit 1 - fi - fi -else - echo -e "\r${RED}✗ Header generation build failed${NC} " - cat /tmp/cargo_build_headers.log - exit 1 -fi - -# Merge all FFI headers to create unified header -echo -e "${GREEN}Merging headers...${NC}" -RUST_DASHCORE_PATH="$PROJECT_ROOT/../rust-dashcore" -KEY_WALLET_HEADER_PATH="$RUST_DASHCORE_PATH/key-wallet-ffi/include/key_wallet_ffi.h" -SPV_HEADER_PATH="$RUST_DASHCORE_PATH/dash-spv-ffi/include/dash_spv_ffi.h" - -if [ -f "$KEY_WALLET_HEADER_PATH" ] && [ -f "$SPV_HEADER_PATH" ]; then - # Create merged header with unified include guard - MERGED_HEADER="$OUTPUT_DIR/dash_unified_ffi.h" - - # Start with unified include guard - cat > "$MERGED_HEADER" << 'EOF' -#ifndef DASH_UNIFIED_FFI_H -#define DASH_UNIFIED_FFI_H - -#pragma once - -/* This file is auto-generated by merging Dash SDK, SPV FFI, and Key Wallet FFI headers. Do not modify manually. */ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// Forward declarations to ensure cross-refs compile regardless of merge order -typedef struct FFIClientConfig FFIClientConfig; -// Provide explicit opaque definitions so Swift can import the type names -typedef struct FFIDashSpvClient { unsigned char _private[0]; } FFIDashSpvClient; -typedef struct FFIWallet { unsigned char _private[0]; } FFIWallet; -typedef struct FFIAccount { unsigned char _private[0]; } FFIAccount; -typedef struct FFIAccountCollection { unsigned char _private[0]; } FFIAccountCollection; -typedef struct FFIBLSAccount { unsigned char _private[0]; } FFIBLSAccount; -typedef struct FFIEdDSAAccount { unsigned char _private[0]; } FFIEdDSAAccount; -typedef struct FFIAddressPool { unsigned char _private[0]; } FFIAddressPool; -typedef struct FFIManagedCoreAccountCollection { unsigned char _private[0]; } FFIManagedCoreAccountCollection; -typedef struct FFIManagedCoreAccount { unsigned char _private[0]; } FFIManagedCoreAccount; -// Platform SDK opaque handles -typedef struct SDKHandle { unsigned char _private[0]; } SDKHandle; -typedef struct DataContractHandle { unsigned char _private[0]; } DataContractHandle; -typedef struct DocumentHandle { unsigned char _private[0]; } DocumentHandle; -typedef struct IdentityHandle { unsigned char _private[0]; } IdentityHandle; -typedef struct IdentityPublicKeyHandle { unsigned char _private[0]; } IdentityPublicKeyHandle; -typedef struct SignerHandle { unsigned char _private[0]; } SignerHandle; -// Shielded pool opaque handle -typedef struct ShieldedPoolClient { unsigned char _private[0]; } ShieldedPoolClient; - -// ============================================================================ -// Key Wallet FFI Functions and Types -// ============================================================================ - -EOF - - # Extract Key Wallet FFI content - # 1. Skip everything up to and including the last #include - # 2. Skip header guards and pragma once - # 3. Strip out all __cplusplus extern "C" blocks (we'll add them properly at the end) - # 4. Fix ManagedWalletInfo reference to FFIManagedWalletInfo - # 5. Include all content (including FFINetworks enum which Swift needs) - # 6. Stop at the header guard closing - awk ' - BEGIN { found_stdlib = 0; in_content = 0 } - /^#include / { found_stdlib = 1; next } - /^#include / { next } - /^#include / { next } - /^#include / { next } - /^#include / { next } - /^#ifndef KEY_WALLET_FFI_H/ { next } - /^#define KEY_WALLET_FFI_H/ { next } - /^#pragma once/ { next } - /^\/\* Warning: This file is auto-generated/ { next } - /^\/\* Generated with cbindgen/ { next } - found_stdlib && /^\/\*/ { in_content = 1 } - found_stdlib && /^typedef/ { in_content = 1 } - /^#ifdef __cplusplus$/ { - in_content = 1 - next # Skip the ifdef __cplusplus line - } - /^extern "C" \{$/ { next } # Skip extern "C" opening - /^} \/\/ extern "C"$/ { next } # Skip extern "C" closing - /^#endif.*__cplusplus/ { next } # Skip any endif with __cplusplus - /^#endif \/\* KEY_WALLET_FFI_H \*\/$/ { exit } - in_content { print } - ' "$KEY_WALLET_HEADER_PATH" >> "$MERGED_HEADER" - - # Add separator for SPV FFI - cat >> "$MERGED_HEADER" << 'EOF' - -// ============================================================================ -// Dash SPV FFI Functions and Types -// ============================================================================ - -EOF - - # Extract SPV FFI content - # Skip duplicate types and problematic parts - awk ' - BEGIN { skip = 0 } - /^#include/ { next } - /^#ifndef DASH_SPV_FFI_H/ { next } - /^#define DASH_SPV_FFI_H/ { next } - /^#pragma once/ { next } - /^typedef struct CoreSDKHandle \{/ { skip = 1 } - /^\} CoreSDKHandle;/ && skip { skip = 0; next } - /^#ifdef __cplusplus$/ { next } - /^namespace dash_spv_ffi \{/ { next } - /^extern "C" \{$/ { next } - /^\} \/\/ namespace dash_spv_ffi$/ { next } - /^} \/\/ extern "C"$/ { next } - /^#endif.*__cplusplus/ { next } - /^#endif.*DASH_SPV_FFI_H/ { next } - !skip { print } - ' "$SPV_HEADER_PATH" >> "$MERGED_HEADER" - - # Add separator and SDK content - cat >> "$MERGED_HEADER" << 'EOF' - -// ============================================================================ -// Dash SDK FFI Functions and Types -// ============================================================================ - -EOF - - # Extract SDK FFI content (skip the header include guards and system includes) - sed -e '1,/^#include /d' \ - -e '/^#ifndef DASH_SDK_FFI_H$/d' \ - -e '/^#define DASH_SDK_FFI_H$/d' \ - -e '/^#endif.*DASH_SDK_FFI_H.*$/d' \ - -e '/^#pragma once$/d' \ - -e '/^#ifdef __cplusplus$/d' \ - -e '/^extern "C" {$/d' \ - -e '/^} \/\/ extern "C"$/d' \ - -e '/^#endif.*__cplusplus.*$/d' \ - "$OUTPUT_DIR/dash_sdk_ffi.h" >> "$MERGED_HEADER" - - # Close C++ guard and add compatibility notes - cat >> "$MERGED_HEADER" << 'EOF' - -// ============================================================================ -// Type Compatibility Notes -// ============================================================================ - -// This unified header combines types from: -// 1. Key Wallet FFI - Core wallet functionality (addresses, keys, UTXOs) -// 2. Dash SPV FFI - SPV client and network functionality -// 3. Dash SDK FFI - Platform SDK for identities and documents -// -// Naming conflicts have been resolved: -// - FFINetwork enum from key-wallet-ffi (single network selection) -// - FFINetworks enum from key-wallet-ffi (bit flags for multiple networks) -// - CoreSDKHandle from SPV header is removed to avoid conflicts -// - ManagedWalletInfo references are properly prefixed with FFI - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif /* DASH_UNIFIED_FFI_H */ -EOF - - # Replace the original header reference with unified header - cp "$MERGED_HEADER" "$OUTPUT_DIR/dash_sdk_ffi.h" - echo -e "${GREEN}✓ Headers merged successfully${NC}" -else - echo -e "${YELLOW}⚠ Key Wallet FFI or SPV FFI headers not found${NC}" - echo -e "${YELLOW} Please build key-wallet-ffi and dash-spv-ffi first:${NC}" - echo -e "${YELLOW} cd ../../../rust-dashcore/key-wallet-ffi && cargo build --release${NC}" - echo -e "${YELLOW} cd ../../../rust-dashcore/dash-spv-ffi && cargo build --release${NC}" -fi - -# Build dash-spv-ffi from local rust-dashcore for device and simulator -RUST_DASHCORE_PATH="$PROJECT_ROOT/../rust-dashcore" -SPV_CRATE_PATH="$RUST_DASHCORE_PATH/dash-spv-ffi" -SPV_TARGET_PATH="$RUST_DASHCORE_PATH/target" -if [ -d "$SPV_CRATE_PATH" ]; then - echo -e "${GREEN}Building dash-spv-ffi (local rust-dashcore)${NC}" - pushd "$SPV_CRATE_PATH" >/dev/null - if [ "$BUILD_ARCH" != "x86" ]; then - if [ -n "${RUST_DASHCORE_TOOLCHAIN:-}" ]; then - echo -e "${GREEN}Using toolchain '+${RUST_DASHCORE_TOOLCHAIN}' for device build${NC}" - cargo +"${RUST_DASHCORE_TOOLCHAIN}" build --lib --target aarch64-apple-ios --release > /tmp/cargo_build_spv_device.log 2>&1 || { echo -e "${RED}✗ dash-spv-ffi device build failed${NC}"; cat /tmp/cargo_build_spv_device.log; exit 1; } - else - cargo build --lib --target aarch64-apple-ios --release > /tmp/cargo_build_spv_device.log 2>&1 || { echo -e "${RED}✗ dash-spv-ffi device build failed${NC}"; cat /tmp/cargo_build_spv_device.log; exit 1; } - fi - fi - if [ "$BUILD_ARCH" = "universal" ]; then - if [ -n "${RUST_DASHCORE_TOOLCHAIN:-}" ]; then - echo -e "${GREEN}Using toolchain '+${RUST_DASHCORE_TOOLCHAIN}' for sim builds${NC}" - cargo +"${RUST_DASHCORE_TOOLCHAIN}" build --lib --target aarch64-apple-ios-sim --release > /tmp/cargo_build_spv_sim_arm.log 2>&1 || { echo -e "${RED}✗ dash-spv-ffi sim (arm64) build failed${NC}"; cat /tmp/cargo_build_spv_sim_arm.log; exit 1; } - cargo +"${RUST_DASHCORE_TOOLCHAIN}" build --lib --target x86_64-apple-ios --release > /tmp/cargo_build_spv_sim_x86.log 2>&1 || { echo -e "${RED}✗ dash-spv-ffi sim (x86_64) build failed${NC}"; cat /tmp/cargo_build_spv_sim_x86.log; exit 1; } - else - cargo build --lib --target aarch64-apple-ios-sim --release > /tmp/cargo_build_spv_sim_arm.log 2>&1 || { echo -e "${RED}✗ dash-spv-ffi sim (arm64) build failed${NC}"; cat /tmp/cargo_build_spv_sim_arm.log; exit 1; } - cargo build --lib --target x86_64-apple-ios --release > /tmp/cargo_build_spv_sim_x86.log 2>&1 || { echo -e "${RED}✗ dash-spv-ffi sim (x86_64) build failed${NC}"; cat /tmp/cargo_build_spv_sim_x86.log; exit 1; } - fi - else - if [ -n "${RUST_DASHCORE_TOOLCHAIN:-}" ]; then - echo -e "${GREEN}Using toolchain '+${RUST_DASHCORE_TOOLCHAIN}' for sim build${NC}" - cargo +"${RUST_DASHCORE_TOOLCHAIN}" build --lib --target aarch64-apple-ios-sim --release > /tmp/cargo_build_spv_sim_arm.log 2>&1 || { echo -e "${RED}✗ dash-spv-ffi sim (arm64) build failed${NC}"; cat /tmp/cargo_build_spv_sim_arm.log; exit 1; } - else - cargo build --lib --target aarch64-apple-ios-sim --release > /tmp/cargo_build_spv_sim_arm.log 2>&1 || { echo -e "${RED}✗ dash-spv-ffi sim (arm64) build failed${NC}"; cat /tmp/cargo_build_spv_sim_arm.log; exit 1; } - fi - fi - popd >/dev/null -else - echo -e "${YELLOW}⚠ Local rust-dashcore not found at $SPV_CRATE_PATH; SPV symbols must be provided by rs-sdk-ffi${NC}" -fi - -# Create simulator library based on architecture -mkdir -p "$OUTPUT_DIR/simulator" - -if [ "$BUILD_ARCH" = "x86" ]; then - cp "$PROJECT_ROOT/target/x86_64-apple-ios/release/librs_sdk_ffi.a" "$OUTPUT_DIR/simulator/librs_sdk_ffi.a" -elif [ "$BUILD_ARCH" = "universal" ]; then - echo -e "${GREEN}Creating universal simulator library...${NC}" - lipo -create \ - "$PROJECT_ROOT/target/x86_64-apple-ios/release/librs_sdk_ffi.a" \ - "$PROJECT_ROOT/target/aarch64-apple-ios-sim/release/librs_sdk_ffi.a" \ - -output "$OUTPUT_DIR/simulator/librs_sdk_ffi.a" -else - # Default to ARM - cp "$PROJECT_ROOT/target/aarch64-apple-ios-sim/release/librs_sdk_ffi.a" "$OUTPUT_DIR/simulator/librs_sdk_ffi.a" -fi - -# Copy device library (if built) -if [ "$BUILD_ARCH" != "x86" ]; then - mkdir -p "$OUTPUT_DIR/device" - cp "$PROJECT_ROOT/target/aarch64-apple-ios/release/librs_sdk_ffi.a" "$OUTPUT_DIR/device/" - # Merge with dash-spv-ffi device lib if available - if [ -f "$SPV_TARGET_PATH/aarch64-apple-ios/release/libdash_spv_ffi.a" ]; then - echo -e "${GREEN}Merging device libs (rs-sdk-ffi + dash-spv-ffi)${NC}" - libtool -static -o "$OUTPUT_DIR/device/libDashSDKFFI_combined.a" \ - "$OUTPUT_DIR/device/librs_sdk_ffi.a" \ - "$SPV_TARGET_PATH/aarch64-apple-ios/release/libdash_spv_ffi.a" - COMBINED_DEVICE_LIB=1 - fi -fi - -# Create module map; include SDK, SPV, and KeyWallet headers -cat > "$OUTPUT_DIR/module.modulemap" << EOF -module DashSDKFFI { - header "dash_sdk_ffi.h" - export * -} - -module DashSPVFFI { - header "dash_spv_ffi.h" - export * -} - -module KeyWalletFFI { - header "key_wallet_ffi.h" - export * -} -EOF - -# Prepare headers directory for XCFramework -HEADERS_DIR="$OUTPUT_DIR/headers" -mkdir -p "$HEADERS_DIR" -cp "$OUTPUT_DIR/dash_sdk_ffi.h" "$HEADERS_DIR/" -cp "$OUTPUT_DIR/module.modulemap" "$HEADERS_DIR/" - -# Also copy raw SPV and KeyWallet headers (SPV now includes KeyWallet) -RUST_DASHCORE_PATH="$PROJECT_ROOT/../rust-dashcore" -KEY_WALLET_HEADER_PATH="$RUST_DASHCORE_PATH/key-wallet-ffi/include/key_wallet_ffi.h" -SPV_HEADER_PATH="$RUST_DASHCORE_PATH/dash-spv-ffi/include/dash_spv_ffi.h" - -if [ -f "$SPV_HEADER_PATH" ]; then - cp "$SPV_HEADER_PATH" "$HEADERS_DIR/" -else - echo -e "${YELLOW}⚠ Missing SPV header at $SPV_HEADER_PATH${NC}" -fi - -if [ -f "$KEY_WALLET_HEADER_PATH" ]; then - cp "$KEY_WALLET_HEADER_PATH" "$HEADERS_DIR/" -else - echo -e "${YELLOW}⚠ Missing KeyWallet header at $KEY_WALLET_HEADER_PATH${NC}" -fi - -# Create XCFramework -echo -e "${GREEN}Creating XCFramework...${NC}" -rm -rf "$OUTPUT_DIR/$FRAMEWORK_NAME.xcframework" - -# Build XCFramework command based on what was built -XCFRAMEWORK_CMD="xcodebuild -create-xcframework" - -if [ "$BUILD_ARCH" != "x86" ] && [ -f "$OUTPUT_DIR/device/librs_sdk_ffi.a" ]; then - if [ -n "${COMBINED_DEVICE_LIB:-}" ] && [ -f "$OUTPUT_DIR/device/libDashSDKFFI_combined.a" ]; then - XCFRAMEWORK_CMD="$XCFRAMEWORK_CMD -library $OUTPUT_DIR/device/libDashSDKFFI_combined.a -headers $HEADERS_DIR" - else - XCFRAMEWORK_CMD="$XCFRAMEWORK_CMD -library $OUTPUT_DIR/device/librs_sdk_ffi.a -headers $HEADERS_DIR" - fi -fi - -if [ -f "$OUTPUT_DIR/simulator/librs_sdk_ffi.a" ]; then - # Try to merge with SPV sim lib if it exists - SIM_SPV_LIB="" - if [ -f "$SPV_TARGET_PATH/aarch64-apple-ios-sim/release/libdash_spv_ffi.a" ]; then - SIM_SPV_LIB="$SPV_TARGET_PATH/aarch64-apple-ios-sim/release/libdash_spv_ffi.a" - elif [ -f "$SPV_TARGET_PATH/x86_64-apple-ios/release/libdash_spv_ffi.a" ]; then - SIM_SPV_LIB="$SPV_TARGET_PATH/x86_64-apple-ios/release/libdash_spv_ffi.a" - fi - if [ -n "$SIM_SPV_LIB" ]; then - echo -e "${GREEN}Merging simulator libs (rs-sdk-ffi + dash-spv-ffi)${NC}" - libtool -static -o "$OUTPUT_DIR/simulator/libDashSDKFFI_combined.a" \ - "$OUTPUT_DIR/simulator/librs_sdk_ffi.a" \ - "$SIM_SPV_LIB" - XCFRAMEWORK_CMD="$XCFRAMEWORK_CMD -library $OUTPUT_DIR/simulator/libDashSDKFFI_combined.a -headers $HEADERS_DIR" - else - XCFRAMEWORK_CMD="$XCFRAMEWORK_CMD -library $OUTPUT_DIR/simulator/librs_sdk_ffi.a -headers $HEADERS_DIR" - fi -fi - -XCFRAMEWORK_CMD="$XCFRAMEWORK_CMD -output $OUTPUT_DIR/$FRAMEWORK_NAME.xcframework" - -if eval $XCFRAMEWORK_CMD > /tmp/xcframework.log 2>&1; then - echo -e "${GREEN}✓ XCFramework created successfully${NC}" -else - echo -e "${RED}✗ XCFramework creation failed${NC}" - cat /tmp/xcframework.log - exit 1 -fi - -# Save rust-dashcore hash so next build can detect changes -if [[ -n "${CURRENT_HASH:-}" ]]; then - mkdir -p "$(dirname "$HASHFILE")" - echo "$CURRENT_HASH" > "$HASHFILE" -fi - -echo -e "\n${GREEN}Build complete!${NC}" -echo -e "Output: ${YELLOW}$OUTPUT_DIR/$FRAMEWORK_NAME.xcframework${NC}" - -# Copy XCFramework to Swift SDK directory -SWIFT_SDK_DIR="$PROJECT_ROOT/packages/swift-sdk" -if [ -d "$SWIFT_SDK_DIR" ]; then - echo -e "\n${GREEN}Copying XCFramework to Swift SDK...${NC}" - rm -rf "$SWIFT_SDK_DIR/$FRAMEWORK_NAME.xcframework" - cp -R "$OUTPUT_DIR/$FRAMEWORK_NAME.xcframework" "$SWIFT_SDK_DIR/" - echo -e "${GREEN}✓ XCFramework copied to ${YELLOW}$SWIFT_SDK_DIR/$FRAMEWORK_NAME.xcframework${NC}" - - # Best-effort: resolve package dependencies and clean stale references in Xcode project - if command -v xcodebuild >/dev/null 2>&1; then - if [ -d "$SWIFT_SDK_DIR/SwiftExampleApp/SwiftExampleApp.xcodeproj" ]; then - echo -e "\n${GREEN}Resolving Swift package dependencies for SwiftExampleApp...${NC}" - (cd "$SWIFT_SDK_DIR" && xcodebuild -project SwiftExampleApp/SwiftExampleApp.xcodeproj -resolvePackageDependencies >/tmp/xcode_resolve.log 2>&1 || true) - - # Optional clean of DerivedData for a fresh build - if [ "${CLEAN_DERIVED_DATA:-0}" = "1" ]; then - echo -e "${YELLOW}Cleaning DerivedData for SwiftExampleApp (CLEAN_DERIVED_DATA=1)...${NC}" - rm -rf "$HOME/Library/Developer/Xcode/DerivedData"/SwiftExampleApp-* 2>/dev/null || true - fi - - # Validate headers and module visibility - echo -e "${GREEN}Validating DashSDKFFI.xcframework presence in SwiftDashSDK Package.swift...${NC}" - if ! grep -q "DashSDKFFI.xcframework" "$SWIFT_SDK_DIR/Package.swift"; then - echo -e "${YELLOW}⚠ DashSDKFFI.xcframework not referenced in Package.swift. Please update the binaryTarget path.${NC}" - fi - fi - else - echo -e "${YELLOW}xcodebuild not found; skipping Xcode project dependency resolution.${NC}" - fi -fi diff --git a/packages/rs-sdk-ffi/cbindgen-core.toml b/packages/rs-sdk-ffi/cbindgen-core.toml deleted file mode 100644 index 5407f15a91b..00000000000 --- a/packages/rs-sdk-ffi/cbindgen-core.toml +++ /dev/null @@ -1,66 +0,0 @@ -# cbindgen configuration for Dash SDK FFI with Core features enabled - -language = "C" -pragma_once = true -include_guard = "DASH_SDK_FFI_H" -autogen_warning = "/* This file is auto-generated. Do not modify manually. */" -include_version = true -namespaces = [] -using_namespaces = [] -sys_includes = ["stdint.h", "stdbool.h"] -includes = ["dash_spv_ffi.h"] -no_includes = false -cpp_compat = true -documentation = true -documentation_style = "c99" - -[defines] - -[export] -include = ["dash_sdk_*", "dash_core_*", "dash_unified_sdk_*", "FFI*"] -# Exclude types that come from key-wallet-ffi or dash-spv-ffi to avoid duplication -exclude = ["FFIAccountType", "FFIAccountTypePreference", "FFIAccountTypeUsed", "FFIAccountCreationOptionType"] -prefix = "" -item_types = ["enums", "structs", "unions", "typedefs", "opaque", "functions"] - -[export.rename] -"SDKHandle" = "dash_sdk_handle_t" -"SDKError" = "dash_sdk_error_t" - -[fn] -args = "horizontal" -rename_args = "snake_case" -must_use = "DASH_SDK_WARN_UNUSED_RESULT" -prefix = "" -postfix = "" - -[struct] -rename_fields = "snake_case" -derive_constructor = false -derive_eq = false -derive_neq = false -derive_lt = false -derive_lte = false -derive_gt = false -derive_gte = false - -[enum] -rename_variant_name_fields = "snake_case" -add_sentinel = false -prefix_with_name = true -derive_helper_methods = false -derive_const_casts = false -derive_mut_casts = false -cast_assert_name = "assert" -must_use = "DASH_SDK_WARN_UNUSED_RESULT" - -[const] -allow_static_const = true -allow_constexpr = false -sort_by = "name" - -[macro_expansion] -bitflags = false - -[parse] -parse_deps = false diff --git a/packages/rs-sdk-ffi/cbindgen-ios.toml b/packages/rs-sdk-ffi/cbindgen-ios.toml deleted file mode 100644 index 70db07d678f..00000000000 --- a/packages/rs-sdk-ffi/cbindgen-ios.toml +++ /dev/null @@ -1,66 +0,0 @@ -# cbindgen configuration for Dash SDK FFI (iOS without Core SDK conflicts) - -language = "C" -pragma_once = true -include_guard = "DASH_SDK_FFI_H" -autogen_warning = "/* This file is auto-generated. Do not modify manually. */" -include_version = true -namespaces = [] -using_namespaces = [] -sys_includes = ["stdint.h", "stdbool.h"] -includes = [] -no_includes = false -cpp_compat = true -documentation = true -documentation_style = "c99" - -[defines] - -[export] -include = ["dash_sdk_*", "dash_core_*", "dash_unified_sdk_*", "dash_spv_ffi_*"] -# Exclude types that come from key-wallet-ffi to avoid duplication -exclude = ["FFIAccountType", "FFIAccountTypePreference", "FFIAccountTypeUsed", "FFIAccountCreationOptionType"] -prefix = "" -item_types = ["enums", "structs", "unions", "typedefs", "opaque", "functions"] - -[export.rename] -"SDKHandle" = "dash_sdk_handle_t" -"SDKError" = "dash_sdk_error_t" - -[fn] -args = "horizontal" -rename_args = "snake_case" -must_use = "DASH_SDK_WARN_UNUSED_RESULT" -prefix = "" -postfix = "" - -[struct] -rename_fields = "snake_case" -derive_constructor = false -derive_eq = false -derive_neq = false -derive_lt = false -derive_lte = false -derive_gt = false -derive_gte = false - -[enum] -rename_variant_name_fields = "snake_case" -add_sentinel = false -prefix_with_name = true -derive_helper_methods = false -derive_const_casts = false -derive_mut_casts = false -cast_assert_name = "assert" -must_use = "DASH_SDK_WARN_UNUSED_RESULT" - -[const] -allow_static_const = true -allow_constexpr = false -sort_by = "name" - -[macro_expansion] -bitflags = false - -[parse] -parse_deps = false diff --git a/packages/rs-sdk-ffi/cbindgen.toml b/packages/rs-sdk-ffi/cbindgen.toml index 678cbb358ca..526247eeebc 100644 --- a/packages/rs-sdk-ffi/cbindgen.toml +++ b/packages/rs-sdk-ffi/cbindgen.toml @@ -1,5 +1,3 @@ -# cbindgen configuration for Dash SDK FFI - language = "C" pragma_once = true include_guard = "DASH_SDK_FFI_H" @@ -8,7 +6,7 @@ include_version = true namespaces = [] using_namespaces = [] sys_includes = ["stdint.h", "stdbool.h"] -includes = ["dash_spv_ffi.h"] +includes = [] no_includes = false cpp_compat = true documentation = true @@ -24,8 +22,6 @@ prefix = "" item_types = ["enums", "structs", "unions", "typedefs", "opaque", "functions"] [export.rename] -"SDKHandle" = "dash_sdk_handle_t" -"SDKError" = "dash_sdk_error_t" [fn] args = "horizontal" @@ -47,7 +43,7 @@ derive_gte = false [enum] rename_variant_name_fields = "snake_case" add_sentinel = false -prefix_with_name = true +prefix_with_name = false derive_helper_methods = false derive_const_casts = false derive_mut_casts = false diff --git a/packages/rs-sdk-ffi/cbindgen_minimal.toml b/packages/rs-sdk-ffi/cbindgen_minimal.toml deleted file mode 100644 index aa5360baae1..00000000000 --- a/packages/rs-sdk-ffi/cbindgen_minimal.toml +++ /dev/null @@ -1,22 +0,0 @@ -language = "C" -pragma_once = true -include_guard = "DASH_SDK_FFI_H" -autogen_warning = "/* This file is auto-generated. Do not modify manually. */" -include_version = true -sys_includes = ["stdint.h", "stdbool.h"] -cpp_compat = true - -[export] -include = ["dash_sdk_*"] -prefix = "dash_sdk_" - -[fn] -rename_args = "snake_case" -prefix = "dash_sdk_" - -[struct] -rename_fields = "snake_case" - -[enum] -rename_variants = "ScreamingSnakeCase" -prefix_with_name = true diff --git a/packages/rs-sdk-ffi/combine_headers.sh b/packages/rs-sdk-ffi/combine_headers.sh deleted file mode 100755 index 4cc48907aa1..00000000000 --- a/packages/rs-sdk-ffi/combine_headers.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash -# Script to add missing Core SDK type definitions to generated header - -set -e - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -OUT_DIR="${OUT_DIR:-$SCRIPT_DIR/build}" -HEADER_FILE="$OUT_DIR/dash_sdk_ffi.h" - -echo "Adding Core SDK type aliases to $HEADER_FILE" - -# Check if header file exists -if [ ! -f "$HEADER_FILE" ]; then - echo "Header file not found: $HEADER_FILE" - exit 1 -fi - -# Add type aliases after the FFI type definitions -# Find where to insert the typedefs (after FFIDashSpvClient typedef) -if grep -q "typedef struct FFIDashSpvClient FFIDashSpvClient;" "$HEADER_FILE"; then - # Create a temporary file - TEMP_FILE=$(mktemp) - - # Process the file to add typedefs - awk ' - /typedef struct FFIDashSpvClient FFIDashSpvClient;/ { - print $0 - print "" - print "/**" - print " * Type aliases for Core SDK compatibility" - print " */" - print "typedef FFIClientConfig CoreSDKConfig;" - print "typedef FFIDashSpvClient CoreSDKClient;" - added = 1 - next - } - { print } - ' "$HEADER_FILE" > "$TEMP_FILE" - - # Replace original file - mv "$TEMP_FILE" "$HEADER_FILE" - echo "Successfully added Core SDK type aliases" -else - echo "Warning: Could not find FFIDashSpvClient typedef in header" -fi diff --git a/packages/rs-sdk-ffi/include/dash_sdk_ffi.h b/packages/rs-sdk-ffi/include/dash_sdk_ffi.h deleted file mode 100644 index b57b79965e1..00000000000 --- a/packages/rs-sdk-ffi/include/dash_sdk_ffi.h +++ /dev/null @@ -1,2274 +0,0 @@ -#ifndef DASH_SDK_FFI_H -#define DASH_SDK_FFI_H - -#pragma once - -/* Generated with cbindgen:0.29.0 */ - -/* This file is auto-generated. Do not modify manually. */ - -#include -#include -#include -#include -#include -#include -#include "dash_spv_ffi.h" - -// Authorized action takers for token operations -typedef enum DashSDKAuthorizedActionTakers { - // No one can perform the action - DashSDKAuthorizedActionTakers_NoOne = 0, - // Only the contract owner can perform the action - DashSDKAuthorizedActionTakers_AuthorizedContractOwner = 1, - // Main group can perform the action - DashSDKAuthorizedActionTakers_MainGroup = 2, - // A specific identity (requires identity_id to be set) - DashSDKAuthorizedActionTakers_Identity = 3, - // A specific group (requires group_position to be set) - DashSDKAuthorizedActionTakers_Group = 4, -} DashSDKAuthorizedActionTakers; - -// Error codes returned by FFI functions -typedef enum DashSDKErrorCode { - // Operation completed successfully - DashSDKErrorCode_Success = 0, - // Invalid parameter passed to function - DashSDKErrorCode_InvalidParameter = 1, - // SDK not initialized or in invalid state - DashSDKErrorCode_InvalidState = 2, - // Network error occurred - DashSDKErrorCode_NetworkError = 3, - // Serialization/deserialization error - DashSDKErrorCode_SerializationError = 4, - // Platform protocol error - DashSDKErrorCode_ProtocolError = 5, - // Cryptographic operation failed - DashSDKErrorCode_CryptoError = 6, - // Resource not found - DashSDKErrorCode_NotFound = 7, - // Operation timed out - DashSDKErrorCode_Timeout = 8, - // Feature not implemented - DashSDKErrorCode_NotImplemented = 9, - // Internal error - DashSDKErrorCode_InternalError = 99, -} DashSDKErrorCode; - -// Gas fees payer option -typedef enum DashSDKGasFeesPaidBy { - // The document owner pays the gas fees - DashSDKGasFeesPaidBy_DocumentOwner = 0, - // The contract owner pays the gas fees - DashSDKGasFeesPaidBy_GasFeesContractOwner = 1, - // Prefer contract owner but fallback to document owner if insufficient balance - DashSDKGasFeesPaidBy_GasFeesPreferContractOwner = 2, -} DashSDKGasFeesPaidBy; - -// Network type for SDK configuration -typedef enum DashSDKNetwork { - // Mainnet - DashSDKNetwork_SDKMainnet = 0, - // Testnet - DashSDKNetwork_SDKTestnet = 1, - // Regtest - DashSDKNetwork_SDKRegtest = 2, - // Devnet - DashSDKNetwork_SDKDevnet = 3, - // Local development network - DashSDKNetwork_SDKLocal = 4, -} DashSDKNetwork; - -// Result data type indicator for iOS -typedef enum DashSDKResultDataType { - // No data (void/null) - DashSDKResultDataType_None = 0, - // C string (char*) - DashSDKResultDataType_String = 1, - // Binary data with length - DashSDKResultDataType_BinaryData = 2, - // Identity handle - DashSDKResultDataType_ResultIdentityHandle = 3, - // Document handle - DashSDKResultDataType_ResultDocumentHandle = 4, - // Data contract handle - DashSDKResultDataType_ResultDataContractHandle = 5, - // Map of identity IDs to balances - DashSDKResultDataType_IdentityBalanceMap = 6, - // Public key handle - DashSDKResultDataType_ResultPublicKeyHandle = 7, -} DashSDKResultDataType; - -// Token configuration update type -typedef enum DashSDKTokenConfigUpdateType { - // No change - DashSDKTokenConfigUpdateType_NoChange = 0, - // Update max supply (requires amount field) - DashSDKTokenConfigUpdateType_MaxSupply = 1, - // Update minting allow choosing destination (requires bool_value field) - DashSDKTokenConfigUpdateType_MintingAllowChoosingDestination = 2, - // Update new tokens destination identity (requires identity_id field) - DashSDKTokenConfigUpdateType_NewTokensDestinationIdentity = 3, - // Update manual minting permissions (requires action_takers field) - DashSDKTokenConfigUpdateType_ManualMinting = 4, - // Update manual burning permissions (requires action_takers field) - DashSDKTokenConfigUpdateType_ManualBurning = 5, - // Update freeze permissions (requires action_takers field) - DashSDKTokenConfigUpdateType_Freeze = 6, - // Update unfreeze permissions (requires action_takers field) - DashSDKTokenConfigUpdateType_Unfreeze = 7, - // Update main control group (requires group_position field) - DashSDKTokenConfigUpdateType_MainControlGroup = 8, -} DashSDKTokenConfigUpdateType; - -// Token distribution type for claim operations -typedef enum DashSDKTokenDistributionType { - // Pre-programmed distribution - DashSDKTokenDistributionType_PreProgrammed = 0, - // Perpetual distribution - DashSDKTokenDistributionType_Perpetual = 1, -} DashSDKTokenDistributionType; - -// Token emergency action type -typedef enum DashSDKTokenEmergencyAction { - // Pause token operations - DashSDKTokenEmergencyAction_Pause = 0, - // Resume token operations - DashSDKTokenEmergencyAction_Resume = 1, -} DashSDKTokenEmergencyAction; - -// Token pricing type -typedef enum DashSDKTokenPricingType { - // Single flat price for all amounts - DashSDKTokenPricingType_SinglePrice = 0, - // Tiered pricing based on amounts - DashSDKTokenPricingType_SetPrices = 1, -} DashSDKTokenPricingType; - -// FFI-compatible network enum for key wallet operations -typedef enum FFIKeyNetwork { - FFIKeyNetwork_KeyMainnet = 0, - FFIKeyNetwork_KeyTestnet = 1, - FFIKeyNetwork_KeyRegtest = 2, - FFIKeyNetwork_KeyDevnet = 3, -} FFIKeyNetwork; - -// State transition type for key selection -typedef enum StateTransitionType { - StateTransitionType_IdentityUpdate = 0, - StateTransitionType_IdentityTopUp = 1, - StateTransitionType_IdentityCreditTransfer = 2, - StateTransitionType_IdentityCreditWithdrawal = 3, - StateTransitionType_DocumentsBatch = 4, - StateTransitionType_DataContractCreate = 5, - StateTransitionType_DataContractUpdate = 6, -} StateTransitionType; - -// Opaque handle to a DataContract -typedef struct DataContractHandle DataContractHandle; - -// Opaque handle to a Document -typedef struct DocumentHandle DocumentHandle; - -// Opaque handle for an extended private key -typedef struct FFIExtendedPrivKey FFIExtendedPrivKey; - -// Opaque handle for an extended public key -typedef struct FFIExtendedPubKey FFIExtendedPubKey; - -// Opaque handle for a BIP39 mnemonic -typedef struct FFIMnemonic FFIMnemonic; - -// Opaque handle for a transaction -typedef struct FFITransaction FFITransaction; - -// Opaque handle to an Identity -typedef struct IdentityHandle IdentityHandle; - -// Opaque handle to an IdentityPublicKey -typedef struct IdentityPublicKeyHandle IdentityPublicKeyHandle; - -// Opaque handle to an SDK instance -typedef struct dash_sdk_handle_t dash_sdk_handle_t; - -// Opaque handle to a Signer -typedef struct SignerHandle SignerHandle; - -// Error structure returned by FFI functions -typedef struct DashSDKError { - // Error code - enum DashSDKErrorCode code; - // Human-readable error message (null-terminated C string) - // Caller must free this with dash_sdk_error_free - char *message; -} DashSDKError; - -// Result type for FFI functions that return data -typedef struct DashSDKResult { - // Type of data being returned - enum DashSDKResultDataType data_type; - // Pointer to the result data (null on error) - void *data; - // Error information (null on success) - struct DashSDKError *error; -} DashSDKResult; - -// Opaque handle to a context provider -typedef struct ContextProviderHandle { - uint8_t private_[0]; -} ContextProviderHandle; - -typedef struct FFIDashSpvClient { - uint8_t opaque[0]; -} FFIDashSpvClient; - -// Handle for Core SDK that can be passed to Platform SDK -// This matches the definition from dash_spv_ffi.h -typedef struct CoreSDKHandle { - struct FFIDashSpvClient *client; -} CoreSDKHandle; - -// Result type for FFI callbacks -typedef struct CallbackResult { - bool success; - int32_t error_code; - const char *error_message; -} CallbackResult; - -// Function pointer type for getting platform activation height -typedef struct CallbackResult (*GetPlatformActivationHeightFn)(void *handle, uint32_t *out_height); - -// Function pointer type for getting quorum public key -typedef struct CallbackResult (*GetQuorumPublicKeyFn)(void *handle, uint32_t quorum_type, const uint8_t *quorum_hash, uint32_t core_chain_locked_height, uint8_t *out_pubkey); - -// Container for context provider callbacks -typedef struct ContextProviderCallbacks { - // Handle to the Core SDK instance - void *core_handle; - // Function to get platform activation height - GetPlatformActivationHeightFn get_platform_activation_height; - // Function to get quorum public key - GetQuorumPublicKeyFn get_quorum_public_key; -} ContextProviderCallbacks; - -// Document creation parameters -typedef struct DashSDKDocumentCreateParams { - // Data contract handle - const struct DataContractHandle *data_contract_handle; - // Document type name - const char *document_type; - // Owner identity handle - const struct IdentityHandle *owner_identity_handle; - // JSON string of document properties - const char *properties_json; -} DashSDKDocumentCreateParams; - -// Token payment information for transactions -typedef struct DashSDKTokenPaymentInfo { - // Payment token contract ID (32 bytes), null for same contract - const uint8_t (*payment_token_contract_id)[32]; - // Token position within the contract (0-based index) - uint16_t token_contract_position; - // Minimum token cost (0 means no minimum) - uint64_t minimum_token_cost; - // Maximum token cost (0 means no maximum) - uint64_t maximum_token_cost; - // Who pays the gas fees - enum DashSDKGasFeesPaidBy gas_fees_paid_by; -} DashSDKTokenPaymentInfo; - -// Put settings for platform operations -typedef struct DashSDKPutSettings { - // Timeout for establishing a connection (milliseconds), 0 means use default - uint64_t connect_timeout_ms; - // Timeout for single request (milliseconds), 0 means use default - uint64_t timeout_ms; - // Number of retries in case of failed requests, 0 means use default - uint32_t retries; - // Ban DAPI address if node not responded or responded with error - bool ban_failed_address; - // Identity nonce stale time in seconds, 0 means use default - uint64_t identity_nonce_stale_time_s; - // User fee increase (additional percentage of processing fee), 0 means no increase - uint16_t user_fee_increase; - // Enable signing with any security level (for debugging) - bool allow_signing_with_any_security_level; - // Enable signing with any purpose (for debugging) - bool allow_signing_with_any_purpose; - // Wait timeout in milliseconds, 0 means use default - uint64_t wait_timeout_ms; -} DashSDKPutSettings; - -// State transition creation options for advanced use cases -typedef struct DashSDKStateTransitionCreationOptions { - // Allow signing with any security level (for debugging) - bool allow_signing_with_any_security_level; - // Allow signing with any purpose (for debugging) - bool allow_signing_with_any_purpose; - // Batch feature version (0 means use default) - uint16_t batch_feature_version; - // Method feature version (0 means use default) - uint16_t method_feature_version; - // Base feature version (0 means use default) - uint16_t base_feature_version; -} DashSDKStateTransitionCreationOptions; - -// Document information -typedef struct DashSDKDocumentInfo { - // Document ID as hex string (null-terminated) - char *id; - // Owner ID as hex string (null-terminated) - char *owner_id; - // Data contract ID as hex string (null-terminated) - char *data_contract_id; - // Document type (null-terminated) - char *document_type; - // Revision number - uint64_t revision; - // Created at timestamp (milliseconds since epoch) - int64_t created_at; - // Updated at timestamp (milliseconds since epoch) - int64_t updated_at; -} DashSDKDocumentInfo; - -// Document search parameters -typedef struct DashSDKDocumentSearchParams { - // Data contract handle - const struct DataContractHandle *data_contract_handle; - // Document type name - const char *document_type; - // JSON string of where clauses (optional) - const char *where_json; - // JSON string of order by clauses (optional) - const char *order_by_json; - // Limit number of results (0 = default) - uint32_t limit; - // Start from index (for pagination) - uint32_t start_at; -} DashSDKDocumentSearchParams; - -// Public key data for creating identity -typedef struct DashSDKPublicKeyData { - // Key ID (0-255) - uint8_t id; - // Key purpose (0-6) - uint8_t purpose; - // Security level (0-3) - uint8_t security_level; - // Key type (0-4) - uint8_t key_type; - // Whether key is read-only - bool read_only; - // Public key data pointer - const uint8_t *data; - // Public key data length - uintptr_t data_len; - // Disabled timestamp (0 if not disabled) - uint64_t disabled_at; -} DashSDKPublicKeyData; - -// Identity information -typedef struct DashSDKIdentityInfo { - // Identity ID as hex string (null-terminated) - char *id; - // Balance in credits - uint64_t balance; - // Revision number - uint64_t revision; - // Public keys count - uint32_t public_keys_count; -} DashSDKIdentityInfo; - -// Result structure for credit transfer operations -typedef struct DashSDKTransferCreditsResult { - // Sender's final balance after transfer - uint64_t sender_balance; - // Receiver's final balance after transfer - uint64_t receiver_balance; -} DashSDKTransferCreditsResult; - -// SDK configuration -typedef struct DashSDKConfig { - // Network to connect to - enum DashSDKNetwork network; - // Comma-separated list of DAPI addresses (e.g., "http://127.0.0.1:3000,http://127.0.0.1:3001") - // If null or empty, will use mock SDK - const char *dapi_addresses; - // Skip asset lock proof verification (for testing) - bool skip_asset_lock_proof_verification; - // Number of retries for failed requests - uint32_t request_retry_count; - // Timeout for requests in milliseconds - uint64_t request_timeout_ms; -} DashSDKConfig; - -// Extended SDK configuration with context provider support -typedef struct DashSDKConfigExtended { - // Base SDK configuration - struct DashSDKConfig base_config; - // Optional context provider handle - struct ContextProviderHandle *context_provider; - // Optional Core SDK handle for automatic context provider creation - struct CoreSDKHandle *core_sdk_handle; -} DashSDKConfigExtended; - -// Function pointer type for iOS signing callback -// Returns pointer to allocated byte array (caller must free with dash_sdk_bytes_free) -// Returns null on error -typedef uint8_t *(*IOSSignCallback)(const uint8_t *identity_public_key_bytes, uintptr_t identity_public_key_len, const uint8_t *data, uintptr_t data_len, uintptr_t *result_len); - -// Function pointer type for iOS can_sign_with callback -typedef bool (*IOSCanSignCallback)(const uint8_t *identity_public_key_bytes, uintptr_t identity_public_key_len); - -// Optional custom deallocator for sign result buffers. -// When provided, this function is called to free the buffer returned by the -// sign callback instead of the default libc free. Pass NULL to use libc free. -typedef void (*FreeResultCallback)(uint8_t *data, uintptr_t len); - -// Signature result structure -typedef struct DashSDKSignature { - uint8_t *signature; - uintptr_t signature_len; -} DashSDKSignature; - -// Token burn parameters -typedef struct DashSDKTokenBurnParams { - // Token contract ID (Base58 encoded) - mutually exclusive with serialized_contract - const char *token_contract_id; - // Serialized data contract (bincode) - mutually exclusive with token_contract_id - const uint8_t *serialized_contract; - // Length of serialized contract data - uintptr_t serialized_contract_len; - // Token position in the contract (defaults to 0 if not specified) - uint16_t token_position; - // Amount to burn - uint64_t amount; - // Optional public note - const char *public_note; -} DashSDKTokenBurnParams; - -// Token claim parameters -typedef struct DashSDKTokenClaimParams { - // Token contract ID (Base58 encoded) - mutually exclusive with serialized_contract - const char *token_contract_id; - // Serialized data contract (bincode) - mutually exclusive with token_contract_id - const uint8_t *serialized_contract; - // Length of serialized contract data - uintptr_t serialized_contract_len; - // Token position in the contract (defaults to 0 if not specified) - uint16_t token_position; - // Distribution type (PreProgrammed or Perpetual) - enum DashSDKTokenDistributionType distribution_type; - // Optional public note - const char *public_note; -} DashSDKTokenClaimParams; - -// Token mint parameters -typedef struct DashSDKTokenMintParams { - // Token contract ID (Base58 encoded) - mutually exclusive with serialized_contract - const char *token_contract_id; - // Serialized data contract (bincode) - mutually exclusive with token_contract_id - const uint8_t *serialized_contract; - // Length of serialized contract data - uintptr_t serialized_contract_len; - // Token position in the contract (defaults to 0 if not specified) - uint16_t token_position; - // Recipient identity ID (32 bytes) - optional - const uint8_t *recipient_id; - // Amount to mint - uint64_t amount; - // Optional public note - const char *public_note; -} DashSDKTokenMintParams; - -// Token transfer parameters -typedef struct DashSDKTokenTransferParams { - // Token contract ID (Base58 encoded) - mutually exclusive with serialized_contract - const char *token_contract_id; - // Serialized data contract (bincode) - mutually exclusive with token_contract_id - const uint8_t *serialized_contract; - // Length of serialized contract data - uintptr_t serialized_contract_len; - // Token position in the contract (defaults to 0 if not specified) - uint16_t token_position; - // Recipient identity ID (32 bytes) - const uint8_t *recipient_id; - // Amount to transfer - uint64_t amount; - // Optional public note - const char *public_note; - // Optional private encrypted note - const char *private_encrypted_note; - // Optional shared encrypted note - const char *shared_encrypted_note; -} DashSDKTokenTransferParams; - -// Token configuration update parameters -typedef struct DashSDKTokenConfigUpdateParams { - // Token contract ID (Base58 encoded) - mutually exclusive with serialized_contract - const char *token_contract_id; - // Serialized data contract (bincode) - mutually exclusive with token_contract_id - const uint8_t *serialized_contract; - // Length of serialized contract data - uintptr_t serialized_contract_len; - // Token position in the contract (defaults to 0 if not specified) - uint16_t token_position; - // The type of configuration update - enum DashSDKTokenConfigUpdateType update_type; - // For MaxSupply updates - the new max supply (0 for no limit) - uint64_t amount; - // For boolean updates like MintingAllowChoosingDestination - bool bool_value; - // For identity-based updates - identity ID (32 bytes) - const uint8_t *identity_id; - // For group-based updates - the group position - uint16_t group_position; - // For permission updates - the authorized action takers - enum DashSDKAuthorizedActionTakers action_takers; - // Optional public note - const char *public_note; -} DashSDKTokenConfigUpdateParams; - -// Token destroy frozen funds parameters -typedef struct DashSDKTokenDestroyFrozenFundsParams { - // Token contract ID (Base58 encoded) - mutually exclusive with serialized_contract - const char *token_contract_id; - // Serialized data contract (bincode) - mutually exclusive with token_contract_id - const uint8_t *serialized_contract; - // Length of serialized contract data - uintptr_t serialized_contract_len; - // Token position in the contract (defaults to 0 if not specified) - uint16_t token_position; - // The frozen identity whose funds to destroy (32 bytes) - const uint8_t *frozen_identity_id; - // Optional public note - const char *public_note; -} DashSDKTokenDestroyFrozenFundsParams; - -// Token emergency action parameters -typedef struct DashSDKTokenEmergencyActionParams { - // Token contract ID (Base58 encoded) - mutually exclusive with serialized_contract - const char *token_contract_id; - // Serialized data contract (bincode) - mutually exclusive with token_contract_id - const uint8_t *serialized_contract; - // Length of serialized contract data - uintptr_t serialized_contract_len; - // Token position in the contract (defaults to 0 if not specified) - uint16_t token_position; - // The emergency action to perform - enum DashSDKTokenEmergencyAction action; - // Optional public note - const char *public_note; -} DashSDKTokenEmergencyActionParams; - -// Token freeze/unfreeze parameters -typedef struct DashSDKTokenFreezeParams { - // Token contract ID (Base58 encoded) - mutually exclusive with serialized_contract - const char *token_contract_id; - // Serialized data contract (bincode) - mutually exclusive with token_contract_id - const uint8_t *serialized_contract; - // Length of serialized contract data - uintptr_t serialized_contract_len; - // Token position in the contract (defaults to 0 if not specified) - uint16_t token_position; - // The identity to freeze/unfreeze (32 bytes) - const uint8_t *target_identity_id; - // Optional public note - const char *public_note; -} DashSDKTokenFreezeParams; - -// Token purchase parameters -typedef struct DashSDKTokenPurchaseParams { - // Token contract ID (Base58 encoded) - mutually exclusive with serialized_contract - const char *token_contract_id; - // Serialized data contract (bincode) - mutually exclusive with token_contract_id - const uint8_t *serialized_contract; - // Length of serialized contract data - uintptr_t serialized_contract_len; - // Token position in the contract (defaults to 0 if not specified) - uint16_t token_position; - // Amount of tokens to purchase - uint64_t amount; - // Total agreed price in credits - uint64_t total_agreed_price; -} DashSDKTokenPurchaseParams; - -// Token price entry for tiered pricing -typedef struct DashSDKTokenPriceEntry { - // Token amount threshold - uint64_t amount; - // Price in credits for this amount - uint64_t price; -} DashSDKTokenPriceEntry; - -// Token set price parameters -typedef struct DashSDKTokenSetPriceParams { - // Token contract ID (Base58 encoded) - mutually exclusive with serialized_contract - const char *token_contract_id; - // Serialized data contract (bincode) - mutually exclusive with token_contract_id - const uint8_t *serialized_contract; - // Length of serialized contract data - uintptr_t serialized_contract_len; - // Token position in the contract (defaults to 0 if not specified) - uint16_t token_position; - // Pricing type - enum DashSDKTokenPricingType pricing_type; - // For SinglePrice - the price in credits (ignored for SetPrices) - uint64_t single_price; - // For SetPrices - array of price entries (ignored for SinglePrice) - const struct DashSDKTokenPriceEntry *price_entries; - // Number of price entries - uint32_t price_entries_count; - // Optional public note - const char *public_note; -} DashSDKTokenSetPriceParams; - -// FFI-compatible transaction input -typedef struct FFITxIn { - // Transaction ID (32 bytes) - uint8_t txid[32]; - // Output index - uint32_t vout; - // Script signature length - uint32_t script_sig_len; - // Script signature data pointer - const uint8_t *script_sig; - // Sequence number - uint32_t sequence; -} FFITxIn; - -// FFI-compatible transaction output -typedef struct FFITxOut { - // Amount in satoshis - uint64_t amount; - // Script pubkey length - uint32_t script_pubkey_len; - // Script pubkey data pointer - const uint8_t *script_pubkey; -} FFITxOut; - -// Binary data container for results -typedef struct DashSDKBinaryData { - // Pointer to the data - uint8_t *data; - // Length of the data - uintptr_t len; -} DashSDKBinaryData; - -// Single entry in an identity balance map -typedef struct DashSDKIdentityBalanceEntry { - // Identity ID (32 bytes) - uint8_t identity_id[32]; - // Balance in credits (u64::MAX means identity not found) - uint64_t balance; -} DashSDKIdentityBalanceEntry; - -// Map of identity IDs to balances -typedef struct DashSDKIdentityBalanceMap { - // Array of entries - struct DashSDKIdentityBalanceEntry *entries; - // Number of entries - uintptr_t count; -} DashSDKIdentityBalanceMap; - -// Unified SDK handle containing both Core and Platform SDKs -typedef struct UnifiedSDKHandle { - struct FFIDashSpvClient *core_client; - struct dash_sdk_handle_t *platform_sdk; - bool integration_enabled; -} UnifiedSDKHandle; - -// Unified SDK configuration combining both Core and Platform settings -typedef struct UnifiedSDKConfig { - // Core SDK configuration (ignored if core feature disabled) - const FFIClientConfig *core_config; - // Platform SDK configuration - struct DashSDKConfig platform_config; - // Whether to enable cross-layer integration - bool enable_integration; -} UnifiedSDKConfig; - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -// Initialize the FFI library. -// This should be called once at app startup before using any other functions. - void dash_sdk_init(void) ; - -// Get the version of the Dash SDK FFI library - const char *dash_sdk_version(void) ; - -// Register Core SDK handle and setup callback bridge with Platform SDK -// -// This function implements the core pattern from dash-unified-ffi-old: -// 1. Takes a Core SDK handle -// 2. Creates callback wrappers for the functions Platform SDK needs -// 3. Registers these callbacks with Platform SDK's context provider system -// -// # Safety -// - `core_handle` must be a valid Core SDK handle that remains valid for the SDK lifetime -// - This function should be called once after creating both Core and Platform SDK instances - int32_t dash_unified_register_core_sdk_handle(void *core_handle) ; - -// Initialize the unified SDK system with callback bridge support -// -// This function initializes both Core SDK and Platform SDK and sets up -// the callback bridge pattern for inter-SDK communication. - int32_t dash_unified_init(void) ; - -// Get unified SDK version information including both Core and Platform components - const char *dash_unified_version(void) ; - -// Check if unified SDK has both Core and Platform support - bool dash_unified_has_full_support(void) ; - -// Fetches contested resource identity votes -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `identity_id` - Base58-encoded identity identifier -// * `limit` - Maximum number of votes to return (optional, 0 for no limit) -// * `offset` - Number of votes to skip (optional, 0 for no offset) -// * `order_ascending` - Whether to order results in ascending order -// -// # Returns -// * JSON array of votes or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_contested_resource_get_identity_votes(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id, uint32_t limit, uint32_t offset, bool order_ascending) ; - -// Fetches contested resources -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `contract_id` - Base58-encoded contract identifier -// * `document_type_name` - Name of the document type -// * `index_name` - Name of the index -// * `start_index_values_json` - JSON array of hex-encoded start index values -// * `end_index_values_json` - JSON array of hex-encoded end index values -// * `count` - Maximum number of resources to return -// * `order_ascending` - Whether to order results in ascending order -// -// # Returns -// * JSON array of contested resources or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_contested_resource_get_resources(const struct dash_sdk_handle_t *sdk_handle, const char *contract_id, const char *document_type_name, const char *index_name, const char *start_index_values_json, const char *end_index_values_json, uint32_t count, bool order_ascending) ; - -// Fetches contested resource vote state -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `contract_id` - Base58-encoded contract identifier -// * `document_type_name` - Name of the document type -// * `index_name` - Name of the index -// * `index_values_json` - JSON array of hex-encoded index values -// * `result_type` - Result type (0=DOCUMENTS, 1=VOTE_TALLY, 2=DOCUMENTS_AND_VOTE_TALLY) -// * `allow_include_locked_and_abstaining_vote_tally` - Whether to include locked and abstaining votes -// * `count` - Maximum number of results to return -// -// # Returns -// * JSON array of contenders or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_contested_resource_get_vote_state(const struct dash_sdk_handle_t *sdk_handle, const char *contract_id, const char *document_type_name, const char *index_name, const char *index_values_json, uint8_t result_type, bool allow_include_locked_and_abstaining_vote_tally, uint32_t count) ; - -// Fetches voters for a contested resource identity -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `contract_id` - Base58-encoded contract identifier -// * `document_type_name` - Name of the document type -// * `index_name` - Name of the index -// * `index_values_json` - JSON array of hex-encoded index values -// * `contestant_id` - Base58-encoded contestant identifier -// * `count` - Maximum number of voters to return -// * `order_ascending` - Whether to order results in ascending order -// -// # Returns -// * JSON array of voters or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_contested_resource_get_voters_for_identity(const struct dash_sdk_handle_t *sdk_handle, const char *contract_id, const char *document_type_name, const char *index_name, const char *index_values_json, const char *contestant_id, uint32_t count, bool order_ascending) ; - -// Create a context provider from a Core SDK handle (DEPRECATED) -// -// This function is deprecated. Use dash_sdk_context_provider_from_callbacks instead. -// -// # Safety -// - `core_handle` must be a valid Core SDK handle -// - String parameters must be valid UTF-8 C strings or null - struct ContextProviderHandle *dash_sdk_context_provider_from_core(struct CoreSDKHandle *core_handle, const char *core_rpc_url, const char *core_rpc_user, const char *core_rpc_password) ; - -// Create a context provider from callbacks -// -// # Safety -// - `callbacks` must contain valid function pointers - struct ContextProviderHandle *dash_sdk_context_provider_from_callbacks(const struct ContextProviderCallbacks *callbacks) ; - -// Destroy a context provider handle -// -// # Safety -// - `handle` must be a valid context provider handle or null - void dash_sdk_context_provider_destroy(struct ContextProviderHandle *handle) ; - -// Initialize the Core SDK -// Returns 0 on success, error code on failure - int32_t dash_core_sdk_init(void) ; - -// Create a Core SDK client with testnet config -// -// # Safety -// - Returns null on failure - struct FFIDashSpvClient *dash_core_sdk_create_client_testnet(void) ; - -// Create a Core SDK client with mainnet config -// -// # Safety -// - Returns null on failure - struct FFIDashSpvClient *dash_core_sdk_create_client_mainnet(void) ; - -// Create a Core SDK client with custom config -// -// # Safety -// - `config` must be a valid CoreSDKConfig pointer -// - Returns null on failure - struct FFIDashSpvClient *dash_core_sdk_create_client(const FFIClientConfig *config) ; - -// Destroy a Core SDK client -// -// # Safety -// - `client` must be a valid Core SDK client handle or null - void dash_core_sdk_destroy_client(struct FFIDashSpvClient *client) ; - -// Start the Core SDK client (begin sync) -// -// # Safety -// - `client` must be a valid Core SDK client handle - int32_t dash_core_sdk_start(struct FFIDashSpvClient *client) ; - -// Stop the Core SDK client -// -// # Safety -// - `client` must be a valid Core SDK client handle - int32_t dash_core_sdk_stop(struct FFIDashSpvClient *client) ; - -// Sync Core SDK client to tip -// -// # Safety -// - `client` must be a valid Core SDK client handle - int32_t dash_core_sdk_sync_to_tip(struct FFIDashSpvClient *client) ; - -// Get the current sync progress -// -// # Safety -// - `client` must be a valid Core SDK client handle -// - Returns pointer to FFISyncProgress structure (caller must free it) - FFISyncProgress *dash_core_sdk_get_sync_progress(struct FFIDashSpvClient *client) ; - -// Get Core SDK statistics -// -// # Safety -// - `client` must be a valid Core SDK client handle -// - Returns pointer to FFISpvStats structure (caller must free it) - FFISpvStats *dash_core_sdk_get_stats(struct FFIDashSpvClient *client) ; - -// Get the current block height -// -// # Safety -// - `client` must be a valid Core SDK client handle -// - `height` must point to a valid u32 - int32_t dash_core_sdk_get_block_height(struct FFIDashSpvClient *client, uint32_t *height) ; - -// Add an address to watch -// -// # Safety -// - `client` must be a valid Core SDK client handle -// - `address` must be a valid null-terminated C string - int32_t dash_core_sdk_watch_address(struct FFIDashSpvClient *client, const char *address) ; - -// Remove an address from watching -// -// # Safety -// - `client` must be a valid Core SDK client handle -// - `address` must be a valid null-terminated C string - int32_t dash_core_sdk_unwatch_address(struct FFIDashSpvClient *client, const char *address) ; - -// Get balance for all watched addresses -// -// # Safety -// - `client` must be a valid Core SDK client handle -// - Returns pointer to FFIBalance structure (caller must free it) - FFIBalance *dash_core_sdk_get_total_balance(struct FFIDashSpvClient *client) ; - -// Get platform activation height -// -// # Safety -// - `client` must be a valid Core SDK client handle -// - `height` must point to a valid u32 - int32_t dash_core_sdk_get_platform_activation_height(struct FFIDashSpvClient *client, uint32_t *height) ; - -// Get quorum public key -// -// # Safety -// - `client` must be a valid Core SDK client handle -// - `quorum_hash` must point to a valid 32-byte buffer -// - `public_key` must point to a valid 48-byte buffer - int32_t dash_core_sdk_get_quorum_public_key(struct FFIDashSpvClient *client, uint32_t quorum_type, const uint8_t *quorum_hash, uint32_t core_chain_locked_height, uint8_t *public_key, uintptr_t public_key_size) ; - -// Get Core SDK handle for platform integration -// -// # Safety -// - `client` must be a valid Core SDK client handle - void *dash_core_sdk_get_core_handle(struct FFIDashSpvClient *client) ; - -// Broadcast a transaction -// -// # Safety -// - `client` must be a valid Core SDK client handle -// - `transaction_hex` must be a valid null-terminated C string - int32_t dash_core_sdk_broadcast_transaction(struct FFIDashSpvClient *client, const char *transaction_hex) ; - -// Check if Core SDK feature is enabled at runtime - bool dash_core_sdk_is_enabled(void) ; - -// Get Core SDK version - const char *dash_core_sdk_version(void) ; - -// Create a new data contract - struct DashSDKResult dash_sdk_data_contract_create(struct dash_sdk_handle_t *sdk_handle, const struct IdentityHandle *owner_identity_handle, const char *documents_schema_json) ; - -// Destroy a data contract handle - void dash_sdk_data_contract_destroy(struct DataContractHandle *handle) ; - -// Put data contract to platform (broadcast state transition) - struct DashSDKResult dash_sdk_data_contract_put_to_platform(struct dash_sdk_handle_t *sdk_handle, const struct DataContractHandle *data_contract_handle, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle) ; - -// Put data contract to platform and wait for confirmation (broadcast state transition and wait for response) - struct DashSDKResult dash_sdk_data_contract_put_to_platform_and_wait(struct dash_sdk_handle_t *sdk_handle, const struct DataContractHandle *data_contract_handle, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle) ; - -// Fetch a data contract by ID - struct DashSDKResult dash_sdk_data_contract_fetch(const struct dash_sdk_handle_t *sdk_handle, const char *contract_id) ; - -// Fetch a data contract by ID and return as JSON - struct DashSDKResult dash_sdk_data_contract_fetch_json(const struct dash_sdk_handle_t *sdk_handle, const char *contract_id) ; - -// Fetch multiple data contracts by their IDs -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `contract_ids`: Comma-separated list of Base58-encoded contract IDs -// -// # Returns -// JSON string containing contract IDs mapped to their data contracts - struct DashSDKResult dash_sdk_data_contracts_fetch_many(const struct dash_sdk_handle_t *sdk_handle, const char *contract_ids) ; - -// Fetch data contract history -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `contract_id`: Base58-encoded contract ID -// - `limit`: Maximum number of history entries to return (0 for default) -// - `offset`: Number of entries to skip (for pagination) -// - `start_at_ms`: Start timestamp in milliseconds (0 for beginning) -// -// # Returns -// JSON string containing the data contract history - struct DashSDKResult dash_sdk_data_contract_fetch_history(const struct dash_sdk_handle_t *sdk_handle, const char *contract_id, unsigned int limit, unsigned int offset, uint64_t start_at_ms) ; - -// Get schema for a specific document type - char *dash_sdk_data_contract_get_schema(const struct DataContractHandle *contract_handle, const char *document_type) ; - -// Create a new document - struct DashSDKResult dash_sdk_document_create(struct dash_sdk_handle_t *sdk_handle, const struct DashSDKDocumentCreateParams *params) ; - -// Delete a document from the platform - struct DashSDKResult dash_sdk_document_delete(struct dash_sdk_handle_t *sdk_handle, const struct DocumentHandle *document_handle, const struct DataContractHandle *data_contract_handle, const char *document_type_name, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKTokenPaymentInfo *token_payment_info, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Delete a document from the platform and wait for confirmation - struct DashSDKResult dash_sdk_document_delete_and_wait(struct dash_sdk_handle_t *sdk_handle, const struct DocumentHandle *document_handle, const struct DataContractHandle *data_contract_handle, const char *document_type_name, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKTokenPaymentInfo *token_payment_info, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Update document price (broadcast state transition) - struct DashSDKResult dash_sdk_document_update_price_of_document(struct dash_sdk_handle_t *sdk_handle, const struct DocumentHandle *document_handle, const struct DataContractHandle *data_contract_handle, const char *document_type_name, uint64_t price, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKTokenPaymentInfo *token_payment_info, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Update document price and wait for confirmation (broadcast state transition and wait for response) - struct DashSDKResult dash_sdk_document_update_price_of_document_and_wait(struct dash_sdk_handle_t *sdk_handle, const struct DocumentHandle *document_handle, const struct DataContractHandle *data_contract_handle, const char *document_type_name, uint64_t price, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKTokenPaymentInfo *token_payment_info, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Purchase document (broadcast state transition) - struct DashSDKResult dash_sdk_document_purchase(struct dash_sdk_handle_t *sdk_handle, const struct DocumentHandle *document_handle, const struct DataContractHandle *data_contract_handle, const char *document_type_name, uint64_t price, const char *purchaser_id, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKTokenPaymentInfo *token_payment_info, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Purchase document and wait for confirmation (broadcast state transition and wait for response) - struct DashSDKResult dash_sdk_document_purchase_and_wait(struct dash_sdk_handle_t *sdk_handle, const struct DocumentHandle *document_handle, const struct DataContractHandle *data_contract_handle, const char *document_type_name, uint64_t price, const char *purchaser_id, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKTokenPaymentInfo *token_payment_info, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Put document to platform (broadcast state transition) - struct DashSDKResult dash_sdk_document_put_to_platform(struct dash_sdk_handle_t *sdk_handle, const struct DocumentHandle *document_handle, const struct DataContractHandle *data_contract_handle, const char *document_type_name, const uint8_t (*entropy)[32], const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKTokenPaymentInfo *token_payment_info, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Put document to platform and wait for confirmation (broadcast state transition and wait for response) - struct DashSDKResult dash_sdk_document_put_to_platform_and_wait(struct dash_sdk_handle_t *sdk_handle, const struct DocumentHandle *document_handle, const struct DataContractHandle *data_contract_handle, const char *document_type_name, const uint8_t (*entropy)[32], const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKTokenPaymentInfo *token_payment_info, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Fetch a document by ID - struct DashSDKResult dash_sdk_document_fetch(const struct dash_sdk_handle_t *sdk_handle, const struct DataContractHandle *data_contract_handle, const char *document_type, const char *document_id) ; - -// Get document information - struct DashSDKDocumentInfo *dash_sdk_document_get_info(const struct DocumentHandle *document_handle) ; - -// Search for documents - struct DashSDKResult dash_sdk_document_search(const struct dash_sdk_handle_t *sdk_handle, const struct DashSDKDocumentSearchParams *params) ; - -// Replace document on platform (broadcast state transition) - struct DashSDKResult dash_sdk_document_replace_on_platform(struct dash_sdk_handle_t *sdk_handle, const struct DocumentHandle *document_handle, const struct DataContractHandle *data_contract_handle, const char *document_type_name, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKTokenPaymentInfo *token_payment_info, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Replace document on platform and wait for confirmation (broadcast state transition and wait for response) - struct DashSDKResult dash_sdk_document_replace_on_platform_and_wait(struct dash_sdk_handle_t *sdk_handle, const struct DocumentHandle *document_handle, const struct DataContractHandle *data_contract_handle, const char *document_type_name, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKTokenPaymentInfo *token_payment_info, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Transfer document to another identity -// -// # Parameters -// - `document_handle`: Handle to the document to transfer -// - `recipient_id`: Base58-encoded ID of the recipient identity -// - `data_contract_handle`: Handle to the data contract -// - `document_type_name`: Name of the document type -// - `identity_public_key_handle`: Public key for signing -// - `signer_handle`: Cryptographic signer -// - `token_payment_info`: Optional token payment information (can be null for defaults) -// - `put_settings`: Optional settings for the operation (can be null for defaults) -// -// # Returns -// Serialized state transition on success - struct DashSDKResult dash_sdk_document_transfer_to_identity(struct dash_sdk_handle_t *sdk_handle, const struct DocumentHandle *document_handle, const char *recipient_id, const struct DataContractHandle *data_contract_handle, const char *document_type_name, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKTokenPaymentInfo *token_payment_info, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Transfer document to another identity and wait for confirmation -// -// # Parameters -// - `document_handle`: Handle to the document to transfer -// - `recipient_id`: Base58-encoded ID of the recipient identity -// - `data_contract_handle`: Handle to the data contract -// - `document_type_name`: Name of the document type -// - `identity_public_key_handle`: Public key for signing -// - `signer_handle`: Cryptographic signer -// - `token_payment_info`: Optional token payment information (can be null for defaults) -// - `put_settings`: Optional settings for the operation (can be null for defaults) -// -// # Returns -// Handle to the transferred document on success - struct DashSDKResult dash_sdk_document_transfer_to_identity_and_wait(struct dash_sdk_handle_t *sdk_handle, const struct DocumentHandle *document_handle, const char *recipient_id, const struct DataContractHandle *data_contract_handle, const char *document_type_name, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKTokenPaymentInfo *token_payment_info, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Destroy a document - struct DashSDKError *dash_sdk_document_destroy(struct dash_sdk_handle_t *sdk_handle, struct DocumentHandle *document_handle) ; - -// Destroy a document handle - void dash_sdk_document_handle_destroy(struct DocumentHandle *handle) ; - -// Get DPNS usernames owned by an identity -// -// This function returns all DPNS usernames associated with a given identity ID. -// It checks for domains where the identity is: -// - The owner of the domain document -// - Listed in records.dashUniqueIdentityId -// - Listed in records.dashAliasIdentityId -// -// # Arguments -// * `sdk_handle` - Handle to the SDK instance -// * `identity_id` - The identity ID to search for (base58 string) -// * `limit` - Maximum number of results to return (0 for default of 10) -// -// # Returns -// * On success: A JSON array of username objects -// * On error: An error result - struct DashSDKResult dash_sdk_dpns_get_usernames(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id, uint32_t limit) ; - -// Check if a DPNS username is available -// -// This function checks if a given username is available for registration. -// It also validates the username format and checks if it's contested. -// -// # Arguments -// * `sdk_handle` - Handle to the SDK instance -// * `label` - The username label to check (e.g., "alice") -// -// # Returns -// * On success: A JSON object with availability information -// * On error: An error result - struct DashSDKResult dash_sdk_dpns_check_availability(const struct dash_sdk_handle_t *sdk_handle, const char *label) ; - -// Search for DPNS names that start with a given prefix -// -// This function searches for DPNS usernames that start with the given prefix. -// -// # Arguments -// * `sdk_handle` - Handle to the SDK instance -// * `prefix` - The prefix to search for (e.g., "ali" to find "alice", "alicia", etc.) -// * `limit` - Maximum number of results to return (0 for default of 10) -// -// # Returns -// * On success: A JSON array of username objects -// * On error: An error result - struct DashSDKResult dash_sdk_dpns_search(const struct dash_sdk_handle_t *sdk_handle, const char *prefix, uint32_t limit) ; - -// Resolve a DPNS name to an identity ID -// -// This function resolves a DPNS username to its associated identity ID. -// The name can be either: -// - A full domain name (e.g., "alice.dash") -// - Just the label (e.g., "alice") -// -// # Arguments -// * `sdk_handle` - Handle to the SDK instance -// * `name` - The DPNS name to resolve -// -// # Returns -// * On success: A JSON object with the identity ID, or null if not found -// * On error: An error result - struct DashSDKResult dash_sdk_dpns_resolve(const struct dash_sdk_handle_t *sdk_handle, const char *name) ; - -// Free an error message - void dash_sdk_error_free(struct DashSDKError *error) ; - -// Fetches proposed epoch blocks by evonode IDs -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `epoch` - Epoch number (optional, 0 for current epoch) -// * `ids_json` - JSON array of hex-encoded evonode pro_tx_hash IDs -// -// # Returns -// * JSON array of evonode proposed block counts or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_evonode_get_proposed_epoch_blocks_by_ids(const struct dash_sdk_handle_t *sdk_handle, uint32_t epoch, const char *ids_json) ; - -// Fetches proposed epoch blocks by range -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `epoch` - Epoch number (optional, 0 for current epoch) -// * `limit` - Maximum number of results to return (optional, 0 for no limit) -// * `start_after` - Start after this pro_tx_hash (hex-encoded, optional) -// * `start_at` - Start at this pro_tx_hash (hex-encoded, optional) -// -// # Returns -// * JSON array of evonode proposed block counts or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_evonode_get_proposed_epoch_blocks_by_range(const struct dash_sdk_handle_t *sdk_handle, uint32_t epoch, uint32_t limit, const char *start_after, const char *start_at) ; - -// Fetches group action signers -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `contract_id` - Base58-encoded contract identifier -// * `group_contract_position` - Position of the group in the contract -// * `status` - Action status (0=Pending, 1=Completed, 2=Expired) -// * `action_id` - Base58-encoded action identifier -// -// # Returns -// * JSON array of signers or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_group_get_action_signers(const struct dash_sdk_handle_t *sdk_handle, const char *contract_id, uint16_t group_contract_position, uint8_t status, const char *action_id) ; - -// Fetches group actions -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `contract_id` - Base58-encoded contract identifier -// * `group_contract_position` - Position of the group in the contract -// * `status` - Action status (0=Pending, 1=Completed, 2=Expired) -// * `start_at_action_id` - Optional starting action ID (Base58-encoded) -// * `limit` - Maximum number of actions to return -// -// # Returns -// * JSON array of group actions or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_group_get_actions(const struct dash_sdk_handle_t *sdk_handle, const char *contract_id, uint16_t group_contract_position, uint8_t status, const char *start_at_action_id, uint16_t limit) ; - -// Fetches information about a group -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `contract_id` - Base58-encoded contract identifier -// * `group_contract_position` - Position of the group in the contract -// -// # Returns -// * JSON string with group information or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_group_get_info(const struct dash_sdk_handle_t *sdk_handle, const char *contract_id, uint16_t group_contract_position) ; - -// Fetches information about multiple groups -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `start_at_position` - Starting position (optional, null for beginning) -// * `limit` - Maximum number of groups to return -// -// # Returns -// * JSON array of group information or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_group_get_infos(const struct dash_sdk_handle_t *sdk_handle, const char *start_at_position, uint32_t limit) ; - -// Create a new identity - struct DashSDKResult dash_sdk_identity_create(struct dash_sdk_handle_t *sdk_handle) ; - -// Create an identity handle from components -// -// This function creates an identity handle from basic components without -// requiring JSON serialization/deserialization. -// -// # Parameters -// - `identity_id`: 32-byte identity ID -// - `public_keys`: Array of public key data -// - `public_keys_count`: Number of public keys in the array -// - `balance`: Identity balance in credits -// - `revision`: Identity revision number -// -// # Returns -// - Handle to the created identity on success -// - Error if creation fails - struct DashSDKResult dash_sdk_identity_create_from_components(const uint8_t *identity_id, const struct DashSDKPublicKeyData *public_keys, uintptr_t public_keys_count, uint64_t balance, uint64_t revision) ; - -// Get a public key from an identity by its ID -// -// # Parameters -// - `identity`: Handle to the identity -// - `key_id`: The ID of the public key to retrieve -// -// # Returns -// - Handle to the public key on success -// - Error if key not found or invalid parameters - struct DashSDKResult dash_sdk_identity_get_public_key_by_id(const struct IdentityHandle *identity, uint8_t key_id) ; - -// Get identity information - struct DashSDKIdentityInfo *dash_sdk_identity_get_info(const struct IdentityHandle *identity_handle) ; - -// Destroy an identity handle - void dash_sdk_identity_destroy(struct IdentityHandle *handle) ; - -// Get the appropriate signing key for a state transition -// -// This function finds a key that meets the purpose and security level requirements -// for the specified state transition type. -// -// # Parameters -// - `identity_handle`: Handle to the identity -// - `transition_type`: Type of state transition to be signed -// -// # Returns -// - Handle to the identity public key on success -// - Error if no suitable key is found - struct DashSDKResult dash_sdk_identity_get_signing_key_for_transition(const struct IdentityHandle *identity_handle, enum StateTransitionType transition_type) ; - -// Get the private key data for a transfer key -// -// This function retrieves the private key data that corresponds to the -// lowest security level transfer key. In a real implementation, this would -// interface with a secure key storage system. -// -// # Parameters -// - `identity_handle`: Handle to the identity -// - `key_index`: The key index from the identity public key -// -// # Returns -// - 32-byte private key data on success -// - Error if key not found or not accessible - struct DashSDKResult dash_sdk_identity_get_transfer_private_key(const struct IdentityHandle *identity_handle, uint32_t key_index) ; - -// Get the key ID from an identity public key - uint32_t dash_sdk_identity_public_key_get_id(const struct IdentityPublicKeyHandle *key_handle) ; - -// Free an identity public key handle - void dash_sdk_identity_public_key_destroy(struct IdentityPublicKeyHandle *handle) ; - -// Register a name for an identity - struct DashSDKError *dash_sdk_identity_register_name(struct dash_sdk_handle_t *sdk_handle, const struct IdentityHandle *identity_handle, const char *name) ; - -// Parse an identity from JSON string to handle -// -// This function takes a JSON string representation of an identity -// (as returned by dash_sdk_identity_fetch) and converts it to an -// identity handle that can be used with other FFI functions. -// -// # Parameters -// - `json_str`: JSON string containing the identity data -// -// # Returns -// - Handle to the parsed identity on success -// - Error if JSON parsing fails - struct DashSDKResult dash_sdk_identity_parse_json(const char *json_str) ; - -// Put identity to platform with instant lock proof -// -// # Parameters -// - `instant_lock_bytes`: Serialized InstantLock data -// - `transaction_bytes`: Serialized Transaction data -// - `output_index`: Index of the output in the transaction payload -// - `private_key`: 32-byte private key associated with the asset lock -// - `put_settings`: Optional settings for the operation (can be null for defaults) - struct DashSDKResult dash_sdk_identity_put_to_platform_with_instant_lock(struct dash_sdk_handle_t *sdk_handle, const struct IdentityHandle *identity_handle, const uint8_t *instant_lock_bytes, uintptr_t instant_lock_len, const uint8_t *transaction_bytes, uintptr_t transaction_len, uint32_t output_index, const uint8_t (*private_key)[32], const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings) ; - -// Put identity to platform with instant lock proof and wait for confirmation -// -// # Parameters -// - `instant_lock_bytes`: Serialized InstantLock data -// - `transaction_bytes`: Serialized Transaction data -// - `output_index`: Index of the output in the transaction payload -// - `private_key`: 32-byte private key associated with the asset lock -// - `put_settings`: Optional settings for the operation (can be null for defaults) -// -// # Returns -// Handle to the confirmed identity on success - struct DashSDKResult dash_sdk_identity_put_to_platform_with_instant_lock_and_wait(struct dash_sdk_handle_t *sdk_handle, const struct IdentityHandle *identity_handle, const uint8_t *instant_lock_bytes, uintptr_t instant_lock_len, const uint8_t *transaction_bytes, uintptr_t transaction_len, uint32_t output_index, const uint8_t (*private_key)[32], const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings) ; - -// Put identity to platform with chain lock proof -// -// # Parameters -// - `core_chain_locked_height`: Core height at which the transaction was chain locked -// - `out_point`: 36-byte OutPoint (32-byte txid + 4-byte vout) -// - `private_key`: 32-byte private key associated with the asset lock -// - `put_settings`: Optional settings for the operation (can be null for defaults) - struct DashSDKResult dash_sdk_identity_put_to_platform_with_chain_lock(struct dash_sdk_handle_t *sdk_handle, const struct IdentityHandle *identity_handle, uint32_t core_chain_locked_height, const uint8_t (*out_point)[36], const uint8_t (*private_key)[32], const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings) ; - -// Put identity to platform with chain lock proof and wait for confirmation -// -// # Parameters -// - `core_chain_locked_height`: Core height at which the transaction was chain locked -// - `out_point`: 36-byte OutPoint (32-byte txid + 4-byte vout) -// - `private_key`: 32-byte private key associated with the asset lock -// - `put_settings`: Optional settings for the operation (can be null for defaults) -// -// # Returns -// Handle to the confirmed identity on success - struct DashSDKResult dash_sdk_identity_put_to_platform_with_chain_lock_and_wait(struct dash_sdk_handle_t *sdk_handle, const struct IdentityHandle *identity_handle, uint32_t core_chain_locked_height, const uint8_t (*out_point)[36], const uint8_t (*private_key)[32], const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings) ; - -// Fetch identity balance -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_id`: Base58-encoded identity ID -// -// # Returns -// The balance of the identity as a string - struct DashSDKResult dash_sdk_identity_fetch_balance(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id) ; - -// Fetch identity balance and revision -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_id`: Base58-encoded identity ID -// -// # Returns -// JSON string containing the balance and revision information - struct DashSDKResult dash_sdk_identity_fetch_balance_and_revision(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id) ; - -// Fetch identity by non-unique public key hash with optional pagination -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `public_key_hash`: Hex-encoded 20-byte public key hash -// - `start_after`: Optional Base58-encoded identity ID to start after (for pagination) -// -// # Returns -// JSON string containing the identity information, or null if not found - struct DashSDKResult dash_sdk_identity_fetch_by_non_unique_public_key_hash(const struct dash_sdk_handle_t *sdk_handle, const char *public_key_hash, const char *start_after) ; - -// Fetch identity by public key hash -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `public_key_hash`: Hex-encoded 20-byte public key hash -// -// # Returns -// JSON string containing the identity information, or null if not found - struct DashSDKResult dash_sdk_identity_fetch_by_public_key_hash(const struct dash_sdk_handle_t *sdk_handle, const char *public_key_hash) ; - -// Fetch identity contract nonce -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_id`: Base58-encoded identity ID -// - `contract_id`: Base58-encoded contract ID -// -// # Returns -// The contract nonce of the identity as a string - struct DashSDKResult dash_sdk_identity_fetch_contract_nonce(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id, const char *contract_id) ; - -// Fetch an identity by ID - struct DashSDKResult dash_sdk_identity_fetch(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id) ; - -// Fetch an identity by ID and return a handle -// -// This function fetches an identity from the network and returns -// a handle that can be used with other FFI functions like transfers. -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_id`: Base58-encoded identity ID -// -// # Returns -// - Handle to the fetched identity on success -// - Error if fetch fails or identity not found - struct DashSDKResult dash_sdk_identity_fetch_handle(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id) ; - -// Fetch balances for multiple identities -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_ids`: Array of identity IDs (32-byte arrays) -// - `identity_ids_len`: Number of identity IDs in the array -// -// # Returns -// DashSDKResult with data_type = IdentityBalanceMap containing identity IDs mapped to their balances - struct DashSDKResult dash_sdk_identities_fetch_balances(const struct dash_sdk_handle_t *sdk_handle, const uint8_t (*identity_ids)[32], uintptr_t identity_ids_len) ; - -// Fetch contract keys for multiple identities -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_ids`: Comma-separated list of Base58-encoded identity IDs -// - `contract_id`: Base58-encoded contract ID -// - `document_type_name`: Optional document type name (pass NULL if not needed) -// - `purposes`: Comma-separated list of key purposes (0=Authentication, 1=Encryption, 2=Decryption, 3=Withdraw) -// -// # Returns -// JSON string containing identity IDs mapped to their contract keys by purpose - struct DashSDKResult dash_sdk_identities_fetch_contract_keys(const struct dash_sdk_handle_t *sdk_handle, const char *identity_ids, const char *contract_id, const char *document_type_name, const char *purposes) ; - -// Fetch identity nonce -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_id`: Base58-encoded identity ID -// -// # Returns -// The nonce of the identity as a string - struct DashSDKResult dash_sdk_identity_fetch_nonce(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id) ; - -// Fetch identity public keys -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_id`: Base58-encoded identity ID -// -// # Returns -// A JSON string containing the identity's public keys - struct DashSDKResult dash_sdk_identity_fetch_public_keys(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id) ; - -// Resolve a name to an identity -// -// This function takes a name in the format "label.parentdomain" (e.g., "alice.dash") -// or just "label" for top-level domains, and returns the associated identity ID. -// -// # Arguments -// * `sdk_handle` - Handle to the SDK instance -// * `name` - C string containing the name to resolve -// -// # Returns -// * On success: A result containing the resolved identity ID -// * On error: An error result - struct DashSDKResult dash_sdk_identity_resolve_name(const struct dash_sdk_handle_t *sdk_handle, const char *name) ; - -// Top up an identity with credits using instant lock proof - struct DashSDKResult dash_sdk_identity_topup_with_instant_lock(struct dash_sdk_handle_t *sdk_handle, const struct IdentityHandle *identity_handle, const uint8_t *instant_lock_bytes, uintptr_t instant_lock_len, const uint8_t *transaction_bytes, uintptr_t transaction_len, uint32_t output_index, const uint8_t (*private_key)[32], const struct DashSDKPutSettings *put_settings) ; - -// Top up an identity with credits using instant lock proof and wait for confirmation - struct DashSDKResult dash_sdk_identity_topup_with_instant_lock_and_wait(struct dash_sdk_handle_t *sdk_handle, const struct IdentityHandle *identity_handle, const uint8_t *instant_lock_bytes, uintptr_t instant_lock_len, const uint8_t *transaction_bytes, uintptr_t transaction_len, uint32_t output_index, const uint8_t (*private_key)[32], const struct DashSDKPutSettings *put_settings) ; - -// Transfer credits from one identity to another -// -// # Parameters -// - `from_identity_handle`: Identity to transfer credits from -// - `to_identity_id`: Base58-encoded ID of the identity to transfer credits to -// - `amount`: Amount of credits to transfer -// - `public_key_id`: ID of the public key to use for signing (pass 0 to auto-select TRANSFER key) -// - `signer_handle`: Cryptographic signer -// - `put_settings`: Optional settings for the operation (can be null for defaults) -// -// # Returns -// DashSDKTransferCreditsResult with sender and receiver final balances on success - struct DashSDKResult dash_sdk_identity_transfer_credits(struct dash_sdk_handle_t *sdk_handle, const struct IdentityHandle *from_identity_handle, const char *to_identity_id, uint64_t amount, uint32_t public_key_id, const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings) ; - -// Free a transfer credits result structure - void dash_sdk_transfer_credits_result_free(struct DashSDKTransferCreditsResult *result) ; - -// Withdraw credits from identity to a Dash address -// -// # Parameters -// - `identity_handle`: Identity to withdraw credits from -// - `address`: Base58-encoded Dash address to withdraw to -// - `amount`: Amount of credits to withdraw -// - `core_fee_per_byte`: Core fee per byte (optional, pass 0 for default) -// - `public_key_id`: ID of the public key to use for signing (pass 0 to auto-select TRANSFER key) -// - `signer_handle`: Cryptographic signer -// - `put_settings`: Optional settings for the operation (can be null for defaults) -// -// # Returns -// The new balance of the identity after withdrawal - struct DashSDKResult dash_sdk_identity_withdraw(struct dash_sdk_handle_t *sdk_handle, const struct IdentityHandle *identity_handle, const char *address, uint64_t amount, uint32_t core_fee_per_byte, uint32_t public_key_id, const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings) ; - -// Test function to diagnose the transfer crash - struct DashSDKResult dash_sdk_test_identity_transfer_crash(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id) ; - -// Generate a new BIP39 mnemonic -// -// # Parameters -// - `word_count`: Number of words (12, 15, 18, 21, or 24) -// -// # Returns -// - Pointer to FFIMnemonic on success -// - NULL on error (check dash_get_last_error) - struct FFIMnemonic *dash_key_mnemonic_generate(uint8_t word_count) ; - -// Create a mnemonic from a phrase -// -// # Parameters -// - `phrase`: The mnemonic phrase as a C string -// -// # Returns -// - Pointer to FFIMnemonic on success -// - NULL on error - struct FFIMnemonic *dash_key_mnemonic_from_phrase(const char *phrase) ; - -// Get the phrase from a mnemonic -// -// # Parameters -// - `mnemonic`: The mnemonic handle -// -// # Returns -// - C string containing the phrase (caller must free with dash_string_free) -// - NULL on error - char *dash_key_mnemonic_phrase(const struct FFIMnemonic *mnemonic) ; - -// Convert mnemonic to seed -// -// # Parameters -// - `mnemonic`: The mnemonic handle -// - `passphrase`: Optional passphrase (can be NULL) -// - `seed_out`: Buffer to write seed (must be 64 bytes) -// -// # Returns -// - 0 on success -// - -1 on error - int32_t dash_key_mnemonic_to_seed(const struct FFIMnemonic *mnemonic, const char *passphrase, uint8_t *seed_out) ; - -// Destroy a mnemonic - void dash_key_mnemonic_destroy(struct FFIMnemonic *mnemonic) ; - -// Create an extended private key from seed -// -// # Parameters -// - `seed`: The seed bytes (must be 64 bytes) -// - `network`: The network type -// -// # Returns -// - Pointer to FFIExtendedPrivKey on success -// - NULL on error - struct FFIExtendedPrivKey *dash_key_xprv_from_seed(const uint8_t *seed, enum FFIKeyNetwork network) ; - -// Derive a child key from extended private key -// -// # Parameters -// - `xprv`: The parent extended private key -// - `index`: The child index -// - `hardened`: Whether to use hardened derivation -// -// # Returns -// - Pointer to derived FFIExtendedPrivKey on success -// - NULL on error - struct FFIExtendedPrivKey *dash_key_xprv_derive_child(const struct FFIExtendedPrivKey *xprv, uint32_t index, bool hardened) ; - -// Derive key at BIP32 path -// -// # Parameters -// - `xprv`: The root extended private key -// - `path`: The derivation path (e.g., "m/44'/5'/0'/0/0") -// -// # Returns -// - Pointer to derived FFIExtendedPrivKey on success -// - NULL on error - struct FFIExtendedPrivKey *dash_key_xprv_derive_path(const struct FFIExtendedPrivKey *xprv, const char *path) ; - -// Get extended public key from extended private key -// -// # Parameters -// - `xprv`: The extended private key -// -// # Returns -// - Pointer to FFIExtendedPubKey on success -// - NULL on error - struct FFIExtendedPubKey *dash_key_xprv_to_xpub(const struct FFIExtendedPrivKey *xprv) ; - -// Get private key bytes -// -// # Parameters -// - `xprv`: The extended private key -// - `key_out`: Buffer to write key (must be 32 bytes) -// -// # Returns -// - 0 on success -// - -1 on error - int32_t dash_key_xprv_private_key(const struct FFIExtendedPrivKey *xprv, uint8_t *key_out) ; - -// Destroy an extended private key - void dash_key_xprv_destroy(struct FFIExtendedPrivKey *xprv) ; - -// Get public key bytes from extended public key -// -// # Parameters -// - `xpub`: The extended public key -// - `key_out`: Buffer to write key (must be 33 bytes for compressed) -// -// # Returns -// - 0 on success -// - -1 on error - int32_t dash_key_xpub_public_key(const struct FFIExtendedPubKey *xpub, uint8_t *key_out) ; - -// Destroy an extended public key - void dash_key_xpub_destroy(struct FFIExtendedPubKey *xpub) ; - -// Generate a P2PKH address from public key -// -// # Parameters -// - `pubkey`: The public key bytes (33 bytes compressed) -// - `network`: The network type -// -// # Returns -// - C string containing the address (caller must free) -// - NULL on error - char *dash_key_address_from_pubkey(const uint8_t *pubkey, enum FFIKeyNetwork network) ; - -// Validate an address string -// -// # Parameters -// - `address`: The address string -// - `network`: The expected network -// -// # Returns -// - 1 if valid -// - 0 if invalid - int32_t dash_key_address_validate(const char *address, enum FFIKeyNetwork network) ; - -// Fetches protocol version upgrade state -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// -// # Returns -// * JSON array of protocol version upgrade information -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_protocol_version_get_upgrade_state(const struct dash_sdk_handle_t *sdk_handle) ; - -// Fetches protocol version upgrade vote status -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `start_pro_tx_hash` - Starting masternode pro_tx_hash (hex-encoded, optional) -// * `count` - Number of vote entries to retrieve -// -// # Returns -// * JSON array of masternode protocol version votes or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_protocol_version_get_upgrade_vote_status(const struct dash_sdk_handle_t *sdk_handle, const char *start_pro_tx_hash, uint32_t count) ; - -// Create a new SDK instance - struct DashSDKResult dash_sdk_create(const struct DashSDKConfig *config) ; - -// Create a new SDK instance with extended configuration including context provider - struct DashSDKResult dash_sdk_create_extended(const struct DashSDKConfigExtended *config) ; - -// Create a new SDK instance with trusted setup -// -// This creates an SDK with a trusted context provider that fetches quorum keys and -// data contracts from trusted endpoints instead of requiring proof verification. -// -// # Safety -// - `config` must be a valid pointer to a DashSDKConfig structure - struct DashSDKResult dash_sdk_create_trusted(const struct DashSDKConfig *config) ; - -// Destroy an SDK instance - void dash_sdk_destroy(struct dash_sdk_handle_t *handle) ; - -// Register global context provider callbacks -// -// This must be called before creating an SDK instance that needs Core SDK functionality. -// The callbacks will be used by all SDK instances created after registration. -// -// # Safety -// - `callbacks` must contain valid function pointers that remain valid for the lifetime of the SDK - int32_t dash_sdk_register_context_callbacks(const struct ContextProviderCallbacks *callbacks) ; - -// Create a new SDK instance with explicit context callbacks -// -// This is an alternative to registering global callbacks. The callbacks are used only for this SDK instance. -// -// # Safety -// - `config` must be a valid pointer to a DashSDKConfig structure -// - `callbacks` must contain valid function pointers that remain valid for the lifetime of the SDK - struct DashSDKResult dash_sdk_create_with_callbacks(const struct DashSDKConfig *config, const struct ContextProviderCallbacks *callbacks) ; - -// Get the current network the SDK is connected to - enum DashSDKNetwork dash_sdk_get_network(const struct dash_sdk_handle_t *handle) ; - -// Create a mock SDK instance with a dump directory (for offline testing) - struct dash_sdk_handle_t *dash_sdk_create_handle_with_mock(const char *dump_dir) ; - -// Create a new iOS signer -// free_result_callback: Optional custom deallocator for sign result buffers (NULL = use libc free). -// Swift/Kotlin callers that allocate with their own allocator MUST supply -// a matching deallocator to avoid undefined behavior. - struct SignerHandle *dash_sdk_signer_create(IOSSignCallback sign_callback, IOSCanSignCallback can_sign_callback, void (*destroy_callback)(void *signer), FreeResultCallback free_result_callback) ; - -// Destroy an iOS signer - void dash_sdk_signer_destroy(struct SignerHandle *handle) ; - -// Free bytes allocated with malloc/calloc. This is the default deallocator used -// when SignerVTable::free_result is NULL. If your callback uses a different -// allocator, supply a custom free_result in the vtable instead. - void dash_sdk_bytes_free(uint8_t *bytes) ; - -// Create a signer from a private key - struct DashSDKResult dash_sdk_signer_create_from_private_key(const uint8_t *private_key, uintptr_t private_key_len) ; - -// Sign data with a signer - struct DashSDKResult dash_sdk_signer_sign(struct SignerHandle *signer_handle, const uint8_t *data, uintptr_t data_len) ; - -// Free a signature - void dash_sdk_signature_free(struct DashSDKSignature *signature) ; - -// Fetches information about current quorums -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// -// # Returns -// * JSON string with current quorums information -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_system_get_current_quorums_info(const struct dash_sdk_handle_t *sdk_handle) ; - -// Fetches information about multiple epochs -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `start_epoch` - Starting epoch index (optional, null for default) -// * `count` - Number of epochs to retrieve -// * `ascending` - Whether to return epochs in ascending order -// -// # Returns -// * JSON array of epoch information or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_system_get_epochs_info(const struct dash_sdk_handle_t *sdk_handle, const char *start_epoch, uint32_t count, bool ascending) ; - -// Fetches path elements -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `path_json` - JSON array of path elements (hex-encoded byte arrays) -// * `keys_json` - JSON array of keys (hex-encoded byte arrays) -// -// # Returns -// * JSON array of elements or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_system_get_path_elements(const struct dash_sdk_handle_t *sdk_handle, const char *path_json, const char *keys_json) ; - -// Get platform status including block heights - struct DashSDKResult dash_sdk_get_platform_status(const struct dash_sdk_handle_t *sdk_handle) ; - -// Fetches a prefunded specialized balance -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `id` - Base58-encoded identifier -// -// # Returns -// * JSON string with balance or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_system_get_prefunded_specialized_balance(const struct dash_sdk_handle_t *sdk_handle, const char *id) ; - -// Fetches the total credits in the platform -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// -// # Returns -// * JSON string with total credits -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_system_get_total_credits_in_platform(const struct dash_sdk_handle_t *sdk_handle) ; - -// Get SDK status including mode and quorum count - struct DashSDKResult dash_sdk_get_status(const struct dash_sdk_handle_t *sdk_handle) ; - -// Burn tokens from an identity and wait for confirmation - struct DashSDKResult dash_sdk_token_burn(struct dash_sdk_handle_t *sdk_handle, const uint8_t *transition_owner_id, const struct DashSDKTokenBurnParams *params, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Claim tokens from a distribution and wait for confirmation - struct DashSDKResult dash_sdk_token_claim(struct dash_sdk_handle_t *sdk_handle, const uint8_t *transition_owner_id, const struct DashSDKTokenClaimParams *params, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Mint tokens to an identity and wait for confirmation - struct DashSDKResult dash_sdk_token_mint(struct dash_sdk_handle_t *sdk_handle, const uint8_t *transition_owner_id, const struct DashSDKTokenMintParams *params, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Token transfer to another identity and wait for confirmation - struct DashSDKResult dash_sdk_token_transfer(struct dash_sdk_handle_t *sdk_handle, const uint8_t *transition_owner_id, const struct DashSDKTokenTransferParams *params, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Update token configuration and wait for confirmation - struct DashSDKResult dash_sdk_token_update_contract_token_configuration(struct dash_sdk_handle_t *sdk_handle, const uint8_t *transition_owner_id, const struct DashSDKTokenConfigUpdateParams *params, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Destroy frozen token funds and wait for confirmation - struct DashSDKResult dash_sdk_token_destroy_frozen_funds(struct dash_sdk_handle_t *sdk_handle, const uint8_t *transition_owner_id, const struct DashSDKTokenDestroyFrozenFundsParams *params, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Perform emergency action on token and wait for confirmation - struct DashSDKResult dash_sdk_token_emergency_action(struct dash_sdk_handle_t *sdk_handle, const uint8_t *transition_owner_id, const struct DashSDKTokenEmergencyActionParams *params, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Freeze a token for an identity and wait for confirmation - struct DashSDKResult dash_sdk_token_freeze(struct dash_sdk_handle_t *sdk_handle, const uint8_t *transition_owner_id, const struct DashSDKTokenFreezeParams *params, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Unfreeze a token for an identity and wait for confirmation - struct DashSDKResult dash_sdk_token_unfreeze(struct dash_sdk_handle_t *sdk_handle, const uint8_t *transition_owner_id, const struct DashSDKTokenFreezeParams *params, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Purchase tokens directly and wait for confirmation - struct DashSDKResult dash_sdk_token_purchase(struct dash_sdk_handle_t *sdk_handle, const uint8_t *transition_owner_id, const struct DashSDKTokenPurchaseParams *params, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Set token price for direct purchase and wait for confirmation - struct DashSDKResult dash_sdk_token_set_price(struct dash_sdk_handle_t *sdk_handle, const uint8_t *transition_owner_id, const struct DashSDKTokenSetPriceParams *params, const struct IdentityPublicKeyHandle *identity_public_key_handle, const struct SignerHandle *signer_handle, const struct DashSDKPutSettings *put_settings, const struct DashSDKStateTransitionCreationOptions *state_transition_creation_options) ; - -// Get identity token balances -// -// This is an alias for dash_sdk_identity_fetch_token_balances for backward compatibility -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_id`: Base58-encoded identity ID -// - `token_ids`: Comma-separated list of Base58-encoded token IDs -// -// # Returns -// JSON string containing token IDs mapped to their balances - struct DashSDKResult dash_sdk_token_get_identity_balances(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id, const char *token_ids) ; - -// Get token contract info -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `token_id`: Base58-encoded token ID -// -// # Returns -// JSON string containing the contract ID and token position, or null if not found - struct DashSDKResult dash_sdk_token_get_contract_info(const struct dash_sdk_handle_t *sdk_handle, const char *token_id) ; - -// Get token direct purchase prices -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `token_ids`: Comma-separated list of Base58-encoded token IDs -// -// # Returns -// JSON string containing token IDs mapped to their pricing information - struct DashSDKResult dash_sdk_token_get_direct_purchase_prices(const struct dash_sdk_handle_t *sdk_handle, const char *token_ids) ; - -// Fetch token balances for multiple identities for a specific token -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_ids`: Comma-separated list of Base58-encoded identity IDs -// - `token_id`: Base58-encoded token ID -// -// # Returns -// JSON string containing identity IDs mapped to their token balances - struct DashSDKResult dash_sdk_identities_fetch_token_balances(const struct dash_sdk_handle_t *sdk_handle, const char *identity_ids, const char *token_id) ; - -// Fetch token information for multiple identities for a specific token -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_ids`: Comma-separated list of Base58-encoded identity IDs -// - `token_id`: Base58-encoded token ID -// -// # Returns -// JSON string containing identity IDs mapped to their token information - struct DashSDKResult dash_sdk_identities_fetch_token_infos(const struct dash_sdk_handle_t *sdk_handle, const char *identity_ids, const char *token_id) ; - -// Fetch token balances for a specific identity -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_id`: Base58-encoded identity ID -// - `token_ids`: Comma-separated list of Base58-encoded token IDs -// -// # Returns -// JSON string containing token IDs mapped to their balances - struct DashSDKResult dash_sdk_identity_fetch_token_balances(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id, const char *token_ids) ; - -// Fetch token information for a specific identity -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_id`: Base58-encoded identity ID -// - `token_ids`: Comma-separated list of Base58-encoded token IDs -// -// # Returns -// JSON string containing token IDs mapped to their information - struct DashSDKResult dash_sdk_identity_fetch_token_infos(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id, const char *token_ids) ; - -// Get identity token information -// -// This is an alias for dash_sdk_identity_fetch_token_infos for backward compatibility -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `identity_id`: Base58-encoded identity ID -// - `token_ids`: Comma-separated list of Base58-encoded token IDs -// -// # Returns -// JSON string containing token IDs mapped to their information - struct DashSDKResult dash_sdk_token_get_identity_infos(const struct dash_sdk_handle_t *sdk_handle, const char *identity_id, const char *token_ids) ; - -// Get token perpetual distribution last claim -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `token_id`: Base58-encoded token ID -// - `identity_id`: Base58-encoded identity ID -// -// # Returns -// JSON string containing the last claim information - struct DashSDKResult dash_sdk_token_get_perpetual_distribution_last_claim(const struct dash_sdk_handle_t *sdk_handle, const char *token_id, const char *identity_id) ; - -// Get token statuses -// -// # Parameters -// - `sdk_handle`: SDK handle -// - `token_ids`: Comma-separated list of Base58-encoded token IDs -// -// # Returns -// JSON string containing token IDs mapped to their status information - struct DashSDKResult dash_sdk_token_get_statuses(const struct dash_sdk_handle_t *sdk_handle, const char *token_ids) ; - -// Fetches the total supply of a token -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `token_id` - Base58-encoded token identifier -// -// # Returns -// * JSON string with token supply info or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_token_get_total_supply(const struct dash_sdk_handle_t *sdk_handle, const char *token_id) ; - -// Create a new empty transaction -// -// # Returns -// - Pointer to FFITransaction on success -// - NULL on error - struct FFITransaction *dash_tx_create(void) ; - -// Add an input to a transaction -// -// # Parameters -// - `tx`: The transaction -// - `input`: The input to add -// -// # Returns -// - 0 on success -// - -1 on error - int32_t dash_tx_add_input(struct FFITransaction *tx, const struct FFITxIn *input) ; - -// Add an output to a transaction -// -// # Parameters -// - `tx`: The transaction -// - `output`: The output to add -// -// # Returns -// - 0 on success -// - -1 on error - int32_t dash_tx_add_output(struct FFITransaction *tx, const struct FFITxOut *output) ; - -// Get the transaction ID -// -// # Parameters -// - `tx`: The transaction -// - `txid_out`: Buffer to write txid (must be 32 bytes) -// -// # Returns -// - 0 on success -// - -1 on error - int32_t dash_tx_get_txid(const struct FFITransaction *tx, uint8_t *txid_out) ; - -// Serialize a transaction -// -// # Parameters -// - `tx`: The transaction -// - `out_buf`: Buffer to write serialized data (can be NULL to get size) -// - `out_len`: In/out parameter for buffer size -// -// # Returns -// - 0 on success -// - -1 on error - int32_t dash_tx_serialize(const struct FFITransaction *tx, uint8_t *out_buf, uint32_t *out_len) ; - -// Deserialize a transaction -// -// # Parameters -// - `data`: The serialized transaction data -// - `len`: Length of the data -// -// # Returns -// - Pointer to FFITransaction on success -// - NULL on error - struct FFITransaction *dash_tx_deserialize(const uint8_t *data, uint32_t len) ; - -// Destroy a transaction - void dash_tx_destroy(struct FFITransaction *tx) ; - -// Calculate signature hash for an input -// -// # Parameters -// - `tx`: The transaction -// - `input_index`: Which input to sign -// - `script_pubkey`: The script pubkey of the output being spent -// - `script_pubkey_len`: Length of script pubkey -// - `sighash_type`: Signature hash type (usually 0x01 for SIGHASH_ALL) -// - `hash_out`: Buffer to write hash (must be 32 bytes) -// -// # Returns -// - 0 on success -// - -1 on error - int32_t dash_tx_sighash(const struct FFITransaction *tx, uint32_t input_index, const uint8_t *script_pubkey, uint32_t script_pubkey_len, uint32_t sighash_type, uint8_t *hash_out) ; - -// Sign a transaction input -// -// # Parameters -// - `tx`: The transaction -// - `input_index`: Which input to sign -// - `private_key`: The private key (32 bytes) -// - `script_pubkey`: The script pubkey of the output being spent -// - `script_pubkey_len`: Length of script pubkey -// - `sighash_type`: Signature hash type -// -// # Returns -// - 0 on success -// - -1 on error - int32_t dash_tx_sign_input(struct FFITransaction *tx, uint32_t input_index, const uint8_t *private_key, const uint8_t *script_pubkey, uint32_t script_pubkey_len, uint32_t sighash_type) ; - -// Create a P2PKH script pubkey -// -// # Parameters -// - `pubkey_hash`: The public key hash (20 bytes) -// - `out_buf`: Buffer to write script (can be NULL to get size) -// - `out_len`: In/out parameter for buffer size -// -// # Returns -// - 0 on success -// - -1 on error - int32_t dash_script_p2pkh(const uint8_t *pubkey_hash, uint8_t *out_buf, uint32_t *out_len) ; - -// Extract public key hash from P2PKH address -// -// # Parameters -// - `address`: The address string -// - `network`: The expected network -// - `hash_out`: Buffer to write hash (must be 20 bytes) -// -// # Returns -// - 0 on success -// - -1 on error - int32_t dash_address_to_pubkey_hash(const char *address, enum FFIKeyNetwork network, uint8_t *hash_out) ; - -// Free a string allocated by the FFI - void dash_sdk_string_free(char *s) ; - -// Free binary data allocated by the FFI - void dash_sdk_binary_data_free(struct DashSDKBinaryData *binary_data) ; - -// Free an identity info structure - void dash_sdk_identity_info_free(struct DashSDKIdentityInfo *info) ; - -// Free a document info structure - void dash_sdk_document_info_free(struct DashSDKDocumentInfo *info) ; - -// Free an identity balance map - void dash_sdk_identity_balance_map_free(struct DashSDKIdentityBalanceMap *map) ; - -// Free a DashSDKResult and all resources it owns. -// Inspects data_type and dispatches to the correct cleanup for data. -// Also frees the error field when present. -// After this call, data and error pointers inside the struct are set to null. -// The DashSDKResult struct itself is NOT freed (typically stack-allocated by caller). -// -// # Safety -// - result must be a valid, non-null pointer to a DashSDKResult whose data and error -// fields were produced by this SDK and have not yet been freed. -// - If result is null this is a no-op. - void dash_sdk_result_free(struct DashSDKResult *result) ; - -// Initialize the unified SDK system -// This initializes both Core SDK (if enabled) and Platform SDK - int32_t dash_unified_sdk_init(void) ; - -// Create a unified SDK handle with both Core and Platform SDKs -// -// # Safety -// - `config` must point to a valid UnifiedSDKConfig structure - struct UnifiedSDKHandle *dash_unified_sdk_create(const struct UnifiedSDKConfig *config) ; - -// Destroy a unified SDK handle -// -// # Safety -// - `handle` must be a valid unified SDK handle or null - void dash_unified_sdk_destroy(struct UnifiedSDKHandle *handle) ; - -// Start both Core and Platform SDKs -// -// # Safety -// - `handle` must be a valid unified SDK handle - int32_t dash_unified_sdk_start(struct UnifiedSDKHandle *handle) ; - -// Stop both Core and Platform SDKs -// -// # Safety -// - `handle` must be a valid unified SDK handle - int32_t dash_unified_sdk_stop(struct UnifiedSDKHandle *handle) ; - -// Get the Core SDK client from a unified handle -// -// # Safety -// - `handle` must be a valid unified SDK handle - struct FFIDashSpvClient *dash_unified_sdk_get_core_client(struct UnifiedSDKHandle *handle) ; - -// Get the Platform SDK from a unified handle -// -// # Safety -// - `handle` must be a valid unified SDK handle - struct dash_sdk_handle_t *dash_unified_sdk_get_platform_sdk(struct UnifiedSDKHandle *handle) ; - -// Check if integration is enabled for this unified SDK -// -// # Safety -// - `handle` must be a valid unified SDK handle - bool dash_unified_sdk_is_integration_enabled(struct UnifiedSDKHandle *handle) ; - -// Check if Core SDK is available in this unified SDK -// -// # Safety -// - `handle` must be a valid unified SDK handle - bool dash_unified_sdk_has_core_sdk(struct UnifiedSDKHandle *handle) ; - -// Register Core SDK with Platform SDK for context provider callbacks -// This enables Platform SDK to query Core SDK for blockchain state -// -// # Safety -// - `handle` must be a valid unified SDK handle - int32_t dash_unified_sdk_register_core_context(struct UnifiedSDKHandle *handle) ; - -// Get combined status of both SDKs -// -// # Safety -// - `handle` must be a valid unified SDK handle -// - `core_height` must point to a valid u32 (set to 0 if core disabled) -// - `platform_ready` must point to a valid bool - int32_t dash_unified_sdk_get_status(struct UnifiedSDKHandle *handle, uint32_t *core_height, bool *platform_ready) ; - -// Get unified SDK version information - const char *dash_unified_sdk_version(void) ; - -// Check if unified SDK was compiled with core support - bool dash_unified_sdk_has_core_support(void) ; - -// Convert a hex string to base58 -// -// # Parameters -// - `hex_string`: Hex encoded string (must be 64 characters for identity IDs) -// -// # Returns -// - Base58 encoded string on success -// - Error if the hex string is invalid - struct DashSDKResult dash_sdk_utils_hex_to_base58(const char *hex_string) ; - -// Convert a base58 string to hex -// -// # Parameters -// - `base58_string`: Base58 encoded string -// -// # Returns -// - Hex encoded string on success -// - Error if the base58 string is invalid - struct DashSDKResult dash_sdk_utils_base58_to_hex(const char *base58_string) ; - -// Validate if a string is valid base58 -// -// # Parameters -// - `string`: String to validate -// -// # Returns -// - 1 if valid base58, 0 if invalid - uint8_t dash_sdk_utils_is_valid_base58(const char *string) ; - -// Fetches vote polls by end date -// -// # Parameters -// * `sdk_handle` - Handle to the SDK instance -// * `start_time_ms` - Start time in milliseconds (optional, 0 for no start time) -// * `start_time_included` - Whether to include the start time -// * `end_time_ms` - End time in milliseconds (optional, 0 for no end time) -// * `end_time_included` - Whether to include the end time -// * `limit` - Maximum number of results to return (optional, 0 for no limit) -// * `offset` - Number of results to skip (optional, 0 for no offset) -// * `ascending` - Whether to order results in ascending order -// -// # Returns -// * JSON array of vote polls grouped by timestamp or null if not found -// * Error message if operation fails -// -// # Safety -// This function is unsafe because it handles raw pointers from C - struct DashSDKResult dash_sdk_voting_get_vote_polls_by_end_date(const struct dash_sdk_handle_t *sdk_handle, uint64_t start_time_ms, bool start_time_included, uint64_t end_time_ms, bool end_time_included, uint32_t limit, uint32_t offset, bool ascending) ; - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -#endif /* DASH_SDK_FFI_H */ diff --git a/packages/rs-sdk-ffi/src/callback_bridge.rs b/packages/rs-sdk-ffi/src/callback_bridge.rs deleted file mode 100644 index b526016f855..00000000000 --- a/packages/rs-sdk-ffi/src/callback_bridge.rs +++ /dev/null @@ -1,215 +0,0 @@ -//! Callback bridge module for Core SDK integration -//! -//! This module implements the callback bridge pattern from dash-unified-ffi-old -//! to eliminate circular dependencies between Platform SDK and Core SDK. -//! Instead of direct linking, Core SDK functions are registered as callbacks -//! at runtime with the Platform SDK. - -use crate::context_callbacks::{CallbackResult, ContextProviderCallbacks}; -use std::ffi::c_void; - -/// Register Core SDK handle and setup callback bridge with Platform SDK -/// -/// This function implements the core pattern from dash-unified-ffi-old: -/// 1. Takes a Core SDK handle -/// 2. Creates callback wrappers for the functions Platform SDK needs -/// 3. Registers these callbacks with Platform SDK's context provider system -/// -/// # Safety -/// - `core_handle` must be a valid Core SDK handle that remains valid for the SDK lifetime -/// - This function should be called once after creating both Core and Platform SDK instances -#[no_mangle] -pub unsafe extern "C" fn dash_unified_register_core_sdk_handle(core_handle: *mut c_void) -> i32 { - if core_handle.is_null() { - return -1; - } - - // Create the callback structure with Core SDK function wrappers - let callbacks = ContextProviderCallbacks { - core_handle, - get_platform_activation_height: bridge_get_platform_activation_height, - get_quorum_public_key: bridge_get_quorum_public_key, - }; - - // Register the callbacks with Platform SDK's context provider system - match crate::context_callbacks::set_global_callbacks(callbacks) { - Ok(()) => 0, - Err(_) => -1, - } -} - -/// Bridge wrapper for Core SDK's get_platform_activation_height function -/// -/// This function wraps the actual Core SDK function call in a callback-compatible signature. -/// It eliminates the circular dependency by calling the Core SDK function via extern declaration -/// rather than direct linking. -/// -/// # Safety -/// - `handle` must be a valid Core SDK handle -/// - `out_height` must be a valid pointer to u32 -unsafe extern "C" fn bridge_get_platform_activation_height( - handle: *mut c_void, - out_height: *mut u32, -) -> CallbackResult { - if handle.is_null() || out_height.is_null() { - return CallbackResult { - success: false, - error_code: -1, - error_message: c"Invalid handle or output pointer".as_ptr(), - }; - } - - // Call the actual Core SDK function via extern declaration - // This avoids circular dependency while still accessing Core SDK functionality - extern "C" { - fn ffi_dash_spv_get_platform_activation_height( - handle: *mut c_void, - out_height: *mut u32, - ) -> i32; - } - - let result = ffi_dash_spv_get_platform_activation_height(handle, out_height); - - if result == 0 { - CallbackResult { - success: true, - error_code: 0, - error_message: std::ptr::null(), - } - } else { - CallbackResult { - success: false, - error_code: result, - error_message: c"Failed to get platform activation height".as_ptr(), - } - } -} - -/// Bridge wrapper for Core SDK's get_quorum_public_key function -/// -/// This function wraps the actual Core SDK function call in a callback-compatible signature. -/// -/// # Safety -/// - `handle` must be a valid Core SDK handle -/// - `quorum_hash` must point to a valid 32-byte buffer -/// - `out_pubkey` must point to a valid 48-byte buffer -unsafe extern "C" fn bridge_get_quorum_public_key( - handle: *mut c_void, - quorum_type: u32, - quorum_hash: *const u8, - core_chain_locked_height: u32, - out_pubkey: *mut u8, -) -> CallbackResult { - if handle.is_null() || quorum_hash.is_null() || out_pubkey.is_null() { - return CallbackResult { - success: false, - error_code: -1, - error_message: c"Invalid handle or pointer parameters".as_ptr(), - }; - } - - // Call the actual Core SDK function via extern declaration - extern "C" { - fn ffi_dash_spv_get_quorum_public_key( - handle: *mut c_void, - quorum_type: u32, - quorum_hash: *const u8, - core_chain_locked_height: u32, - out_pubkey: *mut u8, - pubkey_size: usize, - ) -> i32; - } - - let result = ffi_dash_spv_get_quorum_public_key( - handle, - quorum_type, - quorum_hash, - core_chain_locked_height, - out_pubkey, - 48, // BLS public key size - ); - - if result == 0 { - CallbackResult { - success: true, - error_code: 0, - error_message: std::ptr::null(), - } - } else { - CallbackResult { - success: false, - error_code: result, - error_message: c"Failed to get quorum public key".as_ptr(), - } - } -} - -/// Initialize the unified SDK system with callback bridge support -/// -/// This function initializes both Core SDK and Platform SDK and sets up -/// the callback bridge pattern for inter-SDK communication. -#[no_mangle] -pub extern "C" fn dash_unified_init() -> i32 { - // Initialize Platform SDK first - crate::dash_sdk_init(); - - // Note: Core SDK will be initialized when the client is created - // The callback bridge will be set up when dash_unified_register_core_sdk_handle is called - - 0 -} - -/// Get unified SDK version information including both Core and Platform components -#[no_mangle] -pub extern "C" fn dash_unified_version() -> *const std::os::raw::c_char { - static VERSION: &str = concat!("unified-", env!("CARGO_PKG_VERSION"), "+core+platform\0"); - VERSION.as_ptr() as *const std::os::raw::c_char -} - -/// Check if unified SDK has both Core and Platform support -#[no_mangle] -pub extern "C" fn dash_unified_has_full_support() -> bool { - true // Always true in the unified approach -} - -#[cfg(test)] -mod tests { - use super::*; - use std::ptr; - - #[test] - fn test_callback_bridge_null_handling() { - // Test that bridge functions handle null pointers gracefully - unsafe { - let result = bridge_get_platform_activation_height(ptr::null_mut(), ptr::null_mut()); - assert!(!result.success); - assert_eq!(result.error_code, -1); - } - } - - #[test] - fn test_unified_init() { - let result = dash_unified_init(); - assert_eq!(result, 0); - } - - #[test] - fn test_unified_version() { - let version = dash_unified_version(); - assert!(!version.is_null()); - - let version_str = unsafe { - std::ffi::CStr::from_ptr(version) - .to_str() - .expect("Version should be valid UTF-8") - }; - - assert!(version_str.starts_with("unified-")); - assert!(version_str.contains("+core+platform")); - } - - #[test] - fn test_unified_support() { - assert!(dash_unified_has_full_support()); - } -} diff --git a/packages/rs-sdk-ffi/src/context_provider_stubs.rs b/packages/rs-sdk-ffi/src/context_provider_stubs.rs deleted file mode 100644 index ceb29a841e4..00000000000 --- a/packages/rs-sdk-ffi/src/context_provider_stubs.rs +++ /dev/null @@ -1,72 +0,0 @@ -//! Stub implementations for Core SDK FFI functions -//! -//! These are temporary stubs for testing compilation. -//! In production, these symbols would be provided by linking against the Core SDK library. - -#[cfg(all(test, feature = "ffi_core_stubs", not(feature = "dash_spv")))] -use std::ffi::c_char; - -// Local test-only definitions for stubs -#[cfg(all(test, feature = "ffi_core_stubs", not(feature = "dash_spv")))] -#[repr(C)] -pub struct FFIResult { - pub error_code: i32, - pub error_message: *const c_char, -} - -#[cfg(all(test, feature = "ffi_core_stubs", not(feature = "dash_spv")))] -type FFIDashSpvClient = std::ffi::c_void; - -// Only compile stubs for tests when explicitly enabled AND dash-spv FFI is not linked. -#[cfg(all(test, feature = "ffi_core_stubs", not(feature = "dash_spv")))] -#[no_mangle] -pub unsafe extern "C" fn ffi_dash_spv_get_quorum_public_key( - _client: *mut FFIDashSpvClient, - _quorum_type: u32, - _quorum_hash: *const u8, - _core_chain_locked_height: u32, - out_pubkey: *mut u8, -) -> FFIResult { - // Stub implementation - fill with test data - if !out_pubkey.is_null() { - let test_key = [0u8; 48]; - std::ptr::copy_nonoverlapping(test_key.as_ptr(), out_pubkey, 48); - } - - FFIResult { - error_code: 0, - error_message: std::ptr::null(), - } -} - -#[cfg(all(test, feature = "ffi_core_stubs", not(feature = "dash_spv")))] -#[no_mangle] -pub unsafe extern "C" fn ffi_dash_spv_get_platform_activation_height( - _client: *mut FFIDashSpvClient, - out_height: *mut u32, -) -> FFIResult { - // Stub implementation - return test height - if !out_height.is_null() { - *out_height = 1000000; // Example activation height - } - - FFIResult { - error_code: 0, - error_message: std::ptr::null(), - } -} - -#[cfg(all(test, feature = "ffi_core_stubs", not(feature = "dash_spv")))] -#[no_mangle] -pub unsafe extern "C" fn ffi_dash_spv_get_core_handle( - _client: *mut FFIDashSpvClient, -) -> *mut CoreSDKHandle { - // Stub implementation - std::ptr::null_mut() -} - -#[cfg(all(test, feature = "ffi_core_stubs", not(feature = "dash_spv")))] -#[no_mangle] -pub unsafe extern "C" fn ffi_dash_spv_release_core_handle(_handle: *mut CoreSDKHandle) { - // Stub implementation - nothing to do -} diff --git a/packages/rs-sdk-ffi/src/lib.rs b/packages/rs-sdk-ffi/src/lib.rs index 67ab307ba1e..0a5e2277f69 100644 --- a/packages/rs-sdk-ffi/src/lib.rs +++ b/packages/rs-sdk-ffi/src/lib.rs @@ -7,12 +7,9 @@ mod address; mod address_sync; -mod callback_bridge; mod contested_resource; mod context_callbacks; pub mod context_provider; -#[cfg(test)] -mod context_provider_stubs; mod crypto; mod dashpay; mod data_contract; @@ -40,7 +37,6 @@ mod test_utils; pub use address::*; pub use address_sync::*; -pub use callback_bridge::*; pub use contested_resource::*; pub use context_callbacks::*; pub use context_provider::*; @@ -67,10 +63,6 @@ pub use types::*; pub use utils::*; pub use voting::*; -// Re-export all Core SDK functions and types for unified access when linked -#[cfg(feature = "dash_spv")] -pub use dash_spv_ffi as core_ffi; - // Re-export Platform Wallet FFI functions and types for DashPay support // Note: We re-export selectively to avoid conflicts with rs-sdk-ffi's own modules pub use platform_wallet_ffi::{ diff --git a/packages/rs-unified-sdk-ffi/Cargo.toml b/packages/rs-unified-sdk-ffi/Cargo.toml new file mode 100644 index 00000000000..e774e067ba5 --- /dev/null +++ b/packages/rs-unified-sdk-ffi/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "rs-unified-sdk-ffi" +edition = "2024" +version.workspace = true +rust-version.workspace = true + +[lib] +crate-type = ["staticlib", "cdylib"] + +[dependencies] +dash-spv-ffi = { workspace = true } +key-wallet-ffi = { workspace = true } +rs-sdk-ffi = { path = "../rs-sdk-ffi" } \ No newline at end of file diff --git a/packages/rs-unified-sdk-ffi/src/lib.rs b/packages/rs-unified-sdk-ffi/src/lib.rs new file mode 100644 index 00000000000..59bdd1fac8a --- /dev/null +++ b/packages/rs-unified-sdk-ffi/src/lib.rs @@ -0,0 +1,3 @@ +pub use dash_spv_ffi; +pub use key_wallet_ffi; +pub use rs_sdk_ffi; diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/Core/SPV/SPVClient.swift b/packages/swift-sdk/Sources/SwiftDashSDK/Core/SPV/SPVClient.swift index 42cca1b7f98..345fd6f7211 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/Core/SPV/SPVClient.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/Core/SPV/SPVClient.swift @@ -185,7 +185,7 @@ class SPVClient: @unchecked Sendable { func destroy() { dash_spv_ffi_client_destroy(client) dash_spv_ffi_config_destroy(config) - + client = nil config = nil } diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/Core/Services/WalletService.swift b/packages/swift-sdk/Sources/SwiftDashSDK/Core/Services/WalletService.swift index 41f6050c741..ba19cdb52bb 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/Core/Services/WalletService.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/Core/Services/WalletService.swift @@ -84,9 +84,9 @@ func print(_ items: Any..., separator: String = " ", terminator: String = "\n") Swift.print(output, terminator: terminator) } -// DESIGN NOTE: This class feels like something that should be in the example app, +// DESIGN NOTE: This class feels like something that should be in the example app, // we, as sdk developers, provide the tools and ffi wrappers, but how to -// use them depends on the sdk user, for example, by implementing the SPV event +// use them depends on the sdk user, for example, by implementing the SPV event // handlers, the user can decide what to do with the events, but if we implement them in the sdk // we are taking that decision for them, and maybe not all users want the same thing @MainActor @@ -96,10 +96,10 @@ public class WalletService: ObservableObject { @Published public var masternodesEnabled = true @Published public var lastSyncError: Error? @Published var network: AppNetwork - + // Internal properties private var modelContainer: ModelContainer - + // SPV Client and Wallet wrappers private var spvClient: SPVClient public private(set) var walletManager: CoreWalletManager @@ -152,12 +152,12 @@ public class WalletService: ObservableObject { // Recreate the wallet manager with the new client self.walletManager = try! CoreWalletManager(spvClient: self.spvClient, modelContainer: modelContainer) } - + deinit { spvClient.stopSync() spvClient.destroy() } - + private func initializeNewSPVClient() { SDKLogger.log("Initializing SPV Client for \(self.self.network.rawValue)...", minimumLevel: .medium) @@ -200,7 +200,7 @@ public class WalletService: ObservableObject { SDKLogger.log("WalletManager wrapper initialized successfully", minimumLevel: .medium) } - + // MARK: - Trusted Mode / Masternode Sync public func setMasternodesEnabled(_ enabled: Bool) { masternodesEnabled = enabled @@ -232,7 +232,7 @@ public class WalletService: ObservableObject { // pausing and resuming is not supported so, the trick is the following, // stop the old client and create a new one in its initial state xd spvClient.stopSync() - + self.initializeNewSPVClient() } @@ -265,17 +265,17 @@ public class WalletService: ObservableObject { public func switchNetwork(to network: AppNetwork) async { guard network != self.network else { return } - + print("=== WalletService.switchNetwork START ===") print("Switching from \(self.network.rawValue) to \(network.rawValue)") - + self.network = network self.stopSync() - + print("=== WalletService.switchNetwork END ===") } - + // MARK: - SPV Event Handlers implementations internal final class SPVProgressUpdateEventHandlerImpl: SPVProgressUpdateEventHandler, Sendable { diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/KeyDerivation.swift b/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/KeyDerivation.swift index fbe9c030ae5..f39f2e5518d 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/KeyDerivation.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/KeyDerivation.swift @@ -262,9 +262,9 @@ public class KeyDerivation { /// Extended private key handle public class ExtendedPrivateKey { - private let handle: OpaquePointer + private let handle: UnsafeMutablePointer - internal init(handle: OpaquePointer) { + internal init(handle: UnsafeMutablePointer) { self.handle = handle } @@ -307,9 +307,9 @@ public class ExtendedPrivateKey { /// Extended public key handle public class ExtendedPublicKey { - private let handle: OpaquePointer + private let handle: UnsafeMutablePointer - internal init(handle: OpaquePointer) { + internal init(handle: UnsafeMutablePointer) { self.handle = handle } diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedPlatformAccount.swift b/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedPlatformAccount.swift index a7d7ba13d5b..cd30e9dbed6 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedPlatformAccount.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedPlatformAccount.swift @@ -5,10 +5,8 @@ // Platform payment accounts are identified by (account_index, key_class) // and hold credit/duff balances with their own address pool. // -// Note: FFIManagedPlatformAccount is an incomplete (opaque) C type, so Swift -// imports pointers to it as OpaquePointer rather than -// UnsafeMutablePointer. All FFI functions that -// accept or return this type are called through OpaquePointer here. +// FFIManagedPlatformAccount is an opaque C type with a minimal body so Swift +// can use typed pointers (UnsafeMutablePointer). import Foundation import DashSDKFFI @@ -35,9 +33,9 @@ public struct PlatformPaymentAccountKey: Sendable, Equatable { /// Provides access to credit/duff balances, address counts, and the /// account's address pool. The underlying FFI handle is freed on deinit. public class ManagedPlatformAccount { - private let handle: OpaquePointer + private let handle: UnsafeMutablePointer - internal init(handle: OpaquePointer) { + internal init(handle: UnsafeMutablePointer) { self.handle = handle } diff --git a/packages/swift-sdk/build_ios.sh b/packages/swift-sdk/build_ios.sh index dd4d5f457aa..0449969e477 100755 --- a/packages/swift-sdk/build_ios.sh +++ b/packages/swift-sdk/build_ios.sh @@ -1,110 +1,264 @@ -#!/usr/bin/env bash +#!/bin/bash set -euo pipefail -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -REPO_ROOT="$( cd "$SCRIPT_DIR/../.." && pwd )" +export IPHONEOS_DEPLOYMENT_TARGET="18.0" +export IPHONESIMULATOR_DEPLOYMENT_TARGET="18.0" -# Pass --clean through to rs-sdk-ffi if requested -EXTRA_ARGS="" -for arg in "$@"; do - case $arg in - --clean) EXTRA_ARGS="$EXTRA_ARGS --clean" ;; - esac -done +# ------------------------------- +# Colors +# ------------------------------- +RED="\033[0;31m" +GREEN="\033[0;32m" +NC="\033[0m" + +# ------------------------------- +# Paths & package +# ------------------------------- +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT_DIR="$SCRIPT_DIR/../../" +TARGET_DIR="$ROOT_DIR/target" +PACKAGE="rs-unified-sdk-ffi" +XCFRAMEWORK="$SCRIPT_DIR/DashSDKFFI.xcframework" +PROFILE="dev" # Rust doesn't allow us to use "debug" for some reason, the profile name internally is dev -echo "=== SwiftDashSDK iOS Build (Unified) ===" +# ------------------------------- +# Flags +# ------------------------------- +BUILD_IOS=false +BUILD_SIM=false +BUILD_MAC=false +BUILD_INTEL_MAC=false +CLEAN=false -echo "1) Building Rust FFI (rs-sdk-ffi)" -pushd "$REPO_ROOT/packages/rs-sdk-ffi" >/dev/null -if [[ ! -x ./build_ios.sh ]]; then - echo "❌ Missing rs-sdk-ffi/build_ios.sh" +log_info() { echo -e "${GREEN}$1${NC}"; } +log_error() { echo -e "${RED}$1${NC}"; } + +# ------------------------------- +# Help +# ------------------------------- +show_help() { + echo "Usage: $0 --target [--profile ]" + echo "" + echo "Targets:" + echo " ios -> iPhone device" + echo " sim -> auto-detected iOS simulator" + echo " mac -> Apple Silicon Mac" + echo " intel-mac -> Intel Mac" + echo " all -> all targets except Intel Mac" + echo "" + echo "Profile:" + echo " dev (default)" + echo " release" + echo "" + echo "Examples:" + echo " $0 --target sim --profile release" exit 1 +} + +# ------------------------------- +# Detect simulator target +# ------------------------------- +detect_sim_target() { + ARCH=$(uname -m) + if [[ "$ARCH" == "arm64" ]]; then + echo "aarch64-apple-ios-sim" + else + echo "x86_64-apple-ios" + fi +} + +# ------------------------------- +# Parse flags +# ------------------------------- +while [[ $# -gt 0 ]]; do + case $1 in + --clean) + CLEAN=true + shift + ;; + --target) + case $2 in + ios) BUILD_IOS=true ;; + sim) BUILD_SIM=true ;; + mac) BUILD_MAC=true ;; + intel-mac) BUILD_INTEL_MAC=true ;; + all) BUILD_IOS=true; BUILD_SIM=true; BUILD_MAC=true ;; + *) log_error "Unknown target $2"; show_help ;; + esac + shift 2 + ;; + --profile) + PROFILE="$2" + + if [ ! "$PROFILE" = "dev" ] && [ ! "$PROFILE" = "release" ]; then + log_error "Unknown profile $2"; show_help + fi + + shift 2 + ;; + --help) + show_help + ;; + *) + log_error "Unknown flag $1"; show_help ;; + esac +done + +if $CLEAN; then + log_info "Cleaning all build artifacts..." + rm -rf "$TARGET_DIR" + rm -rf "$XCFRAMEWORK" fi -./build_ios.sh $EXTRA_ARGS -popd >/dev/null - -# Expected output from rs-sdk-ffi -UNIFIED_DIR="$REPO_ROOT/packages/rs-sdk-ffi/build/DashUnifiedSDK.xcframework" -SDKFFI_DIR="$REPO_ROOT/packages/rs-sdk-ffi/build/DashSDKFFI.xcframework" -if [[ -d "$UNIFIED_DIR" ]]; then - SRC_XCFRAMEWORK_DIR="$UNIFIED_DIR" -elif [[ -d "$SDKFFI_DIR" ]]; then - SRC_XCFRAMEWORK_DIR="$SDKFFI_DIR" -else - echo "❌ rs-sdk-ffi build did not produce an XCFramework (expected DashUnifiedSDK.xcframework or DashSDKFFI.xcframework)" - exit 1 + +# ------------------------------- +# Validation +# ------------------------------- +if ! $BUILD_IOS && ! $BUILD_SIM && ! $BUILD_MAC && ! $BUILD_INTEL_MAC; then + log_error "You must specify at least one --target" + show_help fi -echo "2) Installing XCFramework into Swift package" -DEST_XCFRAMEWORK_DIR="$SCRIPT_DIR/DashSDKFFI.xcframework" -rm -rf "$DEST_XCFRAMEWORK_DIR" -cp -R "$SRC_XCFRAMEWORK_DIR" "$DEST_XCFRAMEWORK_DIR" - -# Verify required SPV symbols are present in the binary -# Look for combined lib first (merged with SPV), then fallback to standalone -if [[ -f "$DEST_XCFRAMEWORK_DIR/ios-arm64-simulator/libDashSDKFFI_combined.a" ]]; then - LIB_SIM_MAIN="$DEST_XCFRAMEWORK_DIR/ios-arm64-simulator/libDashSDKFFI_combined.a" -elif [[ -f "$DEST_XCFRAMEWORK_DIR/ios-arm64-simulator/librs_sdk_ffi.a" ]]; then - LIB_SIM_MAIN="$DEST_XCFRAMEWORK_DIR/ios-arm64-simulator/librs_sdk_ffi.a" +log_info "Package: $PACKAGE" +log_info "Profile: $PROFILE" + +# Rust writes the "dev" profile output to the "debug" directory +if [ "$PROFILE" = "dev" ]; then + OUTPUT_DIR="debug" else - echo "❌ Missing simulator library in $DEST_XCFRAMEWORK_DIR/ios-arm64-simulator/" - exit 1 + OUTPUT_DIR="$PROFILE" fi -LIB_SIM_SPV="$DEST_XCFRAMEWORK_DIR/ios-arm64-simulator/libdash_spv_ffi.a" -echo " - Verifying required SPV symbols are present in XCFramework libs" -# Prefer ripgrep if available; fall back to grep for portability -# Avoid -q with pipefail, which can cause nm to SIGPIPE and fail the check. -if command -v rg >/dev/null 2>&1; then - SEARCH_CMD=(rg -F) # fixed-string match -else - SEARCH_CMD=(grep -F) # fixed-string match + +# ------------------------------- +# Build commands +# ------------------------------- + +inject_modulemap() { + local HEADERS_DIR="$1" + + # Create umbrella header that includes all FFI headers in dependency order + cat > "$HEADERS_DIR/DashSDKFFI.h" << 'EOF' +#ifndef DASHSDKFFI_H +#define DASHSDKFFI_H + +// key-wallet-ffi defines FFINetwork used by dash-spv-ffi, so must come first +#include "key-wallet-ffi/key-wallet-ffi.h" +#include "dash-spv-ffi/dash-spv-ffi.h" +#include "rs-sdk-ffi/rs-sdk-ffi.h" + +#endif +EOF + + cat > "$HEADERS_DIR/module.modulemap" << 'EOF' +module DashSDKFFI { + umbrella header "DashSDKFFI.h" + export * +} +EOF + log_info " → module.modulemap + umbrella header injected in $HEADERS_DIR" + + # TODO(build_ios): Quick fix — upstream headers from rust-dashcore emit FFIAssetLockFundingType + # with bare enumerator names (IDENTITY_REGISTRATION, IDENTITY_TOP_UP, etc.) that collide with + # FFIAccountType, which is invalid C (enum constants share the global namespace). + # The proper fix belongs in rust-dashcore's cbindgen config (prefix or namespace the variants). + # Until that fix lands, we strip the enum typedef and replace the type with uint32_t. + for h in "$HEADERS_DIR"/*/*.h; do + perl -i -0777 -pe 's{/\*\*?\s*\n\s*The type of funding account.*?\n\s*\*/\s*\ntypedef enum \{.*?\} FFIAssetLockFundingType;\n}{}s' "$h" + sed -i '' 's/FFIAssetLockFundingType/uint32_t/g' "$h" + done + + # Give opaque struct forward declarations a body so Swift can use UnsafeMutablePointer. + # Skip types that already have a full definition in another header to avoid redefinition. + local defined + defined=$(grep -oh 'typedef struct [A-Za-z_][A-Za-z_0-9]* {' "$HEADERS_DIR"/*/*.h 2>/dev/null \ + | sed 's/typedef struct \([^ ]*\) {/\1/' | sort -u | paste -sd'|' - || true) + for h in "$HEADERS_DIR"/*/*.h; do + if [ -n "$defined" ]; then + perl -i -pe "s/^typedef struct (\w+) \1;\$/ + my \$n=\$1; \$n=~m{^($defined)\$} ? \$_ : \"typedef struct \$n { uint8_t _opaque; } \$n;\n\"/e" "$h" + else + perl -i -pe 's/^typedef struct (\w+) \1;$/typedef struct $1 { uint8_t _opaque; } $1;/' "$h" + fi + done +} + +# iOS device +if $BUILD_IOS; then + IOS_TARGET="aarch64-apple-ios" + log_info "Building iOS device ($IOS_TARGET)..." + cargo build -p "$PACKAGE" --profile "$PROFILE" --target "$IOS_TARGET" + IOS_LIB="$TARGET_DIR/$IOS_TARGET/$OUTPUT_DIR/librs_unified_sdk_ffi.a" + IOS_HEADERS="$TARGET_DIR/$IOS_TARGET/$OUTPUT_DIR/include" + inject_modulemap "$IOS_HEADERS" fi -CHECK_OK=1 -# Use nm -g (global symbols) and grep. Disable pipefail for this check to avoid SIGPIPE issues with large archives. -set +o pipefail -if nm -g "$LIB_SIM_MAIN" 2>/dev/null | "${SEARCH_CMD[@]}" "_dash_spv_ffi_config_add_peer" >/dev/null; then - : -elif [[ -f "$LIB_SIM_SPV" ]] && nm -g "$LIB_SIM_SPV" 2>/dev/null | "${SEARCH_CMD[@]}" "_dash_spv_ffi_config_add_peer" >/dev/null; then - : -else - echo "❌ Missing symbol: dash_spv_ffi_config_add_peer (in both main and spv libs)" - CHECK_OK=0 +# iOS simulator +if $BUILD_SIM; then + SIM_TARGET=$(detect_sim_target) + log_info "Building iOS simulator ($SIM_TARGET)..." + cargo build -p "$PACKAGE" --profile "$PROFILE" --target "$SIM_TARGET" + SIM_LIB="$TARGET_DIR/$SIM_TARGET/$OUTPUT_DIR/librs_unified_sdk_ffi.a" + SIM_HEADERS="$TARGET_DIR/$SIM_TARGET/$OUTPUT_DIR/include" + inject_modulemap "$SIM_HEADERS" fi -if nm -g "$LIB_SIM_MAIN" 2>/dev/null | "${SEARCH_CMD[@]}" "_dash_spv_ffi_config_set_restrict_to_configured_peers" >/dev/null; then - : -elif [[ -f "$LIB_SIM_SPV" ]] && nm -g "$LIB_SIM_SPV" 2>/dev/null | "${SEARCH_CMD[@]}" "_dash_spv_ffi_config_set_restrict_to_configured_peers" >/dev/null; then - : -else - echo "❌ Missing symbol: dash_spv_ffi_config_set_restrict_to_configured_peers (in both main and spv libs)" - CHECK_OK=0 +# macOS +if $BUILD_MAC; then + MAC_TARGET="aarch64-apple-darwin" + log_info "Building macOS ($MAC_TARGET)..." + cargo build -p "$PACKAGE" --profile "$PROFILE" --target "$MAC_TARGET" + MAC_LIB="$TARGET_DIR/$MAC_TARGET/$OUTPUT_DIR/librs_unified_sdk_ffi.a" + MAC_HEADERS="$TARGET_DIR/$MAC_TARGET/$OUTPUT_DIR/include" + inject_modulemap "$MAC_HEADERS" fi -set -o pipefail -if [[ $CHECK_OK -ne 1 ]]; then - echo " Please ensure dash-spv-ffi exports these symbols and is included in the XCFramework." - exit 1 +# Intel Mac +if $BUILD_INTEL_MAC; then + INTEL_MAC_TARGET="x86_64-apple-darwin" + log_info "Building Intel macOS ($INTEL_MAC_TARGET)..." + cargo build -p "$PACKAGE" --profile "$PROFILE" --target "$INTEL_MAC_TARGET" + INTEL_MAC_LIB="$TARGET_DIR/$INTEL_MAC_TARGET/$OUTPUT_DIR/librs_unified_sdk_ffi.a" + INTEL_MAC_HEADERS="$TARGET_DIR/$INTEL_MAC_TARGET/$OUTPUT_DIR/include" + inject_modulemap "$INTEL_MAC_HEADERS" fi -echo "3) Verifying Swift builds (if Xcode available)" +# ------------------------------- +# Create XCFramework +# ------------------------------- +log_info "Generating DashSDKFFI.xcframework " +rm -rf "$XCFRAMEWORK" + +xcodebuild -create-xcframework \ + ${IOS_LIB:+-library "$IOS_LIB" -headers "$IOS_HEADERS"} \ + ${MAC_LIB:+-library "$MAC_LIB" -headers "$MAC_HEADERS"} \ + ${INTEL_MAC_LIB:+-library "$INTEL_MAC_LIB" -headers "$INTEL_MAC_HEADERS"} \ + ${SIM_LIB:+-library "$SIM_LIB" -headers "$SIM_HEADERS"} \ + -output "$XCFRAMEWORK" + +log_info "XCFramework created: $XCFRAMEWORK" + +# ------------------------------- +# Build Swift SDK +# ------------------------------- +SWIFT_PROJECT="$SCRIPT_DIR/SwiftExampleApp/SwiftExampleApp.xcodeproj" +SWIFT_SCHEME="SwiftExampleApp" +SWIFT_DESTINATION="generic/platform=iOS Simulator" +EXCLUDED_ARCHS="x86_64" + if command -v xcodebuild >/dev/null 2>&1; then - set +e - xcodebuild -project "$SCRIPT_DIR/SwiftExampleApp/SwiftExampleApp.xcodeproj" \ - -scheme SwiftExampleApp \ - -sdk iphonesimulator \ - -destination 'generic/platform=iOS Simulator' \ - EXCLUDED_ARCHS=x86_64 \ - -quiet build - XC_STATUS=$? - set -e - if [[ $XC_STATUS -ne 0 ]]; then - echo "❌ Xcode build failed" - exit $XC_STATUS - fi - echo "✅ Xcode build succeeded" + set +e + xcodebuild -project "$SWIFT_PROJECT" \ + -scheme "$SWIFT_SCHEME" \ + -sdk iphonesimulator \ + -destination "$SWIFT_DESTINATION" \ + EXCLUDED_ARCHS="$EXCLUDED_ARCHS" \ + build + XC_STATUS=$? + set -e + if [[ $XC_STATUS -ne 0 ]]; then + log_error "Swift/Xcode build failed" + exit $XC_STATUS + fi + log_info "Swift/Xcode build succeeded" else - echo "⚠️ xcodebuild not found; skipping local build. Run this script on a macOS host with Xcode to fully verify." + echo "xcodebuild not found; skipping Swift verification." fi - -echo "✅ Done. XCFramework installed at $DEST_XCFRAMEWORK_DIR"