diff --git a/.github/package-filters/rs-packages.yml b/.github/package-filters/rs-packages.yml
index 7e31bd9992f..57d2417cbb5 100644
--- a/.github/package-filters/rs-packages.yml
+++ b/.github/package-filters/rs-packages.yml
@@ -75,3 +75,11 @@ dash-sdk:
- packages/rs-sdk/**
- *dapi_client
- *drive
+
+rs-sdk-ffi:
+ - .github/workflows/tests*
+ - packages/rs-sdk-ffi/**
+ - packages/rs-sdk/**
+ - packages/rs-drive-proof-verifier/**
+ - *dapi_client
+ - *drive
diff --git a/.github/workflows/tests-rs-sdk-ffi-build.yml b/.github/workflows/tests-rs-sdk-ffi-build.yml
new file mode 100644
index 00000000000..c9c18499e09
--- /dev/null
+++ b/.github/workflows/tests-rs-sdk-ffi-build.yml
@@ -0,0 +1,57 @@
+name: Test rs-sdk-ffi build
+
+on:
+ workflow_dispatch:
+ pull_request:
+ paths:
+ - 'packages/rs-sdk-ffi/**'
+ - 'packages/rs-sdk/**'
+ - '.github/workflows/tests-rs-sdk-ffi-build.yml'
+ push:
+ branches:
+ - master
+ - 'v[0-9]+\.[0-9]+-dev'
+ paths:
+ - 'packages/rs-sdk-ffi/**'
+ - 'packages/rs-sdk/**'
+ - '.github/workflows/tests-rs-sdk-ffi-build.yml'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ build-ffi-cross-compile:
+ name: Build FFI for Apple target
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out repo
+ uses: actions/checkout@v4
+
+ - name: Setup Rust
+ uses: ./.github/actions/rust
+ with:
+ target: aarch64-apple-darwin
+
+ - name: Install cross-compilation dependencies
+ run: |
+ # Install osxcross or other cross-compilation tools if needed
+ # For now, we'll just add the target
+ rustup target add aarch64-apple-darwin
+
+ - name: Build FFI library for Apple target
+ working-directory: packages/rs-sdk-ffi
+ env:
+ # Set up cross-compilation environment variables if needed
+ CARGO_TARGET_AARCH64_APPLE_DARWIN_LINKER: rust-lld
+ run: |
+ cargo build --release --target aarch64-apple-darwin
+
+ - name: Verify build output
+ run: |
+ if [ ! -f "target/aarch64-apple-darwin/release/librs_sdk_ffi.a" ]; then
+ echo "Error: FFI library was not built for Apple target"
+ exit 1
+ fi
+ echo "FFI library successfully built for Apple target"
+ ls -la target/aarch64-apple-darwin/release/librs_sdk_ffi.a
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 485797b9f40..d37dac2816c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,4 +33,28 @@ node_modules
# Rust build artifacts
/target
+packages/*/target
.gitaipconfig
+
+# Swift build artifacts and IDE files
+.build/
+.swiftpm/
+.index-build/
+DerivedData/
+*.xcworkspace
+xcuserdata/
+*.dSYM/
+*.o
+*.swiftdeps
+*.d
+
+# Generated Swift SDK header files
+packages/swift-sdk/Sources/CDashSDKFFI/DashSDKFFI.h
+packages/swift-sdk/generated/DashSDKFFI.h
+
+# Generated Swift SDK files
+packages/swift-sdk/Sources/CDashSDKFFI/librs_sdk_ffi.pc
+packages/swift-sdk/SwiftExampleApp/DashSDK.xcframework/
+
+# rs-sdk-ffi build directory
+packages/rs-sdk-ffi/build/
diff --git a/Cargo.lock b/Cargo.lock
index 544d483b2b3..1608220d9cc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -777,6 +777,25 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
+[[package]]
+name = "cbindgen"
+version = "0.27.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fce8dd7fcfcbf3a0a87d8f515194b49d6135acab73e18bd380d1d93bb1a15eb"
+dependencies = [
+ "clap",
+ "heck 0.4.1",
+ "indexmap 2.7.0",
+ "log",
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_json",
+ "syn 2.0.100",
+ "tempfile",
+ "toml",
+]
+
[[package]]
name = "cc"
version = "1.2.20"
@@ -4346,6 +4365,28 @@ dependencies = [
"wasm-bindgen-futures",
]
+[[package]]
+name = "rs-sdk-ffi"
+version = "2.0.0-rc.14"
+dependencies = [
+ "bincode",
+ "bs58",
+ "cbindgen",
+ "dash-sdk",
+ "dotenvy",
+ "env_logger",
+ "envy",
+ "hex",
+ "libc",
+ "log",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.12",
+ "tokio",
+ "tracing",
+ "zeroize",
+]
+
[[package]]
name = "rust_decimal"
version = "1.36.0"
diff --git a/Cargo.toml b/Cargo.toml
index 044a49ee457..d156ba0fc83 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -30,7 +30,8 @@ members = [
"packages/check-features",
"packages/wallet-utils-contract",
"packages/token-history-contract",
- "packages/keyword-search-contract"
+ "packages/keyword-search-contract",
+ "packages/rs-sdk-ffi"
]
exclude = ["packages/wasm-sdk"] # This one is experimental and not ready for use
diff --git a/Dockerfile b/Dockerfile
index c0411248e73..d37177d2e66 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -390,6 +390,7 @@ COPY --parents \
packages/wasm-dpp \
packages/rs-dapi-client \
packages/rs-sdk \
+ packages/rs-sdk-ffi \
packages/check-features \
/platform/
diff --git a/docs/SDK_ARCHITECTURE.md b/docs/SDK_ARCHITECTURE.md
new file mode 100644
index 00000000000..6a0019d85e7
--- /dev/null
+++ b/docs/SDK_ARCHITECTURE.md
@@ -0,0 +1,383 @@
+# Dash Platform SDK Architecture
+
+## Overview
+
+The Dash Platform SDK ecosystem consists of multiple layers that enable developers to interact with the Dash Platform across different programming languages and environments. This document provides a comprehensive overview of the SDK architecture, including the relationships between different components and implementation details.
+
+## Architecture Layers
+
+```mermaid
+graph TB
+ subgraph "Platform Core"
+ DP[Dash Platform]
+ end
+
+ subgraph "Core SDK Layer"
+ RS[rs-sdk
Rust SDK Core]
+ end
+
+ subgraph "FFI/Bridge Layer"
+ RSFFI[rs-sdk-ffi
Foreign Function Interface]
+ WASM[wasm-sdk
WebAssembly Bridge]
+ end
+
+ subgraph "Language SDKs"
+ SWIFT[swift-sdk
iOS/macOS SDK]
+ KOTLIN[kotlin-sdk
Android/JVM SDK]
+ JS[js-dash-sdk
JavaScript SDK]
+ PYTHON[python-sdk
Python SDK]
+ GO[go-sdk
Go SDK]
+ end
+
+ subgraph "Applications"
+ IOS[iOS Apps]
+ ANDROID[Android Apps]
+ WEB[Web Apps]
+ NODE[Node.js Apps]
+ PYAPPS[Python Apps/
Scripts/Services]
+ GOAPPS[Go Services/
Microservices]
+ end
+
+ DP --> RS
+ RS --> RSFFI
+ RS --> WASM
+ RSFFI --> SWIFT
+ RSFFI --> KOTLIN
+ RSFFI --> PYTHON
+ RSFFI --> GO
+ WASM --> JS
+ SWIFT --> IOS
+ KOTLIN --> ANDROID
+ JS --> WEB
+ JS --> NODE
+ PYTHON --> PYAPPS
+ GO --> GOAPPS
+
+ style RS fill:#f9f,stroke:#333,stroke-width:4px
+ style RSFFI fill:#bbf,stroke:#333,stroke-width:2px
+ style WASM fill:#bbf,stroke:#333,stroke-width:2px
+```
+
+## Component Details
+
+### 1. Core SDK Layer: rs-sdk
+
+The `rs-sdk` is the foundational Rust implementation that provides:
+
+- **Direct Platform Communication**: Native gRPC client for DAPI
+- **Cryptographic Operations**: Key management, signing, verification
+- **Data Contract Management**: Creation, updates, and validation
+- **Document Operations**: CRUD operations with Platform documents
+- **Identity Management**: Identity creation, updates, credit transfers
+- **State Transitions**: Building and broadcasting state transitions
+- **Proof Verification**: Cryptographic proof validation
+
+```
+┌─────────────────────────────────────────┐
+│ rs-sdk (Rust) │
+├─────────────────────────────────────────┤
+│ • Platform Client │
+│ • Identity Management │
+│ • Document Operations │
+│ • Data Contract Management │
+│ • Cryptographic Operations │
+│ • State Transition Builder │
+│ • Proof Verification │
+└─────────────────────────────────────────┘
+```
+
+### 2. Bridge Layer
+
+#### 2.1 rs-sdk-ffi (Foreign Function Interface)
+
+The FFI layer provides C-compatible bindings for native mobile platforms:
+
+```mermaid
+graph LR
+ subgraph "rs-sdk-ffi"
+ CB[C Bindings]
+ MS[Memory Safety Layer]
+ TS[Type Serialization]
+ EM[Error Mapping]
+ end
+
+ RS[rs-sdk] --> CB
+ CB --> MS
+ MS --> TS
+ TS --> EM
+ EM --> SWIFT[Swift/Kotlin]
+```
+
+**Key Features:**
+- **C ABI Compatibility**: Exposes Rust functions through C interface
+- **Memory Management**: Safe memory handling across language boundaries
+- **Type Mapping**: Converts Rust types to C-compatible structures
+- **Error Handling**: Maps Rust Results to error codes/exceptions
+- **Async Bridge**: Handles Rust async/await for synchronous FFI calls
+
+#### 2.2 wasm-sdk (WebAssembly Bridge)
+
+The WASM bridge enables JavaScript SDK functionality:
+
+```
+┌─────────────────────────────────────────┐
+│ wasm-sdk (WASM) │
+├─────────────────────────────────────────┤
+│ • WebAssembly Compilation of rs-sdk │
+│ • JavaScript Type Bindings │
+│ • Browser-Compatible Crypto │
+│ • Async/Promise Integration │
+│ • Memory Management for JS │
+└─────────────────────────────────────────┘
+```
+
+### 3. Language-Specific SDKs
+
+#### 3.1 Swift SDK (iOS/macOS)
+
+```mermaid
+graph TD
+ subgraph "swift-sdk Architecture"
+ API[Swift API Layer]
+ MOD[Model Layer]
+ FFI[FFI Wrapper]
+ UTIL[Utilities]
+ end
+
+ API --> MOD
+ API --> FFI
+ MOD --> FFI
+ FFI --> RSFFI[rs-sdk-ffi]
+
+ style API fill:#f96,stroke:#333,stroke-width:2px
+```
+
+**Components:**
+- **Swift API Layer**: Idiomatic Swift interfaces
+- **Model Layer**: Swift structs/classes for Platform types
+- **FFI Wrapper**: Safe Swift wrappers around C functions
+- **Error Handling**: Swift Error protocol implementation
+- **Async/Await**: Native Swift concurrency support
+
+#### 3.2 Kotlin SDK (Android/JVM) - Planned
+
+```
+┌─────────────────────────────────────────┐
+│ kotlin-sdk (Planned) │
+├─────────────────────────────────────────┤
+│ • JNI Bindings to rs-sdk-ffi │
+│ • Kotlin-first API │
+│ • Android-Specific Features │
+│ • Coroutine Support │
+│ • Type-Safe Builders │
+└─────────────────────────────────────────┘
+```
+
+#### 3.3 Python SDK - Planned
+
+```
+┌─────────────────────────────────────────┐
+│ python-sdk (Planned) │
+├─────────────────────────────────────────┤
+│ • PyO3 Bindings to rs-sdk-ffi │
+│ • Pythonic API │
+│ • Type Hints Support │
+│ • Async/Await Support │
+│ • Data Science Integration │
+└─────────────────────────────────────────┘
+```
+
+**Use Cases:**
+- **Backend Services**: API servers and microservices
+- **Data Analysis**: Blockchain analytics and reporting
+- **Automation**: Scripts and DevOps tools
+- **Machine Learning**: Data preprocessing for ML pipelines
+
+#### 3.4 Go SDK - Planned
+
+```
+┌─────────────────────────────────────────┐
+│ go-sdk (Planned) │
+├─────────────────────────────────────────┤
+│ • CGO Bindings to rs-sdk-ffi │
+│ • Idiomatic Go API │
+│ • Goroutine Support │
+│ • Context-Based Cancellation │
+│ • Channel-Based Async │
+└─────────────────────────────────────────┘
+```
+
+**Use Cases:**
+- **High-Performance Services**: Low-latency blockchain services
+- **Cloud Native**: Kubernetes operators and controllers
+- **Infrastructure**: DevOps tools and monitoring
+- **Concurrent Processing**: High-throughput transaction processing
+
+#### 3.5 JavaScript SDK (js-dash-sdk)
+
+```mermaid
+graph LR
+ subgraph "js-dash-sdk Architecture"
+ API[JS API]
+ TRANSPORT[Transport Layer]
+ WASM_MOD[WASM Module]
+ MODELS[Models]
+ end
+
+ API --> TRANSPORT
+ API --> MODELS
+ TRANSPORT --> DAPI[DAPI]
+ MODELS --> WASM_MOD
+ WASM_MOD --> WASM[wasm-sdk]
+```
+
+**Features:**
+- **Browser & Node.js Support**: Universal JavaScript compatibility
+- **WASM Integration**: Uses wasm-sdk for crypto operations
+- **Promise-Based API**: Modern async/await support
+- **TypeScript Definitions**: Full type safety
+- **Transport Abstraction**: HTTP/WebSocket support
+
+## Data Flow Example
+
+Here's how a document creation flows through the SDK layers:
+
+```mermaid
+sequenceDiagram
+ participant App as Application
+ participant SDK as Language SDK
+ participant Bridge as FFI/WASM
+ participant Core as rs-sdk
+ participant Platform as Dash Platform
+
+ App->>SDK: Create Document
+ SDK->>Bridge: Serialize Data
+ Bridge->>Core: FFI Call
+ Core->>Core: Build State Transition
+ Core->>Core: Sign with Private Key
+ Core->>Platform: Broadcast via gRPC
+ Platform-->>Core: Confirmation
+ Core-->>Bridge: Result
+ Bridge-->>SDK: Deserialize Result
+ SDK-->>App: Document Created
+```
+
+## Type System Architecture
+
+The SDK maintains type safety across language boundaries:
+
+```
+┌──────────────────┐ ┌─────────────────┐ ┌─────────────────┐
+│ Rust Types │────▶│ C Types │────▶│ Native Types │
+│ │ │ │ │ │
+│ • Identity │ │ • Opaque Ptrs │ │ • Swift Classes │
+│ • Document │ │ • C Structs │ │ • Kotlin Objects│
+│ • DataContract │ │ • Error Codes │ │ • Python Objects│
+│ • StateTransition│ │ • Callbacks │ │ • Go Structs │
+│ │ │ │ │ • JS Objects │
+│ │ │ │ │ • TypeScript │
+└──────────────────┘ └─────────────────┘ └─────────────────┘
+```
+
+## Memory Management Strategy
+
+### FFI Layer (Mobile SDKs)
+- **Ownership Transfer**: Clear ownership rules for memory
+- **Reference Counting**: Smart pointers for shared data
+- **Explicit Cleanup**: Destructor functions for manual memory management
+
+### WASM Layer (JavaScript SDK)
+- **Automatic GC**: Leverages JavaScript garbage collection
+- **Linear Memory**: WASM linear memory model
+- **Typed Arrays**: Efficient binary data handling
+
+## Error Handling Architecture
+
+```mermaid
+graph TB
+ subgraph "Error Flow"
+ RE[Rust Error]
+ CE[C Error Code]
+ SE[Swift Error]
+ KE[Kotlin Result]
+ PE[Python Exception]
+ GE[Go Error]
+ JSE[JS Error]
+ end
+
+ RE --> CE
+ CE --> SE
+ CE --> KE
+ CE --> PE
+ CE --> GE
+ RE --> JSE
+```
+
+Each SDK layer provides appropriate error handling:
+- **Rust**: Result with detailed error types
+- **FFI**: Error codes with error detail retrieval functions
+- **Swift**: Error protocol with associated values
+- **Kotlin**: Sealed classes for type-safe error handling
+- **Python**: Exception hierarchy with error details
+- **Go**: Error interface with wrapped errors
+- **JavaScript**: Error objects with error codes and messages
+
+## Platform Feature Support Matrix
+
+| Feature | Rust SDK | Swift SDK | Kotlin SDK | Python SDK | Go SDK | JS SDK |
+|---------|----------|-----------|------------|------------|--------|---------|
+| Identity Management | ✅ | ✅ | ⏳ | ⏳ | ⏳ | ✅ |
+| Data Contracts | ✅ | ✅ | ⏳ | ⏳ | ⏳ | ✅ |
+| Documents | ✅ | ✅ | ⏳ | ⏳ | ⏳ | ✅ |
+| Tokens | ✅ | ✅ | ⏳ | ⏳ | ⏳ | ⏳ |
+| Proofs | ✅ | ✅ | ⏳ | ⏳ | ⏳ | 🚧 |
+| State Transitions | ✅ | ✅ | ⏳ | ⏳ | ⏳ | ⏳ |
+| Dashpay | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ |
+| Name Service (DPNS) | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ |
+| Core Types Support | ✅ | ✅ | ⏳ | ⏳ | ⏳ | ⏳ |
+| Core Blockchain Sync | 🚧 | 🚧 | ⏳ | ⏳ | ⏳ | ⏳ |
+| Core Deterministic Masternode List Sync | 🚧 | 🚧 | ⏳ | ⏳ | ⏳ | ⏳ |
+
+Legend: ✅ Fully Supported | 🚧 In Development | ⏳ Planned | ❌ Not Supported
+
+## Development Considerations
+
+### Performance
+- **FFI Overhead**: Minimal overhead for native SDKs
+- **WASM Performance**: Near-native performance for crypto operations
+- **Caching**: Built-in caching for Platform queries
+- **Batch Operations**: Support for batching multiple operations
+
+### Security
+- **Key Management**: Secure key storage per platform
+- **Memory Protection**: Safe memory handling across boundaries
+- **Input Validation**: Validation at each layer
+- **Secure Communication**: TLS for all Platform communication
+
+### Testing Strategy
+```
+┌─────────────────────────────────────────┐
+│ Integration Tests │
+├─────────────────────────────────────────┤
+│ Language SDK Tests │
+├─────────────────────────────────────────┤
+│ FFI/WASM Tests │
+├─────────────────────────────────────────┤
+│ rs-sdk Tests │
+└─────────────────────────────────────────┘
+```
+
+## Future Architecture Evolution
+
+### Planned Enhancements
+1. **Direct WASM Bindings**: Skip JavaScript for performance-critical paths
+2. **Unified Type Generation**: Auto-generate types from Rust definitions
+3. **Plugin Architecture**: Extensible SDK functionality
+4. **Offline Support**: Local caching and sync capabilities
+5. **Real-time Updates**: WebSocket support for live updates
+
+### SDK Roadmap
+- **Phase 1**: Core functionality parity across all SDKs
+- **Phase 2**: Platform-specific optimizations
+- **Phase 3**: Advanced features (offline, real-time)
+- **Phase 4**: Developer tools and debugging support
diff --git a/packages/rs-dapi-client/src/transport/grpc.rs b/packages/rs-dapi-client/src/transport/grpc.rs
index a5428409625..8b19fbf1fd3 100644
--- a/packages/rs-dapi-client/src/transport/grpc.rs
+++ b/packages/rs-dapi-client/src/transport/grpc.rs
@@ -614,3 +614,12 @@ impl_transport_request_grpc!(
RequestSettings::default(),
get_token_perpetual_distribution_last_claim
);
+
+// rpc getTokenContractInfo(GetTokenContractInfoRequest) returns (GetTokenContractInfoResponse);
+impl_transport_request_grpc!(
+ platform_proto::GetTokenContractInfoRequest,
+ platform_proto::GetTokenContractInfoResponse,
+ PlatformGrpcClient,
+ RequestSettings::default(),
+ get_token_contract_info
+);
diff --git a/packages/rs-drive-proof-verifier/src/proof.rs b/packages/rs-drive-proof-verifier/src/proof.rs
index dd7d523d6bf..26df9deb900 100644
--- a/packages/rs-drive-proof-verifier/src/proof.rs
+++ b/packages/rs-drive-proof-verifier/src/proof.rs
@@ -1,5 +1,6 @@
pub mod groups;
pub mod identity_token_balance;
+pub mod token_contract_info;
pub mod token_direct_purchase;
pub mod token_info;
pub mod token_perpetual_distribution_last_claim;
diff --git a/packages/rs-drive-proof-verifier/src/proof/token_contract_info.rs b/packages/rs-drive-proof-verifier/src/proof/token_contract_info.rs
new file mode 100644
index 00000000000..133254688ca
--- /dev/null
+++ b/packages/rs-drive-proof-verifier/src/proof/token_contract_info.rs
@@ -0,0 +1,57 @@
+use crate::error::MapGroveDbError;
+use crate::types::token_contract_info::TokenContractInfoResult;
+use crate::verify::verify_tenderdash_proof;
+use crate::{ContextProvider, Error, FromProof};
+use dapi_grpc::platform::v0::{
+ get_token_contract_info_request, get_token_contract_info_response, GetTokenContractInfoRequest,
+ GetTokenContractInfoResponse, Proof, ResponseMetadata,
+};
+use dapi_grpc::platform::VersionedGrpcResponse;
+use dpp::dashcore::Network;
+use dpp::tokens::contract_info::TokenContractInfo;
+use dpp::version::PlatformVersion;
+use drive::drive::Drive;
+
+impl FromProof for TokenContractInfo {
+ type Request = GetTokenContractInfoRequest;
+ type Response = GetTokenContractInfoResponse;
+
+ fn maybe_from_proof_with_metadata<'a, I: Into, O: Into>(
+ request: I,
+ response: O,
+ _network: Network,
+ platform_version: &PlatformVersion,
+ provider: &'a dyn ContextProvider,
+ ) -> Result<(Option, ResponseMetadata, Proof), Error>
+ where
+ Self: Sized + 'a,
+ {
+ let request: Self::Request = request.into();
+ let response: Self::Response = response.into();
+
+ // Parse response to read proof and metadata
+ let proof = response.proof().or(Err(Error::NoProofInResult))?;
+ let mtd = response.metadata().or(Err(Error::EmptyResponseMetadata))?;
+
+ let token_id = match request.version.ok_or(Error::EmptyVersion)? {
+ get_token_contract_info_request::Version::V0(v0) => {
+ v0.token_id.try_into().map_err(|_| Error::RequestError {
+ error: "token_id must be exactly 32 bytes".to_string(),
+ })?
+ }
+ };
+
+ // Extract content from proof and verify Drive/GroveDB proofs
+ let (root_hash, maybe_token_contract_info) = Drive::verify_token_contract_info(
+ &proof.grovedb_proof,
+ token_id,
+ false,
+ platform_version,
+ )
+ .map_drive_error(proof, mtd)?;
+
+ verify_tenderdash_proof(proof, mtd, &root_hash, provider)?;
+
+ Ok((maybe_token_contract_info, mtd.clone(), proof.clone()))
+ }
+}
diff --git a/packages/rs-drive-proof-verifier/src/types.rs b/packages/rs-drive-proof-verifier/src/types.rs
index 8cd6db254b6..4938ae2ad47 100644
--- a/packages/rs-drive-proof-verifier/src/types.rs
+++ b/packages/rs-drive-proof-verifier/src/types.rs
@@ -11,6 +11,8 @@ pub mod evonode_status;
pub mod groups;
/// Identity token balance
pub mod identity_token_balance;
+/// Token contract info
+pub mod token_contract_info;
/// Token info
pub mod token_info;
/// Token status
diff --git a/packages/rs-drive-proof-verifier/src/types/token_contract_info.rs b/packages/rs-drive-proof-verifier/src/types/token_contract_info.rs
new file mode 100644
index 00000000000..5925d79f4e2
--- /dev/null
+++ b/packages/rs-drive-proof-verifier/src/types/token_contract_info.rs
@@ -0,0 +1,4 @@
+use dpp::tokens::contract_info::TokenContractInfo;
+
+/// Token contract info
+pub type TokenContractInfoResult = Option;
diff --git a/packages/rs-drive-verify-c-binding/.gitignore b/packages/rs-drive-verify-c-binding/.gitignore
deleted file mode 100644
index 178ab4f911c..00000000000
--- a/packages/rs-drive-verify-c-binding/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/target
-/Cargo.lock
-a
\ No newline at end of file
diff --git a/packages/rs-drive-verify-c-binding/Cargo.toml b/packages/rs-drive-verify-c-binding/Cargo.toml
deleted file mode 100644
index 22da440ca7c..00000000000
--- a/packages/rs-drive-verify-c-binding/Cargo.toml
+++ /dev/null
@@ -1,20 +0,0 @@
-[package]
-name = "rs-drive-verify-c-binding"
-version = "1.6.2"
-edition = "2021"
-rust-version.workspace = true
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-[lib]
-name = "drive"
-crate-type = ["staticlib"]
-
-[build-dependencies]
-cbindgen = "0.24.3"
-
-[dependencies]
-
-[dependencies.drive]
-path = "../rs-drive"
-features = ["verify"]
-default-features = false
diff --git a/packages/rs-drive-verify-c-binding/build.rs b/packages/rs-drive-verify-c-binding/build.rs
deleted file mode 100644
index 1d94716d7fc..00000000000
--- a/packages/rs-drive-verify-c-binding/build.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-use std::env;
-
-fn main() {
- let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
- let mut config: cbindgen::Config = Default::default();
- config.language = cbindgen::Language::C;
- cbindgen::generate_with_config(crate_dir, config)
- .unwrap()
- .write_to_file("target/drive.h");
-}
diff --git a/packages/rs-drive-verify-c-binding/c/main.c b/packages/rs-drive-verify-c-binding/c/main.c
deleted file mode 100644
index a374f303c12..00000000000
--- a/packages/rs-drive-verify-c-binding/c/main.c
+++ /dev/null
@@ -1,265 +0,0 @@
-#include
-#include
-#include "../target/drive.h"
-#include "./utils.c"
-
-void test_verify_full_identity_by_public_key_hash() {
- char *proof_hex = "06000100a603014a75cf3f535e81c4680f8137a2208dbcb2652ffd7e715bd4290cc5c560b2cc6102cfbe0535bd2defe586b863b9ccb92d0d66fb2b810d730e7ba2cb7e2fb302613b100401180018020114aee302720896bba837dcf3f2d674f546fd25496f00ca359aa1b2032e3158ae5e5c489f7d46722f29644a15e1cf7c3935b30606def61104012000240201203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200a0d5a4f6418663468515cd75189be3e1034bbfa9a1807eb81d964ba7442a0b1e100169931838564707dbf11e90a059fd7dd453cc7e68adb7d2c2375bae53566664e711025670752cc3d883200a7598b65cd74b41a760cc0be57cda5536f15f03c8783aa81001c33635136e502e9ac5244b15a20a757e0759ce0a90823cd37f893f6a49556d26040160002d0401203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2fd1cb12a5b2614000000fbbd3be097e7f07d5619dd69e7767884d116f95ae9a5fcdb651e71727902cc1e10011e0c1443d0925f781132f4c506747202dbffa3ca3ded4d2387d4b7e40e0303e311110201187f03144463a1a994d5040e69c090b6985d7af295bfd11a002300203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200029e6f2d33b1580030e3b6030e3c25016ab7253965682556059dcc243b75c7fa6d1001e09f88cd09cc595d524892b3e642b939f2827995605703c49c861f653001d5e1110101204d04203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200090201010201030000007fae89b888b23f4fbdaed2fb990a1f42727aef5bd2a8b91f8cb970570909ab3901203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a27f030100000b000800000000000000100004010100050201010100d651221796b5206a5b9678a4d9995d519d8b9e75e87d85e57effb91f82a23e8d1002bcf84a882c0f72dd0d520a6954b3e1887fa55b7dc67635b44516856b31fd20a8100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100001e001b0000010200144463a1a994d5040e69c090b6985d7af295bfd11a0000030101003a0037010002010030973988b291fd1bca86d906723e335bdf13d3ebbadfea31dd164b3c672c16da72af8e6edfc0bac44b92b8c536d708dc33000010030102002b00280200030000210360da79c58995e4ec88512af9a4440ca4f2d7bfe84240e17effc4dd8ce94033a20000110201604f04203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2000b03fd1cb12a5b261400000068f31829eaec02f7e5eddada129d4981a99bda0e5c0fd4eff3c23eafc2c79a02";
- char *pub_key_hex = "4463a1a994d5040e69c090b6985d7af295bfd11a";
-
- unsigned char *proof_bin = hex2bin(proof_hex);
- unsigned char *pub_key_bin = hex2bin(pub_key_hex);
-
- IdentityVerificationResult *result = verify_full_identity_by_public_key_hash(proof_bin, 1038, pub_key_bin);
- assert(result->is_valid);
-
- uint8_t expected_root_hash[32] = {72,72,215,200,156,21,128,156,166,182,110,57,113,232,229,242,193,199,240,135,222,102,246,165,181,68,81,221,120,195,236,199};
- assert(is_array_equal(result->root_hash, expected_root_hash,32));
-
- assert(result->has_identity);
-
- Identity *identity = result->identity;
- assert(identity->protocol_version == 1);
-
- uint8_t id[32] = {62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162};
- assert(is_array_equal(*identity->id, id, 32));
-
- // Confirm identity has 3 public keys
- assert(identity->public_keys_count == 3);
-
- // Assert on the first public key
- assert(identity->public_keys[0]->key == 0);
- IdentityPublicKey *first = identity->public_keys[0]->public_key;
- assert(first->id == 0);
- assert(first->purpose == 0);
- assert(first->security_level == 1);
- assert(first->key_type == 2);
- assert(first->read_only == false);
- assert(first->has_disabled_at == false);
- uint8_t first_public_key[20] = {68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, 152, 93, 122, 242, 149, 191, 209, 26};
- assert(is_array_equal(first->data, first_public_key, first->data_length));
-
- // Assert on the second public key
- assert(identity->public_keys[1]->key == 1);
- IdentityPublicKey *second = identity->public_keys[1]->public_key;
- assert(second->id == 1);
- assert(second->purpose == 0);
- assert(second->security_level == 2);
- assert(second->key_type == 1);
- assert(second->read_only == false);
- assert(second->has_disabled_at == false);
- unsigned char second_public_key[50] = {151, 57, 136, 178, 145, 253, 27, 202, 134, 217, 6, 114, 62, 51, 91, 223, 19, 211, 235, 186, 223, 234, 49, 221, 22, 75, 60, 103, 44, 22, 218, 114, 175, 142, 110, 223, 192, 186, 196, 75, 146, 184, 197, 54, 215, 8, 220, 51};
- assert(is_array_equal(second->data,second_public_key, second->data_length));
-
- // Assert on the third public key
- assert(identity->public_keys[0]->key == 0);
- IdentityPublicKey *third = identity->public_keys[2]->public_key;
- assert(third->id == 2);
- assert(third->purpose == 0);
- assert(third->security_level == 3);
- assert(third->key_type == 0);
- assert(third->read_only == false);
- assert(third->has_disabled_at == false);
- unsigned char third_public_key[33] = {3, 96, 218, 121, 197, 137, 149, 228, 236, 136, 81, 42, 249, 164, 68, 12, 164, 242, 215, 191, 232, 66, 64, 225, 126, 255, 196, 221, 140, 233, 64, 51, 162};
- assert(is_array_equal(third->data,third_public_key, third->data_length));
-
- assert(identity->balance == 11077485418638);
- assert(identity->revision == 16);
- assert(!identity->has_metadata);
- assert(!identity->has_asset_lock_proof);
-
-}
-
-void test_verify_full_identities_by_public_key_hashes() {
- char *multiple_identity_proof_hex = "06000100a603014a75cf3f535e81c4680f8137a2208dbcb2652ffd7e715bd4290cc5c560b2cc6102cfbe0535bd2defe586b863b9ccb92d0d66fb2b810d730e7ba2cb7e2fb302613b1004011800180201145e0e49d808ad21d01d07dd799a75bd1b472788a7008c10aa4c1d19e2e7e42fe0b1a7f6d93d4c0b6992ef63ea985c16447cada4629511040120002402012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000ba56cfb1d87ef47857f6b1cd7fb918406fd50f81966619777dd4c1b595a1a26e100169931838564707dbf11e90a059fd7dd453cc7e68adb7d2c2375bae53566664e711025670752cc3d883200a7598b65cd74b41a760cc0be57cda5536f15f03c8783aa81001c33635136e502e9ac5244b15a20a757e0759ce0a90823cd37f893f6a49556d26040160002d04012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30fdbafd6833aeb700000012b27f4a0a7cfd06e3387b33a5bca6682953512e21621ae9cf6d633d9041771910011e0c1443d0925f781132f4c506747202dbffa3ca3ded4d2387d4b7e40e0303e31111020118b3080132c9d35844d5ce2a8e0f377cee23c143a53396073dea86c494b86ba4c4af0b3903141f0815269afc012de44260ceb28a4496d3184184002300200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb00100168576e24521e03ba4b624912bb07833767c81102310b87d8ea1caf2795c68f921102e8b7eb376f0f7993badf93971f690be8a48f09db0711f052a2ed48471497b9d01003144463a1a994d5040e69c090b6985d7af295bfd11a002300203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a20002254bf0a990beb721c21f21e8dbab50e33cd9cf09618fc27c9f7450c673516aee1001c6adfe081809218ee07461f95f53ce6ce462ec379f97a71f1be40f7218cb50af111103145e0e49d808ad21d01d07dd799a75bd1b472788a70023002035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30001001a4b31998d47c30e390f4fa56f28f19c62f114f17a704d29c56e28b6fdb47f101031467892af390cd2b7653a918c7b692c85b87b44d3200230020399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80001001eb4da977338a3da4204eaaac0c8856bdfd51d9b25ceef04b40bb38eff79ab11011021f22102429dbe1bc0ca714847b08187d9a874cc43329aaa79647fb9aa0834d691003149a061f31734c5f5f0b119ab72d433c9af133d3a600230020e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330002644c601e67692188cf5a975c2207caba899d99f1bbd4b62e5fe856850b9d7286100314a54921bb29b67e31898efebc29f241b1aefa4dca002300207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e510010029e6f2d33b1580030e3b6030e3c25016ab7253965682556059dcc243b75c7fa6d0314b3bfce478de96fe30cd3713bf88ce7728687da8a00230020a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40001111110314bb3df025e32fd90d1feee7dca4b83321c683292d0023002003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3001001ee0847805b145b5fb500b139fe12767ee681fc310a21d6e9814619df5187470802a0de352fe6767da7bf4c33ba7d2da8db0440457835d3c2992473210e02b6312c1001e09f88cd09cc595d524892b3e642b939f2827995605703c49c861f653001d5e1029a563c983d202520c1a94f4c6ba99750373450aaf9dcb2a62ef50e9877646043100314ed738aaadd75d1677fefeccadd033f126cfee76a0023002097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000314fbd9daa5993de56a2e4346b7c72ff5585efffaab002300201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb0010111111110101208b06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d300090201010201030000006c4bfcf223cd4fe5c1cac82e1a9e2c73eb0e7f34cebabdd7630e24cb192f975804200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000902010102010300000080da62acb8c49f901d6bf84a2a2af15431e69e29069abf8d02f2c113c6099ba61004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000902010102010300000051a23049efbcde3a0e9c85ea7af05a28d4de31f90ae44a07c5fa18090128237011042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000090201010201030000002a390761b997897afe51540c39dfeb5c78d00781a547d2b83b1e72259894dea5100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f800009020101020103000000b3f28f9cc26df90ea49e13e3cd97c01d772e9d6609453e91d4369ef78e3880a004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200090201010201030000007fae89b888b23f4fbdaed2fb990a1f42727aef5bd2a8b91f8cb970570909ab391004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e5100090201010201030000001d64a3f9270bf8b8104305ba76829472f3aac2b6fff20b98ac10361ec5473fbb11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef0009020101020103000000adb76570d64f89650686df5819414e5e42cf7eedab24605aa63c4b8e26e90eda100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be400009020101020103000000a5a8530416d9462521b6fd932723d8971684b4620e4254caf09c75289e0e64700420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330009020101020103000000fa1d907f967c48292a5af3d4c3aad435c2ee9237119614d612aee3b4f52e3614111111012003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d37f030100000b0008000000000000003d000401010005020101010072cc451270c61384d358f7d41135b78788011830301a697b97a3714c203a36dc100214105bdf191491b67249d321f3d9bebdf82c9a3395fef336c60b3701af0593e7100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b000002030014bb3df025e32fd90d1feee7dca4b83321c683292d0000030101003a0037010001010030a5fd02c96d5f60eb54b15b043a84ed80a0af804eff4a2bfea1fc9fed323232c7ab12072368097e556439d08aa0a6866c000010030102003a003702000001003085ff00e6339367d3e31e27cbc33c13c3cd0c6e973a5b902e76668d7a6daf83c129257cc7f9cc35e1c0689a6df03a891d00001101200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb7f030100000b000800000000000000030004010100050201010100783a62676dbffd012f9343ef0af71c1b800cda19801689dfb7e2372cccc3ed9d10027f0e94e54c63ffdcd3d3d9017a63e82f9984ade5c4faa59d2479c11007932524100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df1102010178030100002b002800000200002103fe65fcdcfe242dc2e43d654274ec9ce1bbbc9dd5a1c88945eeef18cc93151f7f0000030101001e001b010001030014c94f46cf38b83862990f782c84acbc178d7b02da000010030102001e001b02000203001426d387d9884862f96160dd59ca596bdce82da74600001101201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb7f030100000b000800000000000000600004010100050201010100ca3a10eab3b889465bba51bc5354131aee1044e510d9ed4a7068d1181c7dbfcd10029626ec2b4e8861c675b20bc4456333d8c41fd0c0b9c9f0b78047c6634ebab8ef100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100001e001b000003020014fbd9daa5993de56a2e4346b7c72ff5585efffaab0000030101002b002801000300002103fdc9403eb6f005db700e7841627f4f92e7c65d167384cd57a4f4e46583c21afe000010030102002b002802000000002103703446f77c8db1fbac6f3422c8e045098adb662c0b620a15b8c4d9ecd2a3defa000011012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c307f030100000b000800000000000000420004010100050201010100d7f397a816f23f32e9a6cd2ab5b03d5b6d30742cf0b58517f276d9f75c1c4d611002bfd5686ae0d2a7684c2f6ed3a7419a436a5389afc9a84a1bb22a1decdfa7625d100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b0000020300145e0e49d808ad21d01d07dd799a75bd1b472788a70000030101003a003701000001003097c8d8102d216818c693dc46614ce9242b8e54e05a8ff1f520a3694b9481091d92906b13b9b2762b127ee4f07e91119e000010030102003a00370200030100308949c96dda849268044e176dbdba458fb5deac81e9918793bdb837f5afee0c2496a5930d46d1fe37ce536cbef8e95bb40000110120399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f807f030100000b0008000000000000000c0004010100050201010100a9403aa408af35d267980dfff1706d70a59b6dba867d0b568ca8c5b77560d67a100276cbfe822d7b9f6863f9a06b668097458e123ff385e31c29d830d03f1148973a100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100003a0037000000010030b79d4caa865f84207124c3d304430372f39d7c18a237df3a71e3c4fb7ba9ab9816439a809beb8606c3bb52d53a5364590000030101001e001b0100030200146406a5082b231340726d4cd0de2452bc73a33003000010030102001e001b0200010300144ac7b42f524e1d1b22098f85adfca752600ef9a000001101203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a27f030100000b000800000000000000100004010100050201010100d651221796b5206a5b9678a4d9995d519d8b9e75e87d85e57effb91f82a23e8d1002bcf84a882c0f72dd0d520a6954b3e1887fa55b7dc67635b44516856b31fd20a8100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100001e001b0000010200144463a1a994d5040e69c090b6985d7af295bfd11a0000030101003a0037010002010030973988b291fd1bca86d906723e335bdf13d3ebbadfea31dd164b3c672c16da72af8e6edfc0bac44b92b8c536d708dc33000010030102002b00280200030000210360da79c58995e4ec88512af9a4440ca4f2d7bfe84240e17effc4dd8ce94033a200001101207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e517f030100000b000800000000000000580004010100050201010100d95ff983db933edc675487a6f4e388fcf2db59313aeab5f45991a7f2471774471002355f98c38fd87ca5775e5e451243eb11300ed91fc950ea204c0a74b9a1991a25100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100003a0037000003010030b3423844bae8a591bbfb437b55566b5d61e54ee64f93351b0a3b9d4b731445d25ce367f7aedfcb32bd3cd14308a54cf50000030101003a0037010001010030a154c19082ac6b5fec72b81f6488550fec7149d52f66b4463915a61179c4f1f8507d366614b454dabf2c942235caad01000010030102001e001b0200030300140a8c14745c982f9fdc43aa985c02b1e5bff6c403000011012097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef7f030100000b000800000000000000620004010100050201010100412c1e7de2394dcd009223eb8c3a24e34b93a7c48df0bb86499160a31ea9dbdb1002180590eec33397034675f379cf17f62c0e77d17724a03238dcd3f216a4bc9509100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100003a0037000002010030afa4370aa5a48ab2f3ab510ccaba3b6d8cf51752304507e6a341c4e4ff6aa7c07610a503b42f479834b032d25dd160590000030101002b002801000300002103a9584c4580d165d2744ba49a70472653915bfdbec4bef471e26ce4c1c9e6c6ab000010030102001e001b02000102001445d04558a26b8ca04b486957c8abf5abf24ec76f0000110120a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be407f030100000b0008000000000000005d0004010100050201010100f140186a6bd413a50814db484b00398c2e7e6da9fbe2cb536728e880deb7506010027767f75fded47f94a6f81c671d448beddb6c2727f1f209ba015bf8de7331c13c100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100002b002800000000002102eebd2f91818a234e1879f8a55652f1e52419ad168b8f27b91be6b79958f7a5510000030101002b00280100020000210214a91dfcb36718209a5ee79c290029b849f1ce2feef6585a3b3fa37d04fb62b7000010030102001e001b0200030200144ee490084160fc8b1e73361d5a4c055beee77d8c0000110120e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4337f030100000b0008000000000000004f0004010100050201010100eb90b3c6d9a547e3b8a1111f621e0dbe5bfc68a8196371d497cb2912fa809d001002ab80ce7b6ca4875dbc7dc1f0d902551628c97b2383c27d04538d46a97d3cad43100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100001e001b0000020300149a061f31734c5f5f0b119ab72d433c9af133d3a60000030101003a003701000101003096e1fc631934a14acd313ff28ca29c9e9b43181b8df29386702b1a2d65a7cc823683f5733e296fb40c73648bc9cbf625000010030102001e001b02000102001474f185aa527f31202442d208cdb2905fa71403290000110201609f06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3000b03fda4d93a40301700000095840c6be056ed3d199dedf5265a5d3dafd195aa4cb54ca26943f7e092a5f06904200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000b03fd62132d410718000000b9dec92595e5eabb6de045782827bd98b60b9252287eec0f8e3450ea7c59619b1004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000b03fd8e29761d5405000000380d1a8cb3511b3ecf770a1d81f40c293182d29cf0574962db50c4cfb626fdb711042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30000b03fd62b9bfe135190000002eefa752386580c31084b54f2119973ccef6ac92fc38607e8609e896c9994c3e100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80000b03fdd0a1b7eee2140000002271b648a8925b8c717543453a59a3a20a3c52ce9b3e5fc793983c64f9f6fea004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2000b03fd1cb12a5b261400000068f31829eaec02f7e5eddada129d4981a99bda0e5c0fd4eff3c23eafc2c79a021004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e51000b03fd586ba25d1f1a0000005e3b38a6d9bede250ed0b612d01915a78182ee18d819d07d43ae925728b42d2d11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000b03fd120b51f4ea10000000be380b13cfd7149332e5ac818ae84d31e4be119bc0ebd717475630f6f38b6e90100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40000b03fd505d6c926f0d0000009500204c698cc12fc96774a34f77415c37376ff17b492838e414d774b5b7bec10420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae433000b03fd1e078984690800000064d995f4b5b62c480a04f1b8fb4c7a30b607f12da4abc357993ee7505be19b26111111";
- char *pub_key_hash_one_hex = "1f0815269afc012de44260ceb28a4496d3184184";
- char *pub_key_hash_two_hex = "4463a1a994d5040e69c090b6985d7af295bfd11a";
- char *pub_key_hash_three_hex = "5e0e49d808ad21d01d07dd799a75bd1b472788a7";
-
- unsigned char *multiple_identity_proof_bin = hex2bin(multiple_identity_proof_hex);
- unsigned char *pub_key_hashes[3] = {
- hex2bin(pub_key_hash_one_hex),
- hex2bin(pub_key_hash_two_hex),
- hex2bin(pub_key_hash_three_hex),
- };
- MultipleIdentityVerificationResult *multi_iden_result = verify_full_identities_by_public_key_hashes(multiple_identity_proof_bin, 6206, pub_key_hashes, 3);
- assert(multi_iden_result->is_valid);
-
- uint8_t expected_root_hash[32] = {202, 84, 121, 98, 165, 168, 181, 237, 228, 130, 249, 5, 45, 10, 35, 77, 17, 60, 42, 121, 141, 6, 90, 21, 12, 231, 68, 33, 156, 219, 114, 132};
- assert(is_array_equal(expected_root_hash, *multi_iden_result->root_hash, 32));
-
- assert(multi_iden_result->map_size == 3);
-
- uint8_t iden_one_pk_hash[20] = { 31,
- 8,
- 21,
- 38,
- 154,
- 252,
- 1,
- 45,
- 228,
- 66,
- 96,
- 206,
- 178,
- 138,
- 68,
- 150,
- 211,
- 24,
- 65,
- 132};
- assert(is_array_equal(iden_one_pk_hash, multi_iden_result-> public_key_hash_identity_map[0]->public_key_hash, multi_iden_result->public_key_hash_identity_map[0]->public_key_hash_length));
- assert(multi_iden_result->public_key_hash_identity_map[0]->has_identity);
-
- uint8_t iden_two_pk_hash[20] = { 68,
- 99,
- 161,
- 169,
- 148,
- 213,
- 4,
- 14,
- 105,
- 192,
- 144,
- 182,
- 152,
- 93,
- 122,
- 242,
- 149,
- 191,
- 209,
- 26};
- assert(is_array_equal(iden_two_pk_hash, multi_iden_result-> public_key_hash_identity_map[1]->public_key_hash, multi_iden_result->public_key_hash_identity_map[1]->public_key_hash_length));
- assert(multi_iden_result->public_key_hash_identity_map[1]->has_identity);
-
- uint8_t iden_three_pk_hash[20] = { 94,
- 14,
- 73,
- 216, 8,
- 173,
- 33,
- 208,
- 29,
- 7,
- 221,
- 121,
- 154,
- 117,
- 189,
- 27,
- 71,
- 39,
- 136,
- 167};
- assert(is_array_equal(iden_three_pk_hash, multi_iden_result-> public_key_hash_identity_map[2]->public_key_hash, multi_iden_result->public_key_hash_identity_map[2]->public_key_hash_length));
- assert(multi_iden_result->public_key_hash_identity_map[2]->has_identity);
-}
-
-void test_verify_full_identity_by_identity_id() {
- char *proof_hex = "06000100a603014a75cf3f535e81c4680f8137a2208dbcb2652ffd7e715bd4290cc5c560b2cc6102cfbe0535bd2defe586b863b9ccb92d0d66fb2b810d730e7ba2cb7e2fb302613b100401180018020114aee302720896bba837dcf3f2d674f546fd25496f00ca359aa1b2032e3158ae5e5c489f7d46722f29644a15e1cf7c3935b30606def61104012000240201203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200a0d5a4f6418663468515cd75189be3e1034bbfa9a1807eb81d964ba7442a0b1e100169931838564707dbf11e90a059fd7dd453cc7e68adb7d2c2375bae53566664e711025670752cc3d883200a7598b65cd74b41a760cc0be57cda5536f15f03c8783aa81001c33635136e502e9ac5244b15a20a757e0759ce0a90823cd37f893f6a49556d26040160002d0401203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2fd1cb12a5b2614000000fbbd3be097e7f07d5619dd69e7767884d116f95ae9a5fcdb651e71727902cc1e10011e0c1443d0925f781132f4c506747202dbffa3ca3ded4d2387d4b7e40e0303e311110201187f03144463a1a994d5040e69c090b6985d7af295bfd11a002300203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200029e6f2d33b1580030e3b6030e3c25016ab7253965682556059dcc243b75c7fa6d1001e09f88cd09cc595d524892b3e642b939f2827995605703c49c861f653001d5e1110101204d04203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200090201010201030000007fae89b888b23f4fbdaed2fb990a1f42727aef5bd2a8b91f8cb970570909ab3901203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a27f030100000b000800000000000000100004010100050201010100d651221796b5206a5b9678a4d9995d519d8b9e75e87d85e57effb91f82a23e8d1002bcf84a882c0f72dd0d520a6954b3e1887fa55b7dc67635b44516856b31fd20a8100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100001e001b0000010200144463a1a994d5040e69c090b6985d7af295bfd11a0000030101003a0037010002010030973988b291fd1bca86d906723e335bdf13d3ebbadfea31dd164b3c672c16da72af8e6edfc0bac44b92b8c536d708dc33000010030102002b00280200030000210360da79c58995e4ec88512af9a4440ca4f2d7bfe84240e17effc4dd8ce94033a20000110201604f04203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2000b03fd1cb12a5b261400000068f31829eaec02f7e5eddada129d4981a99bda0e5c0fd4eff3c23eafc2c79a02";
- char *identity_id_hex = "3eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2";
-
- unsigned char *proof_bin = hex2bin(proof_hex);
- unsigned char *identity_id_bin = hex2bin(identity_id_hex);
-
- IdentityVerificationResult *result = verify_full_identity_by_identity_id(proof_bin, 1038, true, identity_id_bin);
- assert(result->is_valid);
-
- uint8_t expected_root_hash[32] = {72,72,215,200,156,21,128,156,166,182,110,57,113,232,229,242,193,199,240,135,222,102,246,165,181,68,81,221,120,195,236,199};
- assert(is_array_equal(result->root_hash, expected_root_hash,32));
-
- assert(result->has_identity);
-}
-
-void test_verify_identity_id_by_public_key_hash() {
- char *multiple_identity_proof_hex = "06000100a603014a75cf3f535e81c4680f8137a2208dbcb2652ffd7e715bd4290cc5c560b2cc6102cfbe0535bd2defe586b863b9ccb92d0d66fb2b810d730e7ba2cb7e2fb302613b1004011800180201145e0e49d808ad21d01d07dd799a75bd1b472788a7008c10aa4c1d19e2e7e42fe0b1a7f6d93d4c0b6992ef63ea985c16447cada4629511040120002402012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000ba56cfb1d87ef47857f6b1cd7fb918406fd50f81966619777dd4c1b595a1a26e100169931838564707dbf11e90a059fd7dd453cc7e68adb7d2c2375bae53566664e711025670752cc3d883200a7598b65cd74b41a760cc0be57cda5536f15f03c8783aa81001c33635136e502e9ac5244b15a20a757e0759ce0a90823cd37f893f6a49556d26040160002d04012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30fdbafd6833aeb700000012b27f4a0a7cfd06e3387b33a5bca6682953512e21621ae9cf6d633d9041771910011e0c1443d0925f781132f4c506747202dbffa3ca3ded4d2387d4b7e40e0303e31111020118b3080132c9d35844d5ce2a8e0f377cee23c143a53396073dea86c494b86ba4c4af0b3903141f0815269afc012de44260ceb28a4496d3184184002300200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb00100168576e24521e03ba4b624912bb07833767c81102310b87d8ea1caf2795c68f921102e8b7eb376f0f7993badf93971f690be8a48f09db0711f052a2ed48471497b9d01003144463a1a994d5040e69c090b6985d7af295bfd11a002300203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a20002254bf0a990beb721c21f21e8dbab50e33cd9cf09618fc27c9f7450c673516aee1001c6adfe081809218ee07461f95f53ce6ce462ec379f97a71f1be40f7218cb50af111103145e0e49d808ad21d01d07dd799a75bd1b472788a70023002035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30001001a4b31998d47c30e390f4fa56f28f19c62f114f17a704d29c56e28b6fdb47f101031467892af390cd2b7653a918c7b692c85b87b44d3200230020399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80001001eb4da977338a3da4204eaaac0c8856bdfd51d9b25ceef04b40bb38eff79ab11011021f22102429dbe1bc0ca714847b08187d9a874cc43329aaa79647fb9aa0834d691003149a061f31734c5f5f0b119ab72d433c9af133d3a600230020e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330002644c601e67692188cf5a975c2207caba899d99f1bbd4b62e5fe856850b9d7286100314a54921bb29b67e31898efebc29f241b1aefa4dca002300207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e510010029e6f2d33b1580030e3b6030e3c25016ab7253965682556059dcc243b75c7fa6d0314b3bfce478de96fe30cd3713bf88ce7728687da8a00230020a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40001111110314bb3df025e32fd90d1feee7dca4b83321c683292d0023002003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3001001ee0847805b145b5fb500b139fe12767ee681fc310a21d6e9814619df5187470802a0de352fe6767da7bf4c33ba7d2da8db0440457835d3c2992473210e02b6312c1001e09f88cd09cc595d524892b3e642b939f2827995605703c49c861f653001d5e1029a563c983d202520c1a94f4c6ba99750373450aaf9dcb2a62ef50e9877646043100314ed738aaadd75d1677fefeccadd033f126cfee76a0023002097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000314fbd9daa5993de56a2e4346b7c72ff5585efffaab002300201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb0010111111110101208b06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d300090201010201030000006c4bfcf223cd4fe5c1cac82e1a9e2c73eb0e7f34cebabdd7630e24cb192f975804200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000902010102010300000080da62acb8c49f901d6bf84a2a2af15431e69e29069abf8d02f2c113c6099ba61004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000902010102010300000051a23049efbcde3a0e9c85ea7af05a28d4de31f90ae44a07c5fa18090128237011042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000090201010201030000002a390761b997897afe51540c39dfeb5c78d00781a547d2b83b1e72259894dea5100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f800009020101020103000000b3f28f9cc26df90ea49e13e3cd97c01d772e9d6609453e91d4369ef78e3880a004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200090201010201030000007fae89b888b23f4fbdaed2fb990a1f42727aef5bd2a8b91f8cb970570909ab391004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e5100090201010201030000001d64a3f9270bf8b8104305ba76829472f3aac2b6fff20b98ac10361ec5473fbb11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef0009020101020103000000adb76570d64f89650686df5819414e5e42cf7eedab24605aa63c4b8e26e90eda100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be400009020101020103000000a5a8530416d9462521b6fd932723d8971684b4620e4254caf09c75289e0e64700420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330009020101020103000000fa1d907f967c48292a5af3d4c3aad435c2ee9237119614d612aee3b4f52e3614111111012003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d37f030100000b0008000000000000003d000401010005020101010072cc451270c61384d358f7d41135b78788011830301a697b97a3714c203a36dc100214105bdf191491b67249d321f3d9bebdf82c9a3395fef336c60b3701af0593e7100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b000002030014bb3df025e32fd90d1feee7dca4b83321c683292d0000030101003a0037010001010030a5fd02c96d5f60eb54b15b043a84ed80a0af804eff4a2bfea1fc9fed323232c7ab12072368097e556439d08aa0a6866c000010030102003a003702000001003085ff00e6339367d3e31e27cbc33c13c3cd0c6e973a5b902e76668d7a6daf83c129257cc7f9cc35e1c0689a6df03a891d00001101200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb7f030100000b000800000000000000030004010100050201010100783a62676dbffd012f9343ef0af71c1b800cda19801689dfb7e2372cccc3ed9d10027f0e94e54c63ffdcd3d3d9017a63e82f9984ade5c4faa59d2479c11007932524100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df1102010178030100002b002800000200002103fe65fcdcfe242dc2e43d654274ec9ce1bbbc9dd5a1c88945eeef18cc93151f7f0000030101001e001b010001030014c94f46cf38b83862990f782c84acbc178d7b02da000010030102001e001b02000203001426d387d9884862f96160dd59ca596bdce82da74600001101201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb7f030100000b000800000000000000600004010100050201010100ca3a10eab3b889465bba51bc5354131aee1044e510d9ed4a7068d1181c7dbfcd10029626ec2b4e8861c675b20bc4456333d8c41fd0c0b9c9f0b78047c6634ebab8ef100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100001e001b000003020014fbd9daa5993de56a2e4346b7c72ff5585efffaab0000030101002b002801000300002103fdc9403eb6f005db700e7841627f4f92e7c65d167384cd57a4f4e46583c21afe000010030102002b002802000000002103703446f77c8db1fbac6f3422c8e045098adb662c0b620a15b8c4d9ecd2a3defa000011012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c307f030100000b000800000000000000420004010100050201010100d7f397a816f23f32e9a6cd2ab5b03d5b6d30742cf0b58517f276d9f75c1c4d611002bfd5686ae0d2a7684c2f6ed3a7419a436a5389afc9a84a1bb22a1decdfa7625d100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b0000020300145e0e49d808ad21d01d07dd799a75bd1b472788a70000030101003a003701000001003097c8d8102d216818c693dc46614ce9242b8e54e05a8ff1f520a3694b9481091d92906b13b9b2762b127ee4f07e91119e000010030102003a00370200030100308949c96dda849268044e176dbdba458fb5deac81e9918793bdb837f5afee0c2496a5930d46d1fe37ce536cbef8e95bb40000110120399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f807f030100000b0008000000000000000c0004010100050201010100a9403aa408af35d267980dfff1706d70a59b6dba867d0b568ca8c5b77560d67a100276cbfe822d7b9f6863f9a06b668097458e123ff385e31c29d830d03f1148973a100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100003a0037000000010030b79d4caa865f84207124c3d304430372f39d7c18a237df3a71e3c4fb7ba9ab9816439a809beb8606c3bb52d53a5364590000030101001e001b0100030200146406a5082b231340726d4cd0de2452bc73a33003000010030102001e001b0200010300144ac7b42f524e1d1b22098f85adfca752600ef9a000001101203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a27f030100000b000800000000000000100004010100050201010100d651221796b5206a5b9678a4d9995d519d8b9e75e87d85e57effb91f82a23e8d1002bcf84a882c0f72dd0d520a6954b3e1887fa55b7dc67635b44516856b31fd20a8100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100001e001b0000010200144463a1a994d5040e69c090b6985d7af295bfd11a0000030101003a0037010002010030973988b291fd1bca86d906723e335bdf13d3ebbadfea31dd164b3c672c16da72af8e6edfc0bac44b92b8c536d708dc33000010030102002b00280200030000210360da79c58995e4ec88512af9a4440ca4f2d7bfe84240e17effc4dd8ce94033a200001101207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e517f030100000b000800000000000000580004010100050201010100d95ff983db933edc675487a6f4e388fcf2db59313aeab5f45991a7f2471774471002355f98c38fd87ca5775e5e451243eb11300ed91fc950ea204c0a74b9a1991a25100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100003a0037000003010030b3423844bae8a591bbfb437b55566b5d61e54ee64f93351b0a3b9d4b731445d25ce367f7aedfcb32bd3cd14308a54cf50000030101003a0037010001010030a154c19082ac6b5fec72b81f6488550fec7149d52f66b4463915a61179c4f1f8507d366614b454dabf2c942235caad01000010030102001e001b0200030300140a8c14745c982f9fdc43aa985c02b1e5bff6c403000011012097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef7f030100000b000800000000000000620004010100050201010100412c1e7de2394dcd009223eb8c3a24e34b93a7c48df0bb86499160a31ea9dbdb1002180590eec33397034675f379cf17f62c0e77d17724a03238dcd3f216a4bc9509100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100003a0037000002010030afa4370aa5a48ab2f3ab510ccaba3b6d8cf51752304507e6a341c4e4ff6aa7c07610a503b42f479834b032d25dd160590000030101002b002801000300002103a9584c4580d165d2744ba49a70472653915bfdbec4bef471e26ce4c1c9e6c6ab000010030102001e001b02000102001445d04558a26b8ca04b486957c8abf5abf24ec76f0000110120a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be407f030100000b0008000000000000005d0004010100050201010100f140186a6bd413a50814db484b00398c2e7e6da9fbe2cb536728e880deb7506010027767f75fded47f94a6f81c671d448beddb6c2727f1f209ba015bf8de7331c13c100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100002b002800000000002102eebd2f91818a234e1879f8a55652f1e52419ad168b8f27b91be6b79958f7a5510000030101002b00280100020000210214a91dfcb36718209a5ee79c290029b849f1ce2feef6585a3b3fa37d04fb62b7000010030102001e001b0200030200144ee490084160fc8b1e73361d5a4c055beee77d8c0000110120e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4337f030100000b0008000000000000004f0004010100050201010100eb90b3c6d9a547e3b8a1111f621e0dbe5bfc68a8196371d497cb2912fa809d001002ab80ce7b6ca4875dbc7dc1f0d902551628c97b2383c27d04538d46a97d3cad43100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100001e001b0000020300149a061f31734c5f5f0b119ab72d433c9af133d3a60000030101003a003701000101003096e1fc631934a14acd313ff28ca29c9e9b43181b8df29386702b1a2d65a7cc823683f5733e296fb40c73648bc9cbf625000010030102001e001b02000102001474f185aa527f31202442d208cdb2905fa71403290000110201609f06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3000b03fda4d93a40301700000095840c6be056ed3d199dedf5265a5d3dafd195aa4cb54ca26943f7e092a5f06904200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000b03fd62132d410718000000b9dec92595e5eabb6de045782827bd98b60b9252287eec0f8e3450ea7c59619b1004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000b03fd8e29761d5405000000380d1a8cb3511b3ecf770a1d81f40c293182d29cf0574962db50c4cfb626fdb711042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30000b03fd62b9bfe135190000002eefa752386580c31084b54f2119973ccef6ac92fc38607e8609e896c9994c3e100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80000b03fdd0a1b7eee2140000002271b648a8925b8c717543453a59a3a20a3c52ce9b3e5fc793983c64f9f6fea004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2000b03fd1cb12a5b261400000068f31829eaec02f7e5eddada129d4981a99bda0e5c0fd4eff3c23eafc2c79a021004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e51000b03fd586ba25d1f1a0000005e3b38a6d9bede250ed0b612d01915a78182ee18d819d07d43ae925728b42d2d11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000b03fd120b51f4ea10000000be380b13cfd7149332e5ac818ae84d31e4be119bc0ebd717475630f6f38b6e90100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40000b03fd505d6c926f0d0000009500204c698cc12fc96774a34f77415c37376ff17b492838e414d774b5b7bec10420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae433000b03fd1e078984690800000064d995f4b5b62c480a04f1b8fb4c7a30b607f12da4abc357993ee7505be19b26111111";
- char *pub_key_hash_hex = "1f0815269afc012de44260ceb28a4496d3184184";
-
- unsigned char *proof = hex2bin(multiple_identity_proof_hex);
- unsigned char *pub_key_hash = hex2bin(pub_key_hash_hex);
-
- IdentityIdVerificationResult *result = verify_identity_id_by_public_key_hash(proof, 6206, true, pub_key_hash);
- uint8_t expected_identity_id[32] = {15, 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215, 241, 108, 23, 39,
- 205, 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203,};
- assert(result->is_valid);
- assert(result->has_identity_id);
- assert(result->id_size == 32);
- assert(is_array_equal(expected_identity_id, result->identity_id, result->id_size));
-}
-
-void test_verify_identity_balances_by_identity_ids() {
- char *multiple_identity_proof_hex = "06000100a603014a75cf3f535e81c4680f8137a2208dbcb2652ffd7e715bd4290cc5c560b2cc6102cfbe0535bd2defe586b863b9ccb92d0d66fb2b810d730e7ba2cb7e2fb302613b1004011800180201145e0e49d808ad21d01d07dd799a75bd1b472788a7008c10aa4c1d19e2e7e42fe0b1a7f6d93d4c0b6992ef63ea985c16447cada4629511040120002402012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000ba56cfb1d87ef47857f6b1cd7fb918406fd50f81966619777dd4c1b595a1a26e100169931838564707dbf11e90a059fd7dd453cc7e68adb7d2c2375bae53566664e711025670752cc3d883200a7598b65cd74b41a760cc0be57cda5536f15f03c8783aa81001c33635136e502e9ac5244b15a20a757e0759ce0a90823cd37f893f6a49556d26040160002d04012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30fdbafd6833aeb700000012b27f4a0a7cfd06e3387b33a5bca6682953512e21621ae9cf6d633d9041771910011e0c1443d0925f781132f4c506747202dbffa3ca3ded4d2387d4b7e40e0303e31111020118b3080132c9d35844d5ce2a8e0f377cee23c143a53396073dea86c494b86ba4c4af0b3903141f0815269afc012de44260ceb28a4496d3184184002300200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb00100168576e24521e03ba4b624912bb07833767c81102310b87d8ea1caf2795c68f921102e8b7eb376f0f7993badf93971f690be8a48f09db0711f052a2ed48471497b9d01003144463a1a994d5040e69c090b6985d7af295bfd11a002300203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a20002254bf0a990beb721c21f21e8dbab50e33cd9cf09618fc27c9f7450c673516aee1001c6adfe081809218ee07461f95f53ce6ce462ec379f97a71f1be40f7218cb50af111103145e0e49d808ad21d01d07dd799a75bd1b472788a70023002035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30001001a4b31998d47c30e390f4fa56f28f19c62f114f17a704d29c56e28b6fdb47f101031467892af390cd2b7653a918c7b692c85b87b44d3200230020399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80001001eb4da977338a3da4204eaaac0c8856bdfd51d9b25ceef04b40bb38eff79ab11011021f22102429dbe1bc0ca714847b08187d9a874cc43329aaa79647fb9aa0834d691003149a061f31734c5f5f0b119ab72d433c9af133d3a600230020e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330002644c601e67692188cf5a975c2207caba899d99f1bbd4b62e5fe856850b9d7286100314a54921bb29b67e31898efebc29f241b1aefa4dca002300207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e510010029e6f2d33b1580030e3b6030e3c25016ab7253965682556059dcc243b75c7fa6d0314b3bfce478de96fe30cd3713bf88ce7728687da8a00230020a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40001111110314bb3df025e32fd90d1feee7dca4b83321c683292d0023002003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3001001ee0847805b145b5fb500b139fe12767ee681fc310a21d6e9814619df5187470802a0de352fe6767da7bf4c33ba7d2da8db0440457835d3c2992473210e02b6312c1001e09f88cd09cc595d524892b3e642b939f2827995605703c49c861f653001d5e1029a563c983d202520c1a94f4c6ba99750373450aaf9dcb2a62ef50e9877646043100314ed738aaadd75d1677fefeccadd033f126cfee76a0023002097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000314fbd9daa5993de56a2e4346b7c72ff5585efffaab002300201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb0010111111110101208b06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d300090201010201030000006c4bfcf223cd4fe5c1cac82e1a9e2c73eb0e7f34cebabdd7630e24cb192f975804200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000902010102010300000080da62acb8c49f901d6bf84a2a2af15431e69e29069abf8d02f2c113c6099ba61004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000902010102010300000051a23049efbcde3a0e9c85ea7af05a28d4de31f90ae44a07c5fa18090128237011042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000090201010201030000002a390761b997897afe51540c39dfeb5c78d00781a547d2b83b1e72259894dea5100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f800009020101020103000000b3f28f9cc26df90ea49e13e3cd97c01d772e9d6609453e91d4369ef78e3880a004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200090201010201030000007fae89b888b23f4fbdaed2fb990a1f42727aef5bd2a8b91f8cb970570909ab391004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e5100090201010201030000001d64a3f9270bf8b8104305ba76829472f3aac2b6fff20b98ac10361ec5473fbb11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef0009020101020103000000adb76570d64f89650686df5819414e5e42cf7eedab24605aa63c4b8e26e90eda100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be400009020101020103000000a5a8530416d9462521b6fd932723d8971684b4620e4254caf09c75289e0e64700420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330009020101020103000000fa1d907f967c48292a5af3d4c3aad435c2ee9237119614d612aee3b4f52e3614111111012003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d37f030100000b0008000000000000003d000401010005020101010072cc451270c61384d358f7d41135b78788011830301a697b97a3714c203a36dc100214105bdf191491b67249d321f3d9bebdf82c9a3395fef336c60b3701af0593e7100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b000002030014bb3df025e32fd90d1feee7dca4b83321c683292d0000030101003a0037010001010030a5fd02c96d5f60eb54b15b043a84ed80a0af804eff4a2bfea1fc9fed323232c7ab12072368097e556439d08aa0a6866c000010030102003a003702000001003085ff00e6339367d3e31e27cbc33c13c3cd0c6e973a5b902e76668d7a6daf83c129257cc7f9cc35e1c0689a6df03a891d00001101200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb7f030100000b000800000000000000030004010100050201010100783a62676dbffd012f9343ef0af71c1b800cda19801689dfb7e2372cccc3ed9d10027f0e94e54c63ffdcd3d3d9017a63e82f9984ade5c4faa59d2479c11007932524100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df1102010178030100002b002800000200002103fe65fcdcfe242dc2e43d654274ec9ce1bbbc9dd5a1c88945eeef18cc93151f7f0000030101001e001b010001030014c94f46cf38b83862990f782c84acbc178d7b02da000010030102001e001b02000203001426d387d9884862f96160dd59ca596bdce82da74600001101201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb7f030100000b000800000000000000600004010100050201010100ca3a10eab3b889465bba51bc5354131aee1044e510d9ed4a7068d1181c7dbfcd10029626ec2b4e8861c675b20bc4456333d8c41fd0c0b9c9f0b78047c6634ebab8ef100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100001e001b000003020014fbd9daa5993de56a2e4346b7c72ff5585efffaab0000030101002b002801000300002103fdc9403eb6f005db700e7841627f4f92e7c65d167384cd57a4f4e46583c21afe000010030102002b002802000000002103703446f77c8db1fbac6f3422c8e045098adb662c0b620a15b8c4d9ecd2a3defa000011012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c307f030100000b000800000000000000420004010100050201010100d7f397a816f23f32e9a6cd2ab5b03d5b6d30742cf0b58517f276d9f75c1c4d611002bfd5686ae0d2a7684c2f6ed3a7419a436a5389afc9a84a1bb22a1decdfa7625d100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b0000020300145e0e49d808ad21d01d07dd799a75bd1b472788a70000030101003a003701000001003097c8d8102d216818c693dc46614ce9242b8e54e05a8ff1f520a3694b9481091d92906b13b9b2762b127ee4f07e91119e000010030102003a00370200030100308949c96dda849268044e176dbdba458fb5deac81e9918793bdb837f5afee0c2496a5930d46d1fe37ce536cbef8e95bb40000110120399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f807f030100000b0008000000000000000c0004010100050201010100a9403aa408af35d267980dfff1706d70a59b6dba867d0b568ca8c5b77560d67a100276cbfe822d7b9f6863f9a06b668097458e123ff385e31c29d830d03f1148973a100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100003a0037000000010030b79d4caa865f84207124c3d304430372f39d7c18a237df3a71e3c4fb7ba9ab9816439a809beb8606c3bb52d53a5364590000030101001e001b0100030200146406a5082b231340726d4cd0de2452bc73a33003000010030102001e001b0200010300144ac7b42f524e1d1b22098f85adfca752600ef9a000001101203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a27f030100000b000800000000000000100004010100050201010100d651221796b5206a5b9678a4d9995d519d8b9e75e87d85e57effb91f82a23e8d1002bcf84a882c0f72dd0d520a6954b3e1887fa55b7dc67635b44516856b31fd20a8100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100001e001b0000010200144463a1a994d5040e69c090b6985d7af295bfd11a0000030101003a0037010002010030973988b291fd1bca86d906723e335bdf13d3ebbadfea31dd164b3c672c16da72af8e6edfc0bac44b92b8c536d708dc33000010030102002b00280200030000210360da79c58995e4ec88512af9a4440ca4f2d7bfe84240e17effc4dd8ce94033a200001101207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e517f030100000b000800000000000000580004010100050201010100d95ff983db933edc675487a6f4e388fcf2db59313aeab5f45991a7f2471774471002355f98c38fd87ca5775e5e451243eb11300ed91fc950ea204c0a74b9a1991a25100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100003a0037000003010030b3423844bae8a591bbfb437b55566b5d61e54ee64f93351b0a3b9d4b731445d25ce367f7aedfcb32bd3cd14308a54cf50000030101003a0037010001010030a154c19082ac6b5fec72b81f6488550fec7149d52f66b4463915a61179c4f1f8507d366614b454dabf2c942235caad01000010030102001e001b0200030300140a8c14745c982f9fdc43aa985c02b1e5bff6c403000011012097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef7f030100000b000800000000000000620004010100050201010100412c1e7de2394dcd009223eb8c3a24e34b93a7c48df0bb86499160a31ea9dbdb1002180590eec33397034675f379cf17f62c0e77d17724a03238dcd3f216a4bc9509100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100003a0037000002010030afa4370aa5a48ab2f3ab510ccaba3b6d8cf51752304507e6a341c4e4ff6aa7c07610a503b42f479834b032d25dd160590000030101002b002801000300002103a9584c4580d165d2744ba49a70472653915bfdbec4bef471e26ce4c1c9e6c6ab000010030102001e001b02000102001445d04558a26b8ca04b486957c8abf5abf24ec76f0000110120a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be407f030100000b0008000000000000005d0004010100050201010100f140186a6bd413a50814db484b00398c2e7e6da9fbe2cb536728e880deb7506010027767f75fded47f94a6f81c671d448beddb6c2727f1f209ba015bf8de7331c13c100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100002b002800000000002102eebd2f91818a234e1879f8a55652f1e52419ad168b8f27b91be6b79958f7a5510000030101002b00280100020000210214a91dfcb36718209a5ee79c290029b849f1ce2feef6585a3b3fa37d04fb62b7000010030102001e001b0200030200144ee490084160fc8b1e73361d5a4c055beee77d8c0000110120e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4337f030100000b0008000000000000004f0004010100050201010100eb90b3c6d9a547e3b8a1111f621e0dbe5bfc68a8196371d497cb2912fa809d001002ab80ce7b6ca4875dbc7dc1f0d902551628c97b2383c27d04538d46a97d3cad43100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100001e001b0000020300149a061f31734c5f5f0b119ab72d433c9af133d3a60000030101003a003701000101003096e1fc631934a14acd313ff28ca29c9e9b43181b8df29386702b1a2d65a7cc823683f5733e296fb40c73648bc9cbf625000010030102001e001b02000102001474f185aa527f31202442d208cdb2905fa71403290000110201609f06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3000b03fda4d93a40301700000095840c6be056ed3d199dedf5265a5d3dafd195aa4cb54ca26943f7e092a5f06904200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000b03fd62132d410718000000b9dec92595e5eabb6de045782827bd98b60b9252287eec0f8e3450ea7c59619b1004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000b03fd8e29761d5405000000380d1a8cb3511b3ecf770a1d81f40c293182d29cf0574962db50c4cfb626fdb711042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30000b03fd62b9bfe135190000002eefa752386580c31084b54f2119973ccef6ac92fc38607e8609e896c9994c3e100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80000b03fdd0a1b7eee2140000002271b648a8925b8c717543453a59a3a20a3c52ce9b3e5fc793983c64f9f6fea004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2000b03fd1cb12a5b261400000068f31829eaec02f7e5eddada129d4981a99bda0e5c0fd4eff3c23eafc2c79a021004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e51000b03fd586ba25d1f1a0000005e3b38a6d9bede250ed0b612d01915a78182ee18d819d07d43ae925728b42d2d11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000b03fd120b51f4ea10000000be380b13cfd7149332e5ac818ae84d31e4be119bc0ebd717475630f6f38b6e90100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40000b03fd505d6c926f0d0000009500204c698cc12fc96774a34f77415c37376ff17b492838e414d774b5b7bec10420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae433000b03fd1e078984690800000064d995f4b5b62c480a04f1b8fb4c7a30b607f12da4abc357993ee7505be19b26111111";
- char *iden_one_hex = "3eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2";
- char *iden_two_hex = "97ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef";
-
- unsigned char *proof = hex2bin(multiple_identity_proof_hex);
- unsigned char *iden_ids[2] = {
- hex2bin(iden_one_hex),
- hex2bin(iden_two_hex),
- };
- MultipleIdentityBalanceVerificationResult *result = verify_identity_balances_by_identity_ids(proof, 6206, true, iden_ids, 2);
- assert(result->is_valid);
- assert(result->map_size == 2);
- assert(result->identity_id_balance_map[0]->has_balance);
- assert(result->identity_id_balance_map[0]->balance == 11077485418638);
- uint8_t expected_iden_one_bin[32] = {62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22,
- 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162};
- assert(is_array_equal(expected_iden_one_bin, result->identity_id_balance_map[0]->identity_id, result->identity_id_balance_map[0]->id_size));
-
- assert(result->identity_id_balance_map[1]->has_balance);
- assert(result->identity_id_balance_map[1]->balance == 9300653671817);
- uint8_t expected_iden_two_bin[32] = {151, 172, 124, 81, 243, 147, 225, 5, 188, 204, 9, 152, 150, 127, 129, 13, 246, 19,
- 141, 93, 239, 8, 214, 194, 123, 127, 177, 23, 144, 211, 189, 239,};
- assert(is_array_equal(expected_iden_two_bin, result->identity_id_balance_map[1]->identity_id, result->identity_id_balance_map[1]->id_size));
-}
-
-void test_verify_identity_ids_by_public_key_hashes() {
- char *multiple_identity_proof_hex = "06000100a603014a75cf3f535e81c4680f8137a2208dbcb2652ffd7e715bd4290cc5c560b2cc6102cfbe0535bd2defe586b863b9ccb92d0d66fb2b810d730e7ba2cb7e2fb302613b1004011800180201145e0e49d808ad21d01d07dd799a75bd1b472788a7008c10aa4c1d19e2e7e42fe0b1a7f6d93d4c0b6992ef63ea985c16447cada4629511040120002402012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000ba56cfb1d87ef47857f6b1cd7fb918406fd50f81966619777dd4c1b595a1a26e100169931838564707dbf11e90a059fd7dd453cc7e68adb7d2c2375bae53566664e711025670752cc3d883200a7598b65cd74b41a760cc0be57cda5536f15f03c8783aa81001c33635136e502e9ac5244b15a20a757e0759ce0a90823cd37f893f6a49556d26040160002d04012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30fdbafd6833aeb700000012b27f4a0a7cfd06e3387b33a5bca6682953512e21621ae9cf6d633d9041771910011e0c1443d0925f781132f4c506747202dbffa3ca3ded4d2387d4b7e40e0303e31111020118b3080132c9d35844d5ce2a8e0f377cee23c143a53396073dea86c494b86ba4c4af0b3903141f0815269afc012de44260ceb28a4496d3184184002300200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb00100168576e24521e03ba4b624912bb07833767c81102310b87d8ea1caf2795c68f921102e8b7eb376f0f7993badf93971f690be8a48f09db0711f052a2ed48471497b9d01003144463a1a994d5040e69c090b6985d7af295bfd11a002300203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a20002254bf0a990beb721c21f21e8dbab50e33cd9cf09618fc27c9f7450c673516aee1001c6adfe081809218ee07461f95f53ce6ce462ec379f97a71f1be40f7218cb50af111103145e0e49d808ad21d01d07dd799a75bd1b472788a70023002035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30001001a4b31998d47c30e390f4fa56f28f19c62f114f17a704d29c56e28b6fdb47f101031467892af390cd2b7653a918c7b692c85b87b44d3200230020399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80001001eb4da977338a3da4204eaaac0c8856bdfd51d9b25ceef04b40bb38eff79ab11011021f22102429dbe1bc0ca714847b08187d9a874cc43329aaa79647fb9aa0834d691003149a061f31734c5f5f0b119ab72d433c9af133d3a600230020e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330002644c601e67692188cf5a975c2207caba899d99f1bbd4b62e5fe856850b9d7286100314a54921bb29b67e31898efebc29f241b1aefa4dca002300207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e510010029e6f2d33b1580030e3b6030e3c25016ab7253965682556059dcc243b75c7fa6d0314b3bfce478de96fe30cd3713bf88ce7728687da8a00230020a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40001111110314bb3df025e32fd90d1feee7dca4b83321c683292d0023002003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3001001ee0847805b145b5fb500b139fe12767ee681fc310a21d6e9814619df5187470802a0de352fe6767da7bf4c33ba7d2da8db0440457835d3c2992473210e02b6312c1001e09f88cd09cc595d524892b3e642b939f2827995605703c49c861f653001d5e1029a563c983d202520c1a94f4c6ba99750373450aaf9dcb2a62ef50e9877646043100314ed738aaadd75d1677fefeccadd033f126cfee76a0023002097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000314fbd9daa5993de56a2e4346b7c72ff5585efffaab002300201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb0010111111110101208b06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d300090201010201030000006c4bfcf223cd4fe5c1cac82e1a9e2c73eb0e7f34cebabdd7630e24cb192f975804200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000902010102010300000080da62acb8c49f901d6bf84a2a2af15431e69e29069abf8d02f2c113c6099ba61004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000902010102010300000051a23049efbcde3a0e9c85ea7af05a28d4de31f90ae44a07c5fa18090128237011042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000090201010201030000002a390761b997897afe51540c39dfeb5c78d00781a547d2b83b1e72259894dea5100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f800009020101020103000000b3f28f9cc26df90ea49e13e3cd97c01d772e9d6609453e91d4369ef78e3880a004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200090201010201030000007fae89b888b23f4fbdaed2fb990a1f42727aef5bd2a8b91f8cb970570909ab391004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e5100090201010201030000001d64a3f9270bf8b8104305ba76829472f3aac2b6fff20b98ac10361ec5473fbb11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef0009020101020103000000adb76570d64f89650686df5819414e5e42cf7eedab24605aa63c4b8e26e90eda100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be400009020101020103000000a5a8530416d9462521b6fd932723d8971684b4620e4254caf09c75289e0e64700420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330009020101020103000000fa1d907f967c48292a5af3d4c3aad435c2ee9237119614d612aee3b4f52e3614111111012003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d37f030100000b0008000000000000003d000401010005020101010072cc451270c61384d358f7d41135b78788011830301a697b97a3714c203a36dc100214105bdf191491b67249d321f3d9bebdf82c9a3395fef336c60b3701af0593e7100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b000002030014bb3df025e32fd90d1feee7dca4b83321c683292d0000030101003a0037010001010030a5fd02c96d5f60eb54b15b043a84ed80a0af804eff4a2bfea1fc9fed323232c7ab12072368097e556439d08aa0a6866c000010030102003a003702000001003085ff00e6339367d3e31e27cbc33c13c3cd0c6e973a5b902e76668d7a6daf83c129257cc7f9cc35e1c0689a6df03a891d00001101200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb7f030100000b000800000000000000030004010100050201010100783a62676dbffd012f9343ef0af71c1b800cda19801689dfb7e2372cccc3ed9d10027f0e94e54c63ffdcd3d3d9017a63e82f9984ade5c4faa59d2479c11007932524100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df1102010178030100002b002800000200002103fe65fcdcfe242dc2e43d654274ec9ce1bbbc9dd5a1c88945eeef18cc93151f7f0000030101001e001b010001030014c94f46cf38b83862990f782c84acbc178d7b02da000010030102001e001b02000203001426d387d9884862f96160dd59ca596bdce82da74600001101201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb7f030100000b000800000000000000600004010100050201010100ca3a10eab3b889465bba51bc5354131aee1044e510d9ed4a7068d1181c7dbfcd10029626ec2b4e8861c675b20bc4456333d8c41fd0c0b9c9f0b78047c6634ebab8ef100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100001e001b000003020014fbd9daa5993de56a2e4346b7c72ff5585efffaab0000030101002b002801000300002103fdc9403eb6f005db700e7841627f4f92e7c65d167384cd57a4f4e46583c21afe000010030102002b002802000000002103703446f77c8db1fbac6f3422c8e045098adb662c0b620a15b8c4d9ecd2a3defa000011012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c307f030100000b000800000000000000420004010100050201010100d7f397a816f23f32e9a6cd2ab5b03d5b6d30742cf0b58517f276d9f75c1c4d611002bfd5686ae0d2a7684c2f6ed3a7419a436a5389afc9a84a1bb22a1decdfa7625d100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b0000020300145e0e49d808ad21d01d07dd799a75bd1b472788a70000030101003a003701000001003097c8d8102d216818c693dc46614ce9242b8e54e05a8ff1f520a3694b9481091d92906b13b9b2762b127ee4f07e91119e000010030102003a00370200030100308949c96dda849268044e176dbdba458fb5deac81e9918793bdb837f5afee0c2496a5930d46d1fe37ce536cbef8e95bb40000110120399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f807f030100000b0008000000000000000c0004010100050201010100a9403aa408af35d267980dfff1706d70a59b6dba867d0b568ca8c5b77560d67a100276cbfe822d7b9f6863f9a06b668097458e123ff385e31c29d830d03f1148973a100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100003a0037000000010030b79d4caa865f84207124c3d304430372f39d7c18a237df3a71e3c4fb7ba9ab9816439a809beb8606c3bb52d53a5364590000030101001e001b0100030200146406a5082b231340726d4cd0de2452bc73a33003000010030102001e001b0200010300144ac7b42f524e1d1b22098f85adfca752600ef9a000001101203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a27f030100000b000800000000000000100004010100050201010100d651221796b5206a5b9678a4d9995d519d8b9e75e87d85e57effb91f82a23e8d1002bcf84a882c0f72dd0d520a6954b3e1887fa55b7dc67635b44516856b31fd20a8100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100001e001b0000010200144463a1a994d5040e69c090b6985d7af295bfd11a0000030101003a0037010002010030973988b291fd1bca86d906723e335bdf13d3ebbadfea31dd164b3c672c16da72af8e6edfc0bac44b92b8c536d708dc33000010030102002b00280200030000210360da79c58995e4ec88512af9a4440ca4f2d7bfe84240e17effc4dd8ce94033a200001101207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e517f030100000b000800000000000000580004010100050201010100d95ff983db933edc675487a6f4e388fcf2db59313aeab5f45991a7f2471774471002355f98c38fd87ca5775e5e451243eb11300ed91fc950ea204c0a74b9a1991a25100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100003a0037000003010030b3423844bae8a591bbfb437b55566b5d61e54ee64f93351b0a3b9d4b731445d25ce367f7aedfcb32bd3cd14308a54cf50000030101003a0037010001010030a154c19082ac6b5fec72b81f6488550fec7149d52f66b4463915a61179c4f1f8507d366614b454dabf2c942235caad01000010030102001e001b0200030300140a8c14745c982f9fdc43aa985c02b1e5bff6c403000011012097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef7f030100000b000800000000000000620004010100050201010100412c1e7de2394dcd009223eb8c3a24e34b93a7c48df0bb86499160a31ea9dbdb1002180590eec33397034675f379cf17f62c0e77d17724a03238dcd3f216a4bc9509100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100003a0037000002010030afa4370aa5a48ab2f3ab510ccaba3b6d8cf51752304507e6a341c4e4ff6aa7c07610a503b42f479834b032d25dd160590000030101002b002801000300002103a9584c4580d165d2744ba49a70472653915bfdbec4bef471e26ce4c1c9e6c6ab000010030102001e001b02000102001445d04558a26b8ca04b486957c8abf5abf24ec76f0000110120a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be407f030100000b0008000000000000005d0004010100050201010100f140186a6bd413a50814db484b00398c2e7e6da9fbe2cb536728e880deb7506010027767f75fded47f94a6f81c671d448beddb6c2727f1f209ba015bf8de7331c13c100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100002b002800000000002102eebd2f91818a234e1879f8a55652f1e52419ad168b8f27b91be6b79958f7a5510000030101002b00280100020000210214a91dfcb36718209a5ee79c290029b849f1ce2feef6585a3b3fa37d04fb62b7000010030102001e001b0200030200144ee490084160fc8b1e73361d5a4c055beee77d8c0000110120e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4337f030100000b0008000000000000004f0004010100050201010100eb90b3c6d9a547e3b8a1111f621e0dbe5bfc68a8196371d497cb2912fa809d001002ab80ce7b6ca4875dbc7dc1f0d902551628c97b2383c27d04538d46a97d3cad43100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100001e001b0000020300149a061f31734c5f5f0b119ab72d433c9af133d3a60000030101003a003701000101003096e1fc631934a14acd313ff28ca29c9e9b43181b8df29386702b1a2d65a7cc823683f5733e296fb40c73648bc9cbf625000010030102001e001b02000102001474f185aa527f31202442d208cdb2905fa71403290000110201609f06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3000b03fda4d93a40301700000095840c6be056ed3d199dedf5265a5d3dafd195aa4cb54ca26943f7e092a5f06904200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000b03fd62132d410718000000b9dec92595e5eabb6de045782827bd98b60b9252287eec0f8e3450ea7c59619b1004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000b03fd8e29761d5405000000380d1a8cb3511b3ecf770a1d81f40c293182d29cf0574962db50c4cfb626fdb711042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30000b03fd62b9bfe135190000002eefa752386580c31084b54f2119973ccef6ac92fc38607e8609e896c9994c3e100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80000b03fdd0a1b7eee2140000002271b648a8925b8c717543453a59a3a20a3c52ce9b3e5fc793983c64f9f6fea004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2000b03fd1cb12a5b261400000068f31829eaec02f7e5eddada129d4981a99bda0e5c0fd4eff3c23eafc2c79a021004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e51000b03fd586ba25d1f1a0000005e3b38a6d9bede250ed0b612d01915a78182ee18d819d07d43ae925728b42d2d11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000b03fd120b51f4ea10000000be380b13cfd7149332e5ac818ae84d31e4be119bc0ebd717475630f6f38b6e90100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40000b03fd505d6c926f0d0000009500204c698cc12fc96774a34f77415c37376ff17b492838e414d774b5b7bec10420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae433000b03fd1e078984690800000064d995f4b5b62c480a04f1b8fb4c7a30b607f12da4abc357993ee7505be19b26111111";
- char *pub_key_hash_one_hex = "1f0815269afc012de44260ceb28a4496d3184184";
- char *pub_key_hash_two_hex = "4463a1a994d5040e69c090b6985d7af295bfd11a";
- char *pub_key_hash_three_hex = "5e0e49d808ad21d01d07dd799a75bd1b472788a7";
-
- unsigned char *multiple_identity_proof_bin = hex2bin(multiple_identity_proof_hex);
- unsigned char *pub_key_hashes[3] = {
- hex2bin(pub_key_hash_one_hex),
- hex2bin(pub_key_hash_two_hex),
- hex2bin(pub_key_hash_three_hex),
- };
- MultipleIdentityIdVerificationResult *result = verify_identity_ids_by_public_key_hashes(multiple_identity_proof_bin, 6206, true, pub_key_hashes, 3);
- assert(result->is_valid);
- assert(result->map_size == 3);
-
- assert(result->public_key_hash_identity_id_map[0]->has_identity_id);
- assert(result->public_key_hash_identity_id_map[0]->id_size == 32);
- uint8_t expected_id_one[32] = {15, 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215, 241, 108, 23,
- 39, 205, 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203};
- assert(is_array_equal(expected_id_one, result->public_key_hash_identity_id_map[0]->identity_id, result->public_key_hash_identity_id_map[0]->id_size));
-
- assert(result->public_key_hash_identity_id_map[1]->has_identity_id);
- assert(result->public_key_hash_identity_id_map[1]->id_size == 32);
- uint8_t expected_id_two[32] = {62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22,
- 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162};
- assert(is_array_equal(expected_id_two, result->public_key_hash_identity_id_map[1]->identity_id, result->public_key_hash_identity_id_map[0]->id_size));
-
- assert(result->public_key_hash_identity_id_map[2]->has_identity_id);
- assert(result->public_key_hash_identity_id_map[2]->id_size == 32);
- uint8_t expected_id_three[32] = {53, 168, 221, 106, 101, 237, 66, 153, 18, 210, 219, 5, 68, 98, 199, 232, 192, 17,
- 150, 90, 167, 106, 118, 53, 106, 105, 180, 200, 129, 128, 140, 48,};
- assert(is_array_equal(expected_id_three, result->public_key_hash_identity_id_map[2]->identity_id, result->public_key_hash_identity_id_map[2]->id_size));
-}
-
-
-int main() {
- test_verify_full_identity_by_public_key_hash();
- test_verify_full_identities_by_public_key_hashes();
- test_verify_full_identity_by_identity_id();
- test_verify_identity_id_by_public_key_hash();
- test_verify_identity_balances_by_identity_ids();
- test_verify_identity_ids_by_public_key_hashes();
-
- printf("All assertions passed!!");
-}
diff --git a/packages/rs-drive-verify-c-binding/c/utils.c b/packages/rs-drive-verify-c-binding/c/utils.c
deleted file mode 100644
index db766ffb833..00000000000
--- a/packages/rs-drive-verify-c-binding/c/utils.c
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// Created by anton on 05.10.2021.
-//
-
-#include
-
-char *bin2hex(unsigned char *p, int len)
-{
- char *hex = malloc(((2*len) + 1));
- char *r = hex;
-
- while(len && p)
- {
- (*r) = ((*p) & 0xF0) >> 4;
- (*r) = ((*r) <= 9 ? '0' + (*r) : 'a' - 10 + (*r));
- r++;
- (*r) = ((*p) & 0x0F);
- (*r) = ((*r) <= 9 ? '0' + (*r) : 'a' - 10 + (*r));
- r++;
- p++;
- len--;
- }
- *r = '\0';
-
- return hex;
-}
-
-unsigned char *hex2bin(const char *str)
-{
- int len, h;
- unsigned char *result, *err, *p, c;
-
- err = malloc(1);
- *err = 0;
-
- if (!str)
- return err;
-
- if (!*str)
- return err;
-
- len = 0;
- p = (unsigned char*) str;
- while (*p++)
- len++;
-
- result = malloc((len/2)+1);
- h = !(len%2) * 4;
- p = result;
- *p = 0;
-
- c = *str;
- while(c)
- {
- if(('0' <= c) && (c <= '9'))
- *p += (c - '0') << h;
- else if(('A' <= c) && (c <= 'F'))
- *p += (c - 'A' + 10) << h;
- else if(('a' <= c) && (c <= 'f'))
- *p += (c - 'a' + 10) << h;
- else
- return err;
-
- str++;
- c = *str;
-
- if (h)
- h = 0;
- else
- {
- h = 4;
- p++;
- *p = 0;
- }
- }
-
- return result;
-}
-
-bool is_array_equal(uint8_t a[], uint8_t b[], int size) {
- for (int i = 0; i < size; i++) {
- if (a[i] != b[i]) {
- return false;
- }
- }
- return true;
-}
diff --git a/packages/rs-drive-verify-c-binding/cbindgen.toml b/packages/rs-drive-verify-c-binding/cbindgen.toml
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/packages/rs-drive-verify-c-binding/src/lib.rs b/packages/rs-drive-verify-c-binding/src/lib.rs
deleted file mode 100644
index cb32ff6624b..00000000000
--- a/packages/rs-drive-verify-c-binding/src/lib.rs
+++ /dev/null
@@ -1,782 +0,0 @@
-mod types;
-mod util;
-
-use crate::types::{
- IdentityIdBalanceMap, IdentityIdVerificationResult, IdentityVerificationResult,
- MultipleIdentityBalanceVerificationResult, MultipleIdentityIdVerificationResult,
- MultipleIdentityVerificationResult, PublicKeyHash, PublicKeyHashIdentityIdMap,
- PublicKeyHashIdentityMap,
-};
-use crate::util::{build_c_identity_struct, extract_vector_from_pointer, vec_to_pointer};
-use drive::dpp::identity::state_transition::asset_lock_proof::AssetLockProof as DppAssetLockProof;
-use drive::drive::verify::identity::Identity as DppIdentity;
-use drive::drive::Drive;
-use std::collections::BTreeMap;
-use std::slice;
-
-#[no_mangle]
-pub unsafe extern "C" fn verify_full_identity_by_public_key_hash(
- proof_array: *const u8,
- proof_len: usize,
- public_key_hash: *const PublicKeyHash,
-) -> *const IdentityVerificationResult {
- let proof = unsafe { slice::from_raw_parts(proof_array, proof_len) };
- let public_key_hash = unsafe { std::ptr::read(public_key_hash) };
-
- let verification_result =
- Drive::verify_full_identity_by_public_key_hash(proof, public_key_hash);
-
- match verification_result {
- Ok((root_hash, maybe_identity)) => Box::into_raw(Box::from(IdentityVerificationResult {
- root_hash: Box::into_raw(Box::from(root_hash)),
- is_valid: true,
- has_identity: maybe_identity.is_some(),
- identity: build_c_identity_struct(maybe_identity),
- })),
- Err(..) => Box::into_raw(Box::from(IdentityVerificationResult::default())),
- }
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn verify_full_identities_by_public_key_hashes(
- proof_array: *const u8,
- proof_len: usize,
- public_key_hashes_c: *const *const u8,
- public_key_hash_count: usize,
-) -> *const MultipleIdentityVerificationResult {
- let proof = unsafe { slice::from_raw_parts(proof_array, proof_len) };
- let public_key_hashes =
- extract_vector_from_pointer::<[u8; 20]>(public_key_hashes_c, public_key_hash_count);
-
- let verification_result = Drive::verify_full_identities_by_public_key_hashes::<
- BTreeMap>,
- >(proof, &public_key_hashes);
-
- match verification_result {
- Ok((root_hash, hash_identity_map)) => {
- let mut pkhash_identity_map_as_vec: Vec<*const PublicKeyHashIdentityMap> = Vec::new();
- for (public_key_hash, maybe_identity) in hash_identity_map {
- pkhash_identity_map_as_vec.push(Box::into_raw(Box::from(
- PublicKeyHashIdentityMap {
- public_key_hash: vec_to_pointer(public_key_hash.to_vec()),
- public_key_hash_length: public_key_hash.len(),
- has_identity: maybe_identity.is_some(),
- identity: build_c_identity_struct(maybe_identity),
- },
- )));
- }
-
- Box::into_raw(Box::from(MultipleIdentityVerificationResult {
- is_valid: true,
- root_hash: Box::into_raw(Box::from(root_hash)),
- map_size: pkhash_identity_map_as_vec.len(),
- public_key_hash_identity_map: vec_to_pointer(pkhash_identity_map_as_vec),
- }))
- }
- Err(..) => Box::into_raw(Box::from(MultipleIdentityVerificationResult::default())),
- }
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn verify_full_identity_by_identity_id(
- proof_array: *const u8,
- proof_len: usize,
- is_proof_subset: bool,
- identity_id: *const [u8; 32],
-) -> *const IdentityVerificationResult {
- let proof = unsafe { slice::from_raw_parts(proof_array, proof_len) };
- let identity_id: [u8; 32] = unsafe { std::ptr::read(identity_id) };
- let verification_result =
- Drive::verify_full_identity_by_identity_id(proof, is_proof_subset, identity_id);
- match verification_result {
- Ok((root_hash, maybe_identity)) => Box::into_raw(Box::from(IdentityVerificationResult {
- root_hash: Box::into_raw(Box::from(root_hash)),
- is_valid: true,
- has_identity: maybe_identity.is_some(),
- identity: build_c_identity_struct(maybe_identity),
- })),
- Err(..) => Box::into_raw(Box::from(IdentityVerificationResult::default())),
- }
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn verify_identity_id_by_unique_public_key_hash(
- proof_array: *const u8,
- proof_len: usize,
- is_proof_subset: bool,
- public_key_hash: *const PublicKeyHash,
-) -> *const IdentityIdVerificationResult {
- let proof = unsafe { slice::from_raw_parts(proof_array, proof_len) };
- let public_key_hash = unsafe { std::ptr::read(public_key_hash) };
-
- let verification_result = Drive::verify_identity_id_by_unique_public_key_hash(
- proof,
- is_proof_subset,
- public_key_hash,
- );
-
- match verification_result {
- Ok((root_hash, maybe_identity_id)) => {
- Box::into_raw(Box::from(IdentityIdVerificationResult {
- root_hash: Box::into_raw(Box::from(root_hash)),
- is_valid: true,
- has_identity_id: maybe_identity_id.is_some(),
- identity_id: maybe_identity_id
- .map(|id| vec_to_pointer(id.to_vec()))
- .unwrap_or(std::ptr::null()),
- id_size: maybe_identity_id.map(|id| id.len()).unwrap_or(0),
- }))
- }
- Err(..) => Box::into_raw(Box::from(IdentityIdVerificationResult::default())),
- }
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn verify_identity_balances_by_identity_ids(
- proof_array: *const u8,
- proof_len: usize,
- is_proof_subset: bool,
- identity_ids: *const *const u8,
- id_size: usize,
-) -> *const MultipleIdentityBalanceVerificationResult {
- let proof = unsafe { slice::from_raw_parts(proof_array, proof_len) };
- let identity_ids = extract_vector_from_pointer::<[u8; 32]>(identity_ids, id_size);
-
- let verification_result = Drive::verify_identity_balances_for_identity_ids::<
- Vec<([u8; 32], Option)>,
- >(proof, is_proof_subset, identity_ids.as_slice());
-
- match verification_result {
- Ok((root_hash, identity_id_balance_map)) => {
- let mut identity_id_balance_map_as_vec: Vec<*const IdentityIdBalanceMap> = Vec::new();
- for (identity_id, maybe_balance) in identity_id_balance_map {
- identity_id_balance_map_as_vec.push(Box::into_raw(Box::from(
- IdentityIdBalanceMap {
- identity_id: vec_to_pointer(identity_id.to_vec()),
- id_size: 32,
- has_balance: maybe_balance.is_some(),
- balance: maybe_balance.unwrap_or(0),
- },
- )));
- }
- Box::into_raw(Box::from(MultipleIdentityBalanceVerificationResult {
- is_valid: true,
- root_hash: Box::into_raw(Box::from(root_hash)),
- map_size: identity_id_balance_map_as_vec.len(),
- identity_id_balance_map: vec_to_pointer(identity_id_balance_map_as_vec),
- }))
- }
- Err(..) => Box::into_raw(Box::from(
- MultipleIdentityBalanceVerificationResult::default(),
- )),
- }
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn verify_identity_ids_by_public_key_hashes(
- proof_array: *const u8,
- proof_len: usize,
- is_proof_subset: bool,
- public_key_hashes_c: *const *const u8,
- public_key_hash_count: usize,
-) -> *const MultipleIdentityIdVerificationResult {
- let proof = unsafe { slice::from_raw_parts(proof_array, proof_len) };
- let public_key_hashes =
- extract_vector_from_pointer::<[u8; 20]>(public_key_hashes_c, public_key_hash_count);
-
- let verification_result = Drive::verify_identity_ids_by_public_key_hashes::<
- Vec<(PublicKeyHash, Option<[u8; 32]>)>,
- >(proof, is_proof_subset, public_key_hashes.as_slice());
-
- match verification_result {
- Ok((root_hash, public_key_hash_identity_id_map)) => {
- let mut pkhash_identity_id_map_as_vec: Vec<*const PublicKeyHashIdentityIdMap> =
- Vec::new();
- for (public_key_hash, maybe_identity_id) in &public_key_hash_identity_id_map {
- pkhash_identity_id_map_as_vec.push(Box::into_raw(Box::from(
- PublicKeyHashIdentityIdMap {
- public_key_hash: vec_to_pointer(public_key_hash.to_vec()),
- public_key_hash_size: public_key_hash.len(),
- has_identity_id: maybe_identity_id.is_some(),
- identity_id: maybe_identity_id
- .map(|id| vec_to_pointer(id.to_vec()))
- .unwrap_or(std::ptr::null()),
- id_size: maybe_identity_id.map(|id| id.len()).unwrap_or(0),
- },
- )))
- }
- Box::into_raw(Box::from(MultipleIdentityIdVerificationResult {
- is_valid: true,
- root_hash: Box::into_raw(Box::from(root_hash)),
- map_size: public_key_hash_identity_id_map.len(),
- public_key_hash_identity_id_map: vec_to_pointer(pkhash_identity_id_map_as_vec),
- }))
- }
- Err(..) => Box::into_raw(Box::from(MultipleIdentityIdVerificationResult::default())),
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use drive::drive::verify::RootHash;
- use drive::drive::Drive;
- use std::collections::BTreeMap;
-
- fn single_identity_proof() -> &'static [u8] {
- &[
- 6, 0, 1, 0, 166, 3, 1, 74, 117, 207, 63, 83, 94, 129, 196, 104, 15, 129, 55, 162, 32,
- 141, 188, 178, 101, 47, 253, 126, 113, 91, 212, 41, 12, 197, 197, 96, 178, 204, 97, 2,
- 207, 190, 5, 53, 189, 45, 239, 229, 134, 184, 99, 185, 204, 185, 45, 13, 102, 251, 43,
- 129, 13, 115, 14, 123, 162, 203, 126, 47, 179, 2, 97, 59, 16, 4, 1, 24, 0, 24, 2, 1,
- 20, 174, 227, 2, 114, 8, 150, 187, 168, 55, 220, 243, 242, 214, 116, 245, 70, 253, 37,
- 73, 111, 0, 202, 53, 154, 161, 178, 3, 46, 49, 88, 174, 94, 92, 72, 159, 125, 70, 114,
- 47, 41, 100, 74, 21, 225, 207, 124, 57, 53, 179, 6, 6, 222, 246, 17, 4, 1, 32, 0, 36,
- 2, 1, 32, 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216,
- 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, 0, 160, 213, 164,
- 246, 65, 134, 99, 70, 133, 21, 205, 117, 24, 155, 227, 225, 3, 75, 191, 169, 161, 128,
- 126, 184, 29, 150, 75, 167, 68, 42, 11, 30, 16, 1, 105, 147, 24, 56, 86, 71, 7, 219,
- 241, 30, 144, 160, 89, 253, 125, 212, 83, 204, 126, 104, 173, 183, 210, 194, 55, 91,
- 174, 83, 86, 102, 100, 231, 17, 2, 86, 112, 117, 44, 195, 216, 131, 32, 10, 117, 152,
- 182, 92, 215, 75, 65, 167, 96, 204, 11, 229, 124, 218, 85, 54, 241, 95, 3, 200, 120,
- 58, 168, 16, 1, 195, 54, 53, 19, 110, 80, 46, 154, 197, 36, 75, 21, 162, 10, 117, 126,
- 7, 89, 206, 10, 144, 130, 60, 211, 127, 137, 63, 106, 73, 85, 109, 38, 4, 1, 96, 0, 45,
- 4, 1, 32, 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216,
- 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, 253, 28, 177, 42,
- 91, 38, 20, 0, 0, 0, 251, 189, 59, 224, 151, 231, 240, 125, 86, 25, 221, 105, 231, 118,
- 120, 132, 209, 22, 249, 90, 233, 165, 252, 219, 101, 30, 113, 114, 121, 2, 204, 30, 16,
- 1, 30, 12, 20, 67, 208, 146, 95, 120, 17, 50, 244, 197, 6, 116, 114, 2, 219, 255, 163,
- 202, 61, 237, 77, 35, 135, 212, 183, 228, 14, 3, 3, 227, 17, 17, 2, 1, 24, 127, 3, 20,
- 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, 152, 93, 122, 242, 149, 191,
- 209, 26, 0, 35, 0, 32, 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77,
- 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, 0, 2,
- 158, 111, 45, 51, 177, 88, 0, 48, 227, 182, 3, 14, 60, 37, 1, 106, 183, 37, 57, 101,
- 104, 37, 86, 5, 157, 204, 36, 59, 117, 199, 250, 109, 16, 1, 224, 159, 136, 205, 9,
- 204, 89, 93, 82, 72, 146, 179, 230, 66, 185, 57, 242, 130, 121, 149, 96, 87, 3, 196,
- 156, 134, 31, 101, 48, 1, 213, 225, 17, 1, 1, 32, 77, 4, 32, 62, 171, 130, 51, 233, 19,
- 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108,
- 99, 133, 34, 187, 243, 162, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 127, 174, 137, 184, 136,
- 178, 63, 79, 189, 174, 210, 251, 153, 10, 31, 66, 114, 122, 239, 91, 210, 168, 185, 31,
- 140, 185, 112, 87, 9, 9, 171, 57, 1, 32, 62, 171, 130, 51, 233, 19, 45, 191, 194, 183,
- 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187,
- 243, 162, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 1, 1, 0, 5, 2, 1,
- 1, 1, 0, 214, 81, 34, 23, 150, 181, 32, 106, 91, 150, 120, 164, 217, 153, 93, 81, 157,
- 139, 158, 117, 232, 125, 133, 229, 126, 255, 185, 31, 130, 162, 62, 141, 16, 2, 188,
- 248, 74, 136, 44, 15, 114, 221, 13, 82, 10, 105, 84, 179, 225, 136, 127, 165, 91, 125,
- 198, 118, 53, 180, 69, 22, 133, 107, 49, 253, 32, 168, 16, 1, 70, 25, 123, 162, 209,
- 216, 154, 230, 95, 14, 56, 180, 32, 113, 102, 210, 182, 213, 32, 20, 204, 112, 76, 86,
- 112, 130, 191, 29, 189, 101, 249, 223, 17, 2, 1, 1, 148, 1, 3, 1, 0, 0, 30, 0, 27, 0,
- 0, 1, 2, 0, 20, 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, 152, 93, 122,
- 242, 149, 191, 209, 26, 0, 0, 3, 1, 1, 0, 58, 0, 55, 1, 0, 2, 1, 0, 48, 151, 57, 136,
- 178, 145, 253, 27, 202, 134, 217, 6, 114, 62, 51, 91, 223, 19, 211, 235, 186, 223, 234,
- 49, 221, 22, 75, 60, 103, 44, 22, 218, 114, 175, 142, 110, 223, 192, 186, 196, 75, 146,
- 184, 197, 54, 215, 8, 220, 51, 0, 0, 16, 3, 1, 2, 0, 43, 0, 40, 2, 0, 3, 0, 0, 33, 3,
- 96, 218, 121, 197, 137, 149, 228, 236, 136, 81, 42, 249, 164, 68, 12, 164, 242, 215,
- 191, 232, 66, 64, 225, 126, 255, 196, 221, 140, 233, 64, 51, 162, 0, 0, 17, 2, 1, 96,
- 79, 4, 32, 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216,
- 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, 0, 11, 3, 253, 28,
- 177, 42, 91, 38, 20, 0, 0, 0, 104, 243, 24, 41, 234, 236, 2, 247, 229, 237, 218, 218,
- 18, 157, 73, 129, 169, 155, 218, 14, 92, 15, 212, 239, 243, 194, 62, 175, 194, 199,
- 154, 2,
- ]
- }
-
- fn multiple_identity_proof() -> &'static [u8] {
- &[
- 6, 0, 1, 0, 166, 3, 1, 74, 117, 207, 63, 83, 94, 129, 196, 104, 15, 129, 55, 162, 32,
- 141, 188, 178, 101, 47, 253, 126, 113, 91, 212, 41, 12, 197, 197, 96, 178, 204, 97, 2,
- 207, 190, 5, 53, 189, 45, 239, 229, 134, 184, 99, 185, 204, 185, 45, 13, 102, 251, 43,
- 129, 13, 115, 14, 123, 162, 203, 126, 47, 179, 2, 97, 59, 16, 4, 1, 24, 0, 24, 2, 1,
- 20, 94, 14, 73, 216, 8, 173, 33, 208, 29, 7, 221, 121, 154, 117, 189, 27, 71, 39, 136,
- 167, 0, 140, 16, 170, 76, 29, 25, 226, 231, 228, 47, 224, 177, 167, 246, 217, 61, 76,
- 11, 105, 146, 239, 99, 234, 152, 92, 22, 68, 124, 173, 164, 98, 149, 17, 4, 1, 32, 0,
- 36, 2, 1, 32, 53, 168, 221, 106, 101, 237, 66, 153, 18, 210, 219, 5, 68, 98, 199, 232,
- 192, 17, 150, 90, 167, 106, 118, 53, 106, 105, 180, 200, 129, 128, 140, 48, 0, 186, 86,
- 207, 177, 216, 126, 244, 120, 87, 246, 177, 205, 127, 185, 24, 64, 111, 213, 15, 129,
- 150, 102, 25, 119, 125, 212, 193, 181, 149, 161, 162, 110, 16, 1, 105, 147, 24, 56, 86,
- 71, 7, 219, 241, 30, 144, 160, 89, 253, 125, 212, 83, 204, 126, 104, 173, 183, 210,
- 194, 55, 91, 174, 83, 86, 102, 100, 231, 17, 2, 86, 112, 117, 44, 195, 216, 131, 32,
- 10, 117, 152, 182, 92, 215, 75, 65, 167, 96, 204, 11, 229, 124, 218, 85, 54, 241, 95,
- 3, 200, 120, 58, 168, 16, 1, 195, 54, 53, 19, 110, 80, 46, 154, 197, 36, 75, 21, 162,
- 10, 117, 126, 7, 89, 206, 10, 144, 130, 60, 211, 127, 137, 63, 106, 73, 85, 109, 38, 4,
- 1, 96, 0, 45, 4, 1, 32, 53, 168, 221, 106, 101, 237, 66, 153, 18, 210, 219, 5, 68, 98,
- 199, 232, 192, 17, 150, 90, 167, 106, 118, 53, 106, 105, 180, 200, 129, 128, 140, 48,
- 253, 186, 253, 104, 51, 174, 183, 0, 0, 0, 18, 178, 127, 74, 10, 124, 253, 6, 227, 56,
- 123, 51, 165, 188, 166, 104, 41, 83, 81, 46, 33, 98, 26, 233, 207, 109, 99, 61, 144,
- 65, 119, 25, 16, 1, 30, 12, 20, 67, 208, 146, 95, 120, 17, 50, 244, 197, 6, 116, 114,
- 2, 219, 255, 163, 202, 61, 237, 77, 35, 135, 212, 183, 228, 14, 3, 3, 227, 17, 17, 2,
- 1, 24, 179, 8, 1, 50, 201, 211, 88, 68, 213, 206, 42, 142, 15, 55, 124, 238, 35, 193,
- 67, 165, 51, 150, 7, 61, 234, 134, 196, 148, 184, 107, 164, 196, 175, 11, 57, 3, 20,
- 31, 8, 21, 38, 154, 252, 1, 45, 228, 66, 96, 206, 178, 138, 68, 150, 211, 24, 65, 132,
- 0, 35, 0, 32, 15, 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215, 241,
- 108, 23, 39, 205, 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203, 0, 16, 1,
- 104, 87, 110, 36, 82, 30, 3, 186, 75, 98, 73, 18, 187, 7, 131, 55, 103, 200, 17, 2, 49,
- 11, 135, 216, 234, 28, 175, 39, 149, 198, 143, 146, 17, 2, 232, 183, 235, 55, 111, 15,
- 121, 147, 186, 223, 147, 151, 31, 105, 11, 232, 164, 143, 9, 219, 7, 17, 240, 82, 162,
- 237, 72, 71, 20, 151, 185, 208, 16, 3, 20, 68, 99, 161, 169, 148, 213, 4, 14, 105, 192,
- 144, 182, 152, 93, 122, 242, 149, 191, 209, 26, 0, 35, 0, 32, 62, 171, 130, 51, 233,
- 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35,
- 108, 99, 133, 34, 187, 243, 162, 0, 2, 37, 75, 240, 169, 144, 190, 183, 33, 194, 31,
- 33, 232, 219, 171, 80, 227, 60, 217, 207, 9, 97, 143, 194, 124, 159, 116, 80, 198, 115,
- 81, 106, 238, 16, 1, 198, 173, 254, 8, 24, 9, 33, 142, 224, 116, 97, 249, 95, 83, 206,
- 108, 228, 98, 236, 55, 159, 151, 167, 31, 27, 228, 15, 114, 24, 203, 80, 175, 17, 17,
- 3, 20, 94, 14, 73, 216, 8, 173, 33, 208, 29, 7, 221, 121, 154, 117, 189, 27, 71, 39,
- 136, 167, 0, 35, 0, 32, 53, 168, 221, 106, 101, 237, 66, 153, 18, 210, 219, 5, 68, 98,
- 199, 232, 192, 17, 150, 90, 167, 106, 118, 53, 106, 105, 180, 200, 129, 128, 140, 48,
- 0, 16, 1, 164, 179, 25, 152, 212, 124, 48, 227, 144, 244, 250, 86, 242, 143, 25, 198,
- 47, 17, 79, 23, 167, 4, 210, 156, 86, 226, 139, 111, 219, 71, 241, 1, 3, 20, 103, 137,
- 42, 243, 144, 205, 43, 118, 83, 169, 24, 199, 182, 146, 200, 91, 135, 180, 77, 50, 0,
- 35, 0, 32, 57, 148, 116, 246, 83, 186, 107, 123, 56, 57, 164, 62, 208, 250, 53, 255,
- 205, 221, 94, 250, 29, 14, 112, 130, 148, 27, 214, 36, 12, 33, 159, 128, 0, 16, 1, 235,
- 77, 169, 119, 51, 138, 61, 164, 32, 78, 170, 172, 12, 136, 86, 189, 253, 81, 217, 178,
- 92, 238, 240, 75, 64, 187, 56, 239, 247, 154, 177, 16, 17, 2, 31, 34, 16, 36, 41, 219,
- 225, 188, 12, 167, 20, 132, 123, 8, 24, 125, 154, 135, 76, 196, 51, 41, 170, 167, 150,
- 71, 251, 154, 160, 131, 77, 105, 16, 3, 20, 154, 6, 31, 49, 115, 76, 95, 95, 11, 17,
- 154, 183, 45, 67, 60, 154, 241, 51, 211, 166, 0, 35, 0, 32, 232, 241, 234, 234, 48, 58,
- 184, 92, 10, 32, 220, 110, 128, 186, 85, 30, 63, 171, 43, 133, 112, 35, 25, 161, 34,
- 229, 80, 168, 115, 74, 228, 51, 0, 2, 100, 76, 96, 30, 103, 105, 33, 136, 207, 90, 151,
- 92, 34, 7, 202, 186, 137, 157, 153, 241, 187, 212, 182, 46, 95, 232, 86, 133, 11, 157,
- 114, 134, 16, 3, 20, 165, 73, 33, 187, 41, 182, 126, 49, 137, 142, 254, 188, 41, 242,
- 65, 177, 174, 250, 77, 202, 0, 35, 0, 32, 127, 61, 253, 44, 203, 5, 79, 65, 14, 231,
- 126, 176, 46, 231, 180, 234, 150, 7, 149, 216, 151, 70, 205, 194, 38, 221, 216, 153,
- 230, 172, 78, 81, 0, 16, 2, 158, 111, 45, 51, 177, 88, 0, 48, 227, 182, 3, 14, 60, 37,
- 1, 106, 183, 37, 57, 101, 104, 37, 86, 5, 157, 204, 36, 59, 117, 199, 250, 109, 3, 20,
- 179, 191, 206, 71, 141, 233, 111, 227, 12, 211, 113, 59, 248, 140, 231, 114, 134, 135,
- 218, 138, 0, 35, 0, 32, 168, 155, 161, 167, 178, 189, 91, 153, 252, 27, 238, 224, 90,
- 202, 85, 135, 174, 60, 251, 70, 40, 210, 160, 53, 143, 32, 130, 82, 183, 232, 190, 64,
- 0, 17, 17, 17, 3, 20, 187, 61, 240, 37, 227, 47, 217, 13, 31, 238, 231, 220, 164, 184,
- 51, 33, 198, 131, 41, 45, 0, 35, 0, 32, 3, 193, 33, 26, 169, 210, 98, 57, 198, 220,
- 161, 230, 203, 29, 187, 130, 102, 254, 43, 149, 0, 248, 105, 156, 132, 170, 144, 214,
- 35, 247, 177, 211, 0, 16, 1, 238, 8, 71, 128, 91, 20, 91, 95, 181, 0, 177, 57, 254, 18,
- 118, 126, 230, 129, 252, 49, 10, 33, 214, 233, 129, 70, 25, 223, 81, 135, 71, 8, 2,
- 160, 222, 53, 47, 230, 118, 125, 167, 191, 76, 51, 186, 125, 45, 168, 219, 4, 64, 69,
- 120, 53, 211, 194, 153, 36, 115, 33, 14, 2, 182, 49, 44, 16, 1, 224, 159, 136, 205, 9,
- 204, 89, 93, 82, 72, 146, 179, 230, 66, 185, 57, 242, 130, 121, 149, 96, 87, 3, 196,
- 156, 134, 31, 101, 48, 1, 213, 225, 2, 154, 86, 60, 152, 61, 32, 37, 32, 193, 169, 79,
- 76, 107, 169, 151, 80, 55, 52, 80, 170, 249, 220, 178, 166, 46, 245, 14, 152, 119, 100,
- 96, 67, 16, 3, 20, 237, 115, 138, 170, 221, 117, 209, 103, 127, 239, 236, 202, 221, 3,
- 63, 18, 108, 254, 231, 106, 0, 35, 0, 32, 151, 172, 124, 81, 243, 147, 225, 5, 188,
- 204, 9, 152, 150, 127, 129, 13, 246, 19, 141, 93, 239, 8, 214, 194, 123, 127, 177, 23,
- 144, 211, 189, 239, 0, 3, 20, 251, 217, 218, 165, 153, 61, 229, 106, 46, 67, 70, 183,
- 199, 47, 245, 88, 94, 255, 250, 171, 0, 35, 0, 32, 27, 36, 15, 203, 78, 99, 46, 120,
- 86, 191, 245, 139, 120, 77, 206, 188, 25, 57, 140, 115, 78, 198, 0, 196, 101, 253, 233,
- 90, 35, 102, 219, 235, 0, 16, 17, 17, 17, 17, 1, 1, 32, 139, 6, 4, 32, 3, 193, 33, 26,
- 169, 210, 98, 57, 198, 220, 161, 230, 203, 29, 187, 130, 102, 254, 43, 149, 0, 248,
- 105, 156, 132, 170, 144, 214, 35, 247, 177, 211, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 108,
- 75, 252, 242, 35, 205, 79, 229, 193, 202, 200, 46, 26, 158, 44, 115, 235, 14, 127, 52,
- 206, 186, 189, 215, 99, 14, 36, 203, 25, 47, 151, 88, 4, 32, 15, 126, 159, 152, 150,
- 254, 206, 186, 180, 193, 157, 65, 233, 215, 241, 108, 23, 39, 205, 99, 217, 219, 86,
- 244, 213, 176, 67, 34, 242, 146, 86, 203, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 128, 218,
- 98, 172, 184, 196, 159, 144, 29, 107, 248, 74, 42, 42, 241, 84, 49, 230, 158, 41, 6,
- 154, 191, 141, 2, 242, 193, 19, 198, 9, 155, 166, 16, 4, 32, 27, 36, 15, 203, 78, 99,
- 46, 120, 86, 191, 245, 139, 120, 77, 206, 188, 25, 57, 140, 115, 78, 198, 0, 196, 101,
- 253, 233, 90, 35, 102, 219, 235, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 81, 162, 48, 73, 239,
- 188, 222, 58, 14, 156, 133, 234, 122, 240, 90, 40, 212, 222, 49, 249, 10, 228, 74, 7,
- 197, 250, 24, 9, 1, 40, 35, 112, 17, 4, 32, 53, 168, 221, 106, 101, 237, 66, 153, 18,
- 210, 219, 5, 68, 98, 199, 232, 192, 17, 150, 90, 167, 106, 118, 53, 106, 105, 180, 200,
- 129, 128, 140, 48, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 42, 57, 7, 97, 185, 151, 137, 122,
- 254, 81, 84, 12, 57, 223, 235, 92, 120, 208, 7, 129, 165, 71, 210, 184, 59, 30, 114,
- 37, 152, 148, 222, 165, 16, 4, 32, 57, 148, 116, 246, 83, 186, 107, 123, 56, 57, 164,
- 62, 208, 250, 53, 255, 205, 221, 94, 250, 29, 14, 112, 130, 148, 27, 214, 36, 12, 33,
- 159, 128, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 179, 242, 143, 156, 194, 109, 249, 14, 164,
- 158, 19, 227, 205, 151, 192, 29, 119, 46, 157, 102, 9, 69, 62, 145, 212, 54, 158, 247,
- 142, 56, 128, 160, 4, 32, 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182,
- 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, 0,
- 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 127, 174, 137, 184, 136, 178, 63, 79, 189, 174, 210, 251,
- 153, 10, 31, 66, 114, 122, 239, 91, 210, 168, 185, 31, 140, 185, 112, 87, 9, 9, 171,
- 57, 16, 4, 32, 127, 61, 253, 44, 203, 5, 79, 65, 14, 231, 126, 176, 46, 231, 180, 234,
- 150, 7, 149, 216, 151, 70, 205, 194, 38, 221, 216, 153, 230, 172, 78, 81, 0, 9, 2, 1,
- 1, 2, 1, 3, 0, 0, 0, 29, 100, 163, 249, 39, 11, 248, 184, 16, 67, 5, 186, 118, 130,
- 148, 114, 243, 170, 194, 182, 255, 242, 11, 152, 172, 16, 54, 30, 197, 71, 63, 187, 17,
- 4, 32, 151, 172, 124, 81, 243, 147, 225, 5, 188, 204, 9, 152, 150, 127, 129, 13, 246,
- 19, 141, 93, 239, 8, 214, 194, 123, 127, 177, 23, 144, 211, 189, 239, 0, 9, 2, 1, 1, 2,
- 1, 3, 0, 0, 0, 173, 183, 101, 112, 214, 79, 137, 101, 6, 134, 223, 88, 25, 65, 78, 94,
- 66, 207, 126, 237, 171, 36, 96, 90, 166, 60, 75, 142, 38, 233, 14, 218, 16, 4, 32, 168,
- 155, 161, 167, 178, 189, 91, 153, 252, 27, 238, 224, 90, 202, 85, 135, 174, 60, 251,
- 70, 40, 210, 160, 53, 143, 32, 130, 82, 183, 232, 190, 64, 0, 9, 2, 1, 1, 2, 1, 3, 0,
- 0, 0, 165, 168, 83, 4, 22, 217, 70, 37, 33, 182, 253, 147, 39, 35, 216, 151, 22, 132,
- 180, 98, 14, 66, 84, 202, 240, 156, 117, 40, 158, 14, 100, 112, 4, 32, 232, 241, 234,
- 234, 48, 58, 184, 92, 10, 32, 220, 110, 128, 186, 85, 30, 63, 171, 43, 133, 112, 35,
- 25, 161, 34, 229, 80, 168, 115, 74, 228, 51, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 250, 29,
- 144, 127, 150, 124, 72, 41, 42, 90, 243, 212, 195, 170, 212, 53, 194, 238, 146, 55, 17,
- 150, 20, 214, 18, 174, 227, 180, 245, 46, 54, 20, 17, 17, 17, 1, 32, 3, 193, 33, 26,
- 169, 210, 98, 57, 198, 220, 161, 230, 203, 29, 187, 130, 102, 254, 43, 149, 0, 248,
- 105, 156, 132, 170, 144, 214, 35, 247, 177, 211, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, 0,
- 0, 0, 0, 61, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 114, 204, 69, 18, 112, 198, 19, 132, 211,
- 88, 247, 212, 17, 53, 183, 135, 136, 1, 24, 48, 48, 26, 105, 123, 151, 163, 113, 76,
- 32, 58, 54, 220, 16, 2, 20, 16, 91, 223, 25, 20, 145, 182, 114, 73, 211, 33, 243, 217,
- 190, 189, 248, 44, 154, 51, 149, 254, 243, 54, 198, 11, 55, 1, 175, 5, 147, 231, 16, 1,
- 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113, 102, 210, 182, 213, 32,
- 20, 204, 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223, 17, 2, 1, 1, 163, 1, 3, 1,
- 0, 0, 30, 0, 27, 0, 0, 2, 3, 0, 20, 187, 61, 240, 37, 227, 47, 217, 13, 31, 238, 231,
- 220, 164, 184, 51, 33, 198, 131, 41, 45, 0, 0, 3, 1, 1, 0, 58, 0, 55, 1, 0, 1, 1, 0,
- 48, 165, 253, 2, 201, 109, 95, 96, 235, 84, 177, 91, 4, 58, 132, 237, 128, 160, 175,
- 128, 78, 255, 74, 43, 254, 161, 252, 159, 237, 50, 50, 50, 199, 171, 18, 7, 35, 104, 9,
- 126, 85, 100, 57, 208, 138, 160, 166, 134, 108, 0, 0, 16, 3, 1, 2, 0, 58, 0, 55, 2, 0,
- 0, 1, 0, 48, 133, 255, 0, 230, 51, 147, 103, 211, 227, 30, 39, 203, 195, 60, 19, 195,
- 205, 12, 110, 151, 58, 91, 144, 46, 118, 102, 141, 122, 109, 175, 131, 193, 41, 37,
- 124, 199, 249, 204, 53, 225, 192, 104, 154, 109, 240, 58, 137, 29, 0, 0, 17, 1, 32, 15,
- 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215, 241, 108, 23, 39, 205,
- 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203, 127, 3, 1, 0, 0, 11, 0, 8,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 120, 58, 98, 103, 109, 191,
- 253, 1, 47, 147, 67, 239, 10, 247, 28, 27, 128, 12, 218, 25, 128, 22, 137, 223, 183,
- 226, 55, 44, 204, 195, 237, 157, 16, 2, 127, 14, 148, 229, 76, 99, 255, 220, 211, 211,
- 217, 1, 122, 99, 232, 47, 153, 132, 173, 229, 196, 250, 165, 157, 36, 121, 193, 16, 7,
- 147, 37, 36, 16, 1, 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113,
- 102, 210, 182, 213, 32, 20, 204, 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223,
- 17, 2, 1, 1, 120, 3, 1, 0, 0, 43, 0, 40, 0, 0, 2, 0, 0, 33, 3, 254, 101, 252, 220, 254,
- 36, 45, 194, 228, 61, 101, 66, 116, 236, 156, 225, 187, 188, 157, 213, 161, 200, 137,
- 69, 238, 239, 24, 204, 147, 21, 31, 127, 0, 0, 3, 1, 1, 0, 30, 0, 27, 1, 0, 1, 3, 0,
- 20, 201, 79, 70, 207, 56, 184, 56, 98, 153, 15, 120, 44, 132, 172, 188, 23, 141, 123,
- 2, 218, 0, 0, 16, 3, 1, 2, 0, 30, 0, 27, 2, 0, 2, 3, 0, 20, 38, 211, 135, 217, 136, 72,
- 98, 249, 97, 96, 221, 89, 202, 89, 107, 220, 232, 45, 167, 70, 0, 0, 17, 1, 32, 27, 36,
- 15, 203, 78, 99, 46, 120, 86, 191, 245, 139, 120, 77, 206, 188, 25, 57, 140, 115, 78,
- 198, 0, 196, 101, 253, 233, 90, 35, 102, 219, 235, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0,
- 0, 0, 0, 0, 96, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 202, 58, 16, 234, 179, 184, 137, 70,
- 91, 186, 81, 188, 83, 84, 19, 26, 238, 16, 68, 229, 16, 217, 237, 74, 112, 104, 209,
- 24, 28, 125, 191, 205, 16, 2, 150, 38, 236, 43, 78, 136, 97, 198, 117, 178, 11, 196,
- 69, 99, 51, 216, 196, 31, 208, 192, 185, 201, 240, 183, 128, 71, 198, 99, 78, 186, 184,
- 239, 16, 1, 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113, 102, 210,
- 182, 213, 32, 20, 204, 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223, 17, 2, 1, 1,
- 133, 1, 3, 1, 0, 0, 30, 0, 27, 0, 0, 3, 2, 0, 20, 251, 217, 218, 165, 153, 61, 229,
- 106, 46, 67, 70, 183, 199, 47, 245, 88, 94, 255, 250, 171, 0, 0, 3, 1, 1, 0, 43, 0, 40,
- 1, 0, 3, 0, 0, 33, 3, 253, 201, 64, 62, 182, 240, 5, 219, 112, 14, 120, 65, 98, 127,
- 79, 146, 231, 198, 93, 22, 115, 132, 205, 87, 164, 244, 228, 101, 131, 194, 26, 254, 0,
- 0, 16, 3, 1, 2, 0, 43, 0, 40, 2, 0, 0, 0, 0, 33, 3, 112, 52, 70, 247, 124, 141, 177,
- 251, 172, 111, 52, 34, 200, 224, 69, 9, 138, 219, 102, 44, 11, 98, 10, 21, 184, 196,
- 217, 236, 210, 163, 222, 250, 0, 0, 17, 1, 32, 53, 168, 221, 106, 101, 237, 66, 153,
- 18, 210, 219, 5, 68, 98, 199, 232, 192, 17, 150, 90, 167, 106, 118, 53, 106, 105, 180,
- 200, 129, 128, 140, 48, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, 0, 0, 0, 0, 66, 0, 4, 1, 1,
- 0, 5, 2, 1, 1, 1, 0, 215, 243, 151, 168, 22, 242, 63, 50, 233, 166, 205, 42, 181, 176,
- 61, 91, 109, 48, 116, 44, 240, 181, 133, 23, 242, 118, 217, 247, 92, 28, 77, 97, 16, 2,
- 191, 213, 104, 106, 224, 210, 167, 104, 76, 47, 110, 211, 167, 65, 154, 67, 106, 83,
- 137, 175, 201, 168, 74, 27, 178, 42, 29, 236, 223, 167, 98, 93, 16, 1, 70, 25, 123,
- 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113, 102, 210, 182, 213, 32, 20, 204,
- 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223, 17, 2, 1, 1, 163, 1, 3, 1, 0, 0,
- 30, 0, 27, 0, 0, 2, 3, 0, 20, 94, 14, 73, 216, 8, 173, 33, 208, 29, 7, 221, 121, 154,
- 117, 189, 27, 71, 39, 136, 167, 0, 0, 3, 1, 1, 0, 58, 0, 55, 1, 0, 0, 1, 0, 48, 151,
- 200, 216, 16, 45, 33, 104, 24, 198, 147, 220, 70, 97, 76, 233, 36, 43, 142, 84, 224,
- 90, 143, 241, 245, 32, 163, 105, 75, 148, 129, 9, 29, 146, 144, 107, 19, 185, 178, 118,
- 43, 18, 126, 228, 240, 126, 145, 17, 158, 0, 0, 16, 3, 1, 2, 0, 58, 0, 55, 2, 0, 3, 1,
- 0, 48, 137, 73, 201, 109, 218, 132, 146, 104, 4, 78, 23, 109, 189, 186, 69, 143, 181,
- 222, 172, 129, 233, 145, 135, 147, 189, 184, 55, 245, 175, 238, 12, 36, 150, 165, 147,
- 13, 70, 209, 254, 55, 206, 83, 108, 190, 248, 233, 91, 180, 0, 0, 17, 1, 32, 57, 148,
- 116, 246, 83, 186, 107, 123, 56, 57, 164, 62, 208, 250, 53, 255, 205, 221, 94, 250, 29,
- 14, 112, 130, 148, 27, 214, 36, 12, 33, 159, 128, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0,
- 0, 0, 0, 0, 12, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 169, 64, 58, 164, 8, 175, 53, 210,
- 103, 152, 13, 255, 241, 112, 109, 112, 165, 155, 109, 186, 134, 125, 11, 86, 140, 168,
- 197, 183, 117, 96, 214, 122, 16, 2, 118, 203, 254, 130, 45, 123, 159, 104, 99, 249,
- 160, 107, 102, 128, 151, 69, 142, 18, 63, 243, 133, 227, 28, 41, 216, 48, 208, 63, 17,
- 72, 151, 58, 16, 1, 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113,
- 102, 210, 182, 213, 32, 20, 204, 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223,
- 17, 2, 1, 1, 135, 1, 3, 1, 0, 0, 58, 0, 55, 0, 0, 0, 1, 0, 48, 183, 157, 76, 170, 134,
- 95, 132, 32, 113, 36, 195, 211, 4, 67, 3, 114, 243, 157, 124, 24, 162, 55, 223, 58,
- 113, 227, 196, 251, 123, 169, 171, 152, 22, 67, 154, 128, 155, 235, 134, 6, 195, 187,
- 82, 213, 58, 83, 100, 89, 0, 0, 3, 1, 1, 0, 30, 0, 27, 1, 0, 3, 2, 0, 20, 100, 6, 165,
- 8, 43, 35, 19, 64, 114, 109, 76, 208, 222, 36, 82, 188, 115, 163, 48, 3, 0, 0, 16, 3,
- 1, 2, 0, 30, 0, 27, 2, 0, 1, 3, 0, 20, 74, 199, 180, 47, 82, 78, 29, 27, 34, 9, 143,
- 133, 173, 252, 167, 82, 96, 14, 249, 160, 0, 0, 17, 1, 32, 62, 171, 130, 51, 233, 19,
- 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108,
- 99, 133, 34, 187, 243, 162, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4,
- 1, 1, 0, 5, 2, 1, 1, 1, 0, 214, 81, 34, 23, 150, 181, 32, 106, 91, 150, 120, 164, 217,
- 153, 93, 81, 157, 139, 158, 117, 232, 125, 133, 229, 126, 255, 185, 31, 130, 162, 62,
- 141, 16, 2, 188, 248, 74, 136, 44, 15, 114, 221, 13, 82, 10, 105, 84, 179, 225, 136,
- 127, 165, 91, 125, 198, 118, 53, 180, 69, 22, 133, 107, 49, 253, 32, 168, 16, 1, 70,
- 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113, 102, 210, 182, 213, 32, 20,
- 204, 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223, 17, 2, 1, 1, 148, 1, 3, 1, 0,
- 0, 30, 0, 27, 0, 0, 1, 2, 0, 20, 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182,
- 152, 93, 122, 242, 149, 191, 209, 26, 0, 0, 3, 1, 1, 0, 58, 0, 55, 1, 0, 2, 1, 0, 48,
- 151, 57, 136, 178, 145, 253, 27, 202, 134, 217, 6, 114, 62, 51, 91, 223, 19, 211, 235,
- 186, 223, 234, 49, 221, 22, 75, 60, 103, 44, 22, 218, 114, 175, 142, 110, 223, 192,
- 186, 196, 75, 146, 184, 197, 54, 215, 8, 220, 51, 0, 0, 16, 3, 1, 2, 0, 43, 0, 40, 2,
- 0, 3, 0, 0, 33, 3, 96, 218, 121, 197, 137, 149, 228, 236, 136, 81, 42, 249, 164, 68,
- 12, 164, 242, 215, 191, 232, 66, 64, 225, 126, 255, 196, 221, 140, 233, 64, 51, 162, 0,
- 0, 17, 1, 32, 127, 61, 253, 44, 203, 5, 79, 65, 14, 231, 126, 176, 46, 231, 180, 234,
- 150, 7, 149, 216, 151, 70, 205, 194, 38, 221, 216, 153, 230, 172, 78, 81, 127, 3, 1, 0,
- 0, 11, 0, 8, 0, 0, 0, 0, 0, 0, 0, 88, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 217, 95, 249,
- 131, 219, 147, 62, 220, 103, 84, 135, 166, 244, 227, 136, 252, 242, 219, 89, 49, 58,
- 234, 181, 244, 89, 145, 167, 242, 71, 23, 116, 71, 16, 2, 53, 95, 152, 195, 143, 216,
- 124, 165, 119, 94, 94, 69, 18, 67, 235, 17, 48, 14, 217, 31, 201, 80, 234, 32, 76, 10,
- 116, 185, 161, 153, 26, 37, 16, 1, 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56,
- 180, 32, 113, 102, 210, 182, 213, 32, 20, 204, 112, 76, 86, 112, 130, 191, 29, 189,
- 101, 249, 223, 17, 2, 1, 1, 163, 1, 3, 1, 0, 0, 58, 0, 55, 0, 0, 3, 1, 0, 48, 179, 66,
- 56, 68, 186, 232, 165, 145, 187, 251, 67, 123, 85, 86, 107, 93, 97, 229, 78, 230, 79,
- 147, 53, 27, 10, 59, 157, 75, 115, 20, 69, 210, 92, 227, 103, 247, 174, 223, 203, 50,
- 189, 60, 209, 67, 8, 165, 76, 245, 0, 0, 3, 1, 1, 0, 58, 0, 55, 1, 0, 1, 1, 0, 48, 161,
- 84, 193, 144, 130, 172, 107, 95, 236, 114, 184, 31, 100, 136, 85, 15, 236, 113, 73,
- 213, 47, 102, 180, 70, 57, 21, 166, 17, 121, 196, 241, 248, 80, 125, 54, 102, 20, 180,
- 84, 218, 191, 44, 148, 34, 53, 202, 173, 1, 0, 0, 16, 3, 1, 2, 0, 30, 0, 27, 2, 0, 3,
- 3, 0, 20, 10, 140, 20, 116, 92, 152, 47, 159, 220, 67, 170, 152, 92, 2, 177, 229, 191,
- 246, 196, 3, 0, 0, 17, 1, 32, 151, 172, 124, 81, 243, 147, 225, 5, 188, 204, 9, 152,
- 150, 127, 129, 13, 246, 19, 141, 93, 239, 8, 214, 194, 123, 127, 177, 23, 144, 211,
- 189, 239, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, 0, 0, 0, 0, 98, 0, 4, 1, 1, 0, 5, 2, 1,
- 1, 1, 0, 65, 44, 30, 125, 226, 57, 77, 205, 0, 146, 35, 235, 140, 58, 36, 227, 75, 147,
- 167, 196, 141, 240, 187, 134, 73, 145, 96, 163, 30, 169, 219, 219, 16, 2, 24, 5, 144,
- 238, 195, 51, 151, 3, 70, 117, 243, 121, 207, 23, 246, 44, 14, 119, 209, 119, 36, 160,
- 50, 56, 220, 211, 242, 22, 164, 188, 149, 9, 16, 1, 70, 25, 123, 162, 209, 216, 154,
- 230, 95, 14, 56, 180, 32, 113, 102, 210, 182, 213, 32, 20, 204, 112, 76, 86, 112, 130,
- 191, 29, 189, 101, 249, 223, 17, 2, 1, 1, 148, 1, 3, 1, 0, 0, 58, 0, 55, 0, 0, 2, 1, 0,
- 48, 175, 164, 55, 10, 165, 164, 138, 178, 243, 171, 81, 12, 202, 186, 59, 109, 140,
- 245, 23, 82, 48, 69, 7, 230, 163, 65, 196, 228, 255, 106, 167, 192, 118, 16, 165, 3,
- 180, 47, 71, 152, 52, 176, 50, 210, 93, 209, 96, 89, 0, 0, 3, 1, 1, 0, 43, 0, 40, 1, 0,
- 3, 0, 0, 33, 3, 169, 88, 76, 69, 128, 209, 101, 210, 116, 75, 164, 154, 112, 71, 38,
- 83, 145, 91, 253, 190, 196, 190, 244, 113, 226, 108, 228, 193, 201, 230, 198, 171, 0,
- 0, 16, 3, 1, 2, 0, 30, 0, 27, 2, 0, 1, 2, 0, 20, 69, 208, 69, 88, 162, 107, 140, 160,
- 75, 72, 105, 87, 200, 171, 245, 171, 242, 78, 199, 111, 0, 0, 17, 1, 32, 168, 155, 161,
- 167, 178, 189, 91, 153, 252, 27, 238, 224, 90, 202, 85, 135, 174, 60, 251, 70, 40, 210,
- 160, 53, 143, 32, 130, 82, 183, 232, 190, 64, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, 0, 0,
- 0, 0, 93, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 241, 64, 24, 106, 107, 212, 19, 165, 8, 20,
- 219, 72, 75, 0, 57, 140, 46, 126, 109, 169, 251, 226, 203, 83, 103, 40, 232, 128, 222,
- 183, 80, 96, 16, 2, 119, 103, 247, 95, 222, 212, 127, 148, 166, 248, 28, 103, 29, 68,
- 139, 237, 219, 108, 39, 39, 241, 242, 9, 186, 1, 91, 248, 222, 115, 49, 193, 60, 16, 1,
- 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113, 102, 210, 182, 213, 32,
- 20, 204, 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223, 17, 2, 1, 1, 133, 1, 3, 1,
- 0, 0, 43, 0, 40, 0, 0, 0, 0, 0, 33, 2, 238, 189, 47, 145, 129, 138, 35, 78, 24, 121,
- 248, 165, 86, 82, 241, 229, 36, 25, 173, 22, 139, 143, 39, 185, 27, 230, 183, 153, 88,
- 247, 165, 81, 0, 0, 3, 1, 1, 0, 43, 0, 40, 1, 0, 2, 0, 0, 33, 2, 20, 169, 29, 252, 179,
- 103, 24, 32, 154, 94, 231, 156, 41, 0, 41, 184, 73, 241, 206, 47, 238, 246, 88, 90, 59,
- 63, 163, 125, 4, 251, 98, 183, 0, 0, 16, 3, 1, 2, 0, 30, 0, 27, 2, 0, 3, 2, 0, 20, 78,
- 228, 144, 8, 65, 96, 252, 139, 30, 115, 54, 29, 90, 76, 5, 91, 238, 231, 125, 140, 0,
- 0, 17, 1, 32, 232, 241, 234, 234, 48, 58, 184, 92, 10, 32, 220, 110, 128, 186, 85, 30,
- 63, 171, 43, 133, 112, 35, 25, 161, 34, 229, 80, 168, 115, 74, 228, 51, 127, 3, 1, 0,
- 0, 11, 0, 8, 0, 0, 0, 0, 0, 0, 0, 79, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 235, 144, 179,
- 198, 217, 165, 71, 227, 184, 161, 17, 31, 98, 30, 13, 190, 91, 252, 104, 168, 25, 99,
- 113, 212, 151, 203, 41, 18, 250, 128, 157, 0, 16, 2, 171, 128, 206, 123, 108, 164, 135,
- 93, 188, 125, 193, 240, 217, 2, 85, 22, 40, 201, 123, 35, 131, 194, 125, 4, 83, 141,
- 70, 169, 125, 60, 173, 67, 16, 1, 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56,
- 180, 32, 113, 102, 210, 182, 213, 32, 20, 204, 112, 76, 86, 112, 130, 191, 29, 189,
- 101, 249, 223, 17, 2, 1, 1, 135, 1, 3, 1, 0, 0, 30, 0, 27, 0, 0, 2, 3, 0, 20, 154, 6,
- 31, 49, 115, 76, 95, 95, 11, 17, 154, 183, 45, 67, 60, 154, 241, 51, 211, 166, 0, 0, 3,
- 1, 1, 0, 58, 0, 55, 1, 0, 1, 1, 0, 48, 150, 225, 252, 99, 25, 52, 161, 74, 205, 49, 63,
- 242, 140, 162, 156, 158, 155, 67, 24, 27, 141, 242, 147, 134, 112, 43, 26, 45, 101,
- 167, 204, 130, 54, 131, 245, 115, 62, 41, 111, 180, 12, 115, 100, 139, 201, 203, 246,
- 37, 0, 0, 16, 3, 1, 2, 0, 30, 0, 27, 2, 0, 1, 2, 0, 20, 116, 241, 133, 170, 82, 127,
- 49, 32, 36, 66, 210, 8, 205, 178, 144, 95, 167, 20, 3, 41, 0, 0, 17, 2, 1, 96, 159, 6,
- 4, 32, 3, 193, 33, 26, 169, 210, 98, 57, 198, 220, 161, 230, 203, 29, 187, 130, 102,
- 254, 43, 149, 0, 248, 105, 156, 132, 170, 144, 214, 35, 247, 177, 211, 0, 11, 3, 253,
- 164, 217, 58, 64, 48, 23, 0, 0, 0, 149, 132, 12, 107, 224, 86, 237, 61, 25, 157, 237,
- 245, 38, 90, 93, 61, 175, 209, 149, 170, 76, 181, 76, 162, 105, 67, 247, 224, 146, 165,
- 240, 105, 4, 32, 15, 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215,
- 241, 108, 23, 39, 205, 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203, 0,
- 11, 3, 253, 98, 19, 45, 65, 7, 24, 0, 0, 0, 185, 222, 201, 37, 149, 229, 234, 187, 109,
- 224, 69, 120, 40, 39, 189, 152, 182, 11, 146, 82, 40, 126, 236, 15, 142, 52, 80, 234,
- 124, 89, 97, 155, 16, 4, 32, 27, 36, 15, 203, 78, 99, 46, 120, 86, 191, 245, 139, 120,
- 77, 206, 188, 25, 57, 140, 115, 78, 198, 0, 196, 101, 253, 233, 90, 35, 102, 219, 235,
- 0, 11, 3, 253, 142, 41, 118, 29, 84, 5, 0, 0, 0, 56, 13, 26, 140, 179, 81, 27, 62, 207,
- 119, 10, 29, 129, 244, 12, 41, 49, 130, 210, 156, 240, 87, 73, 98, 219, 80, 196, 207,
- 182, 38, 253, 183, 17, 4, 32, 53, 168, 221, 106, 101, 237, 66, 153, 18, 210, 219, 5,
- 68, 98, 199, 232, 192, 17, 150, 90, 167, 106, 118, 53, 106, 105, 180, 200, 129, 128,
- 140, 48, 0, 11, 3, 253, 98, 185, 191, 225, 53, 25, 0, 0, 0, 46, 239, 167, 82, 56, 101,
- 128, 195, 16, 132, 181, 79, 33, 25, 151, 60, 206, 246, 172, 146, 252, 56, 96, 126, 134,
- 9, 232, 150, 201, 153, 76, 62, 16, 4, 32, 57, 148, 116, 246, 83, 186, 107, 123, 56, 57,
- 164, 62, 208, 250, 53, 255, 205, 221, 94, 250, 29, 14, 112, 130, 148, 27, 214, 36, 12,
- 33, 159, 128, 0, 11, 3, 253, 208, 161, 183, 238, 226, 20, 0, 0, 0, 34, 113, 182, 72,
- 168, 146, 91, 140, 113, 117, 67, 69, 58, 89, 163, 162, 10, 60, 82, 206, 155, 62, 95,
- 199, 147, 152, 60, 100, 249, 246, 254, 160, 4, 32, 62, 171, 130, 51, 233, 19, 45, 191,
- 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133,
- 34, 187, 243, 162, 0, 11, 3, 253, 28, 177, 42, 91, 38, 20, 0, 0, 0, 104, 243, 24, 41,
- 234, 236, 2, 247, 229, 237, 218, 218, 18, 157, 73, 129, 169, 155, 218, 14, 92, 15, 212,
- 239, 243, 194, 62, 175, 194, 199, 154, 2, 16, 4, 32, 127, 61, 253, 44, 203, 5, 79, 65,
- 14, 231, 126, 176, 46, 231, 180, 234, 150, 7, 149, 216, 151, 70, 205, 194, 38, 221,
- 216, 153, 230, 172, 78, 81, 0, 11, 3, 253, 88, 107, 162, 93, 31, 26, 0, 0, 0, 94, 59,
- 56, 166, 217, 190, 222, 37, 14, 208, 182, 18, 208, 25, 21, 167, 129, 130, 238, 24, 216,
- 25, 208, 125, 67, 174, 146, 87, 40, 180, 45, 45, 17, 4, 32, 151, 172, 124, 81, 243,
- 147, 225, 5, 188, 204, 9, 152, 150, 127, 129, 13, 246, 19, 141, 93, 239, 8, 214, 194,
- 123, 127, 177, 23, 144, 211, 189, 239, 0, 11, 3, 253, 18, 11, 81, 244, 234, 16, 0, 0,
- 0, 190, 56, 11, 19, 207, 215, 20, 147, 50, 229, 172, 129, 138, 232, 77, 49, 228, 190,
- 17, 155, 192, 235, 215, 23, 71, 86, 48, 246, 243, 139, 110, 144, 16, 4, 32, 168, 155,
- 161, 167, 178, 189, 91, 153, 252, 27, 238, 224, 90, 202, 85, 135, 174, 60, 251, 70, 40,
- 210, 160, 53, 143, 32, 130, 82, 183, 232, 190, 64, 0, 11, 3, 253, 80, 93, 108, 146,
- 111, 13, 0, 0, 0, 149, 0, 32, 76, 105, 140, 193, 47, 201, 103, 116, 163, 79, 119, 65,
- 92, 55, 55, 111, 241, 123, 73, 40, 56, 228, 20, 215, 116, 181, 183, 190, 193, 4, 32,
- 232, 241, 234, 234, 48, 58, 184, 92, 10, 32, 220, 110, 128, 186, 85, 30, 63, 171, 43,
- 133, 112, 35, 25, 161, 34, 229, 80, 168, 115, 74, 228, 51, 0, 11, 3, 253, 30, 7, 137,
- 132, 105, 8, 0, 0, 0, 100, 217, 149, 244, 181, 182, 44, 72, 10, 4, 241, 184, 251, 76,
- 122, 48, 182, 7, 241, 45, 164, 171, 195, 87, 153, 62, 231, 80, 91, 225, 155, 38, 17,
- 17, 17,
- ]
- }
-
- #[test]
- fn test_verify_full_identity_by_public_key_hash() {
- let proof: &[u8] = single_identity_proof();
- let key_hash: PublicKeyHash = [
- 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, 152, 93, 122, 242, 149, 191,
- 209, 26,
- ];
- let (_root_hash, proved_identity) =
- Drive::verify_full_identity_by_public_key_hash(proof, key_hash).expect("should verify");
- // verify part of the identity, make sure it's the correct one
- assert!(proved_identity.is_some());
- let proved_identity = proved_identity.unwrap();
- assert_eq!(proved_identity.feature_version, 1);
- assert_eq!(proved_identity.public_keys().len(), 3);
- assert_eq!(proved_identity.balance(), 11077485418638);
- }
-
- #[test]
- fn multiple_identity_proofs() {
- let proof = multiple_identity_proof();
- let key_hashes: &[PublicKeyHash] = &[
- [
- 31, 8, 21, 38, 154, 252, 1, 45, 228, 66, 96, 206, 178, 138, 68, 150, 211, 24, 65,
- 132,
- ],
- [
- 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, 152, 93, 122, 242, 149, 191,
- 209, 26,
- ],
- [
- 94, 14, 73, 216, 8, 173, 33, 208, 29, 7, 221, 121, 154, 117, 189, 27, 71, 39, 136,
- 167,
- ],
- [
- 103, 137, 42, 243, 144, 205, 43, 118, 83, 169, 24, 199, 182, 146, 200, 91, 135,
- 180, 77, 50,
- ],
- [
- 154, 6, 31, 49, 115, 76, 95, 95, 11, 17, 154, 183, 45, 67, 60, 154, 241, 51, 211,
- 166,
- ],
- [
- 165, 73, 33, 187, 41, 182, 126, 49, 137, 142, 254, 188, 41, 242, 65, 177, 174, 250,
- 77, 202,
- ],
- [
- 179, 191, 206, 71, 141, 233, 111, 227, 12, 211, 113, 59, 248, 140, 231, 114, 134,
- 135, 218, 138,
- ],
- [
- 187, 61, 240, 37, 227, 47, 217, 13, 31, 238, 231, 220, 164, 184, 51, 33, 198, 131,
- 41, 45,
- ],
- [
- 237, 115, 138, 170, 221, 117, 209, 103, 127, 239, 236, 202, 221, 3, 63, 18, 108,
- 254, 231, 106,
- ],
- [
- 251, 217, 218, 165, 153, 61, 229, 106, 46, 67, 70, 183, 199, 47, 245, 88, 94, 255,
- 250, 171,
- ],
- ];
-
- let (_, proved_identities): ([u8; 32], BTreeMap>) =
- Drive::verify_full_identities_by_public_key_hashes(proof, key_hashes)
- .expect("expect that this be verified");
- assert_eq!(proved_identities.len(), 10);
- }
-
- #[test]
- fn verify_full_identity_by_identity_id() {
- let proof = single_identity_proof();
- let identity_id: [u8; 32] = [
- 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47,
- 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162,
- ];
- let (_root_hash, maybe_identity) =
- Drive::verify_full_identity_by_identity_id(proof, true, identity_id)
- .expect("verification failed");
- let identity = maybe_identity.expect("couldn't get identity");
- assert_eq!(identity.feature_version, 1);
- assert_eq!(identity.public_keys().len(), 3);
- assert_eq!(identity.balance(), 11077485418638);
- }
-
- #[test]
- fn verify_identity_id_by_unique_public_key_hash() {
- let proof = multiple_identity_proof();
- let public_key_hash: PublicKeyHash = [
- 31, 8, 21, 38, 154, 252, 1, 45, 228, 66, 96, 206, 178, 138, 68, 150, 211, 24, 65, 132,
- ];
- let (_root_hash, maybe_identity_id) =
- Drive::verify_identity_id_by_unique_public_key_hash(proof, true, public_key_hash)
- .expect("should verify");
- let expected_identity_id: [u8; 32] = [
- 15, 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215, 241, 108, 23, 39,
- 205, 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203,
- ];
- let actual_identity_id = maybe_identity_id.expect("should have identity id");
- assert_eq!(expected_identity_id, actual_identity_id);
- }
-
- #[ignore]
- #[test]
- fn verify_identity_balance_by_identity_id() {
- // TODO: given identity proof is a subset proof but this verify function expects non-subset proof
- let proof = single_identity_proof();
- let identity_id: [u8; 32] = [
- 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47,
- 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162,
- ];
- let (_root_hash, maybe_balance) =
- Drive::verify_identity_balance_for_identity_id(proof, identity_id, false)
- .expect("should verify");
- let actual_balance = maybe_balance.expect("should have balance");
- assert_eq!(actual_balance, 11077485418639);
- }
-
- #[test]
- fn verify_identity_balances_by_identity_ids() {
- let proof = multiple_identity_proof();
- let identity_ids: &[[u8; 32]] = &[
- [
- 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22,
- 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162,
- ],
- [
- 151, 172, 124, 81, 243, 147, 225, 5, 188, 204, 9, 152, 150, 127, 129, 13, 246, 19,
- 141, 93, 239, 8, 214, 194, 123, 127, 177, 23, 144, 211, 189, 239,
- ],
- ];
- let (_, balances): (RootHash, Vec<([u8; 32], Option)>) =
- Drive::verify_identity_balances_for_identity_ids(proof, true, identity_ids)
- .expect("should verify");
- assert_eq!(balances.len(), 2);
- assert_eq!(balances[0].1.unwrap(), 11077485418638);
- assert_eq!(balances[1].1.unwrap(), 9300653671817);
- }
-
- #[test]
- fn verify_identity_ids_by_public_key_hashes() {
- let proof = multiple_identity_proof();
- let public_key_hashes: &[PublicKeyHash] = &[
- [
- 31, 8, 21, 38, 154, 252, 1, 45, 228, 66, 96, 206, 178, 138, 68, 150, 211, 24, 65,
- 132,
- ],
- [
- 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, 152, 93, 122, 242, 149, 191,
- 209, 26,
- ],
- [
- 94, 14, 73, 216, 8, 173, 33, 208, 29, 7, 221, 121, 154, 117, 189, 27, 71, 39, 136,
- 167,
- ],
- ];
- let (_, ids): (RootHash, Vec<([u8; 20], Option<[u8; 32]>)>) =
- Drive::verify_identity_ids_by_public_key_hashes(proof, true, public_key_hashes)
- .expect("should verify");
- assert_eq!(ids.len(), 3);
- assert_eq!(
- ids[0].1.unwrap(),
- [
- 15, 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215, 241, 108, 23,
- 39, 205, 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203
- ]
- );
- assert_eq!(
- ids[1].1.unwrap(),
- [
- 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22,
- 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162,
- ]
- );
- assert_eq!(
- ids[2].1.unwrap(),
- [
- 53, 168, 221, 106, 101, 237, 66, 153, 18, 210, 219, 5, 68, 98, 199, 232, 192, 17,
- 150, 90, 167, 106, 118, 53, 106, 105, 180, 200, 129, 128, 140, 48,
- ]
- );
- }
-}
diff --git a/packages/rs-drive-verify-c-binding/src/types.rs b/packages/rs-drive-verify-c-binding/src/types.rs
deleted file mode 100644
index 66b42773b73..00000000000
--- a/packages/rs-drive-verify-c-binding/src/types.rs
+++ /dev/null
@@ -1,203 +0,0 @@
-/// Type alias for a public key hash
-pub(crate) type PublicKeyHash = [u8; 20];
-
-/// Represents proof verification result + full identity
-#[repr(C)]
-pub struct IdentityVerificationResult {
- pub is_valid: bool,
- pub root_hash: *const [u8; 32],
- pub has_identity: bool,
- pub identity: *const Identity,
-}
-
-impl Default for IdentityVerificationResult {
- fn default() -> Self {
- Self {
- is_valid: false,
- root_hash: std::ptr::null(),
- has_identity: false,
- identity: std::ptr::null(),
- }
- }
-}
-
-/// Represent proof verification result + multiple identities
-#[repr(C)]
-pub struct MultipleIdentityVerificationResult {
- pub is_valid: bool,
- pub root_hash: *const [u8; 32],
- pub public_key_hash_identity_map: *const *const PublicKeyHashIdentityMap,
- pub map_size: usize,
-}
-
-impl Default for MultipleIdentityVerificationResult {
- fn default() -> Self {
- Self {
- is_valid: false,
- root_hash: std::ptr::null(),
- public_key_hash_identity_map: std::ptr::null(),
- map_size: 0,
- }
- }
-}
-
-/// Maps a public key hash to an identity
-#[repr(C)]
-pub struct PublicKeyHashIdentityMap {
- pub public_key_hash: *const u8,
- pub public_key_hash_length: usize,
- pub has_identity: bool,
- pub identity: *const Identity,
-}
-
-/// Represents proof verification result + identity id result
-#[repr(C)]
-pub struct IdentityIdVerificationResult {
- pub is_valid: bool,
- pub root_hash: *const [u8; 32],
- pub has_identity_id: bool,
- pub identity_id: *const u8,
- pub id_size: usize,
-}
-
-impl Default for IdentityIdVerificationResult {
- fn default() -> Self {
- Self {
- is_valid: false,
- root_hash: std::ptr::null(),
- has_identity_id: false,
- identity_id: std::ptr::null(),
- id_size: 0,
- }
- }
-}
-
-/// Represent proof verification result + multiple identity balance result
-#[repr(C)]
-pub struct MultipleIdentityBalanceVerificationResult {
- pub is_valid: bool,
- pub root_hash: *const [u8; 32],
- pub identity_id_balance_map: *const *const IdentityIdBalanceMap,
- pub map_size: usize,
-}
-
-impl Default for MultipleIdentityBalanceVerificationResult {
- fn default() -> Self {
- Self {
- is_valid: true,
- root_hash: std::ptr::null(),
- identity_id_balance_map: std::ptr::null(),
- map_size: 0,
- }
- }
-}
-
-/// Maps from an identity id to an optional balance
-#[repr(C)]
-pub struct IdentityIdBalanceMap {
- pub identity_id: *const u8,
- pub id_size: usize,
- pub has_balance: bool,
- pub balance: u64,
-}
-
-/// Represents proof verification result + multiple identity id result
-#[repr(C)]
-pub struct MultipleIdentityIdVerificationResult {
- pub is_valid: bool,
- pub root_hash: *const [u8; 32],
- pub map_size: usize,
- pub public_key_hash_identity_id_map: *const *const PublicKeyHashIdentityIdMap,
-}
-
-impl Default for MultipleIdentityIdVerificationResult {
- fn default() -> Self {
- Self {
- is_valid: true,
- root_hash: std::ptr::null(),
- map_size: 0,
- public_key_hash_identity_id_map: std::ptr::null(),
- }
- }
-}
-
-/// Maps a public key hash to an identity id
-#[repr(C)]
-pub struct PublicKeyHashIdentityIdMap {
- pub public_key_hash: *const u8,
- pub public_key_hash_size: usize,
- pub has_identity_id: bool,
- pub identity_id: *const u8,
- pub id_size: usize,
-}
-
-/// Represents an identity
-#[repr(C)]
-pub struct Identity {
- pub protocol_version: u32,
- pub id: *const [u8; 32],
- pub public_keys_count: usize,
- pub public_keys: *const *const IdPublicKeyMap,
- pub balance: u64,
- pub revision: u64,
- pub has_asset_lock_proof: bool,
- pub asset_lock_proof: *const AssetLockProof,
- pub has_metadata: bool,
- pub meta_data: *const MetaData,
-}
-
-/// Maps a key id to a public key
-#[repr(C)]
-pub struct IdPublicKeyMap {
- pub key: u32,
- pub public_key: *const IdentityPublicKey,
-}
-
-/// Represents an identity public key
-#[repr(C)]
-pub struct IdentityPublicKey {
- pub id: u32,
-
- // AUTHENTICATION = 0,
- // ENCRYPTION = 1,
- // DECRYPTION = 2,
- // WITHDRAW = 3
- pub purpose: u8,
-
- // MASTER = 0,
- // CRITICAL = 1,
- // HIGH = 2,
- // MEDIUM = 3
- pub security_level: u8,
-
- // ECDSA_SECP256K1 = 0,
- // BLS312_381 = 1,
- // ECDSA_HASH160 = 2,
- // BIP13_SCRIPT_HASH = 3
- pub key_type: u8,
-
- pub read_only: bool,
- pub data_length: usize,
- pub data: *const u8,
- pub has_disabled_at: bool,
- pub disabled_at: u64,
-}
-
-/// Represents an asset lock proof
-// TODO: add the actual asset lock types
-#[repr(C)]
-pub struct AssetLockProof {
- pub is_instant: bool,
- // pub instant_asset_lock_proof: *const InstantAssetLocKProof,
- pub is_chain: bool,
- // pub chain_asset_lock_proof: *const ChainAssetLockProof,
-}
-
-/// Represents identity metat data
-#[repr(C)]
-pub struct MetaData {
- pub block_height: u64,
- pub core_chain_locked_height: u64,
- pub time_ms: u64,
- pub protocol_version: u32,
-}
diff --git a/packages/rs-drive-verify-c-binding/src/util.rs b/packages/rs-drive-verify-c-binding/src/util.rs
deleted file mode 100644
index e83ff3443c3..00000000000
--- a/packages/rs-drive-verify-c-binding/src/util.rs
+++ /dev/null
@@ -1,97 +0,0 @@
-use crate::types::{AssetLockProof, IdPublicKeyMap, Identity, IdentityPublicKey, MetaData};
-use crate::{DppAssetLockProof, DppIdentity};
-use std::{mem, slice};
-
-pub(crate) fn build_c_identity_struct(maybe_identity: Option) -> *mut Identity {
- maybe_identity
- .map(|identity| {
- Box::into_raw(Box::from(Identity {
- protocol_version: identity.feature_version,
- id: Box::into_raw(Box::from(identity.id().0 .0)),
- public_keys_count: identity.public_keys().len(),
- public_keys: build_c_public_keys_struct(&identity),
- balance: identity.balance,
- revision: identity.revision,
- has_asset_lock_proof: identity.asset_lock_proof.is_some(),
- asset_lock_proof: build_c_asset_lock_proof_struct(&identity),
- has_metadata: identity.metadata.is_some(),
- meta_data: build_c_metadata_struct(&identity),
- }))
- })
- .unwrap_or(std::ptr::null_mut())
-}
-
-pub(crate) fn build_c_public_keys_struct(identity: &DppIdentity) -> *const *const IdPublicKeyMap {
- let mut id_public_key_map_as_vec: Vec<*const IdPublicKeyMap> = vec![];
- for (key_id, identity_public_key) in identity.public_keys() {
- id_public_key_map_as_vec.push(Box::into_raw(Box::from(IdPublicKeyMap {
- key: *key_id,
- public_key: Box::into_raw(Box::from(IdentityPublicKey {
- id: identity_public_key.id,
- purpose: identity_public_key.purpose as u8,
- security_level: identity_public_key.security_level as u8,
- key_type: identity_public_key.key_type as u8,
- read_only: identity_public_key.read_only,
- data_length: identity_public_key.data.len(),
- data: vec_to_pointer(identity_public_key.data.to_vec()),
- has_disabled_at: identity_public_key.disabled_at.is_some(),
- disabled_at: identity_public_key.disabled_at.unwrap_or(0),
- })),
- })))
- }
- let pointer = id_public_key_map_as_vec.as_ptr();
- mem::forget(id_public_key_map_as_vec);
- pointer
-}
-
-pub(crate) fn build_c_asset_lock_proof_struct(identity: &DppIdentity) -> *const AssetLockProof {
- let asset_lock_proof = &identity.asset_lock_proof;
- if let Some(asset_lock_proof) = asset_lock_proof {
- // TODO: construct the actual asset lock proofs
- match asset_lock_proof {
- DppAssetLockProof::Instant(..) => Box::into_raw(Box::from(AssetLockProof {
- is_chain: false,
- is_instant: true,
- })),
- DppAssetLockProof::Chain(..) => Box::into_raw(Box::from(AssetLockProof {
- is_chain: true,
- is_instant: false,
- })),
- }
- } else {
- Box::into_raw(Box::from(AssetLockProof {
- is_chain: false,
- is_instant: false,
- }))
- }
-}
-
-pub(crate) fn build_c_metadata_struct(identity: &DppIdentity) -> *const MetaData {
- let metadata = &identity.metadata;
- if let Some(metadata) = metadata {
- Box::into_raw(Box::from(MetaData {
- block_height: metadata.block_height,
- core_chain_locked_height: metadata.core_chain_locked_height,
- time_ms: metadata.time_ms,
- protocol_version: metadata.protocol_version,
- }))
- } else {
- std::ptr::null()
- }
-}
-
-pub(crate) fn extract_vector_from_pointer(ptr: *const *const u8, count: usize) -> Vec {
- let mut result = Vec::new();
- let inner_pointers = unsafe { slice::from_raw_parts(ptr, count) };
- for i in 0..count {
- let inner_item: T = unsafe { std::ptr::read(inner_pointers[i] as *const T) };
- result.push(inner_item);
- }
- result
-}
-
-pub(crate) fn vec_to_pointer(a: Vec) -> *const T {
- let ptr = a.as_ptr();
- mem::forget(a);
- ptr
-}
diff --git a/packages/rs-sdk-ffi/Cargo.toml b/packages/rs-sdk-ffi/Cargo.toml
new file mode 100644
index 00000000000..34dd47db200
--- /dev/null
+++ b/packages/rs-sdk-ffi/Cargo.toml
@@ -0,0 +1,51 @@
+[package]
+name = "rs-sdk-ffi"
+version = "2.0.0-rc.14"
+authors = ["Dash Core Group "]
+edition = "2021"
+license = "MIT"
+description = "FFI bindings for Dash Platform SDK - C-compatible interface for cross-platform integration"
+
+[lib]
+crate-type = ["rlib", "staticlib", "cdylib"]
+
+[dependencies]
+dash-sdk = { path = "../rs-sdk", features = ["mocks"] }
+
+# FFI and serialization
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
+bincode = { version = "=2.0.0-rc.3", features = ["serde"] }
+
+# Async runtime
+tokio = { version = "1.41", features = ["rt-multi-thread", "macros"] }
+
+# Error handling
+thiserror = "2.0"
+
+# Logging
+tracing = "0.1"
+
+# Encoding
+bs58 = "0.5"
+hex = "0.4"
+
+# System APIs
+libc = "0.2"
+
+[build-dependencies]
+cbindgen = "0.27"
+
+[dev-dependencies]
+hex = "0.4"
+env_logger = "0.11"
+dotenvy = "0.15"
+envy = "0.4"
+zeroize = "1.8"
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
+log = "0.4"
+
+[[test]]
+name = "integration"
+path = "tests/integration.rs"
\ No newline at end of file
diff --git a/packages/rs-sdk-ffi/NULL_CHECK_FIXES_SUMMARY.md b/packages/rs-sdk-ffi/NULL_CHECK_FIXES_SUMMARY.md
new file mode 100644
index 00000000000..d53f4e45559
--- /dev/null
+++ b/packages/rs-sdk-ffi/NULL_CHECK_FIXES_SUMMARY.md
@@ -0,0 +1,57 @@
+# Null Pointer Check Fixes Summary
+
+This document summarizes the null pointer checks added to the rs-sdk-ffi files.
+
+## Files Fixed
+
+### 1. group/queries/actions.rs
+- Added null check for `sdk_handle`
+- Added null check for `contract_id` parameter
+
+### 2. group/queries/infos.rs
+- Added null check for `sdk_handle`
+
+### 3. group/queries/action_signers.rs
+- Added null check for `sdk_handle`
+- Added null check for `contract_id` parameter
+- Added null check for `action_id` parameter
+
+### 4. protocol_version/queries/upgrade_vote_status.rs
+- Added null check for `sdk_handle`
+
+### 5. evonode/queries/proposed_epoch_blocks_by_range.rs
+- Added null check for `sdk_handle`
+
+### 6. token/queries/total_supply.rs
+- Added null check for `sdk_handle`
+- Added null check for `token_id` parameter
+
+### 7. token/queries/pre_programmed_distributions.rs
+- Added null check for `sdk_handle` (in commented code)
+- Added null check for `token_id` parameter (in commented code)
+
+### 8. system/queries/path_elements.rs
+- Added null check for `sdk_handle`
+- Added null check for `path_json` parameter
+- Added null check for `keys_json` parameter
+
+### 9. system/queries/prefunded_specialized_balance.rs
+- Added null check for `sdk_handle`
+- Added null check for `id` parameter
+
+### 10. identity/queries/resolve.rs
+- No changes needed - file already had proper null checks for both `sdk_handle` and `name` parameters
+
+## Pattern Used
+
+All null checks follow the same pattern:
+```rust
+if sdk_handle.is_null() {
+ return Err("SDK handle is null".to_string());
+}
+if some_parameter.is_null() {
+ return Err("Parameter name is null".to_string());
+}
+```
+
+These checks are placed at the beginning of the internal functions before any pointer dereferencing occurs.
\ No newline at end of file
diff --git a/packages/rs-sdk-ffi/README.md b/packages/rs-sdk-ffi/README.md
new file mode 100644
index 00000000000..2a52096d520
--- /dev/null
+++ b/packages/rs-sdk-ffi/README.md
@@ -0,0 +1,213 @@
+# Dash SDK FFI
+
+FFI bindings for integrating Dash Platform SDK with cross-platform applications.
+
+## Overview
+
+This crate provides C-compatible FFI bindings for the Dash Platform SDK (`rs-sdk`), enabling applications on any platform that supports C interfaces to interact with Dash Platform. This includes iOS (Swift), Android (JNI), Python (ctypes/cffi), Node.js (node-ffi), and more.
+
+## Building
+
+### Prerequisites
+
+- Rust toolchain with appropriate targets:
+ ```bash
+ # For iOS
+ rustup target add aarch64-apple-ios
+ rustup target add aarch64-apple-ios-sim
+ rustup target add x86_64-apple-ios
+
+ # For Android
+ rustup target add aarch64-linux-android
+ rustup target add armv7-linux-androideabi
+ rustup target add x86_64-linux-android
+
+ # For other platforms, add as needed
+ ```
+
+- cbindgen (for header generation): `cargo install cbindgen`
+
+### Build Instructions
+
+For standard builds:
+```bash
+cargo build --release
+```
+
+To generate C headers:
+```bash
+GENERATE_BINDINGS=1 cargo build --release
+```
+
+### Platform-Specific Builds
+
+#### iOS
+```bash
+./build_ios.sh
+```
+
+#### Android
+```bash
+cargo build --target aarch64-linux-android --release
+```
+
+#### Other Platforms
+Build for your target platform using the appropriate Rust target.
+
+## Integration
+
+### C/C++ Usage
+
+```c
+#include "dash_sdk_ffi.h"
+
+// Initialize the SDK
+dash_sdk_init();
+
+// Create SDK configuration
+DashSDKConfig config = {
+ .network = DASH_SDK_NETWORK_TESTNET,
+ .dapi_addresses = "seed-1.testnet.networks.dash.org",
+ .request_retry_count = 3,
+ .request_timeout_ms = 30000
+};
+
+// Create SDK instance
+DashSDKResult result = dash_sdk_create(&config);
+if (result.error) {
+ // Handle error
+ dash_sdk_error_free(result.error);
+ return;
+}
+
+void* sdk = result.data;
+
+// Use the SDK...
+
+// Clean up
+dash_sdk_destroy(sdk);
+```
+
+### Swift Usage Example
+
+```swift
+// Initialize the SDK
+dash_sdk_init()
+
+// Create SDK configuration
+var config = DashSDKConfig(
+ network: DashSDKNetwork.testnet,
+ dapi_addresses: "seed-1.testnet.networks.dash.org".cString(using: .utf8),
+ request_retry_count: 3,
+ request_timeout_ms: 30000
+)
+
+// Create SDK instance
+let result = dash_sdk_create(&config)
+if let error = result.error {
+ // Handle error
+ dash_sdk_error_free(error)
+ return
+}
+
+let sdk = result.data
+
+// Use the SDK...
+
+// Clean up
+dash_sdk_destroy(sdk)
+```
+
+### Python Usage Example
+
+```python
+import ctypes
+from ctypes import *
+
+# Load the library
+lib = cdll.LoadLibrary('./target/release/librs_sdk_ffi.so')
+
+# Initialize
+lib.dash_sdk_init()
+
+# Create configuration
+class DashSDKConfig(Structure):
+ _fields_ = [
+ ("network", c_int),
+ ("dapi_addresses", c_char_p),
+ ("request_retry_count", c_uint32),
+ ("request_timeout_ms", c_uint64)
+ ]
+
+config = DashSDKConfig(
+ network=1, # Testnet
+ dapi_addresses=b"seed-1.testnet.networks.dash.org",
+ request_retry_count=3,
+ request_timeout_ms=30000
+)
+
+# Create SDK instance
+result = lib.dash_sdk_create(byref(config))
+# ... handle result and use SDK
+```
+
+## API Reference
+
+### Core Functions
+
+- `dash_sdk_init()` - Initialize the FFI library
+- `dash_sdk_create()` - Create an SDK instance
+- `dash_sdk_destroy()` - Destroy an SDK instance
+- `dash_sdk_version()` - Get the SDK version
+
+### Identity Operations
+
+- `dash_sdk_identity_fetch()` - Fetch an identity by ID
+- `dash_sdk_identity_create()` - Create a new identity
+- `dash_sdk_identity_topup()` - Top up identity with credits
+- `dash_sdk_identity_register_name()` - Register a DPNS name
+
+### Document Operations
+
+- `dash_sdk_document_create()` - Create a new document
+- `dash_sdk_document_update()` - Update an existing document
+- `dash_sdk_document_delete()` - Delete a document
+- `dash_sdk_document_fetch()` - Fetch documents by query
+
+### Data Contract Operations
+
+- `dash_sdk_data_contract_create()` - Create a new data contract
+- `dash_sdk_data_contract_update()` - Update a data contract
+- `dash_sdk_data_contract_fetch()` - Fetch a data contract
+
+## Architecture
+
+The FFI layer follows these principles:
+
+1. **Opaque Handles**: Complex Rust types are exposed as opaque pointers
+2. **C-Compatible Types**: All data crossing the FFI boundary uses C-compatible types
+3. **Error Handling**: Functions return error codes with optional error messages
+4. **Memory Management**: Clear ownership rules with dedicated free functions
+5. **Cross-Platform**: Works on any platform that can interface with C
+
+## Development
+
+### Adding New Functions
+
+1. Add the Rust implementation in the appropriate module
+2. Ensure the function is marked with `#[no_mangle]` and `extern "C"`
+3. Update cbindgen.toml if needed
+4. Regenerate headers by running: `GENERATE_BINDINGS=1 cargo build --release`
+
+### Testing
+
+Run tests with:
+```bash
+cargo test
+```
+
+For platform-specific testing, create test applications on each target platform.
+
+## License
+
+MIT
\ No newline at end of file
diff --git a/packages/rs-sdk-ffi/README_NAME_RESOLUTION.md b/packages/rs-sdk-ffi/README_NAME_RESOLUTION.md
new file mode 100644
index 00000000000..147b4d5ee8f
--- /dev/null
+++ b/packages/rs-sdk-ffi/README_NAME_RESOLUTION.md
@@ -0,0 +1,111 @@
+# DPNS Name Resolution Implementation
+
+This document describes the implementation of the `dash_sdk_identity_resolve_name` function in the rs-sdk-ffi package.
+
+## Overview
+
+The function resolves DPNS (Dash Platform Name Service) names to identity IDs. DPNS is similar to DNS but for Dash Platform, allowing users to register human-readable names that point to their identity IDs.
+
+## Function Signature
+
+```c
+DashSDKResult dash_sdk_identity_resolve_name(
+ const SDKHandle* sdk_handle,
+ const char* name
+);
+```
+
+## Parameters
+
+- `sdk_handle`: A handle to an initialized SDK instance
+- `name`: A null-terminated C string containing the name to resolve (e.g., "alice.dash" or just "alice")
+
+## Return Value
+
+Returns a `DashSDKResult` that contains:
+- On success: Binary data containing the 32-byte identity ID
+- On error: An error code and message
+
+## Implementation Details
+
+### Name Parsing
+
+Names are parsed into two components:
+1. **Label**: The leftmost part of the name (e.g., "alice" in "alice.dash")
+2. **Parent Domain**: The domain after the last dot (e.g., "dash" in "alice.dash")
+
+If no parent domain is specified, "dash" is used as the default.
+
+### Normalization
+
+Both the label and parent domain are normalized using `convert_to_homograph_safe_chars` to prevent homograph attacks and ensure consistent lookups.
+
+### DPNS Contract
+
+The function queries the DPNS data contract which stores domain documents. Each domain document contains:
+- `normalizedLabel`: The normalized version of the label
+- `normalizedParentDomainName`: The normalized parent domain name
+- `records`: A map that can contain:
+ - `dashUniqueIdentityId`: The primary identity ID for this name
+ - `dashAliasIdentityId`: An alias identity ID for this name
+
+### Query Process
+
+1. Fetch the DPNS data contract using its well-known ID
+2. Create a document query for the "domain" document type
+3. Add where clauses to filter by normalized label and parent domain
+4. Fetch the matching document
+5. Extract the identity ID from the `records` field
+
+### Priority
+
+The function checks for identity IDs in this order:
+1. `dashUniqueIdentityId` (primary)
+2. `dashAliasIdentityId` (alias)
+
+## Error Handling
+
+The function returns appropriate error codes for:
+- `InvalidParameter`: Null SDK handle, null name, or invalid UTF-8
+- `InvalidState`: No tokio runtime available
+- `NotFound`: DPNS contract not found, domain not found, or no identity ID in records
+- `NetworkError`: Failed to fetch data from the network
+- `InternalError`: Failed to create queries or other internal errors
+
+## Example Usage
+
+```c
+// Initialize SDK
+DashSDKConfig config = {
+ .network = DashSDKNetwork_Testnet,
+ .dapi_addresses = "https://testnet.dash.org:443",
+ // ... other config
+};
+DashSDKResult sdk_result = dash_sdk_create(&config);
+SDKHandle* sdk = (SDKHandle*)sdk_result.data;
+
+// Resolve a name
+DashSDKResult result = dash_sdk_identity_resolve_name(sdk, "alice.dash");
+
+if (result.error == NULL) {
+ // Success - result.data contains binary identity ID
+ DashSDKBinaryData* binary_data = (DashSDKBinaryData*)result.data;
+ // Use binary_data->data (32 bytes) and binary_data->len
+
+ // Clean up
+ dash_sdk_result_free(result);
+} else {
+ // Handle error
+ printf("Error: %s\n", result.error->message);
+ dash_sdk_result_free(result);
+}
+```
+
+## Testing
+
+The implementation includes unit tests for:
+- Null parameter handling
+- Invalid UTF-8 handling
+- Name parsing logic
+
+Integration tests would require a running Dash Platform network with registered DPNS names.
\ No newline at end of file
diff --git a/packages/rs-sdk-ffi/build.rs b/packages/rs-sdk-ffi/build.rs
new file mode 100644
index 00000000000..ec8a5fb5b42
--- /dev/null
+++ b/packages/rs-sdk-ffi/build.rs
@@ -0,0 +1,33 @@
+use std::env;
+use std::path::Path;
+
+fn main() {
+ let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
+ let out_dir = env::var("OUT_DIR").unwrap();
+
+ // Only generate bindings when explicitly requested
+ if env::var("GENERATE_BINDINGS").is_ok() {
+ 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. */".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,
+ ..Default::default()
+ };
+
+ cbindgen::Builder::new()
+ .with_crate(crate_dir)
+ .with_config(config)
+ .generate()
+ .expect("Unable to generate bindings")
+ .write_to_file(Path::new(&out_dir).join("dash_sdk_ffi.h"));
+ }
+}
diff --git a/packages/rs-sdk-ffi/build_ios.sh b/packages/rs-sdk-ffi/build_ios.sh
new file mode 100755
index 00000000000..62b966c87d3
--- /dev/null
+++ b/packages/rs-sdk-ffi/build_ios.sh
@@ -0,0 +1,142 @@
+#!/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
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+PROJECT_ROOT="$SCRIPT_DIR/../.."
+PROJECT_NAME="rs_sdk_ffi"
+FRAMEWORK_NAME="DashSDK"
+
+# Get architecture argument (default to arm)
+BUILD_ARCH="${1:-arm}"
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+echo -e "${GREEN}Building Dash iOS SDK for architecture: $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"
+ 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
+
+# Build for iOS device (arm64) - always needed
+if [ "$BUILD_ARCH" != "x86" ]; then
+ echo -e "${GREEN}Building for iOS device (arm64)...${NC}"
+ cargo build --target aarch64-apple-ios --release --package rs-sdk-ffi
+fi
+
+# Build for iOS simulator based on architecture
+if [ "$BUILD_ARCH" = "x86" ]; then
+ echo -e "${GREEN}Building for iOS simulator (x86_64)...${NC}"
+ cargo build --target x86_64-apple-ios --release --package rs-sdk-ffi
+elif [ "$BUILD_ARCH" = "universal" ]; then
+ echo -e "${GREEN}Building for iOS simulator (arm64)...${NC}"
+ cargo build --target aarch64-apple-ios-sim --release --package rs-sdk-ffi
+ echo -e "${GREEN}Building for iOS simulator (x86_64)...${NC}"
+ cargo build --target x86_64-apple-ios --release --package rs-sdk-ffi
+else
+ # Default to ARM
+ echo -e "${GREEN}Building for iOS simulator (arm64)...${NC}"
+ cargo build --target aarch64-apple-ios-sim --release --package rs-sdk-ffi
+fi
+
+# Create output directory
+OUTPUT_DIR="$SCRIPT_DIR/build"
+mkdir -p "$OUTPUT_DIR"
+
+# Generate C headers
+echo -e "${GREEN}Generating C headers...${NC}"
+GENERATE_BINDINGS=1 cargo build --release --package rs-sdk-ffi
+cp "$PROJECT_ROOT/target/release/build/"*"/out/dash_sdk_ffi.h" "$OUTPUT_DIR/" 2>/dev/null || {
+ echo -e "${YELLOW}Warning: Could not find generated header. Running cbindgen manually...${NC}"
+ cbindgen --config cbindgen.toml --crate rs-sdk-ffi --output "$OUTPUT_DIR/dash_sdk_ffi.h"
+}
+
+# Create simulator library based on architecture
+echo -e "${GREEN}Creating simulator library...${NC}"
+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
+ echo -e "${GREEN}Copying device library...${NC}"
+ mkdir -p "$OUTPUT_DIR/device"
+ cp "$PROJECT_ROOT/target/aarch64-apple-ios/release/librs_sdk_ffi.a" "$OUTPUT_DIR/device/"
+fi
+
+# Create module map
+echo -e "${GREEN}Creating module map...${NC}"
+cat > "$OUTPUT_DIR/module.modulemap" << EOF
+module DashSDKFFI {
+ header "dash_sdk_ffi.h"
+ export *
+}
+EOF
+
+# Prepare headers directory for XCFramework
+echo -e "${GREEN}Preparing headers for XCFramework...${NC}"
+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/"
+
+# 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
+ XCFRAMEWORK_CMD="$XCFRAMEWORK_CMD -library $OUTPUT_DIR/device/librs_sdk_ffi.a -headers $HEADERS_DIR"
+fi
+
+if [ -f "$OUTPUT_DIR/simulator/librs_sdk_ffi.a" ]; then
+ XCFRAMEWORK_CMD="$XCFRAMEWORK_CMD -library $OUTPUT_DIR/simulator/librs_sdk_ffi.a -headers $HEADERS_DIR"
+fi
+
+XCFRAMEWORK_CMD="$XCFRAMEWORK_CMD -output $OUTPUT_DIR/$FRAMEWORK_NAME.xcframework"
+
+eval $XCFRAMEWORK_CMD
+
+echo -e "${GREEN}Build complete!${NC}"
+echo -e "XCFramework created at: ${YELLOW}$OUTPUT_DIR/$FRAMEWORK_NAME.xcframework${NC}"
+echo -e "To use in your iOS project:"
+echo -e "1. Drag $FRAMEWORK_NAME.xcframework into your Xcode project"
+echo -e "2. Import the module: ${YELLOW}import DashSDKFFI${NC}"
\ No newline at end of file
diff --git a/packages/rs-sdk-ffi/cbindgen.toml b/packages/rs-sdk-ffi/cbindgen.toml
new file mode 100644
index 00000000000..68465d0afd0
--- /dev/null
+++ b/packages/rs-sdk-ffi/cbindgen.toml
@@ -0,0 +1,71 @@
+# cbindgen configuration for Dash SDK FFI
+
+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_*"]
+exclude = []
+prefix = "dash_sdk_"
+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 = "dash_sdk_"
+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_variants = "ScreamingSnakeCase"
+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"
+
+# Rename all enums to avoid conflicts by prefixing with enum name
+[enum.rename_variants]
+"*" = "{}_{}"
+
+[const]
+allow_static_const = true
+allow_constexpr = false
+sort_by = "name"
+
+[macro_expansion]
+bitflags = false
+
+[parse]
+parse_deps = true
+include = []
\ No newline at end of file
diff --git a/packages/rs-sdk-ffi/cbindgen_minimal.toml b/packages/rs-sdk-ffi/cbindgen_minimal.toml
new file mode 100644
index 00000000000..f2bab562a93
--- /dev/null
+++ b/packages/rs-sdk-ffi/cbindgen_minimal.toml
@@ -0,0 +1,22 @@
+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
\ No newline at end of file
diff --git a/packages/rs-sdk-ffi/src/contested_resource/mod.rs b/packages/rs-sdk-ffi/src/contested_resource/mod.rs
new file mode 100644
index 00000000000..f080b01bc15
--- /dev/null
+++ b/packages/rs-sdk-ffi/src/contested_resource/mod.rs
@@ -0,0 +1,5 @@
+// Contested resource modules
+pub mod queries;
+
+// Re-export all public functions
+pub use queries::*;
diff --git a/packages/rs-sdk-ffi/src/contested_resource/queries/identity_votes.rs b/packages/rs-sdk-ffi/src/contested_resource/queries/identity_votes.rs
new file mode 100644
index 00000000000..66d34b3abbb
--- /dev/null
+++ b/packages/rs-sdk-ffi/src/contested_resource/queries/identity_votes.rs
@@ -0,0 +1,193 @@
+use crate::types::SDKHandle;
+use crate::{DashSDKError, DashSDKErrorCode, DashSDKResult, DashSDKResultDataType};
+use dash_sdk::dpp::voting::votes::resource_vote::accessors::v0::ResourceVoteGettersV0;
+use dash_sdk::dpp::voting::votes::resource_vote::ResourceVote;
+use dash_sdk::drive::query::contested_resource_votes_given_by_identity_query::ContestedResourceVotesGivenByIdentityQuery;
+use dash_sdk::platform::FetchMany;
+use std::ffi::{c_char, c_void, CStr, CString};
+
+/// 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
+#[no_mangle]
+pub unsafe extern "C" fn dash_sdk_contested_resource_get_identity_votes(
+ sdk_handle: *const SDKHandle,
+ identity_id: *const c_char,
+ limit: u32,
+ offset: u32,
+ order_ascending: bool,
+) -> DashSDKResult {
+ match get_contested_resource_identity_votes(
+ sdk_handle,
+ identity_id,
+ limit,
+ offset,
+ order_ascending,
+ ) {
+ Ok(Some(json)) => {
+ let c_str = match CString::new(json) {
+ Ok(s) => s,
+ Err(e) => {
+ return DashSDKResult {
+ data_type: DashSDKResultDataType::None,
+ data: std::ptr::null_mut(),
+ error: Box::into_raw(Box::new(DashSDKError::new(
+ DashSDKErrorCode::InternalError,
+ format!("Failed to create CString: {}", e),
+ ))),
+ }
+ }
+ };
+ DashSDKResult {
+ data_type: DashSDKResultDataType::String,
+ data: c_str.into_raw() as *mut c_void,
+ error: std::ptr::null_mut(),
+ }
+ }
+ Ok(None) => DashSDKResult {
+ data_type: DashSDKResultDataType::None,
+ data: std::ptr::null_mut(),
+ error: std::ptr::null_mut(),
+ },
+ Err(e) => DashSDKResult {
+ data_type: DashSDKResultDataType::None,
+ data: std::ptr::null_mut(),
+ error: Box::into_raw(Box::new(DashSDKError::new(
+ DashSDKErrorCode::InternalError,
+ e,
+ ))),
+ },
+ }
+}
+
+fn get_contested_resource_identity_votes(
+ sdk_handle: *const SDKHandle,
+ identity_id: *const c_char,
+ limit: u32,
+ offset: u32,
+ order_ascending: bool,
+) -> Result