-
Notifications
You must be signed in to change notification settings - Fork 9
refactor: split key wallet #74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 5 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
0467808
split out key wallet functionality from rust-dash-core
QuantumExplorer 3dd8f79
work on splitting out the key wallet
QuantumExplorer 2348b2c
more work
QuantumExplorer d8f05ec
more work
QuantumExplorer 93d1bfa
more work
QuantumExplorer 18b98c0
commit
QuantumExplorer ba7e02e
commit
QuantumExplorer edc92b1
Delete NETWORK_HANDLING_FIXES.md
QuantumExplorer dca15ac
more work
QuantumExplorer c1a3c53
Merge branch 'refactor/splitKeyWallet' of github.com:dashpay/rust-das…
QuantumExplorer 5b43816
more
QuantumExplorer ce1787b
more
QuantumExplorer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| [package] | ||
| name = "dash-network-ffi" | ||
| version.workspace = true | ||
| edition = "2021" | ||
| authors = ["Quantum Explorer <[email protected]>"] | ||
| license = "CC0-1.0" | ||
| repository = "https://github.com/dashpay/rust-dashcore/" | ||
| description = "FFI bindings for dash-network types" | ||
| keywords = ["dash", "network", "ffi", "bindings"] | ||
| readme = "README.md" | ||
|
|
||
| [dependencies] | ||
| dash-network = { path = "../dash-network", default-features = false } | ||
| uniffi = { version = "0.27", features = ["cli"] } | ||
| thiserror = "1.0" | ||
|
|
||
| [build-dependencies] | ||
| uniffi = { version = "0.27", features = ["build"] } | ||
|
|
||
| [dev-dependencies] | ||
| hex = "0.4" | ||
|
|
||
| [lib] | ||
| crate-type = ["cdylib", "staticlib"] | ||
| name = "dash_network_ffi" | ||
|
|
||
| [[bin]] | ||
| name = "uniffi-bindgen" | ||
| path = "uniffi-bindgen.rs" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| # dash-network-ffi | ||
|
|
||
| FFI bindings for the dash-network crate, providing language bindings via UniFFI. | ||
|
|
||
| ## Overview | ||
|
|
||
| This crate provides Foreign Function Interface (FFI) bindings for the `dash-network` types, allowing them to be used from other programming languages like Swift, Python, Kotlin, and Ruby. | ||
|
|
||
| ## Features | ||
|
|
||
| - UniFFI-based bindings for the Network enum | ||
| - Network information and utilities exposed through FFI | ||
| - Support for magic bytes operations | ||
| - Core version activation queries | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Building | ||
|
|
||
| ```bash | ||
| cargo build --release | ||
| ``` | ||
|
|
||
| ### Generating Bindings | ||
|
|
||
| To generate bindings for your target language: | ||
|
|
||
| ```bash | ||
| cargo run --bin uniffi-bindgen generate src/dash_network.udl --language swift | ||
| cargo run --bin uniffi-bindgen generate src/dash_network.udl --language python | ||
| cargo run --bin uniffi-bindgen generate src/dash_network.udl --language kotlin | ||
| ``` | ||
|
|
||
| ### Example Usage (Swift) | ||
|
|
||
| ```swift | ||
| // Initialize the library | ||
| dashNetworkFfiInitialize() | ||
|
|
||
| // Create a network info object | ||
| let networkInfo = NetworkInfo(network: .dash) | ||
|
|
||
| // Get magic bytes | ||
| let magic = networkInfo.magic() | ||
| print("Dash network magic: \(String(format: "0x%08X", magic))") | ||
|
|
||
| // Check if core v20 is active | ||
| if networkInfo.isCoreV20Active(blockHeight: 2000000) { | ||
| print("Core v20 is active!") | ||
| } | ||
|
|
||
| // Create from magic bytes | ||
| do { | ||
| let network = try NetworkInfo.fromMagic(magic: 0xBD6B0CBF) | ||
| print("Network: \(network.toString())") | ||
| } catch { | ||
| print("Invalid magic bytes") | ||
| } | ||
| ``` | ||
|
|
||
| ### Example Usage (Python) | ||
|
|
||
| ```python | ||
| import dash_network_ffi | ||
|
|
||
| # Initialize the library | ||
| dash_network_ffi.initialize() | ||
|
|
||
| # Create a network info object | ||
| network_info = dash_network_ffi.NetworkInfo(dash_network_ffi.Network.DASH) | ||
|
|
||
| # Get magic bytes | ||
| magic = network_info.magic() | ||
| print(f"Dash network magic: 0x{magic:08X}") | ||
|
|
||
| # Check if core v20 is active | ||
| if network_info.is_core_v20_active(2000000): | ||
| print("Core v20 is active!") | ||
|
|
||
| # Create from magic bytes | ||
| try: | ||
| network = dash_network_ffi.NetworkInfo.from_magic(0xBD6B0CBF) | ||
| print(f"Network: {network.to_string()}") | ||
| except dash_network_ffi.NetworkError.InvalidMagic: | ||
| print("Invalid magic bytes") | ||
| ``` | ||
|
|
||
| ## API | ||
|
|
||
| ### Network Enum | ||
|
|
||
| - `Dash` - Dash mainnet | ||
| - `Testnet` - Dash testnet | ||
| - `Devnet` - Dash devnet | ||
| - `Regtest` - Regression test network | ||
|
|
||
| ### NetworkInfo Class | ||
|
|
||
| #### Constructors | ||
| - `new(network: Network)` - Create from a Network enum value | ||
| - `from_magic(magic: u32)` - Create from magic bytes (throws NetworkError) | ||
|
|
||
| #### Methods | ||
| - `magic() -> u32` - Get the network's magic bytes | ||
| - `to_string() -> String` - Get the network name as a string | ||
| - `is_core_v20_active(block_height: u32) -> bool` - Check if core v20 is active at height | ||
| - `core_v20_activation_height() -> u32` - Get the activation height for core v20 | ||
|
|
||
| ### NetworkError Enum | ||
|
|
||
| - `InvalidMagic` - Invalid magic bytes provided | ||
| - `InvalidNetwork` - Invalid network specified | ||
|
|
||
| ## License | ||
|
|
||
| This project is licensed under the CC0 1.0 Universal license. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| fn main() { | ||
| uniffi::generate_scaffolding("src/dash_network.udl").unwrap(); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| namespace dash_network_ffi { | ||
| // Initialize function for any setup needs | ||
| void initialize(); | ||
| }; | ||
|
|
||
| // Network enum matching the dash-network crate | ||
| enum Network { | ||
| "Dash", | ||
| "Testnet", | ||
| "Devnet", | ||
| "Regtest", | ||
| }; | ||
|
|
||
| // Interface for network-related operations | ||
| interface NetworkInfo { | ||
| // Constructor | ||
| [Name=new] | ||
| constructor(Network network); | ||
|
|
||
| // Create from magic bytes | ||
| [Name=from_magic, Throws=NetworkError] | ||
| constructor(u32 magic); | ||
|
|
||
| // Get the magic bytes for this network | ||
| u32 magic(); | ||
|
|
||
| // Get the network as a string | ||
| string to_string(); | ||
|
|
||
| // Check if core v20 is active at a given height | ||
| boolean is_core_v20_active(u32 block_height); | ||
|
|
||
| // Get the core v20 activation height | ||
| u32 core_v20_activation_height(); | ||
| }; | ||
|
|
||
| [Error] | ||
| enum NetworkError { | ||
| "InvalidMagic", | ||
| "InvalidNetwork", | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| //! FFI bindings for dash-network library | ||
|
|
||
| use dash_network::Network as DashNetwork; | ||
|
|
||
| // Include the UniFFI scaffolding | ||
| uniffi::include_scaffolding!("dash_network"); | ||
|
|
||
| // Initialize function | ||
| pub fn initialize() { | ||
| // Any global initialization if needed | ||
| } | ||
|
|
||
| // Re-export Network enum for UniFFI | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
| pub enum Network { | ||
| Dash, | ||
| Testnet, | ||
| Devnet, | ||
| Regtest, | ||
| } | ||
|
|
||
| impl From<Network> for DashNetwork { | ||
| fn from(n: Network) -> Self { | ||
| match n { | ||
| Network::Dash => DashNetwork::Dash, | ||
| Network::Testnet => DashNetwork::Testnet, | ||
| Network::Devnet => DashNetwork::Devnet, | ||
| Network::Regtest => DashNetwork::Regtest, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl From<DashNetwork> for Network { | ||
| fn from(n: DashNetwork) -> Self { | ||
| match n { | ||
| DashNetwork::Dash => Network::Dash, | ||
| DashNetwork::Testnet => Network::Testnet, | ||
| DashNetwork::Devnet => Network::Devnet, | ||
| DashNetwork::Regtest => Network::Regtest, | ||
| _ => Network::Testnet, // Default for unknown networks | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)] | ||
| pub enum NetworkError { | ||
| #[error("Invalid magic bytes")] | ||
| InvalidMagic, | ||
| #[error("Invalid network")] | ||
| InvalidNetwork, | ||
| } | ||
|
|
||
| pub struct NetworkInfo { | ||
| network: DashNetwork, | ||
| } | ||
|
|
||
| impl NetworkInfo { | ||
| pub fn new(network: Network) -> Self { | ||
| Self { | ||
| network: network.into(), | ||
| } | ||
| } | ||
|
|
||
| pub fn from_magic(magic: u32) -> Result<Self, NetworkError> { | ||
| DashNetwork::from_magic(magic) | ||
| .map(|network| Self { | ||
| network, | ||
| }) | ||
| .ok_or(NetworkError::InvalidMagic) | ||
| } | ||
|
|
||
| pub fn magic(&self) -> u32 { | ||
| self.network.magic() | ||
| } | ||
|
|
||
| pub fn to_string(&self) -> String { | ||
| self.network.to_string() | ||
| } | ||
|
|
||
| pub fn is_core_v20_active(&self, block_height: u32) -> bool { | ||
| self.network.core_v20_is_active_at(block_height) | ||
| } | ||
|
|
||
| pub fn core_v20_activation_height(&self) -> u32 { | ||
| self.network.core_v20_activation_height() | ||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
| #[test] | ||
| fn test_network_conversion() { | ||
| // Test FFI to Dash Network conversion | ||
| assert_eq!(DashNetwork::from(Network::Dash), DashNetwork::Dash); | ||
| assert_eq!(DashNetwork::from(Network::Testnet), DashNetwork::Testnet); | ||
| assert_eq!(DashNetwork::from(Network::Devnet), DashNetwork::Devnet); | ||
| assert_eq!(DashNetwork::from(Network::Regtest), DashNetwork::Regtest); | ||
|
|
||
| // Test Dash Network to FFI conversion | ||
| assert_eq!(Network::from(DashNetwork::Dash), Network::Dash); | ||
| assert_eq!(Network::from(DashNetwork::Testnet), Network::Testnet); | ||
| assert_eq!(Network::from(DashNetwork::Devnet), Network::Devnet); | ||
| assert_eq!(Network::from(DashNetwork::Regtest), Network::Regtest); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_network_info_creation() { | ||
| let info = NetworkInfo::new(Network::Dash); | ||
| assert_eq!(info.network, DashNetwork::Dash); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_magic_bytes() { | ||
| let dash_info = NetworkInfo::new(Network::Dash); | ||
| assert_eq!(dash_info.magic(), 0xBD6B0CBF); | ||
|
|
||
| let testnet_info = NetworkInfo::new(Network::Testnet); | ||
| assert_eq!(testnet_info.magic(), 0xFFCAE2CE); | ||
|
|
||
| let devnet_info = NetworkInfo::new(Network::Devnet); | ||
| assert_eq!(devnet_info.magic(), 0xCEFFCAE2); | ||
|
|
||
| let regtest_info = NetworkInfo::new(Network::Regtest); | ||
| assert_eq!(regtest_info.magic(), 0xDAB5BFFA); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_from_magic() { | ||
| // Valid magic bytes | ||
| assert!(NetworkInfo::from_magic(0xBD6B0CBF).is_ok()); | ||
| assert!(NetworkInfo::from_magic(0xFFCAE2CE).is_ok()); | ||
| assert!(NetworkInfo::from_magic(0xCEFFCAE2).is_ok()); | ||
| assert!(NetworkInfo::from_magic(0xDAB5BFFA).is_ok()); | ||
|
|
||
| // Invalid magic bytes | ||
| assert!(matches!(NetworkInfo::from_magic(0x12345678), Err(NetworkError::InvalidMagic))); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_network_to_string() { | ||
| assert_eq!(NetworkInfo::new(Network::Dash).to_string(), "dash"); | ||
| assert_eq!(NetworkInfo::new(Network::Testnet).to_string(), "testnet"); | ||
| assert_eq!(NetworkInfo::new(Network::Devnet).to_string(), "devnet"); | ||
| assert_eq!(NetworkInfo::new(Network::Regtest).to_string(), "regtest"); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_core_v20_activation() { | ||
| let dash_info = NetworkInfo::new(Network::Dash); | ||
| assert_eq!(dash_info.core_v20_activation_height(), 1987776); | ||
| assert!(!dash_info.is_core_v20_active(1987775)); | ||
| assert!(dash_info.is_core_v20_active(1987776)); | ||
| assert!(dash_info.is_core_v20_active(2000000)); | ||
|
|
||
| let testnet_info = NetworkInfo::new(Network::Testnet); | ||
| assert_eq!(testnet_info.core_v20_activation_height(), 905100); | ||
| assert!(!testnet_info.is_core_v20_active(905099)); | ||
| assert!(testnet_info.is_core_v20_active(905100)); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_round_trip_conversions() { | ||
| let networks = vec![Network::Dash, Network::Testnet, Network::Devnet, Network::Regtest]; | ||
|
|
||
| for network in networks { | ||
| let dash_network: DashNetwork = network.into(); | ||
| let back_to_ffi: Network = dash_network.into(); | ||
| assert_eq!(network, back_to_ffi); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| fn main() { | ||
| uniffi::uniffi_bindgen_main() | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.