Skip to main content

accumulate_client/
lib.rs

1//! Accumulate Rust SDK (V2/V3 unified) with DevNet-first flows
2//!
3//! This crate provides a unified client for interacting with Accumulate blockchain
4//! networks, supporting both V2 and V3 protocol versions.
5
6// Import the main V2/V3 client as the primary AccumulateClient
7pub use crate::client::AccumulateClient;
8
9/// Type alias for convenient access to AccumulateClient methods
10pub type Accumulate = AccumulateClient;
11pub use crate::codec::{
12    TransactionCodec, TransactionEnvelope, TransactionSignature,
13    TransactionBodyBuilder, TokenRecipient, KeySpec, BinaryReader, BinaryWriter,
14    AccumulateHash, UrlHash, canonical_json, sha256_bytes, to_canonical_string
15};
16pub use crate::canonjson::{dumps_canonical, canonicalize};
17pub use crate::crypto::ed25519::{Ed25519Signer, verify, verify_prehashed, verify_signature, sha256};
18pub use crate::crypto::ed25519_helper::Ed25519Helper;
19pub use crate::codec::hash_helper::HashHelper;
20pub use crate::protocol::{EnvelopeBuilder, helpers as protocol_helpers};
21pub use crate::generated::enums::{
22    AccountAuthOperationType, AccountType, AllowedTransactionBit, BookType,
23    DataEntryType, ExecutorVersion, KeyPageOperationType, NetworkMaintenanceOperationType,
24    ObjectType, PartitionType, SignatureType, TransactionMax, TransactionType,
25    VoteType, VoteTally,
26};
27pub use crate::generated::signatures::*;
28pub use crate::generated::header::*;
29pub use crate::generated::transactions::*;
30// Import protocol types from generated module
31pub use crate::generated::types as protocol_types;
32// Import what's actually available from api_methods
33pub use crate::generated::api_methods::{
34    AccumulateRpc,
35    // Parameter types used in tests
36    StatusParams, QueryParams, ExecuteParams, QueryDirectoryParams, QueryTxParams,
37    QueryTxLocalParams, ExecuteCreateIdentityParams, ExecuteSendTokensParams,
38    FaucetParams, VersionParams, DescribeParams,
39    // Response types used in tests
40    StatusResponse, QueryResponse, ExecuteResponse, QueryDirectoryResponse, QueryTxResponse,
41    QueryTxLocalResponse, ExecuteCreateIdentityResponse, ExecuteSendTokensResponse
42};
43// Export the generic client wrapper as a different name to avoid conflicts
44pub use crate::generated::api_methods::AccumulateClient as GenericAccumulateClient;
45pub use crate::runtime::signing::*;
46pub use crate::runtime::rpc::*;
47#[cfg(test)]
48pub use crate::runtime::signing_test_shims;
49
50/// Canonical JSON encoding utilities
51pub mod canonjson;
52/// Main Accumulate client implementation
53pub mod client;
54/// Binary encoding/decoding utilities
55pub mod codec;
56/// Cryptographic utilities (Ed25519, hashing)
57pub mod crypto;
58/// Error types and handling
59pub mod errors;
60/// Auto-generated protocol types
61pub mod generated;
62/// Helper utilities (SmartSigner, TxBody, KeyManager, QuickStart)
63pub mod helpers;
64/// JSON-RPC client implementation
65pub mod json_rpc_client;
66/// Protocol envelope and transaction building
67pub mod protocol;
68/// Runtime utilities (RPC, signing)
69pub mod runtime;
70/// V3 API type definitions
71pub mod types;
72/// Type matrix for testing
73pub mod types_matrix;
74
75// Re-export helper utilities for convenience
76pub use crate::helpers::{
77    // Constants
78    KERMIT_V2, KERMIT_V3, DEVNET_V2, DEVNET_V3,
79    // Transaction builders
80    TxBody, TxResult,
81    // Smart signing
82    SmartSigner, HeaderOptions, KeyManager, KeyPageState, KeyEntry,
83    // QuickStart API
84    QuickStart, Wallet, AdiInfo, KeyPageInfo,
85    // Polling utilities
86    poll_for_balance, poll_for_credits, wait_for_tx,
87    // URL derivation
88    derive_lite_identity_url, derive_lite_token_account_url, sha256_hash,
89};
90
91// Re-export V3 API types for convenience
92pub use crate::types::{
93    // V3 Service Types
94    V3NodeInfo, ServiceAddress, NodeInfoOptions,
95    V3ConsensusStatus, LastBlock, ConsensusPeerInfo, ConsensusStatusOptions,
96    V3NetworkStatus, AcmeOracle, PartitionExecutorVersion, NetworkStatusOptions,
97    V3Metrics, MetricsOptions,
98    V3Submission, SubmitOptions, ValidateOptions,
99    V3FaucetOptions, V3SnapshotInfo, ListSnapshotsOptions,
100    FindServiceOptions, FindServiceResult, SubscribeOptions,
101    // V3 Query Types
102    RangeOptions, ReceiptOptions, DefaultQuery,
103    ChainQuery, DataQuery, DirectoryQuery, PendingQuery, BlockQuery,
104    AnchorSearchQuery, PublicKeySearchQuery, PublicKeyHashSearchQuery,
105    DelegateSearchQuery, MessageHashSearchQuery, V3Query,
106};
107
108use anyhow::Result;
109use std::time::Duration;
110use url::Url;
111
112/// Configuration options for the Accumulate client
113#[derive(Debug, Clone)]
114pub struct AccOptions {
115    /// Request timeout duration
116    pub timeout: Duration,
117    /// Default headers to include with requests
118    pub headers: std::collections::HashMap<String, String>,
119}
120
121impl Default for AccOptions {
122    fn default() -> Self {
123        Self {
124            timeout: Duration::from_secs(30),
125            headers: std::collections::HashMap::new(),
126        }
127    }
128}
129
130impl AccumulateClient {
131    /// Create a new client from explicit V2 and V3 endpoints
132    pub async fn from_endpoints(v2: Url, v3: Url, opts: AccOptions) -> Result<Self> {
133        Self::new_with_options(v2, v3, opts)
134            .await
135            .map_err(|e| anyhow::anyhow!(e))
136    }
137
138    /// Create a new client from environment variables
139    ///
140    /// Reads the following environment variables:
141    /// - `ACCUMULATE_V2_URL`: V2 endpoint URL
142    /// - `ACCUMULATE_V3_URL`: V3 endpoint URL
143    /// - `ACCUMULATE_TIMEOUT_MS`: Request timeout in milliseconds (optional, defaults to 30000)
144    pub async fn from_env() -> Result<Self> {
145        dotenvy::dotenv().ok(); // Load .env file if present, ignore errors
146
147        let v2_url = std::env::var("ACCUMULATE_V2_URL")
148            .map_err(|_| anyhow::anyhow!("ACCUMULATE_V2_URL environment variable not set"))?;
149        let v3_url = std::env::var("ACCUMULATE_V3_URL")
150            .map_err(|_| anyhow::anyhow!("ACCUMULATE_V3_URL environment variable not set"))?;
151
152        let v2 = Url::parse(&v2_url)?;
153        let v3 = Url::parse(&v3_url)?;
154
155        let timeout_ms = std::env::var("ACCUMULATE_TIMEOUT_MS")
156            .ok()
157            .and_then(|s| s.parse().ok())
158            .unwrap_or(30_000);
159
160        let opts = AccOptions {
161            timeout: Duration::from_millis(timeout_ms),
162            ..Default::default()
163        };
164
165        Self::from_endpoints(v2, v3, opts).await
166    }
167
168    /// Create a client configured for DevNet
169    pub async fn devnet(opts: AccOptions) -> Result<Self> {
170        let v2 = Url::parse("http://localhost:26660/v2")?;
171        let v3 = Url::parse("http://localhost:26661/v3")?;
172        Self::from_endpoints(v2, v3, opts).await
173    }
174
175    /// Create a client configured for TestNet
176    pub async fn testnet(opts: AccOptions) -> Result<Self> {
177        let v2 = Url::parse("https://testnet.accumulatenetwork.io/v2")?;
178        let v3 = Url::parse("https://testnet.accumulatenetwork.io/v3")?;
179        Self::from_endpoints(v2, v3, opts).await
180    }
181
182    /// Create a client configured for MainNet
183    pub async fn mainnet(opts: AccOptions) -> Result<Self> {
184        let v2 = Url::parse("https://mainnet.accumulatenetwork.io/v2")?;
185        let v3 = Url::parse("https://mainnet.accumulatenetwork.io/v3")?;
186        Self::from_endpoints(v2, v3, opts).await
187    }
188
189    /// Create a client configured for a custom endpoint
190    pub async fn custom(base_url: &str, opts: AccOptions) -> Result<Self> {
191        let base = Url::parse(base_url)?;
192        let v2 = base.join("/v2")?;
193        let v3 = base.join("/v3")?;
194        Self::from_endpoints(v2, v3, opts).await
195    }
196}