neo3/
lib.rs

1#![allow(warnings)]
2
3//! ![Neo Logo](https://neo.org/images/neo-logo/NEO-logo.svg)
4//! # NeoRust SDK v0.4.1
5//!
6//! A comprehensive Rust library for building applications on the Neo N3 blockchain ecosystem.
7//!
8//! [![Crates.io](https://img.shields.io/crates/v/neo3.svg)](https://crates.io/crates/neo3)
9//! [![Documentation](https://docs.rs/neo3/badge.svg)](https://docs.rs/neo3)
10//!
11//! ## Features
12//!
13//! This crate provides several feature flags to customize functionality:
14//!
15//! - **futures**: Enables async/futures support for asynchronous blockchain operations. This is recommended
16//!   for most applications that need to interact with the Neo blockchain without blocking.
17//!
18//! - **ledger**: Enables hardware wallet support via Ledger devices. When enabled, you can use Ledger
19//!   hardware wallets for transaction signing and key management. This feature provides an additional
20//!   security layer by keeping private keys on dedicated hardware.
21//!
22//! - **aws**: ⚠️ **DISABLED in v0.4.1** due to security vulnerabilities in rusoto dependencies.
23//!   Will be re-enabled in a future version with modern AWS SDK. For AWS KMS integration,
24//!   please use v0.3.0 or wait for the next major release with updated AWS dependencies.
25//!
26//! To enable specific features in your project, modify your `Cargo.toml` as follows:
27//!
28//! ```toml
29//! [dependencies]
30//! neo3 = { version = "0.4.1", features = ["futures", "ledger"] }
31//! ```
32//!
33//! You can disable default features with:
34//!
35//! ```toml
36//! neo3 = { version = "0.4.1", default-features = false, features = ["futures"] }
37//! ```
38//!
39//! ## Overview
40//!
41//! NeoRust is a complete SDK designed to make Neo N3 blockchain development in Rust
42//! intuitive, type-safe, and productive. The library provides full support for all
43//! Neo N3 features and follows Rust best practices for reliability and performance.
44//!
45//! ## Core Modules
46//!
47//! NeoRust is organized into specialized modules, each handling specific aspects of Neo N3:
48//!
49//! - [**neo_builder**](neo_builder): Transaction construction and script building
50//! - [**neo_clients**](neo_clients): Neo node interaction and RPC client implementations
51//! - [**neo_codec**](neo_codec): Serialization and deserialization of Neo data structures
52//! - [**neo_config**](neo_config): Configuration for networks and client settings
53//! - [**neo_contract**](neo_contract): Smart contract interaction and token standards
54//! - [**neo_crypto**](neo_crypto): Cryptographic primitives and operations
55//! - [**neo_error**](neo_error): Unified error handling
56//! - [**neo_fs**](neo_fs): NeoFS distributed storage system integration
57//! - [**neo_protocol**](neo_protocol): Core blockchain protocol implementations
58//! - [**neo_types**](neo_types): Core data types and primitives for Neo N3
59//! - [**neo_utils**](neo_utils): General utility functions
60//! - [**neo_wallets**](neo_wallets): Wallet management for Neo N3
61//! - [**neo_x**](neo_x): Neo X EVM compatibility layer
62//!
63//! ## Quick Start
64//!
65//! Import all essential types and traits using the `prelude`:
66//!
67//! ```rust
68//! use neo3::prelude::*;
69//! ```
70//!
71//! ## Complete Example
72//!
73//! Here's a comprehensive example showcasing common operations with the NeoRust SDK:
74//!
75//! ```no_run
76//! use neo3::neo_protocol::{Account, AccountTrait};
77//! use neo3::neo_clients::{HttpProvider, RpcClient, APITrait};
78//!
79//! async fn neo_example() -> Result<(), Box<dyn std::error::Error>> {
80//!     // Connect to Neo TestNet
81//!     let provider = HttpProvider::new("https://testnet1.neo.org:443")?;
82//!     let client = RpcClient::new(provider);
83//!     
84//!     // Get basic blockchain information
85//!     let block_height = client.get_block_count().await?;
86//!     println!("Connected to Neo TestNet at height: {}", block_height);
87//!     
88//!     // Create a new wallet account
89//!     let account = Account::create()?;
90//!     println!("New account created:");
91//!     println!("  Address:     {}", account.get_address());
92//!     println!("  Script Hash: {}", account.get_script_hash());
93//!     
94//!     // Get version information
95//!     let version = client.get_version().await?;
96//!     println!("Node version: {}", version.user_agent);
97//!     
98//!     Ok(())
99//! }
100//! ```
101//!
102//! ## Usage Examples
103//!
104//! ### Connecting to a Neo N3 node
105//!
106//! ```no_run
107//! use neo3::neo_clients::{HttpProvider, RpcClient, APITrait};
108//!
109//! #[tokio::main]
110//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
111//!     // Connect to Neo N3 MainNet
112//!     let provider = HttpProvider::new("https://mainnet1.neo.org:443")?;
113//!     let client = RpcClient::new(provider);
114//!     
115//!     // Get basic blockchain information
116//!     let block_count = client.get_block_count().await?;
117//!     println!("Current block count: {}", block_count);
118//!     
119//!     let version = client.get_version().await?;
120//!     println!("Node version: {}", version.user_agent);
121//!     
122//!     Ok(())
123//! }
124//! ```
125//!
126//! ### Creating and sending a transaction
127//!
128//! ```no_run
129//! use neo3::neo_clients::{HttpProvider, RpcClient, APITrait};
130//! use neo3::neo_protocol::{Account, AccountTrait};
131//! use neo3::neo_types::{ScriptHash, ContractParameter, ScriptHashExtension};
132//! use neo3::neo_builder::{ScriptBuilder, TransactionBuilder, AccountSigner};
133//! use std::str::FromStr;
134//!
135//! #[tokio::main]
136//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
137//!     // Initialize the JSON-RPC provider
138//!     let provider = HttpProvider::new("https://testnet1.neo.org:443")?;
139//!     let client = RpcClient::new(provider);
140//!
141//!     // Create accounts for the sender and recipient
142//!     let sender = Account::from_wif("YOUR_SENDER_WIF_HERE")?;
143//!     let recipient = ScriptHash::from_address("NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc")?;
144//!
145//!     // Get the GAS token contract
146//!     let gas_token_hash = ScriptHash::from_str("d2a4cff31913016155e38e474a2c06d08be276cf")?;
147//!     
148//!     // Build the transaction using the ScriptBuilder
149//!     let script = ScriptBuilder::new()
150//!         .contract_call(
151//!             &gas_token_hash,
152//!             "transfer",
153//!             &[
154//!                 ContractParameter::h160(&sender.get_script_hash()),
155//!                 ContractParameter::h160(&recipient),
156//!                 ContractParameter::integer(1_0000_0000), // 1 GAS (8 decimals)
157//!                 ContractParameter::any(),
158//!             ],
159//!             None,
160//!         )?
161//!         .to_bytes();
162//!     
163//!     // Create and configure the transaction
164//!     let mut tx_builder = TransactionBuilder::with_client(&client);
165//!     tx_builder
166//!         .set_script(Some(script))
167//!         .set_signers(vec![AccountSigner::called_by_entry(&sender)?.into()])?
168//!         .valid_until_block(client.get_block_count().await? + 5760)?; // Valid for ~1 day
169//!
170//!     // Sign the transaction
171//!     let mut tx = tx_builder.sign().await?;
172//!
173//!     // Send the transaction
174//!     let result = tx.send_tx().await?;
175//!     println!("Transaction sent: {}", result.hash);
176//!
177//!     // Wait for the transaction to be confirmed
178//!     println!("Waiting for confirmation...");
179//!     tx.track_tx(10).await?;
180//!     println!("Transaction confirmed!");
181//!
182//!     // Get the application log
183//!     let app_log = tx.get_application_log(&client).await?;
184//!     println!("Application log: {:?}", app_log);
185//!
186//!     Ok(())
187//! }
188//! ```
189//!
190//! ### Interacting with a smart contract
191//!
192//! ```no_run
193//! use neo3::neo_clients::{HttpProvider, RpcClient, APITrait};
194//! use std::str::FromStr;
195//!
196//! #[tokio::main]
197//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
198//!     // Connect to Neo N3 TestNet
199//!     let provider = HttpProvider::new("https://testnet1.neo.org:443")?;
200//!     let client = RpcClient::new(provider);
201//!     
202//!     // Get basic blockchain information
203//!     let block_count = client.get_block_count().await?;
204//!     println!("Block count: {}", block_count);
205//!     
206//!     // Get version information
207//!     let version = client.get_version().await?;
208//!     println!("Node version: {}", version.user_agent);
209//!     
210//!     Ok(())
211//! }
212//! ```
213//!
214//! ### Working with NEP-17 tokens
215//!
216//! ```no_run
217//! use neo3::neo_clients::{HttpProvider, RpcClient, APITrait};
218//! use neo3::neo_protocol::{Account, AccountTrait};
219//! use std::str::FromStr;
220//!
221//! #[tokio::main]
222//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
223//!     // Connect to Neo N3 TestNet
224//!     let provider = HttpProvider::new("https://testnet1.neo.org:443")?;
225//!     let client = RpcClient::new(provider);
226//!     
227//!     // Create an account
228//!     let account = Account::from_wif("YOUR_PRIVATE_KEY_WIF_HERE")?;
229//!     
230//!     // Get account information
231//!     println!("Account address: {}", account.get_address());
232//!     println!("Account script hash: {}", account.get_script_hash());
233//!     
234//!     Ok(())
235//! }
236//! ```
237//!
238//! ### Using the Neo Name Service (NNS)
239//!
240//! ```no_run
241//! use neo3::neo_clients::{HttpProvider, RpcClient, APITrait};
242//!
243//! #[tokio::main]
244//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
245//!     // Connect to Neo N3 TestNet
246//!     let provider = HttpProvider::new("https://testnet1.neo.org:443")?;
247//!     let client = RpcClient::new(provider);
248//!     
249//!     // Get blockchain information
250//!     let block_count = client.get_block_count().await?;
251//!     println!("Current block count: {}", block_count);
252//!     
253//!     Ok(())
254//! }
255//! ```
256//!
257//! For more usage examples, refer to the [`examples` directory](https://github.com/R3E-Network/NeoRust/tree/master/examples) in the repository.
258//!
259//! ## Project Structure
260//!
261//! ```text
262//! NeoRust
263//! ├── examples
264//! │   ├── neo_nodes          - Examples for connecting to Neo nodes
265//! │   ├── neo_transactions   - Examples for creating and sending transactions
266//! │   ├── neo_smart_contracts - Examples for interacting with smart contracts
267//! │   ├── neo_wallets        - Examples for wallet management
268//! │   ├── neo_nep17_tokens   - Examples for working with NEP-17 tokens
269//! │   └── neo_nns            - Examples for using the Neo Name Service
270//! └── src
271//!     ├── neo_builder        - Transaction and script building utilities
272//!     ├── neo_clients        - Neo node interaction clients (RPC and WebSocket)
273//!     ├── neo_codec          - Encoding and decoding for Neo-specific data structures
274//!     ├── neo_config         - Network and client configuration management
275//!     ├── neo_contract       - Smart contract interaction abstractions
276//!     ├── neo_crypto         - Neo-specific cryptographic operations
277//!     ├── neo_protocol       - Neo network protocol implementation
278//!     ├── neo_types          - Core Neo ecosystem data types
279//!     └── neo_wallets        - Neo asset and account management
280//! ```
281//!
282//! ## Module Overview
283//!
284//! - **neo_builder**: Transaction and script building utilities.
285//!   - Transaction construction and signing
286//!   - Script building for contract calls
287//!   - Network fee calculation
288//!
289//! - **neo_clients**: Neo node interaction clients.
290//!   - HTTP, WebSocket, and IPC providers
291//!   - JSON-RPC client implementation
292//!   - Event subscription and notification handling
293//!
294//! - **neo_codec**: Encoding and decoding for Neo-specific data structures.
295//!   - Binary serialization and deserialization
296//!   - Neo VM script encoding
297//!
298//! - **neo_config**: Network and client configuration management.
299//!   - Network magic numbers
300//!   - Client settings
301//!
302//! - **neo_contract**: Smart contract interaction abstractions.
303//!   - Contract invocation and deployment
304//!   - NEP-17 token standard implementation
305//!   - Native contracts (GAS, NEO, etc.)
306//!   - Neo Name Service (NNS) support
307//!
308//! - **neo_crypto**: Neo-specific cryptographic operations.
309//!   - Key generation and management
310//!   - Signing and verification
311//!   - Hashing functions
312//!
313//! - **neo_protocol**: Neo network protocol implementation.
314//!   - Account management
315//!   - Address formats and conversions
316//!
317//! - **neo_types**: Core Neo ecosystem data types.
318//!   - Script hashes
319//!   - Contract parameters
320//!   - Block and transaction types
321//!   - NNS name types
322//!
323//! - **neo_wallets**: Neo asset and account management.
324//!   - Wallet creation and management
325//!   - NEP-6 wallet standard support
326//!   - Account import/export
327//!   - Wallet backup and recovery
328//!
329//! For detailed information, consult the documentation of each module.
330
331#![warn(missing_debug_implementations, missing_docs, rust_2018_idioms, unreachable_pub)]
332#![doc(test(no_crate_inject, attr(deny(rust_2018_idioms), allow(dead_code, unused_variables))))]
333
334// For macro expansions only, not public API.
335#[doc(hidden)]
336#[allow(unused_extern_crates)]
337extern crate self as neo3;
338
339// Core modules - always available
340pub mod neo_error;
341pub mod neo_types;
342pub mod neo_utils;
343
344// All modules unconditionally available
345pub mod neo_builder;
346pub mod neo_clients;
347pub mod neo_codec;
348pub mod neo_config;
349pub mod neo_contract;
350pub mod neo_crypto;
351pub mod neo_fs;
352pub mod neo_protocol;
353pub mod neo_wallets;
354pub mod neo_x;
355
356// Re-exports for convenience
357#[doc(inline)]
358pub use neo_builder as builder;
359#[doc(inline)]
360pub use neo_clients as providers;
361#[doc(inline)]
362pub use neo_codec as codec;
363#[doc(inline)]
364pub use neo_config as config;
365#[doc(inline)]
366pub use neo_crypto as crypto;
367#[doc(inline)]
368pub use neo_protocol as protocol;
369#[doc(inline)]
370pub use neo_wallets as wallets;
371#[doc(inline)]
372pub use neo_x as x;
373// No need to re-export specialized modules as they're already public with their full names
374
375// Re-export common types directly in lib.rs for easy access
376pub use crate::neo_types::{
377	deserialize_address_or_script_hash,
378	deserialize_h256,
379	deserialize_h256_option,
380	deserialize_hash_map_h160_account,
381	deserialize_script_hash,
382	deserialize_script_hash_option,
383	deserialize_url_option,
384	serialize_address_or_script_hash,
385	serialize_h256,
386	serialize_h256_option,
387	serialize_hash_map_h160_account,
388	// Serialization/deserialization helpers
389	serialize_script_hash,
390	serialize_script_hash_option,
391	serialize_url_option,
392	var_size,
393	vec_to_array32,
394	Address,
395	AddressOrScriptHash,
396	// Additional types
397	Base64Encode,
398	Bytes,
399	ContractIdentifiers,
400	// Contract types
401	ContractManifest,
402	ContractParameter,
403	ContractParameterType,
404	ContractState,
405	InvocationResult,
406	// NNS types
407	NNSName,
408	NefFile,
409	OpCode,
410	OperandSize,
411	ParameterValue,
412	ScriptHash,
413	ScriptHashExtension,
414	// Additional types
415	ScryptParamsDef,
416	StackItem,
417	StringExt,
418	TypeError,
419	VMState,
420};
421
422// Add direct re-exports for commonly used serde utils
423pub use crate::neo_types::serde_with_utils::{
424	deserialize_boolean_expression, deserialize_bytes, deserialize_h160, deserialize_hardforks,
425	deserialize_hashmap_address_u256, deserialize_hashmap_u256_hashset_h256,
426	deserialize_hashmap_u256_hashset_u256, deserialize_hashmap_u256_vec_u256,
427	deserialize_hashset_u256, deserialize_map, deserialize_private_key, deserialize_public_key,
428	deserialize_public_key_option, deserialize_scopes, deserialize_vec_script_hash,
429	deserialize_vec_script_hash_option, deserialize_wildcard, serialize_boolean_expression,
430	serialize_bytes, serialize_h160, serialize_hashmap_address_u256,
431	serialize_hashmap_u256_hashset_h256, serialize_hashmap_u256_hashset_u256,
432	serialize_hashmap_u256_vec_u256, serialize_hashset_u256, serialize_map, serialize_private_key,
433	serialize_public_key, serialize_public_key_option, serialize_scopes, serialize_vec_script_hash,
434	serialize_vec_script_hash_option, serialize_wildcard,
435};
436
437// Re-export additional contract types
438pub use crate::neo_types::contract::{
439	ContractMethodToken, ContractNef, NativeContractState, NeoVMStateType,
440};
441
442// Re-export value extension trait
443pub use crate::neo_types::serde_value::ValueExtension;
444
445/// Convenient imports for commonly used types and traits.
446///
447/// This prelude module provides a single import to access the most commonly used
448/// components of the NeoRust SDK. Import it with:
449///
450/// ```rust
451/// use neo3::prelude::*;
452/// ```
453pub mod prelude;
454
455#[cfg(all(test))]
456mod tests {
457	use super::prelude::*;
458	use primitive_types::H160;
459	use std::str::FromStr;
460
461	use tokio;
462
463	use crate::{
464		builder::{AccountSigner, ScriptBuilder, TransactionBuilder},
465		neo_clients::{APITrait, HttpProvider, RpcClient},
466		neo_protocol::{Account, AccountTrait},
467	};
468	use url::Url;
469
470	#[cfg(all(test))]
471	#[tokio::test]
472	#[ignore] // Ignoring this test as it requires a live Neo N3 node and real tokens
473	async fn test_create_and_send_transaction() -> Result<(), Box<dyn std::error::Error>> {
474		// Initialize the JSON-RPC provider - using TestNet for safer testing
475		let http_provider = HttpProvider::new("https://testnet1.neo.org:443")?;
476		let rpc_client = RpcClient::new(http_provider);
477
478		// Create accounts for the sender and recipient
479		let sender = Account::from_wif("L1WMhxazScMhUrdv34JqQb1HFSQmWeN2Kpc1R9JGKwL7CDNP21uR")?;
480		let recipient = Account::from_address("NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc")?;
481
482		// Use the correct GAS token hash for Neo N3 TestNet
483		let gas_token_hash = "d2a4cff31913016155e38e474a2c06d08be276cf"; // GAS token on Neo N3
484
485		// Create a new TransactionBuilder
486		let mut tx_builder = TransactionBuilder::with_client(&rpc_client);
487
488		// Build the transaction
489		tx_builder
490			.set_script(Some(
491				ScriptBuilder::new()
492					.contract_call(
493						&H160::from_str(gas_token_hash)?,
494						"transfer",
495						&[
496							ContractParameter::h160(&sender.get_script_hash()),
497							ContractParameter::h160(&recipient.get_script_hash()),
498							ContractParameter::integer(1_0000_0000), // 1 GAS (8 decimals)
499							ContractParameter::any(),
500						],
501						None,
502					)
503					.map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?
504					.to_bytes(),
505			))
506			.set_signers(vec![AccountSigner::called_by_entry(&sender)?.into()])
507			.map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?
508			.valid_until_block(rpc_client.get_block_count().await? + 5760)?; // Valid for ~1 day
509
510		// Sign the transaction
511		let mut signed_tx = tx_builder.sign().await?;
512
513		// For testing purposes, we'll just verify that we can create and sign the transaction
514		// without actually sending it to the network
515		println!("Transaction created and signed successfully");
516		println!("Transaction size: {} bytes", signed_tx.size());
517		println!("System fee: {} GAS", signed_tx.sys_fee as f64 / 100_000_000.0);
518		println!("Network fee: {} GAS", signed_tx.net_fee as f64 / 100_000_000.0);
519
520		Ok(())
521	}
522}
523
524// Adding trait implementations for serde JSON serialization
525// These extensions will be used by the http-client feature
526pub mod extensions {
527	use serde_json::{Result as JsonResult, Value};
528
529	pub trait ToValue {
530		fn to_value(&self) -> Value;
531	}
532
533	impl ToValue for String {
534		fn to_value(&self) -> Value {
535			serde_json::Value::String(self.clone())
536		}
537	}
538
539	impl ToValue for &str {
540		fn to_value(&self) -> Value {
541			serde_json::Value::String((*self).to_string())
542		}
543	}
544
545	impl ToValue for u32 {
546		fn to_value(&self) -> Value {
547			serde_json::Value::Number(serde_json::Number::from(*self))
548		}
549	}
550
551	impl ToValue for i32 {
552		fn to_value(&self) -> Value {
553			serde_json::Value::Number(serde_json::Number::from(*self))
554		}
555	}
556
557	impl ToValue for bool {
558		fn to_value(&self) -> Value {
559			serde_json::Value::Bool(*self)
560		}
561	}
562}
563
564// Explicitly mark external dependencies with cfg_attr for docs.rs
565#[cfg(feature = "futures")]
566pub use futures;
567
568#[cfg(feature = "ledger")]
569pub use coins_ledger;
570
571// AWS feature is disabled in v0.4.1 due to security vulnerabilities
572// #[cfg(feature = "aws")]
573// #[cfg_attr(docsrs, doc(cfg(feature = "aws")))]
574// pub use rusoto_core;
575//
576// #[cfg(feature = "aws")]
577// #[cfg_attr(docsrs, doc(cfg(feature = "aws")))]
578// pub use rusoto_kms;