From 0af0835ea6c7d35c5c1efd6f63899706dd85ab91 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Mon, 16 Mar 2026 01:18:22 +0000 Subject: [PATCH 01/60] fix: restore cross-account lookup resolution at round boundaries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes three bugs introduced after the Scheduled URL Resolver merge that broke cross-account field mapping (lookup_index with register_from) at round boundaries: 1. Compiler key resolution priority swap — resolved_key_reg (PDA reverse lookup result) was given priority over the LookupIndex result, causing mutations to be keyed by round_address instead of round_id. 2. Null-key handler execution — when LookupIndex returned null, handlers continued with key=null creating phantom entities that prevented queueing for reprocessing. Added AbortIfNullKey opcode. 3. Stale lookup index entries — PDA mapping changes at round boundaries left old entries that shadowed the updated mapping. Added PDA change detection, stale index clearing, and last_account_data cache for reprocessing. --- .../src/codegen/vixen_runtime.rs | 61 ++++++- interpreter/src/compiler.rs | 40 +++-- interpreter/src/vm.rs | 164 +++++++++++++++++- 3 files changed, 247 insertions(+), 18 deletions(-) diff --git a/hyperstack-macros/src/codegen/vixen_runtime.rs b/hyperstack-macros/src/codegen/vixen_runtime.rs index ef75199e..3b5f7c0c 100644 --- a/hyperstack-macros/src/codegen/vixen_runtime.rs +++ b/hyperstack-macros/src/codegen/vixen_runtime.rs @@ -752,9 +752,35 @@ pub fn generate_vm_handler( let context = hyperstack::runtime::hyperstack_interpreter::UpdateContext::new_account(slot, signature.clone(), write_version); + // Clone event data before process_event so we can cache it + // for reprocessing when a PDA mapping changes at round boundaries. + let event_value_for_cache = event_value.clone(); + let result = vm.process_event(&self.bytecode, event_value, event_type, Some(&context), Some(&mut log)) .map_err(|e| e.to_string()); + // Cache the last account data per PDA address. When a PDA + // mapping later changes (same PDA, different seed) the cached + // data is returned for reprocessing with the corrected mapping. + if result.is_ok() { + vm.cache_last_account_data( + 0, + &account_address, + hyperstack::runtime::hyperstack_interpreter::PendingAccountUpdate { + account_type: event_type.to_string(), + pda_address: account_address.clone(), + account_data: event_value_for_cache, + slot, + write_version, + signature: signature.clone(), + queued_at: std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_secs() as i64, + }, + ); + } + let requests = if result.is_ok() { vm.take_resolver_requests() } else { @@ -910,7 +936,12 @@ pub fn generate_vm_handler( "Flushing pending account updates from instruction hooks" ); for update in pending_updates { - let resolved_key = vm.try_pda_reverse_lookup(0, "default_pda_lookup", &update.pda_address); + // Use chained PDA + lookup-index resolution so that + // __resolved_primary_key carries the actual primary key + // (e.g. round_id) instead of the intermediate PDA value + // (e.g. round_address). Falls back to raw PDA result when + // lookup index isn't populated yet. + let resolved_key = vm.try_chained_pda_lookup(0, "default_pda_lookup", &update.pda_address); let mut account_data = update.account_data; if let Some(key) = resolved_key { @@ -1745,9 +1776,30 @@ pub fn generate_account_handler_impl( let context = hyperstack::runtime::hyperstack_interpreter::UpdateContext::new_account(slot, signature.clone(), write_version); + let event_value_for_cache = event_value.clone(); + let result = vm.process_event(&self.bytecode, event_value, event_type, Some(&context), Some(&mut log)) .map_err(|e| e.to_string()); + if result.is_ok() { + vm.cache_last_account_data( + 0, + &account_address, + hyperstack::runtime::hyperstack_interpreter::PendingAccountUpdate { + account_type: event_type.to_string(), + pda_address: account_address.clone(), + account_data: event_value_for_cache, + slot, + write_version, + signature: signature.clone(), + queued_at: std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_secs() as i64, + }, + ); + } + let requests = if result.is_ok() { vm.take_resolver_requests() } else { @@ -1901,7 +1953,12 @@ pub fn generate_instruction_handler_impl( if !pending_updates.is_empty() { for update in pending_updates { - let resolved_key = vm.try_pda_reverse_lookup(0, "default_pda_lookup", &update.pda_address); + // Use chained PDA + lookup-index resolution so that + // __resolved_primary_key carries the actual primary key + // (e.g. round_id) instead of the intermediate PDA value + // (e.g. round_address). Falls back to raw PDA result when + // lookup index isn't populated yet. + let resolved_key = vm.try_chained_pda_lookup(0, "default_pda_lookup", &update.pda_address); let mut account_data = update.account_data; if let Some(key) = resolved_key { diff --git a/interpreter/src/compiler.rs b/interpreter/src/compiler.rs index 65dc1a4e..863d0c3b 100644 --- a/interpreter/src/compiler.rs +++ b/interpreter/src/compiler.rs @@ -11,6 +11,15 @@ fn stop_field_path(target_path: &str) -> String { #[derive(Debug, Clone)] pub enum OpCode { + /// Abort the handler with empty mutations when the key register is null + /// and the event is an account-state update (not IxState / CpiEvent). + /// Placed immediately after key resolution so that downstream opcodes + /// (index updates, field mappings, resolvers, emit) never execute with + /// a garbage key. The null-key event is then eligible for queueing by + /// process_event's miss-handling logic. + AbortIfNullKey { + key: Register, + }, LoadEventField { path: FieldPath, dest: Register, @@ -664,6 +673,13 @@ impl TypedCompiler { ops.extend(self.compile_key_loading(&spec.key_resolution, key_reg, &spec.mappings)); + // Guard: if key resolved to null on an account-state event, abort + // early with empty mutations so process_event can queue the update + // for later reprocessing. Without this, downstream opcodes would + // create a phantom entity keyed by null and produce non-empty + // mutations that prevent queueing. + ops.push(OpCode::AbortIfNullKey { key: key_reg }); + ops.push(OpCode::ReadOrInitState { state_id: self.state_id, key: key_reg, @@ -1196,7 +1212,11 @@ impl TypedCompiler { let lookup_reg = 15; let result_reg = 17; - // Prefer resolver-provided key as lookup input + // Prefer resolver-provided key as lookup input. + // When __resolved_primary_key is set (e.g. round_address from + // PDA reverse lookup), use it directly — this gives a one-hop + // lookup (round_address → round_id) instead of a two-hop chain + // (Var address → PDA → round_address → round_id). ops.push(OpCode::CopyRegister { source: resolved_key_reg, dest: lookup_reg, @@ -1230,18 +1250,14 @@ impl TypedCompiler { // which caused the PDA address to be used as the key instead of the round_id. // This resulted in mutations with key = PDA address instead of key = primary_key. - // First, set key_reg to __resolved_primary_key (may be null). - // When the flush path provides a resolved key via PDA reverse lookup, - // this gives it priority over the LookupIndex result. - // This matches the pattern used by Embedded and Computed strategies. + // Use LookupIndex result as the primary key. Do NOT fall back to + // resolved_key_reg (__resolved_primary_key) because for Lookup handlers + // it contains the PDA reverse-lookup result (e.g. round_address), which + // is an intermediate value, not the actual primary key (e.g. round_id). + // If the LookupIndex chain returns null (round not yet indexed), key + // stays null so the update is queued and reprocessed once the lookup + // index is populated—matching the pre-23503ac behaviour. ops.push(OpCode::CopyRegister { - source: resolved_key_reg, - dest: key_reg, - }); - // If key_reg is still null (no resolved key from flush), use the LookupIndex result. - // This preserves the original behavior for first-arrival events where - // __resolved_primary_key is not yet set. - ops.push(OpCode::CopyRegisterIfNull { source: result_reg, dest: key_reg, }); diff --git a/interpreter/src/vm.rs b/interpreter/src/vm.rs index 44c4e438..a7d2e480 100644 --- a/interpreter/src/vm.rs +++ b/interpreter/src/vm.rs @@ -352,6 +352,13 @@ impl LookupIndex { self.index.lock().unwrap().put(key, primary_key); } + /// Remove an entry by lookup value. Used when a PDA mapping changes to + /// clear stale entries that would otherwise shadow the updated PDA mapping. + pub fn remove(&self, lookup_value: &Value) { + let key = value_to_cache_key(lookup_value); + self.index.lock().unwrap().pop(&key); + } + pub fn len(&self) -> usize { self.index.lock().unwrap().len() } @@ -769,6 +776,10 @@ pub struct StateTable { pub pda_reverse_lookups: HashMap, pub pending_updates: DashMap>, pub pending_instruction_events: DashMap>, + /// Cache of the most recent account data per PDA address. When a PDA + /// mapping changes (same PDA, different seed) the cached data is returned + /// for reprocessing so cross-account Lookup handlers resolve to the new key. + pub last_account_data: DashMap, version_tracker: VersionTracker, instruction_dedup_cache: VersionTracker, config: StateTableConfig, @@ -946,18 +957,51 @@ impl VmContext { pda_reverse_lookups: HashMap::new(), pending_updates: DashMap::new(), pending_instruction_events: DashMap::new(), + last_account_data: DashMap::new(), version_tracker: VersionTracker::new(), instruction_dedup_cache: VersionTracker::with_capacity( DEFAULT_MAX_INSTRUCTION_DEDUP_ENTRIES, ), config: StateTableConfig::default(), - entity_name: "default".to_string(), + entity_name: String::new(), recent_tx_instructions: std::sync::Mutex::new(LruCache::new( NonZeroUsize::new(1000).unwrap(), )), deferred_when_ops: DashMap::new(), }, ); + + vm + } + + /// Create a new VmContext specifically for multi-entity operation. + pub fn new_multi_entity() -> Self { + let vm = VmContext { + registers: vec![Value::Null; 32], + states: HashMap::new(), + instructions_executed: 0, + cache_hits: 0, + path_cache: HashMap::new(), + pda_cache_hits: 0, + pda_cache_misses: 0, + pending_queue_size: 0, + resolver_requests: VecDeque::new(), + resolver_pending: HashMap::new(), + resolver_cache: LruCache::new( + NonZeroUsize::new(DEFAULT_MAX_RESOLVER_CACHE_ENTRIES) + .expect("capacity must be > 0"), + ), + resolver_cache_hits: 0, + resolver_cache_misses: 0, + current_context: None, + warnings: Vec::new(), + last_pda_lookup_miss: None, + last_lookup_index_miss: None, + last_pda_registered: None, + last_lookup_index_keys: Vec::new(), + scheduled_callbacks: Vec::new(), + }; + vm } @@ -997,6 +1041,7 @@ impl VmContext { pda_reverse_lookups: HashMap::new(), pending_updates: DashMap::new(), pending_instruction_events: DashMap::new(), + last_account_data: DashMap::new(), version_tracker: VersionTracker::new(), instruction_dedup_cache: VersionTracker::with_capacity( DEFAULT_MAX_INSTRUCTION_DEDUP_ENTRIES, @@ -1889,6 +1934,22 @@ impl VmContext { self.registers[*dest] = value; pc += 1; } + OpCode::AbortIfNullKey { key } => { + let key_value = &self.registers[*key]; + if key_value.is_null() + && event_type.ends_with("State") + && !event_type.ends_with("IxState") + && !event_type.ends_with("CpiEvent") + { + tracing::debug!( + event_type = %event_type, + "AbortIfNullKey: key is null for account state event, \ + returning empty mutations for queueing" + ); + return Ok(Vec::new()); + } + pc += 1; + } OpCode::ReadOrInitState { state_id: _, key, @@ -1907,6 +1968,7 @@ impl VmContext { pda_reverse_lookups: HashMap::new(), pending_updates: DashMap::new(), pending_instruction_events: DashMap::new(), + last_account_data: DashMap::new(), version_tracker: VersionTracker::new(), instruction_dedup_cache: VersionTracker::with_capacity( DEFAULT_MAX_INSTRUCTION_DEDUP_ENTRIES, @@ -3555,7 +3617,16 @@ impl VmContext { .entry(lookup_name.to_string()) .or_insert_with(|| PdaReverseLookup::new(DEFAULT_MAX_PDA_REVERSE_LOOKUP_ENTRIES)); - let evicted_pda = lookup.insert(pda_address.clone(), seed_value); + // Detect if the PDA mapping is CHANGING (same PDA, different seed). + // This happens at round boundaries when e.g. entropyVar is remapped + // from old_round to new_round by a Reset instruction. + let old_seed = lookup.index.peek(&pda_address).cloned(); + let mapping_changed = old_seed + .as_ref() + .map(|old| old != &seed_value) + .unwrap_or(false); + + let evicted_pda = lookup.insert(pda_address.clone(), seed_value.clone()); if let Some(ref evicted) = evicted_pda { if let Some((_, evicted_updates)) = state.pending_updates.remove(evicted) { @@ -3564,8 +3635,37 @@ impl VmContext { } } - // Flush and return pending updates for this PDA - self.flush_pending_updates(state_id, &pda_address) + // Flush pending updates from QueueUntil for this PDA + let mut pending = self.flush_pending_updates(state_id, &pda_address)?; + + // When the mapping changed, the last account update for this PDA was + // processed with the OLD seed (wrong key). We need to: + // 1. Remove stale lookup-index entries that map this PDA address to the + // old primary key — otherwise LookupIndex resolves the stale entry + // before PDA reverse lookup is even tried. + // 2. Pull the cached account data and return it for reprocessing with + // the new mapping. + if mapping_changed { + if let Some(state) = self.states.get(&state_id) { + // Clear stale lookup-index entries for this PDA address + for index in state.lookup_indexes.values() { + index.remove(&Value::String(pda_address.clone())); + } + + if let Some((_, cached)) = state.last_account_data.remove(&pda_address) { + tracing::info!( + pda = %pda_address, + old_seed = ?old_seed, + new_seed = %seed_value, + account_type = %cached.account_type, + "PDA mapping changed — clearing stale indexes and reprocessing cached data" + ); + pending.push(cached); + } + } + } + + Ok(pending) } /// Clean up expired pending updates that are older than the TTL @@ -3980,6 +4080,24 @@ impl VmContext { } } + /// Cache the most recent account data for a PDA address. + /// Called by the vixen runtime after a Lookup-handler account update is + /// successfully processed. When a PDA mapping later changes (e.g. at a + /// round boundary), the cached data is returned for reprocessing with the + /// new mapping. + pub fn cache_last_account_data( + &mut self, + state_id: u32, + pda_address: &str, + update: PendingAccountUpdate, + ) { + if let Some(state) = self.states.get(&state_id) { + state + .last_account_data + .insert(pda_address.to_string(), update); + } + } + /// Try to resolve a primary key via PDA reverse lookup pub fn try_pda_reverse_lookup( &mut self, @@ -4000,6 +4118,44 @@ impl VmContext { None } + /// Try to resolve a value through lookup indexes. + /// This attempts to resolve the value using any lookup index in the state. + pub fn try_lookup_index_resolution(&self, state_id: u32, value: &Value) -> Option { + let state = self.states.get(&state_id)?; + + for index in state.lookup_indexes.values() { + if let Some(resolved) = index.lookup(value) { + return Some(resolved); + } + } + + None + } + + /// Try to resolve a primary key via chained PDA + lookup index resolution. + /// First tries PDA reverse lookup, then tries to resolve the result through lookup indexes. + /// This is useful when the PDA maps to an intermediate value (e.g., round address) + /// that needs to be resolved to the actual primary key (e.g., round_id). + pub fn try_chained_pda_lookup( + &mut self, + state_id: u32, + lookup_name: &str, + pda_address: &str, + ) -> Option { + // First, try PDA reverse lookup + let pda_result = self.try_pda_reverse_lookup(state_id, lookup_name, pda_address)?; + + // Try to resolve the PDA result through lookup indexes + // (e.g., round address -> round_id) + let pda_value = Value::String(pda_result.clone()); + if let Some(resolved) = self.try_lookup_index_resolution(state_id, &pda_value) { + resolved.as_str().map(|s| s.to_string()) + } else { + // Return the PDA result if we can't resolve further + pda_value.as_str().map(|s| s.to_string()) + } + } + // ============================================================================ // Computed Expression Evaluator (Task 5) // ============================================================================ From 1f248462ebf99c9cc2f646a2110e8c06b4475c64 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Mon, 16 Mar 2026 01:19:13 +0000 Subject: [PATCH 02/60] chore: Bump cargo lock --- examples/ore-server/Cargo.lock | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/examples/ore-server/Cargo.lock b/examples/ore-server/Cargo.lock index 956c0a4b..5e68ebd1 100644 --- a/examples/ore-server/Cargo.lock +++ b/examples/ore-server/Cargo.lock @@ -1139,12 +1139,13 @@ dependencies = [ [[package]] name = "hyperstack" -version = "0.5.3" +version = "0.5.5" dependencies = [ "anyhow", "bs58", "bytemuck", "dotenvy", + "futures", "hyperstack-interpreter", "hyperstack-macros", "hyperstack-sdk", @@ -1162,7 +1163,7 @@ dependencies = [ [[package]] name = "hyperstack-idl" -version = "0.1.0" +version = "0.1.2" dependencies = [ "serde", "serde_json", @@ -1172,7 +1173,7 @@ dependencies = [ [[package]] name = "hyperstack-interpreter" -version = "0.5.3" +version = "0.5.5" dependencies = [ "bs58", "dashmap", @@ -1181,6 +1182,7 @@ dependencies = [ "hyperstack-idl", "hyperstack-macros", "lru", + "percent-encoding", "prost 0.13.5", "prost-reflect", "prost-types 0.13.5", @@ -1195,7 +1197,7 @@ dependencies = [ [[package]] name = "hyperstack-macros" -version = "0.5.3" +version = "0.5.5" dependencies = [ "bs58", "hex", @@ -1210,7 +1212,7 @@ dependencies = [ [[package]] name = "hyperstack-sdk" -version = "0.5.3" +version = "0.5.5" dependencies = [ "anyhow", "flate2", @@ -1227,7 +1229,7 @@ dependencies = [ [[package]] name = "hyperstack-server" -version = "0.5.3" +version = "0.5.5" dependencies = [ "anyhow", "base64 0.22.1", From f6c9f969377ef148c8df65500a817d7a7c5c2438 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Mon, 16 Mar 2026 01:20:17 +0000 Subject: [PATCH 03/60] refactor: remove duplicate URL path qualification in nested struct resolver --- hyperstack-macros/src/stream_spec/sections.rs | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/hyperstack-macros/src/stream_spec/sections.rs b/hyperstack-macros/src/stream_spec/sections.rs index 45dec2d0..96cde9ca 100644 --- a/hyperstack-macros/src/stream_spec/sections.rs +++ b/hyperstack-macros/src/stream_spec/sections.rs @@ -632,7 +632,7 @@ pub fn process_nested_struct( } }); - let resolver = if let Some(ref _url_path) = qualified_url { + let resolver = if let Some(ref url_path) = qualified_url { let method = resolve_attr .method .as_deref() @@ -644,16 +644,10 @@ pub fn process_nested_struct( let url_source = if resolve_attr.url_is_template { crate::ast::UrlSource::Template(super::entity::parse_url_template( - resolve_attr.url.as_deref().unwrap(), + url_path, )) } else { - let url_path_raw = resolve_attr.url.as_deref().unwrap(); - let qualified = if url_path_raw.contains('.') { - url_path_raw.to_string() - } else { - format!("{}.{}", section_name, url_path_raw) - }; - crate::ast::UrlSource::FieldPath(qualified) + crate::ast::UrlSource::FieldPath(url_path.clone()) }; crate::ast::ResolverType::Url(crate::ast::UrlResolverConfig { @@ -677,14 +671,7 @@ pub fn process_nested_struct( let from = if resolve_attr.url_is_template { None } else { - let qualified_url = resolve_attr.url.as_deref().map(|url_path_raw| { - if url_path_raw.contains('.') { - url_path_raw.to_string() - } else { - format!("{}.{}", section_name, url_path_raw) - } - }); - qualified_url.or(resolve_attr.from) + qualified_url.or(resolve_attr.from.clone()) }; resolve_specs.push(parse::ResolveSpec { From 768c407adce786003c30c634432279456baa5102 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Tue, 17 Mar 2026 11:52:12 +0000 Subject: [PATCH 04/60] feat: add Keccak256 hashing and slot hash caching - Add Keccak256 computed expression for cryptographic hashing - Implement slot_hash_bytes and expires_at_slot_hash fields in Ore stack - Add pre_reveal_rng and pre_reveal_winning_square computed fields - Add sha3 dependency to hyperstack runtime features --- hyperstack-macros/src/ast/types.rs | 7 +- hyperstack-macros/src/codegen/computed.rs | 434 +++++++++++++++++- hyperstack-macros/src/stream_spec/computed.rs | 7 + hyperstack-macros/src/stream_spec/entity.rs | 44 +- hyperstack/Cargo.toml | 6 + hyperstack/src/lib.rs | 3 + interpreter/Cargo.toml | 3 + stacks/ore/.hyperstack/OreStream.stack.json | 187 +++++++- stacks/ore/src/stack.rs | 17 + 9 files changed, 693 insertions(+), 15 deletions(-) diff --git a/hyperstack-macros/src/ast/types.rs b/hyperstack-macros/src/ast/types.rs index 9fadb515..6d5652fb 100644 --- a/hyperstack-macros/src/ast/types.rs +++ b/hyperstack-macros/src/ast/types.rs @@ -60,7 +60,6 @@ pub enum PopulationStrategy { UniqueCount, } - /// Default discriminant size (8 bytes for Anchor). /// Used by InstructionDef serde default. fn default_discriminant_size() -> usize { @@ -261,6 +260,12 @@ pub enum ComputedExpr { // Context access - slot and timestamp from the update that triggered evaluation ContextSlot, ContextTimestamp, + + /// Keccak256 hash function for computing Ethereum-compatible hashes + /// Takes a byte array expression and returns the 32-byte hash as a Vec + Keccak256 { + expr: Box, + }, } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/hyperstack-macros/src/codegen/computed.rs b/hyperstack-macros/src/codegen/computed.rs index 8b823a0f..a363bd2b 100644 --- a/hyperstack-macros/src/codegen/computed.rs +++ b/hyperstack-macros/src/codegen/computed.rs @@ -93,6 +93,9 @@ fn extract_deps_recursive(expr: &ComputedExpr, section: &str, deps: &mut HashSet extract_deps_recursive(expr, section, deps); } ComputedExpr::ContextSlot | ComputedExpr::ContextTimestamp => {} + ComputedExpr::Keccak256 { expr } => { + extract_deps_recursive(expr, section, deps); + } } } @@ -115,6 +118,7 @@ fn contains_resolver_computed(expr: &ComputedExpr) -> bool { | ComputedExpr::U64FromLeBytes { bytes: expr } | ComputedExpr::U64FromBeBytes { bytes: expr } | ComputedExpr::JsonToBytes { expr } + | ComputedExpr::Keccak256 { expr } | ComputedExpr::Unary { expr, .. } => contains_resolver_computed(expr), ComputedExpr::Binary { left, right, .. } => { contains_resolver_computed(left) || contains_resolver_computed(right) @@ -492,20 +496,23 @@ pub fn generate_computed_expr_code(expr: &ComputedExpr) -> TokenStream { let method_name = method.as_str(); let arg_codes: Vec = args.iter().map(generate_computed_expr_code).collect(); + // Wrap in an immediately-invoked closure returning Option so that + // .ok()? works regardless of whether the surrounding context returns + // Result or Option. quote! { - { - let resolver_args = vec![#(hyperstack::runtime::serde_json::to_value(#arg_codes)?),*]; + (|| -> Option { + let resolver_args = vec![#(hyperstack::runtime::serde_json::to_value(#arg_codes).ok()?),*]; let resolver_value = hyperstack::runtime::hyperstack_interpreter::resolvers::evaluate_resolver_computed( #resolver_name, #method_name, &resolver_args, - )?; + ).ok()?; if resolver_value.is_null() { None } else { Some(resolver_value) } - } + })() } } ComputedExpr::Literal { value } => { @@ -646,5 +653,424 @@ pub fn generate_computed_expr_code(expr: &ComputedExpr) -> TokenStream { // __context_timestamp is i64, use directly quote! { __context_timestamp } } + ComputedExpr::Keccak256 { expr } => { + let inner = generate_computed_expr_code(expr); + quote! { + { + use hyperstack::runtime::sha3::{Digest, Keccak256}; + let bytes = #inner; + let hash = Keccak256::digest(&bytes); + hash.to_vec() + } + } + } + } +} + +/// Generate code for a computed expression that uses a local cache for intra-section field references. +/// This ensures dependent computed fields see the newly computed values within the same evaluation cycle. +pub fn generate_computed_expr_code_with_cache( + expr: &ComputedExpr, + section: &str, + computed_field_names: &[String], +) -> TokenStream { + match expr { + ComputedExpr::FieldRef { path } => { + let parts: Vec<&str> = path.split('.').collect(); + if parts.len() >= 2 && parts[0] == section { + // This is a field reference within the same section + let field_name = parts[1]; + if computed_field_names.contains(&field_name.to_string()) { + // It's a computed field - read from cache to get the latest value + let remaining_path: Vec<&str> = parts[2..].to_vec(); + if remaining_path.is_empty() { + return quote! { + computed_cache.get(#field_name).cloned() + }; + } else { + let path_tokens: Vec<_> = remaining_path + .iter() + .map(|p| quote! { .and_then(|v| v.get(#p)) }) + .collect(); + return quote! { + computed_cache.get(#field_name).cloned()#(#path_tokens)* + }; + } + } + } + // Not a computed field in this section - delegate to original implementation + generate_computed_expr_code(expr) + } + ComputedExpr::Binary { op, left, right } => { + let left_code = + generate_computed_expr_code_with_cache(left, section, computed_field_names); + let right_code = + generate_computed_expr_code_with_cache(right, section, computed_field_names); + let op_code = match op { + BinaryOp::Add => quote! { + }, + BinaryOp::Sub => quote! { - }, + BinaryOp::Mul => quote! { * }, + BinaryOp::Div => quote! { / }, + BinaryOp::Mod => quote! { % }, + BinaryOp::Gt => quote! { > }, + BinaryOp::Lt => quote! { < }, + BinaryOp::Gte => quote! { >= }, + BinaryOp::Lte => quote! { <= }, + BinaryOp::Eq => quote! { == }, + BinaryOp::Ne => quote! { != }, + BinaryOp::And => quote! { && }, + BinaryOp::Or => quote! { || }, + BinaryOp::Xor => quote! { ^ }, + BinaryOp::BitAnd => quote! { & }, + BinaryOp::BitOr => quote! { | }, + BinaryOp::Shl => quote! { << }, + BinaryOp::Shr => quote! { >> }, + }; + quote! { (#left_code #op_code #right_code) } + } + ComputedExpr::MethodCall { + expr: inner, + method, + args, + } => { + let inner_code = + generate_computed_expr_code_with_cache(inner, section, computed_field_names); + let method_ident = format_ident!("{}", method); + + // Special handling for .map() with closures - check if closure body references computed fields + if method == "map" && args.len() == 1 { + if let ComputedExpr::Closure { param, body } = &args[0] { + let param_ident = format_ident!("{}", param); + // Check if the closure body references any computed fields in this section + let body_deps = extract_field_dependencies(body, section); + let has_computed_deps: std::collections::HashSet = body_deps + .intersection(&computed_field_names.iter().cloned().collect()) + .cloned() + .collect(); + + // Closures in .map() return Option, so use option-safe code generation + let body_code = if has_computed_deps.is_empty() { + generate_option_safe_expr_code(body) + } else { + generate_computed_expr_code_with_cache_option_safe( + body, + section, + computed_field_names, + ) + }; + + return quote! { + { + let inner_result = #inner_code; + hyperstack::runtime::tracing::debug!(inner = ?inner_result, "[COMPUTED] Inner value before map"); + // Handle both arrays (Vec) and single values (u64) + let map_result: Option = inner_result.and_then(|v| { + if let Some(arr) = v.as_array() { + // Handle array: map over each element + hyperstack::runtime::tracing::debug!(array_len = arr.len(), "[COMPUTED] Mapping over array"); + let mapped: Vec<_> = arr + .iter() + .filter_map(|elem| { + elem.as_u64().and_then(|#param_ident| { + hyperstack::runtime::tracing::debug!(elem = #param_ident, "[COMPUTED] Processing array element"); + let result = #body_code; + hyperstack::runtime::serde_json::to_value(result).ok() + }) + }) + .collect(); + hyperstack::runtime::serde_json::to_value(mapped).ok() + } else { + // Handle single value + v.as_u64().and_then(|#param_ident| { + hyperstack::runtime::tracing::debug!(value = #param_ident, "[COMPUTED] Processing single value"); + let result = #body_code; + hyperstack::runtime::serde_json::to_value(result).ok() + }) + } + }); + hyperstack::runtime::tracing::debug!(result = ?map_result, "[COMPUTED] Map operation result"); + map_result + } + }; + } + } + + let arg_codes: Vec = args + .iter() + .map(|arg| { + generate_computed_expr_code_with_cache(arg, section, computed_field_names) + }) + .collect(); + + quote! { #inner_code.#method_ident(#(#arg_codes),*) } + } + ComputedExpr::Cast { + expr: inner, + to_type, + } => { + let inner_code = + generate_computed_expr_code_with_cache(inner, section, computed_field_names); + let type_ident = format_ident!("{}", to_type); + quote! { (#inner_code as #type_ident) } + } + ComputedExpr::Paren { expr: inner } => { + let inner_code = + generate_computed_expr_code_with_cache(inner, section, computed_field_names); + quote! { (#inner_code) } + } + ComputedExpr::UnwrapOr { + expr: inner, + default, + } => { + let inner_code = + generate_computed_expr_code_with_cache(inner, section, computed_field_names); + let default_num = match default { + serde_json::Value::Number(n) => { + if let Some(i) = n.as_i64() { + quote! { #i } + } else if let Some(u) = n.as_u64() { + quote! { #u } + } else { + let f = n.as_f64().unwrap_or(0.0); + quote! { #f } + } + } + serde_json::Value::Bool(b) => { + if *b { + quote! { 1i64 } + } else { + quote! { 0i64 } + } + } + _ => quote! { 0i64 }, + }; + quote! { + #inner_code.and_then(|v| v.as_i64().or_else(|| v.as_u64().map(|u| u as i64))).unwrap_or(#default_num) + } + } + ComputedExpr::Some { value } => { + let inner = + generate_computed_expr_code_with_cache(value, section, computed_field_names); + quote! { Some(#inner) } + } + ComputedExpr::None => { + quote! { None } + } + ComputedExpr::Unary { op, expr: inner } => { + let inner_code = + generate_computed_expr_code_with_cache(inner, section, computed_field_names); + match op { + UnaryOp::Not => quote! { !#inner_code }, + UnaryOp::ReverseBits => quote! { #inner_code.reverse_bits() }, + } + } + ComputedExpr::Keccak256 { expr: inner } => { + let inner_code = + generate_computed_expr_code_with_cache(inner, section, computed_field_names); + quote! { + { + use hyperstack::runtime::sha3::{Digest, Keccak256}; + let bytes = #inner_code; + let hash = Keccak256::digest(&bytes); + hash.to_vec() + } + } + } + ComputedExpr::U64FromLeBytes { bytes } => { + let bytes_code = + generate_computed_expr_code_with_cache(bytes, section, computed_field_names); + quote! { + { + let slice = #bytes_code; + let arr: [u8; 8] = slice.try_into().unwrap_or([0u8; 8]); + u64::from_le_bytes(arr) + } + } + } + ComputedExpr::ByteArray { bytes } => { + let byte_literals: Vec = bytes + .iter() + .map(|b| { + let byte_val = *b; + quote! { #byte_val } + }) + .collect(); + quote! { vec![#(#byte_literals),*] } + } + ComputedExpr::Var { name } => { + let name_ident = format_ident!("{}", name); + quote! { #name_ident } + } + ComputedExpr::Literal { value } => match value { + serde_json::Value::Number(n) => { + if let Some(u) = n.as_u64() { + quote! { #u } + } else if let Some(i) = n.as_i64() { + quote! { #i } + } else { + let num = n.as_f64().unwrap_or(0.0); + quote! { #num } + } + } + serde_json::Value::Bool(b) => { + quote! { #b } + } + serde_json::Value::Null => { + quote! { () } + } + _ => quote! { 0.0_f64 }, + }, + ComputedExpr::ResolverComputed { + resolver, + method, + args, + } => { + let resolver_name = resolver.as_str(); + let method_name = method.as_str(); + // Use cache-aware codegen for args so that intra-section computed + // field references (e.g. results.expires_at_slot_hash) read from + // computed_cache instead of the stale section_parent_state snapshot. + let arg_codes: Vec = args + .iter() + .map(|arg| { + generate_computed_expr_code_with_cache(arg, section, computed_field_names) + }) + .collect(); + quote! { + (|| -> Option { + let resolver_args = vec![#(hyperstack::runtime::serde_json::to_value(#arg_codes).ok()?),*]; + let resolver_value = hyperstack::runtime::hyperstack_interpreter::resolvers::evaluate_resolver_computed( + #resolver_name, + #method_name, + &resolver_args, + ).ok()?; + if resolver_value.is_null() { + None + } else { + Some(resolver_value) + } + })() + } + } + ComputedExpr::Closure { param, body } => { + let param_ident = format_ident!("{}", param); + let body_code = + generate_computed_expr_code_with_cache(body, section, computed_field_names); + quote! { |#param_ident| #body_code } + } + // Fallback for any unhandled expressions + _ => generate_computed_expr_code(expr), + } +} + +/// Option-safe version of generate_computed_expr_code_with_cache. +/// Use this when the generated code will be used inside a closure that returns Option. +fn generate_computed_expr_code_with_cache_option_safe( + expr: &ComputedExpr, + section: &str, + computed_field_names: &[String], +) -> TokenStream { + match expr { + ComputedExpr::FieldRef { path } => { + let parts: Vec<&str> = path.split('.').collect(); + if parts.len() >= 2 && parts[0] == section { + let field_name = parts[1]; + if computed_field_names.contains(&field_name.to_string()) { + let remaining_path: Vec<&str> = parts[2..].to_vec(); + if remaining_path.is_empty() { + return quote! { + computed_cache.get(#field_name).cloned() + }; + } else { + let path_tokens: Vec<_> = remaining_path + .iter() + .map(|p| quote! { .and_then(|v| v.get(#p)) }) + .collect(); + return quote! { + computed_cache.get(#field_name).cloned()#(#path_tokens)* + }; + } + } + } + generate_option_safe_expr_code(expr) + } + ComputedExpr::Binary { op, left, right } => { + let left_code = generate_computed_expr_code_with_cache_option_safe( + left, + section, + computed_field_names, + ); + let right_code = generate_computed_expr_code_with_cache_option_safe( + right, + section, + computed_field_names, + ); + let op_code = match op { + BinaryOp::Add => quote! { + }, + BinaryOp::Sub => quote! { - }, + BinaryOp::Mul => quote! { * }, + BinaryOp::Div => quote! { / }, + BinaryOp::Mod => quote! { % }, + BinaryOp::Gt => quote! { > }, + BinaryOp::Lt => quote! { < }, + BinaryOp::Gte => quote! { >= }, + BinaryOp::Lte => quote! { <= }, + BinaryOp::Eq => quote! { == }, + BinaryOp::Ne => quote! { != }, + BinaryOp::And => quote! { && }, + BinaryOp::Or => quote! { || }, + BinaryOp::Xor => quote! { ^ }, + BinaryOp::BitAnd => quote! { & }, + BinaryOp::BitOr => quote! { | }, + BinaryOp::Shl => quote! { << }, + BinaryOp::Shr => quote! { >> }, + }; + quote! { (#left_code #op_code #right_code) } + } + ComputedExpr::ResolverComputed { + resolver, + method, + args, + } => { + let resolver_name = resolver.as_str(); + let method_name = method.as_str(); + let arg_codes: Vec = + args.iter().map(generate_option_safe_expr_code).collect(); + quote! { + { + let resolver_args = vec![#(hyperstack::runtime::serde_json::to_value(#arg_codes).ok()?),*]; + let resolver_value = hyperstack::runtime::hyperstack_interpreter::resolvers::evaluate_resolver_computed( + #resolver_name, + #method_name, + &resolver_args, + ).ok()?; + if resolver_value.is_null() { + None + } else { + Some(resolver_value) + } + } + } + } + ComputedExpr::Var { name } => { + let name_ident = format_ident!("{}", name); + quote! { #name_ident } + } + ComputedExpr::Literal { value } => match value { + serde_json::Value::Number(n) => { + if let Some(u) = n.as_u64() { + quote! { #u } + } else if let Some(i) = n.as_i64() { + quote! { #i } + } else { + let num = n.as_f64().unwrap_or(0.0); + quote! { #num } + } + } + serde_json::Value::Bool(b) => quote! { #b }, + serde_json::Value::Null => quote! { () }, + _ => quote! { 0.0_f64 }, + }, + _ => generate_option_safe_expr_code(expr), } } diff --git a/hyperstack-macros/src/stream_spec/computed.rs b/hyperstack-macros/src/stream_spec/computed.rs index 542eac92..85bcd3a4 100644 --- a/hyperstack-macros/src/stream_spec/computed.rs +++ b/hyperstack-macros/src/stream_spec/computed.rs @@ -34,6 +34,7 @@ pub fn parse_computed_expression(tokens: &proc_macro2::TokenStream) -> ComputedE fn resolver_for_method(method: &str) -> Option<&'static str> { match method { "ui_amount" | "raw_amount" => Some("TokenMetadata"), + "slot_hash" | "keccak_rng" => Some("SlotHash"), _ => None, } } @@ -141,6 +142,9 @@ pub fn qualify_field_refs(expr: ComputedExpr, section: &str) -> ComputedExpr { }, ComputedExpr::ContextSlot => ComputedExpr::ContextSlot, ComputedExpr::ContextTimestamp => ComputedExpr::ContextTimestamp, + ComputedExpr::Keccak256 { expr } => ComputedExpr::Keccak256 { + expr: Box::new(qualify_field_refs(*expr, section)), + }, } } @@ -380,6 +384,9 @@ fn resolve_bindings_in_expr(expr: ComputedExpr, bindings: &HashSet) -> C ComputedExpr::JsonToBytes { expr } => ComputedExpr::JsonToBytes { expr: Box::new(resolve_bindings_in_expr(*expr, bindings)), }, + ComputedExpr::Keccak256 { expr } => ComputedExpr::Keccak256 { + expr: Box::new(resolve_bindings_in_expr(*expr, bindings)), + }, ComputedExpr::Closure { param, body } => { // The closure param is also a binding let mut new_bindings = bindings.clone(); diff --git a/hyperstack-macros/src/stream_spec/entity.rs b/hyperstack-macros/src/stream_spec/entity.rs index b43bf5d0..b489534a 100644 --- a/hyperstack-macros/src/stream_spec/entity.rs +++ b/hyperstack-macros/src/stream_spec/entity.rs @@ -1005,7 +1005,13 @@ fn generate_computed_fields_hook( // Get dependencies for this section let deps = section_dependencies.get(section).cloned().unwrap_or_default(); - let _section_str = section.as_str(); + let section_str = section.as_str(); + + // Collect all computed field names in this section for cache tracking + let computed_field_names: Vec = fields.iter().map(|(field_name, _expression, _field_type)| { + field_name.clone() + }).collect(); + let field_evaluations: Vec<_> = fields.iter().map(|(field_name, expression, field_type)| { let field_str = field_name.as_str(); let field_ident = format_ident!("{}", field_name); @@ -1016,16 +1022,30 @@ fn generate_computed_fields_hook( let parsed_expr = parse_computed_expression(expression); // Qualify the expression with the section prefix for unqualified field refs let qualified_expr = qualify_field_refs(parsed_expr, section); - let expr_code = crate::codegen::generate_computed_expr_code(&qualified_expr); + // Use cache-aware code generation for intra-section dependencies + let expr_code = crate::codegen::generate_computed_expr_code_with_cache(&qualified_expr, section_str, &computed_field_names); quote! { // Evaluate: #field_name + hyperstack::runtime::tracing::info!( + section = #section_str, + field = #field_str, + "[COMPUTED] Evaluating computed field" + ); let computed_value = { - // state is the full entity JSON state + // state is the full entity JSON state (for cross-section references) let state = §ion_parent_state; #expr_code }; let serialized_value = hyperstack::runtime::serde_json::to_value(&computed_value)?; + hyperstack::runtime::tracing::info!( + section = #section_str, + field = #field_str, + value = %serialized_value, + "[COMPUTED] Computed field result" + ); + // Update cache so dependent fields can read this value + computed_cache.insert(#field_str.to_string(), serialized_value.clone()); section_obj.insert(#field_str.to_string(), serialized_value); let #field_ident: #field_type = section_obj @@ -1076,7 +1096,13 @@ fn generate_computed_fields_hook( extract_field!(whale_trade_count, u64); extract_field!(average_trade_size, f64); - // Evaluate computed fields + // Initialize cache with current section values for intra-section computed field dependencies + let mut computed_cache: std::collections::HashMap = std::collections::HashMap::new(); + for (key, value) in section_obj.iter() { + computed_cache.insert(key.clone(), value.clone()); + } + + // Evaluate computed fields (they read from cache for intra-section dependencies) #(#field_evaluations)* Ok(()) @@ -1095,7 +1121,8 @@ fn generate_computed_fields_hook( // Generate pre-extraction of cross-section data // These return Option so we can gracefully skip evaluation if a dependency doesn't exist yet let dep_extractions: Vec<_> = deps.iter().map(|dep_section| { - let dep_section_ident = format_ident!("{}", dep_section); + // Use a unique variable name to avoid shadowing issues + let dep_section_ident = format_ident!("{}_section", dep_section); let dep_section_str = dep_section.as_str(); let section_struct_ident = format_ident!("{}Section", dep_section); quote! { @@ -1119,13 +1146,14 @@ fn generate_computed_fields_hook( } else { // Has cross-section dependencies - extract first, then compute // If ANY dependency is missing, skip evaluation (the computed fields will remain None) - let dep_param_names: Vec<_> = deps.iter().map(|dep| format_ident!("{}", dep)).collect(); + let dep_param_names: Vec<_> = deps.iter().map(|dep| format_ident!("{}_section", dep)).collect(); let dep_checks: Vec<_> = deps.iter().map(|dep| { - let dep_ident = format_ident!("{}", dep); + let dep_ident = format_ident!("{}_section", dep); quote! { #dep_ident.is_some() } }).collect(); let dep_unwraps: Vec<_> = deps.iter().map(|dep| { - let dep_ident = format_ident!("{}", dep); + // Use consistent variable naming + let dep_ident = format_ident!("{}_section", dep); quote! { let #dep_ident = #dep_ident.unwrap(); } }).collect(); quote! { diff --git a/hyperstack/Cargo.toml b/hyperstack/Cargo.toml index cd86185f..b3fbfb6a 100644 --- a/hyperstack/Cargo.toml +++ b/hyperstack/Cargo.toml @@ -37,8 +37,11 @@ bytemuck = { version = "1.21", features = ["derive", "min_const_generics"], opti yellowstone-vixen = { workspace = true, optional = true } yellowstone-vixen-core = { workspace = true, optional = true } yellowstone-vixen-yellowstone-grpc-source = { workspace = true, optional = true } +yellowstone-grpc-client = { workspace = true, optional = true } +yellowstone-grpc-proto = { workspace = true, optional = true } reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls"], optional = true } futures = { version = "0.3", optional = true } +sha3 = { version = "0.10", optional = true } [features] default = ["interpreter", "macros", "server"] @@ -60,6 +63,9 @@ runtime = [ "dep:yellowstone-vixen", "dep:yellowstone-vixen-core", "dep:yellowstone-vixen-yellowstone-grpc-source", + "dep:yellowstone-grpc-client", + "dep:yellowstone-grpc-proto", "dep:reqwest", "dep:futures", + "dep:sha3", ] diff --git a/hyperstack/src/lib.rs b/hyperstack/src/lib.rs index 24d69802..97e6be94 100644 --- a/hyperstack/src/lib.rs +++ b/hyperstack/src/lib.rs @@ -69,9 +69,12 @@ pub mod runtime { pub use reqwest; pub use serde; pub use serde_json; + pub use sha3; pub use smallvec; pub use tokio; pub use tracing; + pub use yellowstone_grpc_client; + pub use yellowstone_grpc_proto; pub use yellowstone_vixen; pub use yellowstone_vixen_core; pub use yellowstone_vixen_yellowstone_grpc_source; diff --git a/interpreter/Cargo.toml b/interpreter/Cargo.toml index 60dbaaf5..f8b58ae1 100644 --- a/interpreter/Cargo.toml +++ b/interpreter/Cargo.toml @@ -24,7 +24,10 @@ hex = "0.4" bs58 = "0.5" lru = "0.12" sha2 = "0.10" +sha3 = "0.10" tracing = "0.1" +tokio = { version = "1.0", features = ["sync"] } +once_cell = "1.20" percent-encoding = "2" reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } futures = "0.3" diff --git a/stacks/ore/.hyperstack/OreStream.stack.json b/stacks/ore/.hyperstack/OreStream.stack.json index b8144570..9c1f1b10 100644 --- a/stacks/ore/.hyperstack/OreStream.stack.json +++ b/stacks/ore/.hyperstack/OreStream.stack.json @@ -3053,6 +3053,24 @@ }, "transform": null, "population": "LastWrite" + }, + { + "target_path": "results.slot_hash_bytes", + "source": { + "FromSource": { + "path": { + "segments": [ + "slot_hash" + ], + "offsets": null + }, + "default": null, + "transform": null + } + }, + "transform": null, + "population": "LastWrite", + "emit": false } ], "conditions": [], @@ -3361,6 +3379,27 @@ "source_path": null, "resolved_type": null }, + { + "field_name": "slot_hash_bytes", + "rust_type_name": "Option < Vec < u8 > >", + "base_type": "Array", + "is_optional": true, + "is_array": true, + "inner_type": "Vec < u8 >", + "source_path": null, + "resolved_type": null, + "emit": false + }, + { + "field_name": "expires_at_slot_hash", + "rust_type_name": "Option < Vec < u8 > >", + "base_type": "Array", + "is_optional": true, + "is_array": true, + "inner_type": "Vec < u8 >", + "source_path": null, + "resolved_type": null + }, { "field_name": "rng", "rust_type_name": "Option < u64 >", @@ -3390,6 +3429,26 @@ "inner_type": "bool", "source_path": null, "resolved_type": null + }, + { + "field_name": "pre_reveal_rng", + "rust_type_name": "Option < u64 >", + "base_type": "Integer", + "is_optional": true, + "is_array": false, + "inner_type": "u64", + "source_path": null, + "resolved_type": null + }, + { + "field_name": "pre_reveal_winning_square", + "rust_type_name": "Option < u64 >", + "base_type": "Integer", + "is_optional": true, + "is_array": false, + "inner_type": "u64", + "source_path": null, + "resolved_type": null } ], "is_nested_struct": false, @@ -3707,6 +3766,36 @@ "source_path": null, "resolved_type": null }, + "results.expires_at_slot_hash": { + "field_name": "expires_at_slot_hash", + "rust_type_name": "Option < Vec < u8 > >", + "base_type": "Array", + "is_optional": true, + "is_array": true, + "inner_type": "Vec < u8 >", + "source_path": null, + "resolved_type": null + }, + "results.pre_reveal_rng": { + "field_name": "pre_reveal_rng", + "rust_type_name": "Option < u64 >", + "base_type": "Integer", + "is_optional": true, + "is_array": false, + "inner_type": "u64", + "source_path": null, + "resolved_type": null + }, + "results.pre_reveal_winning_square": { + "field_name": "pre_reveal_winning_square", + "rust_type_name": "Option < u64 >", + "base_type": "Integer", + "is_optional": true, + "is_array": false, + "inner_type": "u64", + "source_path": null, + "resolved_type": null + }, "results.rent_payer": { "field_name": "rent_payer", "rust_type_name": "Option < String >", @@ -3737,6 +3826,17 @@ "source_path": null, "resolved_type": null }, + "results.slot_hash_bytes": { + "field_name": "slot_hash_bytes", + "rust_type_name": "Option < Vec < u8 > >", + "base_type": "Array", + "is_optional": true, + "is_array": true, + "inner_type": "Vec < u8 >", + "source_path": null, + "resolved_type": null, + "emit": false + }, "results.top_miner": { "field_name": "top_miner", "rust_type_name": "Option < String >", @@ -4090,9 +4190,12 @@ "state.total_winnings", "state.deployed_per_square_ui", "results.top_miner_reward", + "results.expires_at_slot_hash", "results.rng", "results.winning_square", "results.did_hit_motherlode", + "results.pre_reveal_rng", + "results.pre_reveal_winning_square", "treasury.motherlode" ], "computed_field_specs": [ @@ -4377,6 +4480,23 @@ }, "result_type": "Option < f64 >" }, + { + "target_path": "results.expires_at_slot_hash", + "expression": { + "ResolverComputed": { + "resolver": "SlotHash", + "method": "slot_hash", + "args": [ + { + "FieldRef": { + "path": "state.expires_at" + } + } + ] + } + }, + "result_type": "Option < Vec < u8 > >" + }, { "target_path": "results.rng", "expression": { @@ -4762,6 +4882,69 @@ }, "result_type": "Option < bool >" }, + { + "target_path": "results.pre_reveal_rng", + "expression": { + "ResolverComputed": { + "resolver": "SlotHash", + "method": "keccak_rng", + "args": [ + { + "FieldRef": { + "path": "results.expires_at_slot_hash" + } + }, + { + "FieldRef": { + "path": "entropy.resolved_seed" + } + }, + { + "FieldRef": { + "path": "entropy.entropy_samples" + } + } + ] + } + }, + "result_type": "Option < u64 >" + }, + { + "target_path": "results.pre_reveal_winning_square", + "expression": { + "MethodCall": { + "expr": { + "FieldRef": { + "path": "results.pre_reveal_rng" + } + }, + "method": "map", + "args": [ + { + "Closure": { + "param": "r", + "body": { + "Binary": { + "op": "Mod", + "left": { + "Var": { + "name": "r" + } + }, + "right": { + "Literal": { + "value": 25 + } + } + } + } + } + } + ] + } + }, + "result_type": "Option < u64 >" + }, { "target_path": "treasury.motherlode", "expression": { @@ -4785,7 +4968,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "93f4b9ed6412e15ba1d92475355f5b1d2f5b8b81358ec01e620dbf50ff0b79dd", + "content_hash": "7a868be08df6c5f84524662785b0f3c6d69c3ce57a11e1e9a92c31efdbfdd466", "views": [ { "id": "OreRound/latest", @@ -8867,5 +9050,5 @@ ] } ], - "content_hash": "f6e4c04a606dddbd67be4924d7fa529569af4bef53760a7259f5da1914ea2da6" + "content_hash": "f55e8993b0bd69e07f04787cc9a6b513df6d784796fcdef555073fa7f58cdbb8" } \ No newline at end of file diff --git a/stacks/ore/src/stack.rs b/stacks/ore/src/stack.rs index 708762c2..f754cf38 100644 --- a/stacks/ore/src/stack.rs +++ b/stacks/ore/src/stack.rs @@ -96,6 +96,15 @@ pub mod ore_stream { #[map(ore_sdk::accounts::Round::slot_hash, strategy = LastWrite, transform = Base58Encode)] pub slot_hash: Option, + // Raw bytes of slot_hash for RNG calculation (from Round account, not entropy) + #[map(ore_sdk::accounts::Round::slot_hash, strategy = LastWrite, emit = false)] + pub slot_hash_bytes: Option>, + + // Computed field that fetches the slot hash at expires_at from our cache + // This is populated from the SlotHashes sysvar via gRPC subscription + #[computed(state.expires_at.slot_hash())] + pub expires_at_slot_hash: Option>, + #[computed( let hash = entropy.entropy_value_bytes.to_bytes(); if (hash.len() as u64) != 32 { @@ -121,6 +130,14 @@ pub mod ore_stream { #[computed(results.rng.map(|r| r.reverse_bits() % 625 == 0))] pub did_hit_motherlode: Option, + + // Pre-reveal RNG calculation using resolved seed from API + // keccak_rng resolver: keccak256(slot_hash || seed || samples_le_bytes) → XOR-folded u64 + #[computed(results.expires_at_slot_hash.keccak_rng(entropy.resolved_seed, entropy.entropy_samples))] + pub pre_reveal_rng: Option, + + #[computed(results.pre_reveal_rng.map(|r| r % 25))] + pub pre_reveal_winning_square: Option, } #[derive(Debug, Clone, Serialize, Deserialize, Stream)] From a11c6695f66f8951e6aa5635649de0047536be00 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Tue, 17 Mar 2026 11:52:17 +0000 Subject: [PATCH 05/60] feat: add skip_resolvers mechanism for stale data reprocessing - Add skip_resolvers flag to UpdateContext for reprocessed cached data - Create UpdateContext::new_reprocessed() for PDA mapping change scenarios - Add is_stale_reprocess flag to PendingAccountUpdate - Skip QueueResolver opcodes when processing stale reprocessed data - Add slot_hash_cache module for efficient slot hash lookups --- interpreter/src/ast.rs | 6 + interpreter/src/lib.rs | 4 + interpreter/src/resolvers.rs | 203 +++++++++++- interpreter/src/scheduler.rs | 68 +++- interpreter/src/slot_hash_cache.rs | 58 ++++ interpreter/src/vm.rs | 481 ++++++++++++++++++++++++++++- 6 files changed, 801 insertions(+), 19 deletions(-) create mode 100644 interpreter/src/slot_hash_cache.rs diff --git a/interpreter/src/ast.rs b/interpreter/src/ast.rs index bf50da0e..bbc6a83b 100644 --- a/interpreter/src/ast.rs +++ b/interpreter/src/ast.rs @@ -332,6 +332,12 @@ pub enum ComputedExpr { ContextSlot, /// Access the unix timestamp from the current update context ContextTimestamp, + + /// Keccak256 hash function for computing Ethereum-compatible hashes + /// Takes a byte array expression and returns the 32-byte hash as a Vec + Keccak256 { + expr: Box, + }, } /// Binary operators for computed expressions diff --git a/interpreter/src/lib.rs b/interpreter/src/lib.rs index ca20233c..a29cfec3 100644 --- a/interpreter/src/lib.rs +++ b/interpreter/src/lib.rs @@ -33,11 +33,15 @@ pub mod proto_router; pub mod resolvers; pub mod rust; pub mod scheduler; +pub mod slot_hash_cache; pub mod spec_trait; pub mod typescript; pub mod vm; pub mod vm_metrics; +// Re-export slot hash cache functions +pub use slot_hash_cache::{get_slot_hash, record_slot_hash}; + pub use canonical_log::{CanonicalLog, LogLevel}; pub use metrics_context::{FieldAccessor, FieldRef, MetricsContext}; pub use resolvers::{ diff --git a/interpreter/src/resolvers.rs b/interpreter/src/resolvers.rs index b8226195..be30b9f5 100644 --- a/interpreter/src/resolvers.rs +++ b/interpreter/src/resolvers.rs @@ -252,9 +252,10 @@ impl ResolverRegistry { | crate::ast::ComputedExpr::Some { value: expr } | crate::ast::ComputedExpr::Slice { expr, .. } | crate::ast::ComputedExpr::Index { expr, .. } - | crate::ast::ComputedExpr::U64FromLeBytes { bytes: expr } + | crate::ast::ComputedExpr::U64FromLeBytes { bytes: expr } | crate::ast::ComputedExpr::U64FromBeBytes { bytes: expr } | crate::ast::ComputedExpr::JsonToBytes { expr } + | crate::ast::ComputedExpr::Keccak256 { expr } | crate::ast::ComputedExpr::Unary { expr, .. } => { self.validate_computed_expr(expr, errors); } @@ -291,6 +292,7 @@ impl ResolverRegistry { static BUILTIN_RESOLVER_REGISTRY: OnceLock = OnceLock::new(); pub fn register_builtin_resolvers(registry: &mut ResolverRegistry) { + registry.register(Box::new(SlotHashResolver)); registry.register(Box::new(TokenMetadataResolver)); } @@ -695,8 +697,27 @@ pub async fn resolve_url_batch( .map(|v| (v.url.clone(), v.method.clone())) .collect(); + // Log all URLs being fetched + for (url, method) in &batch_input { + tracing::info!( + url = %url, + method = ?method, + "[RESOLVER] Fetching URL" + ); + } + let results = url_client.resolve_batch(&batch_input).await; + // Log results summary + let success_count = results.len(); + let fail_count = batch_input.len() - success_count; + tracing::info!( + success = success_count, + failed = fail_count, + total = batch_input.len(), + "[RESOLVER] URL batch fetch completed" + ); + // Apply results to VM state, requeue anything that didn't resolve let mut vm = vm.lock().unwrap_or_else(|e| e.into_inner()); let mut mutations = Vec::new(); @@ -705,8 +726,21 @@ pub async fn resolve_url_batch( for entry in valid { match results.get(&entry.url) { Some(resolved_value) => { + tracing::info!( + url = %entry.url, + cache_key = %entry.request.cache_key, + response = %resolved_value, + "[RESOLVER] Applying resolver result to state" + ); match vm.apply_resolver_result(bytecode, &entry.request.cache_key, resolved_value.clone()) { - Ok(mut new_mutations) => mutations.append(&mut new_mutations), + Ok(mut new_mutations) => { + tracing::info!( + url = %entry.url, + mutation_count = new_mutations.len(), + "[RESOLVER] Successfully applied resolver result" + ); + mutations.append(&mut new_mutations) + } Err(err) => { tracing::warn!(url = %entry.url, "Failed to apply URL resolver result: {}", err); } @@ -726,6 +760,171 @@ pub async fn resolve_url_batch( mutations } +/// Resolver for looking up slot hashes by slot number +/// Uses the global slot hash cache populated from gRPC stream +struct SlotHashResolver; + +const SLOT_HASH_METHODS: &[ResolverComputedMethod] = &[ + ResolverComputedMethod { + name: "slot_hash", + arg_count: 1, + }, + ResolverComputedMethod { + name: "keccak_rng", + arg_count: 3, + }, +]; + +impl SlotHashResolver { + /// Compute keccak256(slot_hash || seed || samples_le_bytes) and XOR-fold into a u64. + /// args[0] = slot_hash bytes (JSON array of 32 bytes) + /// args[1] = seed bytes (JSON array of 32 bytes) + /// args[2] = samples (u64 number) + fn evaluate_keccak_rng(args: &[Value]) -> Result> { + if args.len() != 3 { + return Ok(Value::Null); + } + + let slot_hash = Self::json_array_to_bytes(&args[0], 32); + let seed = Self::json_array_to_bytes(&args[1], 32); + let samples = match &args[2] { + Value::Number(n) => n.as_u64(), + _ => None, + }; + + let (slot_hash, seed, samples) = match (slot_hash, seed, samples) { + (Some(s), Some(sd), Some(sm)) => (s, sd, sm), + _ => return Ok(Value::Null), + }; + + // Build input: slot_hash[32] || seed[32] || samples_le_bytes[8] + let mut input = Vec::with_capacity(72); + input.extend_from_slice(&slot_hash); + input.extend_from_slice(&seed); + input.extend_from_slice(&samples.to_le_bytes()); + + // keccak256 + use sha3::{Digest, Keccak256}; + let hash = Keccak256::digest(&input); + + if hash.len() < 32 { + return Ok(Value::Null); + } + + // XOR-fold four u64 chunks + let r1 = u64::from_le_bytes(hash[0..8].try_into()?); + let r2 = u64::from_le_bytes(hash[8..16].try_into()?); + let r3 = u64::from_le_bytes(hash[16..24].try_into()?); + let r4 = u64::from_le_bytes(hash[24..32].try_into()?); + let rng = r1 ^ r2 ^ r3 ^ r4; + + Ok(Value::Number(rng.into())) + } + + /// Extract a byte array of expected length from a JSON array value. + fn json_array_to_bytes(value: &Value, expected_len: usize) -> Option> { + let arr = value.as_array()?; + let bytes: Vec = arr + .iter() + .filter_map(|v| v.as_u64().map(|n| n as u8)) + .collect(); + if bytes.len() == expected_len { + Some(bytes) + } else { + None + } + } + + fn evaluate_slot_hash(args: &[Value]) -> Result> { + if args.len() != 1 { + return Ok(Value::Null); + } + + let slot = match &args[0] { + Value::Number(n) => n.as_u64().unwrap_or(0), + _ => return Ok(Value::Null), + }; + + if slot == 0 { + return Ok(Value::Null); + } + + // Try to get the slot hash from the global cache + // Note: This runs in an async context but the resolver interface is sync + // We use block_in_place to avoid blocking the runtime + let slot_hash = tokio::task::block_in_place(|| { + tokio::runtime::Handle::current().block_on(async { + crate::slot_hash_cache::get_slot_hash(slot).await + }) + }); + + match slot_hash { + Some(hash) => { + // Convert the base58 encoded slot hash to bytes + // The slot hash is a 32-byte value base58 encoded + match bs58::decode(&hash).into_vec() { + Ok(bytes) if bytes.len() == 32 => { + // Return as JSON array of bytes + let json_bytes: Vec = bytes.into_iter().map(|b| Value::Number(b.into())).collect(); + Ok(Value::Array(json_bytes)) + } + _ => { + tracing::warn!(slot = slot, hash = hash, "Failed to decode slot hash"); + Ok(Value::Null) + } + } + } + None => { + tracing::debug!(slot = slot, "Slot hash not found in cache"); + Ok(Value::Null) + } + } + } +} + +impl ResolverDefinition for SlotHashResolver { + fn name(&self) -> &'static str { + "SlotHash" + } + + fn output_type(&self) -> &'static str { + "SlotHash" + } + + fn computed_methods(&self) -> &'static [ResolverComputedMethod] { + SLOT_HASH_METHODS + } + + fn evaluate_computed( + &self, + method: &str, + args: &[Value], + ) -> std::result::Result> { + match method { + "slot_hash" => Self::evaluate_slot_hash(args), + "keccak_rng" => Self::evaluate_keccak_rng(args), + _ => Err(format!("Unknown SlotHash method '{}'", method).into()), + } + } + + fn typescript_interface(&self) -> Option<&'static str> { + Some( + r#"export interface SlotHash { + hash: string; +}"#, + ) + } + + fn typescript_schema(&self) -> Option { + Some(ResolverTypeScriptSchema { + name: "SlotHashSchema", + definition: r#"export const SlotHashSchema = z.object({ + hash: z.string(), +});"#, + }) + } +} + struct TokenMetadataResolver; const TOKEN_METADATA_METHODS: &[ResolverComputedMethod] = &[ diff --git a/interpreter/src/scheduler.rs b/interpreter/src/scheduler.rs index 0f4e3957..2fdf032f 100644 --- a/interpreter/src/scheduler.rs +++ b/interpreter/src/scheduler.rs @@ -53,14 +53,32 @@ impl SlotScheduler { let due = std::mem::replace(&mut self.callbacks, future); let mut result = Vec::new(); - for (_slot, callbacks) in due { + let mut total_count = 0; + for (slot, callbacks) in due { + total_count += callbacks.len(); for cb in callbacks { let dedup_key = Self::dedup_key(&cb); + tracing::info!( + current_slot = current_slot, + scheduled_slot = slot, + entity = %cb.entity_name, + primary_key = %cb.primary_key, + resolver = ?cb.resolver, + "[RESOLVER] Scheduled callback firing" + ); self.registered.remove(&dedup_key); self.slot_index.remove(&dedup_key); result.push(cb); } } + if total_count > 0 { + tracing::info!( + current_slot = current_slot, + count = total_count, + pending = self.pending_count(), + "[RESOLVER] Total scheduled callbacks fired for current slot" + ); + } result } @@ -74,11 +92,17 @@ impl SlotScheduler { fn dedup_key(cb: &ScheduledCallback) -> DedupKey { let resolver_key = serde_json::to_string(&cb.resolver).unwrap_or_default(); - let condition_key = cb.condition.as_ref() + let condition_key = cb + .condition + .as_ref() .map(|c| serde_json::to_string(c).unwrap_or_default()) .unwrap_or_default(); let pk_key = cb.primary_key.to_string(); - (cb.entity_name.clone(), pk_key, format!("{}:{}", resolver_key, condition_key)) + ( + cb.entity_name.clone(), + pk_key, + format!("{}:{}", resolver_key, condition_key), + ) } } @@ -92,7 +116,11 @@ pub fn evaluate_condition(condition: &ResolverCondition, state: &Value) -> bool /// parameter positions. Query strings permit additional chars (`!`, `$`, `'`, `(`, `)`, `+`, etc.) /// that will be over-encoded. This is safe for the current numeric/base58 use-cases but may need /// a path-vs-query split if general-purpose URL templates are needed. -const URL_SEGMENT_SET: &AsciiSet = &NON_ALPHANUMERIC.remove(b'-').remove(b'.').remove(b'_').remove(b'~'); +const URL_SEGMENT_SET: &AsciiSet = &NON_ALPHANUMERIC + .remove(b'-') + .remove(b'.') + .remove(b'_') + .remove(b'~'); pub fn build_url_from_template(template: &[UrlTemplatePart], state: &Value) -> Option { let mut url = String::new(); @@ -130,10 +158,34 @@ fn evaluate_comparison(field_value: &Value, op: &ComparisonOp, condition_value: match op { ComparisonOp::Equal => field_value == condition_value, ComparisonOp::NotEqual => field_value != condition_value, - ComparisonOp::GreaterThan => compare_numeric(field_value, condition_value, |a, b| a > b, |a, b| a > b, |a, b| a > b), - ComparisonOp::GreaterThanOrEqual => compare_numeric(field_value, condition_value, |a, b| a >= b, |a, b| a >= b, |a, b| a >= b), - ComparisonOp::LessThan => compare_numeric(field_value, condition_value, |a, b| a < b, |a, b| a < b, |a, b| a < b), - ComparisonOp::LessThanOrEqual => compare_numeric(field_value, condition_value, |a, b| a <= b, |a, b| a <= b, |a, b| a <= b), + ComparisonOp::GreaterThan => compare_numeric( + field_value, + condition_value, + |a, b| a > b, + |a, b| a > b, + |a, b| a > b, + ), + ComparisonOp::GreaterThanOrEqual => compare_numeric( + field_value, + condition_value, + |a, b| a >= b, + |a, b| a >= b, + |a, b| a >= b, + ), + ComparisonOp::LessThan => compare_numeric( + field_value, + condition_value, + |a, b| a < b, + |a, b| a < b, + |a, b| a < b, + ), + ComparisonOp::LessThanOrEqual => compare_numeric( + field_value, + condition_value, + |a, b| a <= b, + |a, b| a <= b, + |a, b| a <= b, + ), } } diff --git a/interpreter/src/slot_hash_cache.rs b/interpreter/src/slot_hash_cache.rs new file mode 100644 index 00000000..1bb5852e --- /dev/null +++ b/interpreter/src/slot_hash_cache.rs @@ -0,0 +1,58 @@ +//! Shared slot hash cache accessible from both server and interpreter +//! +//! This module provides a global cache for slot hashes that is populated +//! by the gRPC stream and accessed by computed field resolvers. + +use std::collections::HashMap; +use std::sync::Arc; +use tokio::sync::RwLock; + +/// Global slot hash cache +static SLOT_HASH_CACHE: once_cell::sync::Lazy>>> = + once_cell::sync::Lazy::new(|| Arc::new(RwLock::new(HashMap::new()))); + +/// Maximum number of slot hashes to keep in cache (prevent unbounded growth) +const MAX_CACHE_SIZE: usize = 50000; + +/// Record a slot hash in the global cache +pub async fn record_slot_hash(slot: u64, slot_hash: String) { + let mut cache: tokio::sync::RwLockWriteGuard<'_, HashMap> = SLOT_HASH_CACHE.write().await; + cache.insert(slot, slot_hash); + + // Prune old entries if cache is too large + if cache.len() > MAX_CACHE_SIZE { + // Remove oldest 25% of entries + let slots_to_remove: Vec = cache + .keys() + .take(cache.len() / 4) + .copied() + .collect(); + for slot in slots_to_remove { + cache.remove(&slot); + } + } +} + +/// Get a slot hash from the global cache +pub async fn get_slot_hash(slot: u64) -> Option { + let cache: tokio::sync::RwLockReadGuard<'_, HashMap> = SLOT_HASH_CACHE.read().await; + cache.get(&slot).cloned() +} + +/// Check if a slot hash is in the cache +pub async fn has_slot_hash(slot: u64) -> bool { + let cache: tokio::sync::RwLockReadGuard<'_, HashMap> = SLOT_HASH_CACHE.read().await; + cache.contains_key(&slot) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_slot_hash_cache() { + record_slot_hash(100, "test_hash".to_string()).await; + assert_eq!(get_slot_hash(100).await, Some("test_hash".to_string())); + assert_eq!(get_slot_hash(101).await, None); + } +} \ No newline at end of file diff --git a/interpreter/src/vm.rs b/interpreter/src/vm.rs index a7d2e480..9cc35196 100644 --- a/interpreter/src/vm.rs +++ b/interpreter/src/vm.rs @@ -29,6 +29,10 @@ pub struct UpdateContext { /// Transaction index for instruction updates (orders transactions within a slot) /// Used for staleness detection to reject out-of-order updates pub txn_index: Option, + /// When true, QueueResolver opcodes are skipped during handler execution. + /// Set for reprocessed cached data from PDA mapping changes to prevent + /// stale data from triggering resolvers or locking in wrong values via SetOnce. + pub skip_resolvers: bool, /// Additional custom metadata that can be added without breaking changes pub metadata: HashMap, } @@ -42,6 +46,7 @@ impl UpdateContext { timestamp: None, write_version: None, txn_index: None, + skip_resolvers: false, metadata: HashMap::new(), } } @@ -54,6 +59,7 @@ impl UpdateContext { timestamp: Some(timestamp), write_version: None, txn_index: None, + skip_resolvers: false, metadata: HashMap::new(), } } @@ -66,6 +72,7 @@ impl UpdateContext { timestamp: None, write_version: Some(write_version), txn_index: None, + skip_resolvers: false, metadata: HashMap::new(), } } @@ -78,6 +85,22 @@ impl UpdateContext { timestamp: None, write_version: None, txn_index: Some(txn_index), + skip_resolvers: false, + metadata: HashMap::new(), + } + } + + /// Create context for reprocessed cached account data from PDA mapping changes. + /// Uses empty signature to prevent `when` guards from matching stale instructions, + /// and sets skip_resolvers to prevent stale scheduling/SetOnce lock-in. + pub fn new_reprocessed(slot: u64, write_version: u64) -> Self { + Self { + slot: Some(slot), + signature: None, + timestamp: None, + write_version: Some(write_version), + txn_index: None, + skip_resolvers: true, metadata: HashMap::new(), } } @@ -569,6 +592,12 @@ pub struct PendingAccountUpdate { pub write_version: u64, pub signature: String, pub queued_at: i64, + /// When true, this update was pulled from the `last_account_data` cache + /// during a PDA mapping change. It carries stale data from a previous + /// entity mapping and should use `UpdateContext::new_reprocessed` to + /// prevent `when` guards from matching stale instruction signatures + /// and to skip resolver scheduling. + pub is_stale_reprocess: bool, } /// Input for queueing an instruction event when PDA lookup fails. @@ -1115,6 +1144,15 @@ impl VmContext { let mut dirty_tracker = DirtyTracker::new(); let should_emit = |path: &str| !entity_bytecode.non_emitted_fields.contains(path); + tracing::info!( + entity = %target.entity_name, + primary_key = %target.primary_key, + cache_key = %cache_key, + extract_targets = ?target.extracts.iter().map(|e| &e.target_path).collect::>(), + resolved_value = %resolved_value, + "[RESOLVER] Applying resolved value to entity state" + ); + Self::apply_resolver_extractions_to_value( &mut entity_state, &resolved_value, @@ -1130,6 +1168,13 @@ impl VmContext { .map(|path| Self::get_value_at_path(&entity_state, path)) .collect(); + tracing::debug!( + entity = %target.entity_name, + primary_key = %target.primary_key, + computed_paths = ?entity_bytecode.computed_paths, + "[COMPUTED] Evaluating computed fields after resolver" + ); + let context_slot = self.current_context.as_ref().and_then(|c| c.slot); let context_timestamp = self .current_context @@ -1142,24 +1187,61 @@ impl VmContext { .as_secs() as i64 }); let eval_result = evaluator(&mut entity_state, context_slot, context_timestamp); + if eval_result.is_ok() { + let mut changed_fields = Vec::new(); for (path, old_value) in entity_bytecode.computed_paths.iter().zip(old_values.iter()) { let new_value = Self::get_value_at_path(&entity_state, path); - if new_value != *old_value && should_emit(path) { + let changed = new_value != *old_value; + let will_emit = should_emit(path); + + tracing::debug!( + entity = %target.entity_name, + primary_key = %target.primary_key, + field_path = %path, + old_value = ?old_value, + new_value = ?new_value, + changed = %changed, + will_emit = %will_emit, + "[COMPUTED] Checking computed field change" + ); + + if changed && will_emit { dirty_tracker.mark_replaced(path); + changed_fields.push(path.clone()); } } + if !changed_fields.is_empty() { + tracing::info!( + entity = %target.entity_name, + primary_key = %target.primary_key, + changed_fields = ?changed_fields, + "[COMPUTED] Computed fields changed after resolver" + ); + } } } state.insert_with_eviction(target.primary_key.clone(), entity_state.clone()); if dirty_tracker.is_empty() { + tracing::debug!( + entity = %target.entity_name, + primary_key = %target.primary_key, + "[RESOLVER] No dirty fields after resolver result, skipping mutation" + ); continue; } + tracing::info!( + entity = %target.entity_name, + primary_key = %target.primary_key, + dirty_fields = ?dirty_tracker.iter().collect::>(), + "[RESOLVER] Resolver result applied, emitting mutation" + ); + let patch = Self::build_partial_state_from_value(&entity_state, &dirty_tracker)?; mutations.push(Mutation { @@ -1190,6 +1272,18 @@ impl VmContext { .unwrap() .as_secs() as i64; + // Log resolver request details + let current_slot = self.current_context.as_ref().and_then(|ctx| ctx.slot); + tracing::info!( + resolver_type = ?resolver, + cache_key = %cache_key, + input = %input, + entity = %target.entity_name, + primary_key = %target.primary_key, + current_slot = ?current_slot, + "[RESOLVER] Enqueueing resolver request" + ); + self.resolver_pending.insert( cache_key.clone(), PendingResolverEntry { @@ -1529,7 +1623,24 @@ impl VmContext { "flushing deferred when-ops" ); for op in deferred_ops { - match self.apply_deferred_when_op(state_id, &op) { + // Look up the entity bytecode to get the computed fields evaluator + let (evaluator, computed_paths) = bytecode + .entities + .get(&op.entity_name) + .map(|eb| { + ( + eb.computed_fields_evaluator.as_ref(), + eb.computed_paths.as_slice(), + ) + }) + .unwrap_or((None, &[])); + + match self.apply_deferred_when_op( + state_id, + &op, + evaluator, + Some(computed_paths), + ) { Ok(mutations) => all_mutations.extend(mutations), Err(e) => tracing::warn!( "Failed to apply deferred when-op: {}", @@ -1692,6 +1803,10 @@ impl VmContext { match self.apply_deferred_when_op( entity_bytecode.state_id, &op, + entity_bytecode + .computed_fields_evaluator + .as_ref(), + Some(&entity_bytecode.computed_paths), ) { Ok(mutations) => { all_mutations.extend(mutations) @@ -2704,12 +2819,72 @@ impl VmContext { } => { let actual_state_id = override_state_id; + // Log what triggered this resolver + let trigger_info = if let Some(ref ctx) = self.current_context { + if let Some(ref sig) = ctx.signature { + format!( + "instruction (slot={}, sig={})", + ctx.slot.unwrap_or(0), + &sig[..std::cmp::min(16, sig.len())] + ) + } else { + format!("account update (slot={})", ctx.slot.unwrap_or(0)) + } + } else { + "unknown".to_string() + }; + + tracing::info!( + entity = %entity_name, + trigger = %trigger_info, + resolver = ?resolver, + schedule_at = ?schedule_at, + "[RESOLVER] QueueResolver opcode triggered by event" + ); + + // Skip resolvers for reprocessed cached data from PDA mapping changes. + // Stale data can carry wrong field values (e.g. old entropy_value) and + // wrong schedule_at slots that would lock in incorrect results via SetOnce. + if self + .current_context + .as_ref() + .map(|c| c.skip_resolvers) + .unwrap_or(false) + { + tracing::info!( + entity = %entity_name, + "[RESOLVER] Skipping resolver: context is reprocessed cached data" + ); + pc += 1; + continue; + } + // Evaluate condition if present if let Some(cond) = condition { let field_val = Self::get_value_at_path(&self.registers[*state], &cond.field_path) .unwrap_or(Value::Null); - if !self.evaluate_comparison(&field_val, &cond.op, &cond.value)? { + let condition_met = + self.evaluate_comparison(&field_val, &cond.op, &cond.value)?; + + // Get full state snapshot for debugging + let state_json = + serde_json::to_string(&self.registers[*state]).unwrap_or_default(); + let has_entropy = state_json.contains("entropy"); + let has_entropy_value = state_json.contains("entropy_value"); + + tracing::info!( + entity = %entity_name, + condition_field = %cond.field_path, + condition_met = condition_met, + field_value = ?field_val, + has_entropy_section = has_entropy, + has_entropy_value_field = has_entropy_value, + state_size = state_json.len(), + "[RESOLVER] Evaluating resolver condition" + ); + + if !condition_met { pc += 1; continue; } @@ -2730,6 +2905,15 @@ impl VmContext { if current_slot < target_slot { let key_value = &self.registers[*key]; if !key_value.is_null() { + tracing::info!( + entity = %entity_name, + primary_key = %key_value, + current_slot = current_slot, + target_slot = target_slot, + slots_until_fire = target_slot - current_slot, + schedule_at_path = %schedule_path, + "[RESOLVER] Scheduling deferred resolver" + ); self.scheduled_callbacks.push(( target_slot, ScheduledCallback { @@ -2746,11 +2930,25 @@ impl VmContext { retry_count: 0, }, )); + } else { + tracing::warn!( + entity = %entity_name, + current_slot = current_slot, + target_slot = target_slot, + "[RESOLVER] Cannot schedule deferred resolver: primary key is null" + ); } pc += 1; continue; } // current_slot >= target_slot: fall through to immediate resolution + tracing::info!( + entity = %entity_name, + primary_key = %self.registers[*key], + current_slot = current_slot, + target_slot = target_slot, + "[RESOLVER] schedule_at slot already passed, falling through to immediate execution" + ); } None => { // schedule_at path is missing or value is not a u64 — @@ -2812,6 +3010,12 @@ impl VmContext { } }) { + tracing::info!( + entity = %entity_name, + primary_key = %self.registers[*key], + extract_targets = ?extracts.iter().map(|e| &e.target_path).collect::>(), + "[RESOLVER] SetOnce guard: all extract targets already populated, skipping resolver" + ); pc += 1; continue; } @@ -2837,6 +3041,14 @@ impl VmContext { extracts: extracts.clone(), }; + tracing::info!( + entity = %entity_name, + trigger = %trigger_info, + cache_key = %cache_key, + input = ?input, + "[RESOLVER] Queueing immediate resolver request" + ); + self.enqueue_resolver_request( cache_key, resolver.clone(), @@ -3507,6 +3719,10 @@ impl VmContext { &mut self, state_id: u32, op: &DeferredWhenOperation, + entity_evaluator: Option< + &Box, i64) -> Result<()> + Send + Sync>, + >, + computed_paths: Option<&[String]>, ) -> Result> { let state = self.states.get(&state_id).ok_or("State not found")?; @@ -3518,9 +3734,50 @@ impl VmContext { .get_and_touch(&op.primary_key) .unwrap_or_else(|| json!({})); + // Track old values of computed fields before setting the new value + let old_computed_values: Vec<_> = computed_paths + .map(|paths| { + paths + .iter() + .map(|path| Self::get_value_at_path(&entity_state, path)) + .collect() + }) + .unwrap_or_default(); + Self::set_nested_field_value(&mut entity_state, &op.field_path, op.field_value.clone())?; - state.insert_with_eviction(op.primary_key.clone(), entity_state); + // Re-evaluate computed fields if an evaluator is provided + if let Some(evaluator) = entity_evaluator { + let context_slot = self.current_context.as_ref().and_then(|c| c.slot); + let context_timestamp = self + .current_context + .as_ref() + .map(|c| c.timestamp()) + .unwrap_or_else(|| { + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs() as i64 + }); + + tracing::debug!( + entity_name = %op.entity_name, + primary_key = %op.primary_key, + field_path = %op.field_path, + "Re-evaluating computed fields after deferred when-op" + ); + + if let Err(e) = evaluator(&mut entity_state, context_slot, context_timestamp) { + tracing::warn!( + entity_name = %op.entity_name, + primary_key = %op.primary_key, + error = %e, + "Failed to evaluate computed fields after deferred when-op" + ); + } + } + + state.insert_with_eviction(op.primary_key.clone(), entity_state.clone()); if !op.emit { return Ok(vec![]); @@ -3529,6 +3786,38 @@ impl VmContext { let mut patch = json!({}); Self::set_nested_field_value(&mut patch, &op.field_path, op.field_value.clone())?; + // Add computed field changes to the patch + if let Some(paths) = computed_paths { + tracing::debug!( + entity_name = %op.entity_name, + primary_key = %op.primary_key, + computed_paths_count = paths.len(), + "Checking computed fields for changes after deferred when-op" + ); + for (path, old_value) in paths.iter().zip(old_computed_values.iter()) { + let new_value = Self::get_value_at_path(&entity_state, path); + tracing::debug!( + entity_name = %op.entity_name, + primary_key = %op.primary_key, + field_path = %path, + old_value = ?old_value, + new_value = ?new_value, + "Comparing computed field values" + ); + if let Some(ref new_val) = new_value { + if Some(new_val) != old_value.as_ref() { + Self::set_nested_field_value(&mut patch, path, new_val.clone())?; + tracing::info!( + entity_name = %op.entity_name, + primary_key = %op.primary_key, + field_path = %path, + "Computed field changed after deferred when-op, including in mutation" + ); + } + } + } + } + Ok(vec![Mutation { export: op.entity_name.clone(), key: op.primary_key.clone(), @@ -3626,6 +3915,20 @@ impl VmContext { .map(|old| old != &seed_value) .unwrap_or(false); + if !mapping_changed && old_seed.is_none() { + tracing::info!( + pda = %pda_address, + seed = %seed_value, + "[PDA] First-time PDA reverse lookup established" + ); + } else if !mapping_changed { + tracing::debug!( + pda = %pda_address, + seed = %seed_value, + "[PDA] PDA reverse lookup re-registered (same mapping)" + ); + } + let evicted_pda = lookup.insert(pda_address.clone(), seed_value.clone()); if let Some(ref evicted) = evicted_pda { @@ -3652,7 +3955,7 @@ impl VmContext { index.remove(&Value::String(pda_address.clone())); } - if let Some((_, cached)) = state.last_account_data.remove(&pda_address) { + if let Some((_, mut cached)) = state.last_account_data.remove(&pda_address) { tracing::info!( pda = %pda_address, old_seed = ?old_seed, @@ -3660,6 +3963,7 @@ impl VmContext { account_type = %cached.account_type, "PDA mapping changed — clearing stale indexes and reprocessing cached data" ); + cached.is_stale_reprocess = true; pending.push(cached); } } @@ -3782,6 +4086,7 @@ impl VmContext { .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs() as i64, + is_stale_reprocess: false, }; let pda_address = pending.pda_address.clone(); @@ -4365,6 +4670,16 @@ impl VmContext { .as_ref() .map(|ctx| json!(ctx.timestamp())) .unwrap_or(Value::Null)), + + ComputedExpr::Keccak256 { expr } => { + let val = self.evaluate_computed_expr_with_env(expr, state, env)?; + let bytes = self.value_to_bytes(&val)?; + use sha3::{Digest, Keccak256}; + let hash = Keccak256::digest(&bytes); + Ok(Value::Array( + hash.to_vec().iter().map(|b| json!(*b)).collect(), + )) + } } } @@ -4782,9 +5097,18 @@ impl VmContext { crate::resolvers::validate_resolver_computed_specs(computed_field_specs)?; for spec in computed_field_specs { - if let Ok(result) = self.evaluate_computed_expr(&spec.expression, state) { - self.set_field_in_state(state, &spec.target_path, result)?; - updated_paths.push(spec.target_path.clone()); + match self.evaluate_computed_expr(&spec.expression, state) { + Ok(result) => { + self.set_field_in_state(state, &spec.target_path, result)?; + updated_paths.push(spec.target_path.clone()); + } + Err(e) => { + tracing::warn!( + target_path = %spec.target_path, + error = %e, + "Failed to evaluate computed field" + ); + } } } @@ -5199,7 +5523,7 @@ mod tests { let deferred = state.deferred_when_ops.remove(&key).unwrap().1; for op in deferred { - vm.apply_deferred_when_op(0, &op).unwrap(); + vm.apply_deferred_when_op(0, &op, None, None).unwrap(); } let state = vm.states.get(&0).unwrap(); @@ -5240,4 +5564,143 @@ mod tests { "Deferred ops should be empty after cleanup" ); } + + #[test] + fn test_deferred_when_op_recomputes_dependent_fields() { + use crate::ast::{BinaryOp, ComputedExpr, ComputedFieldSpec}; + + let mut vm = VmContext::new(); + + // Create computed field specs similar to the ore stack: + // pre_reveal_rng depends on base_value + // pre_reveal_winning_square depends on pre_reveal_rng + let computed_specs = vec![ + ComputedFieldSpec { + target_path: "results.pre_reveal_rng".to_string(), + result_type: "Option".to_string(), + expression: ComputedExpr::FieldRef { + path: "entropy.base_value".to_string(), + }, + }, + ComputedFieldSpec { + target_path: "results.pre_reveal_winning_square".to_string(), + result_type: "Option".to_string(), + expression: ComputedExpr::MethodCall { + expr: Box::new(ComputedExpr::FieldRef { + path: "results.pre_reveal_rng".to_string(), + }), + method: "map".to_string(), + args: vec![ComputedExpr::Closure { + param: "r".to_string(), + body: Box::new(ComputedExpr::Binary { + op: BinaryOp::Mod, + left: Box::new(ComputedExpr::Var { + name: "r".to_string(), + }), + right: Box::new(ComputedExpr::Literal { + value: serde_json::json!(25), + }), + }), + }], + }, + }, + ]; + + let evaluator: Box, i64) -> Result<()> + Send + Sync> = + Box::new(VmContext::create_evaluator_from_specs(computed_specs)); + + // Test that when we set entropy.base_value via deferred when-op, + // both computed fields are updated + let primary_key = json!("test_pk"); + let op = DeferredWhenOperation { + entity_name: "TestEntity".to_string(), + primary_key: primary_key.clone(), + field_path: "entropy.base_value".to_string(), + field_value: json!(100), + when_instruction: "TestIxState".to_string(), + signature: "test_sig".to_string(), + slot: 100, + deferred_at: 0, + emit: true, + }; + + // Store the entity in state first + let initial_state = json!({ + "results": {} + }); + vm.states + .get(&0) + .unwrap() + .insert_with_eviction(primary_key.clone(), initial_state); + + // Apply the deferred when-op with the evaluator + let mutations = vm + .apply_deferred_when_op( + 0, + &op, + Some(&evaluator), + Some(&[ + "results.pre_reveal_rng".to_string(), + "results.pre_reveal_winning_square".to_string(), + ]), + ) + .unwrap(); + + // Check the entity state + let state = vm.states.get(&0).unwrap(); + let entity = state.data.get(&primary_key).unwrap(); + + println!( + "Entity state: {}", + serde_json::to_string_pretty(&*entity).unwrap() + ); + + // Verify base value was set + assert_eq!( + entity.get("entropy").and_then(|e| e.get("base_value")), + Some(&json!(100)), + "Base value should be set" + ); + + // Verify computed fields were calculated + let pre_reveal_rng = entity + .get("results") + .and_then(|r| r.get("pre_reveal_rng")) + .cloned(); + let pre_reveal_winning_square = entity + .get("results") + .and_then(|r| r.get("pre_reveal_winning_square")) + .cloned(); + + assert_eq!( + pre_reveal_rng, + Some(json!(100)), + "pre_reveal_rng should be computed" + ); + assert_eq!( + pre_reveal_winning_square, + Some(json!(0)), + "pre_reveal_winning_square should be 100 % 25 = 0" + ); + + // Verify mutations include computed fields + assert!(!mutations.is_empty(), "Should have mutations"); + let mutation = &mutations[0]; + let patch = &mutation.patch; + + assert!( + patch + .get("results") + .and_then(|r| r.get("pre_reveal_rng")) + .is_some(), + "Mutation should include pre_reveal_rng" + ); + assert!( + patch + .get("results") + .and_then(|r| r.get("pre_reveal_winning_square")) + .is_some(), + "Mutation should include pre_reveal_winning_square" + ); + } } From 0b8681eb8cf399e09140495c749872dcae91b1c1 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Tue, 17 Mar 2026 11:52:35 +0000 Subject: [PATCH 06/60] feat: improve slot scheduler with notification-based waiting and enhanced logging - Add slot tracker notification support with 5s polling fallback - Export generate_computed_expr_code_with_cache for intra-section caching - Add detailed tracing for scheduler callback processing - Improve condition evaluation visibility with field value logging - Add SetOnce guard logging to track skipped callbacks --- hyperstack-macros/src/codegen/mod.rs | 1 + .../src/codegen/vixen_runtime.rs | 398 ++++++++++++++++-- 2 files changed, 358 insertions(+), 41 deletions(-) diff --git a/hyperstack-macros/src/codegen/mod.rs b/hyperstack-macros/src/codegen/mod.rs index aea630d4..e3fd4004 100644 --- a/hyperstack-macros/src/codegen/mod.rs +++ b/hyperstack-macros/src/codegen/mod.rs @@ -20,6 +20,7 @@ pub(crate) mod vixen_runtime; pub(crate) use bytecode::generate_bytecode_from_spec; pub(crate) use computed::generate_computed_evaluator; pub(crate) use computed::generate_computed_expr_code; +pub(crate) use computed::generate_computed_expr_code_with_cache; pub(crate) use field_accessors::generate_field_accessors; pub(crate) use handlers::generate_handlers_from_specs; pub(crate) use multi_entity::generate_multi_entity_builder; diff --git a/hyperstack-macros/src/codegen/vixen_runtime.rs b/hyperstack-macros/src/codegen/vixen_runtime.rs index 3b5f7c0c..d1643f09 100644 --- a/hyperstack-macros/src/codegen/vixen_runtime.rs +++ b/hyperstack-macros/src/codegen/vixen_runtime.rs @@ -61,9 +61,15 @@ fn generate_slot_scheduler_task() -> TokenStream { "SlotScheduler: started (in-memory only, pending callbacks will not survive restarts)" ); loop { + // Wait for a slot advance notification, or fall back to polling + // every 5s in case notifications are missed. + hyperstack::runtime::tokio::select! { + _ = slot_tracker.notified() => {}, + _ = hyperstack::runtime::tokio::time::sleep(std::time::Duration::from_secs(5)) => {}, + } + let current_slot = slot_tracker.get(); if current_slot == 0 { - hyperstack::runtime::tokio::time::sleep(std::time::Duration::from_millis(400)).await; continue; } @@ -77,6 +83,14 @@ fn generate_slot_scheduler_task() -> TokenStream { const MAX_RETRIES: u32 = hyperstack::runtime::hyperstack_interpreter::scheduler::MAX_RETRIES; + if !due.is_empty() { + hyperstack::runtime::tracing::info!( + current_slot = current_slot, + due_count = due.len(), + "[SCHEDULER] Processing due callbacks" + ); + } + for mut callback in due { let state = { let vm_guard = vm.lock().unwrap_or_else(|e| e.into_inner()); @@ -102,12 +116,17 @@ fn generate_slot_scheduler_task() -> TokenStream { }; if let Some(ref condition) = callback.condition { - if !hyperstack::runtime::hyperstack_interpreter::scheduler::evaluate_condition(condition, &state) { - hyperstack::runtime::tracing::debug!( - entity = %callback.entity_name, - key = ?callback.primary_key, - "SlotScheduler: condition no longer met, skipping callback" - ); + let condition_met = hyperstack::runtime::hyperstack_interpreter::scheduler::evaluate_condition(condition, &state); + let field_val = hyperstack::runtime::hyperstack_interpreter::scheduler::get_value_at_path(&state, &condition.field_path); + hyperstack::runtime::tracing::info!( + entity = %callback.entity_name, + key = ?callback.primary_key, + condition_field = %condition.field_path, + condition_met = condition_met, + field_value = ?field_val, + "[SCHEDULER] Re-evaluating condition at callback fire time" + ); + if !condition_met { continue; } } @@ -117,11 +136,16 @@ fn generate_slot_scheduler_task() -> TokenStream { // Already-set fields are protected from overwrite by the // SetOnce guard in VmContext::set_value_at_path. let already_resolved = callback.extracts.iter().all(|ext| { - hyperstack::runtime::hyperstack_interpreter::scheduler::get_value_at_path(&state, &ext.target_path) - .map(|v| !v.is_null()) - .unwrap_or(false) + let val = hyperstack::runtime::hyperstack_interpreter::scheduler::get_value_at_path(&state, &ext.target_path); + val.map(|v| !v.is_null()).unwrap_or(false) }); if already_resolved { + hyperstack::runtime::tracing::info!( + entity = %callback.entity_name, + key = ?callback.primary_key, + targets = ?callback.extracts.iter().map(|e| &e.target_path).collect::>(), + "[SCHEDULER] SetOnce guard: all targets already populated, skipping" + ); continue; } } @@ -170,6 +194,15 @@ fn generate_slot_scheduler_task() -> TokenStream { let cache_key = format!("scheduled:{}:{}:{}", callback.entity_name, callback.primary_key, url); + hyperstack::runtime::tracing::info!( + current_slot = current_slot, + entity = %callback.entity_name, + primary_key = %callback.primary_key, + url = %url, + cache_key = %cache_key, + "[RESOLVER] Executing scheduled URL resolver" + ); + // IMPORTANT: enqueue + take must stay inside the same lock guard. // Splitting them risks lost or duplicated requests during reconnects. let requests = { @@ -196,6 +229,14 @@ fn generate_slot_scheduler_task() -> TokenStream { requests, ).await; + hyperstack::runtime::tracing::info!( + current_slot = current_slot, + entity = %callback.entity_name, + primary_key = %callback.primary_key, + mutation_count = url_mutations.len(), + "[RESOLVER] Scheduled URL resolver completed" + ); + if url_mutations.is_empty() { if callback.retry_count < MAX_RETRIES { callback.retry_count += 1; @@ -229,8 +270,177 @@ fn generate_slot_scheduler_task() -> TokenStream { "SlotScheduler: tick panicked, continuing" ); } + } + }); + } + } +} + +/// Generate the `tokio::spawn` block for the gRPC slot subscription. +/// +/// Opens a dedicated gRPC connection to stream slot updates, updating the +/// `SlotTracker` on each new slot. This drives the scheduler to fire callbacks +/// immediately when the target slot arrives, rather than waiting for the next +/// account/instruction event. +fn generate_slot_subscription_task() -> TokenStream { + quote! { + // Helper function to parse SlotHashes sysvar data + async fn parse_and_cache_slot_hashes(current_slot: u64, data: &[u8]) -> Result<(), Box> { + if data.len() < 8 { + return Err("Data too short".into()); + } + + let len = u64::from_le_bytes([ + data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7], + ]) as usize; - hyperstack::runtime::tokio::time::sleep(std::time::Duration::from_millis(400)).await; + let entry_size = 40; + let expected_size = 8 + (len * entry_size); + + if data.len() < expected_size { + return Err(format!("Data too short: expected {}, got {}", expected_size, data.len()).into()); + } + + for i in 0..len { + let offset = 8 + (i * entry_size); + let slot = u64::from_le_bytes([ + data[offset], data[offset + 1], data[offset + 2], data[offset + 3], + data[offset + 4], data[offset + 5], data[offset + 6], data[offset + 7], + ]); + let hash_bytes = &data[offset + 8..offset + 40]; + let hash = hyperstack::runtime::bs58::encode(hash_bytes).into_string(); + hyperstack::runtime::hyperstack_interpreter::record_slot_hash(slot, hash).await; + hyperstack::runtime::tracing::debug!(slot = slot, current_slot = current_slot, "[SLOT_SUB] Cached slot hash"); + } + Ok(()) + } + + { + let slot_tracker = slot_tracker.clone(); + let endpoint = endpoint.clone(); + let x_token = x_token.clone(); + + hyperstack::runtime::tokio::spawn(async move { + hyperstack::runtime::tracing::info!("[SLOT_SUB] Starting dedicated gRPC slot subscription"); + + loop { + let result: Result<(), Box> = async { + use hyperstack::runtime::yellowstone_grpc_proto::geyser::{ + SubscribeRequest, SubscribeRequestFilterSlots, SubscribeRequestFilterAccounts, + subscribe_update::UpdateOneof, + }; + use hyperstack::runtime::futures::StreamExt; + + let mut client = hyperstack::runtime::yellowstone_grpc_client::GeyserGrpcClient + ::build_from_shared(endpoint.clone())? + .x_token(x_token.clone())? + .max_decoding_message_size(usize::MAX) + .accept_compressed( + hyperstack::runtime::yellowstone_grpc_proto::tonic::codec::CompressionEncoding::Zstd + ) + .connect_timeout(std::time::Duration::from_secs(30)) + .timeout(std::time::Duration::from_secs(60)) + .tls_config( + hyperstack::runtime::yellowstone_grpc_proto::tonic::transport::ClientTlsConfig::new() + .with_native_roots() + )? + .connect() + .await?; + + // Solana SlotHashes sysvar address + let slot_hashes_sysvar = "SysvarS1otHashes111111111111111111111111111".to_string(); + + let subscribe_request = SubscribeRequest { + slots: std::collections::HashMap::from([( + "slot_sub".to_string(), + SubscribeRequestFilterSlots { + filter_by_commitment: Some(true), + interslot_updates: None, + }, + )]), + // Subscribe to SlotHashes sysvar to capture slot hashes + accounts: std::collections::HashMap::from([( + "slot_hashes_sysvar".to_string(), + SubscribeRequestFilterAccounts { + account: vec![slot_hashes_sysvar.clone()], + owner: vec![], + filters: vec![], + nonempty_txn_signature: None, + }, + )]), + transactions: std::collections::HashMap::new(), + transactions_status: std::collections::HashMap::new(), + blocks: std::collections::HashMap::new(), + blocks_meta: std::collections::HashMap::new(), + entry: std::collections::HashMap::new(), + commitment: Some( + hyperstack::runtime::yellowstone_grpc_proto::geyser::CommitmentLevel::Processed as i32 + ), + accounts_data_slice: vec![], + ping: None, + from_slot: None, + }; + + let (_sub_tx, mut stream) = client + .subscribe_with_request(Some(subscribe_request)) + .await?; + + hyperstack::runtime::tracing::info!("[SLOT_SUB] Connected and subscribed to slot and SlotHashes updates"); + + while let Some(msg) = stream.next().await { + match msg { + Ok(update) => { + match update.update_oneof { + Some(UpdateOneof::Slot(slot_update)) => { + slot_tracker.record(slot_update.slot); + } + Some(UpdateOneof::Account(account_update)) => { + // Process SlotHashes sysvar update + if let Some(account) = account_update.account { + if hyperstack::runtime::bs58::encode(&account.pubkey).into_string() == slot_hashes_sysvar { + hyperstack::runtime::tracing::debug!( + slot = account_update.slot, + "[SLOT_SUB] Received SlotHashes sysvar update" + ); + // Parse slot hashes from account data + // The SlotHashes sysvar contains a vector of (slot, hash) pairs + if let Err(e) = parse_and_cache_slot_hashes( + account_update.slot, + &account.data, + ).await { + hyperstack::runtime::tracing::warn!( + error = %e, + "[SLOT_SUB] Failed to parse SlotHashes" + ); + } + } + } + } + _ => {} + } + } + Err(e) => { + hyperstack::runtime::tracing::warn!( + error = %e, + "[SLOT_SUB] Stream error, will reconnect" + ); + break; + } + } + } + + Ok(()) + }.await; + + if let Err(e) = result { + hyperstack::runtime::tracing::warn!( + error = %e, + "[SLOT_SUB] Connection failed, reconnecting in 2s" + ); + } + + hyperstack::runtime::tokio::time::sleep(std::time::Duration::from_secs(2)).await; } }); } @@ -714,6 +924,13 @@ pub fn generate_vm_handler( match resolver_result { hyperstack::runtime::hyperstack_interpreter::resolvers::KeyResolution::Found(resolved_key) => { + hyperstack::runtime::tracing::info!( + event_type = %event_type, + account = %account_address, + resolved_key = %resolved_key, + slot = slot, + "[PDA] Account key resolution: Found" + ); if !resolved_key.is_empty() { if let Some(obj) = event_value.as_object_mut() { obj.insert("__resolved_primary_key".to_string(), hyperstack::runtime::serde_json::json!(resolved_key)); @@ -722,7 +939,7 @@ pub fn generate_vm_handler( } hyperstack::runtime::hyperstack_interpreter::resolvers::KeyResolution::QueueUntil(_discriminators) => { let mut vm = self.vm.lock().unwrap_or_else(|e| e.into_inner()); - tracing::info!( + hyperstack::runtime::tracing::info!( event_type = %event_type, pda = %account_address, slot = slot, @@ -777,6 +994,7 @@ pub fn generate_vm_handler( .duration_since(std::time::UNIX_EPOCH) .unwrap_or_default() .as_secs() as i64, + is_stale_reprocess: false, }, ); } @@ -799,10 +1017,33 @@ pub fn generate_vm_handler( if !scheduled_callbacks.is_empty() { let mut scheduler = self.slot_scheduler.lock().unwrap_or_else(|e| e.into_inner()); for (target_slot, callback) in scheduled_callbacks { + hyperstack::runtime::tracing::info!( + event_type = %event_type, + account = %account_address, + slot = slot, + target_slot = target_slot, + entity = %callback.entity_name, + primary_key = %callback.primary_key, + "[RESOLVER] Scheduled callback registered for future slot" + ); scheduler.register(target_slot, callback); } } + // Log resolver requests being created + if !resolver_requests.is_empty() { + for req in &resolver_requests { + hyperstack::runtime::tracing::info!( + event_type = %event_type, + account = %account_address, + slot = slot, + resolver = ?req.resolver, + input = %req.input, + "[RESOLVER] Resolver request created from account update" + ); + } + } + let resolver_mutations = if mutations_result.is_ok() { self.resolve_and_apply_resolvers(resolver_requests).await } else { @@ -930,49 +1171,73 @@ pub fn generate_vm_handler( // Process pending account updates from instruction hooks if !pending_updates.is_empty() { - tracing::info!( + hyperstack::runtime::tracing::info!( count = pending_updates.len(), event_type = %event_type, - "Flushing pending account updates from instruction hooks" + "[PDA] Flushing pending account updates from instruction hooks" ); for update in pending_updates { - // Use chained PDA + lookup-index resolution so that - // __resolved_primary_key carries the actual primary key - // (e.g. round_id) instead of the intermediate PDA value - // (e.g. round_address). Falls back to raw PDA result when - // lookup index isn't populated yet. + hyperstack::runtime::tracing::info!( + account_type = %update.account_type, + pda = %update.pda_address, + update_slot = update.slot, + current_instruction_slot = slot, + "[PDA] Reprocessing flushed update" + ); let resolved_key = vm.try_chained_pda_lookup(0, "default_pda_lookup", &update.pda_address); let mut account_data = update.account_data; - if let Some(key) = resolved_key { + if let Some(ref key) = resolved_key { + hyperstack::runtime::tracing::info!( + pda = %update.pda_address, + resolved_key = %key, + "[PDA] Chained PDA lookup resolved for reprocessed update" + ); if let Some(obj) = account_data.as_object_mut() { obj.insert("__resolved_primary_key".to_string(), hyperstack::runtime::serde_json::json!(key)); } + } else { + hyperstack::runtime::tracing::warn!( + pda = %update.pda_address, + "[PDA] Chained PDA lookup returned None for reprocessed update" + ); } - let update_context = hyperstack::runtime::hyperstack_interpreter::UpdateContext::new_account( - update.slot, - update.signature.clone(), - update.write_version, - ); + let update_context = if update.is_stale_reprocess { + hyperstack::runtime::tracing::info!( + pda = %update.pda_address, + "[PDA] Using reprocessed context (empty sig, skip resolvers)" + ); + hyperstack::runtime::hyperstack_interpreter::UpdateContext::new_reprocessed( + update.slot, + update.write_version, + ) + } else { + hyperstack::runtime::hyperstack_interpreter::UpdateContext::new_account( + update.slot, + update.signature.clone(), + update.write_version, + ) + }; match vm.process_event(&bytecode, account_data, &update.account_type, Some(&update_context), None) { Ok(pending_mutations) => { - tracing::info!( + hyperstack::runtime::tracing::info!( account_type = %update.account_type, pda = %update.pda_address, mutations = pending_mutations.len(), - "Reprocessed flushed account update" + is_stale = update.is_stale_reprocess, + "[PDA] Reprocessed flushed account update" ); if let Ok(ref mut mutations) = result { mutations.extend(pending_mutations); } } Err(e) => { - tracing::warn!( + hyperstack::runtime::tracing::warn!( account_type = %update.account_type, error = %e, - "Failed to reprocess flushed account update" + "[PDA] Failed to reprocess flushed account update" ); } } @@ -1094,6 +1359,7 @@ pub fn generate_spec_function( }; let slot_scheduler_task = generate_slot_scheduler_task(); + let slot_subscription_task = generate_slot_subscription_task(); quote! { pub fn spec() -> hyperstack::runtime::hyperstack_server::Spec { @@ -1174,6 +1440,9 @@ pub fn generate_spec_function( // Spawn slot scheduler background task #slot_scheduler_task + // Spawn dedicated gRPC slot subscription to drive the scheduler in real-time + #slot_subscription_task + loop { let from_slot = { let last = slot_tracker.get(); @@ -1745,6 +2014,13 @@ pub fn generate_account_handler_impl( match resolver_result { hyperstack::runtime::hyperstack_interpreter::resolvers::KeyResolution::Found(resolved_key) => { + hyperstack::runtime::tracing::info!( + event_type = %event_type, + account = %account_address, + resolved_key = %resolved_key, + slot = slot, + "[PDA] Account key resolution: Found" + ); if !resolved_key.is_empty() { if let Some(obj) = event_value.as_object_mut() { obj.insert("__resolved_primary_key".to_string(), hyperstack::runtime::serde_json::json!(resolved_key)); @@ -1796,6 +2072,7 @@ pub fn generate_account_handler_impl( .duration_since(std::time::UNIX_EPOCH) .unwrap_or_default() .as_secs() as i64, + is_stale_reprocess: false, }, ); } @@ -1952,29 +2229,64 @@ pub fn generate_instruction_handler_impl( drop(ctx); if !pending_updates.is_empty() { + hyperstack::runtime::tracing::info!( + count = pending_updates.len(), + event_type = %event_type, + "[PDA] Flushing pending account updates from instruction hooks" + ); for update in pending_updates { - // Use chained PDA + lookup-index resolution so that - // __resolved_primary_key carries the actual primary key - // (e.g. round_id) instead of the intermediate PDA value - // (e.g. round_address). Falls back to raw PDA result when - // lookup index isn't populated yet. + hyperstack::runtime::tracing::info!( + account_type = %update.account_type, + pda = %update.pda_address, + update_slot = update.slot, + current_instruction_slot = slot, + "[PDA] Reprocessing flushed update" + ); let resolved_key = vm.try_chained_pda_lookup(0, "default_pda_lookup", &update.pda_address); let mut account_data = update.account_data; - if let Some(key) = resolved_key { + if let Some(ref key) = resolved_key { + hyperstack::runtime::tracing::info!( + pda = %update.pda_address, + resolved_key = %key, + "[PDA] Chained PDA lookup resolved for reprocessed update" + ); if let Some(obj) = account_data.as_object_mut() { obj.insert("__resolved_primary_key".to_string(), hyperstack::runtime::serde_json::json!(key)); } + } else { + hyperstack::runtime::tracing::warn!( + pda = %update.pda_address, + "[PDA] Chained PDA lookup returned None for reprocessed update" + ); } - let update_context = hyperstack::runtime::hyperstack_interpreter::UpdateContext::new_account( - update.slot, - update.signature.clone(), - update.write_version, - ); + let update_context = if update.is_stale_reprocess { + hyperstack::runtime::tracing::info!( + pda = %update.pda_address, + "[PDA] Using reprocessed context (empty sig, skip resolvers)" + ); + hyperstack::runtime::hyperstack_interpreter::UpdateContext::new_reprocessed( + update.slot, + update.write_version, + ) + } else { + hyperstack::runtime::hyperstack_interpreter::UpdateContext::new_account( + update.slot, + update.signature.clone(), + update.write_version, + ) + }; match vm.process_event(&bytecode, account_data, &update.account_type, Some(&update_context), None) { Ok(pending_mutations) => { + hyperstack::runtime::tracing::info!( + account_type = %update.account_type, + pda = %update.pda_address, + mutations = pending_mutations.len(), + is_stale = update.is_stale_reprocess, + "[PDA] Reprocessed flushed account update" + ); if let Ok(ref mut mutations) = result { mutations.extend(pending_mutations); } @@ -1983,7 +2295,7 @@ pub fn generate_instruction_handler_impl( hyperstack::runtime::tracing::warn!( account_type = %update.account_type, error = %e, - "Flushed account reprocessing failed" + "[PDA] Flushed account reprocessing failed" ); } } @@ -2160,6 +2472,7 @@ pub fn generate_multi_pipeline_spec_function( }).collect(); let slot_scheduler_task = generate_slot_scheduler_task(); + let slot_subscription_task = generate_slot_subscription_task(); quote! { pub fn spec() -> hyperstack::runtime::hyperstack_server::Spec { @@ -2239,6 +2552,9 @@ pub fn generate_multi_pipeline_spec_function( // Spawn slot scheduler background task #slot_scheduler_task + // Spawn dedicated gRPC slot subscription to drive the scheduler in real-time + #slot_subscription_task + loop { let from_slot = { let last = slot_tracker.get(); From 2f23205577c814572e57e5628bee9225d4631f4b Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Tue, 17 Mar 2026 11:52:41 +0000 Subject: [PATCH 07/60] feat: add Yellowstone gRPC dependencies and update Ore examples - Add yellowstone-grpc-client and yellowstone-grpc-proto dependencies - Update Ore React components with latest schema changes - Update Ore TypeScript example with local development URL - Update hyperstack-server with new health check improvements - Sync all Cargo.lock files with new dependencies --- Cargo.lock | 2534 ++++++++++++++- Cargo.toml | 3 + .../ore-react/src/components/BlockGrid.tsx | 6 +- .../ore-react/src/components/OreDashboard.tsx | 7 +- examples/ore-server/Cargo.lock | 2836 +++++++++++++++-- examples/ore-server/Cargo.toml | 1 + examples/ore-typescript/src/main.ts | 58 +- rust/hyperstack-server/Cargo.toml | 1 + rust/hyperstack-server/src/health.rs | 66 +- stacks/ore/Cargo.lock | 2366 +++++++++++++- stacks/sdk/typescript/src/ore/index.ts | 6 + 11 files changed, 7258 insertions(+), 626 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 301a4776..ff1f6265 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,107 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + [[package]] name = "adler2" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "agave-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a2c365c0245cbb8959de725fc2b44c754b673fdf34c9a7f9d4a25c35a7bf1" +dependencies = [ + "ahash 0.8.12", + "solana-epoch-schedule", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", + "solana-svm-feature-set", +] + +[[package]] +name = "agave-reserved-account-keys" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8289c8a8a2ef5aa10ce49a070f360f4e035ee3410b8d8f3580fb39d8cf042581" +dependencies = [ + "agave-feature-set", + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.16", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.4" @@ -88,6 +183,18 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "async-stream" version = "0.3.6" @@ -107,7 +214,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -118,7 +225,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -277,6 +384,12 @@ dependencies = [ "tower-service", ] +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + [[package]] name = "base64" version = "0.21.7" @@ -289,6 +402,15 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -301,6 +423,30 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +[[package]] +name = "blake3" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2468ef7d57b3fb7e16b576e8377cdbde2320c60e1491e961d11da40fc4f02a2d" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -310,15 +456,74 @@ dependencies = [ "generic-array", ] +[[package]] +name = "borsh" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115e54d64eb62cdebad391c19efc9dce4981c690c85a33a12199d99bb9546fee" +dependencies = [ + "borsh-derive 0.10.4", + "hashbrown 0.12.3", +] + [[package]] name = "borsh" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" dependencies = [ + "borsh-derive 1.6.0", "cfg_aliases", ] +[[package]] +name = "borsh-derive" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" +dependencies = [ + "borsh-derive-internal", + "borsh-schema-derive-internal", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" +dependencies = [ + "once_cell", + "proc-macro-crate 3.5.0", + "proc-macro2", + "quote", + "syn 2.0.113", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65d6ba50644c98714aa2a70d13d7df3cd75cd2b523a2b452bf010443800976b3" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "bs58" version = "0.5.1" @@ -334,6 +539,16 @@ version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + [[package]] name = "bytemuck" version = "1.25.0" @@ -351,7 +566,7 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -403,6 +618,16 @@ dependencies = [ "windows-link", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "4.5.54" @@ -444,7 +669,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -482,6 +707,32 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "constant_time_eq" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + [[package]] name = "core-foundation" version = "0.9.4" @@ -582,6 +833,12 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + [[package]] name = "crypto-common" version = "0.1.7" @@ -589,9 +846,61 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rand_core 0.6.4", + "rustc_version", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.113", +] + [[package]] name = "dashmap" version = "6.1.0" @@ -612,6 +921,12 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" +[[package]] +name = "derivation-path" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" + [[package]] name = "dialoguer" version = "0.11.0" @@ -625,14 +940,24 @@ dependencies = [ "zeroize", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "crypto-common", + "subtle", ] [[package]] @@ -664,7 +989,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -684,7 +1009,7 @@ checksum = "c32e3e8ab1b6ee2e06418f40f94f315d82b35157eb1d2322a6e20a4b15106b84" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -693,6 +1018,29 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + [[package]] name = "either" version = "1.15.0" @@ -736,6 +1084,18 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "filetime" version = "0.2.27" @@ -885,7 +1245,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -928,6 +1288,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.16" @@ -937,7 +1308,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -1004,6 +1375,9 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.8", +] [[package]] name = "hashbrown" @@ -1047,12 +1421,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] -name = "http" -version = "0.2.12" +name = "hmac" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "bytes", + "digest 0.10.7", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", "fnv", "itoa", ] @@ -1256,9 +1639,12 @@ dependencies = [ "reqwest 0.11.27", "serde", "serde_json", + "sha3", "smallvec", "tokio", "tracing", + "yellowstone-grpc-client", + "yellowstone-grpc-proto", "yellowstone-vixen", "yellowstone-vixen-core", "yellowstone-vixen-yellowstone-grpc-source", @@ -1286,7 +1672,7 @@ dependencies = [ "serde", "serde_json", "tar", - "toml", + "toml 0.8.23", "uuid", ] @@ -1296,7 +1682,7 @@ version = "0.1.2" dependencies = [ "serde", "serde_json", - "sha2", + "sha2 0.10.9", "strsim", ] @@ -1311,6 +1697,7 @@ dependencies = [ "hyperstack-idl", "hyperstack-macros", "lru", + "once_cell", "opentelemetry", "opentelemetry-otlp", "opentelemetry_sdk", @@ -1321,8 +1708,10 @@ dependencies = [ "reqwest 0.12.28", "serde", "serde_json", - "sha2", + "sha2 0.10.9", + "sha3", "solana-pubkey", + "tokio", "tonic 0.12.3", "tracing", "tracing-opentelemetry", @@ -1339,8 +1728,8 @@ dependencies = [ "quote", "serde", "serde_json", - "sha2", - "syn", + "sha2 0.10.9", + "syn 2.0.113", ] [[package]] @@ -1377,6 +1766,7 @@ dependencies = [ "hyper-util", "hyperstack-interpreter", "lru", + "once_cell", "opentelemetry", "opentelemetry-otlp", "opentelemetry_sdk", @@ -1565,6 +1955,15 @@ dependencies = [ "web-time", ] +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + [[package]] name = "instant" version = "0.1.13" @@ -1640,6 +2039,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kaigan" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba15de5aeb137f0f65aa3bf82187647f1285abfe5b20c80c2c37f7007ad519a" +dependencies = [ + "borsh 0.10.4", + "serde", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -1663,6 +2081,52 @@ dependencies = [ "redox_syscall 0.7.0", ] +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + [[package]] name = "linux-raw-sys" version = "0.11.0" @@ -1732,6 +2196,27 @@ version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + [[package]] name = "mime" version = "0.3.17" @@ -1755,7 +2240,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.61.2", ] @@ -1791,6 +2276,36 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.113", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1810,6 +2325,28 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +dependencies = [ + "proc-macro-crate 3.5.0", + "proc-macro2", + "quote", + "syn 2.0.113", +] + [[package]] name = "number_prefix" version = "0.4.0" @@ -1828,6 +2365,12 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "openssl" version = "0.10.75" @@ -1851,7 +2394,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -2015,6 +2558,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -2048,7 +2600,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -2069,6 +2621,18 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "portable-atomic" version = "1.13.0" @@ -2100,7 +2664,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.113", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml 0.5.11", +] + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit 0.25.4+spec-1.1.0", ] [[package]] @@ -2158,7 +2740,7 @@ dependencies = [ "prost 0.13.5", "prost-types 0.13.5", "regex", - "syn", + "syn 2.0.113", "tempfile", ] @@ -2180,7 +2762,7 @@ dependencies = [ "pulldown-cmark", "pulldown-cmark-to-cmark", "regex", - "syn", + "syn 2.0.113", "tempfile", ] @@ -2194,7 +2776,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -2207,7 +2789,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -2220,7 +2802,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -2280,6 +2862,15 @@ dependencies = [ "pulldown-cmark", ] +[[package]] +name = "qstring" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding", +] + [[package]] name = "quinn" version = "0.11.9" @@ -2293,7 +2884,7 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls 0.23.36", - "socket2 0.5.10", + "socket2 0.6.1", "thiserror 2.0.17", "tokio", "tracing", @@ -2330,9 +2921,9 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.10", + "socket2 0.6.1", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -2350,6 +2941,19 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + [[package]] name = "rand" version = "0.8.5" @@ -2371,6 +2975,16 @@ dependencies = [ "rand_core 0.9.3", ] +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -2391,6 +3005,15 @@ dependencies = [ "rand_core 0.9.3", ] +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + [[package]] name = "rand_core" version = "0.6.4" @@ -2409,6 +3032,15 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -2596,6 +3228,15 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "1.1.3" @@ -2786,6 +3427,12 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + [[package]] name = "serde" version = "1.0.228" @@ -2796,6 +3443,25 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -2813,205 +3479,1665 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] name = "serde_json" version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shell-words" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "solana-account" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f949fe4edaeaea78c844023bfc1c898e0b1f5a100f8a8d2d0f85d0a7b090258" +dependencies = [ + "bincode", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-sysvar", +] + +[[package]] +name = "solana-account-decoder" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba71c97fa4d85ce4a1e0e79044ad0406c419382be598c800202903a7688ce71a" +dependencies = [ + "Inflector", + "base64 0.22.1", + "bincode", + "bs58", + "bv", + "serde", + "serde_derive", + "serde_json", + "solana-account", + "solana-account-decoder-client-types", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-config-program-client", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-instruction", + "solana-loader-v3-interface", + "solana-nonce", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-slot-hashes", + "solana-slot-history", + "solana-stake-interface", + "solana-sysvar", + "solana-vote-interface", + "spl-generic-token", + "spl-token", + "spl-token-2022", + "spl-token-group-interface", + "spl-token-metadata-interface", + "thiserror 2.0.17", + "zstd", +] + +[[package]] +name = "solana-account-decoder-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5519e8343325b707f17fbed54fcefb325131b692506d0af9e08a539d15e4f8cf" +dependencies = [ + "base64 0.22.1", + "bs58", + "serde", + "serde_derive", + "serde_json", + "solana-account", + "solana-pubkey", + "zstd", +] + +[[package]] +name = "solana-account-info" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8f5152a288ef1912300fc6efa6c2d1f9bb55d9398eb6c72326360b8063987da" +dependencies = [ + "bincode", + "serde", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", +] + +[[package]] +name = "solana-address-lookup-table-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1673f67efe870b64a65cb39e6194be5b26527691ce5922909939961a6e6b395" +dependencies = [ + "bincode", + "bytemuck", + "serde", + "serde_derive", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-slot-hashes", +] + +[[package]] +name = "solana-atomic-u64" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52e52720efe60465b052b9e7445a01c17550666beec855cce66f44766697bc2" +dependencies = [ + "parking_lot 0.12.5", +] + +[[package]] +name = "solana-big-mod-exp" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75db7f2bbac3e62cfd139065d15bcda9e2428883ba61fc8d27ccb251081e7567" +dependencies = [ + "num-bigint", + "num-traits", + "solana-define-syscall", +] + +[[package]] +name = "solana-bincode" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a3787b8cf9c9fe3dd360800e8b70982b9e5a8af9e11c354b6665dd4a003adc" +dependencies = [ + "bincode", + "serde", + "solana-instruction", +] + +[[package]] +name = "solana-blake3-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0801e25a1b31a14494fc80882a036be0ffd290efc4c2d640bfcca120a4672" +dependencies = [ + "blake3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + +[[package]] +name = "solana-borsh" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718333bcd0a1a7aed6655aa66bef8d7fb047944922b2d3a18f49cbc13e73d004" +dependencies = [ + "borsh 0.10.4", + "borsh 1.6.0", +] + +[[package]] +name = "solana-clock" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8584296123df8fe229b95e2ebfd37ae637fe9db9b7d4dd677ac5a78e80dbfce" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-commitment-config" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac49c4dde3edfa832de1697e9bcdb7c3b3f7cb7a1981b7c62526c8bb6700fb73" + +[[package]] +name = "solana-config-program-client" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53aceac36f105fd4922e29b4f0c1f785b69d7b3e7e387e384b8985c8e0c3595e" +dependencies = [ + "bincode", + "borsh 0.10.4", + "kaigan", + "serde", + "solana-program", +] + +[[package]] +name = "solana-cpi" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc71126edddc2ba014622fc32d0f5e2e78ec6c5a1e0eb511b85618c09e9ea11" +dependencies = [ + "solana-account-info", + "solana-define-syscall", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-stable-layout", +] + +[[package]] +name = "solana-curve25519" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae4261b9a8613d10e77ac831a8fa60b6fa52b9b103df46d641deff9f9812a23" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "solana-define-syscall", + "subtle", + "thiserror 2.0.17", +] + +[[package]] +name = "solana-decode-error" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c781686a18db2f942e70913f7ca15dc120ec38dcab42ff7557db2c70c625a35" +dependencies = [ + "num-traits", +] + +[[package]] +name = "solana-define-syscall" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae3e2abcf541c8122eafe9a625d4d194b4023c20adde1e251f94e056bb1aee2" + +[[package]] +name = "solana-derivation-path" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "939756d798b25c5ec3cca10e06212bdca3b1443cb9bb740a38124f58b258737b" +dependencies = [ + "derivation-path", + "qstring", + "uriparse", +] + +[[package]] +name = "solana-epoch-rewards" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b575d3dd323b9ea10bb6fe89bf6bf93e249b215ba8ed7f68f1a3633f384db7" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-epoch-schedule" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fce071fbddecc55d727b1d7ed16a629afe4f6e4c217bc8d00af3b785f6f67ed" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-example-mocks" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84461d56cbb8bb8d539347151e0525b53910102e4bced875d49d5139708e39d3" +dependencies = [ + "serde", + "serde_derive", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-hash", + "solana-instruction", + "solana-keccak-hasher", + "solana-message", + "solana-nonce", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", + "thiserror 2.0.17", +] + +[[package]] +name = "solana-feature-gate-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f5c5382b449e8e4e3016fb05e418c53d57782d8b5c30aa372fc265654b956d" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-fee-calculator" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89bc408da0fb3812bc3008189d148b4d3e08252c79ad810b245482a3f70cd8d" +dependencies = [ + "log", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-hash" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b96e9f0300fa287b545613f007dfe20043d7812bee255f418c1eb649c93b63" +dependencies = [ + "borsh 1.6.0", + "bytemuck", + "bytemuck_derive", + "five8", + "js-sys", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-sanitize", + "wasm-bindgen", +] + +[[package]] +name = "solana-instruction" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab5682934bd1f65f8d2c16f21cb532526fcc1a09f796e2cacdb091eee5774ad" +dependencies = [ + "bincode", + "borsh 1.6.0", + "getrandom 0.2.16", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "serde_json", + "solana-define-syscall", + "solana-pubkey", + "wasm-bindgen", +] + +[[package]] +name = "solana-instructions-sysvar" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0e85a6fad5c2d0c4f5b91d34b8ca47118fc593af706e523cdbedf846a954f57" +dependencies = [ + "bitflags 2.10.0", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-serialize-utils", + "solana-sysvar-id", +] + +[[package]] +name = "solana-keccak-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7aeb957fbd42a451b99235df4942d96db7ef678e8d5061ef34c9b34cae12f79" +dependencies = [ + "sha3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + +[[package]] +name = "solana-keypair" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd3f04aa1a05c535e93e121a95f66e7dcccf57e007282e8255535d24bf1e98bb" +dependencies = [ + "ed25519-dalek", + "five8", + "rand 0.7.3", + "solana-pubkey", + "solana-seed-phrase", + "solana-signature", + "solana-signer", + "wasm-bindgen", +] + +[[package]] +name = "solana-last-restart-slot" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6360ac2fdc72e7463565cd256eedcf10d7ef0c28a1249d261ec168c1b55cdd" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-loader-v2-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ab08006dad78ae7cd30df8eea0539e207d08d91eaefb3e1d49a446e1c49654" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-loader-v3-interface" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f7162a05b8b0773156b443bccd674ea78bb9aa406325b467ea78c06c99a63a2" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-loader-v4-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "706a777242f1f39a83e2a96a2a6cb034cb41169c6ecbee2cf09cb873d9659e7e" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-message" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1796aabce376ff74bf89b78d268fa5e683d7d7a96a0a4e4813ec34de49d5314b" +dependencies = [ + "bincode", + "blake3", + "lazy_static", + "serde", + "serde_derive", + "solana-bincode", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-system-interface", + "solana-transaction-error", + "wasm-bindgen", +] + +[[package]] +name = "solana-msg" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36a1a14399afaabc2781a1db09cb14ee4cc4ee5c7a5a3cfcc601811379a8092" +dependencies = [ + "solana-define-syscall", +] + +[[package]] +name = "solana-native-token" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61515b880c36974053dd499c0510066783f0cc6ac17def0c7ef2a244874cf4a9" + +[[package]] +name = "solana-nonce" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703e22eb185537e06204a5bd9d509b948f0066f2d1d814a6f475dafb3ddf1325" +dependencies = [ + "serde", + "serde_derive", + "solana-fee-calculator", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", +] + +[[package]] +name = "solana-program" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98eca145bd3545e2fbb07166e895370576e47a00a7d824e325390d33bf467210" +dependencies = [ + "bincode", + "blake3", + "borsh 0.10.4", + "borsh 1.6.0", + "bs58", + "bytemuck", + "console_error_panic_hook", + "console_log", + "getrandom 0.2.16", + "lazy_static", + "log", + "memoffset", + "num-bigint", + "num-derive", + "num-traits", + "rand 0.8.5", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info", + "solana-address-lookup-table-interface", + "solana-atomic-u64", + "solana-big-mod-exp", + "solana-bincode", + "solana-blake3-hasher", + "solana-borsh", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-define-syscall", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-example-mocks", + "solana-feature-gate-interface", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-keccak-hasher", + "solana-last-restart-slot", + "solana-loader-v2-interface", + "solana-loader-v3-interface", + "solana-loader-v4-interface", + "solana-message", + "solana-msg", + "solana-native-token", + "solana-nonce", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-secp256k1-recover", + "solana-serde-varint", + "solana-serialize-utils", + "solana-sha256-hasher", + "solana-short-vec", + "solana-slot-hashes", + "solana-slot-history", + "solana-stable-layout", + "solana-stake-interface", + "solana-system-interface", + "solana-sysvar", + "solana-sysvar-id", + "solana-vote-interface", + "thiserror 2.0.17", + "wasm-bindgen", +] + +[[package]] +name = "solana-program-entrypoint" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32ce041b1a0ed275290a5008ee1a4a6c48f5054c8a3d78d313c08958a06aedbd" +dependencies = [ + "solana-account-info", + "solana-msg", + "solana-program-error", + "solana-pubkey", +] + +[[package]] +name = "solana-program-error" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee2e0217d642e2ea4bee237f37bd61bb02aec60da3647c48ff88f6556ade775" +dependencies = [ + "borsh 1.6.0", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-pubkey", +] + +[[package]] +name = "solana-program-memory" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a5426090c6f3fd6cfdc10685322fede9ca8e5af43cd6a59e98bfe4e91671712" +dependencies = [ + "solana-define-syscall", +] + +[[package]] +name = "solana-program-option" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc677a2e9bc616eda6dbdab834d463372b92848b2bfe4a1ed4e4b4adba3397d0" + +[[package]] +name = "solana-program-pack" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "319f0ef15e6e12dc37c597faccb7d62525a509fec5f6975ecb9419efddeb277b" +dependencies = [ + "solana-program-error", +] + +[[package]] +name = "solana-pubkey" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b62adb9c3261a052ca1f999398c388f1daf558a1b492f60a6d9e64857db4ff1" +dependencies = [ + "borsh 0.10.4", + "borsh 1.6.0", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "five8", + "five8_const", + "getrandom 0.2.16", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-decode-error", + "solana-define-syscall", + "solana-sanitize", + "solana-sha256-hasher", + "wasm-bindgen", +] + +[[package]] +name = "solana-rent" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1aea8fdea9de98ca6e8c2da5827707fb3842833521b528a713810ca685d2480" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-reward-info" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18205b69139b1ae0ab8f6e11cdcb627328c0814422ad2482000fa2ca54ae4a2f" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-sanitize" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61f1bc1357b8188d9c4a3af3fc55276e56987265eb7ad073ae6f8180ee54cecf" + +[[package]] +name = "solana-sdk-ids" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5d8b9cc68d5c88b062a33e23a6466722467dde0035152d8fb1afbcdf350a5f" +dependencies = [ + "solana-pubkey", +] + +[[package]] +name = "solana-sdk-macro" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86280da8b99d03560f6ab5aca9de2e38805681df34e0bb8f238e69b29433b9df" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "syn 2.0.113", +] + +[[package]] +name = "solana-secp256k1-recover" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa3120b6cdaa270f39444f5093a90a7b03d296d362878f7a6991d6de3bbe496" +dependencies = [ + "libsecp256k1", + "solana-define-syscall", + "thiserror 2.0.17", +] + +[[package]] +name = "solana-security-txt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" + +[[package]] +name = "solana-seed-derivable" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beb82b5adb266c6ea90e5cf3967235644848eac476c5a1f2f9283a143b7c97f" +dependencies = [ + "solana-derivation-path", +] + +[[package]] +name = "solana-seed-phrase" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36187af2324f079f65a675ec22b31c24919cb4ac22c79472e85d819db9bbbc15" +dependencies = [ + "hmac", + "pbkdf2", + "sha2 0.10.9", +] + +[[package]] +name = "solana-serde-varint" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a7e155eba458ecfb0107b98236088c3764a09ddf0201ec29e52a0be40857113" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-serialize-utils" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "817a284b63197d2b27afdba829c5ab34231da4a9b4e763466a003c40ca4f535e" +dependencies = [ + "solana-instruction", + "solana-pubkey", + "solana-sanitize", +] + +[[package]] +name = "solana-sha256-hasher" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa3feb32c28765f6aa1ce8f3feac30936f16c5c3f7eb73d63a5b8f6f8ecdc44" +dependencies = [ + "sha2 0.10.9", + "solana-define-syscall", + "solana-hash", +] + +[[package]] +name = "solana-short-vec" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c54c66f19b9766a56fa0057d060de8378676cb64987533fa088861858fc5a69" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-signature" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c8ec8e657aecfc187522fc67495142c12f35e55ddeca8698edbb738b8dbd8c" +dependencies = [ + "ed25519-dalek", + "five8", + "serde", + "serde-big-array", + "serde_derive", + "solana-sanitize", +] + +[[package]] +name = "solana-signer" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c41991508a4b02f021c1342ba00bcfa098630b213726ceadc7cb032e051975b" +dependencies = [ + "solana-pubkey", + "solana-signature", + "solana-transaction-error", +] + +[[package]] +name = "solana-slot-hashes" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8691982114513763e88d04094c9caa0376b867a29577939011331134c301ce" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-slot-history" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ccc1b2067ca22754d5283afb2b0126d61eae734fc616d23871b0943b0d935e" +dependencies = [ + "bv", + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-stable-layout" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f14f7d02af8f2bc1b5efeeae71bc1c2b7f0f65cd75bcc7d8180f2c762a57f54" +dependencies = [ + "solana-instruction", + "solana-pubkey", +] + +[[package]] +name = "solana-stake-interface" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5269e89fde216b4d7e1d1739cf5303f8398a1ff372a81232abbee80e554a838c" +dependencies = [ + "borsh 0.10.4", + "borsh 1.6.0", + "num-traits", + "serde", + "serde_derive", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-system-interface", + "solana-sysvar-id", +] + +[[package]] +name = "solana-svm-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f24b836eb4d74ec255217bdbe0f24f64a07adeac31aca61f334f91cd4a3b1d5" + +[[package]] +name = "solana-system-interface" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94d7c18cb1a91c6be5f5a8ac9276a1d7c737e39a21beba9ea710ab4b9c63bc90" +dependencies = [ + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction", + "solana-pubkey", + "wasm-bindgen", +] + +[[package]] +name = "solana-sysvar" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8c3595f95069f3d90f275bb9bd235a1973c4d059028b0a7f81baca2703815db" +dependencies = [ + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "lazy_static", + "serde", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-define-syscall", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-last-restart-slot", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", + "solana-rent", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-slot-hashes", + "solana-slot-history", + "solana-stake-interface", + "solana-sysvar-id", +] + +[[package]] +name = "solana-sysvar-id" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5762b273d3325b047cfda250787f8d796d781746860d5d0a746ee29f3e8812c1" +dependencies = [ + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-transaction" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80657d6088f721148f5d889c828ca60c7daeedac9a8679f9ec215e0c42bcbf41" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-instruction", + "solana-keypair", + "solana-message", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-signature", + "solana-transaction-error", + "wasm-bindgen", +] + +[[package]] +name = "solana-transaction-context" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a312304361987a85b2ef2293920558e6612876a639dd1309daf6d0d59ef2fe" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account", + "solana-instruction", + "solana-instructions-sysvar", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", +] + +[[package]] +name = "solana-transaction-error" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a9dc8fdb61c6088baab34fc3a8b8473a03a7a5fd404ed8dd502fa79b67cb1" +dependencies = [ + "serde", + "serde_derive", + "solana-instruction", + "solana-sanitize", +] + +[[package]] +name = "solana-transaction-status" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135f92f4192cc68900c665becf97fc0a6500ae5a67ff347bf2cbc20ecfefa821" +dependencies = [ + "Inflector", + "agave-reserved-account-keys", + "base64 0.22.1", + "bincode", + "borsh 1.6.0", + "bs58", + "log", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-hash", + "solana-instruction", + "solana-loader-v2-interface", + "solana-loader-v3-interface", + "solana-message", + "solana-program-option", + "solana-pubkey", + "solana-reward-info", + "solana-sdk-ids", + "solana-signature", + "solana-stake-interface", + "solana-system-interface", + "solana-transaction", + "solana-transaction-error", + "solana-transaction-status-client-types", + "solana-vote-interface", + "spl-associated-token-account", + "spl-memo", + "spl-token", + "spl-token-2022", + "spl-token-group-interface", + "spl-token-metadata-interface", + "thiserror 2.0.17", +] + +[[package]] +name = "solana-transaction-status-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f1d7c2387c35850848212244d2b225847666cb52d3bd59a5c409d2c300303d" +dependencies = [ + "base64 0.22.1", + "bincode", + "bs58", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder-client-types", + "solana-commitment-config", + "solana-message", + "solana-reward-info", + "solana-signature", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "thiserror 2.0.17", +] + +[[package]] +name = "solana-vote-interface" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b80d57478d6599d30acc31cc5ae7f93ec2361a06aefe8ea79bc81739a08af4c3" +dependencies = [ + "bincode", + "num-derive", + "num-traits", + "serde", + "serde_derive", + "solana-clock", + "solana-decode-error", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-serde-varint", + "solana-serialize-utils", + "solana-short-vec", + "solana-system-interface", +] + +[[package]] +name = "solana-zk-sdk" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b9fc6ec37d16d0dccff708ed1dd6ea9ba61796700c3bb7c3b401973f10f63b" +dependencies = [ + "aes-gcm-siv", + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "itertools 0.12.1", + "js-sys", + "merlin", + "num-derive", + "num-traits", + "rand 0.8.5", + "serde", + "serde_derive", + "serde_json", + "sha3", + "solana-derivation-path", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-seed-derivable", + "solana-seed-phrase", + "solana-signature", + "solana-signer", + "subtle", + "thiserror 2.0.17", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "spl-associated-token-account" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae179d4a26b3c7a20c839898e6aed84cb4477adf108a366c95532f058aea041b" dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", + "borsh 1.6.0", + "num-derive", + "num-traits", + "solana-program", + "spl-associated-token-account-client", + "spl-token", + "spl-token-2022", + "thiserror 2.0.17", ] [[package]] -name = "serde_spanned" -version = "0.6.9" +name = "spl-associated-token-account-client" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "d6f8349dbcbe575f354f9a533a21f272f3eb3808a49e2fdc1c34393b88ba76cb" dependencies = [ - "serde", + "solana-instruction", + "solana-pubkey", ] [[package]] -name = "serde_urlencoded" -version = "0.7.1" +name = "spl-discriminator" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +checksum = "a7398da23554a31660f17718164e31d31900956054f54f52d5ec1be51cb4f4b3" dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", + "bytemuck", + "solana-program-error", + "solana-sha256-hasher", + "spl-discriminator-derive", ] [[package]] -name = "sha1" -version = "0.10.6" +name = "spl-discriminator-derive" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "quote", + "spl-discriminator-syn", + "syn 2.0.113", ] [[package]] -name = "sha2" -version = "0.10.9" +name = "spl-discriminator-syn" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "5d1dbc82ab91422345b6df40a79e2b78c7bce1ebb366da323572dd60b7076b67" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.113", + "thiserror 1.0.69", ] [[package]] -name = "sharded-slab" -version = "0.1.7" +name = "spl-elgamal-registry" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +checksum = "65edfeed09cd4231e595616aa96022214f9c9d2be02dea62c2b30d5695a6833a" dependencies = [ - "lazy_static", + "bytemuck", + "solana-account-info", + "solana-cpi", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-system-interface", + "solana-sysvar", + "solana-zk-sdk", + "spl-pod", + "spl-token-confidential-transfer-proof-extraction", ] [[package]] -name = "shell-words" -version = "1.1.1" +name = "spl-generic-token" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" +checksum = "741a62a566d97c58d33f9ed32337ceedd4e35109a686e31b1866c5dfa56abddc" +dependencies = [ + "bytemuck", + "solana-pubkey", +] [[package]] -name = "shlex" -version = "1.3.0" +name = "spl-memo" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "9f09647c0974e33366efeb83b8e2daebb329f0420149e74d3a4bd2c08cf9f7cb" +dependencies = [ + "solana-account-info", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", +] [[package]] -name = "signal-hook-registry" -version = "1.4.8" +name = "spl-pod" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +checksum = "d994afaf86b779104b4a95ba9ca75b8ced3fdb17ee934e38cb69e72afbe17799" dependencies = [ - "errno", - "libc", + "borsh 1.6.0", + "bytemuck", + "bytemuck_derive", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "solana-program-option", + "solana-pubkey", + "solana-zk-sdk", + "thiserror 2.0.17", ] [[package]] -name = "simd-adler32" -version = "0.3.8" +name = "spl-program-error" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "9cdebc8b42553070b75aa5106f071fef2eb798c64a7ec63375da4b1f058688c6" +dependencies = [ + "num-derive", + "num-traits", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "spl-program-error-derive", + "thiserror 2.0.17", +] [[package]] -name = "slab" -version = "0.4.11" +name = "spl-program-error-derive" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "2a2539e259c66910d78593475540e8072f0b10f0f61d7607bbf7593899ed52d0" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.113", +] [[package]] -name = "smallvec" -version = "1.15.1" +name = "spl-tlv-account-resolution" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "1408e961215688715d5a1063cbdcf982de225c45f99c82b4f7d7e1dd22b998d7" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", + "thiserror 2.0.17", +] [[package]] -name = "socket2" -version = "0.5.10" +name = "spl-token" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +checksum = "053067c6a82c705004f91dae058b11b4780407e9ccd6799dc9e7d0fab5f242da" dependencies = [ - "libc", - "windows-sys 0.52.0", + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-sysvar", + "thiserror 2.0.17", ] [[package]] -name = "socket2" -version = "0.6.1" +name = "spl-token-2022" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "31f0dfbb079eebaee55e793e92ca5f433744f4b71ee04880bfd6beefba5973e5" dependencies = [ - "libc", - "windows-sys 0.60.2", + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-native-token", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-security-txt", + "solana-system-interface", + "solana-sysvar", + "solana-zk-sdk", + "spl-elgamal-registry", + "spl-memo", + "spl-pod", + "spl-token", + "spl-token-confidential-transfer-ciphertext-arithmetic", + "spl-token-confidential-transfer-proof-extraction", + "spl-token-confidential-transfer-proof-generation", + "spl-token-group-interface", + "spl-token-metadata-interface", + "spl-transfer-hook-interface", + "spl-type-length-value", + "thiserror 2.0.17", ] [[package]] -name = "solana-atomic-u64" -version = "2.2.1" +name = "spl-token-confidential-transfer-ciphertext-arithmetic" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52e52720efe60465b052b9e7445a01c17550666beec855cce66f44766697bc2" +checksum = "cddd52bfc0f1c677b41493dafa3f2dbbb4b47cf0990f08905429e19dc8289b35" dependencies = [ - "parking_lot 0.12.5", + "base64 0.22.1", + "bytemuck", + "solana-curve25519", + "solana-zk-sdk", ] [[package]] -name = "solana-decode-error" -version = "2.3.0" +name = "spl-token-confidential-transfer-proof-extraction" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c781686a18db2f942e70913f7ca15dc120ec38dcab42ff7557db2c70c625a35" +checksum = "fe2629860ff04c17bafa9ba4bed8850a404ecac81074113e1f840dbd0ebb7bd6" dependencies = [ - "num-traits", + "bytemuck", + "solana-account-info", + "solana-curve25519", + "solana-instruction", + "solana-instructions-sysvar", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "solana-sdk-ids", + "solana-zk-sdk", + "spl-pod", + "thiserror 2.0.17", ] [[package]] -name = "solana-define-syscall" -version = "2.3.0" +name = "spl-token-confidential-transfer-proof-generation" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae3e2abcf541c8122eafe9a625d4d194b4023c20adde1e251f94e056bb1aee2" +checksum = "fa27b9174bea869a7ebf31e0be6890bce90b1a4288bc2bbf24bd413f80ae3fde" +dependencies = [ + "curve25519-dalek 4.1.3", + "solana-zk-sdk", + "thiserror 2.0.17", +] [[package]] -name = "solana-hash" -version = "2.3.0" +name = "spl-token-group-interface" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b96e9f0300fa287b545613f007dfe20043d7812bee255f418c1eb649c93b63" +checksum = "5597b4cd76f85ce7cd206045b7dc22da8c25516573d42d267c8d1fd128db5129" dependencies = [ - "five8", - "js-sys", - "solana-atomic-u64", - "solana-sanitize", - "wasm-bindgen", + "bytemuck", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "thiserror 2.0.17", ] [[package]] -name = "solana-pubkey" -version = "2.4.0" +name = "spl-token-metadata-interface" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b62adb9c3261a052ca1f999398c388f1daf558a1b492f60a6d9e64857db4ff1" +checksum = "304d6e06f0de0c13a621464b1fd5d4b1bebf60d15ca71a44d3839958e0da16ee" dependencies = [ - "five8", - "five8_const", - "getrandom 0.2.16", - "js-sys", + "borsh 1.6.0", + "num-derive", "num-traits", - "solana-atomic-u64", + "solana-borsh", "solana-decode-error", - "solana-define-syscall", - "solana-sanitize", - "solana-sha256-hasher", - "wasm-bindgen", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-type-length-value", + "thiserror 2.0.17", ] [[package]] -name = "solana-sanitize" -version = "2.2.1" +name = "spl-transfer-hook-interface" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61f1bc1357b8188d9c4a3af3fc55276e56987265eb7ad073ae6f8180ee54cecf" +checksum = "a7e905b849b6aba63bde8c4badac944ebb6c8e6e14817029cbe1bc16829133bd" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value", + "thiserror 2.0.17", +] [[package]] -name = "solana-sha256-hasher" -version = "2.3.0" +name = "spl-type-length-value" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa3feb32c28765f6aa1ce8f3feac30936f16c5c3f7eb73d63a5b8f6f8ecdc44" +checksum = "d417eb548214fa822d93f84444024b4e57c13ed6719d4dcc68eec24fb481e9f5" dependencies = [ - "sha2", - "solana-define-syscall", - "solana-hash", + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "spl-discriminator", + "spl-pod", + "thiserror 2.0.17", ] [[package]] @@ -3032,6 +5158,17 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.113" @@ -3066,7 +5203,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -3150,7 +5287,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -3161,7 +5298,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -3233,7 +5370,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -3332,6 +5469,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "toml" version = "0.8.23" @@ -3340,8 +5486,8 @@ checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", - "toml_datetime", - "toml_edit", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", ] [[package]] @@ -3353,6 +5499,15 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "1.0.0+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.22.27" @@ -3362,11 +5517,32 @@ dependencies = [ "indexmap 2.12.1", "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "toml_write", "winnow", ] +[[package]] +name = "toml_edit" +version = "0.25.4+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7193cbd0ce53dc966037f54351dbbcf0d5a642c7f0038c382ef9e677ce8c13f2" +dependencies = [ + "indexmap 2.12.1", + "toml_datetime 1.0.0+spec-1.1.0", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.9+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +dependencies = [ + "winnow", +] + [[package]] name = "toml_write" version = "0.1.2" @@ -3476,7 +5652,7 @@ dependencies = [ "prost-build 0.13.5", "prost-types 0.13.5", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -3488,7 +5664,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -3526,7 +5702,7 @@ dependencies = [ "prost-build 0.14.1", "prost-types 0.14.1", "quote", - "syn", + "syn 2.0.113", "tempfile", "tonic-build 0.14.2", ] @@ -3649,7 +5825,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -3791,12 +5967,32 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + [[package]] name = "url" version = "2.5.8" @@ -3872,6 +6068,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -3932,7 +6134,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.113", "wasm-bindgen-shared", ] @@ -4032,7 +6234,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -4043,7 +6245,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -4363,9 +6565,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbba21b6046eff1c9be2366a70d7264763b10004306e874b54409503a39e5f1e" dependencies = [ "anyhow", + "bincode", "prost 0.14.1", "prost-types 0.14.1", "protobuf-src", + "solana-account", + "solana-account-decoder", + "solana-clock", + "solana-hash", + "solana-message", + "solana-pubkey", + "solana-signature", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "solana-transaction-status", "tonic 0.14.2", "tonic-build 0.14.2", "tonic-prost", @@ -4399,7 +6613,7 @@ version = "0.6.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e2760099b3e0810026ec77bb886bbe62bffa70819eea4defb62d480366d828b" dependencies = [ - "borsh", + "borsh 1.6.0", "bs58", "clap", "serde", @@ -4458,7 +6672,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", "synstructure", ] @@ -4479,7 +6693,7 @@ checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] @@ -4499,7 +6713,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", "synstructure", ] @@ -4508,6 +6722,20 @@ name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.113", +] [[package]] name = "zerotrie" @@ -4539,7 +6767,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.113", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 941c862f..081dbd54 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,3 +29,6 @@ yellowstone-vixen = "0.6.0-alpha.0" yellowstone-vixen-core = "0.6.0-alpha.0" yellowstone-vixen-proto = "0.6.0-alpha.0" yellowstone-vixen-yellowstone-grpc-source = "0.6.0-alpha.0" +# Yellowstone gRPC client (for standalone slot subscriptions) +yellowstone-grpc-client = "9.1.0" +yellowstone-grpc-proto = "9.1.0" diff --git a/examples/ore-react/src/components/BlockGrid.tsx b/examples/ore-react/src/components/BlockGrid.tsx index 2f1bc212..b90dcb8e 100644 --- a/examples/ore-react/src/components/BlockGrid.tsx +++ b/examples/ore-react/src/components/BlockGrid.tsx @@ -11,7 +11,7 @@ export function BlockGrid({ round }: BlockGridProps) { id: i + 1, minerCount: round.state.count_per_square[i], deployedUi, - isWinner: round.results?.winning_square === i, + isWinner: (round.results?.winning_square === i) || (round.results?.pre_reveal_winning_square === i), })) : Array.from({ length: 25 }, (_, i) => ({ id: i + 1, @@ -21,9 +21,9 @@ export function BlockGrid({ round }: BlockGridProps) { })); return ( -
diff --git a/examples/ore-server/Cargo.lock b/examples/ore-server/Cargo.lock index 5e68ebd1..4a61a85d 100644 --- a/examples/ore-server/Cargo.lock +++ b/examples/ore-server/Cargo.lock @@ -2,12 +2,83 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + [[package]] name = "adler2" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "agave-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a2c365c0245cbb8959de725fc2b44c754b673fdf34c9a7f9d4a25c35a7bf1" +dependencies = [ + "ahash", + "solana-epoch-schedule", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", + "solana-svm-feature-set", +] + +[[package]] +name = "agave-reserved-account-keys" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8289c8a8a2ef5aa10ce49a070f360f4e035ee3410b8d8f3580fb39d8cf042581" +dependencies = [ + "agave-feature-set", + "solana-pubkey", + "solana-sdk-ids", +] + [[package]] name = "ahash" version = "0.8.12" @@ -15,6 +86,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -37,9 +109,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -52,15 +124,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -87,9 +159,21 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "async-stream" @@ -110,7 +194,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -121,7 +205,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -235,6 +319,12 @@ dependencies = [ "tower-service", ] +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + [[package]] name = "base64" version = "0.21.7" @@ -247,6 +337,15 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -255,9 +354,33 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" + +[[package]] +name = "blake3" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2468ef7d57b3fb7e16b576e8377cdbde2320c60e1491e961d11da40fc4f02a2d" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] [[package]] name = "block-buffer" @@ -308,10 +431,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" dependencies = [ "once_cell", - "proc-macro-crate 3.4.0", + "proc-macro-crate 3.5.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -347,9 +470,19 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" + +[[package]] +name = "bv" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] [[package]] name = "bytemuck" @@ -368,7 +501,7 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -379,15 +512,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.53" +version = "1.2.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932" +checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" dependencies = [ "find-msvc-tools", "jobserver", @@ -407,11 +540,21 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" -version = "4.5.54" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" dependencies = [ "clap_builder", "clap_derive", @@ -419,9 +562,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.54" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", @@ -432,27 +575,53 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "clap_lex" -version = "0.7.7" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "constant_time_eq" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] name = "core-foundation" @@ -554,6 +723,12 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + [[package]] name = "crypto-common" version = "0.1.7" @@ -561,9 +736,61 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rand_core 0.6.4", + "rustc_version", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "dashmap" version = "6.1.0" @@ -584,14 +811,30 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +[[package]] +name = "derivation-path" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "crypto-common", + "subtle", ] [[package]] @@ -602,7 +845,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -622,7 +865,7 @@ checksum = "c32e3e8ab1b6ee2e06418f40f94f315d82b35157eb1d2322a6e20a4b15106b84" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -631,6 +874,29 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + [[package]] name = "either" version = "1.15.0" @@ -668,11 +934,23 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "find-msvc-tools" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "five8" @@ -706,9 +984,9 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flate2" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", @@ -737,9 +1015,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -752,9 +1030,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -762,15 +1040,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -779,38 +1057,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -820,7 +1098,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -834,6 +1111,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.17" @@ -843,7 +1131,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -856,11 +1144,24 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "wasip2", + "wasip3", +] + [[package]] name = "h2" version = "0.3.27" @@ -955,6 +1256,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "http" version = "0.2.12" @@ -1092,12 +1402,12 @@ dependencies = [ "http 1.4.0", "hyper 1.8.1", "hyper-util", - "rustls 0.23.36", + "rustls 0.23.37", "rustls-pki-types", "tokio", "tokio-rustls 0.26.4", "tower-service", - "webpki-roots 1.0.5", + "webpki-roots 1.0.6", ] [[package]] @@ -1115,14 +1425,13 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64 0.22.1", "bytes", "futures-channel", - "futures-core", "futures-util", "http 1.4.0", "http-body 1.0.1", @@ -1131,7 +1440,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.1", + "socket2 0.6.3", "tokio", "tower-service", "tracing", @@ -1153,9 +1462,12 @@ dependencies = [ "reqwest 0.11.27", "serde", "serde_json", + "sha3", "smallvec", "tokio", "tracing", + "yellowstone-grpc-client", + "yellowstone-grpc-proto", "yellowstone-vixen", "yellowstone-vixen-core", "yellowstone-vixen-yellowstone-grpc-source", @@ -1167,7 +1479,7 @@ version = "0.1.2" dependencies = [ "serde", "serde_json", - "sha2", + "sha2 0.10.9", "strsim", ] @@ -1182,6 +1494,7 @@ dependencies = [ "hyperstack-idl", "hyperstack-macros", "lru", + "once_cell", "percent-encoding", "prost 0.13.5", "prost-reflect", @@ -1189,8 +1502,10 @@ dependencies = [ "reqwest 0.12.28", "serde", "serde_json", - "sha2", + "sha2 0.10.9", + "sha3", "solana-pubkey", + "tokio", "tonic 0.12.3", "tracing", ] @@ -1206,8 +1521,8 @@ dependencies = [ "quote", "serde", "serde_json", - "sha2", - "syn 2.0.114", + "sha2 0.10.9", + "syn 2.0.117", ] [[package]] @@ -1243,6 +1558,7 @@ dependencies = [ "hyper-util", "hyperstack-interpreter", "lru", + "once_cell", "serde", "serde_json", "smallvec", @@ -1340,6 +1656,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "idna" version = "1.1.0" @@ -1379,6 +1701,17 @@ checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown 0.16.1", + "serde", + "serde_core", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", ] [[package]] @@ -1392,9 +1725,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" @@ -1412,6 +1745,15 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.14.0" @@ -1439,31 +1781,102 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.85" +version = "0.3.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" dependencies = [ "once_cell", "wasm-bindgen", ] [[package]] -name = "lazy_static" -version = "1.5.0" +name = "kaigan" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "2ba15de5aeb137f0f65aa3bf82187647f1285abfe5b20c80c2c37f7007ad519a" +dependencies = [ + "borsh 0.10.4", + "serde", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.180" +version = "0.2.183" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" @@ -1524,9 +1937,30 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "merlin" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] [[package]] name = "mime" @@ -1551,7 +1985,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.61.2", ] @@ -1570,6 +2004,36 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1589,11 +2053,33 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate 3.5.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -1601,11 +2087,17 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "openssl-probe" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "ore-server" @@ -1615,7 +2107,7 @@ dependencies = [ "dotenvy", "hyperstack-server", "ore-stack", - "rustls 0.23.36", + "rustls 0.23.37", "tokio", "tracing-subscriber", ] @@ -1678,6 +2170,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -1707,29 +2208,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "pin-project-lite" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pin-utils" @@ -1743,6 +2244,18 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "potential_utf" version = "0.1.4" @@ -1768,7 +2281,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1782,18 +2295,18 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -1825,7 +2338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" dependencies = [ "heck", - "itertools", + "itertools 0.14.0", "log", "multimap", "once_cell", @@ -1834,7 +2347,7 @@ dependencies = [ "prost 0.13.5", "prost-types 0.13.5", "regex", - "syn 2.0.114", + "syn 2.0.117", "tempfile", ] @@ -1845,7 +2358,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" dependencies = [ "heck", - "itertools", + "itertools 0.14.0", "log", "multimap", "petgraph 0.8.3", @@ -1855,7 +2368,7 @@ dependencies = [ "pulldown-cmark", "pulldown-cmark-to-cmark", "regex", - "syn 2.0.114", + "syn 2.0.117", "tempfile", ] @@ -1866,10 +2379,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools", + "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1879,10 +2392,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" dependencies = [ "anyhow", - "itertools", + "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1924,11 +2437,11 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" +checksum = "83c41efbf8f90ac44de7f3a868f0867851d261b56291732d0cbf7cceaaeb55a6" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "memchr", "unicase", ] @@ -1942,6 +2455,15 @@ dependencies = [ "pulldown-cmark", ] +[[package]] +name = "qstring" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding", +] + [[package]] name = "quinn" version = "0.11.9" @@ -1954,8 +2476,8 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.36", - "socket2 0.5.10", + "rustls 0.23.37", + "socket2 0.6.3", "thiserror 2.0.18", "tokio", "tracing", @@ -1974,7 +2496,7 @@ dependencies = [ "rand 0.9.2", "ring", "rustc-hash", - "rustls 0.23.36", + "rustls 0.23.37", "rustls-pki-types", "slab", "thiserror 2.0.18", @@ -1992,16 +2514,16 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.10", + "socket2 0.6.3", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] name = "quote" -version = "1.0.43" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -2012,6 +2534,25 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + [[package]] name = "rand" version = "0.8.5" @@ -2033,6 +2574,16 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -2053,6 +2604,15 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + [[package]] name = "rand_core" version = "0.6.4" @@ -2071,6 +2631,15 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -2086,14 +2655,14 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", ] [[package]] name = "regex" -version = "1.12.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -2103,9 +2672,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -2114,9 +2683,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "reqwest" @@ -2179,7 +2748,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.36", + "rustls 0.23.37", "rustls-pki-types", "serde", "serde_json", @@ -2194,7 +2763,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 1.0.5", + "webpki-roots 1.0.6", ] [[package]] @@ -2217,13 +2786,22 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "errno", "libc", "linux-raw-sys", @@ -2258,9 +2836,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.36" +version = "0.23.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" dependencies = [ "log", "once_cell", @@ -2342,15 +2920,15 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] @@ -2373,11 +2951,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.5.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -2386,14 +2964,20 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.15.0" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", ] +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + [[package]] name = "serde" version = "1.0.228" @@ -2404,6 +2988,25 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -2421,7 +3024,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2457,7 +3060,20 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", ] [[package]] @@ -2468,7 +3084,17 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", ] [[package]] @@ -2477,138 +3103,1571 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ - "lazy_static", + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "solana-account" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f949fe4edaeaea78c844023bfc1c898e0b1f5a100f8a8d2d0f85d0a7b090258" +dependencies = [ + "bincode", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-sysvar", +] + +[[package]] +name = "solana-account-decoder" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba71c97fa4d85ce4a1e0e79044ad0406c419382be598c800202903a7688ce71a" +dependencies = [ + "Inflector", + "base64 0.22.1", + "bincode", + "bs58", + "bv", + "serde", + "serde_derive", + "serde_json", + "solana-account", + "solana-account-decoder-client-types", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-config-program-client", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-instruction", + "solana-loader-v3-interface", + "solana-nonce", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-slot-hashes", + "solana-slot-history", + "solana-stake-interface", + "solana-sysvar", + "solana-vote-interface", + "spl-generic-token", + "spl-token", + "spl-token-2022", + "spl-token-group-interface", + "spl-token-metadata-interface", + "thiserror 2.0.18", + "zstd", +] + +[[package]] +name = "solana-account-decoder-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5519e8343325b707f17fbed54fcefb325131b692506d0af9e08a539d15e4f8cf" +dependencies = [ + "base64 0.22.1", + "bs58", + "serde", + "serde_derive", + "serde_json", + "solana-account", + "solana-pubkey", + "zstd", +] + +[[package]] +name = "solana-account-info" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8f5152a288ef1912300fc6efa6c2d1f9bb55d9398eb6c72326360b8063987da" +dependencies = [ + "bincode", + "serde", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", +] + +[[package]] +name = "solana-address-lookup-table-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1673f67efe870b64a65cb39e6194be5b26527691ce5922909939961a6e6b395" +dependencies = [ + "bincode", + "bytemuck", + "serde", + "serde_derive", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-slot-hashes", +] + +[[package]] +name = "solana-atomic-u64" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52e52720efe60465b052b9e7445a01c17550666beec855cce66f44766697bc2" +dependencies = [ + "parking_lot 0.12.5", +] + +[[package]] +name = "solana-big-mod-exp" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75db7f2bbac3e62cfd139065d15bcda9e2428883ba61fc8d27ccb251081e7567" +dependencies = [ + "num-bigint", + "num-traits", + "solana-define-syscall", +] + +[[package]] +name = "solana-bincode" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a3787b8cf9c9fe3dd360800e8b70982b9e5a8af9e11c354b6665dd4a003adc" +dependencies = [ + "bincode", + "serde", + "solana-instruction", +] + +[[package]] +name = "solana-blake3-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0801e25a1b31a14494fc80882a036be0ffd290efc4c2d640bfcca120a4672" +dependencies = [ + "blake3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + +[[package]] +name = "solana-borsh" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718333bcd0a1a7aed6655aa66bef8d7fb047944922b2d3a18f49cbc13e73d004" +dependencies = [ + "borsh 0.10.4", + "borsh 1.6.0", +] + +[[package]] +name = "solana-clock" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8584296123df8fe229b95e2ebfd37ae637fe9db9b7d4dd677ac5a78e80dbfce" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-commitment-config" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac49c4dde3edfa832de1697e9bcdb7c3b3f7cb7a1981b7c62526c8bb6700fb73" + +[[package]] +name = "solana-config-program-client" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53aceac36f105fd4922e29b4f0c1f785b69d7b3e7e387e384b8985c8e0c3595e" +dependencies = [ + "bincode", + "borsh 0.10.4", + "kaigan", + "serde", + "solana-program", +] + +[[package]] +name = "solana-cpi" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc71126edddc2ba014622fc32d0f5e2e78ec6c5a1e0eb511b85618c09e9ea11" +dependencies = [ + "solana-account-info", + "solana-define-syscall", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-stable-layout", +] + +[[package]] +name = "solana-curve25519" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae4261b9a8613d10e77ac831a8fa60b6fa52b9b103df46d641deff9f9812a23" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "solana-define-syscall", + "subtle", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-decode-error" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c781686a18db2f942e70913f7ca15dc120ec38dcab42ff7557db2c70c625a35" +dependencies = [ + "num-traits", +] + +[[package]] +name = "solana-define-syscall" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae3e2abcf541c8122eafe9a625d4d194b4023c20adde1e251f94e056bb1aee2" + +[[package]] +name = "solana-derivation-path" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "939756d798b25c5ec3cca10e06212bdca3b1443cb9bb740a38124f58b258737b" +dependencies = [ + "derivation-path", + "qstring", + "uriparse", +] + +[[package]] +name = "solana-epoch-rewards" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b575d3dd323b9ea10bb6fe89bf6bf93e249b215ba8ed7f68f1a3633f384db7" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-epoch-schedule" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fce071fbddecc55d727b1d7ed16a629afe4f6e4c217bc8d00af3b785f6f67ed" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-example-mocks" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84461d56cbb8bb8d539347151e0525b53910102e4bced875d49d5139708e39d3" +dependencies = [ + "serde", + "serde_derive", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-hash", + "solana-instruction", + "solana-keccak-hasher", + "solana-message", + "solana-nonce", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-feature-gate-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f5c5382b449e8e4e3016fb05e418c53d57782d8b5c30aa372fc265654b956d" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-fee-calculator" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89bc408da0fb3812bc3008189d148b4d3e08252c79ad810b245482a3f70cd8d" +dependencies = [ + "log", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-hash" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b96e9f0300fa287b545613f007dfe20043d7812bee255f418c1eb649c93b63" +dependencies = [ + "borsh 1.6.0", + "bytemuck", + "bytemuck_derive", + "five8", + "js-sys", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-sanitize", + "wasm-bindgen", +] + +[[package]] +name = "solana-instruction" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab5682934bd1f65f8d2c16f21cb532526fcc1a09f796e2cacdb091eee5774ad" +dependencies = [ + "bincode", + "borsh 1.6.0", + "getrandom 0.2.17", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "serde_json", + "solana-define-syscall", + "solana-pubkey", + "wasm-bindgen", +] + +[[package]] +name = "solana-instructions-sysvar" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0e85a6fad5c2d0c4f5b91d34b8ca47118fc593af706e523cdbedf846a954f57" +dependencies = [ + "bitflags 2.11.0", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-serialize-utils", + "solana-sysvar-id", +] + +[[package]] +name = "solana-keccak-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7aeb957fbd42a451b99235df4942d96db7ef678e8d5061ef34c9b34cae12f79" +dependencies = [ + "sha3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + +[[package]] +name = "solana-keypair" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd3f04aa1a05c535e93e121a95f66e7dcccf57e007282e8255535d24bf1e98bb" +dependencies = [ + "ed25519-dalek", + "five8", + "rand 0.7.3", + "solana-pubkey", + "solana-seed-phrase", + "solana-signature", + "solana-signer", + "wasm-bindgen", +] + +[[package]] +name = "solana-last-restart-slot" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6360ac2fdc72e7463565cd256eedcf10d7ef0c28a1249d261ec168c1b55cdd" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-loader-v2-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ab08006dad78ae7cd30df8eea0539e207d08d91eaefb3e1d49a446e1c49654" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-loader-v3-interface" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f7162a05b8b0773156b443bccd674ea78bb9aa406325b467ea78c06c99a63a2" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-loader-v4-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "706a777242f1f39a83e2a96a2a6cb034cb41169c6ecbee2cf09cb873d9659e7e" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-message" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1796aabce376ff74bf89b78d268fa5e683d7d7a96a0a4e4813ec34de49d5314b" +dependencies = [ + "bincode", + "blake3", + "lazy_static", + "serde", + "serde_derive", + "solana-bincode", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-system-interface", + "solana-transaction-error", + "wasm-bindgen", +] + +[[package]] +name = "solana-msg" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36a1a14399afaabc2781a1db09cb14ee4cc4ee5c7a5a3cfcc601811379a8092" +dependencies = [ + "solana-define-syscall", +] + +[[package]] +name = "solana-native-token" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61515b880c36974053dd499c0510066783f0cc6ac17def0c7ef2a244874cf4a9" + +[[package]] +name = "solana-nonce" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703e22eb185537e06204a5bd9d509b948f0066f2d1d814a6f475dafb3ddf1325" +dependencies = [ + "serde", + "serde_derive", + "solana-fee-calculator", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", +] + +[[package]] +name = "solana-program" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98eca145bd3545e2fbb07166e895370576e47a00a7d824e325390d33bf467210" +dependencies = [ + "bincode", + "blake3", + "borsh 0.10.4", + "borsh 1.6.0", + "bs58", + "bytemuck", + "console_error_panic_hook", + "console_log", + "getrandom 0.2.17", + "lazy_static", + "log", + "memoffset", + "num-bigint", + "num-derive", + "num-traits", + "rand 0.8.5", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info", + "solana-address-lookup-table-interface", + "solana-atomic-u64", + "solana-big-mod-exp", + "solana-bincode", + "solana-blake3-hasher", + "solana-borsh", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-define-syscall", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-example-mocks", + "solana-feature-gate-interface", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-keccak-hasher", + "solana-last-restart-slot", + "solana-loader-v2-interface", + "solana-loader-v3-interface", + "solana-loader-v4-interface", + "solana-message", + "solana-msg", + "solana-native-token", + "solana-nonce", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-secp256k1-recover", + "solana-serde-varint", + "solana-serialize-utils", + "solana-sha256-hasher", + "solana-short-vec", + "solana-slot-hashes", + "solana-slot-history", + "solana-stable-layout", + "solana-stake-interface", + "solana-system-interface", + "solana-sysvar", + "solana-sysvar-id", + "solana-vote-interface", + "thiserror 2.0.18", + "wasm-bindgen", +] + +[[package]] +name = "solana-program-entrypoint" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32ce041b1a0ed275290a5008ee1a4a6c48f5054c8a3d78d313c08958a06aedbd" +dependencies = [ + "solana-account-info", + "solana-msg", + "solana-program-error", + "solana-pubkey", +] + +[[package]] +name = "solana-program-error" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee2e0217d642e2ea4bee237f37bd61bb02aec60da3647c48ff88f6556ade775" +dependencies = [ + "borsh 1.6.0", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-pubkey", +] + +[[package]] +name = "solana-program-memory" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a5426090c6f3fd6cfdc10685322fede9ca8e5af43cd6a59e98bfe4e91671712" +dependencies = [ + "solana-define-syscall", +] + +[[package]] +name = "solana-program-option" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc677a2e9bc616eda6dbdab834d463372b92848b2bfe4a1ed4e4b4adba3397d0" + +[[package]] +name = "solana-program-pack" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "319f0ef15e6e12dc37c597faccb7d62525a509fec5f6975ecb9419efddeb277b" +dependencies = [ + "solana-program-error", +] + +[[package]] +name = "solana-pubkey" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b62adb9c3261a052ca1f999398c388f1daf558a1b492f60a6d9e64857db4ff1" +dependencies = [ + "borsh 0.10.4", + "borsh 1.6.0", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "five8", + "five8_const", + "getrandom 0.2.17", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-decode-error", + "solana-define-syscall", + "solana-sanitize", + "solana-sha256-hasher", + "wasm-bindgen", +] + +[[package]] +name = "solana-rent" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1aea8fdea9de98ca6e8c2da5827707fb3842833521b528a713810ca685d2480" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-reward-info" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18205b69139b1ae0ab8f6e11cdcb627328c0814422ad2482000fa2ca54ae4a2f" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-sanitize" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61f1bc1357b8188d9c4a3af3fc55276e56987265eb7ad073ae6f8180ee54cecf" + +[[package]] +name = "solana-sdk-ids" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5d8b9cc68d5c88b062a33e23a6466722467dde0035152d8fb1afbcdf350a5f" +dependencies = [ + "solana-pubkey", +] + +[[package]] +name = "solana-sdk-macro" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86280da8b99d03560f6ab5aca9de2e38805681df34e0bb8f238e69b29433b9df" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "solana-secp256k1-recover" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa3120b6cdaa270f39444f5093a90a7b03d296d362878f7a6991d6de3bbe496" +dependencies = [ + "libsecp256k1", + "solana-define-syscall", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-security-txt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" + +[[package]] +name = "solana-seed-derivable" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beb82b5adb266c6ea90e5cf3967235644848eac476c5a1f2f9283a143b7c97f" +dependencies = [ + "solana-derivation-path", +] + +[[package]] +name = "solana-seed-phrase" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36187af2324f079f65a675ec22b31c24919cb4ac22c79472e85d819db9bbbc15" +dependencies = [ + "hmac", + "pbkdf2", + "sha2 0.10.9", +] + +[[package]] +name = "solana-serde-varint" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a7e155eba458ecfb0107b98236088c3764a09ddf0201ec29e52a0be40857113" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-serialize-utils" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "817a284b63197d2b27afdba829c5ab34231da4a9b4e763466a003c40ca4f535e" +dependencies = [ + "solana-instruction", + "solana-pubkey", + "solana-sanitize", +] + +[[package]] +name = "solana-sha256-hasher" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa3feb32c28765f6aa1ce8f3feac30936f16c5c3f7eb73d63a5b8f6f8ecdc44" +dependencies = [ + "sha2 0.10.9", + "solana-define-syscall", + "solana-hash", +] + +[[package]] +name = "solana-short-vec" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c54c66f19b9766a56fa0057d060de8378676cb64987533fa088861858fc5a69" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-signature" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c8ec8e657aecfc187522fc67495142c12f35e55ddeca8698edbb738b8dbd8c" +dependencies = [ + "ed25519-dalek", + "five8", + "serde", + "serde-big-array", + "serde_derive", + "solana-sanitize", +] + +[[package]] +name = "solana-signer" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c41991508a4b02f021c1342ba00bcfa098630b213726ceadc7cb032e051975b" +dependencies = [ + "solana-pubkey", + "solana-signature", + "solana-transaction-error", +] + +[[package]] +name = "solana-slot-hashes" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8691982114513763e88d04094c9caa0376b867a29577939011331134c301ce" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-slot-history" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ccc1b2067ca22754d5283afb2b0126d61eae734fc616d23871b0943b0d935e" +dependencies = [ + "bv", + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-stable-layout" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f14f7d02af8f2bc1b5efeeae71bc1c2b7f0f65cd75bcc7d8180f2c762a57f54" +dependencies = [ + "solana-instruction", + "solana-pubkey", +] + +[[package]] +name = "solana-stake-interface" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5269e89fde216b4d7e1d1739cf5303f8398a1ff372a81232abbee80e554a838c" +dependencies = [ + "borsh 0.10.4", + "borsh 1.6.0", + "num-traits", + "serde", + "serde_derive", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-system-interface", + "solana-sysvar-id", +] + +[[package]] +name = "solana-svm-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f24b836eb4d74ec255217bdbe0f24f64a07adeac31aca61f334f91cd4a3b1d5" + +[[package]] +name = "solana-system-interface" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94d7c18cb1a91c6be5f5a8ac9276a1d7c737e39a21beba9ea710ab4b9c63bc90" +dependencies = [ + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction", + "solana-pubkey", + "wasm-bindgen", +] + +[[package]] +name = "solana-sysvar" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8c3595f95069f3d90f275bb9bd235a1973c4d059028b0a7f81baca2703815db" +dependencies = [ + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "lazy_static", + "serde", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-define-syscall", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-last-restart-slot", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", + "solana-rent", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-slot-hashes", + "solana-slot-history", + "solana-stake-interface", + "solana-sysvar-id", +] + +[[package]] +name = "solana-sysvar-id" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5762b273d3325b047cfda250787f8d796d781746860d5d0a746ee29f3e8812c1" +dependencies = [ + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-transaction" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80657d6088f721148f5d889c828ca60c7daeedac9a8679f9ec215e0c42bcbf41" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-instruction", + "solana-keypair", + "solana-message", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-signature", + "solana-transaction-error", + "wasm-bindgen", +] + +[[package]] +name = "solana-transaction-context" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a312304361987a85b2ef2293920558e6612876a639dd1309daf6d0d59ef2fe" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account", + "solana-instruction", + "solana-instructions-sysvar", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", +] + +[[package]] +name = "solana-transaction-error" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a9dc8fdb61c6088baab34fc3a8b8473a03a7a5fd404ed8dd502fa79b67cb1" +dependencies = [ + "serde", + "serde_derive", + "solana-instruction", + "solana-sanitize", +] + +[[package]] +name = "solana-transaction-status" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135f92f4192cc68900c665becf97fc0a6500ae5a67ff347bf2cbc20ecfefa821" +dependencies = [ + "Inflector", + "agave-reserved-account-keys", + "base64 0.22.1", + "bincode", + "borsh 1.6.0", + "bs58", + "log", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-hash", + "solana-instruction", + "solana-loader-v2-interface", + "solana-loader-v3-interface", + "solana-message", + "solana-program-option", + "solana-pubkey", + "solana-reward-info", + "solana-sdk-ids", + "solana-signature", + "solana-stake-interface", + "solana-system-interface", + "solana-transaction", + "solana-transaction-error", + "solana-transaction-status-client-types", + "solana-vote-interface", + "spl-associated-token-account", + "spl-memo", + "spl-token", + "spl-token-2022", + "spl-token-group-interface", + "spl-token-metadata-interface", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-transaction-status-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f1d7c2387c35850848212244d2b225847666cb52d3bd59a5c409d2c300303d" +dependencies = [ + "base64 0.22.1", + "bincode", + "bs58", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder-client-types", + "solana-commitment-config", + "solana-message", + "solana-reward-info", + "solana-signature", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-vote-interface" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b80d57478d6599d30acc31cc5ae7f93ec2361a06aefe8ea79bc81739a08af4c3" +dependencies = [ + "bincode", + "num-derive", + "num-traits", + "serde", + "serde_derive", + "solana-clock", + "solana-decode-error", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-serde-varint", + "solana-serialize-utils", + "solana-short-vec", + "solana-system-interface", +] + +[[package]] +name = "solana-zk-sdk" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b9fc6ec37d16d0dccff708ed1dd6ea9ba61796700c3bb7c3b401973f10f63b" +dependencies = [ + "aes-gcm-siv", + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "itertools 0.12.1", + "js-sys", + "merlin", + "num-derive", + "num-traits", + "rand 0.8.5", + "serde", + "serde_derive", + "serde_json", + "sha3", + "solana-derivation-path", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-seed-derivable", + "solana-seed-phrase", + "solana-signature", + "solana-signer", + "subtle", + "thiserror 2.0.18", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "spl-associated-token-account" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae179d4a26b3c7a20c839898e6aed84cb4477adf108a366c95532f058aea041b" +dependencies = [ + "borsh 1.6.0", + "num-derive", + "num-traits", + "solana-program", + "spl-associated-token-account-client", + "spl-token", + "spl-token-2022", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-associated-token-account-client" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f8349dbcbe575f354f9a533a21f272f3eb3808a49e2fdc1c34393b88ba76cb" +dependencies = [ + "solana-instruction", + "solana-pubkey", +] + +[[package]] +name = "spl-discriminator" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7398da23554a31660f17718164e31d31900956054f54f52d5ec1be51cb4f4b3" +dependencies = [ + "bytemuck", + "solana-program-error", + "solana-sha256-hasher", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" +dependencies = [ + "quote", + "spl-discriminator-syn", + "syn 2.0.117", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d1dbc82ab91422345b6df40a79e2b78c7bce1ebb366da323572dd60b7076b67" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.117", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-elgamal-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65edfeed09cd4231e595616aa96022214f9c9d2be02dea62c2b30d5695a6833a" +dependencies = [ + "bytemuck", + "solana-account-info", + "solana-cpi", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-system-interface", + "solana-sysvar", + "solana-zk-sdk", + "spl-pod", + "spl-token-confidential-transfer-proof-extraction", +] + +[[package]] +name = "spl-generic-token" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "741a62a566d97c58d33f9ed32337ceedd4e35109a686e31b1866c5dfa56abddc" +dependencies = [ + "bytemuck", + "solana-pubkey", ] [[package]] -name = "shlex" -version = "1.3.0" +name = "spl-memo" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "9f09647c0974e33366efeb83b8e2daebb329f0420149e74d3a4bd2c08cf9f7cb" +dependencies = [ + "solana-account-info", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", +] [[package]] -name = "signal-hook-registry" -version = "1.4.8" +name = "spl-pod" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +checksum = "d994afaf86b779104b4a95ba9ca75b8ced3fdb17ee934e38cb69e72afbe17799" dependencies = [ - "errno", - "libc", + "borsh 1.6.0", + "bytemuck", + "bytemuck_derive", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "solana-program-option", + "solana-pubkey", + "solana-zk-sdk", + "thiserror 2.0.18", ] [[package]] -name = "simd-adler32" -version = "0.3.8" +name = "spl-program-error" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "9cdebc8b42553070b75aa5106f071fef2eb798c64a7ec63375da4b1f058688c6" +dependencies = [ + "num-derive", + "num-traits", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "spl-program-error-derive", + "thiserror 2.0.18", +] [[package]] -name = "slab" -version = "0.4.11" +name = "spl-program-error-derive" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "2a2539e259c66910d78593475540e8072f0b10f0f61d7607bbf7593899ed52d0" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.117", +] [[package]] -name = "smallvec" -version = "1.15.1" +name = "spl-tlv-account-resolution" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "1408e961215688715d5a1063cbdcf982de225c45f99c82b4f7d7e1dd22b998d7" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", + "thiserror 2.0.18", +] [[package]] -name = "socket2" -version = "0.5.10" +name = "spl-token" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +checksum = "053067c6a82c705004f91dae058b11b4780407e9ccd6799dc9e7d0fab5f242da" dependencies = [ - "libc", - "windows-sys 0.52.0", + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-sysvar", + "thiserror 2.0.18", ] [[package]] -name = "socket2" -version = "0.6.1" +name = "spl-token-2022" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "31f0dfbb079eebaee55e793e92ca5f433744f4b71ee04880bfd6beefba5973e5" dependencies = [ - "libc", - "windows-sys 0.60.2", + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-native-token", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-security-txt", + "solana-system-interface", + "solana-sysvar", + "solana-zk-sdk", + "spl-elgamal-registry", + "spl-memo", + "spl-pod", + "spl-token", + "spl-token-confidential-transfer-ciphertext-arithmetic", + "spl-token-confidential-transfer-proof-extraction", + "spl-token-confidential-transfer-proof-generation", + "spl-token-group-interface", + "spl-token-metadata-interface", + "spl-transfer-hook-interface", + "spl-type-length-value", + "thiserror 2.0.18", ] [[package]] -name = "solana-atomic-u64" -version = "2.2.1" +name = "spl-token-confidential-transfer-ciphertext-arithmetic" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52e52720efe60465b052b9e7445a01c17550666beec855cce66f44766697bc2" +checksum = "cddd52bfc0f1c677b41493dafa3f2dbbb4b47cf0990f08905429e19dc8289b35" dependencies = [ - "parking_lot 0.12.5", + "base64 0.22.1", + "bytemuck", + "solana-curve25519", + "solana-zk-sdk", ] [[package]] -name = "solana-decode-error" -version = "2.3.0" +name = "spl-token-confidential-transfer-proof-extraction" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c781686a18db2f942e70913f7ca15dc120ec38dcab42ff7557db2c70c625a35" +checksum = "fe2629860ff04c17bafa9ba4bed8850a404ecac81074113e1f840dbd0ebb7bd6" dependencies = [ - "num-traits", + "bytemuck", + "solana-account-info", + "solana-curve25519", + "solana-instruction", + "solana-instructions-sysvar", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "solana-sdk-ids", + "solana-zk-sdk", + "spl-pod", + "thiserror 2.0.18", ] [[package]] -name = "solana-define-syscall" -version = "2.3.0" +name = "spl-token-confidential-transfer-proof-generation" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae3e2abcf541c8122eafe9a625d4d194b4023c20adde1e251f94e056bb1aee2" +checksum = "fa27b9174bea869a7ebf31e0be6890bce90b1a4288bc2bbf24bd413f80ae3fde" +dependencies = [ + "curve25519-dalek 4.1.3", + "solana-zk-sdk", + "thiserror 2.0.18", +] [[package]] -name = "solana-hash" -version = "2.3.0" +name = "spl-token-group-interface" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b96e9f0300fa287b545613f007dfe20043d7812bee255f418c1eb649c93b63" +checksum = "5597b4cd76f85ce7cd206045b7dc22da8c25516573d42d267c8d1fd128db5129" dependencies = [ - "five8", - "js-sys", - "solana-atomic-u64", - "solana-sanitize", - "wasm-bindgen", + "bytemuck", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "thiserror 2.0.18", ] [[package]] -name = "solana-pubkey" -version = "2.4.0" +name = "spl-token-metadata-interface" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b62adb9c3261a052ca1f999398c388f1daf558a1b492f60a6d9e64857db4ff1" +checksum = "304d6e06f0de0c13a621464b1fd5d4b1bebf60d15ca71a44d3839958e0da16ee" dependencies = [ - "borsh 0.10.4", "borsh 1.6.0", - "five8", - "five8_const", - "getrandom 0.2.17", - "js-sys", + "num-derive", "num-traits", - "serde", - "serde_derive", - "solana-atomic-u64", + "solana-borsh", "solana-decode-error", - "solana-define-syscall", - "solana-sanitize", - "solana-sha256-hasher", - "wasm-bindgen", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-type-length-value", + "thiserror 2.0.18", ] [[package]] -name = "solana-sanitize" -version = "2.2.1" +name = "spl-transfer-hook-interface" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61f1bc1357b8188d9c4a3af3fc55276e56987265eb7ad073ae6f8180ee54cecf" +checksum = "a7e905b849b6aba63bde8c4badac944ebb6c8e6e14817029cbe1bc16829133bd" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value", + "thiserror 2.0.18", +] [[package]] -name = "solana-sha256-hasher" -version = "2.3.0" +name = "spl-type-length-value" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa3feb32c28765f6aa1ce8f3feac30936f16c5c3f7eb73d63a5b8f6f8ecdc44" +checksum = "d417eb548214fa822d93f84444024b4e57c13ed6719d4dcc68eec24fb481e9f5" dependencies = [ - "sha2", - "solana-define-syscall", - "solana-hash", + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "spl-discriminator", + "spl-pod", + "thiserror 2.0.18", ] [[package]] @@ -2642,9 +4701,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.114" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -2674,7 +4733,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2700,12 +4759,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.24.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", @@ -2747,7 +4806,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2758,7 +4817,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2782,9 +4841,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" dependencies = [ "tinyvec_macros", ] @@ -2797,9 +4856,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.49.0" +version = "1.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" dependencies = [ "bytes", "libc", @@ -2807,20 +4866,20 @@ dependencies = [ "parking_lot 0.12.5", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.1", + "socket2 0.6.3", "tokio-macros", "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2850,7 +4909,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.36", + "rustls 0.23.37", "tokio", ] @@ -2918,18 +4977,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.5+spec-1.1.0" +version = "1.0.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.10+spec-1.0.0" +version = "0.25.4+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +checksum = "7193cbd0ce53dc966037f54351dbbcf0d5a642c7f0038c382ef9e677ce8c13f2" dependencies = [ "indexmap 2.13.0", "toml_datetime", @@ -2939,9 +4998,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.6+spec-1.1.0" +version = "1.0.9+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" dependencies = [ "winnow", ] @@ -2980,9 +5039,9 @@ dependencies = [ [[package]] name = "tonic" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203" +checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" dependencies = [ "async-trait", "axum 0.8.8", @@ -2999,7 +5058,7 @@ dependencies = [ "percent-encoding", "pin-project", "rustls-native-certs", - "socket2 0.6.1", + "socket2 0.6.3", "sync_wrapper 1.0.2", "tokio", "tokio-rustls 0.26.4", @@ -3022,59 +5081,59 @@ dependencies = [ "prost-build 0.13.5", "prost-types 0.13.5", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "tonic-build" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40aaccc9f9eccf2cd82ebc111adc13030d23e887244bc9cfa5d1d636049de3" +checksum = "1882ac3bf5ef12877d7ed57aad87e75154c11931c2ba7e6cde5e22d63522c734" dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "tonic-health" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a82868bf299e0a1d2e8dce0dc33a46c02d6f045b2c1f1d6cc8dc3d0bf1812ef" +checksum = "f4ff0636fef47afb3ec02818f5bceb4377b8abb9d6a386aeade18bd6212f8eb7" dependencies = [ "prost 0.14.3", "tokio", "tokio-stream", - "tonic 0.14.2", + "tonic 0.14.5", "tonic-prost", ] [[package]] name = "tonic-prost" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67" +checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" dependencies = [ "bytes", "prost 0.14.3", - "tonic 0.14.2", + "tonic 0.14.5", ] [[package]] name = "tonic-prost-build" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4a16cba4043dc3ff43fcb3f96b4c5c154c64cbd18ca8dce2ab2c6a451d058a2" +checksum = "f3144df636917574672e93d0f56d7edec49f90305749c668df5101751bb8f95a" dependencies = [ "prettyplease", "proc-macro2", "prost-build 0.14.3", "prost-types 0.14.3", "quote", - "syn 2.0.114", + "syn 2.0.117", "tempfile", - "tonic-build 0.14.2", + "tonic-build 0.14.5", ] [[package]] @@ -3152,7 +5211,7 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "bytes", "futures-util", "http 1.4.0", @@ -3195,7 +5254,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3231,9 +5290,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", "nu-ansi-term", @@ -3308,9 +5367,25 @@ checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "universal-hash" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] [[package]] name = "untrusted" @@ -3318,6 +5393,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + [[package]] name = "url" version = "2.5.8" @@ -3350,11 +5435,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.19.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.2", "js-sys", "serde_core", "wasm-bindgen", @@ -3381,6 +5466,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -3396,11 +5487,20 @@ dependencies = [ "wit-bindgen", ] +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasm-bindgen" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" dependencies = [ "cfg-if", "once_cell", @@ -3411,9 +5511,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.58" +version = "0.4.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8" dependencies = [ "cfg-if", "futures-util", @@ -3425,9 +5525,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3435,31 +5535,65 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.13.0", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.11.0", + "hashbrown 0.15.5", + "indexmap 2.13.0", + "semver", +] + [[package]] name = "web-sys" -version = "0.3.85" +version = "0.3.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" dependencies = [ "js-sys", "wasm-bindgen", @@ -3487,14 +5621,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.5", + "webpki-roots 1.0.6", ] [[package]] name = "webpki-roots" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" dependencies = [ "rustls-pki-types", ] @@ -3751,9 +5885,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" dependencies = [ "memchr", ] @@ -3773,6 +5907,88 @@ name = "wit-bindgen" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap 2.13.0", + "prettyplease", + "syn 2.0.117", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.117", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.11.0", + "indexmap 2.13.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.13.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "writeable" @@ -3789,7 +6005,7 @@ dependencies = [ "bytes", "futures", "thiserror 1.0.69", - "tonic 0.14.2", + "tonic 0.14.5", "tonic-health", "yellowstone-grpc-proto", ] @@ -3801,11 +6017,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbba21b6046eff1c9be2366a70d7264763b10004306e874b54409503a39e5f1e" dependencies = [ "anyhow", + "bincode", "prost 0.14.3", "prost-types 0.14.3", "protobuf-src", - "tonic 0.14.2", - "tonic-build 0.14.2", + "solana-account", + "solana-account-decoder", + "solana-clock", + "solana-hash", + "solana-message", + "solana-pubkey", + "solana-signature", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "solana-transaction-status", + "tonic 0.14.5", + "tonic-build 0.14.5", "tonic-prost", "tonic-prost-build", ] @@ -3896,28 +6124,28 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.33" +version = "0.8.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" +checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.33" +version = "0.8.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" +checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3937,7 +6165,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", "synstructure", ] @@ -3946,6 +6174,20 @@ name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] [[package]] name = "zerotrie" @@ -3977,14 +6219,14 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "zmij" -version = "1.0.16" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfcd145825aace48cff44a8844de64bf75feec3080e0aa5cdbde72961ae51a65" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" [[package]] name = "zstd" diff --git a/examples/ore-server/Cargo.toml b/examples/ore-server/Cargo.toml index bc2d9006..b6b47b21 100644 --- a/examples/ore-server/Cargo.toml +++ b/examples/ore-server/Cargo.toml @@ -9,6 +9,7 @@ name = "ore-server" path = "src/main.rs" [workspace] +resolver = "2" [dependencies] ore-stack = { path = "../../stacks/ore" } diff --git a/examples/ore-typescript/src/main.ts b/examples/ore-typescript/src/main.ts index b13b81f3..6ca0cec8 100644 --- a/examples/ore-typescript/src/main.ts +++ b/examples/ore-typescript/src/main.ts @@ -2,22 +2,24 @@ import { z } from 'zod'; import { HyperStack } from 'hyperstack-typescript'; import { ORE_STREAM_STACK, - OreRoundSchema, - OreRoundIdSchema, - OreTreasurySchema, - OreTreasuryIdSchema, + // OreRoundSchema, + // OreRoundIdSchema, + // OreTreasurySchema, + // OreTreasuryIdSchema, } from 'hyperstack-stacks/ore'; -const OreRoundWithIdSchema = OreRoundSchema.extend({ - id: OreRoundIdSchema.required(), -}); - -const OreTreasuryWithIdSchema = OreTreasurySchema.extend({ - id: OreTreasuryIdSchema.required(), -}); - -type OreRoundWithId = z.infer; -type OreTreasuryWithId = z.infer; +// const OreRoundWithIdSchema = OreRoundSchema.extend({ +// id: OreRoundIdSchema.required(), +// }); +// +// const OreTreasuryWithIdSchema = OreTreasurySchema.extend({ +// id: OreTreasuryIdSchema.required(), +// }); +// +// type OreRoundWithId = z.infer; +// type OreTreasuryWithId = z.infer; +type OreRoundWithId = any; +type OreTreasuryWithId = any; function printRound(round: OreRoundWithId) { console.log(`\n=== Round #${round.id.round_id ?? 'N/A'} ===`); @@ -41,29 +43,31 @@ function printTreasury(treasury: OreTreasuryWithId) { } async function main() { - const hs = await HyperStack.connect(ORE_STREAM_STACK); + const hs = await HyperStack.connect(ORE_STREAM_STACK, { url: 'http://localhost:8878' }); console.log('--- Streaming OreRound and OreTreasury updates ---\n'); const streamRounds = async () => { for await (const round of hs.views.OreRound.latest.use({ take: 1, - schema: OreRoundWithIdSchema, - })) { - printRound(round); - } - }; - - const streamTreasury = async () => { - for await (const treasury of hs.views.OreTreasury.list.use({ - take: 1, - schema: OreTreasuryWithIdSchema, + // schema: OreRoundWithIdSchema, })) { - printTreasury(treasury); + console.log(round); + // printRound(round); } }; + await streamRounds(); - await Promise.all([streamRounds(), streamTreasury()]); + // const streamTreasury = async () => { + // for await (const treasury of hs.views.OreTreasury.list.use({ + // take: 1, + // schema: OreTreasuryWithIdSchema, + // })) { + // printTreasury(treasury); + // } + // }; + // + // await Promise.all([streamRounds(), streamTreasury()]); } main().catch((err) => { diff --git a/rust/hyperstack-server/Cargo.toml b/rust/hyperstack-server/Cargo.toml index ad58dd1c..424e8dfa 100644 --- a/rust/hyperstack-server/Cargo.toml +++ b/rust/hyperstack-server/Cargo.toml @@ -40,6 +40,7 @@ lru = "0.12" dashmap = "6.1" flate2 = "1.0" base64 = "0.22" +once_cell = "1.20" # HTTP server for health endpoint hyper = { version = "1.6", features = ["server", "http1"] } diff --git a/rust/hyperstack-server/src/health.rs b/rust/hyperstack-server/src/health.rs index 488728cc..b6c046ac 100644 --- a/rust/hyperstack-server/src/health.rs +++ b/rust/hyperstack-server/src/health.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::Arc; use std::time::{Duration, Instant, SystemTime}; @@ -5,26 +6,66 @@ use tokio::sync::RwLock; use tokio::time::interval; use tracing::{error, info, warn}; -/// Tracks the last processed slot for stream resumption after reconnection +/// Tracks the last processed slot for stream resumption after reconnection. +/// +/// Includes a `Notify` that wakes waiters whenever the slot advances, +/// allowing the scheduler to react immediately to new slots instead of polling. +/// Also maintains a cache of slot hashes indexed by slot number. #[derive(Clone)] pub struct SlotTracker { last_slot: Arc, + notify: Arc, + /// Cache of slot hashes indexed by slot number + slot_hashes: Arc>>, } impl SlotTracker { pub fn new() -> Self { Self { last_slot: Arc::new(AtomicU64::new(0)), + notify: Arc::new(tokio::sync::Notify::new()), + slot_hashes: Arc::new(RwLock::new(HashMap::new())), } } pub fn record(&self, slot: u64) { - self.last_slot.fetch_max(slot, Ordering::Relaxed); + let old = self.last_slot.fetch_max(slot, Ordering::Relaxed); + if slot > old { + self.notify.notify_waiters(); + } + } + + /// Record a slot hash for a specific slot + pub async fn record_slot_hash(&self, slot: u64, slot_hash: String) { + let mut hashes = self.slot_hashes.write().await; + hashes.insert(slot, slot_hash); + + // Prune old entries to prevent unbounded growth (keep last 10000 slots) + let slots_to_remove: Vec = hashes + .keys() + .filter(|&&s| s < slot.saturating_sub(10000)) + .copied() + .collect(); + for s in slots_to_remove { + hashes.remove(&s); + } + } + + /// Get the slot hash for a specific slot (if cached) + pub async fn get_slot_hash(&self, slot: u64) -> Option { + let hashes = self.slot_hashes.read().await; + hashes.get(&slot).cloned() } pub fn get(&self) -> u64 { self.last_slot.load(Ordering::Relaxed) } + + /// Returns a future that resolves when the slot advances. + /// Use with `tokio::select!` and a fallback timeout. + pub fn notified(&self) -> impl std::future::Future + '_ { + self.notify.notified() + } } impl Default for SlotTracker { @@ -33,6 +74,27 @@ impl Default for SlotTracker { } } +/// Global slot tracker instance for accessing slot hashes from computed fields +static GLOBAL_SLOT_TRACKER: once_cell::sync::Lazy>>> = + once_cell::sync::Lazy::new(|| Arc::new(tokio::sync::RwLock::new(None))); + +/// Initialize the global slot tracker +pub async fn init_global_slot_tracker(slot_tracker: SlotTracker) { + let mut global = GLOBAL_SLOT_TRACKER.write().await; + *global = Some(slot_tracker); +} + +/// Get the slot hash for a specific slot (if available) +/// This can be called from computed fields +pub async fn get_slot_hash(slot: u64) -> Option { + let global = GLOBAL_SLOT_TRACKER.read().await; + if let Some(ref tracker) = *global { + tracker.get_slot_hash(slot).await + } else { + None + } +} + #[derive(Debug, Clone)] pub enum StreamStatus { Connected, diff --git a/stacks/ore/Cargo.lock b/stacks/ore/Cargo.lock index d2e403ff..0641d103 100644 --- a/stacks/ore/Cargo.lock +++ b/stacks/ore/Cargo.lock @@ -2,12 +2,83 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + [[package]] name = "adler2" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "agave-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a2c365c0245cbb8959de725fc2b44c754b673fdf34c9a7f9d4a25c35a7bf1" +dependencies = [ + "ahash", + "solana-epoch-schedule", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", + "solana-svm-feature-set", +] + +[[package]] +name = "agave-reserved-account-keys" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8289c8a8a2ef5aa10ce49a070f360f4e035ee3410b8d8f3580fb39d8cf042581" +dependencies = [ + "agave-feature-set", + "solana-pubkey", + "solana-sdk-ids", +] + [[package]] name = "ahash" version = "0.8.12" @@ -15,6 +86,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -91,6 +163,18 @@ version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "async-stream" version = "0.3.6" @@ -235,6 +319,12 @@ dependencies = [ "tower-service", ] +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + [[package]] name = "base64" version = "0.21.7" @@ -247,6 +337,15 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -259,6 +358,30 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +[[package]] +name = "blake3" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2468ef7d57b3fb7e16b576e8377cdbde2320c60e1491e961d11da40fc4f02a2d" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -351,6 +474,16 @@ version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + [[package]] name = "bytemuck" version = "1.25.0" @@ -407,6 +540,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "4.5.57" @@ -454,6 +597,32 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "constant_time_eq" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + [[package]] name = "core-foundation" version = "0.9.4" @@ -554,6 +723,12 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + [[package]] name = "crypto-common" version = "0.1.7" @@ -561,9 +736,61 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rand_core 0.6.4", + "rustc_version", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "dashmap" version = "6.1.0" @@ -584,14 +811,30 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +[[package]] +name = "derivation-path" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "crypto-common", + "subtle", ] [[package]] @@ -631,6 +874,29 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + [[package]] name = "either" version = "1.15.0" @@ -668,6 +934,18 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "find-msvc-tools" version = "0.1.9" @@ -834,6 +1112,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.17" @@ -843,7 +1132,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -955,6 +1244,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "http" version = "0.2.12" @@ -1152,9 +1450,12 @@ dependencies = [ "reqwest 0.11.27", "serde", "serde_json", + "sha3", "smallvec", "tokio", "tracing", + "yellowstone-grpc-client", + "yellowstone-grpc-proto", "yellowstone-vixen", "yellowstone-vixen-core", "yellowstone-vixen-yellowstone-grpc-source", @@ -1166,7 +1467,7 @@ version = "0.1.2" dependencies = [ "serde", "serde_json", - "sha2", + "sha2 0.10.9", "strsim", ] @@ -1181,6 +1482,7 @@ dependencies = [ "hyperstack-idl", "hyperstack-macros", "lru", + "once_cell", "percent-encoding", "prost 0.13.5", "prost-reflect", @@ -1188,8 +1490,10 @@ dependencies = [ "reqwest 0.12.28", "serde", "serde_json", - "sha2", + "sha2 0.10.9", + "sha3", "solana-pubkey", + "tokio", "tonic 0.12.3", "tracing", ] @@ -1205,7 +1509,7 @@ dependencies = [ "quote", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "syn 2.0.114", ] @@ -1242,6 +1546,7 @@ dependencies = [ "hyper-util", "hyperstack-interpreter", "lru", + "once_cell", "serde", "serde_json", "smallvec", @@ -1380,6 +1685,15 @@ dependencies = [ "hashbrown 0.16.1", ] +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + [[package]] name = "instant" version = "0.1.13" @@ -1411,6 +1725,15 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.14.0" @@ -1446,6 +1769,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kaigan" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba15de5aeb137f0f65aa3bf82187647f1285abfe5b20c80c2c37f7007ad519a" +dependencies = [ + "borsh 0.10.4", + "serde", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -1459,31 +1801,77 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] -name = "linux-raw-sys" -version = "0.11.0" +name = "libsecp256k1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", +] [[package]] -name = "litemap" -version = "0.8.1" +name = "libsecp256k1-core" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] [[package]] -name = "lock_api" -version = "0.4.14" +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" dependencies = [ - "scopeguard", + "libsecp256k1-core", ] [[package]] -name = "log" -version = "0.4.29" +name = "libsecp256k1-gen-genmult" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru" @@ -1527,6 +1915,27 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + [[package]] name = "mime" version = "0.3.17" @@ -1550,7 +1959,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.61.2", ] @@ -1569,6 +1978,36 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1588,6 +2027,28 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -1600,6 +2061,12 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "openssl-probe" version = "0.2.1" @@ -1664,6 +2131,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -1729,6 +2205,18 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "potential_utf" version = "0.1.4" @@ -1811,7 +2299,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" dependencies = [ "heck", - "itertools", + "itertools 0.14.0", "log", "multimap", "once_cell", @@ -1831,7 +2319,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" dependencies = [ "heck", - "itertools", + "itertools 0.14.0", "log", "multimap", "petgraph 0.8.3", @@ -1852,7 +2340,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools", + "itertools 0.14.0", "proc-macro2", "quote", "syn 2.0.114", @@ -1865,7 +2353,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" dependencies = [ "anyhow", - "itertools", + "itertools 0.14.0", "proc-macro2", "quote", "syn 2.0.114", @@ -1928,6 +2416,15 @@ dependencies = [ "pulldown-cmark", ] +[[package]] +name = "qstring" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding", +] + [[package]] name = "quinn" version = "0.11.9" @@ -1998,6 +2495,19 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + [[package]] name = "rand" version = "0.8.5" @@ -2019,6 +2529,16 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -2039,6 +2559,15 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + [[package]] name = "rand_core" version = "0.6.4" @@ -2057,6 +2586,15 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -2203,6 +2741,15 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "1.1.3" @@ -2371,230 +2918,1711 @@ dependencies = [ ] [[package]] -name = "security-framework-sys" -version = "2.15.0" +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "solana-account" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f949fe4edaeaea78c844023bfc1c898e0b1f5a100f8a8d2d0f85d0a7b090258" +dependencies = [ + "bincode", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-sysvar", +] + +[[package]] +name = "solana-account-decoder" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba71c97fa4d85ce4a1e0e79044ad0406c419382be598c800202903a7688ce71a" +dependencies = [ + "Inflector", + "base64 0.22.1", + "bincode", + "bs58", + "bv", + "serde", + "serde_derive", + "serde_json", + "solana-account", + "solana-account-decoder-client-types", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-config-program-client", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-instruction", + "solana-loader-v3-interface", + "solana-nonce", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-slot-hashes", + "solana-slot-history", + "solana-stake-interface", + "solana-sysvar", + "solana-vote-interface", + "spl-generic-token", + "spl-token", + "spl-token-2022", + "spl-token-group-interface", + "spl-token-metadata-interface", + "thiserror 2.0.18", + "zstd", +] + +[[package]] +name = "solana-account-decoder-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5519e8343325b707f17fbed54fcefb325131b692506d0af9e08a539d15e4f8cf" +dependencies = [ + "base64 0.22.1", + "bs58", + "serde", + "serde_derive", + "serde_json", + "solana-account", + "solana-pubkey", + "zstd", +] + +[[package]] +name = "solana-account-info" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8f5152a288ef1912300fc6efa6c2d1f9bb55d9398eb6c72326360b8063987da" +dependencies = [ + "bincode", + "serde", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", +] + +[[package]] +name = "solana-address-lookup-table-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1673f67efe870b64a65cb39e6194be5b26527691ce5922909939961a6e6b395" +dependencies = [ + "bincode", + "bytemuck", + "serde", + "serde_derive", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-slot-hashes", +] + +[[package]] +name = "solana-atomic-u64" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52e52720efe60465b052b9e7445a01c17550666beec855cce66f44766697bc2" +dependencies = [ + "parking_lot 0.12.5", +] + +[[package]] +name = "solana-big-mod-exp" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75db7f2bbac3e62cfd139065d15bcda9e2428883ba61fc8d27ccb251081e7567" +dependencies = [ + "num-bigint", + "num-traits", + "solana-define-syscall", +] + +[[package]] +name = "solana-bincode" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a3787b8cf9c9fe3dd360800e8b70982b9e5a8af9e11c354b6665dd4a003adc" +dependencies = [ + "bincode", + "serde", + "solana-instruction", +] + +[[package]] +name = "solana-blake3-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0801e25a1b31a14494fc80882a036be0ffd290efc4c2d640bfcca120a4672" +dependencies = [ + "blake3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + +[[package]] +name = "solana-borsh" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718333bcd0a1a7aed6655aa66bef8d7fb047944922b2d3a18f49cbc13e73d004" +dependencies = [ + "borsh 0.10.4", + "borsh 1.6.0", +] + +[[package]] +name = "solana-clock" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8584296123df8fe229b95e2ebfd37ae637fe9db9b7d4dd677ac5a78e80dbfce" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-commitment-config" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac49c4dde3edfa832de1697e9bcdb7c3b3f7cb7a1981b7c62526c8bb6700fb73" + +[[package]] +name = "solana-config-program-client" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53aceac36f105fd4922e29b4f0c1f785b69d7b3e7e387e384b8985c8e0c3595e" +dependencies = [ + "bincode", + "borsh 0.10.4", + "kaigan", + "serde", + "solana-program", +] + +[[package]] +name = "solana-cpi" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc71126edddc2ba014622fc32d0f5e2e78ec6c5a1e0eb511b85618c09e9ea11" +dependencies = [ + "solana-account-info", + "solana-define-syscall", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-stable-layout", +] + +[[package]] +name = "solana-curve25519" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae4261b9a8613d10e77ac831a8fa60b6fa52b9b103df46d641deff9f9812a23" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "solana-define-syscall", + "subtle", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-decode-error" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c781686a18db2f942e70913f7ca15dc120ec38dcab42ff7557db2c70c625a35" +dependencies = [ + "num-traits", +] + +[[package]] +name = "solana-define-syscall" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae3e2abcf541c8122eafe9a625d4d194b4023c20adde1e251f94e056bb1aee2" + +[[package]] +name = "solana-derivation-path" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "939756d798b25c5ec3cca10e06212bdca3b1443cb9bb740a38124f58b258737b" +dependencies = [ + "derivation-path", + "qstring", + "uriparse", +] + +[[package]] +name = "solana-epoch-rewards" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b575d3dd323b9ea10bb6fe89bf6bf93e249b215ba8ed7f68f1a3633f384db7" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-epoch-schedule" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fce071fbddecc55d727b1d7ed16a629afe4f6e4c217bc8d00af3b785f6f67ed" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-example-mocks" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84461d56cbb8bb8d539347151e0525b53910102e4bced875d49d5139708e39d3" +dependencies = [ + "serde", + "serde_derive", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-hash", + "solana-instruction", + "solana-keccak-hasher", + "solana-message", + "solana-nonce", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-feature-gate-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f5c5382b449e8e4e3016fb05e418c53d57782d8b5c30aa372fc265654b956d" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-fee-calculator" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89bc408da0fb3812bc3008189d148b4d3e08252c79ad810b245482a3f70cd8d" +dependencies = [ + "log", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-hash" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b96e9f0300fa287b545613f007dfe20043d7812bee255f418c1eb649c93b63" +dependencies = [ + "borsh 1.6.0", + "bytemuck", + "bytemuck_derive", + "five8", + "js-sys", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-sanitize", + "wasm-bindgen", +] + +[[package]] +name = "solana-instruction" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab5682934bd1f65f8d2c16f21cb532526fcc1a09f796e2cacdb091eee5774ad" +dependencies = [ + "bincode", + "borsh 1.6.0", + "getrandom 0.2.17", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "serde_json", + "solana-define-syscall", + "solana-pubkey", + "wasm-bindgen", +] + +[[package]] +name = "solana-instructions-sysvar" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0e85a6fad5c2d0c4f5b91d34b8ca47118fc593af706e523cdbedf846a954f57" +dependencies = [ + "bitflags 2.10.0", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-serialize-utils", + "solana-sysvar-id", +] + +[[package]] +name = "solana-keccak-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7aeb957fbd42a451b99235df4942d96db7ef678e8d5061ef34c9b34cae12f79" +dependencies = [ + "sha3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + +[[package]] +name = "solana-keypair" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd3f04aa1a05c535e93e121a95f66e7dcccf57e007282e8255535d24bf1e98bb" +dependencies = [ + "ed25519-dalek", + "five8", + "rand 0.7.3", + "solana-pubkey", + "solana-seed-phrase", + "solana-signature", + "solana-signer", + "wasm-bindgen", +] + +[[package]] +name = "solana-last-restart-slot" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6360ac2fdc72e7463565cd256eedcf10d7ef0c28a1249d261ec168c1b55cdd" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-loader-v2-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ab08006dad78ae7cd30df8eea0539e207d08d91eaefb3e1d49a446e1c49654" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-loader-v3-interface" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f7162a05b8b0773156b443bccd674ea78bb9aa406325b467ea78c06c99a63a2" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-loader-v4-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "706a777242f1f39a83e2a96a2a6cb034cb41169c6ecbee2cf09cb873d9659e7e" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-message" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1796aabce376ff74bf89b78d268fa5e683d7d7a96a0a4e4813ec34de49d5314b" +dependencies = [ + "bincode", + "blake3", + "lazy_static", + "serde", + "serde_derive", + "solana-bincode", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-system-interface", + "solana-transaction-error", + "wasm-bindgen", +] + +[[package]] +name = "solana-msg" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36a1a14399afaabc2781a1db09cb14ee4cc4ee5c7a5a3cfcc601811379a8092" +dependencies = [ + "solana-define-syscall", +] + +[[package]] +name = "solana-native-token" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61515b880c36974053dd499c0510066783f0cc6ac17def0c7ef2a244874cf4a9" + +[[package]] +name = "solana-nonce" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703e22eb185537e06204a5bd9d509b948f0066f2d1d814a6f475dafb3ddf1325" +dependencies = [ + "serde", + "serde_derive", + "solana-fee-calculator", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", +] + +[[package]] +name = "solana-program" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98eca145bd3545e2fbb07166e895370576e47a00a7d824e325390d33bf467210" +dependencies = [ + "bincode", + "blake3", + "borsh 0.10.4", + "borsh 1.6.0", + "bs58", + "bytemuck", + "console_error_panic_hook", + "console_log", + "getrandom 0.2.17", + "lazy_static", + "log", + "memoffset", + "num-bigint", + "num-derive", + "num-traits", + "rand 0.8.5", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info", + "solana-address-lookup-table-interface", + "solana-atomic-u64", + "solana-big-mod-exp", + "solana-bincode", + "solana-blake3-hasher", + "solana-borsh", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-define-syscall", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-example-mocks", + "solana-feature-gate-interface", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-keccak-hasher", + "solana-last-restart-slot", + "solana-loader-v2-interface", + "solana-loader-v3-interface", + "solana-loader-v4-interface", + "solana-message", + "solana-msg", + "solana-native-token", + "solana-nonce", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-secp256k1-recover", + "solana-serde-varint", + "solana-serialize-utils", + "solana-sha256-hasher", + "solana-short-vec", + "solana-slot-hashes", + "solana-slot-history", + "solana-stable-layout", + "solana-stake-interface", + "solana-system-interface", + "solana-sysvar", + "solana-sysvar-id", + "solana-vote-interface", + "thiserror 2.0.18", + "wasm-bindgen", +] + +[[package]] +name = "solana-program-entrypoint" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32ce041b1a0ed275290a5008ee1a4a6c48f5054c8a3d78d313c08958a06aedbd" +dependencies = [ + "solana-account-info", + "solana-msg", + "solana-program-error", + "solana-pubkey", +] + +[[package]] +name = "solana-program-error" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee2e0217d642e2ea4bee237f37bd61bb02aec60da3647c48ff88f6556ade775" +dependencies = [ + "borsh 1.6.0", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-pubkey", +] + +[[package]] +name = "solana-program-memory" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a5426090c6f3fd6cfdc10685322fede9ca8e5af43cd6a59e98bfe4e91671712" +dependencies = [ + "solana-define-syscall", +] + +[[package]] +name = "solana-program-option" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc677a2e9bc616eda6dbdab834d463372b92848b2bfe4a1ed4e4b4adba3397d0" + +[[package]] +name = "solana-program-pack" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "319f0ef15e6e12dc37c597faccb7d62525a509fec5f6975ecb9419efddeb277b" +dependencies = [ + "solana-program-error", +] + +[[package]] +name = "solana-pubkey" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b62adb9c3261a052ca1f999398c388f1daf558a1b492f60a6d9e64857db4ff1" +dependencies = [ + "borsh 0.10.4", + "borsh 1.6.0", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "five8", + "five8_const", + "getrandom 0.2.17", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-decode-error", + "solana-define-syscall", + "solana-sanitize", + "solana-sha256-hasher", + "wasm-bindgen", +] + +[[package]] +name = "solana-rent" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1aea8fdea9de98ca6e8c2da5827707fb3842833521b528a713810ca685d2480" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-reward-info" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18205b69139b1ae0ab8f6e11cdcb627328c0814422ad2482000fa2ca54ae4a2f" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-sanitize" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61f1bc1357b8188d9c4a3af3fc55276e56987265eb7ad073ae6f8180ee54cecf" + +[[package]] +name = "solana-sdk-ids" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5d8b9cc68d5c88b062a33e23a6466722467dde0035152d8fb1afbcdf350a5f" +dependencies = [ + "solana-pubkey", +] + +[[package]] +name = "solana-sdk-macro" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86280da8b99d03560f6ab5aca9de2e38805681df34e0bb8f238e69b29433b9df" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "solana-secp256k1-recover" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa3120b6cdaa270f39444f5093a90a7b03d296d362878f7a6991d6de3bbe496" +dependencies = [ + "libsecp256k1", + "solana-define-syscall", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-security-txt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" + +[[package]] +name = "solana-seed-derivable" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beb82b5adb266c6ea90e5cf3967235644848eac476c5a1f2f9283a143b7c97f" +dependencies = [ + "solana-derivation-path", +] + +[[package]] +name = "solana-seed-phrase" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36187af2324f079f65a675ec22b31c24919cb4ac22c79472e85d819db9bbbc15" +dependencies = [ + "hmac", + "pbkdf2", + "sha2 0.10.9", +] + +[[package]] +name = "solana-serde-varint" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a7e155eba458ecfb0107b98236088c3764a09ddf0201ec29e52a0be40857113" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-serialize-utils" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "817a284b63197d2b27afdba829c5ab34231da4a9b4e763466a003c40ca4f535e" +dependencies = [ + "solana-instruction", + "solana-pubkey", + "solana-sanitize", +] + +[[package]] +name = "solana-sha256-hasher" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa3feb32c28765f6aa1ce8f3feac30936f16c5c3f7eb73d63a5b8f6f8ecdc44" +dependencies = [ + "sha2 0.10.9", + "solana-define-syscall", + "solana-hash", +] + +[[package]] +name = "solana-short-vec" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c54c66f19b9766a56fa0057d060de8378676cb64987533fa088861858fc5a69" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-signature" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c8ec8e657aecfc187522fc67495142c12f35e55ddeca8698edbb738b8dbd8c" +dependencies = [ + "ed25519-dalek", + "five8", + "serde", + "serde-big-array", + "serde_derive", + "solana-sanitize", +] + +[[package]] +name = "solana-signer" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c41991508a4b02f021c1342ba00bcfa098630b213726ceadc7cb032e051975b" +dependencies = [ + "solana-pubkey", + "solana-signature", + "solana-transaction-error", +] + +[[package]] +name = "solana-slot-hashes" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8691982114513763e88d04094c9caa0376b867a29577939011331134c301ce" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-slot-history" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ccc1b2067ca22754d5283afb2b0126d61eae734fc616d23871b0943b0d935e" +dependencies = [ + "bv", + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-stable-layout" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f14f7d02af8f2bc1b5efeeae71bc1c2b7f0f65cd75bcc7d8180f2c762a57f54" +dependencies = [ + "solana-instruction", + "solana-pubkey", +] + +[[package]] +name = "solana-stake-interface" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5269e89fde216b4d7e1d1739cf5303f8398a1ff372a81232abbee80e554a838c" +dependencies = [ + "borsh 0.10.4", + "borsh 1.6.0", + "num-traits", + "serde", + "serde_derive", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-system-interface", + "solana-sysvar-id", +] + +[[package]] +name = "solana-svm-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f24b836eb4d74ec255217bdbe0f24f64a07adeac31aca61f334f91cd4a3b1d5" + +[[package]] +name = "solana-system-interface" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94d7c18cb1a91c6be5f5a8ac9276a1d7c737e39a21beba9ea710ab4b9c63bc90" +dependencies = [ + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction", + "solana-pubkey", + "wasm-bindgen", +] + +[[package]] +name = "solana-sysvar" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8c3595f95069f3d90f275bb9bd235a1973c4d059028b0a7f81baca2703815db" +dependencies = [ + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "lazy_static", + "serde", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-define-syscall", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-last-restart-slot", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", + "solana-rent", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-slot-hashes", + "solana-slot-history", + "solana-stake-interface", + "solana-sysvar-id", +] + +[[package]] +name = "solana-sysvar-id" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5762b273d3325b047cfda250787f8d796d781746860d5d0a746ee29f3e8812c1" +dependencies = [ + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-transaction" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80657d6088f721148f5d889c828ca60c7daeedac9a8679f9ec215e0c42bcbf41" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-instruction", + "solana-keypair", + "solana-message", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-signature", + "solana-transaction-error", + "wasm-bindgen", +] + +[[package]] +name = "solana-transaction-context" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a312304361987a85b2ef2293920558e6612876a639dd1309daf6d0d59ef2fe" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account", + "solana-instruction", + "solana-instructions-sysvar", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", +] + +[[package]] +name = "solana-transaction-error" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a9dc8fdb61c6088baab34fc3a8b8473a03a7a5fd404ed8dd502fa79b67cb1" +dependencies = [ + "serde", + "serde_derive", + "solana-instruction", + "solana-sanitize", +] + +[[package]] +name = "solana-transaction-status" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135f92f4192cc68900c665becf97fc0a6500ae5a67ff347bf2cbc20ecfefa821" +dependencies = [ + "Inflector", + "agave-reserved-account-keys", + "base64 0.22.1", + "bincode", + "borsh 1.6.0", + "bs58", + "log", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-hash", + "solana-instruction", + "solana-loader-v2-interface", + "solana-loader-v3-interface", + "solana-message", + "solana-program-option", + "solana-pubkey", + "solana-reward-info", + "solana-sdk-ids", + "solana-signature", + "solana-stake-interface", + "solana-system-interface", + "solana-transaction", + "solana-transaction-error", + "solana-transaction-status-client-types", + "solana-vote-interface", + "spl-associated-token-account", + "spl-memo", + "spl-token", + "spl-token-2022", + "spl-token-group-interface", + "spl-token-metadata-interface", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-transaction-status-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f1d7c2387c35850848212244d2b225847666cb52d3bd59a5c409d2c300303d" +dependencies = [ + "base64 0.22.1", + "bincode", + "bs58", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder-client-types", + "solana-commitment-config", + "solana-message", + "solana-reward-info", + "solana-signature", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-vote-interface" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "b80d57478d6599d30acc31cc5ae7f93ec2361a06aefe8ea79bc81739a08af4c3" dependencies = [ - "core-foundation-sys", - "libc", + "bincode", + "num-derive", + "num-traits", + "serde", + "serde_derive", + "solana-clock", + "solana-decode-error", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-serde-varint", + "solana-serialize-utils", + "solana-short-vec", + "solana-system-interface", ] [[package]] -name = "serde" -version = "1.0.228" +name = "solana-zk-sdk" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "97b9fc6ec37d16d0dccff708ed1dd6ea9ba61796700c3bb7c3b401973f10f63b" dependencies = [ - "serde_core", + "aes-gcm-siv", + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "itertools 0.12.1", + "js-sys", + "merlin", + "num-derive", + "num-traits", + "rand 0.8.5", + "serde", "serde_derive", + "serde_json", + "sha3", + "solana-derivation-path", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-seed-derivable", + "solana-seed-phrase", + "solana-signature", + "solana-signer", + "subtle", + "thiserror 2.0.18", + "wasm-bindgen", + "zeroize", ] [[package]] -name = "serde_core" -version = "1.0.228" +name = "spl-associated-token-account" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "ae179d4a26b3c7a20c839898e6aed84cb4477adf108a366c95532f058aea041b" dependencies = [ - "serde_derive", + "borsh 1.6.0", + "num-derive", + "num-traits", + "solana-program", + "spl-associated-token-account-client", + "spl-token", + "spl-token-2022", + "thiserror 2.0.18", ] [[package]] -name = "serde_derive" -version = "1.0.228" +name = "spl-associated-token-account-client" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "d6f8349dbcbe575f354f9a533a21f272f3eb3808a49e2fdc1c34393b88ba76cb" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", + "solana-instruction", + "solana-pubkey", ] [[package]] -name = "serde_json" -version = "1.0.149" +name = "spl-discriminator" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "a7398da23554a31660f17718164e31d31900956054f54f52d5ec1be51cb4f4b3" dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", + "bytemuck", + "solana-program-error", + "solana-sha256-hasher", + "spl-discriminator-derive", ] [[package]] -name = "serde_urlencoded" -version = "0.7.1" +name = "spl-discriminator-derive" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", + "quote", + "spl-discriminator-syn", + "syn 2.0.114", ] [[package]] -name = "sha1" -version = "0.10.6" +name = "spl-discriminator-syn" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "5d1dbc82ab91422345b6df40a79e2b78c7bce1ebb366da323572dd60b7076b67" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.114", + "thiserror 1.0.69", ] [[package]] -name = "sha2" -version = "0.10.9" +name = "spl-elgamal-registry" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "65edfeed09cd4231e595616aa96022214f9c9d2be02dea62c2b30d5695a6833a" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "bytemuck", + "solana-account-info", + "solana-cpi", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-system-interface", + "solana-sysvar", + "solana-zk-sdk", + "spl-pod", + "spl-token-confidential-transfer-proof-extraction", ] [[package]] -name = "sharded-slab" -version = "0.1.7" +name = "spl-generic-token" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +checksum = "741a62a566d97c58d33f9ed32337ceedd4e35109a686e31b1866c5dfa56abddc" dependencies = [ - "lazy_static", + "bytemuck", + "solana-pubkey", ] [[package]] -name = "shlex" -version = "1.3.0" +name = "spl-memo" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "9f09647c0974e33366efeb83b8e2daebb329f0420149e74d3a4bd2c08cf9f7cb" +dependencies = [ + "solana-account-info", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", +] [[package]] -name = "signal-hook-registry" -version = "1.4.8" +name = "spl-pod" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +checksum = "d994afaf86b779104b4a95ba9ca75b8ced3fdb17ee934e38cb69e72afbe17799" dependencies = [ - "errno", - "libc", + "borsh 1.6.0", + "bytemuck", + "bytemuck_derive", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "solana-program-option", + "solana-pubkey", + "solana-zk-sdk", + "thiserror 2.0.18", ] [[package]] -name = "simd-adler32" -version = "0.3.8" +name = "spl-program-error" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "9cdebc8b42553070b75aa5106f071fef2eb798c64a7ec63375da4b1f058688c6" +dependencies = [ + "num-derive", + "num-traits", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "spl-program-error-derive", + "thiserror 2.0.18", +] [[package]] -name = "slab" -version = "0.4.12" +name = "spl-program-error-derive" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +checksum = "2a2539e259c66910d78593475540e8072f0b10f0f61d7607bbf7593899ed52d0" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.114", +] [[package]] -name = "smallvec" -version = "1.15.1" +name = "spl-tlv-account-resolution" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "1408e961215688715d5a1063cbdcf982de225c45f99c82b4f7d7e1dd22b998d7" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", + "thiserror 2.0.18", +] [[package]] -name = "socket2" -version = "0.5.10" +name = "spl-token" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +checksum = "053067c6a82c705004f91dae058b11b4780407e9ccd6799dc9e7d0fab5f242da" dependencies = [ - "libc", - "windows-sys 0.52.0", + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-sysvar", + "thiserror 2.0.18", ] [[package]] -name = "socket2" -version = "0.6.2" +name = "spl-token-2022" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "31f0dfbb079eebaee55e793e92ca5f433744f4b71ee04880bfd6beefba5973e5" dependencies = [ - "libc", - "windows-sys 0.60.2", + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-native-token", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-security-txt", + "solana-system-interface", + "solana-sysvar", + "solana-zk-sdk", + "spl-elgamal-registry", + "spl-memo", + "spl-pod", + "spl-token", + "spl-token-confidential-transfer-ciphertext-arithmetic", + "spl-token-confidential-transfer-proof-extraction", + "spl-token-confidential-transfer-proof-generation", + "spl-token-group-interface", + "spl-token-metadata-interface", + "spl-transfer-hook-interface", + "spl-type-length-value", + "thiserror 2.0.18", ] [[package]] -name = "solana-atomic-u64" -version = "2.2.1" +name = "spl-token-confidential-transfer-ciphertext-arithmetic" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52e52720efe60465b052b9e7445a01c17550666beec855cce66f44766697bc2" +checksum = "cddd52bfc0f1c677b41493dafa3f2dbbb4b47cf0990f08905429e19dc8289b35" dependencies = [ - "parking_lot 0.12.5", + "base64 0.22.1", + "bytemuck", + "solana-curve25519", + "solana-zk-sdk", ] [[package]] -name = "solana-decode-error" -version = "2.3.0" +name = "spl-token-confidential-transfer-proof-extraction" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c781686a18db2f942e70913f7ca15dc120ec38dcab42ff7557db2c70c625a35" +checksum = "fe2629860ff04c17bafa9ba4bed8850a404ecac81074113e1f840dbd0ebb7bd6" dependencies = [ - "num-traits", + "bytemuck", + "solana-account-info", + "solana-curve25519", + "solana-instruction", + "solana-instructions-sysvar", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "solana-sdk-ids", + "solana-zk-sdk", + "spl-pod", + "thiserror 2.0.18", ] [[package]] -name = "solana-define-syscall" -version = "2.3.0" +name = "spl-token-confidential-transfer-proof-generation" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae3e2abcf541c8122eafe9a625d4d194b4023c20adde1e251f94e056bb1aee2" +checksum = "fa27b9174bea869a7ebf31e0be6890bce90b1a4288bc2bbf24bd413f80ae3fde" +dependencies = [ + "curve25519-dalek 4.1.3", + "solana-zk-sdk", + "thiserror 2.0.18", +] [[package]] -name = "solana-hash" -version = "2.3.0" +name = "spl-token-group-interface" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b96e9f0300fa287b545613f007dfe20043d7812bee255f418c1eb649c93b63" +checksum = "5597b4cd76f85ce7cd206045b7dc22da8c25516573d42d267c8d1fd128db5129" dependencies = [ - "five8", - "js-sys", - "solana-atomic-u64", - "solana-sanitize", - "wasm-bindgen", + "bytemuck", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "thiserror 2.0.18", ] [[package]] -name = "solana-pubkey" -version = "2.4.0" +name = "spl-token-metadata-interface" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b62adb9c3261a052ca1f999398c388f1daf558a1b492f60a6d9e64857db4ff1" +checksum = "304d6e06f0de0c13a621464b1fd5d4b1bebf60d15ca71a44d3839958e0da16ee" dependencies = [ - "borsh 0.10.4", "borsh 1.6.0", - "five8", - "five8_const", - "getrandom 0.2.17", - "js-sys", + "num-derive", "num-traits", - "serde", - "serde_derive", - "solana-atomic-u64", + "solana-borsh", "solana-decode-error", - "solana-define-syscall", - "solana-sanitize", - "solana-sha256-hasher", - "wasm-bindgen", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-type-length-value", + "thiserror 2.0.18", ] [[package]] -name = "solana-sanitize" -version = "2.2.1" +name = "spl-transfer-hook-interface" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61f1bc1357b8188d9c4a3af3fc55276e56987265eb7ad073ae6f8180ee54cecf" +checksum = "a7e905b849b6aba63bde8c4badac944ebb6c8e6e14817029cbe1bc16829133bd" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value", + "thiserror 2.0.18", +] [[package]] -name = "solana-sha256-hasher" -version = "2.3.0" +name = "spl-type-length-value" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa3feb32c28765f6aa1ce8f3feac30936f16c5c3f7eb73d63a5b8f6f8ecdc44" +checksum = "d417eb548214fa822d93f84444024b4e57c13ed6719d4dcc68eec24fb481e9f5" dependencies = [ - "sha2", - "solana-define-syscall", - "solana-hash", + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "spl-discriminator", + "spl-pod", + "thiserror 2.0.18", ] [[package]] @@ -3298,12 +5326,32 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + [[package]] name = "url" version = "2.5.8" @@ -3367,6 +5415,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -3787,9 +5841,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbba21b6046eff1c9be2366a70d7264763b10004306e874b54409503a39e5f1e" dependencies = [ "anyhow", + "bincode", "prost 0.14.3", "prost-types 0.14.3", "protobuf-src", + "solana-account", + "solana-account-decoder", + "solana-clock", + "solana-hash", + "solana-message", + "solana-pubkey", + "solana-signature", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", + "solana-transaction-status", "tonic 0.14.3", "tonic-build 0.14.3", "tonic-prost", @@ -3932,6 +5998,20 @@ name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] [[package]] name = "zerotrie" diff --git a/stacks/sdk/typescript/src/ore/index.ts b/stacks/sdk/typescript/src/ore/index.ts index 929235e0..5b782096 100644 --- a/stacks/sdk/typescript/src/ore/index.ts +++ b/stacks/sdk/typescript/src/ore/index.ts @@ -8,6 +8,7 @@ export interface OreRoundEntropy { entropy_start_at?: number | null; entropy_value?: string | null; entropy_var_address?: string | null; + expires_at?: number | null; resolved_seed?: any[] | null; } @@ -23,6 +24,8 @@ export interface OreRoundMetrics { export interface OreRoundResults { did_hit_motherlode?: boolean | null; + pre_reveal_rng?: number | null; + pre_reveal_winning_square?: number | null; rent_payer?: string | null; rng?: number | null; slot_hash?: string | null; @@ -82,6 +85,7 @@ export const OreRoundEntropySchema = z.object({ entropy_start_at: z.number().nullable().optional(), entropy_value: z.string().nullable().optional(), entropy_var_address: z.string().nullable().optional(), + expires_at: z.number().nullable().optional(), resolved_seed: z.array(z.any()).nullable().optional(), }); @@ -97,6 +101,8 @@ export const OreRoundMetricsSchema = z.object({ export const OreRoundResultsSchema = z.object({ did_hit_motherlode: z.boolean().nullable().optional(), + pre_reveal_rng: z.number().nullable().optional(), + pre_reveal_winning_square: z.number().nullable().optional(), rent_payer: z.string().nullable().optional(), rng: z.number().nullable().optional(), slot_hash: z.string().nullable().optional(), From a426edbd4fa8f32b031038aaf61d7f4e1b94c8f7 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Tue, 17 Mar 2026 16:42:25 +0000 Subject: [PATCH 08/60] feat: Add rt-multi-thread --- interpreter/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/Cargo.toml b/interpreter/Cargo.toml index f8b58ae1..d86f258d 100644 --- a/interpreter/Cargo.toml +++ b/interpreter/Cargo.toml @@ -26,7 +26,7 @@ lru = "0.12" sha2 = "0.10" sha3 = "0.10" tracing = "0.1" -tokio = { version = "1.0", features = ["sync"] } +tokio = { version = "1.0", features = ["sync", "rt-multi-thread"] } once_cell = "1.20" percent-encoding = "2" reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } From e83b003c03696311ee6d8fcbb9440d45cbab4d15 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Tue, 17 Mar 2026 16:42:57 +0000 Subject: [PATCH 09/60] fix: Remove debugging --- examples/ore-react/src/components/OreDashboard.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/examples/ore-react/src/components/OreDashboard.tsx b/examples/ore-react/src/components/OreDashboard.tsx index 671e6f49..769a5f1d 100644 --- a/examples/ore-react/src/components/OreDashboard.tsx +++ b/examples/ore-react/src/components/OreDashboard.tsx @@ -7,15 +7,10 @@ import { ConnectionBadge } from './ConnectionBadge'; import { ThemeToggle } from './ThemeToggle'; export function OreDashboard() { - const { views, isConnected } = useHyperstack(ORE_STREAM_STACK, { url: 'http://localhost:8878' }); + const { views, isConnected } = useHyperstack(ORE_STREAM_STACK); const { data: latestRound } = views.OreRound.latest.useOne({ schema: ValidatedOreRoundSchema }); - console.log(latestRound); - // const { data: latestRoundRaw } = views.OreRound.latest.use({ take: 2 }); const { data: treasuryData } = views.OreTreasury.list.useOne(); - // console.log(latestRoundRaw); - // return null; - return (
From 432deedd3cb7f2cf05883df7c0c4b5c9dd6eef54 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Tue, 17 Mar 2026 17:50:35 +0000 Subject: [PATCH 10/60] chore: Remove excessive debug logging from resolver pipeline --- .../src/codegen/vixen_runtime.rs | 40 ---- interpreter/src/resolvers.rs | 30 --- interpreter/src/scheduler.rs | 16 -- interpreter/src/vm.rs | 179 +++--------------- 4 files changed, 27 insertions(+), 238 deletions(-) diff --git a/hyperstack-macros/src/codegen/vixen_runtime.rs b/hyperstack-macros/src/codegen/vixen_runtime.rs index d1643f09..fda18412 100644 --- a/hyperstack-macros/src/codegen/vixen_runtime.rs +++ b/hyperstack-macros/src/codegen/vixen_runtime.rs @@ -194,15 +194,6 @@ fn generate_slot_scheduler_task() -> TokenStream { let cache_key = format!("scheduled:{}:{}:{}", callback.entity_name, callback.primary_key, url); - hyperstack::runtime::tracing::info!( - current_slot = current_slot, - entity = %callback.entity_name, - primary_key = %callback.primary_key, - url = %url, - cache_key = %cache_key, - "[RESOLVER] Executing scheduled URL resolver" - ); - // IMPORTANT: enqueue + take must stay inside the same lock guard. // Splitting them risks lost or duplicated requests during reconnects. let requests = { @@ -229,14 +220,6 @@ fn generate_slot_scheduler_task() -> TokenStream { requests, ).await; - hyperstack::runtime::tracing::info!( - current_slot = current_slot, - entity = %callback.entity_name, - primary_key = %callback.primary_key, - mutation_count = url_mutations.len(), - "[RESOLVER] Scheduled URL resolver completed" - ); - if url_mutations.is_empty() { if callback.retry_count < MAX_RETRIES { callback.retry_count += 1; @@ -1017,33 +1000,10 @@ pub fn generate_vm_handler( if !scheduled_callbacks.is_empty() { let mut scheduler = self.slot_scheduler.lock().unwrap_or_else(|e| e.into_inner()); for (target_slot, callback) in scheduled_callbacks { - hyperstack::runtime::tracing::info!( - event_type = %event_type, - account = %account_address, - slot = slot, - target_slot = target_slot, - entity = %callback.entity_name, - primary_key = %callback.primary_key, - "[RESOLVER] Scheduled callback registered for future slot" - ); scheduler.register(target_slot, callback); } } - // Log resolver requests being created - if !resolver_requests.is_empty() { - for req in &resolver_requests { - hyperstack::runtime::tracing::info!( - event_type = %event_type, - account = %account_address, - slot = slot, - resolver = ?req.resolver, - input = %req.input, - "[RESOLVER] Resolver request created from account update" - ); - } - } - let resolver_mutations = if mutations_result.is_ok() { self.resolve_and_apply_resolvers(resolver_requests).await } else { diff --git a/interpreter/src/resolvers.rs b/interpreter/src/resolvers.rs index be30b9f5..617f571f 100644 --- a/interpreter/src/resolvers.rs +++ b/interpreter/src/resolvers.rs @@ -697,27 +697,8 @@ pub async fn resolve_url_batch( .map(|v| (v.url.clone(), v.method.clone())) .collect(); - // Log all URLs being fetched - for (url, method) in &batch_input { - tracing::info!( - url = %url, - method = ?method, - "[RESOLVER] Fetching URL" - ); - } - let results = url_client.resolve_batch(&batch_input).await; - // Log results summary - let success_count = results.len(); - let fail_count = batch_input.len() - success_count; - tracing::info!( - success = success_count, - failed = fail_count, - total = batch_input.len(), - "[RESOLVER] URL batch fetch completed" - ); - // Apply results to VM state, requeue anything that didn't resolve let mut vm = vm.lock().unwrap_or_else(|e| e.into_inner()); let mut mutations = Vec::new(); @@ -726,19 +707,8 @@ pub async fn resolve_url_batch( for entry in valid { match results.get(&entry.url) { Some(resolved_value) => { - tracing::info!( - url = %entry.url, - cache_key = %entry.request.cache_key, - response = %resolved_value, - "[RESOLVER] Applying resolver result to state" - ); match vm.apply_resolver_result(bytecode, &entry.request.cache_key, resolved_value.clone()) { Ok(mut new_mutations) => { - tracing::info!( - url = %entry.url, - mutation_count = new_mutations.len(), - "[RESOLVER] Successfully applied resolver result" - ); mutations.append(&mut new_mutations) } Err(err) => { diff --git a/interpreter/src/scheduler.rs b/interpreter/src/scheduler.rs index 2fdf032f..0db9ef86 100644 --- a/interpreter/src/scheduler.rs +++ b/interpreter/src/scheduler.rs @@ -58,27 +58,11 @@ impl SlotScheduler { total_count += callbacks.len(); for cb in callbacks { let dedup_key = Self::dedup_key(&cb); - tracing::info!( - current_slot = current_slot, - scheduled_slot = slot, - entity = %cb.entity_name, - primary_key = %cb.primary_key, - resolver = ?cb.resolver, - "[RESOLVER] Scheduled callback firing" - ); self.registered.remove(&dedup_key); self.slot_index.remove(&dedup_key); result.push(cb); } } - if total_count > 0 { - tracing::info!( - current_slot = current_slot, - count = total_count, - pending = self.pending_count(), - "[RESOLVER] Total scheduled callbacks fired for current slot" - ); - } result } diff --git a/interpreter/src/vm.rs b/interpreter/src/vm.rs index 9cc35196..ac8ecb96 100644 --- a/interpreter/src/vm.rs +++ b/interpreter/src/vm.rs @@ -905,7 +905,21 @@ impl StateTable { let dominated = self .version_tracker .get(primary_key, event_type) - .map(|(last_slot, last_version)| (slot, ordering_value) <= (last_slot, last_version)) + .map(|(last_slot, last_version)| { + let is_stale = (slot, ordering_value) <= (last_slot, last_version); + if is_stale && event_type == "ore::RoundState" { + tracing::debug!( + entity_key = %primary_key, + event_type = %event_type, + current_slot = slot, + current_write_version = ordering_value, + last_slot = last_slot, + last_write_version = last_version, + "RoundState recency check: stale update detected" + ); + } + is_stale + }) .unwrap_or(false); if dominated { @@ -1144,15 +1158,6 @@ impl VmContext { let mut dirty_tracker = DirtyTracker::new(); let should_emit = |path: &str| !entity_bytecode.non_emitted_fields.contains(path); - tracing::info!( - entity = %target.entity_name, - primary_key = %target.primary_key, - cache_key = %cache_key, - extract_targets = ?target.extracts.iter().map(|e| &e.target_path).collect::>(), - resolved_value = %resolved_value, - "[RESOLVER] Applying resolved value to entity state" - ); - Self::apply_resolver_extractions_to_value( &mut entity_state, &resolved_value, @@ -1168,13 +1173,6 @@ impl VmContext { .map(|path| Self::get_value_at_path(&entity_state, path)) .collect(); - tracing::debug!( - entity = %target.entity_name, - primary_key = %target.primary_key, - computed_paths = ?entity_bytecode.computed_paths, - "[COMPUTED] Evaluating computed fields after resolver" - ); - let context_slot = self.current_context.as_ref().and_then(|c| c.slot); let context_timestamp = self .current_context @@ -1197,51 +1195,20 @@ impl VmContext { let changed = new_value != *old_value; let will_emit = should_emit(path); - tracing::debug!( - entity = %target.entity_name, - primary_key = %target.primary_key, - field_path = %path, - old_value = ?old_value, - new_value = ?new_value, - changed = %changed, - will_emit = %will_emit, - "[COMPUTED] Checking computed field change" - ); - if changed && will_emit { dirty_tracker.mark_replaced(path); changed_fields.push(path.clone()); } } - if !changed_fields.is_empty() { - tracing::info!( - entity = %target.entity_name, - primary_key = %target.primary_key, - changed_fields = ?changed_fields, - "[COMPUTED] Computed fields changed after resolver" - ); - } } } state.insert_with_eviction(target.primary_key.clone(), entity_state.clone()); if dirty_tracker.is_empty() { - tracing::debug!( - entity = %target.entity_name, - primary_key = %target.primary_key, - "[RESOLVER] No dirty fields after resolver result, skipping mutation" - ); continue; } - tracing::info!( - entity = %target.entity_name, - primary_key = %target.primary_key, - dirty_fields = ?dirty_tracker.iter().collect::>(), - "[RESOLVER] Resolver result applied, emitting mutation" - ); - let patch = Self::build_partial_state_from_value(&entity_state, &dirty_tracker)?; mutations.push(Mutation { @@ -1272,18 +1239,6 @@ impl VmContext { .unwrap() .as_secs() as i64; - // Log resolver request details - let current_slot = self.current_context.as_ref().and_then(|ctx| ctx.slot); - tracing::info!( - resolver_type = ?resolver, - cache_key = %cache_key, - input = %input, - entity = %target.entity_name, - primary_key = %target.primary_key, - current_slot = ?current_slot, - "[RESOLVER] Enqueueing resolver request" - ); - self.resolver_pending.insert( cache_key.clone(), PendingResolverEntry { @@ -2117,19 +2072,28 @@ impl VmContext { if !key_value.is_null() { if let Some(ctx) = &self.current_context { // Account updates: use recency check to discard stale updates + // IMPORTANT: Use account address (PDA) as the key, not entity key, + // because multiple accounts can update the same entity and each + // has its own independent write_version if ctx.is_account_update() { if let (Some(slot), Some(write_version)) = (ctx.slot, ctx.write_version) { + // Get account address from event_value for proper tracking + let account_address = event_value + .get("__account_address") + .cloned() + .unwrap_or_else(|| key_value.clone()); + if !state.is_fresh_update( - &key_value, + &account_address, event_type, slot, write_version, ) { self.add_warning(format!( - "Stale account update skipped: slot={}, write_version={}", - slot, write_version + "Stale account update skipped: slot={}, write_version={}, account={}", + slot, write_version, account_address )); return Ok(Vec::new()); } @@ -2834,14 +2798,6 @@ impl VmContext { "unknown".to_string() }; - tracing::info!( - entity = %entity_name, - trigger = %trigger_info, - resolver = ?resolver, - schedule_at = ?schedule_at, - "[RESOLVER] QueueResolver opcode triggered by event" - ); - // Skip resolvers for reprocessed cached data from PDA mapping changes. // Stale data can carry wrong field values (e.g. old entropy_value) and // wrong schedule_at slots that would lock in incorrect results via SetOnce. @@ -2851,10 +2807,6 @@ impl VmContext { .map(|c| c.skip_resolvers) .unwrap_or(false) { - tracing::info!( - entity = %entity_name, - "[RESOLVER] Skipping resolver: context is reprocessed cached data" - ); pc += 1; continue; } @@ -2867,23 +2819,6 @@ impl VmContext { let condition_met = self.evaluate_comparison(&field_val, &cond.op, &cond.value)?; - // Get full state snapshot for debugging - let state_json = - serde_json::to_string(&self.registers[*state]).unwrap_or_default(); - let has_entropy = state_json.contains("entropy"); - let has_entropy_value = state_json.contains("entropy_value"); - - tracing::info!( - entity = %entity_name, - condition_field = %cond.field_path, - condition_met = condition_met, - field_value = ?field_val, - has_entropy_section = has_entropy, - has_entropy_value_field = has_entropy_value, - state_size = state_json.len(), - "[RESOLVER] Evaluating resolver condition" - ); - if !condition_met { pc += 1; continue; @@ -2905,15 +2840,6 @@ impl VmContext { if current_slot < target_slot { let key_value = &self.registers[*key]; if !key_value.is_null() { - tracing::info!( - entity = %entity_name, - primary_key = %key_value, - current_slot = current_slot, - target_slot = target_slot, - slots_until_fire = target_slot - current_slot, - schedule_at_path = %schedule_path, - "[RESOLVER] Scheduling deferred resolver" - ); self.scheduled_callbacks.push(( target_slot, ScheduledCallback { @@ -2930,36 +2856,16 @@ impl VmContext { retry_count: 0, }, )); - } else { - tracing::warn!( - entity = %entity_name, - current_slot = current_slot, - target_slot = target_slot, - "[RESOLVER] Cannot schedule deferred resolver: primary key is null" - ); } pc += 1; continue; } // current_slot >= target_slot: fall through to immediate resolution - tracing::info!( - entity = %entity_name, - primary_key = %self.registers[*key], - current_slot = current_slot, - target_slot = target_slot, - "[RESOLVER] schedule_at slot already passed, falling through to immediate execution" - ); } None => { // schedule_at path is missing or value is not a u64 — // skip resolver entirely rather than executing immediately, // since the state likely hasn't been fully populated yet. - tracing::warn!( - schedule_at_path = %schedule_path, - entity = %entity_name, - "schedule_at field path is missing or not a valid u64 in state; \ - skipping resolver (state may not be fully populated yet)" - ); pc += 1; continue; } @@ -2982,16 +2888,6 @@ impl VmContext { let key_value = &self.registers[*key]; if input.is_null() || key_value.is_null() { - tracing::warn!( - entity = %entity_name, - resolver = ?resolver, - input_path = %input_path.as_deref().unwrap_or(""), - input_is_null = input.is_null(), - key_is_null = key_value.is_null(), - input = ?input, - key = ?key_value, - "Resolver skipped: null input or key" - ); pc += 1; continue; } @@ -3010,12 +2906,6 @@ impl VmContext { } }) { - tracing::info!( - entity = %entity_name, - primary_key = %self.registers[*key], - extract_targets = ?extracts.iter().map(|e| &e.target_path).collect::>(), - "[RESOLVER] SetOnce guard: all extract targets already populated, skipping resolver" - ); pc += 1; continue; } @@ -3041,14 +2931,6 @@ impl VmContext { extracts: extracts.clone(), }; - tracing::info!( - entity = %entity_name, - trigger = %trigger_info, - cache_key = %cache_key, - input = ?input, - "[RESOLVER] Queueing immediate resolver request" - ); - self.enqueue_resolver_request( cache_key, resolver.clone(), @@ -3057,13 +2939,6 @@ impl VmContext { ); } } else { - tracing::warn!( - entity = %entity_name, - resolver = ?resolver, - input_path = %input_path.as_deref().unwrap_or(""), - state = ?self.registers[*state], - "Resolver skipped: input path not found in state" - ); } pc += 1; From e4dcf1cc5694897e460207df85d5a93a449c5a12 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Tue, 17 Mar 2026 17:50:43 +0000 Subject: [PATCH 11/60] fix: Add optional chaining for safer property access in Ore examples --- examples/ore-react/src/components/BlockGrid.tsx | 2 +- examples/ore-react/src/components/OreDashboard.tsx | 4 ++-- examples/ore-react/src/components/StatsPanel.tsx | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/ore-react/src/components/BlockGrid.tsx b/examples/ore-react/src/components/BlockGrid.tsx index b90dcb8e..44719c78 100644 --- a/examples/ore-react/src/components/BlockGrid.tsx +++ b/examples/ore-react/src/components/BlockGrid.tsx @@ -7,7 +7,7 @@ interface BlockGridProps { export function BlockGrid({ round }: BlockGridProps) { const blocks = round - ? round.state.deployed_per_square_ui.map((deployedUi, i) => ({ + ? (round.state?.deployed_per_square_ui || []).map((deployedUi, i) => ({ id: i + 1, minerCount: round.state.count_per_square[i], deployedUi, diff --git a/examples/ore-react/src/components/OreDashboard.tsx b/examples/ore-react/src/components/OreDashboard.tsx index 769a5f1d..84a4a4a5 100644 --- a/examples/ore-react/src/components/OreDashboard.tsx +++ b/examples/ore-react/src/components/OreDashboard.tsx @@ -7,8 +7,8 @@ import { ConnectionBadge } from './ConnectionBadge'; import { ThemeToggle } from './ThemeToggle'; export function OreDashboard() { - const { views, isConnected } = useHyperstack(ORE_STREAM_STACK); - const { data: latestRound } = views.OreRound.latest.useOne({ schema: ValidatedOreRoundSchema }); + const { views, isConnected } = useHyperstack(ORE_STREAM_STACK, { url: 'http://localhost:8878' }); + const { data: latestRound } = views.OreRound.latest.useOne(); const { data: treasuryData } = views.OreTreasury.list.useOne(); return ( diff --git a/examples/ore-react/src/components/StatsPanel.tsx b/examples/ore-react/src/components/StatsPanel.tsx index 43e9bffa..6a31c3fd 100644 --- a/examples/ore-react/src/components/StatsPanel.tsx +++ b/examples/ore-react/src/components/StatsPanel.tsx @@ -12,7 +12,7 @@ export function StatsPanel({ round, treasuryMotherlode, isConnected }: StatsPane const [timeRemaining, setTimeRemaining] = useState('00:00'); useEffect(() => { - const expiresAtUnix = round?.state.estimated_expires_at_unix; + const expiresAtUnix = round?.state?.estimated_expires_at_unix; if (!expiresAtUnix) { setTimeRemaining('00:00'); return; @@ -35,7 +35,7 @@ export function StatsPanel({ round, treasuryMotherlode, isConnected }: StatsPane updateTimer(); const interval = setInterval(updateTimer, 1000); return () => clearInterval(interval); - }, [round?.state.estimated_expires_at_unix]); + }, [round?.state?.estimated_expires_at_unix]); return (
@@ -56,7 +56,7 @@ export function StatsPanel({ round, treasuryMotherlode, isConnected }: StatsPane
- {round ? round.state.total_deployed.toFixed(4) : '0.0000'} + {round ? round.state?.total_deployed.toFixed(4) : '0.0000'}
Total deployed
@@ -70,11 +70,11 @@ export function StatsPanel({ round, treasuryMotherlode, isConnected }: StatsPane
- Round {round?.id.round_id ?? '–'} + Round {round?.id?.round_id ?? '–'} {round && ( <> · - {round.state.total_miners} miners + {round.state?.total_miners} miners )}
From d46ab22fc644769e74444244d3185f18f05dfb6b Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Tue, 17 Mar 2026 17:50:50 +0000 Subject: [PATCH 12/60] feat: Enable treasury streaming in TypeScript example --- examples/ore-typescript/src/main.ts | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/examples/ore-typescript/src/main.ts b/examples/ore-typescript/src/main.ts index 6ca0cec8..57113acc 100644 --- a/examples/ore-typescript/src/main.ts +++ b/examples/ore-typescript/src/main.ts @@ -15,7 +15,6 @@ import { // const OreTreasuryWithIdSchema = OreTreasurySchema.extend({ // id: OreTreasuryIdSchema.required(), // }); -// // type OreRoundWithId = z.infer; // type OreTreasuryWithId = z.infer; type OreRoundWithId = any; @@ -56,18 +55,17 @@ async function main() { // printRound(round); } }; - await streamRounds(); - // const streamTreasury = async () => { - // for await (const treasury of hs.views.OreTreasury.list.use({ - // take: 1, - // schema: OreTreasuryWithIdSchema, - // })) { - // printTreasury(treasury); - // } - // }; - // - // await Promise.all([streamRounds(), streamTreasury()]); + const streamTreasury = async () => { + for await (const treasury of hs.views.OreTreasury.list.use({ + take: 1, + // schema: OreTreasuryWithIdSchema, + })) { + printTreasury(treasury); + } + }; + + await Promise.all([streamRounds(), streamTreasury()]); } main().catch((err) => { From 1115054bb31e6275b23d161eb1c7defbad0a3b9f Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Tue, 17 Mar 2026 17:50:57 +0000 Subject: [PATCH 13/60] feat: Update Ore stack IDL with program address and formatting --- stacks/ore/.hyperstack/OreStream.stack.json | 421 +++++++++++++++++++- stacks/ore/idl/entropy.json | 1 + stacks/ore/idl/ore.json | 171 ++++++-- 3 files changed, 555 insertions(+), 38 deletions(-) diff --git a/stacks/ore/.hyperstack/OreStream.stack.json b/stacks/ore/.hyperstack/OreStream.stack.json index 9c1f1b10..2f22a1db 100644 --- a/stacks/ore/.hyperstack/OreStream.stack.json +++ b/stacks/ore/.hyperstack/OreStream.stack.json @@ -24,6 +24,40 @@ ], "docs": [ "Automation parameters for automated mining deployments." + ], + "fields": [ + { + "name": "amount", + "type": "u64" + }, + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "balance", + "type": "u64" + }, + { + "name": "executor", + "type": "publicKey" + }, + { + "name": "fee", + "type": "u64" + }, + { + "name": "strategy", + "type": "u64" + }, + { + "name": "mask", + "type": "u64" + }, + { + "name": "reload", + "type": "u64" + } ] }, { @@ -40,6 +74,24 @@ ], "docs": [ "Global round tracking for the mining game." + ], + "fields": [ + { + "name": "round_id", + "type": "u64" + }, + { + "name": "start_slot", + "type": "u64" + }, + { + "name": "end_slot", + "type": "u64" + }, + { + "name": "epoch_id", + "type": "u64" + } ] }, { @@ -56,6 +108,32 @@ ], "docs": [ "Program configuration state." + ], + "fields": [ + { + "name": "admin", + "type": "publicKey" + }, + { + "name": "buffer_a", + "type": "publicKey" + }, + { + "name": "buffer_b", + "type": "publicKey" + }, + { + "name": "buffer_c", + "type": "publicKey" + }, + { + "name": "buffer_d", + "type": "publicKey" + }, + { + "name": "buffer_e", + "type": "u64" + } ] }, { @@ -72,6 +150,80 @@ ], "docs": [ "Tracks a miner's deployed SOL and reward balances." + ], + "fields": [ + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "deployed", + "type": { + "array": [ + "u64", + 25 + ] + } + }, + { + "name": "cumulative", + "type": { + "array": [ + "u64", + 25 + ] + } + }, + { + "name": "checkpoint_fee", + "type": "u64" + }, + { + "name": "checkpoint_id", + "type": "u64" + }, + { + "name": "last_claim_ore_at", + "type": "i64" + }, + { + "name": "last_claim_sol_at", + "type": "i64" + }, + { + "name": "rewards_factor", + "type": { + "defined": "Numeric" + } + }, + { + "name": "rewards_sol", + "type": "u64" + }, + { + "name": "rewards_ore", + "type": "u64" + }, + { + "name": "refined_ore", + "type": "u64" + }, + { + "name": "round_id", + "type": "u64" + }, + { + "name": "lifetime_rewards_sol", + "type": "u64" + }, + { + "name": "lifetime_rewards_ore", + "type": "u64" + }, + { + "name": "lifetime_deployed", + "type": "u64" + } ] }, { @@ -88,6 +240,75 @@ ], "docs": [ "State for a single mining round." + ], + "fields": [ + { + "name": "id", + "type": "u64" + }, + { + "name": "deployed", + "type": { + "array": [ + "u64", + 25 + ] + } + }, + { + "name": "slot_hash", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "count", + "type": { + "array": [ + "u64", + 25 + ] + } + }, + { + "name": "expires_at", + "type": "u64" + }, + { + "name": "motherlode", + "type": "u64" + }, + { + "name": "rent_payer", + "type": "publicKey" + }, + { + "name": "top_miner", + "type": "publicKey" + }, + { + "name": "top_miner_reward", + "type": "u64" + }, + { + "name": "total_deployed", + "type": "u64" + }, + { + "name": "total_miners", + "type": "u64" + }, + { + "name": "total_vaulted", + "type": "u64" + }, + { + "name": "total_winnings", + "type": "u64" + } ] }, { @@ -104,6 +325,66 @@ ], "docs": [ "State for a staking participant." + ], + "fields": [ + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "balance", + "type": "u64" + }, + { + "name": "buffer_a", + "type": "u64" + }, + { + "name": "buffer_b", + "type": "u64" + }, + { + "name": "buffer_c", + "type": "u64" + }, + { + "name": "buffer_d", + "type": "u64" + }, + { + "name": "compound_fee_reserve", + "type": "u64" + }, + { + "name": "last_claim_at", + "type": "i64" + }, + { + "name": "last_deposit_at", + "type": "i64" + }, + { + "name": "last_withdraw_at", + "type": "i64" + }, + { + "name": "rewards_factor", + "type": { + "defined": "Numeric" + } + }, + { + "name": "rewards", + "type": "u64" + }, + { + "name": "lifetime_rewards", + "type": "u64" + }, + { + "name": "buffer_f", + "type": "u64" + } ] }, { @@ -120,6 +401,48 @@ ], "docs": [ "Singleton treasury account tracking protocol balances." + ], + "fields": [ + { + "name": "balance", + "type": "u64" + }, + { + "name": "buffer_a", + "type": "u64" + }, + { + "name": "motherlode", + "type": "u64" + }, + { + "name": "miner_rewards_factor", + "type": { + "defined": "Numeric" + } + }, + { + "name": "stake_rewards_factor", + "type": { + "defined": "Numeric" + } + }, + { + "name": "buffer_b", + "type": "u64" + }, + { + "name": "total_refined", + "type": "u64" + }, + { + "name": "total_staked", + "type": "u64" + }, + { + "name": "total_unclaimed", + "type": "u64" + } ] } ], @@ -136,6 +459,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Configures or closes a miner automation account.", "Automation PDA seeds: [\"automation\", signer].", @@ -222,6 +546,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Settles miner rewards for a completed round.", "Treasury PDA seeds: [\"treasury\"]." @@ -290,6 +615,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Claims SOL rewards from the miner account." ], @@ -333,6 +659,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Claims ORE token rewards from the treasury vault." ], @@ -424,6 +751,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Closes an expired round account and returns rent to the payer.", "Round PDA seeds: [\"round\", round_id].", @@ -493,6 +821,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Deploys SOL to selected squares for the current round.", "Automation PDA seeds: [\"automation\", authority].", @@ -613,6 +942,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Emits an arbitrary log message from the board PDA.", "Bytes following the discriminator are logged verbatim." @@ -641,6 +971,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Finalizes the current round, mints rewards, and opens the next round.", "Board PDA seeds: [\"board\"].", @@ -807,6 +1138,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Deposits ORE into a staking account.", "Stake PDA seeds: [\"stake\", signer]." @@ -916,6 +1248,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Withdraws ORE from a staking account.", "Stake PDA seeds: [\"stake\", signer]." @@ -1013,6 +1346,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Claims accrued staking rewards.", "Stake PDA seeds: [\"stake\", signer].", @@ -1111,6 +1445,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Buys back ORE from the market." ], @@ -1129,6 +1464,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Swaps vaulted SOL for ORE via a CPI and burns the proceeds.", "Treasury PDA seeds: [\"treasury\"].", @@ -1227,6 +1563,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Wraps SOL held by the treasury into WSOL for swapping.", "Treasury PDA seeds: [\"treasury\"]." @@ -1292,6 +1629,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Updates the program admin address." ], @@ -1340,6 +1678,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Creates a new entropy var account through the entropy program." ], @@ -1433,6 +1772,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Reloads SOL into the automation account." ], @@ -1451,6 +1791,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Compounds staking yield." ], @@ -1469,6 +1810,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Liquidation instruction." ], @@ -2147,6 +2489,72 @@ ], "docs": [ "An entropy variable account that stores randomness generation state." + ], + "fields": [ + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "id", + "type": "u64" + }, + { + "name": "provider", + "type": "publicKey" + }, + { + "name": "commit", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "seed", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "slot_hash", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "value", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "samples", + "type": "u64" + }, + { + "name": "is_auto", + "type": "u64" + }, + { + "name": "start_at", + "type": "u64" + }, + { + "name": "end_at", + "type": "u64" + } ] } ], @@ -2163,6 +2571,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Creates a new entropy var account.", "Var PDA seeds: [\"var\", authority, id]." @@ -2249,6 +2658,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Closes an entropy var account and returns rent to the authority." ], @@ -2292,6 +2702,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Updates the var for the next random value sample.", "Resets the commit to the previous seed and clears slot_hash, seed, and value." @@ -2333,6 +2744,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Reveals the seed and finalizes the random value.", "The seed must hash to the commit stored in the var account." @@ -2379,6 +2791,7 @@ 0, 0 ], + "discriminant": null, "docs": [ "Samples the slot hash at the end_at slot.", "Must be called after the end_at slot has passed." @@ -4968,7 +5381,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "7a868be08df6c5f84524662785b0f3c6d69c3ce57a11e1e9a92c31efdbfdd466", + "content_hash": "228a3402ec182567cdbfaa707138362ff7c3a5e3f5854a76cdff6d7b7c79d706", "views": [ { "id": "OreRound/latest", @@ -5584,7 +5997,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "6c304a5351de588793a9394e722ea4870805730d38b3a1782a970400b4fc3f36", + "content_hash": "807c6c941a86f6d21c0801d6c92481665cf7778931c56f4b9f716dce6413f6b3", "views": [] }, { @@ -6942,7 +7355,7 @@ "resolver_specs": [], "computed_fields": [], "computed_field_specs": [], - "content_hash": "f6a0a3a397a148fa34256295b78d8ce504484bb768958fa8593d4cd1b6a3bac7", + "content_hash": "65b194af422058c586a9425a4e34887d163f7adae4c6ad952968e9c10905d2d7", "views": [] } ], @@ -9050,5 +9463,5 @@ ] } ], - "content_hash": "f55e8993b0bd69e07f04787cc9a6b513df6d784796fcdef555073fa7f58cdbb8" + "content_hash": "ffe594cf02bed5cffc6fe87c68b45bdea44c183c18cbefb71e5763c3e93780f1" } \ No newline at end of file diff --git a/stacks/ore/idl/entropy.json b/stacks/ore/idl/entropy.json index 77ad5542..cfef866e 100644 --- a/stacks/ore/idl/entropy.json +++ b/stacks/ore/idl/entropy.json @@ -1,5 +1,6 @@ { "version": "0.1.5", + "address": "3jSkUuYBoJzQPMEzTvkDFXCZUBksPamrVhrnHR9igu2X", "name": "entropy", "instructions": [ { diff --git a/stacks/ore/idl/ore.json b/stacks/ore/idl/ore.json index 01667cf3..7d52a4a1 100644 --- a/stacks/ore/idl/ore.json +++ b/stacks/ore/idl/ore.json @@ -1,5 +1,6 @@ { "version": "3.7.22", + "address": "oreV3EG1i9BEgiAJ8b177Z2S2rMarzak4NMv1kULvWv", "name": "ore", "instructions": [ { @@ -1428,21 +1429,66 @@ "type": { "kind": "struct", "fields": [ - {"name": "disc", "type": "u64"}, - {"name": "round_id", "type": "u64"}, - {"name": "start_slot", "type": "u64"}, - {"name": "end_slot", "type": "u64"}, - {"name": "winning_square", "type": "u64"}, - {"name": "top_miner", "type": "publicKey"}, - {"name": "num_winners", "type": "u64"}, - {"name": "motherlode", "type": "u64"}, - {"name": "total_deployed", "type": "u64"}, - {"name": "total_vaulted", "type": "u64"}, - {"name": "total_winnings", "type": "u64"}, - {"name": "total_minted", "type": "u64"}, - {"name": "ts", "type": "i64"}, - {"name": "rng", "type": "u64"}, - {"name": "deployed_winning_square", "type": "u64"} + { + "name": "disc", + "type": "u64" + }, + { + "name": "round_id", + "type": "u64" + }, + { + "name": "start_slot", + "type": "u64" + }, + { + "name": "end_slot", + "type": "u64" + }, + { + "name": "winning_square", + "type": "u64" + }, + { + "name": "top_miner", + "type": "publicKey" + }, + { + "name": "num_winners", + "type": "u64" + }, + { + "name": "motherlode", + "type": "u64" + }, + { + "name": "total_deployed", + "type": "u64" + }, + { + "name": "total_vaulted", + "type": "u64" + }, + { + "name": "total_winnings", + "type": "u64" + }, + { + "name": "total_minted", + "type": "u64" + }, + { + "name": "ts", + "type": "i64" + }, + { + "name": "rng", + "type": "u64" + }, + { + "name": "deployed_winning_square", + "type": "u64" + } ] } }, @@ -1451,12 +1497,30 @@ "type": { "kind": "struct", "fields": [ - {"name": "disc", "type": "u64"}, - {"name": "ore_buried", "type": "u64"}, - {"name": "ore_shared", "type": "u64"}, - {"name": "sol_amount", "type": "u64"}, - {"name": "new_circulating_supply", "type": "u64"}, - {"name": "ts", "type": "i64"} + { + "name": "disc", + "type": "u64" + }, + { + "name": "ore_buried", + "type": "u64" + }, + { + "name": "ore_shared", + "type": "u64" + }, + { + "name": "sol_amount", + "type": "u64" + }, + { + "name": "new_circulating_supply", + "type": "u64" + }, + { + "name": "ts", + "type": "i64" + } ] } }, @@ -1465,15 +1529,42 @@ "type": { "kind": "struct", "fields": [ - {"name": "disc", "type": "u64"}, - {"name": "authority", "type": "publicKey"}, - {"name": "amount", "type": "u64"}, - {"name": "mask", "type": "u64"}, - {"name": "round_id", "type": "u64"}, - {"name": "signer", "type": "publicKey"}, - {"name": "strategy", "type": "u64"}, - {"name": "total_squares", "type": "u64"}, - {"name": "ts", "type": "i64"} + { + "name": "disc", + "type": "u64" + }, + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "amount", + "type": "u64" + }, + { + "name": "mask", + "type": "u64" + }, + { + "name": "round_id", + "type": "u64" + }, + { + "name": "signer", + "type": "publicKey" + }, + { + "name": "strategy", + "type": "u64" + }, + { + "name": "total_squares", + "type": "u64" + }, + { + "name": "ts", + "type": "i64" + } ] } }, @@ -1482,10 +1573,22 @@ "type": { "kind": "struct", "fields": [ - {"name": "disc", "type": "u64"}, - {"name": "sol_amount", "type": "u64"}, - {"name": "recipient", "type": "publicKey"}, - {"name": "ts", "type": "i64"} + { + "name": "disc", + "type": "u64" + }, + { + "name": "sol_amount", + "type": "u64" + }, + { + "name": "recipient", + "type": "publicKey" + }, + { + "name": "ts", + "type": "i64" + } ] } } From b05ae9bd169f48c2cfd1222d8fa4adc882d96adc Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Tue, 17 Mar 2026 17:51:07 +0000 Subject: [PATCH 14/60] fix: Core interpreter and server improvements --- hyperstack-idl/src/snapshot.rs | 38 ++++++++++- hyperstack-idl/tests/parse_fixtures.rs | 64 +++++++++++++++++++ hyperstack-macros/src/ast/writer.rs | 16 +++++ hyperstack-macros/src/codegen/computed.rs | 10 ++- hyperstack-macros/src/stream_spec/entity.rs | 11 ---- interpreter/src/compiler.rs | 10 +++ rust/hyperstack-server/src/sorted_cache.rs | 1 + rust/hyperstack-server/src/view/spec.rs | 1 + .../hyperstack-server/src/websocket/server.rs | 1 + 9 files changed, 134 insertions(+), 18 deletions(-) diff --git a/hyperstack-idl/src/snapshot.rs b/hyperstack-idl/src/snapshot.rs index 68448d15..9c7d4e1a 100644 --- a/hyperstack-idl/src/snapshot.rs +++ b/hyperstack-idl/src/snapshot.rs @@ -2,10 +2,12 @@ use serde::{de::Error, Deserialize, Deserializer, Serialize}; +use crate::types::SteelDiscriminant; + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct IdlSnapshot { pub name: String, - #[serde(default, skip_serializing_if = "Option::is_none")] + #[serde(default, skip_serializing_if = "Option::is_none", alias = "address")] pub program_id: Option, pub version: String, pub accounts: Vec, @@ -32,18 +34,51 @@ pub struct IdlAccountSnapshot { pub docs: Vec, #[serde(default, skip_serializing_if = "Option::is_none")] pub serialization: Option, + /// Account fields - populated from inline type definition + #[serde(default)] + pub fields: Vec, + /// Inline type definition (for Steel format with type.fields structure) + #[serde(rename = "type", default, skip_serializing_if = "Option::is_none")] + pub type_def: Option, +} + +/// Inline type definition for account fields (Steel format) +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct IdlInlineTypeDef { + pub kind: String, + pub fields: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct IdlInstructionSnapshot { pub name: String, + #[serde(default)] pub discriminator: Vec, #[serde(default)] + pub discriminant: Option, + #[serde(default)] pub docs: Vec, pub accounts: Vec, pub args: Vec, } +impl IdlInstructionSnapshot { + /// Get the computed 8-byte discriminator. + /// Returns the explicit discriminator if present, otherwise computes from discriminant. + pub fn get_discriminator(&self) -> Vec { + if !self.discriminator.is_empty() { + return self.discriminator.clone(); + } + + if let Some(disc) = &self.discriminant { + let value = disc.value as u8; + return vec![value, 0, 0, 0, 0, 0, 0, 0]; + } + + crate::discriminator::anchor_discriminator(&format!("global:{}", self.name)) + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct IdlInstructionAccountSnapshot { pub name: String, @@ -212,6 +247,7 @@ mod tests { instructions: vec![IdlInstructionSnapshot { name: "example_instruction".to_string(), discriminator: vec![8, 7, 6, 5, 4, 3, 2, 1], + discriminant: None, docs: vec!["Example instruction".to_string()], accounts: vec![IdlInstructionAccountSnapshot { name: "payer".to_string(), diff --git a/hyperstack-idl/tests/parse_fixtures.rs b/hyperstack-idl/tests/parse_fixtures.rs index e75552a1..2906cc29 100644 --- a/hyperstack-idl/tests/parse_fixtures.rs +++ b/hyperstack-idl/tests/parse_fixtures.rs @@ -1,4 +1,6 @@ use hyperstack_idl::parse::parse_idl_file; +use hyperstack_idl::snapshot::IdlSnapshot; +use std::fs; use std::path::PathBuf; fn fixture_path(name: &str) -> PathBuf { @@ -18,6 +20,68 @@ fn test_parse_ore_legacy() { assert!(idl.name.is_some(), "ore should have a name"); } +#[test] +fn test_ore_instructions_have_discriminators() { + // Test that ore.json instructions have proper discriminators when parsed as IdlSnapshot + // This tests the fix for Steel-style discriminant format + let idl_json = fs::read_to_string(fixture_path("ore.json")).expect("should read ore.json"); + let snapshot: IdlSnapshot = + serde_json::from_str(&idl_json).expect("should parse as IdlSnapshot"); + + assert_eq!( + snapshot.instructions.len(), + 19, + "ore should have 19 instructions" + ); + + // All instructions should have non-empty discriminators via get_discriminator() + let empty_count = snapshot + .instructions + .iter() + .filter(|ix| ix.get_discriminator().is_empty()) + .count(); + + assert_eq!( + empty_count, 0, + "All ore instructions should have discriminators computed from discriminant field" + ); + + // Verify specific instruction + let automate = snapshot + .instructions + .iter() + .find(|ix| ix.name == "automate") + .expect("should find automate instruction"); + + assert_eq!( + automate.get_discriminator(), + vec![0, 0, 0, 0, 0, 0, 0, 0], + "automate instruction should have discriminator [0,0,0,0,0,0,0,0]" + ); + + // Verify program_id is parsed from address field (using original IDL, not fixture) + let original_idl_json = fs::read_to_string( + "/Users/adrian/code/defi/hypertek/hyperstack-oss/stacks/ore/idl/ore.json", + ) + .expect("should read original ore.json"); + let original_snapshot: IdlSnapshot = + serde_json::from_str(&original_idl_json).expect("should parse original as IdlSnapshot"); + + assert_eq!( + original_snapshot.program_id, + Some("oreV3EG1i9BEgiAJ8b177Z2S2rMarzak4NMv1kULvWv".to_string()), + "program_id should be parsed from address field" + ); + + // Verify discriminant_size is 1 for Steel-style + // Note: This will fail until the fix is applied in hyperstack-debug + // The default is 8, but it should be detected as 1 for Steel-style + println!( + "Ore discriminant_size (before fix): {}", + original_snapshot.discriminant_size + ); +} + #[test] fn test_parse_entropy_legacy() { let idl = parse_idl_file(&fixture_path("entropy.json")).expect("should parse entropy.json"); diff --git a/hyperstack-macros/src/ast/writer.rs b/hyperstack-macros/src/ast/writer.rs index fc3d513a..7ae07654 100644 --- a/hyperstack-macros/src/ast/writer.rs +++ b/hyperstack-macros/src/ast/writer.rs @@ -230,6 +230,21 @@ pub fn convert_idl_to_snapshot(idl: &idl_parser::IdlSpec) -> IdlSnapshot { discriminator: acc.get_discriminator(), docs: acc.docs.clone(), serialization, + // Extract fields from inline type definition if present + fields: acc.type_def.as_ref().map_or_else( + Vec::new, + |type_def| match type_def { + idl_parser::IdlTypeDefKind::Struct { fields, .. } => fields + .iter() + .map(|f| IdlFieldSnapshot { + name: f.name.clone(), + type_: convert_idl_type(&f.type_), + }) + .collect(), + _ => Vec::new(), + }, + ), + type_def: None, // Fields are extracted above, no need to keep type_def } }) .collect(), @@ -239,6 +254,7 @@ pub fn convert_idl_to_snapshot(idl: &idl_parser::IdlSpec) -> IdlSnapshot { .map(|instr| IdlInstructionSnapshot { name: instr.name.clone(), discriminator: instr.get_discriminator(), + discriminant: None, docs: instr.docs.clone(), accounts: instr .accounts diff --git a/hyperstack-macros/src/codegen/computed.rs b/hyperstack-macros/src/codegen/computed.rs index a363bd2b..274510dd 100644 --- a/hyperstack-macros/src/codegen/computed.rs +++ b/hyperstack-macros/src/codegen/computed.rs @@ -451,13 +451,16 @@ pub fn generate_computed_expr_code(expr: &ComputedExpr) -> TokenStream { let param_ident = format_ident!("{}", param); if contains_resolver_computed(body) { + // For closures with resolver calls, pass the element as JSON value + // and let the resolver extract what it needs let body_code = generate_option_safe_expr_code(body); return quote! { #inner.as_ref().and_then(|v| { v.as_array().map(|arr| { arr.iter() .filter_map(|elem| { - let #param_ident = elem.as_f64()?; + // Pass element as serde_json::Value for resolvers + let #param_ident = elem; #body_code }) .collect::>() @@ -762,17 +765,14 @@ pub fn generate_computed_expr_code_with_cache( return quote! { { let inner_result = #inner_code; - hyperstack::runtime::tracing::debug!(inner = ?inner_result, "[COMPUTED] Inner value before map"); // Handle both arrays (Vec) and single values (u64) let map_result: Option = inner_result.and_then(|v| { if let Some(arr) = v.as_array() { // Handle array: map over each element - hyperstack::runtime::tracing::debug!(array_len = arr.len(), "[COMPUTED] Mapping over array"); let mapped: Vec<_> = arr .iter() .filter_map(|elem| { elem.as_u64().and_then(|#param_ident| { - hyperstack::runtime::tracing::debug!(elem = #param_ident, "[COMPUTED] Processing array element"); let result = #body_code; hyperstack::runtime::serde_json::to_value(result).ok() }) @@ -782,13 +782,11 @@ pub fn generate_computed_expr_code_with_cache( } else { // Handle single value v.as_u64().and_then(|#param_ident| { - hyperstack::runtime::tracing::debug!(value = #param_ident, "[COMPUTED] Processing single value"); let result = #body_code; hyperstack::runtime::serde_json::to_value(result).ok() }) } }); - hyperstack::runtime::tracing::debug!(result = ?map_result, "[COMPUTED] Map operation result"); map_result } }; diff --git a/hyperstack-macros/src/stream_spec/entity.rs b/hyperstack-macros/src/stream_spec/entity.rs index b489534a..80da9d67 100644 --- a/hyperstack-macros/src/stream_spec/entity.rs +++ b/hyperstack-macros/src/stream_spec/entity.rs @@ -1027,23 +1027,12 @@ fn generate_computed_fields_hook( quote! { // Evaluate: #field_name - hyperstack::runtime::tracing::info!( - section = #section_str, - field = #field_str, - "[COMPUTED] Evaluating computed field" - ); let computed_value = { // state is the full entity JSON state (for cross-section references) let state = §ion_parent_state; #expr_code }; let serialized_value = hyperstack::runtime::serde_json::to_value(&computed_value)?; - hyperstack::runtime::tracing::info!( - section = #section_str, - field = #field_str, - value = %serialized_value, - "[COMPUTED] Computed field result" - ); // Update cache so dependent fields can read this value computed_cache.insert(#field_str.to_string(), serialized_value.clone()); section_obj.insert(#field_str.to_string(), serialized_value); diff --git a/interpreter/src/compiler.rs b/interpreter/src/compiler.rs index 863d0c3b..7c169438 100644 --- a/interpreter/src/compiler.rs +++ b/interpreter/src/compiler.rs @@ -1243,6 +1243,16 @@ impl TypedCompiler { lookup_value: lookup_reg, dest: result_reg, }); + // CRITICAL: For Lookup resolution, we ONLY use the lookup result. + // If the lookup fails (result_reg is null), the mutation will be skipped. + // We do NOT fall back to __resolved_primary_key or the raw lookup value, + // because that would create a separate entity with the wrong key. + // The resolver-provided key (e.g., PDA address) is only used as the lookup input, + // NOT as the entity key. The entity key must come from the lookup index. + ops.push(OpCode::CopyRegister { + source: result_reg, + dest: key_reg, + }); // NOTE: We intentionally do NOT fall back to lookup_reg when LookupIndex returns null. // If the lookup fails (because the RoundState account hasn't been processed yet), // the result_reg will remain null, and the mutation will be skipped. diff --git a/rust/hyperstack-server/src/sorted_cache.rs b/rust/hyperstack-server/src/sorted_cache.rs index e29f488c..fb3659b6 100644 --- a/rust/hyperstack-server/src/sorted_cache.rs +++ b/rust/hyperstack-server/src/sorted_cache.rs @@ -229,6 +229,7 @@ impl SortedViewCache { self.cache_dirty = true; let position = self.find_position(&entity_key); + UpsertResult::Inserted { position } } diff --git a/rust/hyperstack-server/src/view/spec.rs b/rust/hyperstack-server/src/view/spec.rs index 1fdbfe4f..490a06f9 100644 --- a/rust/hyperstack-server/src/view/spec.rs +++ b/rust/hyperstack-server/src/view/spec.rs @@ -1,5 +1,6 @@ use crate::materialized_view::{CompareOp, FilterConfig, SortConfig, SortOrder, ViewPipeline}; use crate::websocket::frame::Mode; +use tracing; // # View System Architecture // diff --git a/rust/hyperstack-server/src/websocket/server.rs b/rust/hyperstack-server/src/websocket/server.rs index 53e951ca..a3fce0dc 100644 --- a/rust/hyperstack-server/src/websocket/server.rs +++ b/rust/hyperstack-server/src/websocket/server.rs @@ -838,6 +838,7 @@ async fn attach_derived_view_subscription_otel( data: data.clone(), append: vec![], }; + if let Ok(json) = serde_json::to_vec(&frame) { let payload = Arc::new(Bytes::from(json)); if client_mgr.send_to_client(client_id, payload).is_err() { From 3d8d5d3de72e74965b310bdda9c0227be2fc8825 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Tue, 17 Mar 2026 18:18:06 +0000 Subject: [PATCH 15/60] fix: Ore react --- examples/ore-react/src/components/OreDashboard.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/ore-react/src/components/OreDashboard.tsx b/examples/ore-react/src/components/OreDashboard.tsx index 84a4a4a5..769a5f1d 100644 --- a/examples/ore-react/src/components/OreDashboard.tsx +++ b/examples/ore-react/src/components/OreDashboard.tsx @@ -7,8 +7,8 @@ import { ConnectionBadge } from './ConnectionBadge'; import { ThemeToggle } from './ThemeToggle'; export function OreDashboard() { - const { views, isConnected } = useHyperstack(ORE_STREAM_STACK, { url: 'http://localhost:8878' }); - const { data: latestRound } = views.OreRound.latest.useOne(); + const { views, isConnected } = useHyperstack(ORE_STREAM_STACK); + const { data: latestRound } = views.OreRound.latest.useOne({ schema: ValidatedOreRoundSchema }); const { data: treasuryData } = views.OreTreasury.list.useOne(); return ( From 42460d2c2cf5dbb582da78e73100ab42b6213786 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Wed, 18 Mar 2026 20:30:52 +0000 Subject: [PATCH 16/60] fix: keep gRPC subscription sender alive to prevent stream termination --- hyperstack-macros/src/codegen/vixen_runtime.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hyperstack-macros/src/codegen/vixen_runtime.rs b/hyperstack-macros/src/codegen/vixen_runtime.rs index fda18412..718c69d7 100644 --- a/hyperstack-macros/src/codegen/vixen_runtime.rs +++ b/hyperstack-macros/src/codegen/vixen_runtime.rs @@ -365,9 +365,11 @@ fn generate_slot_subscription_task() -> TokenStream { from_slot: None, }; - let (_sub_tx, mut stream) = client + let (sub_tx, mut stream) = client .subscribe_with_request(Some(subscribe_request)) .await?; + // Keep sender alive for the duration of the stream + let _keep_alive = sub_tx; hyperstack::runtime::tracing::info!("[SLOT_SUB] Connected and subscribed to slot and SlotHashes updates"); From f39158107e551a544bb610ca4a8d7a59e81f6460 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Wed, 18 Mar 2026 20:34:32 +0000 Subject: [PATCH 17/60] fix(tests): replace diagnostic println with assertion for discriminant_size --- hyperstack-idl/tests/parse_fixtures.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/hyperstack-idl/tests/parse_fixtures.rs b/hyperstack-idl/tests/parse_fixtures.rs index 2906cc29..c7b5d4b0 100644 --- a/hyperstack-idl/tests/parse_fixtures.rs +++ b/hyperstack-idl/tests/parse_fixtures.rs @@ -59,13 +59,11 @@ fn test_ore_instructions_have_discriminators() { "automate instruction should have discriminator [0,0,0,0,0,0,0,0]" ); - // Verify program_id is parsed from address field (using original IDL, not fixture) - let original_idl_json = fs::read_to_string( - "/Users/adrian/code/defi/hypertek/hyperstack-oss/stacks/ore/idl/ore.json", - ) - .expect("should read original ore.json"); + // Verify program_id is parsed from address field (using ore.json fixture) + let original_idl_json = + fs::read_to_string(fixture_path("ore.json")).expect("should read ore.json"); let original_snapshot: IdlSnapshot = - serde_json::from_str(&original_idl_json).expect("should parse original as IdlSnapshot"); + serde_json::from_str(&original_idl_json).expect("should parse ore.json as IdlSnapshot"); assert_eq!( original_snapshot.program_id, @@ -73,12 +71,9 @@ fn test_ore_instructions_have_discriminators() { "program_id should be parsed from address field" ); - // Verify discriminant_size is 1 for Steel-style - // Note: This will fail until the fix is applied in hyperstack-debug - // The default is 8, but it should be detected as 1 for Steel-style - println!( - "Ore discriminant_size (before fix): {}", - original_snapshot.discriminant_size + assert_eq!( + original_snapshot.discriminant_size, 1, + "Steel-style IDL should use 1-byte discriminants" ); } From 7da11f71e70f2c8a1150f8cc3463c3b4ffa8cd27 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Wed, 18 Mar 2026 20:36:52 +0000 Subject: [PATCH 18/60] fix: restore type safety in ore-typescript example --- examples/ore-typescript/src/main.ts | 35 +++++++++++++---------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/examples/ore-typescript/src/main.ts b/examples/ore-typescript/src/main.ts index 57113acc..a248a0be 100644 --- a/examples/ore-typescript/src/main.ts +++ b/examples/ore-typescript/src/main.ts @@ -2,23 +2,21 @@ import { z } from 'zod'; import { HyperStack } from 'hyperstack-typescript'; import { ORE_STREAM_STACK, - // OreRoundSchema, - // OreRoundIdSchema, - // OreTreasurySchema, - // OreTreasuryIdSchema, + OreRoundSchema, + OreRoundIdSchema, + OreTreasurySchema, + OreTreasuryIdSchema, } from 'hyperstack-stacks/ore'; -// const OreRoundWithIdSchema = OreRoundSchema.extend({ -// id: OreRoundIdSchema.required(), -// }); -// -// const OreTreasuryWithIdSchema = OreTreasurySchema.extend({ -// id: OreTreasuryIdSchema.required(), -// }); -// type OreRoundWithId = z.infer; -// type OreTreasuryWithId = z.infer; -type OreRoundWithId = any; -type OreTreasuryWithId = any; +const OreRoundWithIdSchema = OreRoundSchema.extend({ + id: OreRoundIdSchema.partial(), +}); + +const OreTreasuryWithIdSchema = OreTreasurySchema.extend({ + id: OreTreasuryIdSchema.partial(), +}); +type OreRoundWithId = z.infer; +type OreTreasuryWithId = z.infer; function printRound(round: OreRoundWithId) { console.log(`\n=== Round #${round.id.round_id ?? 'N/A'} ===`); @@ -49,17 +47,16 @@ async function main() { const streamRounds = async () => { for await (const round of hs.views.OreRound.latest.use({ take: 1, - // schema: OreRoundWithIdSchema, + schema: OreRoundWithIdSchema, })) { - console.log(round); - // printRound(round); + printRound(round); } }; const streamTreasury = async () => { for await (const treasury of hs.views.OreTreasury.list.use({ take: 1, - // schema: OreTreasuryWithIdSchema, + schema: OreTreasuryWithIdSchema, })) { printTreasury(treasury); } From d1a788750d095af2a837b713795d3ecb5b836b3c Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Wed, 18 Mar 2026 20:41:54 +0000 Subject: [PATCH 19/60] refactor: remove redundant CpiEvent check in AbortIfNullKey The condition `!event_type.ends_with(CpiEvent)` was logically redundant since the outer check `event_type.ends_with(State)` already guarantees the string cannot end with CpiEvent. --- interpreter/src/vm.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/interpreter/src/vm.rs b/interpreter/src/vm.rs index ac8ecb96..4ccd00f9 100644 --- a/interpreter/src/vm.rs +++ b/interpreter/src/vm.rs @@ -2009,7 +2009,6 @@ impl VmContext { if key_value.is_null() && event_type.ends_with("State") && !event_type.ends_with("IxState") - && !event_type.ends_with("CpiEvent") { tracing::debug!( event_type = %event_type, From 94249badb4a1a1d0af860048c8ca1bc758818c7b Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Wed, 18 Mar 2026 20:43:08 +0000 Subject: [PATCH 20/60] fix: use BTreeMap for slot hash cache to ensure oldest entries are evicted --- interpreter/src/slot_hash_cache.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/interpreter/src/slot_hash_cache.rs b/interpreter/src/slot_hash_cache.rs index 1bb5852e..203aa517 100644 --- a/interpreter/src/slot_hash_cache.rs +++ b/interpreter/src/slot_hash_cache.rs @@ -3,20 +3,20 @@ //! This module provides a global cache for slot hashes that is populated //! by the gRPC stream and accessed by computed field resolvers. -use std::collections::HashMap; +use std::collections::BTreeMap; use std::sync::Arc; use tokio::sync::RwLock; /// Global slot hash cache -static SLOT_HASH_CACHE: once_cell::sync::Lazy>>> = - once_cell::sync::Lazy::new(|| Arc::new(RwLock::new(HashMap::new()))); +static SLOT_HASH_CACHE: once_cell::sync::Lazy>>> = + once_cell::sync::Lazy::new(|| Arc::new(RwLock::new(BTreeMap::new()))); /// Maximum number of slot hashes to keep in cache (prevent unbounded growth) const MAX_CACHE_SIZE: usize = 50000; /// Record a slot hash in the global cache pub async fn record_slot_hash(slot: u64, slot_hash: String) { - let mut cache: tokio::sync::RwLockWriteGuard<'_, HashMap> = SLOT_HASH_CACHE.write().await; + let mut cache: tokio::sync::RwLockWriteGuard<'_, BTreeMap> = SLOT_HASH_CACHE.write().await; cache.insert(slot, slot_hash); // Prune old entries if cache is too large @@ -35,13 +35,13 @@ pub async fn record_slot_hash(slot: u64, slot_hash: String) { /// Get a slot hash from the global cache pub async fn get_slot_hash(slot: u64) -> Option { - let cache: tokio::sync::RwLockReadGuard<'_, HashMap> = SLOT_HASH_CACHE.read().await; + let cache: tokio::sync::RwLockReadGuard<'_, BTreeMap> = SLOT_HASH_CACHE.read().await; cache.get(&slot).cloned() } /// Check if a slot hash is in the cache pub async fn has_slot_hash(slot: u64) -> bool { - let cache: tokio::sync::RwLockReadGuard<'_, HashMap> = SLOT_HASH_CACHE.read().await; + let cache: tokio::sync::RwLockReadGuard<'_, BTreeMap> = SLOT_HASH_CACHE.read().await; cache.contains_key(&slot) } From c8b26d58f62041cb7c5fe1624f5313f63a9ef9d9 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Wed, 18 Mar 2026 23:35:38 +0000 Subject: [PATCH 21/60] fix: implement discriminant size inference and fix test failures - Add missing fields to IdlAccountSnapshot test initialization - Implement automatic discriminant size detection based on instruction format - Add address field to ore.json fixture for IdlSnapshot compatibility - Remove non-standard discriminant_size field from ore.json --- hyperstack-idl/src/snapshot.rs | 76 ++++++++++++++++++++++++-- hyperstack-idl/tests/fixtures/ore.json | 1 + 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/hyperstack-idl/src/snapshot.rs b/hyperstack-idl/src/snapshot.rs index 9c7d4e1a..e9124470 100644 --- a/hyperstack-idl/src/snapshot.rs +++ b/hyperstack-idl/src/snapshot.rs @@ -1,10 +1,10 @@ //! Snapshot type definitions -use serde::{de::Error, Deserialize, Deserializer, Serialize}; +use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize}; use crate::types::SteelDiscriminant; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize)] pub struct IdlSnapshot { pub name: String, #[serde(default, skip_serializing_if = "Option::is_none", alias = "address")] @@ -18,12 +18,73 @@ pub struct IdlSnapshot { pub events: Vec, #[serde(default)] pub errors: Vec, - #[serde(default = "default_discriminant_size")] pub discriminant_size: usize, } -fn default_discriminant_size() -> usize { - 8 +impl<'de> Deserialize<'de> for IdlSnapshot { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // First deserialize to a generic Value to inspect instructions + let value = serde_json::Value::deserialize(deserializer)?; + + // Check if any instruction has discriminant (Steel-style) vs discriminator (Anchor-style) + let discriminant_size = value + .get("instructions") + .and_then(|instrs| instrs.as_array()) + .map(|instrs| { + instrs.iter().any(|ix| { + // Steel-style: has discriminant field, no discriminator or empty discriminator + let has_discriminant = ix.get("discriminant").is_some(); + let discriminator = ix.get("discriminator"); + let has_discriminator = discriminator + .map(|d| { + !d.is_null() && d.as_array().map(|a| !a.is_empty()).unwrap_or(true) + }) + .unwrap_or(false); + has_discriminant && !has_discriminator + }) + }) + .map(|is_steel| if is_steel { 1 } else { 8 }) + .unwrap_or(8); // Default to 8 if no instructions + + // Now deserialize the full struct + let mut intermediate: IdlSnapshotIntermediate = serde_json::from_value(value) + .map_err(|e| DeError::custom(format!("Failed to deserialize IDL: {}", e)))?; + intermediate.discriminant_size = discriminant_size; + + Ok(IdlSnapshot { + name: intermediate.name, + program_id: intermediate.program_id, + version: intermediate.version, + accounts: intermediate.accounts, + instructions: intermediate.instructions, + types: intermediate.types, + events: intermediate.events, + errors: intermediate.errors, + discriminant_size: intermediate.discriminant_size, + }) + } +} + +// Intermediate struct for deserialization +#[derive(Debug, Clone, Deserialize)] +struct IdlSnapshotIntermediate { + pub name: String, + #[serde(default, alias = "address")] + pub program_id: Option, + pub version: String, + pub accounts: Vec, + pub instructions: Vec, + #[serde(default)] + pub types: Vec, + #[serde(default)] + pub events: Vec, + #[serde(default)] + pub errors: Vec, + #[serde(default)] + pub discriminant_size: usize, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -124,6 +185,7 @@ fn deserialize_hash_map<'de, D>( where D: Deserializer<'de>, { + use serde::de::Error; let values: Vec = Vec::deserialize(deserializer)?; if values.len() != 2 { return Err(D::Error::custom("hashMap must have exactly 2 elements")); @@ -243,6 +305,8 @@ mod tests { discriminator: vec![1, 2, 3, 4, 5, 6, 7, 8], docs: vec!["Example account".to_string()], serialization: Some(IdlSerializationSnapshot::Borsh), + fields: vec![], + type_def: None, }], instructions: vec![IdlInstructionSnapshot { name: "example_instruction".to_string(), @@ -289,7 +353,7 @@ mod tests { name: "ExampleError".to_string(), msg: Some("example".to_string()), }], - discriminant_size: default_discriminant_size(), + discriminant_size: 8, }; let serialized = serde_json::to_value(&snapshot).expect("serialize snapshot"); diff --git a/hyperstack-idl/tests/fixtures/ore.json b/hyperstack-idl/tests/fixtures/ore.json index e4485200..41bdd617 100644 --- a/hyperstack-idl/tests/fixtures/ore.json +++ b/hyperstack-idl/tests/fixtures/ore.json @@ -1,6 +1,7 @@ { "version": "3.7.22", "name": "ore", + "address": "oreV3EG1i9BEgiAJ8b177Z2S2rMarzak4NMv1kULvWv", "instructions": [ { "name": "automate", From 32bc6325ce4fec41f274dc0d9610eac60f2442d6 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Wed, 18 Mar 2026 23:38:57 +0000 Subject: [PATCH 22/60] chore: Update ore sdk --- stacks/sdk/typescript/src/ore/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stacks/sdk/typescript/src/ore/index.ts b/stacks/sdk/typescript/src/ore/index.ts index 5b782096..e629bc19 100644 --- a/stacks/sdk/typescript/src/ore/index.ts +++ b/stacks/sdk/typescript/src/ore/index.ts @@ -8,7 +8,6 @@ export interface OreRoundEntropy { entropy_start_at?: number | null; entropy_value?: string | null; entropy_var_address?: string | null; - expires_at?: number | null; resolved_seed?: any[] | null; } @@ -24,6 +23,7 @@ export interface OreRoundMetrics { export interface OreRoundResults { did_hit_motherlode?: boolean | null; + expires_at_slot_hash?: any[] | null; pre_reveal_rng?: number | null; pre_reveal_winning_square?: number | null; rent_payer?: string | null; @@ -85,7 +85,6 @@ export const OreRoundEntropySchema = z.object({ entropy_start_at: z.number().nullable().optional(), entropy_value: z.string().nullable().optional(), entropy_var_address: z.string().nullable().optional(), - expires_at: z.number().nullable().optional(), resolved_seed: z.array(z.any()).nullable().optional(), }); @@ -101,6 +100,7 @@ export const OreRoundMetricsSchema = z.object({ export const OreRoundResultsSchema = z.object({ did_hit_motherlode: z.boolean().nullable().optional(), + expires_at_slot_hash: z.array(z.any()).nullable().optional(), pre_reveal_rng: z.number().nullable().optional(), pre_reveal_winning_square: z.number().nullable().optional(), rent_payer: z.string().nullable().optional(), From c19d1ec5926ee9099c6ab4254bde30b2c794e27f Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 01:08:02 +0000 Subject: [PATCH 23/60] fix: resolve clippy warnings across workspace - Remove unused imports in hyperstack-macros and hyperstack-server - Fix empty else branch in vm.rs - Remove unused variables in scheduler.rs and vm.rs - Fix let-and-return pattern in VmContext::new_multi_entity() - Add #[allow(clippy::type_complexity)] for complex entity_evaluator type --- hyperstack-macros/src/codegen/mod.rs | 1 - interpreter/src/scheduler.rs | 4 +--- interpreter/src/vm.rs | 12 +++++------- rust/hyperstack-server/src/view/spec.rs | 1 - 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/hyperstack-macros/src/codegen/mod.rs b/hyperstack-macros/src/codegen/mod.rs index e3fd4004..74d70b81 100644 --- a/hyperstack-macros/src/codegen/mod.rs +++ b/hyperstack-macros/src/codegen/mod.rs @@ -19,7 +19,6 @@ pub(crate) mod vixen_runtime; // Internal re-exports for use within this crate only pub(crate) use bytecode::generate_bytecode_from_spec; pub(crate) use computed::generate_computed_evaluator; -pub(crate) use computed::generate_computed_expr_code; pub(crate) use computed::generate_computed_expr_code_with_cache; pub(crate) use field_accessors::generate_field_accessors; pub(crate) use handlers::generate_handlers_from_specs; diff --git a/interpreter/src/scheduler.rs b/interpreter/src/scheduler.rs index 0db9ef86..9d286433 100644 --- a/interpreter/src/scheduler.rs +++ b/interpreter/src/scheduler.rs @@ -53,9 +53,7 @@ impl SlotScheduler { let due = std::mem::replace(&mut self.callbacks, future); let mut result = Vec::new(); - let mut total_count = 0; - for (slot, callbacks) in due { - total_count += callbacks.len(); + for (_slot, callbacks) in due { for cb in callbacks { let dedup_key = Self::dedup_key(&cb); self.registered.remove(&dedup_key); diff --git a/interpreter/src/vm.rs b/interpreter/src/vm.rs index 4ccd00f9..59a3aa88 100644 --- a/interpreter/src/vm.rs +++ b/interpreter/src/vm.rs @@ -1019,7 +1019,7 @@ impl VmContext { /// Create a new VmContext specifically for multi-entity operation. pub fn new_multi_entity() -> Self { - let vm = VmContext { + VmContext { registers: vec![Value::Null; 32], states: HashMap::new(), instructions_executed: 0, @@ -1043,9 +1043,7 @@ impl VmContext { last_pda_registered: None, last_lookup_index_keys: Vec::new(), scheduled_callbacks: Vec::new(), - }; - - vm + } } pub fn new_with_config(state_config: StateTableConfig) -> Self { @@ -2015,8 +2013,8 @@ impl VmContext { "AbortIfNullKey: key is null for account state event, \ returning empty mutations for queueing" ); - return Ok(Vec::new()); } + pc += 1; } OpCode::ReadOrInitState { @@ -2783,7 +2781,7 @@ impl VmContext { let actual_state_id = override_state_id; // Log what triggered this resolver - let trigger_info = if let Some(ref ctx) = self.current_context { + let _trigger_info = if let Some(ref ctx) = self.current_context { if let Some(ref sig) = ctx.signature { format!( "instruction (slot={}, sig={})", @@ -2937,7 +2935,6 @@ impl VmContext { target, ); } - } else { } pc += 1; @@ -3589,6 +3586,7 @@ impl VmContext { false } + #[allow(clippy::type_complexity)] fn apply_deferred_when_op( &mut self, state_id: u32, diff --git a/rust/hyperstack-server/src/view/spec.rs b/rust/hyperstack-server/src/view/spec.rs index 490a06f9..1fdbfe4f 100644 --- a/rust/hyperstack-server/src/view/spec.rs +++ b/rust/hyperstack-server/src/view/spec.rs @@ -1,6 +1,5 @@ use crate::materialized_view::{CompareOp, FilterConfig, SortConfig, SortOrder, ViewPipeline}; use crate::websocket::frame::Mode; -use tracing; // # View System Architecture // From 8d983597d021c0617f6b8efb27e010d5d03cd277 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 02:45:46 +0000 Subject: [PATCH 24/60] fix: add missing return to AbortIfNullKey opcode The opcode was logging a debug message but falling through to continue execution instead of returning early. This caused phantom entities to be created with null keys and prevented events from being queued for reprocessing. Added the missing `return Ok(Vec::new())` to properly abort execution when the abort condition is met. --- interpreter/src/vm.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interpreter/src/vm.rs b/interpreter/src/vm.rs index 59a3aa88..749f4bee 100644 --- a/interpreter/src/vm.rs +++ b/interpreter/src/vm.rs @@ -1020,7 +1020,7 @@ impl VmContext { /// Create a new VmContext specifically for multi-entity operation. pub fn new_multi_entity() -> Self { VmContext { - registers: vec![Value::Null; 32], + registers: vec![Value::Null; 256], states: HashMap::new(), instructions_executed: 0, cache_hits: 0, @@ -2013,6 +2013,7 @@ impl VmContext { "AbortIfNullKey: key is null for account state event, \ returning empty mutations for queueing" ); + return Ok(Vec::new()); } pc += 1; From f1a6755ed16c64b9931c94e8b5c40315369cfda4 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 02:59:00 +0000 Subject: [PATCH 25/60] refactor: remove application-specific debug logging from generic VM Remove hardcoded ore::RoundState event type check from the generic is_fresh_update method. This debug logging coupled the VM layer to the Ore-specific stack, which could silently affect future stacks using similar event type prefixes. --- interpreter/src/vm.rs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/interpreter/src/vm.rs b/interpreter/src/vm.rs index 749f4bee..88af73c7 100644 --- a/interpreter/src/vm.rs +++ b/interpreter/src/vm.rs @@ -905,21 +905,7 @@ impl StateTable { let dominated = self .version_tracker .get(primary_key, event_type) - .map(|(last_slot, last_version)| { - let is_stale = (slot, ordering_value) <= (last_slot, last_version); - if is_stale && event_type == "ore::RoundState" { - tracing::debug!( - entity_key = %primary_key, - event_type = %event_type, - current_slot = slot, - current_write_version = ordering_value, - last_slot = last_slot, - last_write_version = last_version, - "RoundState recency check: stale update detected" - ); - } - is_stale - }) + .map(|(last_slot, last_version)| (slot, ordering_value) <= (last_slot, last_version)) .unwrap_or(false); if dominated { From 3525397a8adec127ac261b1c6e6cab2617f1217b Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 03:05:52 +0000 Subject: [PATCH 26/60] fix: prevent panic in SlotHash resolver when using current_thread runtime Replace tokio::sync::RwLock with std::sync::RwLock in slot_hash_cache, making the cache functions synchronous. This eliminates the need for tokio::task::block_in_place which panics on current_thread runtimes. Fixes issue where tests using #[tokio::test] would panic when the SlotHash resolver was invoked. --- .../src/codegen/vixen_runtime.rs | 2 +- interpreter/src/resolvers.rs | 21 ++--------- interpreter/src/slot_hash_cache.rs | 37 ++++++++----------- 3 files changed, 20 insertions(+), 40 deletions(-) diff --git a/hyperstack-macros/src/codegen/vixen_runtime.rs b/hyperstack-macros/src/codegen/vixen_runtime.rs index 718c69d7..bb953a37 100644 --- a/hyperstack-macros/src/codegen/vixen_runtime.rs +++ b/hyperstack-macros/src/codegen/vixen_runtime.rs @@ -293,7 +293,7 @@ fn generate_slot_subscription_task() -> TokenStream { ]); let hash_bytes = &data[offset + 8..offset + 40]; let hash = hyperstack::runtime::bs58::encode(hash_bytes).into_string(); - hyperstack::runtime::hyperstack_interpreter::record_slot_hash(slot, hash).await; + hyperstack::runtime::hyperstack_interpreter::record_slot_hash(slot, hash); hyperstack::runtime::tracing::debug!(slot = slot, current_slot = current_slot, "[SLOT_SUB] Cached slot hash"); } Ok(()) diff --git a/interpreter/src/resolvers.rs b/interpreter/src/resolvers.rs index 617f571f..4cf3bbbb 100644 --- a/interpreter/src/resolvers.rs +++ b/interpreter/src/resolvers.rs @@ -820,13 +820,7 @@ impl SlotHashResolver { } // Try to get the slot hash from the global cache - // Note: This runs in an async context but the resolver interface is sync - // We use block_in_place to avoid blocking the runtime - let slot_hash = tokio::task::block_in_place(|| { - tokio::runtime::Handle::current().block_on(async { - crate::slot_hash_cache::get_slot_hash(slot).await - }) - }); + let slot_hash = crate::slot_hash_cache::get_slot_hash(slot); match slot_hash { Some(hash) => { @@ -878,20 +872,11 @@ impl ResolverDefinition for SlotHashResolver { } fn typescript_interface(&self) -> Option<&'static str> { - Some( - r#"export interface SlotHash { - hash: string; -}"#, - ) + None } fn typescript_schema(&self) -> Option { - Some(ResolverTypeScriptSchema { - name: "SlotHashSchema", - definition: r#"export const SlotHashSchema = z.object({ - hash: z.string(), -});"#, - }) + None } } diff --git a/interpreter/src/slot_hash_cache.rs b/interpreter/src/slot_hash_cache.rs index 203aa517..17cd2273 100644 --- a/interpreter/src/slot_hash_cache.rs +++ b/interpreter/src/slot_hash_cache.rs @@ -1,11 +1,10 @@ //! Shared slot hash cache accessible from both server and interpreter -//! +//! //! This module provides a global cache for slot hashes that is populated //! by the gRPC stream and accessed by computed field resolvers. use std::collections::BTreeMap; -use std::sync::Arc; -use tokio::sync::RwLock; +use std::sync::{Arc, RwLock}; /// Global slot hash cache static SLOT_HASH_CACHE: once_cell::sync::Lazy>>> = @@ -15,18 +14,14 @@ static SLOT_HASH_CACHE: once_cell::sync::Lazy>> const MAX_CACHE_SIZE: usize = 50000; /// Record a slot hash in the global cache -pub async fn record_slot_hash(slot: u64, slot_hash: String) { - let mut cache: tokio::sync::RwLockWriteGuard<'_, BTreeMap> = SLOT_HASH_CACHE.write().await; +pub fn record_slot_hash(slot: u64, slot_hash: String) { + let mut cache = SLOT_HASH_CACHE.write().expect("RwLock poisoned"); cache.insert(slot, slot_hash); - + // Prune old entries if cache is too large if cache.len() > MAX_CACHE_SIZE { // Remove oldest 25% of entries - let slots_to_remove: Vec = cache - .keys() - .take(cache.len() / 4) - .copied() - .collect(); + let slots_to_remove: Vec = cache.keys().take(cache.len() / 4).copied().collect(); for slot in slots_to_remove { cache.remove(&slot); } @@ -34,14 +29,14 @@ pub async fn record_slot_hash(slot: u64, slot_hash: String) { } /// Get a slot hash from the global cache -pub async fn get_slot_hash(slot: u64) -> Option { - let cache: tokio::sync::RwLockReadGuard<'_, BTreeMap> = SLOT_HASH_CACHE.read().await; +pub fn get_slot_hash(slot: u64) -> Option { + let cache = SLOT_HASH_CACHE.read().expect("RwLock poisoned"); cache.get(&slot).cloned() } /// Check if a slot hash is in the cache -pub async fn has_slot_hash(slot: u64) -> bool { - let cache: tokio::sync::RwLockReadGuard<'_, BTreeMap> = SLOT_HASH_CACHE.read().await; +pub fn has_slot_hash(slot: u64) -> bool { + let cache = SLOT_HASH_CACHE.read().expect("RwLock poisoned"); cache.contains_key(&slot) } @@ -49,10 +44,10 @@ pub async fn has_slot_hash(slot: u64) -> bool { mod tests { use super::*; - #[tokio::test] - async fn test_slot_hash_cache() { - record_slot_hash(100, "test_hash".to_string()).await; - assert_eq!(get_slot_hash(100).await, Some("test_hash".to_string())); - assert_eq!(get_slot_hash(101).await, None); + #[test] + fn test_slot_hash_cache() { + record_slot_hash(100, "test_hash".to_string()); + assert_eq!(get_slot_hash(100), Some("test_hash".to_string())); + assert_eq!(get_slot_hash(101), None); } -} \ No newline at end of file +} From 358d9bdc5f53ae1e888df9630885f1baeaaa22d1 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 03:08:59 +0000 Subject: [PATCH 27/60] fix: correct SlotHashResolver TypeScript types to match actual return values Replace incorrect { hash: string } interface with proper types: - SlotHashBytes: interface for 32-byte array returned by slot_hash - KeccakRngValue: type alias for u64 number returned by keccak_rng Add matching Zod schemas with validation for byte ranges. --- interpreter/src/resolvers.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/interpreter/src/resolvers.rs b/interpreter/src/resolvers.rs index 4cf3bbbb..83dea1d2 100644 --- a/interpreter/src/resolvers.rs +++ b/interpreter/src/resolvers.rs @@ -872,11 +872,25 @@ impl ResolverDefinition for SlotHashResolver { } fn typescript_interface(&self) -> Option<&'static str> { - None + Some( + r#"export interface SlotHashBytes { + /** 32-byte slot hash as array of numbers (0-255) */ + bytes: number[]; +} + +export type KeccakRngValue = number;"#, + ) } fn typescript_schema(&self) -> Option { - None + Some(ResolverTypeScriptSchema { + name: "SlotHashTypes", + definition: r#"export const SlotHashBytesSchema = z.object({ + bytes: z.array(z.number().int().min(0).max(255)).length(32), +}); + +export const KeccakRngValueSchema = z.number().int().min(0);"#, + }) } } From 4d283f2bd749690eb7b79e1c80e0447c79b35d8d Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 03:13:51 +0000 Subject: [PATCH 28/60] fix: align Steel discriminant size with get_discriminator return value Steel-style IDLs set discriminant_size = 1 but get_discriminator() was returning 8-byte vectors. Now returns single byte [value] for Steel discriminants, matching the declared size and preventing silent instruction matching bugs. --- hyperstack-idl/src/parse.rs | 10 ++-------- hyperstack-idl/src/snapshot.rs | 2 +- hyperstack-idl/src/types.rs | 2 +- hyperstack-idl/tests/parse_fixtures.rs | 4 ++-- interpreter/src/compiler.rs | 8 +++++++- interpreter/src/vm.rs | 10 +++++----- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/hyperstack-idl/src/parse.rs b/hyperstack-idl/src/parse.rs index bd6f1dc0..de90ff37 100644 --- a/hyperstack-idl/src/parse.rs +++ b/hyperstack-idl/src/parse.rs @@ -177,14 +177,8 @@ mod tests { }"#; let idl = parse_idl_content(json).unwrap(); - assert_eq!( - idl.instructions[0].get_discriminator(), - vec![0, 0, 0, 0, 0, 0, 0, 0] - ); - assert_eq!( - idl.instructions[1].get_discriminator(), - vec![1, 0, 0, 0, 0, 0, 0, 0] - ); + assert_eq!(idl.instructions[0].get_discriminator(), vec![0]); + assert_eq!(idl.instructions[1].get_discriminator(), vec![1]); } #[test] diff --git a/hyperstack-idl/src/snapshot.rs b/hyperstack-idl/src/snapshot.rs index e9124470..879f085f 100644 --- a/hyperstack-idl/src/snapshot.rs +++ b/hyperstack-idl/src/snapshot.rs @@ -133,7 +133,7 @@ impl IdlInstructionSnapshot { if let Some(disc) = &self.discriminant { let value = disc.value as u8; - return vec![value, 0, 0, 0, 0, 0, 0, 0]; + return vec![value]; } crate::discriminator::anchor_discriminator(&format!("global:{}", self.name)) diff --git a/hyperstack-idl/src/types.rs b/hyperstack-idl/src/types.rs index 6255ceef..870b74a3 100644 --- a/hyperstack-idl/src/types.rs +++ b/hyperstack-idl/src/types.rs @@ -78,7 +78,7 @@ impl IdlInstruction { if let Some(disc) = &self.discriminant { let value = disc.value as u8; - return vec![value, 0, 0, 0, 0, 0, 0, 0]; + return vec![value]; } crate::discriminator::anchor_discriminator(&format!("global:{}", self.name)) diff --git a/hyperstack-idl/tests/parse_fixtures.rs b/hyperstack-idl/tests/parse_fixtures.rs index c7b5d4b0..bd65d9d8 100644 --- a/hyperstack-idl/tests/parse_fixtures.rs +++ b/hyperstack-idl/tests/parse_fixtures.rs @@ -55,8 +55,8 @@ fn test_ore_instructions_have_discriminators() { assert_eq!( automate.get_discriminator(), - vec![0, 0, 0, 0, 0, 0, 0, 0], - "automate instruction should have discriminator [0,0,0,0,0,0,0,0]" + vec![0], + "automate instruction should have discriminator [0]" ); // Verify program_id is parsed from address field (using ore.json fixture) diff --git a/interpreter/src/compiler.rs b/interpreter/src/compiler.rs index 7c169438..e9484519 100644 --- a/interpreter/src/compiler.rs +++ b/interpreter/src/compiler.rs @@ -19,6 +19,7 @@ pub enum OpCode { /// process_event's miss-handling logic. AbortIfNullKey { key: Register, + is_account_event: bool, }, LoadEventField { path: FieldPath, @@ -678,7 +679,12 @@ impl TypedCompiler { // for later reprocessing. Without this, downstream opcodes would // create a phantom entity keyed by null and produce non-empty // mutations that prevent queueing. - ops.push(OpCode::AbortIfNullKey { key: key_reg }); + let event_type = self.get_event_type(&spec.source); + let is_account_event = event_type.ends_with("State") && !event_type.ends_with("IxState"); + ops.push(OpCode::AbortIfNullKey { + key: key_reg, + is_account_event, + }); ops.push(OpCode::ReadOrInitState { state_id: self.state_id, diff --git a/interpreter/src/vm.rs b/interpreter/src/vm.rs index 88af73c7..dfea9e89 100644 --- a/interpreter/src/vm.rs +++ b/interpreter/src/vm.rs @@ -1988,12 +1988,12 @@ impl VmContext { self.registers[*dest] = value; pc += 1; } - OpCode::AbortIfNullKey { key } => { + OpCode::AbortIfNullKey { + key, + is_account_event, + } => { let key_value = &self.registers[*key]; - if key_value.is_null() - && event_type.ends_with("State") - && !event_type.ends_with("IxState") - { + if key_value.is_null() && *is_account_event { tracing::debug!( event_type = %event_type, "AbortIfNullKey: key is null for account state event, \ From d67b727e3cb34f2f9eb66d75f15add86bc8dbbd6 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 03:34:11 +0000 Subject: [PATCH 29/60] fix: use dynamic-length discriminator slice in generated code Changed DISCRIMINATOR constant type from [u8; 8] to &'static [u8] to support both 1-byte Steel discriminants and 8-byte Anchor discriminants. Updated try_from_bytes() to use dynamic length checks and fixed slice comparison. --- hyperstack-macros/src/idl_codegen.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/hyperstack-macros/src/idl_codegen.rs b/hyperstack-macros/src/idl_codegen.rs index 1af60a39..96ec62fc 100644 --- a/hyperstack-macros/src/idl_codegen.rs +++ b/hyperstack-macros/src/idl_codegen.rs @@ -404,13 +404,13 @@ fn generate_account_type( if use_bytemuck { let bytemuck_try_from = quote! { impl #name { - pub const DISCRIMINATOR: [u8; 8] = #disc_array; + pub const DISCRIMINATOR: &'static [u8] = &#disc_array; pub fn try_from_bytes(data: &[u8]) -> Result> { - if data.len() < 8 { + if data.len() < Self::DISCRIMINATOR.len() { return Err("Data too short for discriminator".into()); } - let body = &data[8..]; + let body = &data[Self::DISCRIMINATOR.len()..]; let struct_size = std::mem::size_of::(); if body.len() < struct_size { return Err(format!( @@ -478,13 +478,13 @@ fn generate_account_type( } impl #name { - pub const DISCRIMINATOR: [u8; 8] = #disc_array; + pub const DISCRIMINATOR: &'static [u8] = &#disc_array; pub fn try_from_bytes(data: &[u8]) -> Result> { - if data.len() < 8 { + if data.len() < Self::DISCRIMINATOR.len() { return Err("Data too short for discriminator".into()); } - let mut reader = &data[8..]; + let mut reader = &data[Self::DISCRIMINATOR.len()..]; borsh::BorshDeserialize::deserialize_reader(&mut reader) .map_err(|e| e.into()) } @@ -534,7 +534,7 @@ fn generate_instruction_type( } impl #name { - pub const DISCRIMINATOR: [u8; 8] = #disc_array; + pub const DISCRIMINATOR: &'static [u8] = &#disc_array; pub fn try_from_bytes(data: &[u8]) -> Result> { let mut reader = data; @@ -605,21 +605,21 @@ fn generate_event_type( } impl #name { - pub const DISCRIMINATOR: [u8; 8] = #disc_array; + pub const DISCRIMINATOR: &'static [u8] = &#disc_array; /// Decode a CPI event from raw instruction data. - /// Anchor CPI events: 8-byte discriminator followed by Borsh-encoded payload. + /// Anchor CPI events: discriminator followed by Borsh-encoded payload. pub fn try_from_bytes(data: &[u8]) -> Result> { - if data.len() < 8 { + if data.len() < Self::DISCRIMINATOR.len() { return Err("Data too short for event discriminator".into()); } - if data[..8] != Self::DISCRIMINATOR { + if &data[..Self::DISCRIMINATOR.len()] != Self::DISCRIMINATOR { return Err(format!( "Discriminator mismatch: expected {:?}, got {:?}", - Self::DISCRIMINATOR, &data[..8] + Self::DISCRIMINATOR, &data[..Self::DISCRIMINATOR.len()] ).into()); } - let mut reader = &data[8..]; + let mut reader = &data[Self::DISCRIMINATOR.len()..]; borsh::BorshDeserialize::deserialize_reader(&mut reader).map_err(|e| e.into()) } From 172f5947d1c12743bf1449b21fd703807a2ce7e3 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 03:34:44 +0000 Subject: [PATCH 30/60] chore: Update ore stack --- stacks/ore/.hyperstack/OreStream.stack.json | 459 +++----------------- 1 file changed, 51 insertions(+), 408 deletions(-) diff --git a/stacks/ore/.hyperstack/OreStream.stack.json b/stacks/ore/.hyperstack/OreStream.stack.json index 2f22a1db..173bda5d 100644 --- a/stacks/ore/.hyperstack/OreStream.stack.json +++ b/stacks/ore/.hyperstack/OreStream.stack.json @@ -450,13 +450,6 @@ { "name": "automate", "discriminator": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, 0 ], "discriminant": null, @@ -537,14 +530,7 @@ { "name": "checkpoint", "discriminator": [ - 2, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 2 ], "discriminant": null, "docs": [ @@ -606,14 +592,7 @@ { "name": "claimSol", "discriminator": [ - 3, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 3 ], "discriminant": null, "docs": [ @@ -650,14 +629,7 @@ { "name": "claimOre", "discriminator": [ - 4, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 4 ], "discriminant": null, "docs": [ @@ -742,14 +714,7 @@ { "name": "close", "discriminator": [ - 5, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 5 ], "discriminant": null, "docs": [ @@ -812,14 +777,7 @@ { "name": "deploy", "discriminator": [ - 6, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 6 ], "discriminant": null, "docs": [ @@ -933,14 +891,7 @@ { "name": "log", "discriminator": [ - 8, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 8 ], "discriminant": null, "docs": [ @@ -962,14 +913,7 @@ { "name": "reset", "discriminator": [ - 9, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 9 ], "discriminant": null, "docs": [ @@ -1129,14 +1073,7 @@ { "name": "deposit", "discriminator": [ - 10, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 10 ], "discriminant": null, "docs": [ @@ -1239,14 +1176,7 @@ { "name": "withdraw", "discriminator": [ - 11, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 11 ], "discriminant": null, "docs": [ @@ -1337,14 +1267,7 @@ { "name": "claimYield", "discriminator": [ - 12, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 12 ], "discriminant": null, "docs": [ @@ -1436,14 +1359,7 @@ { "name": "buyback", "discriminator": [ - 13, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 13 ], "discriminant": null, "docs": [ @@ -1455,14 +1371,7 @@ { "name": "bury", "discriminator": [ - 24, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 24 ], "discriminant": null, "docs": [ @@ -1554,14 +1463,7 @@ { "name": "wrap", "discriminator": [ - 14, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 14 ], "discriminant": null, "docs": [ @@ -1620,14 +1522,7 @@ { "name": "setAdmin", "discriminator": [ - 15, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 15 ], "discriminant": null, "docs": [ @@ -1669,14 +1564,7 @@ { "name": "newVar", "discriminator": [ - 19, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 19 ], "discriminant": null, "docs": [ @@ -1763,14 +1651,7 @@ { "name": "reloadSol", "discriminator": [ - 21, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 21 ], "discriminant": null, "docs": [ @@ -1782,14 +1663,7 @@ { "name": "compoundYield", "discriminator": [ - 22, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 22 ], "discriminant": null, "docs": [ @@ -1801,14 +1675,7 @@ { "name": "liq", "discriminator": [ - 25, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 25 ], "discriminant": null, "docs": [ @@ -2562,13 +2429,6 @@ { "name": "open", "discriminator": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, 0 ], "discriminant": null, @@ -2649,14 +2509,7 @@ { "name": "close", "discriminator": [ - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 1 ], "discriminant": null, "docs": [ @@ -2693,14 +2546,7 @@ { "name": "next", "discriminator": [ - 2, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 2 ], "discriminant": null, "docs": [ @@ -2735,14 +2581,7 @@ { "name": "reveal", "discriminator": [ - 4, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 4 ], "discriminant": null, "docs": [ @@ -2782,14 +2621,7 @@ { "name": "sample", "discriminator": [ - 5, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 5 ], "discriminant": null, "docs": [ @@ -4408,14 +4240,7 @@ "lookup_name": "default_pda_lookup", "queue_discriminators": [ [ - 9, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 9 ] ] } @@ -5381,7 +5206,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "228a3402ec182567cdbfaa707138362ff7c3a5e3f5854a76cdff6d7b7c79d706", + "content_hash": "2499bee255d1ab8600d1e2abe118043e3c7c04ea6164dc0c81eba2fa33bb03e4", "views": [ { "id": "OreRound/latest", @@ -5885,14 +5710,7 @@ "lookup_name": "default_pda_lookup", "queue_discriminators": [ [ - 9, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 9 ] ] } @@ -5997,7 +5815,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "807c6c941a86f6d21c0801d6c92481665cf7778931c56f4b9f716dce6413f6b3", + "content_hash": "ffec247e90689c746263a287f04388f5eefe1ee5058713739673c197f030731b", "views": [] }, { @@ -7337,14 +7155,7 @@ "lookup_name": "default_pda_lookup", "queue_discriminators": [ [ - 9, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 9 ] ] } @@ -7355,7 +7166,7 @@ "resolver_specs": [], "computed_fields": [], "computed_field_specs": [], - "content_hash": "65b194af422058c586a9425a4e34887d163f7adae4c6ad952968e9c10905d2d7", + "content_hash": "9155b664af8383fd8a2d2272d69df1480f8181c1316cc12cb83ff444a95610bb", "views": [] } ], @@ -7367,13 +7178,6 @@ { "name": "automate", "discriminator": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, 0 ], "discriminator_size": 1, @@ -7473,14 +7277,7 @@ { "name": "checkpoint", "discriminator": [ - 2, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 2 ], "discriminator_size": 1, "accounts": [ @@ -7562,14 +7359,7 @@ { "name": "claimSol", "discriminator": [ - 3, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 3 ], "discriminator_size": 1, "accounts": [ @@ -7623,14 +7413,7 @@ { "name": "claimOre", "discriminator": [ - 4, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 4 ], "discriminator_size": 1, "accounts": [ @@ -7741,14 +7524,7 @@ { "name": "close", "discriminator": [ - 5, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 5 ], "discriminator_size": 1, "accounts": [ @@ -7831,14 +7607,7 @@ { "name": "deploy", "discriminator": [ - 6, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 6 ], "discriminator_size": 1, "accounts": [ @@ -7979,14 +7748,7 @@ { "name": "log", "discriminator": [ - 8, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 8 ], "discriminator_size": 1, "accounts": [ @@ -8022,14 +7784,7 @@ { "name": "reset", "discriminator": [ - 9, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 9 ], "discriminator_size": 1, "accounts": [ @@ -8227,14 +7982,7 @@ { "name": "deposit", "discriminator": [ - 10, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 10 ], "discriminator_size": 1, "accounts": [ @@ -8364,14 +8112,7 @@ { "name": "withdraw", "discriminator": [ - 11, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 11 ], "discriminator_size": 1, "accounts": [ @@ -8488,14 +8229,7 @@ { "name": "claimYield", "discriminator": [ - 12, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 12 ], "discriminator_size": 1, "accounts": [ @@ -8613,14 +8347,7 @@ { "name": "buyback", "discriminator": [ - 13, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 13 ], "discriminator_size": 1, "accounts": [], @@ -8645,14 +8372,7 @@ { "name": "bury", "discriminator": [ - 24, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 24 ], "discriminator_size": 1, "accounts": [ @@ -8769,14 +8489,7 @@ { "name": "wrap", "discriminator": [ - 14, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 14 ], "discriminator_size": 1, "accounts": [ @@ -8854,14 +8567,7 @@ { "name": "setAdmin", "discriminator": [ - 15, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 15 ], "discriminator_size": 1, "accounts": [ @@ -8920,14 +8626,7 @@ { "name": "newVar", "discriminator": [ - 19, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 19 ], "discriminator_size": 1, "accounts": [ @@ -9031,14 +8730,7 @@ { "name": "reloadSol", "discriminator": [ - 21, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 21 ], "discriminator_size": 1, "accounts": [], @@ -9063,14 +8755,7 @@ { "name": "compoundYield", "discriminator": [ - 22, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 22 ], "discriminator_size": 1, "accounts": [], @@ -9095,14 +8780,7 @@ { "name": "liq", "discriminator": [ - 25, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 25 ], "discriminator_size": 1, "accounts": [], @@ -9127,13 +8805,6 @@ { "name": "open", "discriminator": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, 0 ], "discriminator_size": 1, @@ -9228,14 +8899,7 @@ { "name": "close", "discriminator": [ - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 1 ], "discriminator_size": 1, "accounts": [ @@ -9289,14 +8953,7 @@ { "name": "next", "discriminator": [ - 2, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 2 ], "discriminator_size": 1, "accounts": [ @@ -9346,14 +9003,7 @@ { "name": "reveal", "discriminator": [ - 4, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 4 ], "discriminator_size": 1, "accounts": [ @@ -9403,14 +9053,7 @@ { "name": "sample", "discriminator": [ - 5, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 5 ], "discriminator_size": 1, "accounts": [ @@ -9463,5 +9106,5 @@ ] } ], - "content_hash": "ffe594cf02bed5cffc6fe87c68b45bdea44c183c18cbefb71e5763c3e93780f1" + "content_hash": "80c3ed1638194dc541594dd82dd1e80f8660aee2254d71b3e78cfae7edadfb2f" } \ No newline at end of file From 34e888d76a530125c7b1d697ed36326523be11a8 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 03:36:20 +0000 Subject: [PATCH 31/60] chore: Ore stack --- stacks/ore/.hyperstack/OreStream.stack.json | 56 ++++++++++----------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/stacks/ore/.hyperstack/OreStream.stack.json b/stacks/ore/.hyperstack/OreStream.stack.json index 173bda5d..64e1b165 100644 --- a/stacks/ore/.hyperstack/OreStream.stack.json +++ b/stacks/ore/.hyperstack/OreStream.stack.json @@ -4225,24 +4225,24 @@ }, "resolver_hooks": [ { - "account_type": "entropy::VarState", + "account_type": "ore::TreasuryState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [] + "queue_discriminators": [ + [ + 9 + ] + ] } } }, { - "account_type": "ore::TreasuryState", + "account_type": "entropy::VarState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [ - [ - 9 - ] - ] + "queue_discriminators": [] } } } @@ -5206,7 +5206,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "2499bee255d1ab8600d1e2abe118043e3c7c04ea6164dc0c81eba2fa33bb03e4", + "content_hash": "71c8796142e933db057e499e2e4a69de15e119e69cd075418ff50de18d51adec", "views": [ { "id": "OreRound/latest", @@ -5695,24 +5695,24 @@ }, "resolver_hooks": [ { - "account_type": "entropy::VarState", + "account_type": "ore::TreasuryState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [] + "queue_discriminators": [ + [ + 9 + ] + ] } } }, { - "account_type": "ore::TreasuryState", + "account_type": "entropy::VarState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [ - [ - 9 - ] - ] + "queue_discriminators": [] } } } @@ -5815,7 +5815,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "ffec247e90689c746263a287f04388f5eefe1ee5058713739673c197f030731b", + "content_hash": "5e4e0c9ad6793cd2f8c0f5016320b373ea1537edd10f9634159c3739f1db4f80", "views": [] }, { @@ -7140,24 +7140,24 @@ }, "resolver_hooks": [ { - "account_type": "entropy::VarState", + "account_type": "ore::TreasuryState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [] + "queue_discriminators": [ + [ + 9 + ] + ] } } }, { - "account_type": "ore::TreasuryState", + "account_type": "entropy::VarState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [ - [ - 9 - ] - ] + "queue_discriminators": [] } } } @@ -7166,7 +7166,7 @@ "resolver_specs": [], "computed_fields": [], "computed_field_specs": [], - "content_hash": "9155b664af8383fd8a2d2272d69df1480f8181c1316cc12cb83ff444a95610bb", + "content_hash": "aab096b52a9436ab7c2927e6c7f79408ada29daa124b2364cb9f36364f5050b4", "views": [] } ], @@ -9106,5 +9106,5 @@ ] } ], - "content_hash": "80c3ed1638194dc541594dd82dd1e80f8660aee2254d71b3e78cfae7edadfb2f" + "content_hash": "88eb65a18eb2103607ae49f4f407c9b76fea89fe3cc93a08f935f7c3c4025d27" } \ No newline at end of file From b95151935194640daa1c7f7ea312081b62e42055 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 03:43:04 +0000 Subject: [PATCH 32/60] fix: add optional chaining for null safety in ore-react components Prevent runtime TypeErrors by adding optional chaining to: - round.state?.total_deployed?.toFixed(4) in StatsPanel - round.state?.count_per_square?.[i] in BlockGrid --- examples/ore-react/src/components/BlockGrid.tsx | 2 +- examples/ore-react/src/components/StatsPanel.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/ore-react/src/components/BlockGrid.tsx b/examples/ore-react/src/components/BlockGrid.tsx index 44719c78..1df97b44 100644 --- a/examples/ore-react/src/components/BlockGrid.tsx +++ b/examples/ore-react/src/components/BlockGrid.tsx @@ -9,7 +9,7 @@ export function BlockGrid({ round }: BlockGridProps) { const blocks = round ? (round.state?.deployed_per_square_ui || []).map((deployedUi, i) => ({ id: i + 1, - minerCount: round.state.count_per_square[i], + minerCount: round.state?.count_per_square?.[i], deployedUi, isWinner: (round.results?.winning_square === i) || (round.results?.pre_reveal_winning_square === i), })) diff --git a/examples/ore-react/src/components/StatsPanel.tsx b/examples/ore-react/src/components/StatsPanel.tsx index 6a31c3fd..1bdc2709 100644 --- a/examples/ore-react/src/components/StatsPanel.tsx +++ b/examples/ore-react/src/components/StatsPanel.tsx @@ -56,7 +56,7 @@ export function StatsPanel({ round, treasuryMotherlode, isConnected }: StatsPane
- {round ? round.state?.total_deployed.toFixed(4) : '0.0000'} + {round ? round.state?.total_deployed?.toFixed(4) : '0.0000'}
Total deployed
From 8c8875b4c587f282e6f3993c1651aebe816004c1 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 03:43:44 +0000 Subject: [PATCH 33/60] fix: conditionally enable TLS only for https/grpcs endpoints in slot subscription The generated slot-subscription task was unconditionally applying TLS configuration, which broke plain http:// endpoints. Now TLS is only enabled when the endpoint scheme is https:// or grpcs://. --- hyperstack-macros/src/codegen/vixen_runtime.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/hyperstack-macros/src/codegen/vixen_runtime.rs b/hyperstack-macros/src/codegen/vixen_runtime.rs index bb953a37..1eb51d5d 100644 --- a/hyperstack-macros/src/codegen/vixen_runtime.rs +++ b/hyperstack-macros/src/codegen/vixen_runtime.rs @@ -315,7 +315,7 @@ fn generate_slot_subscription_task() -> TokenStream { }; use hyperstack::runtime::futures::StreamExt; - let mut client = hyperstack::runtime::yellowstone_grpc_client::GeyserGrpcClient + let mut builder = hyperstack::runtime::yellowstone_grpc_client::GeyserGrpcClient ::build_from_shared(endpoint.clone())? .x_token(x_token.clone())? .max_decoding_message_size(usize::MAX) @@ -323,13 +323,16 @@ fn generate_slot_subscription_task() -> TokenStream { hyperstack::runtime::yellowstone_grpc_proto::tonic::codec::CompressionEncoding::Zstd ) .connect_timeout(std::time::Duration::from_secs(30)) - .timeout(std::time::Duration::from_secs(60)) - .tls_config( + .timeout(std::time::Duration::from_secs(60)); + + if endpoint.starts_with("https://") || endpoint.starts_with("grpcs://") { + builder = builder.tls_config( hyperstack::runtime::yellowstone_grpc_proto::tonic::transport::ClientTlsConfig::new() .with_native_roots() - )? - .connect() - .await?; + )?; + } + + let mut client = builder.connect().await?; // Solana SlotHashes sysvar address let slot_hashes_sysvar = "SysvarS1otHashes111111111111111111111111111".to_string(); From 10ff8aa10cec3f31707ebb39fd5a0fd3b9e06737 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 03:56:02 +0000 Subject: [PATCH 34/60] fix: prevent silent byte truncation in json_array_to_bytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reject JSON array elements outside [0, 255] range instead of silently truncating them. Values > 255 were being wrapped (e.g., 256 → 0) which could produce incorrect RNG values. --- interpreter/src/resolvers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/src/resolvers.rs b/interpreter/src/resolvers.rs index 83dea1d2..f66ddf09 100644 --- a/interpreter/src/resolvers.rs +++ b/interpreter/src/resolvers.rs @@ -796,7 +796,7 @@ impl SlotHashResolver { let arr = value.as_array()?; let bytes: Vec = arr .iter() - .filter_map(|v| v.as_u64().map(|n| n as u8)) + .filter_map(|v| v.as_u64().and_then(|n| u8::try_from(n).ok())) .collect(); if bytes.len() == expected_len { Some(bytes) From 32a4e5e3943d2742e5f86550b88f6e0e68bb606c Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 03:56:20 +0000 Subject: [PATCH 35/60] refactor: remove dead _trigger_info allocation in QueueResolver opcode --- interpreter/src/vm.rs | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/interpreter/src/vm.rs b/interpreter/src/vm.rs index dfea9e89..837ae4c9 100644 --- a/interpreter/src/vm.rs +++ b/interpreter/src/vm.rs @@ -2767,21 +2767,6 @@ impl VmContext { } => { let actual_state_id = override_state_id; - // Log what triggered this resolver - let _trigger_info = if let Some(ref ctx) = self.current_context { - if let Some(ref sig) = ctx.signature { - format!( - "instruction (slot={}, sig={})", - ctx.slot.unwrap_or(0), - &sig[..std::cmp::min(16, sig.len())] - ) - } else { - format!("account update (slot={})", ctx.slot.unwrap_or(0)) - } - } else { - "unknown".to_string() - }; - // Skip resolvers for reprocessed cached data from PDA mapping changes. // Stale data can carry wrong field values (e.g. old entropy_value) and // wrong schedule_at slots that would lock in incorrect results via SetOnce. From 97f2bbe55b437ce19e77e56a493ffb71b35f736f Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 03:58:13 +0000 Subject: [PATCH 36/60] refactor: remove unreachable hash length check in keccak256 resolver Keccak256::digest is guaranteed by the sha3 crate to always return exactly 32 bytes (256 bits). The hash.len() < 32 guard was dead code and has been removed. --- interpreter/src/resolvers.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/interpreter/src/resolvers.rs b/interpreter/src/resolvers.rs index f66ddf09..b21173e9 100644 --- a/interpreter/src/resolvers.rs +++ b/interpreter/src/resolvers.rs @@ -777,10 +777,6 @@ impl SlotHashResolver { use sha3::{Digest, Keccak256}; let hash = Keccak256::digest(&input); - if hash.len() < 32 { - return Ok(Value::Null); - } - // XOR-fold four u64 chunks let r1 = u64::from_le_bytes(hash[0..8].try_into()?); let r2 = u64::from_le_bytes(hash[8..16].try_into()?); From 462230f814d08acd985fc13b3f17820ff6e1ac94 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 04:26:28 +0000 Subject: [PATCH 37/60] fix: reduce MAX_CACHE_SIZE from 50k to 1k --- interpreter/src/slot_hash_cache.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/interpreter/src/slot_hash_cache.rs b/interpreter/src/slot_hash_cache.rs index 17cd2273..c6d91a67 100644 --- a/interpreter/src/slot_hash_cache.rs +++ b/interpreter/src/slot_hash_cache.rs @@ -11,7 +11,7 @@ static SLOT_HASH_CACHE: once_cell::sync::Lazy>> once_cell::sync::Lazy::new(|| Arc::new(RwLock::new(BTreeMap::new()))); /// Maximum number of slot hashes to keep in cache (prevent unbounded growth) -const MAX_CACHE_SIZE: usize = 50000; +const MAX_CACHE_SIZE: usize = 1000; /// Record a slot hash in the global cache pub fn record_slot_hash(slot: u64, slot_hash: String) { @@ -20,10 +20,10 @@ pub fn record_slot_hash(slot: u64, slot_hash: String) { // Prune old entries if cache is too large if cache.len() > MAX_CACHE_SIZE { - // Remove oldest 25% of entries - let slots_to_remove: Vec = cache.keys().take(cache.len() / 4).copied().collect(); - for slot in slots_to_remove { - cache.remove(&slot); + // Remove oldest 25% of entries using pop_first for O(log n) per removal + let target_size = cache.len() - cache.len() / 4; + while cache.len() > target_size { + cache.pop_first(); } } } From 2ef8917d242fb93ceb7e5c7fd55ff236d02ebd64 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 04:36:46 +0000 Subject: [PATCH 38/60] fix: use resolver schema types for computed fields in TypeScript generation Computed fields using resolvers (e.g., slot_hash()) were generating weak z.array(z.any()) schemas instead of the proper resolver schemas like SlotHashBytesSchema. This fix extracts resolver output types from computed expressions and propagates them to field_mappings, enabling the TypeScript generator to emit proper schema references for resolver-backed computed fields. --- .../src/stream_spec/ast_writer.rs | 41 +++++++++++++++++-- hyperstack-macros/src/stream_spec/computed.rs | 26 ++++++++++++ 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/hyperstack-macros/src/stream_spec/ast_writer.rs b/hyperstack-macros/src/stream_spec/ast_writer.rs index adbb5f00..669ec806 100644 --- a/hyperstack-macros/src/stream_spec/ast_writer.rs +++ b/hyperstack-macros/src/stream_spec/ast_writer.rs @@ -13,8 +13,8 @@ use crate::ast::writer::{ convert_idl_to_snapshot, parse_population_strategy, parse_transformation, }; use crate::ast::{ - ComparisonOp, ComputedFieldSpec, ConditionExpr, EntitySection, FieldPath, HookAction, - IdentitySpec, IdlSerializationSnapshot, InstructionHook, KeyResolutionStrategy, + ComparisonOp, ComputedFieldSpec, ConditionExpr, EntitySection, FieldPath, FieldTypeInfo, + HookAction, IdentitySpec, IdlSerializationSnapshot, InstructionHook, KeyResolutionStrategy, LookupIndexSpec, MappingSource, ResolveStrategy, ResolverCondition, ResolverExtractSpec, ResolverHook, ResolverSpec, ResolverStrategy, ResolverType, SerializableFieldMapping, SerializableHandlerSpec, SerializableStreamSpec, SourceSpec, @@ -25,7 +25,9 @@ use crate::parse::conditions as condition_parser; use crate::parse::idl as idl_parser; use crate::utils::path_to_string; -use super::computed::{parse_computed_expression, qualify_field_refs}; +use super::computed::{ + extract_resolver_type_from_computed_expr, parse_computed_expression, qualify_field_refs, +}; use super::handlers::{find_field_in_instruction, get_join_on_field}; // ============================================================================ @@ -149,6 +151,39 @@ pub fn build_ast( } } + // Add computed fields to field_mappings with resolver type information + // This ensures computed fields that use resolvers get proper TypeScript schema generation + for computed_spec in &computed_field_specs { + if let Some(resolver_type) = + extract_resolver_type_from_computed_expr(&computed_spec.expression) + { + // Parse the result type to determine if it's optional and if it's an array + let result_type = &computed_spec.result_type; + let is_optional = + result_type.starts_with("Option <") || result_type.starts_with("Option<"); + let is_array = result_type.contains("Vec <") + || result_type.contains("Vec<") + || result_type.contains("["); + + let field_info = FieldTypeInfo { + field_name: computed_spec.target_path.clone(), + rust_type_name: computed_spec.result_type.clone(), + base_type: if is_array { + crate::ast::BaseType::Array + } else { + crate::ast::BaseType::Any + }, + is_optional, + is_array, + inner_type: Some(resolver_type.to_string()), + source_path: None, + resolved_type: None, + emit: true, + }; + field_mappings.insert(computed_spec.target_path.clone(), field_info); + } + } + let mut spec = SerializableStreamSpec { state_name: entity_name.to_string(), program_id, diff --git a/hyperstack-macros/src/stream_spec/computed.rs b/hyperstack-macros/src/stream_spec/computed.rs index 85bcd3a4..a2073349 100644 --- a/hyperstack-macros/src/stream_spec/computed.rs +++ b/hyperstack-macros/src/stream_spec/computed.rs @@ -39,6 +39,32 @@ fn resolver_for_method(method: &str) -> Option<&'static str> { } } +/// Get the output type name for a resolver method. +/// This maps resolver method names to their TypeScript output type names. +pub fn resolver_output_type(method: &str) -> Option<&'static str> { + match method { + "slot_hash" => Some("SlotHash"), + "keccak_rng" => Some("KeccakRngValue"), + "ui_amount" => Some("TokenUiAmount"), + "raw_amount" => Some("TokenRawAmount"), + _ => None, + } +} + +/// Extract the resolver output type from a computed expression. +/// Returns the type name if the expression is a ResolverComputed call. +pub fn extract_resolver_type_from_computed_expr( + expr: &crate::ast::ComputedExpr, +) -> Option<&'static str> { + use crate::ast::ComputedExpr; + match expr { + ComputedExpr::ResolverComputed { method, .. } => resolver_output_type(method), + ComputedExpr::Some { value } => extract_resolver_type_from_computed_expr(value), + ComputedExpr::Paren { expr } => extract_resolver_type_from_computed_expr(expr), + _ => None, + } +} + /// Qualify unqualified field references in a computed expression with a section prefix. /// /// This ensures that field references like `total_buy_volume` become `trading.total_buy_volume` From 03e00aa4248be85146e60c133cc88130c240dcc1 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 04:49:18 +0000 Subject: [PATCH 39/60] fix: remove unnecessary async from parse_and_cache_slot_hashes The function contains only synchronous logic with no await points. Making it async forces unnecessary Tokio state machine allocation and obscures the synchronous nature to callers. --- hyperstack-macros/src/codegen/vixen_runtime.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hyperstack-macros/src/codegen/vixen_runtime.rs b/hyperstack-macros/src/codegen/vixen_runtime.rs index 1eb51d5d..2dac5774 100644 --- a/hyperstack-macros/src/codegen/vixen_runtime.rs +++ b/hyperstack-macros/src/codegen/vixen_runtime.rs @@ -268,7 +268,7 @@ fn generate_slot_scheduler_task() -> TokenStream { fn generate_slot_subscription_task() -> TokenStream { quote! { // Helper function to parse SlotHashes sysvar data - async fn parse_and_cache_slot_hashes(current_slot: u64, data: &[u8]) -> Result<(), Box> { + fn parse_and_cache_slot_hashes(current_slot: u64, data: &[u8]) -> Result<(), Box> { if data.len() < 8 { return Err("Data too short".into()); } @@ -396,7 +396,7 @@ fn generate_slot_subscription_task() -> TokenStream { if let Err(e) = parse_and_cache_slot_hashes( account_update.slot, &account.data, - ).await { + ) { hyperstack::runtime::tracing::warn!( error = %e, "[SLOT_SUB] Failed to parse SlotHashes" From 77d2566db00255cc5460e3ea4490302d0e530a25 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 04:49:45 +0000 Subject: [PATCH 40/60] fix: change any() to all() for Steel-style IDL detection --- hyperstack-idl/src/snapshot.rs | 45 +++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/hyperstack-idl/src/snapshot.rs b/hyperstack-idl/src/snapshot.rs index 879f085f..ebdf0d52 100644 --- a/hyperstack-idl/src/snapshot.rs +++ b/hyperstack-idl/src/snapshot.rs @@ -34,7 +34,7 @@ impl<'de> Deserialize<'de> for IdlSnapshot { .get("instructions") .and_then(|instrs| instrs.as_array()) .map(|instrs| { - instrs.iter().any(|ix| { + instrs.iter().all(|ix| { // Steel-style: has discriminant field, no discriminator or empty discriminator let has_discriminant = ix.get("discriminant").is_some(); let discriminator = ix.get("discriminator"); @@ -87,22 +87,59 @@ struct IdlSnapshotIntermediate { pub discriminant_size: usize, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize)] pub struct IdlAccountSnapshot { + pub name: String, + pub discriminator: Vec, + pub docs: Vec, + pub serialization: Option, + /// Account fields - populated from inline type definition + pub fields: Vec, + /// Inline type definition (for Steel format with type.fields structure) + #[serde(skip_serializing_if = "Option::is_none")] + pub type_def: Option, +} + +// Intermediate struct for deserialization +#[derive(Deserialize)] +struct IdlAccountSnapshotIntermediate { pub name: String, pub discriminator: Vec, #[serde(default)] pub docs: Vec, #[serde(default, skip_serializing_if = "Option::is_none")] pub serialization: Option, - /// Account fields - populated from inline type definition #[serde(default)] pub fields: Vec, - /// Inline type definition (for Steel format with type.fields structure) #[serde(rename = "type", default, skip_serializing_if = "Option::is_none")] pub type_def: Option, } +impl<'de> Deserialize<'de> for IdlAccountSnapshot { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let intermediate = IdlAccountSnapshotIntermediate::deserialize(deserializer)?; + + // Normalize fields: if empty but type_def has fields, use those + let fields = if intermediate.fields.is_empty() && intermediate.type_def.is_some() { + intermediate.type_def.as_ref().unwrap().fields.clone() + } else { + intermediate.fields + }; + + Ok(IdlAccountSnapshot { + name: intermediate.name, + discriminator: intermediate.discriminator, + docs: intermediate.docs, + serialization: intermediate.serialization, + fields, + type_def: intermediate.type_def, + }) + } +} + /// Inline type definition for account fields (Steel format) #[derive(Debug, Clone, Serialize, Deserialize)] pub struct IdlInlineTypeDef { From b3e6dac0cda3428471f2d648200c3b866f26e108 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 04:55:37 +0000 Subject: [PATCH 41/60] fix: replace unnecessary unwrap with if let pattern --- hyperstack-idl/src/snapshot.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hyperstack-idl/src/snapshot.rs b/hyperstack-idl/src/snapshot.rs index ebdf0d52..617282bb 100644 --- a/hyperstack-idl/src/snapshot.rs +++ b/hyperstack-idl/src/snapshot.rs @@ -123,8 +123,12 @@ impl<'de> Deserialize<'de> for IdlAccountSnapshot { let intermediate = IdlAccountSnapshotIntermediate::deserialize(deserializer)?; // Normalize fields: if empty but type_def has fields, use those - let fields = if intermediate.fields.is_empty() && intermediate.type_def.is_some() { - intermediate.type_def.as_ref().unwrap().fields.clone() + let fields = if intermediate.fields.is_empty() { + if let Some(type_def) = intermediate.type_def.as_ref() { + type_def.fields.clone() + } else { + intermediate.fields + } } else { intermediate.fields }; From 99427f6d6ca03c691c9556f1dc69065ca5b2b1e0 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 05:14:58 +0000 Subject: [PATCH 42/60] fix: prevent integer overflow in SlotHashes sysvar parsing --- hyperstack-macros/src/codegen/vixen_runtime.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hyperstack-macros/src/codegen/vixen_runtime.rs b/hyperstack-macros/src/codegen/vixen_runtime.rs index 2dac5774..12ca0387 100644 --- a/hyperstack-macros/src/codegen/vixen_runtime.rs +++ b/hyperstack-macros/src/codegen/vixen_runtime.rs @@ -278,8 +278,10 @@ fn generate_slot_subscription_task() -> TokenStream { data[4], data[5], data[6], data[7], ]) as usize; - let entry_size = 40; - let expected_size = 8 + (len * entry_size); + let entry_size: usize = 40; + let expected_size = 8_usize + .checked_add(len.checked_mul(entry_size).ok_or("len * entry_size overflow")?) + .ok_or("expected_size overflow")?; if data.len() < expected_size { return Err(format!("Data too short: expected {}, got {}", expected_size, data.len()).into()); From abad594108d0f9b1f795d7f320e7f69b1027fce6 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 05:15:28 +0000 Subject: [PATCH 43/60] fix: prevent empty instruction arrays from being misclassified as Steel-style Empty instruction arrays caused `iter().all()` to return true (vacuous truth), incorrectly setting discriminant_size to 1 instead of the default 8. Now empty arrays default to Anchor-style (8 bytes) as intended. --- hyperstack-idl/src/snapshot.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hyperstack-idl/src/snapshot.rs b/hyperstack-idl/src/snapshot.rs index 617282bb..5cc4fddd 100644 --- a/hyperstack-idl/src/snapshot.rs +++ b/hyperstack-idl/src/snapshot.rs @@ -34,6 +34,9 @@ impl<'de> Deserialize<'de> for IdlSnapshot { .get("instructions") .and_then(|instrs| instrs.as_array()) .map(|instrs| { + if instrs.is_empty() { + return false; + } instrs.iter().all(|ix| { // Steel-style: has discriminant field, no discriminator or empty discriminator let has_discriminant = ix.get("discriminant").is_some(); From 9f0769209f382291d3fd8119d8fc39549d0314d1 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 05:28:14 +0000 Subject: [PATCH 44/60] fix: serialize pre_reveal_rng as string to avoid JS precision loss The keccak_rng resolver returns a u64 value (XOR-fold of four u64 chunks) which can exceed Number.MAX_SAFE_INTEGER (2^53-1). This caused precision loss when JSON.parse'd in JavaScript. Changed serialization to use decimal strings instead of JSON numbers for the pre_reveal_rng field. --- interpreter/src/resolvers.rs | 6 +++--- stacks/sdk/typescript/src/ore/index.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interpreter/src/resolvers.rs b/interpreter/src/resolvers.rs index b21173e9..bd18e08e 100644 --- a/interpreter/src/resolvers.rs +++ b/interpreter/src/resolvers.rs @@ -784,7 +784,7 @@ impl SlotHashResolver { let r4 = u64::from_le_bytes(hash[24..32].try_into()?); let rng = r1 ^ r2 ^ r3 ^ r4; - Ok(Value::Number(rng.into())) + Ok(Value::String(rng.to_string())) } /// Extract a byte array of expected length from a JSON array value. @@ -874,7 +874,7 @@ impl ResolverDefinition for SlotHashResolver { bytes: number[]; } -export type KeccakRngValue = number;"#, +export type KeccakRngValue = string;"#, ) } @@ -885,7 +885,7 @@ export type KeccakRngValue = number;"#, bytes: z.array(z.number().int().min(0).max(255)).length(32), }); -export const KeccakRngValueSchema = z.number().int().min(0);"#, +export const KeccakRngValueSchema = z.string();"#, }) } } diff --git a/stacks/sdk/typescript/src/ore/index.ts b/stacks/sdk/typescript/src/ore/index.ts index e629bc19..18b97692 100644 --- a/stacks/sdk/typescript/src/ore/index.ts +++ b/stacks/sdk/typescript/src/ore/index.ts @@ -24,7 +24,7 @@ export interface OreRoundMetrics { export interface OreRoundResults { did_hit_motherlode?: boolean | null; expires_at_slot_hash?: any[] | null; - pre_reveal_rng?: number | null; + pre_reveal_rng?: string | null; pre_reveal_winning_square?: number | null; rent_payer?: string | null; rng?: number | null; @@ -101,7 +101,7 @@ export const OreRoundMetricsSchema = z.object({ export const OreRoundResultsSchema = z.object({ did_hit_motherlode: z.boolean().nullable().optional(), expires_at_slot_hash: z.array(z.any()).nullable().optional(), - pre_reveal_rng: z.number().nullable().optional(), + pre_reveal_rng: z.string().nullable().optional(), pre_reveal_winning_square: z.number().nullable().optional(), rent_payer: z.string().nullable().optional(), rng: z.number().nullable().optional(), From 927b364a996ce9047641a35a66d346485feac4d8 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 06:05:23 +0000 Subject: [PATCH 45/60] fix: derive state_id from bytecode routing for PDA cache --- hyperstack-macros/src/codegen/vixen_runtime.rs | 16 ++++++++++++++-- interpreter/src/resolvers.rs | 5 +++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/hyperstack-macros/src/codegen/vixen_runtime.rs b/hyperstack-macros/src/codegen/vixen_runtime.rs index 12ca0387..0c9c5aa4 100644 --- a/hyperstack-macros/src/codegen/vixen_runtime.rs +++ b/hyperstack-macros/src/codegen/vixen_runtime.rs @@ -970,8 +970,14 @@ pub fn generate_vm_handler( // mapping later changes (same PDA, different seed) the cached // data is returned for reprocessing with the corrected mapping. if result.is_ok() { + // Derive state_id from bytecode routing (same logic as process_event) + let state_id = self.bytecode.event_routing.get(event_type) + .and_then(|entities| entities.first()) + .and_then(|entity_name| self.bytecode.entities.get(entity_name)) + .map(|eb| eb.state_id) + .unwrap_or(0); vm.cache_last_account_data( - 0, + state_id, &account_address, hyperstack::runtime::hyperstack_interpreter::PendingAccountUpdate { account_type: event_type.to_string(), @@ -2025,8 +2031,14 @@ pub fn generate_account_handler_impl( .map_err(|e| e.to_string()); if result.is_ok() { + // Derive state_id from bytecode routing (same logic as process_event) + let state_id = self.bytecode.event_routing.get(event_type) + .and_then(|entities| entities.first()) + .and_then(|entity_name| self.bytecode.entities.get(entity_name)) + .map(|eb| eb.state_id) + .unwrap_or(0); vm.cache_last_account_data( - 0, + state_id, &account_address, hyperstack::runtime::hyperstack_interpreter::PendingAccountUpdate { account_type: event_type.to_string(), diff --git a/interpreter/src/resolvers.rs b/interpreter/src/resolvers.rs index bd18e08e..f4d17ec6 100644 --- a/interpreter/src/resolvers.rs +++ b/interpreter/src/resolvers.rs @@ -797,6 +797,11 @@ impl SlotHashResolver { if bytes.len() == expected_len { Some(bytes) } else { + tracing::debug!( + got = bytes.len(), + expected = expected_len, + "json_array_to_bytes: length mismatch or out-of-range element" + ); None } } From 1de42276d04d81837f1f7455bc9b7be6b96714c5 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 06:12:13 +0000 Subject: [PATCH 46/60] chore: Ore stack --- stacks/ore/.hyperstack/OreStream.stack.json | 134 +++++++++++--------- stacks/sdk/typescript/src/ore/index.ts | 4 +- 2 files changed, 73 insertions(+), 65 deletions(-) diff --git a/stacks/ore/.hyperstack/OreStream.stack.json b/stacks/ore/.hyperstack/OreStream.stack.json index 64e1b165..2dc40862 100644 --- a/stacks/ore/.hyperstack/OreStream.stack.json +++ b/stacks/ore/.hyperstack/OreStream.stack.json @@ -25,6 +25,7 @@ "docs": [ "Automation parameters for automated mining deployments." ], + "serialization": null, "fields": [ { "name": "amount", @@ -75,6 +76,7 @@ "docs": [ "Global round tracking for the mining game." ], + "serialization": null, "fields": [ { "name": "round_id", @@ -109,6 +111,7 @@ "docs": [ "Program configuration state." ], + "serialization": null, "fields": [ { "name": "admin", @@ -151,6 +154,7 @@ "docs": [ "Tracks a miner's deployed SOL and reward balances." ], + "serialization": null, "fields": [ { "name": "authority", @@ -241,6 +245,7 @@ "docs": [ "State for a single mining round." ], + "serialization": null, "fields": [ { "name": "id", @@ -326,6 +331,7 @@ "docs": [ "State for a staking participant." ], + "serialization": null, "fields": [ { "name": "authority", @@ -402,6 +408,7 @@ "docs": [ "Singleton treasury account tracking protocol balances." ], + "serialization": null, "fields": [ { "name": "balance", @@ -2357,6 +2364,7 @@ "docs": [ "An entropy variable account that stores randomness generation state." ], + "serialization": null, "fields": [ { "name": "authority", @@ -4012,22 +4020,22 @@ "resolved_type": null }, "results.expires_at_slot_hash": { - "field_name": "expires_at_slot_hash", + "field_name": "results.expires_at_slot_hash", "rust_type_name": "Option < Vec < u8 > >", "base_type": "Array", "is_optional": true, "is_array": true, - "inner_type": "Vec < u8 >", + "inner_type": "SlotHash", "source_path": null, "resolved_type": null }, "results.pre_reveal_rng": { - "field_name": "pre_reveal_rng", + "field_name": "results.pre_reveal_rng", "rust_type_name": "Option < u64 >", - "base_type": "Integer", + "base_type": "Any", "is_optional": true, "is_array": false, - "inner_type": "u64", + "inner_type": "KeccakRngValue", "source_path": null, "resolved_type": null }, @@ -4093,12 +4101,12 @@ "resolved_type": null }, "results.top_miner_reward": { - "field_name": "top_miner_reward", + "field_name": "results.top_miner_reward", "rust_type_name": "Option < f64 >", - "base_type": "Float", + "base_type": "Any", "is_optional": true, "is_array": false, - "inner_type": "f64", + "inner_type": "TokenUiAmount", "source_path": null, "resolved_type": null }, @@ -4163,22 +4171,22 @@ "resolved_type": null }, "state.motherlode": { - "field_name": "motherlode", + "field_name": "state.motherlode", "rust_type_name": "Option < f64 >", - "base_type": "Float", + "base_type": "Any", "is_optional": true, "is_array": false, - "inner_type": "f64", + "inner_type": "TokenUiAmount", "source_path": null, "resolved_type": null }, "state.total_deployed": { - "field_name": "total_deployed", + "field_name": "state.total_deployed", "rust_type_name": "Option < f64 >", - "base_type": "Float", + "base_type": "Any", "is_optional": true, "is_array": false, - "inner_type": "f64", + "inner_type": "TokenUiAmount", "source_path": null, "resolved_type": null }, @@ -4193,56 +4201,56 @@ "resolved_type": null }, "state.total_vaulted": { - "field_name": "total_vaulted", + "field_name": "state.total_vaulted", "rust_type_name": "Option < f64 >", - "base_type": "Float", + "base_type": "Any", "is_optional": true, "is_array": false, - "inner_type": "f64", + "inner_type": "TokenUiAmount", "source_path": null, "resolved_type": null }, "state.total_winnings": { - "field_name": "total_winnings", + "field_name": "state.total_winnings", "rust_type_name": "Option < f64 >", - "base_type": "Float", + "base_type": "Any", "is_optional": true, "is_array": false, - "inner_type": "f64", + "inner_type": "TokenUiAmount", "source_path": null, "resolved_type": null }, "treasury.motherlode": { - "field_name": "motherlode", + "field_name": "treasury.motherlode", "rust_type_name": "Option < f64 >", - "base_type": "Float", + "base_type": "Any", "is_optional": true, "is_array": false, - "inner_type": "f64", + "inner_type": "TokenUiAmount", "source_path": null, "resolved_type": null } }, "resolver_hooks": [ { - "account_type": "ore::TreasuryState", + "account_type": "entropy::VarState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [ - [ - 9 - ] - ] + "queue_discriminators": [] } } }, { - "account_type": "entropy::VarState", + "account_type": "ore::TreasuryState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [] + "queue_discriminators": [ + [ + 9 + ] + ] } } } @@ -5206,7 +5214,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "71c8796142e933db057e499e2e4a69de15e119e69cd075418ff50de18d51adec", + "content_hash": "be2cac5010099fdf867871a3a4f3904f2cd290f5fcafd2933f7c9d5f02d47ec1", "views": [ { "id": "OreRound/latest", @@ -5571,42 +5579,42 @@ "resolved_type": null }, "state.motherlode": { - "field_name": "motherlode", + "field_name": "state.motherlode", "rust_type_name": "Option < f64 >", - "base_type": "Float", + "base_type": "Any", "is_optional": true, "is_array": false, - "inner_type": "f64", + "inner_type": "TokenUiAmount", "source_path": null, "resolved_type": null }, "state.total_refined": { - "field_name": "total_refined", + "field_name": "state.total_refined", "rust_type_name": "Option < f64 >", - "base_type": "Float", + "base_type": "Any", "is_optional": true, "is_array": false, - "inner_type": "f64", + "inner_type": "TokenUiAmount", "source_path": null, "resolved_type": null }, "state.total_staked": { - "field_name": "total_staked", + "field_name": "state.total_staked", "rust_type_name": "Option < f64 >", - "base_type": "Float", + "base_type": "Any", "is_optional": true, "is_array": false, - "inner_type": "f64", + "inner_type": "TokenUiAmount", "source_path": null, "resolved_type": null }, "state.total_unclaimed": { - "field_name": "total_unclaimed", + "field_name": "state.total_unclaimed", "rust_type_name": "Option < f64 >", - "base_type": "Float", + "base_type": "Any", "is_optional": true, "is_array": false, - "inner_type": "f64", + "inner_type": "TokenUiAmount", "source_path": null, "resolved_type": null }, @@ -5695,24 +5703,24 @@ }, "resolver_hooks": [ { - "account_type": "ore::TreasuryState", + "account_type": "entropy::VarState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [ - [ - 9 - ] - ] + "queue_discriminators": [] } } }, { - "account_type": "entropy::VarState", + "account_type": "ore::TreasuryState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [] + "queue_discriminators": [ + [ + 9 + ] + ] } } } @@ -5815,7 +5823,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "5e4e0c9ad6793cd2f8c0f5016320b373ea1537edd10f9634159c3739f1db4f80", + "content_hash": "4b680401e840febd69cd77fe8db0716267b83525028af37a5e05ef65cfdc52a4", "views": [] }, { @@ -7140,24 +7148,24 @@ }, "resolver_hooks": [ { - "account_type": "ore::TreasuryState", + "account_type": "entropy::VarState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [ - [ - 9 - ] - ] + "queue_discriminators": [] } } }, { - "account_type": "entropy::VarState", + "account_type": "ore::TreasuryState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [] + "queue_discriminators": [ + [ + 9 + ] + ] } } } @@ -7166,7 +7174,7 @@ "resolver_specs": [], "computed_fields": [], "computed_field_specs": [], - "content_hash": "aab096b52a9436ab7c2927e6c7f79408ada29daa124b2364cb9f36364f5050b4", + "content_hash": "40a0247d41dc28a177b8e4e74f518d34a1b6810695600fb2dd6d1f92795eaa3c", "views": [] } ], @@ -9106,5 +9114,5 @@ ] } ], - "content_hash": "88eb65a18eb2103607ae49f4f407c9b76fea89fe3cc93a08f935f7c3c4025d27" + "content_hash": "268bee113d011a0a49d48573aff397cfb5ca7baa180899050aa61f5719bcf070" } \ No newline at end of file diff --git a/stacks/sdk/typescript/src/ore/index.ts b/stacks/sdk/typescript/src/ore/index.ts index 18b97692..e629bc19 100644 --- a/stacks/sdk/typescript/src/ore/index.ts +++ b/stacks/sdk/typescript/src/ore/index.ts @@ -24,7 +24,7 @@ export interface OreRoundMetrics { export interface OreRoundResults { did_hit_motherlode?: boolean | null; expires_at_slot_hash?: any[] | null; - pre_reveal_rng?: string | null; + pre_reveal_rng?: number | null; pre_reveal_winning_square?: number | null; rent_payer?: string | null; rng?: number | null; @@ -101,7 +101,7 @@ export const OreRoundMetricsSchema = z.object({ export const OreRoundResultsSchema = z.object({ did_hit_motherlode: z.boolean().nullable().optional(), expires_at_slot_hash: z.array(z.any()).nullable().optional(), - pre_reveal_rng: z.string().nullable().optional(), + pre_reveal_rng: z.number().nullable().optional(), pre_reveal_winning_square: z.number().nullable().optional(), rent_payer: z.string().nullable().optional(), rng: z.number().nullable().optional(), From 5d28937796b8c7672cff02c1f648ac0f37f48c44 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 06:57:17 +0000 Subject: [PATCH 47/60] fix: TypeScript generator now correctly types computed fields using resolver output types The `pre_reveal_rng` field (computed via `keccak_rng` resolver) was being typed as `number` instead of `string`. The resolver returns `Value::String` to avoid JavaScript precision loss for large u64 values. Changes: - Updated `is_output_type()` to check TypeScript interfaces for type aliases - Fixed `add_unmapped_fields()` to use resolver types from field_mappings - Updated `uses_builtin_type()` to check field_mappings for computed fields This ensures computed fields that use resolver methods get the correct TypeScript types generated. --- interpreter/src/resolvers.rs | 18 ++++++++++++++--- interpreter/src/typescript.rs | 27 +++++++++++++++++++++++++- stacks/sdk/typescript/src/ore/index.ts | 22 +++++++++++++++++---- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/interpreter/src/resolvers.rs b/interpreter/src/resolvers.rs index f4d17ec6..28030dbe 100644 --- a/interpreter/src/resolvers.rs +++ b/interpreter/src/resolvers.rs @@ -158,9 +158,21 @@ impl ResolverRegistry { } pub fn is_output_type(&self, type_name: &str) -> bool { - self.resolvers - .values() - .any(|resolver| resolver.output_type() == type_name) + self.resolvers.values().any(|resolver| { + // Check primary output type + if resolver.output_type() == type_name { + return true; + } + // Check for additional types defined in typescript_interface + if let Some(interface) = resolver.typescript_interface() { + // Look for type aliases like: export type TypeName = ... + let type_pattern = format!("export type {} =", type_name); + if interface.contains(&type_pattern) { + return true; + } + } + false + }) } pub fn evaluate_computed( diff --git a/interpreter/src/typescript.rs b/interpreter/src/typescript.rs index d7544e8b..00ba2345 100644 --- a/interpreter/src/typescript.rs +++ b/interpreter/src/typescript.rs @@ -289,9 +289,27 @@ function listView(view: string): ViewDef { .any(|f| f.name == field_info.field_name); if !already_exists { + // For computed fields, check field_mappings for resolver type info + let field_path = format!("{}.{}", section.name, field_info.field_name); + let effective_field_info = + if let Some(mapping) = self.spec.field_mappings.get(&field_path) { + // Use mapping's inner_type if it's a resolver output type + if mapping + .inner_type + .as_ref() + .map_or(false, |t| is_builtin_resolver_type(t)) + { + mapping + } else { + field_info + } + } else { + field_info + }; + section_fields.push(TypeScriptField { name: field_info.field_name.clone(), - ts_type: self.field_type_info_to_typescript(field_info), + ts_type: self.field_type_info_to_typescript(effective_field_info), optional: field_info.is_optional, description: None, }); @@ -553,6 +571,7 @@ function listView(view: string): ViewDef { } fn uses_builtin_type(&self, type_name: &str) -> bool { + // Check section fields for section in &self.spec.sections { for field in §ion.fields { if field.inner_type.as_deref() == Some(type_name) { @@ -560,6 +579,12 @@ function listView(view: string): ViewDef { } } } + // Check field_mappings for computed fields (they may have resolver types not in sections) + for (field_path, field_info) in &self.spec.field_mappings { + if field_info.inner_type.as_deref() == Some(type_name) { + return true; + } + } false } diff --git a/stacks/sdk/typescript/src/ore/index.ts b/stacks/sdk/typescript/src/ore/index.ts index e629bc19..f3404f07 100644 --- a/stacks/sdk/typescript/src/ore/index.ts +++ b/stacks/sdk/typescript/src/ore/index.ts @@ -23,8 +23,8 @@ export interface OreRoundMetrics { export interface OreRoundResults { did_hit_motherlode?: boolean | null; - expires_at_slot_hash?: any[] | null; - pre_reveal_rng?: number | null; + expires_at_slot_hash?: SlotHash | null; + pre_reveal_rng?: KeccakRngValue | null; pre_reveal_winning_square?: number | null; rent_payer?: string | null; rng?: number | null; @@ -61,6 +61,13 @@ export interface OreRound { ore_metadata?: TokenMetadata | null; } +export interface SlotHashBytes { + /** 32-byte slot hash as array of numbers (0-255) */ + bytes: number[]; +} + +export type KeccakRngValue = string; + export interface TokenMetadata { mint: string; name?: string | null; @@ -69,6 +76,12 @@ export interface TokenMetadata { logo_uri?: string | null; } +export const SlotHashBytesSchema = z.object({ + bytes: z.array(z.number().int().min(0).max(255)).length(32), +}); + +export const KeccakRngValueSchema = z.string(); + export const TokenMetadataSchema = z.object({ mint: z.string(), name: z.string().nullable().optional(), @@ -100,8 +113,8 @@ export const OreRoundMetricsSchema = z.object({ export const OreRoundResultsSchema = z.object({ did_hit_motherlode: z.boolean().nullable().optional(), - expires_at_slot_hash: z.array(z.any()).nullable().optional(), - pre_reveal_rng: z.number().nullable().optional(), + expires_at_slot_hash: SlotHashSchema.nullable().optional(), + pre_reveal_rng: KeccakRngValueSchema.nullable().optional(), pre_reveal_winning_square: z.number().nullable().optional(), rent_payer: z.string().nullable().optional(), rng: z.number().nullable().optional(), @@ -431,6 +444,7 @@ export const ORE_STREAM_STACK = { OreTreasuryId: OreTreasuryIdSchema, OreTreasury: OreTreasurySchema, OreTreasuryState: OreTreasuryStateSchema, + SlotHashTypes: SlotHashTypes, TokenMetadata: TokenMetadataSchema, Treasury: TreasurySchema, }, From b37ef43e93d5c20903b01831424d94f6bb86bd72 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 07:29:19 +0000 Subject: [PATCH 48/60] fix: correct resolver output types and schema generation in TypeScript emitter - Map `slot_hash` resolver method to `SlotHashBytes` (not `SlotHash`) so the interface and Zod schema names match what the resolver actually declares - Extend `is_output_type()` to recognise types declared via `export interface` in addition to type aliases, so `SlotHashBytes` is found as a builtin type - Extend `generate_builtin_resolver_interfaces/schemas` to emit the full resolver block whenever any type it declares is used (not just the primary output_type), covering the `KeccakRngValue`/`SlotHashBytes` split - Filter the schemas const-block to only include `*Schema`-named entries in both the single-entity and multi-entity code paths, preventing bare group names like `SlotHashTypes` from leaking into the stack object --- hyperstack-macros/src/stream_spec/computed.rs | 2 +- interpreter/src/resolvers.rs | 5 ++ interpreter/src/typescript.rs | 80 ++++++++++++++++--- stacks/ore/.hyperstack/OreStream.stack.json | 6 +- stacks/sdk/typescript/src/ore/index.ts | 27 +++---- 5 files changed, 93 insertions(+), 27 deletions(-) diff --git a/hyperstack-macros/src/stream_spec/computed.rs b/hyperstack-macros/src/stream_spec/computed.rs index a2073349..0a3dbb10 100644 --- a/hyperstack-macros/src/stream_spec/computed.rs +++ b/hyperstack-macros/src/stream_spec/computed.rs @@ -43,7 +43,7 @@ fn resolver_for_method(method: &str) -> Option<&'static str> { /// This maps resolver method names to their TypeScript output type names. pub fn resolver_output_type(method: &str) -> Option<&'static str> { match method { - "slot_hash" => Some("SlotHash"), + "slot_hash" => Some("SlotHashBytes"), "keccak_rng" => Some("KeccakRngValue"), "ui_amount" => Some("TokenUiAmount"), "raw_amount" => Some("TokenRawAmount"), diff --git a/interpreter/src/resolvers.rs b/interpreter/src/resolvers.rs index 28030dbe..c5c32c00 100644 --- a/interpreter/src/resolvers.rs +++ b/interpreter/src/resolvers.rs @@ -170,6 +170,11 @@ impl ResolverRegistry { if interface.contains(&type_pattern) { return true; } + // Look for interfaces like: export interface TypeName ... + let interface_pattern = format!("export interface {}", type_name); + if interface.contains(&interface_pattern) { + return true; + } } false }) diff --git a/interpreter/src/typescript.rs b/interpreter/src/typescript.rs index 00ba2345..654300b1 100644 --- a/interpreter/src/typescript.rs +++ b/interpreter/src/typescript.rs @@ -297,7 +297,7 @@ function listView(view: string): ViewDef { if mapping .inner_type .as_ref() - .map_or(false, |t| is_builtin_resolver_type(t)) + .is_some_and(|t| is_builtin_resolver_type(t)) { mapping } else { @@ -558,8 +558,35 @@ function listView(view: string): ViewDef { let registry = crate::resolvers::builtin_resolver_registry(); for resolver in registry.definitions() { - if self.uses_builtin_type(resolver.output_type()) - && !self.already_emitted_types.contains(resolver.output_type()) + let output_type = resolver.output_type(); + let should_emit = self.uses_builtin_type(output_type) + && !self.already_emitted_types.contains(output_type); + + // Also check if any types from the resolver's typescript_schema are used + let extra_types_used = if let Some(ts_schema) = resolver.typescript_schema() { + // Extract type names from export statements (simple string parsing) + ts_schema.definition.lines().any(|line| { + let line = line.trim(); + // Match "export const TypeNameSchema" + if let Some(rest) = line.strip_prefix("export const ") { + let parts: Vec<&str> = rest.split_whitespace().collect(); + if parts.len() >= 2 && parts[1] == "=" { + // Extract the base type name from "TypeNameSchema" + let schema_name = parts[0]; + if let Some(type_name) = schema_name.strip_suffix("Schema") { + return self.uses_builtin_type(type_name) + && !self.already_emitted_types.contains(type_name); + } + } + } + false + }) + } else { + false + }; + + if (should_emit || extra_types_used) + && !self.already_emitted_types.contains(output_type) { if let Some(schema) = resolver.typescript_schema() { schemas.push((schema.name.to_string(), schema.definition.to_string())); @@ -580,7 +607,7 @@ function listView(view: string): ViewDef { } } // Check field_mappings for computed fields (they may have resolver types not in sections) - for (field_path, field_info) in &self.spec.field_mappings { + for (_field_path, field_info) in &self.spec.field_mappings { if field_info.inner_type.as_deref() == Some(type_name) { return true; } @@ -593,9 +620,34 @@ function listView(view: string): ViewDef { let registry = crate::resolvers::builtin_resolver_registry(); for resolver in registry.definitions() { - if self.uses_builtin_type(resolver.output_type()) - && !self.already_emitted_types.contains(resolver.output_type()) - { + let output_type = resolver.output_type(); + let should_emit = self.uses_builtin_type(output_type) + && !self.already_emitted_types.contains(output_type); + + // Also check if any types from the resolver's typescript_interface are used + let extra_types_used = if let Some(ts_interface) = resolver.typescript_interface() { + // Extract type names from export statements (simple string parsing) + ts_interface.lines().any(|line| { + let line = line.trim(); + // Match "export type TypeName" or "export interface TypeName" + if let Some(rest) = line.strip_prefix("export type ") { + if let Some(type_name) = rest.split_whitespace().next() { + return self.uses_builtin_type(type_name) + && !self.already_emitted_types.contains(type_name); + } + } else if let Some(rest) = line.strip_prefix("export interface ") { + if let Some(type_name) = rest.split_whitespace().next() { + return self.uses_builtin_type(type_name) + && !self.already_emitted_types.contains(type_name); + } + } + false + }) + } else { + false + }; + + if should_emit || extra_types_used { if let Some(interface) = resolver.typescript_interface() { interfaces.push(interface.to_string()); } @@ -974,9 +1026,14 @@ function listView(view: string): ViewDef { } else { let schema_entries: Vec = unique_schemas .iter() + .filter(|name| name.ends_with("Schema")) .map(|name| format!(" {}: {},", name.trim_end_matches("Schema"), name)) .collect(); - format!("\n schemas: {{\n{}\n }},", schema_entries.join("\n")) + if schema_entries.is_empty() { + String::new() + } else { + format!("\n schemas: {{\n{}\n }},", schema_entries.join("\n")) + } }; // Generate URL line - either actual URL or placeholder comment @@ -2092,9 +2149,14 @@ fn generate_stack_definition_multi( } else { let schema_entries: Vec = unique_schemas .iter() + .filter(|name| name.ends_with("Schema")) .map(|name| format!(" {}: {},", name.trim_end_matches("Schema"), name)) .collect(); - format!("\n schemas: {{\n{}\n }},", schema_entries.join("\n")) + if schema_entries.is_empty() { + String::new() + } else { + format!("\n schemas: {{\n{}\n }},", schema_entries.join("\n")) + } }; let entity_types: Vec = entity_names.iter().map(|n| to_pascal_case(n)).collect(); diff --git a/stacks/ore/.hyperstack/OreStream.stack.json b/stacks/ore/.hyperstack/OreStream.stack.json index 2dc40862..742d6fa4 100644 --- a/stacks/ore/.hyperstack/OreStream.stack.json +++ b/stacks/ore/.hyperstack/OreStream.stack.json @@ -4025,7 +4025,7 @@ "base_type": "Array", "is_optional": true, "is_array": true, - "inner_type": "SlotHash", + "inner_type": "SlotHashBytes", "source_path": null, "resolved_type": null }, @@ -5214,7 +5214,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "be2cac5010099fdf867871a3a4f3904f2cd290f5fcafd2933f7c9d5f02d47ec1", + "content_hash": "ecfad36cebb6a104a85ac59728fe4894ce668f8e9ef41085ce9add942622f503", "views": [ { "id": "OreRound/latest", @@ -9114,5 +9114,5 @@ ] } ], - "content_hash": "268bee113d011a0a49d48573aff397cfb5ca7baa180899050aa61f5719bcf070" + "content_hash": "69c671a42d1a1f13d3cb41d873c164ef21d4de4c840e47564b75eee05d7eb5f0" } \ No newline at end of file diff --git a/stacks/sdk/typescript/src/ore/index.ts b/stacks/sdk/typescript/src/ore/index.ts index f3404f07..0877c9a5 100644 --- a/stacks/sdk/typescript/src/ore/index.ts +++ b/stacks/sdk/typescript/src/ore/index.ts @@ -23,7 +23,7 @@ export interface OreRoundMetrics { export interface OreRoundResults { did_hit_motherlode?: boolean | null; - expires_at_slot_hash?: SlotHash | null; + expires_at_slot_hash?: SlotHashBytes | null; pre_reveal_rng?: KeccakRngValue | null; pre_reveal_winning_square?: number | null; rent_payer?: string | null; @@ -61,13 +61,6 @@ export interface OreRound { ore_metadata?: TokenMetadata | null; } -export interface SlotHashBytes { - /** 32-byte slot hash as array of numbers (0-255) */ - bytes: number[]; -} - -export type KeccakRngValue = string; - export interface TokenMetadata { mint: string; name?: string | null; @@ -76,11 +69,12 @@ export interface TokenMetadata { logo_uri?: string | null; } -export const SlotHashBytesSchema = z.object({ - bytes: z.array(z.number().int().min(0).max(255)).length(32), -}); +export interface SlotHashBytes { + /** 32-byte slot hash as array of numbers (0-255) */ + bytes: number[]; +} -export const KeccakRngValueSchema = z.string(); +export type KeccakRngValue = string; export const TokenMetadataSchema = z.object({ mint: z.string(), @@ -90,6 +84,12 @@ export const TokenMetadataSchema = z.object({ logo_uri: z.string().nullable().optional(), }); +export const SlotHashBytesSchema = z.object({ + bytes: z.array(z.number().int().min(0).max(255)).length(32), +}); + +export const KeccakRngValueSchema = z.string(); + export const OreRoundEntropySchema = z.object({ entropy_end_at: z.number().nullable().optional(), entropy_samples: z.number().nullable().optional(), @@ -113,7 +113,7 @@ export const OreRoundMetricsSchema = z.object({ export const OreRoundResultsSchema = z.object({ did_hit_motherlode: z.boolean().nullable().optional(), - expires_at_slot_hash: SlotHashSchema.nullable().optional(), + expires_at_slot_hash: SlotHashBytesSchema.nullable().optional(), pre_reveal_rng: KeccakRngValueSchema.nullable().optional(), pre_reveal_winning_square: z.number().nullable().optional(), rent_payer: z.string().nullable().optional(), @@ -444,7 +444,6 @@ export const ORE_STREAM_STACK = { OreTreasuryId: OreTreasuryIdSchema, OreTreasury: OreTreasurySchema, OreTreasuryState: OreTreasuryStateSchema, - SlotHashTypes: SlotHashTypes, TokenMetadata: TokenMetadataSchema, Treasury: TreasurySchema, }, From 663f85ec55a550dc660582e957ec192476f5f3a9 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 07:34:27 +0000 Subject: [PATCH 49/60] chore: fix clippy for-kv-map lint in typescript field_mappings loop --- interpreter/src/typescript.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/src/typescript.rs b/interpreter/src/typescript.rs index 654300b1..079f6591 100644 --- a/interpreter/src/typescript.rs +++ b/interpreter/src/typescript.rs @@ -607,7 +607,7 @@ function listView(view: string): ViewDef { } } // Check field_mappings for computed fields (they may have resolver types not in sections) - for (_field_path, field_info) in &self.spec.field_mappings { + for field_info in self.spec.field_mappings.values() { if field_info.inner_type.as_deref() == Some(type_name) { return true; } From 5f423dacf10fb9beae9659e29e444e6becef67c8 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 07:51:59 +0000 Subject: [PATCH 50/60] fix: Ore sdk --- stacks/sdk/typescript/src/ore/index.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/stacks/sdk/typescript/src/ore/index.ts b/stacks/sdk/typescript/src/ore/index.ts index 0877c9a5..b0d5cd81 100644 --- a/stacks/sdk/typescript/src/ore/index.ts +++ b/stacks/sdk/typescript/src/ore/index.ts @@ -61,6 +61,13 @@ export interface OreRound { ore_metadata?: TokenMetadata | null; } +export interface SlotHashBytes { + /** 32-byte slot hash as array of numbers (0-255) */ + bytes: number[]; +} + +export type KeccakRngValue = string; + export interface TokenMetadata { mint: string; name?: string | null; @@ -69,12 +76,11 @@ export interface TokenMetadata { logo_uri?: string | null; } -export interface SlotHashBytes { - /** 32-byte slot hash as array of numbers (0-255) */ - bytes: number[]; -} +export const SlotHashBytesSchema = z.object({ + bytes: z.array(z.number().int().min(0).max(255)).length(32), +}); -export type KeccakRngValue = string; +export const KeccakRngValueSchema = z.string(); export const TokenMetadataSchema = z.object({ mint: z.string(), @@ -84,12 +90,6 @@ export const TokenMetadataSchema = z.object({ logo_uri: z.string().nullable().optional(), }); -export const SlotHashBytesSchema = z.object({ - bytes: z.array(z.number().int().min(0).max(255)).length(32), -}); - -export const KeccakRngValueSchema = z.string(); - export const OreRoundEntropySchema = z.object({ entropy_end_at: z.number().nullable().optional(), entropy_samples: z.number().nullable().optional(), From 0129f75ad443b9340a38f8da256ab6f8c977d1e2 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 08:04:46 +0000 Subject: [PATCH 51/60] fix: use BTreeMap in ResolverRegistry to ensure deterministic SDK output --- interpreter/src/resolvers.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interpreter/src/resolvers.rs b/interpreter/src/resolvers.rs index c5c32c00..ad61a884 100644 --- a/interpreter/src/resolvers.rs +++ b/interpreter/src/resolvers.rs @@ -1,4 +1,4 @@ -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeMap, HashMap, HashSet}; use std::sync::OnceLock; use futures::future::join_all; @@ -129,7 +129,7 @@ pub trait ResolverDefinition: Send + Sync { } pub struct ResolverRegistry { - resolvers: HashMap>, + resolvers: BTreeMap>, } impl Default for ResolverRegistry { @@ -141,7 +141,7 @@ impl Default for ResolverRegistry { impl ResolverRegistry { pub fn new() -> Self { Self { - resolvers: HashMap::new(), + resolvers: BTreeMap::new(), } } From eb396c9c4ecc5df63688df60a504dd21cd18b5e7 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 08:05:45 +0000 Subject: [PATCH 52/60] chore: Ore stack --- stacks/ore/.hyperstack/OreStream.stack.json | 56 ++++++++++----------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/stacks/ore/.hyperstack/OreStream.stack.json b/stacks/ore/.hyperstack/OreStream.stack.json index 742d6fa4..9f581975 100644 --- a/stacks/ore/.hyperstack/OreStream.stack.json +++ b/stacks/ore/.hyperstack/OreStream.stack.json @@ -4233,24 +4233,24 @@ }, "resolver_hooks": [ { - "account_type": "entropy::VarState", + "account_type": "ore::TreasuryState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [] + "queue_discriminators": [ + [ + 9 + ] + ] } } }, { - "account_type": "ore::TreasuryState", + "account_type": "entropy::VarState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [ - [ - 9 - ] - ] + "queue_discriminators": [] } } } @@ -5214,7 +5214,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "ecfad36cebb6a104a85ac59728fe4894ce668f8e9ef41085ce9add942622f503", + "content_hash": "7da22a62f17d58cd93d7038f54a9e9e759e19932881e8b862270044316a0a43e", "views": [ { "id": "OreRound/latest", @@ -5703,24 +5703,24 @@ }, "resolver_hooks": [ { - "account_type": "entropy::VarState", + "account_type": "ore::TreasuryState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [] + "queue_discriminators": [ + [ + 9 + ] + ] } } }, { - "account_type": "ore::TreasuryState", + "account_type": "entropy::VarState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [ - [ - 9 - ] - ] + "queue_discriminators": [] } } } @@ -5823,7 +5823,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "4b680401e840febd69cd77fe8db0716267b83525028af37a5e05ef65cfdc52a4", + "content_hash": "3e6bf64fc20802888bfe8407bb44f4e84ffb7125075b32a52a261109872a0be3", "views": [] }, { @@ -7148,24 +7148,24 @@ }, "resolver_hooks": [ { - "account_type": "entropy::VarState", + "account_type": "ore::TreasuryState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [] + "queue_discriminators": [ + [ + 9 + ] + ] } } }, { - "account_type": "ore::TreasuryState", + "account_type": "entropy::VarState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [ - [ - 9 - ] - ] + "queue_discriminators": [] } } } @@ -7174,7 +7174,7 @@ "resolver_specs": [], "computed_fields": [], "computed_field_specs": [], - "content_hash": "40a0247d41dc28a177b8e4e74f518d34a1b6810695600fb2dd6d1f92795eaa3c", + "content_hash": "09a53443efc060de74ec1b49ab15d77dbd9afed04a4b9bbbe094ca6d84d06462", "views": [] } ], @@ -9114,5 +9114,5 @@ ] } ], - "content_hash": "69c671a42d1a1f13d3cb41d873c164ef21d4de4c840e47564b75eee05d7eb5f0" + "content_hash": "46f513eef3ec941b80a2174a660b83ffefa452dcd377501f0482580a695f9004" } \ No newline at end of file From f4de6ef1a835f204a8af39b4610481356bd62410 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 08:16:56 +0000 Subject: [PATCH 53/60] fix: replace silent u8 truncation of Steel discriminant with try_from --- hyperstack-idl/src/snapshot.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hyperstack-idl/src/snapshot.rs b/hyperstack-idl/src/snapshot.rs index 5cc4fddd..201df03b 100644 --- a/hyperstack-idl/src/snapshot.rs +++ b/hyperstack-idl/src/snapshot.rs @@ -176,7 +176,8 @@ impl IdlInstructionSnapshot { } if let Some(disc) = &self.discriminant { - let value = disc.value as u8; + let value = + u8::try_from(disc.value).expect("Steel discriminant value exceeds u8::MAX (255)"); return vec![value]; } From 247ffa37b3656677e4ede419c22ab99c2b8bf077 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 08:18:57 +0000 Subject: [PATCH 54/60] fix: wrap slot hash bytes in object to match SlotHashBytes schema --- interpreter/src/resolvers.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/interpreter/src/resolvers.rs b/interpreter/src/resolvers.rs index ad61a884..1f65b7cf 100644 --- a/interpreter/src/resolvers.rs +++ b/interpreter/src/resolvers.rs @@ -846,9 +846,11 @@ impl SlotHashResolver { // The slot hash is a 32-byte value base58 encoded match bs58::decode(&hash).into_vec() { Ok(bytes) if bytes.len() == 32 => { - // Return as JSON array of bytes + // Return as { bytes: [...] } to match the SlotHashBytes TypeScript interface let json_bytes: Vec = bytes.into_iter().map(|b| Value::Number(b.into())).collect(); - Ok(Value::Array(json_bytes)) + let mut obj = serde_json::Map::new(); + obj.insert("bytes".to_string(), Value::Array(json_bytes)); + Ok(Value::Object(obj)) } _ => { tracing::warn!(slot = slot, hash = hash, "Failed to decode slot hash"); From 1b59633f542dad2e140e914ff3e787019dd75944 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 08:19:02 +0000 Subject: [PATCH 55/60] fix: cache account data for all entity states that route an event type --- .../src/codegen/vixen_runtime.rs | 94 ++++++++++--------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/hyperstack-macros/src/codegen/vixen_runtime.rs b/hyperstack-macros/src/codegen/vixen_runtime.rs index 0c9c5aa4..72d9243b 100644 --- a/hyperstack-macros/src/codegen/vixen_runtime.rs +++ b/hyperstack-macros/src/codegen/vixen_runtime.rs @@ -970,29 +970,30 @@ pub fn generate_vm_handler( // mapping later changes (same PDA, different seed) the cached // data is returned for reprocessing with the corrected mapping. if result.is_ok() { - // Derive state_id from bytecode routing (same logic as process_event) - let state_id = self.bytecode.event_routing.get(event_type) - .and_then(|entities| entities.first()) - .and_then(|entity_name| self.bytecode.entities.get(entity_name)) - .map(|eb| eb.state_id) - .unwrap_or(0); - vm.cache_last_account_data( - state_id, - &account_address, - hyperstack::runtime::hyperstack_interpreter::PendingAccountUpdate { - account_type: event_type.to_string(), - pda_address: account_address.clone(), - account_data: event_value_for_cache, - slot, - write_version, - signature: signature.clone(), - queued_at: std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap_or_default() - .as_secs() as i64, - is_stale_reprocess: false, - }, - ); + // Cache under every state_id that routes this event_type so that + // register_pda_reverse_lookup finds data for all participating entities. + let state_ids: std::collections::HashSet = self.bytecode.event_routing + .get(event_type) + .map(|entities| entities.iter() + .filter_map(|name| self.bytecode.entities.get(name).map(|eb| eb.state_id)) + .collect()) + .unwrap_or_default(); + let pending = hyperstack::runtime::hyperstack_interpreter::PendingAccountUpdate { + account_type: event_type.to_string(), + pda_address: account_address.clone(), + account_data: event_value_for_cache, + slot, + write_version, + signature: signature.clone(), + queued_at: std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_secs() as i64, + is_stale_reprocess: false, + }; + for state_id in state_ids { + vm.cache_last_account_data(state_id, &account_address, pending.clone()); + } } let requests = if result.is_ok() { @@ -2031,29 +2032,30 @@ pub fn generate_account_handler_impl( .map_err(|e| e.to_string()); if result.is_ok() { - // Derive state_id from bytecode routing (same logic as process_event) - let state_id = self.bytecode.event_routing.get(event_type) - .and_then(|entities| entities.first()) - .and_then(|entity_name| self.bytecode.entities.get(entity_name)) - .map(|eb| eb.state_id) - .unwrap_or(0); - vm.cache_last_account_data( - state_id, - &account_address, - hyperstack::runtime::hyperstack_interpreter::PendingAccountUpdate { - account_type: event_type.to_string(), - pda_address: account_address.clone(), - account_data: event_value_for_cache, - slot, - write_version, - signature: signature.clone(), - queued_at: std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap_or_default() - .as_secs() as i64, - is_stale_reprocess: false, - }, - ); + // Cache under every state_id that routes this event_type so that + // register_pda_reverse_lookup finds data for all participating entities. + let state_ids: std::collections::HashSet = self.bytecode.event_routing + .get(event_type) + .map(|entities| entities.iter() + .filter_map(|name| self.bytecode.entities.get(name).map(|eb| eb.state_id)) + .collect()) + .unwrap_or_default(); + let pending = hyperstack::runtime::hyperstack_interpreter::PendingAccountUpdate { + account_type: event_type.to_string(), + pda_address: account_address.clone(), + account_data: event_value_for_cache, + slot, + write_version, + signature: signature.clone(), + queued_at: std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_secs() as i64, + is_stale_reprocess: false, + }; + for state_id in state_ids { + vm.cache_last_account_data(state_id, &account_address, pending.clone()); + } } let requests = if result.is_ok() { From 7dae442780bfe03ebc972af3301532592a6201c0 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 08:25:31 +0000 Subject: [PATCH 56/60] refactor: replace AbortIfNullKey is_account string heuristic with structural SourceSpec field --- hyperstack-macros/src/ast/types.rs | 3 +++ hyperstack-macros/src/ast/writer.rs | 1 + hyperstack-macros/src/codegen/handlers.rs | 2 ++ hyperstack-macros/src/stream_spec/ast_writer.rs | 2 ++ hyperstack-macros/src/stream_spec/proto_struct.rs | 2 ++ interpreter/src/ast.rs | 6 ++++++ interpreter/src/compiler.rs | 9 +++++++-- 7 files changed, 23 insertions(+), 2 deletions(-) diff --git a/hyperstack-macros/src/ast/types.rs b/hyperstack-macros/src/ast/types.rs index 6d5652fb..b01f437d 100644 --- a/hyperstack-macros/src/ast/types.rs +++ b/hyperstack-macros/src/ast/types.rs @@ -379,6 +379,9 @@ pub enum SourceSpec { type_name: String, #[serde(default, skip_serializing_if = "Option::is_none")] serialization: Option, + /// True when this handler listens to an account-state event. + #[serde(default)] + is_account: bool, }, } diff --git a/hyperstack-macros/src/ast/writer.rs b/hyperstack-macros/src/ast/writer.rs index 7ae07654..37ab0252 100644 --- a/hyperstack-macros/src/ast/writer.rs +++ b/hyperstack-macros/src/ast/writer.rs @@ -618,6 +618,7 @@ pub fn build_handlers_from_sources( discriminator: None, type_name, serialization, + is_account: !is_instruction && !is_cpi_event, }, key_resolution, mappings: serializable_mappings, diff --git a/hyperstack-macros/src/codegen/handlers.rs b/hyperstack-macros/src/codegen/handlers.rs index 1e0e2d20..08112665 100644 --- a/hyperstack-macros/src/codegen/handlers.rs +++ b/hyperstack-macros/src/codegen/handlers.rs @@ -92,6 +92,7 @@ fn build_source_spec_code(source: &SourceSpec) -> TokenStream { discriminator, type_name, serialization, + is_account, } => { let program_id_code = match program_id { Some(id) => quote! { Some(#id.to_string()) }, @@ -125,6 +126,7 @@ fn build_source_spec_code(source: &SourceSpec) -> TokenStream { discriminator: #discriminator_code, type_name: #type_name.to_string(), serialization: #serialization_code, + is_account: #is_account, } } } diff --git a/hyperstack-macros/src/stream_spec/ast_writer.rs b/hyperstack-macros/src/stream_spec/ast_writer.rs index 669ec806..e66618e4 100644 --- a/hyperstack-macros/src/stream_spec/ast_writer.rs +++ b/hyperstack-macros/src/stream_spec/ast_writer.rs @@ -749,6 +749,7 @@ fn build_source_handler( discriminator: None, type_name, serialization, + is_account: !is_instruction && !is_cpi_event, }, key_resolution, mappings: serializable_mappings, @@ -973,6 +974,7 @@ fn build_event_handler( discriminator: None, type_name, serialization: None, + is_account: false, }, key_resolution, mappings: serializable_mappings, diff --git a/hyperstack-macros/src/stream_spec/proto_struct.rs b/hyperstack-macros/src/stream_spec/proto_struct.rs index 3869fe40..c1353282 100644 --- a/hyperstack-macros/src/stream_spec/proto_struct.rs +++ b/hyperstack-macros/src/stream_spec/proto_struct.rs @@ -368,6 +368,7 @@ pub fn process_struct_with_context( }; let type_suffix = if is_instruction { "IxState" } else { "State" }; + let is_account_source = !is_instruction; handler_fns.push(quote! { fn #handler_name() -> hyperstack::runtime::hyperstack_interpreter::ast::TypedHandlerSpec<#state_name> { hyperstack::runtime::hyperstack_interpreter::ast::TypedHandlerSpec::new( @@ -376,6 +377,7 @@ pub fn process_struct_with_context( discriminator: None, type_name: format!("{}{}", #account_type, #type_suffix), serialization: None, + is_account: #is_account_source, }, #key_resolution, vec![ diff --git a/interpreter/src/ast.rs b/interpreter/src/ast.rs index bbc6a83b..74e1293e 100644 --- a/interpreter/src/ast.rs +++ b/interpreter/src/ast.rs @@ -739,6 +739,12 @@ pub enum SourceSpec { type_name: String, #[serde(default, skip_serializing_if = "Option::is_none")] serialization: Option, + /// True when this handler listens to an account-state event (not an + /// instruction or custom event). Set at code-generation time from + /// the structural source kind so the compiler does not need to rely + /// on naming-convention heuristics. + #[serde(default)] + is_account: bool, }, } diff --git a/interpreter/src/compiler.rs b/interpreter/src/compiler.rs index e9484519..7816d91a 100644 --- a/interpreter/src/compiler.rs +++ b/interpreter/src/compiler.rs @@ -679,8 +679,13 @@ impl TypedCompiler { // for later reprocessing. Without this, downstream opcodes would // create a phantom entity keyed by null and produce non-empty // mutations that prevent queueing. - let event_type = self.get_event_type(&spec.source); - let is_account_event = event_type.ends_with("State") && !event_type.ends_with("IxState"); + let is_account_event = matches!( + spec.source, + SourceSpec::Source { + is_account: true, + .. + } + ); ops.push(OpCode::AbortIfNullKey { key: key_reg, is_account_event, From fa09ef9cce75b64df295971c35ade31a724522c5 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 08:35:29 +0000 Subject: [PATCH 57/60] fix: replace panicking expect with graceful fallback in get_discriminator --- Cargo.lock | 1 + hyperstack-idl/Cargo.toml | 1 + hyperstack-idl/src/snapshot.rs | 13 ++++++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff1f6265..31457034 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1684,6 +1684,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "strsim", + "tracing", ] [[package]] diff --git a/hyperstack-idl/Cargo.toml b/hyperstack-idl/Cargo.toml index 5df1fc6b..0d040afc 100644 --- a/hyperstack-idl/Cargo.toml +++ b/hyperstack-idl/Cargo.toml @@ -16,3 +16,4 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" sha2 = "0.10" strsim = "0.11" +tracing = "0.1" diff --git a/hyperstack-idl/src/snapshot.rs b/hyperstack-idl/src/snapshot.rs index 201df03b..66a60933 100644 --- a/hyperstack-idl/src/snapshot.rs +++ b/hyperstack-idl/src/snapshot.rs @@ -176,9 +176,16 @@ impl IdlInstructionSnapshot { } if let Some(disc) = &self.discriminant { - let value = - u8::try_from(disc.value).expect("Steel discriminant value exceeds u8::MAX (255)"); - return vec![value]; + match u8::try_from(disc.value) { + Ok(value) => return vec![value], + Err(_) => { + tracing::warn!( + instruction = %self.name, + value = disc.value, + "Steel discriminant exceeds u8::MAX; falling back to Anchor hash" + ); + } + } } crate::discriminator::anchor_discriminator(&format!("global:{}", self.name)) From 7c60332338263aba907728a50293854e366de1d8 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 08:46:30 +0000 Subject: [PATCH 58/60] refactor: replace string-scanning in is_output_type with explicit extra_output_types trait method --- interpreter/src/resolvers.rs | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/interpreter/src/resolvers.rs b/interpreter/src/resolvers.rs index 1f65b7cf..d3667bd3 100644 --- a/interpreter/src/resolvers.rs +++ b/interpreter/src/resolvers.rs @@ -126,6 +126,9 @@ pub trait ResolverDefinition: Send + Sync { fn typescript_schema(&self) -> Option { None } + fn extra_output_types(&self) -> &'static [&'static str] { + &[] + } } pub struct ResolverRegistry { @@ -159,24 +162,8 @@ impl ResolverRegistry { pub fn is_output_type(&self, type_name: &str) -> bool { self.resolvers.values().any(|resolver| { - // Check primary output type - if resolver.output_type() == type_name { - return true; - } - // Check for additional types defined in typescript_interface - if let Some(interface) = resolver.typescript_interface() { - // Look for type aliases like: export type TypeName = ... - let type_pattern = format!("export type {} =", type_name); - if interface.contains(&type_pattern) { - return true; - } - // Look for interfaces like: export interface TypeName ... - let interface_pattern = format!("export interface {}", type_name); - if interface.contains(&interface_pattern) { - return true; - } - } - false + resolver.output_type() == type_name + || resolver.extra_output_types().contains(&type_name) }) } @@ -902,6 +889,10 @@ export type KeccakRngValue = string;"#, ) } + fn extra_output_types(&self) -> &'static [&'static str] { + &["SlotHashBytes", "KeccakRngValue"] + } + fn typescript_schema(&self) -> Option { Some(ResolverTypeScriptSchema { name: "SlotHashTypes", From 1f67a7a9589823262a972ea01c71ad4e04e24ffe Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 08:46:51 +0000 Subject: [PATCH 59/60] fix: serialize u64-from-bytes computed fields as strings to avoid JS precision loss --- .../src/stream_spec/ast_writer.rs | 24 +++++++++-- hyperstack-macros/src/stream_spec/computed.rs | 41 +++++++++++++++++++ interpreter/src/vm.rs | 4 +- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/hyperstack-macros/src/stream_spec/ast_writer.rs b/hyperstack-macros/src/stream_spec/ast_writer.rs index e66618e4..eb50026c 100644 --- a/hyperstack-macros/src/stream_spec/ast_writer.rs +++ b/hyperstack-macros/src/stream_spec/ast_writer.rs @@ -26,7 +26,8 @@ use crate::parse::idl as idl_parser; use crate::utils::path_to_string; use super::computed::{ - extract_resolver_type_from_computed_expr, parse_computed_expression, qualify_field_refs, + expr_contains_u64_from_bytes, extract_resolver_type_from_computed_expr, + parse_computed_expression, qualify_field_refs, }; use super::handlers::{find_field_in_instruction, get_join_on_field}; @@ -154,9 +155,24 @@ pub fn build_ast( // Add computed fields to field_mappings with resolver type information // This ensures computed fields that use resolvers get proper TypeScript schema generation for computed_spec in &computed_field_specs { - if let Some(resolver_type) = - extract_resolver_type_from_computed_expr(&computed_spec.expression) - { + // Determine the TypeScript type override for this computed field. + // Priority 1: explicit resolver method (e.g. .keccak_rng(...)) → its declared output type. + // Priority 2: expression assembles a u64 from raw bytes → "KeccakRngValue" (string), + // because values span [0, 2^64-1] and exceed Number.MAX_SAFE_INTEGER. + let resolver_type: Option<&'static str> = + extract_resolver_type_from_computed_expr(&computed_spec.expression).or_else(|| { + let result_type = &computed_spec.result_type; + let is_u64 = result_type == "u64" + || result_type == "Option < u64 >" + || result_type == "Option"; + if is_u64 && expr_contains_u64_from_bytes(&computed_spec.expression) { + Some("KeccakRngValue") + } else { + None + } + }); + + if let Some(resolver_type) = resolver_type { // Parse the result type to determine if it's optional and if it's an array let result_type = &computed_spec.result_type; let is_optional = diff --git a/hyperstack-macros/src/stream_spec/computed.rs b/hyperstack-macros/src/stream_spec/computed.rs index 0a3dbb10..564ea089 100644 --- a/hyperstack-macros/src/stream_spec/computed.rs +++ b/hyperstack-macros/src/stream_spec/computed.rs @@ -51,6 +51,47 @@ pub fn resolver_output_type(method: &str) -> Option<&'static str> { } } +/// Returns true if the expression tree contains any U64FromLeBytes or U64FromBeBytes node. +/// Used to detect full-range u64 computations that must be serialized as strings in TypeScript. +pub fn expr_contains_u64_from_bytes(expr: &crate::ast::ComputedExpr) -> bool { + use crate::ast::ComputedExpr; + match expr { + ComputedExpr::U64FromLeBytes { .. } | ComputedExpr::U64FromBeBytes { .. } => true, + ComputedExpr::Some { value } => expr_contains_u64_from_bytes(value), + ComputedExpr::Paren { expr } => expr_contains_u64_from_bytes(expr), + ComputedExpr::Binary { left, right, .. } => { + expr_contains_u64_from_bytes(left) || expr_contains_u64_from_bytes(right) + } + ComputedExpr::Unary { expr, .. } => expr_contains_u64_from_bytes(expr), + ComputedExpr::MethodCall { expr, args, .. } => { + expr_contains_u64_from_bytes(expr) || args.iter().any(expr_contains_u64_from_bytes) + } + ComputedExpr::Cast { expr, .. } => expr_contains_u64_from_bytes(expr), + ComputedExpr::UnwrapOr { expr, .. } => expr_contains_u64_from_bytes(expr), + ComputedExpr::Slice { expr, .. } => expr_contains_u64_from_bytes(expr), + ComputedExpr::Index { expr, .. } => expr_contains_u64_from_bytes(expr), + ComputedExpr::Let { value, body, .. } => { + expr_contains_u64_from_bytes(value) || expr_contains_u64_from_bytes(body) + } + ComputedExpr::If { + condition: _, + then_branch, + else_branch, + } => expr_contains_u64_from_bytes(then_branch) || expr_contains_u64_from_bytes(else_branch), + ComputedExpr::Keccak256 { expr } => expr_contains_u64_from_bytes(expr), + ComputedExpr::JsonToBytes { expr } => expr_contains_u64_from_bytes(expr), + ComputedExpr::Closure { body, .. } => expr_contains_u64_from_bytes(body), + ComputedExpr::ResolverComputed { .. } + | ComputedExpr::FieldRef { .. } + | ComputedExpr::Var { .. } + | ComputedExpr::Literal { .. } + | ComputedExpr::ByteArray { .. } + | ComputedExpr::None + | ComputedExpr::ContextSlot + | ComputedExpr::ContextTimestamp => false, + } +} + /// Extract the resolver output type from a computed expression. /// Returns the type name if the expression is a ResolverComputed call. pub fn extract_resolver_type_from_computed_expr( diff --git a/interpreter/src/vm.rs b/interpreter/src/vm.rs index 837ae4c9..fcc4d67c 100644 --- a/interpreter/src/vm.rs +++ b/interpreter/src/vm.rs @@ -4386,7 +4386,7 @@ impl VmContext { let arr: [u8; 8] = byte_vec[..8] .try_into() .map_err(|_| "Failed to convert to [u8; 8]")?; - Ok(json!(u64::from_le_bytes(arr))) + Ok(Value::String(u64::from_le_bytes(arr).to_string())) } ComputedExpr::U64FromBeBytes { bytes } => { @@ -4402,7 +4402,7 @@ impl VmContext { let arr: [u8; 8] = byte_vec[..8] .try_into() .map_err(|_| "Failed to convert to [u8; 8]")?; - Ok(json!(u64::from_be_bytes(arr))) + Ok(Value::String(u64::from_be_bytes(arr).to_string())) } ComputedExpr::ByteArray { bytes } => { From 7af4cf3a82df4ce92a6dba98828406dd8d198419 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Thu, 19 Mar 2026 08:57:22 +0000 Subject: [PATCH 60/60] fix: Keccak types --- stacks/ore/.hyperstack/OreStream.stack.json | 86 +++++++++++---------- stacks/ore/Cargo.lock | 1 + stacks/sdk/typescript/src/ore/index.ts | 4 +- 3 files changed, 50 insertions(+), 41 deletions(-) diff --git a/stacks/ore/.hyperstack/OreStream.stack.json b/stacks/ore/.hyperstack/OreStream.stack.json index 9f581975..7f3c8ca5 100644 --- a/stacks/ore/.hyperstack/OreStream.stack.json +++ b/stacks/ore/.hyperstack/OreStream.stack.json @@ -2792,7 +2792,8 @@ "Source": { "program_id": null, "discriminator": null, - "type_name": "entropy::VarState" + "type_name": "entropy::VarState", + "is_account": true } }, "key_resolution": { @@ -3067,7 +3068,8 @@ "Source": { "program_id": null, "discriminator": null, - "type_name": "ore::RoundState" + "type_name": "ore::RoundState", + "is_account": true } }, "key_resolution": { @@ -3334,7 +3336,8 @@ "Source": { "program_id": null, "discriminator": null, - "type_name": "ore::TreasuryState" + "type_name": "ore::TreasuryState", + "is_account": true } }, "key_resolution": { @@ -3376,7 +3379,8 @@ "Source": { "program_id": null, "discriminator": null, - "type_name": "ore::CheckpointIxState" + "type_name": "ore::CheckpointIxState", + "is_account": false } }, "key_resolution": { @@ -3417,7 +3421,8 @@ "Source": { "program_id": null, "discriminator": null, - "type_name": "ore::DeployIxState" + "type_name": "ore::DeployIxState", + "is_account": false } }, "key_resolution": { @@ -4060,12 +4065,12 @@ "resolved_type": null }, "results.rng": { - "field_name": "rng", + "field_name": "results.rng", "rust_type_name": "Option < u64 >", - "base_type": "Integer", + "base_type": "Any", "is_optional": true, "is_array": false, - "inner_type": "u64", + "inner_type": "KeccakRngValue", "source_path": null, "resolved_type": null }, @@ -4233,24 +4238,24 @@ }, "resolver_hooks": [ { - "account_type": "ore::TreasuryState", + "account_type": "entropy::VarState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [ - [ - 9 - ] - ] + "queue_discriminators": [] } } }, { - "account_type": "entropy::VarState", + "account_type": "ore::TreasuryState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [] + "queue_discriminators": [ + [ + 9 + ] + ] } } } @@ -5214,7 +5219,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "7da22a62f17d58cd93d7038f54a9e9e759e19932881e8b862270044316a0a43e", + "content_hash": "f4f0834dae1b5a90d32250f96663d719c0697d22d3ef7c95b6189ff7a167079e", "views": [ { "id": "OreRound/latest", @@ -5257,7 +5262,8 @@ "Source": { "program_id": null, "discriminator": null, - "type_name": "ore::TreasuryState" + "type_name": "ore::TreasuryState", + "is_account": true } }, "key_resolution": { @@ -5703,24 +5709,24 @@ }, "resolver_hooks": [ { - "account_type": "ore::TreasuryState", + "account_type": "entropy::VarState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [ - [ - 9 - ] - ] + "queue_discriminators": [] } } }, { - "account_type": "entropy::VarState", + "account_type": "ore::TreasuryState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [] + "queue_discriminators": [ + [ + 9 + ] + ] } } } @@ -5823,7 +5829,7 @@ "result_type": "Option < f64 >" } ], - "content_hash": "3e6bf64fc20802888bfe8407bb44f4e84ffb7125075b32a52a261109872a0be3", + "content_hash": "2209440d59e788f8381792812368fc7e1b9bc9f188c8ab8352cc1bf6e05001d5", "views": [] }, { @@ -5848,7 +5854,8 @@ "Source": { "program_id": null, "discriminator": null, - "type_name": "ore::AutomationState" + "type_name": "ore::AutomationState", + "is_account": true } }, "key_resolution": { @@ -6037,7 +6044,8 @@ "Source": { "program_id": null, "discriminator": null, - "type_name": "ore::MinerState" + "type_name": "ore::MinerState", + "is_account": true } }, "key_resolution": { @@ -7148,24 +7156,24 @@ }, "resolver_hooks": [ { - "account_type": "ore::TreasuryState", + "account_type": "entropy::VarState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [ - [ - 9 - ] - ] + "queue_discriminators": [] } } }, { - "account_type": "entropy::VarState", + "account_type": "ore::TreasuryState", "strategy": { "PdaReverseLookup": { "lookup_name": "default_pda_lookup", - "queue_discriminators": [] + "queue_discriminators": [ + [ + 9 + ] + ] } } } @@ -7174,7 +7182,7 @@ "resolver_specs": [], "computed_fields": [], "computed_field_specs": [], - "content_hash": "09a53443efc060de74ec1b49ab15d77dbd9afed04a4b9bbbe094ca6d84d06462", + "content_hash": "22aea1c2e9647ccbed3ff8311ce336354a0b79e8d9ef11933d262faed8b1adb9", "views": [] } ], @@ -9114,5 +9122,5 @@ ] } ], - "content_hash": "46f513eef3ec941b80a2174a660b83ffefa452dcd377501f0482580a695f9004" + "content_hash": "3cb0cdf6716a7a3c096d4b92cdb60adcb8d982b4d6f22d2f96a7381b2583c84f" } \ No newline at end of file diff --git a/stacks/ore/Cargo.lock b/stacks/ore/Cargo.lock index 0641d103..1a8cc4b4 100644 --- a/stacks/ore/Cargo.lock +++ b/stacks/ore/Cargo.lock @@ -1469,6 +1469,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "strsim", + "tracing", ] [[package]] diff --git a/stacks/sdk/typescript/src/ore/index.ts b/stacks/sdk/typescript/src/ore/index.ts index b0d5cd81..9a2497cb 100644 --- a/stacks/sdk/typescript/src/ore/index.ts +++ b/stacks/sdk/typescript/src/ore/index.ts @@ -27,7 +27,7 @@ export interface OreRoundResults { pre_reveal_rng?: KeccakRngValue | null; pre_reveal_winning_square?: number | null; rent_payer?: string | null; - rng?: number | null; + rng?: KeccakRngValue | null; slot_hash?: string | null; top_miner?: string | null; top_miner_reward?: number | null; @@ -117,7 +117,7 @@ export const OreRoundResultsSchema = z.object({ pre_reveal_rng: KeccakRngValueSchema.nullable().optional(), pre_reveal_winning_square: z.number().nullable().optional(), rent_payer: z.string().nullable().optional(), - rng: z.number().nullable().optional(), + rng: KeccakRngValueSchema.nullable().optional(), slot_hash: z.string().nullable().optional(), top_miner: z.string().nullable().optional(), top_miner_reward: z.number().nullable().optional(),