v0.5.3-pre.005-fix010
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/app_state.rs
|
||||
// version: 20
|
||||
// version: 21
|
||||
|
||||
//! Shared Tauri application state and startup initialization.
|
||||
|
||||
@@ -18,6 +18,12 @@ pub(crate) struct AppState {
|
||||
logging_guard: std::sync::Mutex<ks_logging::LoggingGuard>,
|
||||
http_pool: ks_onchain_transport::HttpEndpointPool,
|
||||
store: tokio::sync::OnceCell<ks_store::Store>,
|
||||
profile_stores: tokio::sync::Mutex<
|
||||
std::collections::BTreeMap<
|
||||
std::string::String,
|
||||
std::sync::Arc<tokio::sync::OnceCell<ks_store::Store>>,
|
||||
>,
|
||||
>,
|
||||
ws_pool:
|
||||
std::sync::Mutex<std::option::Option<std::sync::Arc<ks_onchain_transport::WsEndpointPool>>>,
|
||||
demo_ws_session:
|
||||
@@ -108,6 +114,7 @@ impl crate::AppState {
|
||||
logging_guard: std::sync::Mutex::new(logging_guard),
|
||||
http_pool,
|
||||
store: tokio::sync::OnceCell::new(),
|
||||
profile_stores: tokio::sync::Mutex::new(std::collections::BTreeMap::new()),
|
||||
ws_pool: std::sync::Mutex::new(std::option::Option::None),
|
||||
demo_ws_session: tokio::sync::Mutex::new(std::option::Option::None),
|
||||
demo_backfill_running: std::sync::atomic::AtomicBool::new(false),
|
||||
@@ -195,6 +202,63 @@ impl crate::AppState {
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Returns a shared persistent store for one immutable configured profile.
|
||||
pub(crate) async fn store_for_profile(
|
||||
&self,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
) -> ks_core::Result<ks_store::Store> {
|
||||
let configured_profile = self
|
||||
.app_config
|
||||
.profiles
|
||||
.iter()
|
||||
.find(|candidate| return candidate.name == profile.name);
|
||||
let configured_database = match configured_profile {
|
||||
std::option::Option::Some(value) => value.database.clone(),
|
||||
std::option::Option::None => {
|
||||
return std::result::Result::Err(ks_core::Error::invalid_state(
|
||||
"store profile is not part of the resolved application configuration",
|
||||
));
|
||||
},
|
||||
};
|
||||
if configured_database != profile.database {
|
||||
return std::result::Result::Err(ks_core::Error::invalid_state(
|
||||
"store profile database configuration mismatch",
|
||||
));
|
||||
}
|
||||
if profile.name == self.active_profile.name {
|
||||
let store_result = self.store().await;
|
||||
return match store_result {
|
||||
std::result::Result::Ok(store) => std::result::Result::Ok(store.clone()),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(error),
|
||||
};
|
||||
}
|
||||
let cell = {
|
||||
let mut stores = self.profile_stores.lock().await;
|
||||
if let std::option::Option::Some(existing) = stores.get(profile.name.as_str()) {
|
||||
std::sync::Arc::clone(existing)
|
||||
} else {
|
||||
let created = std::sync::Arc::new(tokio::sync::OnceCell::new());
|
||||
stores.insert(profile.name.clone(), std::sync::Arc::clone(&created));
|
||||
created
|
||||
}
|
||||
};
|
||||
let options = match ks_store::StoreOpenOptions::new(
|
||||
configured_database.enabled,
|
||||
configured_database.backend,
|
||||
configured_database.backend_options,
|
||||
) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let store_result = cell
|
||||
.get_or_try_init(|| return async move { return ks_store::Store::open(options).await })
|
||||
.await;
|
||||
return match store_result {
|
||||
std::result::Result::Ok(store) => std::result::Result::Ok(store.clone()),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(error),
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns the session-only execution-wallet alias override for one profile.
|
||||
pub(crate) fn demo_execution_wallet_alias_override(
|
||||
&self,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/demo_decode_replay.rs
|
||||
// version: 45
|
||||
// version: 46
|
||||
|
||||
//! Tauri commands and UI payloads for contextual instruction decode replay.
|
||||
|
||||
@@ -271,8 +271,10 @@ pub(crate) struct DemoDecodeDiagnosticsPayload {
|
||||
pub(crate) struct DemoTransactionAnnotationRequest {
|
||||
/// Optional partial transaction signature.
|
||||
pub(crate) signature_contains: std::option::Option<std::string::String>,
|
||||
/// Maximum returned rows.
|
||||
pub(crate) limit: u32,
|
||||
/// Opaque cursor identifying the requested Store block.
|
||||
pub(crate) cursor: std::option::Option<std::string::String>,
|
||||
/// One-based Store block index maintained by the desktop navigation.
|
||||
pub(crate) block_index: u32,
|
||||
}
|
||||
|
||||
/// UI-safe committed transaction annotation row.
|
||||
@@ -313,6 +315,20 @@ pub(crate) struct DemoTransactionAnnotationRow {
|
||||
pub(crate) updated_at: std::string::String,
|
||||
}
|
||||
|
||||
/// One counted Store block of committed transaction annotations.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_app_demo_desktop/demo_decode_replay/DemoTransactionAnnotationPagePayload.ts"
|
||||
)]
|
||||
pub(crate) struct DemoTransactionAnnotationPagePayload {
|
||||
/// Shared block metadata refreshed with this load.
|
||||
pub(crate) page: crate::DemoStoreBlockMetadata,
|
||||
/// Annotations in the current Store block.
|
||||
pub(crate) rows: std::vec::Vec<crate::DemoTransactionAnnotationRow>,
|
||||
}
|
||||
|
||||
pub(crate) struct DemoDecodeReplayObserver<'a> {
|
||||
pub(crate) app_handle: tauri::AppHandle,
|
||||
pub(crate) campaign_id: std::string::String,
|
||||
@@ -604,39 +620,49 @@ pub(crate) async fn demo_decode_replay_diagnostics(
|
||||
pub(crate) async fn demo_decode_replay_annotations(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
request: crate::DemoTransactionAnnotationRequest,
|
||||
) -> std::result::Result<std::vec::Vec<crate::DemoTransactionAnnotationRow>, std::string::String> {
|
||||
let filter_result = ks_store::MaterializedOutputFilter::new(
|
||||
) -> std::result::Result<crate::DemoTransactionAnnotationPagePayload, std::string::String> {
|
||||
let filter = ks_store::MaterializedOutputPageFilter::new(
|
||||
std::option::Option::Some("materializer.transaction.annotations".to_string()),
|
||||
std::option::Option::Some("transaction_annotation".to_string()),
|
||||
std::option::Option::Some("spl.memo".to_string()),
|
||||
request.signature_contains,
|
||||
request.limit,
|
||||
std::vec::Vec::new(),
|
||||
);
|
||||
let filter = match filter_result {
|
||||
let page_request_result = crate::demo_store_block_request(request.cursor);
|
||||
let page_request = match page_request_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
tracing::debug!(target: crate::TRACING_TARGET, action = "load_transaction_annotations", signature_contains = ?filter.signature_contains, limit = filter.limit, "load bounded committed transaction annotation journal");
|
||||
tracing::debug!(target: crate::TRACING_TARGET, action = "load_transaction_annotations", block_index = request.block_index, "load committed transaction annotation Store block");
|
||||
let store_result = crate::shared_store(state.inner()).await;
|
||||
let store = match store_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let rows_result =
|
||||
ks_store::DecodePipelineStore::list_materialized_outputs(&store, &filter).await;
|
||||
let rows = match rows_result {
|
||||
let page_result = store.materialized_output_page(&filter, &page_request).await;
|
||||
let page = match page_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let mut output = std::vec::Vec::with_capacity(rows.len());
|
||||
for row in rows {
|
||||
let metadata_result =
|
||||
crate::demo_store_block_metadata(page.total_rows, page.next_cursor, request.block_index);
|
||||
let metadata = match metadata_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let mut rows = std::vec::Vec::with_capacity(page.rows.len());
|
||||
for row in page.rows {
|
||||
let mapped = annotation_payload(row);
|
||||
match mapped {
|
||||
std::result::Result::Ok(value) => output.push(value),
|
||||
std::result::Result::Ok(value) => rows.push(value),
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
}
|
||||
}
|
||||
tracing::debug!(target: crate::TRACING_TARGET, action = "load_transaction_annotations", row_count = output.len(), "bounded committed transaction annotation journal loaded");
|
||||
return std::result::Result::Ok(output);
|
||||
tracing::debug!(target: crate::TRACING_TARGET, action = "load_transaction_annotations", row_count = rows.len(), total_rows = %metadata.total_rows, block_index = metadata.block_index, total_blocks = metadata.total_blocks, "committed transaction annotation Store block loaded");
|
||||
return std::result::Result::Ok(crate::DemoTransactionAnnotationPagePayload {
|
||||
page: metadata,
|
||||
rows,
|
||||
});
|
||||
}
|
||||
|
||||
fn register_active_campaign(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// file: kb-app-demo-desktop/src/demo_devnet_common.rs
|
||||
// version: 7
|
||||
// version: 9
|
||||
|
||||
//! Shared Devnet demo UI contracts.
|
||||
//! Shared Devnet demo UI contracts and profile/store helpers.
|
||||
|
||||
use ts_rs::TS; // rust-rules: derive-import
|
||||
|
||||
@@ -31,8 +31,57 @@ pub(crate) struct DemoExecutionDevnetStoreReadinessPayload {
|
||||
pub(crate) expected_resources: u32,
|
||||
}
|
||||
|
||||
/// Resolves one explicitly selected compatible Devnet profile.
|
||||
pub(crate) fn select_devnet_profile(
|
||||
config: &ks_config::AppConfig,
|
||||
profile_name: &str,
|
||||
) -> std::result::Result<ks_config::ProfileConfig, std::string::String> {
|
||||
return ks_pipeline_demo_scenarios::resolve_demo_devnet_profile(
|
||||
config,
|
||||
std::option::Option::Some(profile_name),
|
||||
)
|
||||
.map_err(|error| return error.to_string());
|
||||
}
|
||||
|
||||
/// Verifies or initializes the configured store selected by one Devnet profile.
|
||||
pub(crate) async fn demo_execution_devnet_prepare_profile(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
profile_name: std::string::String,
|
||||
) -> std::result::Result<DemoExecutionDevnetStoreReadinessPayload, std::string::String> {
|
||||
let profile = match select_devnet_profile(state.app_config(), profile_name.as_str()) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let store = match crate::shared_store_for_profile(state.inner(), &profile).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let configuration = store.configuration_summary();
|
||||
let initialization = store.initialization_summary();
|
||||
if initialization.status != ks_store::StoreInitializationStatus::Ready {
|
||||
return std::result::Result::Err(format!(
|
||||
"Devnet profile '{}' store model is incomplete and automatic initialization is {}",
|
||||
profile.name,
|
||||
if configuration.auto_initialize_schema { "enabled" } else { "disabled" }
|
||||
));
|
||||
}
|
||||
let readiness = ks_pipeline_demo_scenarios::DevnetProfileStoreReadiness {
|
||||
profile_name: profile.name.clone(),
|
||||
backend: configuration.backend_code.clone(),
|
||||
auto_initialize_schema: configuration.auto_initialize_schema,
|
||||
available_resources_before: initialization
|
||||
.available_resource_count
|
||||
.saturating_sub(initialization.created_resource_count)
|
||||
as usize,
|
||||
created_resources: initialization.created_resource_count as usize,
|
||||
available_resources_after: initialization.available_resource_count as usize,
|
||||
expected_resources: initialization.expected_resource_count as usize,
|
||||
};
|
||||
return std::result::Result::Ok(devnet_store_readiness_payload(readiness));
|
||||
}
|
||||
|
||||
/// Converts the reusable scenario readiness report to the desktop TS-RS payload.
|
||||
pub(crate) fn devnet_store_readiness_payload(
|
||||
fn devnet_store_readiness_payload(
|
||||
readiness: ks_pipeline_demo_scenarios::DevnetProfileStoreReadiness,
|
||||
) -> DemoExecutionDevnetStoreReadinessPayload {
|
||||
return DemoExecutionDevnetStoreReadinessPayload {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/demo_execution_metadata_metaplex_token_metadata.rs
|
||||
// version: 13
|
||||
// version: 14
|
||||
|
||||
//! Desktop adapters for generic and qualified Metaplex Token Metadata execution workflows.
|
||||
|
||||
@@ -190,7 +190,7 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_execute(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let store = match crate::open_store(&profile).await {
|
||||
let store = match crate::shared_store_for_profile(state.inner(), &profile).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
@@ -1041,7 +1041,7 @@ pub(crate) async fn demo_execution_metadata_metaplex_execute_campaign(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let store = match crate::open_store(&profile).await {
|
||||
let store = match crate::shared_store_for_profile(state.inner(), &profile).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/demo_execution_metadata_token_2022.rs
|
||||
// version: 7
|
||||
// version: 8
|
||||
|
||||
//! Thin desktop adapter for the complete Token-2022 Token Metadata Devnet campaign.
|
||||
|
||||
@@ -88,7 +88,7 @@ pub(crate) async fn demo_execution_metadata_token_2022_execute_campaign(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let store = match crate::open_store(&profile).await {
|
||||
let store = match crate::shared_store_for_profile(state.inner(), &profile).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/demo_execution_solana_core.rs
|
||||
// version: 23
|
||||
// version: 26
|
||||
|
||||
//! Tauri adapter for bounded Solana Core execution on Devnet.
|
||||
|
||||
@@ -359,17 +359,6 @@ impl ks_pipeline_demo_scenarios::SolanaExecutionObserver
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn select_devnet_profile(
|
||||
config: &ks_config::AppConfig,
|
||||
profile_name: &str,
|
||||
) -> std::result::Result<ks_config::ProfileConfig, std::string::String> {
|
||||
return ks_pipeline_demo_scenarios::resolve_demo_devnet_profile(
|
||||
config,
|
||||
std::option::Option::Some(profile_name),
|
||||
)
|
||||
.map_err(|error| return error.to_string());
|
||||
}
|
||||
|
||||
pub(crate) fn execution_cluster_code(
|
||||
cluster: ks_lib::ExApiExecutionCluster,
|
||||
) -> std::string::String {
|
||||
@@ -394,25 +383,6 @@ pub(crate) fn confirmation_status_code(
|
||||
};
|
||||
}
|
||||
|
||||
/// Verifies or initializes the configured store selected by one Devnet profile.
|
||||
pub(crate) async fn demo_execution_devnet_prepare_profile(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
profile_name: std::string::String,
|
||||
) -> std::result::Result<crate::DemoExecutionDevnetStoreReadinessPayload, std::string::String> {
|
||||
let profile = match crate::select_devnet_profile(state.app_config(), profile_name.as_str()) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let readiness =
|
||||
match ks_pipeline_demo_scenarios::prepare_demo_devnet_profile_store(&profile).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(error.to_string());
|
||||
},
|
||||
};
|
||||
return std::result::Result::Ok(crate::devnet_store_readiness_payload(readiness));
|
||||
}
|
||||
|
||||
/// Returns compatible Devnet profiles and conservative defaults.
|
||||
pub(crate) fn demo_execution_solana_core_options(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
@@ -473,7 +443,7 @@ pub(crate) async fn demo_execution_solana_core_execute(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let store = match crate::open_store(&profile).await {
|
||||
let store = match crate::shared_store_for_profile(state.inner(), &profile).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
@@ -557,7 +527,7 @@ pub(crate) async fn demo_execution_spl_memo_execute(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let store = match crate::open_store(&profile).await {
|
||||
let store = match crate::shared_store_for_profile(state.inner(), &profile).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/demo_spl_ata.rs
|
||||
// version: 19
|
||||
// version: 21
|
||||
|
||||
//! Thin Tauri adapter for ATA execution, derivation and lifecycle journal reads.
|
||||
|
||||
@@ -129,8 +129,24 @@ pub(crate) struct DemoSplAtaJournalRequest {
|
||||
pub(crate) associated_token_account: std::option::Option<std::string::String>,
|
||||
/// Optional exact materialized operation.
|
||||
pub(crate) operation: std::option::Option<std::string::String>,
|
||||
/// Maximum returned rows.
|
||||
pub(crate) limit: u32,
|
||||
/// Opaque cursor identifying the requested Store block.
|
||||
pub(crate) cursor: std::option::Option<std::string::String>,
|
||||
/// One-based Store block index maintained by the desktop navigation.
|
||||
pub(crate) block_index: u32,
|
||||
}
|
||||
|
||||
/// One counted Store block of ATA lifecycle journal rows.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_app_demo_desktop/demo_spl_ata/DemoSplAtaJournalPagePayload.ts"
|
||||
)]
|
||||
pub(crate) struct DemoSplAtaJournalPagePayload {
|
||||
/// Shared block metadata refreshed with this load.
|
||||
pub(crate) page: crate::DemoStoreBlockMetadata,
|
||||
/// Typed rows retained from the current Store block.
|
||||
pub(crate) rows: std::vec::Vec<crate::DemoSplAtaJournalRow>,
|
||||
}
|
||||
|
||||
/// One UI-safe ATA lifecycle journal row.
|
||||
@@ -260,7 +276,7 @@ pub(crate) async fn demo_execution_spl_ata_execute(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let store = match crate::open_store(&profile).await {
|
||||
let store = match crate::shared_store_for_profile(state.inner(), &profile).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
@@ -303,46 +319,54 @@ pub(crate) async fn demo_execution_spl_ata_execute(
|
||||
pub(crate) async fn demo_spl_ata_journal(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
request: crate::DemoSplAtaJournalRequest,
|
||||
) -> std::result::Result<std::vec::Vec<crate::DemoSplAtaJournalRow>, std::string::String> {
|
||||
if request.limit == 0 || request.limit > 500 {
|
||||
return std::result::Result::Err("ATA journal limit must be between 1 and 500".to_string());
|
||||
}
|
||||
) -> std::result::Result<crate::DemoSplAtaJournalPagePayload, std::string::String> {
|
||||
let profile =
|
||||
match crate::select_devnet_profile(state.app_config(), request.profile_name.as_str()) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let store = match crate::open_store(&profile).await {
|
||||
let store = match crate::shared_store_for_profile(state.inner(), &profile).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let filter = match ks_store::MaterializedOutputFilter::new(
|
||||
let mut payload_match_groups = std::vec::Vec::new();
|
||||
if let std::option::Option::Some(operation) = request.operation.as_ref() {
|
||||
payload_match_groups.push(vec![serde_json::json!({"operation": operation})]);
|
||||
}
|
||||
if let std::option::Option::Some(mint) = request.mint.as_ref() {
|
||||
payload_match_groups.push(vec![serde_json::json!({"mint": mint})]);
|
||||
}
|
||||
if let std::option::Option::Some(associated_token_account) =
|
||||
request.associated_token_account.as_ref()
|
||||
{
|
||||
payload_match_groups
|
||||
.push(vec![serde_json::json!({"associatedTokenAccount": associated_token_account})]);
|
||||
}
|
||||
let filter = ks_store::MaterializedOutputPageFilter::new(
|
||||
std::option::Option::Some("materializer.token.accounts".to_string()),
|
||||
std::option::Option::None,
|
||||
std::option::Option::Some("spl.associated_token_account".to_string()),
|
||||
request.signature_contains.clone(),
|
||||
500,
|
||||
) {
|
||||
payload_match_groups,
|
||||
);
|
||||
let page_request_result = crate::demo_store_block_request(request.cursor.clone());
|
||||
let page_request = match page_request_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let page_result = store.materialized_output_page(&filter, &page_request).await;
|
||||
let page = match page_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let rows = match ks_store::DecodePipelineStore::list_materialized_outputs(&store, &filter).await
|
||||
{
|
||||
let metadata_result =
|
||||
crate::demo_store_block_metadata(page.total_rows, page.next_cursor, request.block_index);
|
||||
let metadata = match metadata_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let mut output = std::vec::Vec::new();
|
||||
for row in rows {
|
||||
if row.source_decoder_name != "spl.associated_token_account"
|
||||
|| !journal_matches(&row.payload_json, &request)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
output.push(journal_row(row));
|
||||
if output.len() >= request.limit as usize {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return std::result::Result::Ok(output);
|
||||
let rows = page.rows.into_iter().map(journal_row).collect();
|
||||
return std::result::Result::Ok(crate::DemoSplAtaJournalPagePayload { page: metadata, rows });
|
||||
}
|
||||
|
||||
async fn load_profile_wallet(
|
||||
@@ -544,6 +568,7 @@ fn summary_payload(
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn journal_matches(payload: &serde_json::Value, request: &crate::DemoSplAtaJournalRequest) -> bool {
|
||||
for (expected, key) in [
|
||||
(&request.operation, "operation"),
|
||||
@@ -605,7 +630,8 @@ mod tests {
|
||||
mint: std::option::Option::Some("mint111".to_string()),
|
||||
associated_token_account: std::option::Option::Some("ata111".to_string()),
|
||||
operation: std::option::Option::Some("create_idempotent".to_string()),
|
||||
limit: 100,
|
||||
cursor: std::option::Option::None,
|
||||
block_index: 1,
|
||||
};
|
||||
assert!(super::journal_matches(
|
||||
&serde_json::json!({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/demo_spl_token.rs
|
||||
// version: 17
|
||||
// version: 19
|
||||
|
||||
//! Thin Tauri adapter for classic SPL Token execution and materialized journals.
|
||||
|
||||
@@ -111,8 +111,24 @@ pub(crate) struct DemoSplTokenJournalRequest {
|
||||
pub(crate) family: std::option::Option<std::string::String>,
|
||||
/// Optional exact operation code without the `spl.token.` prefix.
|
||||
pub(crate) operation: std::option::Option<std::string::String>,
|
||||
/// Maximum number of rows returned after typed filtering.
|
||||
pub(crate) limit: u32,
|
||||
/// Opaque cursor identifying the requested Store block.
|
||||
pub(crate) cursor: std::option::Option<std::string::String>,
|
||||
/// One-based Store block index maintained by the desktop navigation.
|
||||
pub(crate) block_index: u32,
|
||||
}
|
||||
|
||||
/// One counted Store block of classic SPL Token journal rows.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_app_demo_desktop/demo_spl_token/DemoSplTokenJournalPagePayload.ts"
|
||||
)]
|
||||
pub(crate) struct DemoSplTokenJournalPagePayload {
|
||||
/// Shared block metadata refreshed with this load.
|
||||
pub(crate) page: crate::DemoStoreBlockMetadata,
|
||||
/// Typed rows retained from the current Store block.
|
||||
pub(crate) rows: std::vec::Vec<crate::DemoSplTokenJournalRow>,
|
||||
}
|
||||
|
||||
/// UI-safe materialized classic SPL Token journal row.
|
||||
@@ -183,7 +199,7 @@ pub(crate) async fn demo_execution_spl_token_execute(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let store = match crate::open_store(&profile).await {
|
||||
let store = match crate::shared_store_for_profile(state.inner(), &profile).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
@@ -246,7 +262,7 @@ pub(crate) async fn demo_execution_spl_token_execute(
|
||||
pub(crate) async fn demo_spl_token_journal(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
request: crate::DemoSplTokenJournalRequest,
|
||||
) -> std::result::Result<std::vec::Vec<crate::DemoSplTokenJournalRow>, std::string::String> {
|
||||
) -> std::result::Result<crate::DemoSplTokenJournalPagePayload, std::string::String> {
|
||||
let validated = match validate_journal_request(request) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
@@ -256,43 +272,48 @@ pub(crate) async fn demo_spl_token_journal(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let store = match crate::open_store(&profile).await {
|
||||
let store = match crate::shared_store_for_profile(state.inner(), &profile).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let needs_payload_filter =
|
||||
validated.mint.is_some() || validated.account.is_some() || validated.operation.is_some();
|
||||
let query_limit = if needs_payload_filter {
|
||||
ks_store::MAX_MATERIALIZED_OUTPUT_QUERY_ROWS
|
||||
} else {
|
||||
validated.limit
|
||||
};
|
||||
let filter = match ks_store::MaterializedOutputFilter::new(
|
||||
let mut payload_match_groups = std::vec::Vec::new();
|
||||
if let std::option::Option::Some(operation) = validated.operation.as_ref() {
|
||||
payload_match_groups.push(vec![serde_json::json!({"operation": operation})]);
|
||||
}
|
||||
if let std::option::Option::Some(mint) = validated.mint.as_ref() {
|
||||
payload_match_groups.push(vec![
|
||||
serde_json::json!({"mint": mint}),
|
||||
serde_json::json!({"accounts": [{"role": "mint", "accountKey": mint}]}),
|
||||
]);
|
||||
}
|
||||
if let std::option::Option::Some(account) = validated.account.as_ref() {
|
||||
payload_match_groups.push(vec![serde_json::json!({"accounts": [{"accountKey": account}]})]);
|
||||
}
|
||||
let filter = ks_store::MaterializedOutputPageFilter::new(
|
||||
std::option::Option::None,
|
||||
validated.family.clone(),
|
||||
std::option::Option::Some("spl.token".to_string()),
|
||||
validated.signature_contains.clone(),
|
||||
query_limit,
|
||||
) {
|
||||
payload_match_groups,
|
||||
);
|
||||
let page_request_result = crate::demo_store_block_request(validated.cursor.clone());
|
||||
let page_request = match page_request_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let page_result = store.materialized_output_page(&filter, &page_request).await;
|
||||
let page = match page_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let rows = match ks_store::DecodePipelineStore::list_materialized_outputs(&store, &filter).await
|
||||
{
|
||||
let metadata_result =
|
||||
crate::demo_store_block_metadata(page.total_rows, page.next_cursor, validated.block_index);
|
||||
let metadata = match metadata_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let mut output = std::vec::Vec::new();
|
||||
for row in rows {
|
||||
if row.source_decoder_name != "spl.token" || !payload_matches(&row.payload_json, &validated)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
output.push(journal_row(row));
|
||||
if output.len() >= validated.limit as usize {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return std::result::Result::Ok(output);
|
||||
let rows = page.rows.into_iter().map(journal_row).collect();
|
||||
return std::result::Result::Ok(crate::DemoSplTokenJournalPagePayload { page: metadata, rows });
|
||||
}
|
||||
|
||||
fn summary_payload(
|
||||
@@ -412,12 +433,6 @@ fn replay_diagnostics(summary: &ks_pipeline::DecodeReplaySummary) -> serde_json:
|
||||
fn validate_journal_request(
|
||||
request: crate::DemoSplTokenJournalRequest,
|
||||
) -> std::result::Result<crate::DemoSplTokenJournalRequest, std::string::String> {
|
||||
if request.limit == 0 || request.limit > ks_store::MAX_MATERIALIZED_OUTPUT_QUERY_ROWS {
|
||||
return std::result::Result::Err(format!(
|
||||
"journal limit must be between 1 and {}",
|
||||
ks_store::MAX_MATERIALIZED_OUTPUT_QUERY_ROWS
|
||||
));
|
||||
}
|
||||
if request.profile_name.trim().is_empty() {
|
||||
return std::result::Result::Err("journal profile name must not be empty".to_string());
|
||||
}
|
||||
@@ -456,7 +471,8 @@ fn validate_journal_request(
|
||||
account,
|
||||
family,
|
||||
operation,
|
||||
limit: request.limit,
|
||||
cursor: request.cursor,
|
||||
block_index: request.block_index,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -473,6 +489,7 @@ fn bounded_optional(
|
||||
return std::result::Result::Ok(trimmed);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn payload_matches(
|
||||
payload: &serde_json::Value,
|
||||
request: &crate::DemoSplTokenJournalRequest,
|
||||
@@ -586,7 +603,8 @@ mod tests {
|
||||
account: std::option::Option::Some("source111".to_string()),
|
||||
family: std::option::Option::Some("token_account".to_string()),
|
||||
operation: std::option::Option::Some("transfer_checked".to_string()),
|
||||
limit: 25,
|
||||
cursor: std::option::Option::None,
|
||||
block_index: 1,
|
||||
};
|
||||
let payload = serde_json::json!({
|
||||
"operation": "transfer_checked",
|
||||
@@ -622,7 +640,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn journal_rejects_unbounded_or_unknown_family_requests() {
|
||||
fn journal_rejects_unknown_family_requests() {
|
||||
let request = crate::DemoSplTokenJournalRequest {
|
||||
profile_name: "local_devnet".to_string(),
|
||||
signature_contains: std::option::Option::None,
|
||||
@@ -630,7 +648,8 @@ mod tests {
|
||||
account: std::option::Option::None,
|
||||
family: std::option::Option::Some("fee".to_string()),
|
||||
operation: std::option::Option::None,
|
||||
limit: 501,
|
||||
cursor: std::option::Option::None,
|
||||
block_index: 1,
|
||||
};
|
||||
assert!(super::validate_journal_request(request).is_err());
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/demo_spl_token_2022.rs
|
||||
// version: 20
|
||||
// version: 21
|
||||
|
||||
//! Thin Tauri adapter for independent public Token-2022 Devnet validation scenarios.
|
||||
|
||||
@@ -159,7 +159,7 @@ pub(crate) async fn demo_execution_spl_token_2022_execute(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let store = match crate::open_store(&profile).await {
|
||||
let store = match crate::shared_store_for_profile(state.inner(), &profile).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
|
||||
@@ -1,10 +1,78 @@
|
||||
// file: kb-app-demo-desktop/src/demo_store_common.rs
|
||||
// version: 19
|
||||
// version: 21
|
||||
|
||||
//! Shared backend-agnostic store demo helpers and serializable payloads.
|
||||
|
||||
use ts_rs::TS; // rust-rules: derive-import
|
||||
|
||||
/// Pagination metadata shared by desktop Store block listings.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_app_demo_desktop/demo_store/DemoStoreBlockMetadata.ts"
|
||||
)]
|
||||
pub(crate) struct DemoStoreBlockMetadata {
|
||||
/// Fixed number of backend rows requested per Store block.
|
||||
pub(crate) block_size: u16,
|
||||
/// One-based block index, or zero when the filtered result set is empty.
|
||||
pub(crate) block_index: u32,
|
||||
/// Total matching rows rendered losslessly for the WebView.
|
||||
pub(crate) total_rows: std::string::String,
|
||||
/// Total number of fixed Store blocks.
|
||||
pub(crate) total_blocks: u32,
|
||||
/// Opaque cursor for the next Store block when one exists.
|
||||
pub(crate) next_cursor: std::option::Option<std::string::String>,
|
||||
}
|
||||
|
||||
/// Fixed backend block size used by desktop Store listings.
|
||||
pub(crate) const DEMO_STORE_BLOCK_SIZE: u16 = ks_store::MAX_PAGE_SIZE;
|
||||
|
||||
/// Builds one fixed-size Store block request.
|
||||
pub(crate) fn demo_store_block_request(
|
||||
cursor: std::option::Option<std::string::String>,
|
||||
) -> std::result::Result<ks_store::PageRequest, std::string::String> {
|
||||
let request_result = ks_store::PageRequest::new(crate::DEMO_STORE_BLOCK_SIZE, cursor);
|
||||
return match request_result {
|
||||
std::result::Result::Ok(value) => std::result::Result::Ok(value),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
}
|
||||
|
||||
/// Calculates refreshed desktop block metadata from one counted Store page.
|
||||
pub(crate) fn demo_store_block_metadata(
|
||||
total_rows: u64,
|
||||
next_cursor: std::option::Option<std::string::String>,
|
||||
requested_block_index: u32,
|
||||
) -> std::result::Result<crate::DemoStoreBlockMetadata, std::string::String> {
|
||||
if requested_block_index == 0 {
|
||||
return std::result::Result::Err("Store block index must be greater than zero".to_string());
|
||||
}
|
||||
let block_size = u64::from(crate::DEMO_STORE_BLOCK_SIZE);
|
||||
let total_blocks_u64 = if total_rows == 0 { 0 } else { ((total_rows - 1) / block_size) + 1 };
|
||||
let total_blocks_result = u32::try_from(total_blocks_u64);
|
||||
let total_blocks = match total_blocks_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_error) => {
|
||||
return std::result::Result::Err(
|
||||
"Store block count exceeds desktop bounds".to_string(),
|
||||
);
|
||||
},
|
||||
};
|
||||
if total_blocks > 0 && requested_block_index > total_blocks {
|
||||
return std::result::Result::Err(format!(
|
||||
"Store block {requested_block_index} no longer exists; reload the first block"
|
||||
));
|
||||
}
|
||||
return std::result::Result::Ok(crate::DemoStoreBlockMetadata {
|
||||
block_size: crate::DEMO_STORE_BLOCK_SIZE,
|
||||
block_index: if total_rows == 0 { 0 } else { requested_block_index },
|
||||
total_rows: total_rows.to_string(),
|
||||
total_blocks,
|
||||
next_cursor,
|
||||
});
|
||||
}
|
||||
|
||||
/// UI-safe diagnostics for one logical store resource.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -34,33 +102,6 @@ pub(crate) struct DemoStoreResourceSnapshot {
|
||||
pub(crate) latest_created_at: std::option::Option<std::string::String>,
|
||||
}
|
||||
|
||||
/// Builds backend-agnostic store-open options from one resolved profile.
|
||||
fn store_open_options_from_profile(
|
||||
profile: &ks_config::ProfileConfig,
|
||||
) -> ks_core::Result<ks_store::StoreOpenOptions> {
|
||||
return ks_store::StoreOpenOptions::new(
|
||||
profile.database.enabled,
|
||||
profile.database.backend.clone(),
|
||||
profile.database.backend_options.clone(),
|
||||
);
|
||||
}
|
||||
|
||||
/// Opens a backend-agnostic store from one resolved profile.
|
||||
///
|
||||
/// Prefer [`crate::AppState::store`] for desktop commands that already own application state.
|
||||
pub(crate) async fn open_store(
|
||||
profile: &ks_config::ProfileConfig,
|
||||
) -> std::result::Result<ks_store::Store, std::string::String> {
|
||||
let options = match store_open_options_from_profile(profile) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
return match ks_store::Store::open(options).await {
|
||||
std::result::Result::Ok(store) => std::result::Result::Ok(store),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
}
|
||||
|
||||
/// Clones the persistent store held by application state.
|
||||
pub(crate) async fn shared_store(
|
||||
state: &crate::AppState,
|
||||
@@ -72,6 +113,18 @@ pub(crate) async fn shared_store(
|
||||
};
|
||||
}
|
||||
|
||||
/// Clones the shared persistent store held for one configured profile.
|
||||
pub(crate) async fn shared_store_for_profile(
|
||||
state: &crate::AppState,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
) -> std::result::Result<ks_store::Store, std::string::String> {
|
||||
let store_result = state.store_for_profile(profile).await;
|
||||
return match store_result {
|
||||
std::result::Result::Ok(store) => std::result::Result::Ok(store),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
}
|
||||
|
||||
/// Converts one logical store resource diagnostic to the UI payload shape.
|
||||
pub(crate) fn store_resource_snapshot(
|
||||
value: &ks_store::StoreResourceDiagnostics,
|
||||
@@ -262,3 +315,22 @@ fn emit_store_startup_splash(
|
||||
std::option::Option::None,
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn fixed_store_block_metadata_rounds_up_and_keeps_empty_zero() {
|
||||
let first_result = crate::demo_store_block_metadata(
|
||||
1749,
|
||||
std::option::Option::Some("next".to_string()),
|
||||
1,
|
||||
);
|
||||
let first = match first_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("unexpected block metadata error: {error}"),
|
||||
};
|
||||
assert_eq!(first.total_blocks, 4);
|
||||
assert_eq!(first.total_rows, "1749");
|
||||
assert_eq!(first.block_size, 500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/demo_store_replay_candidates.rs
|
||||
// version: 16
|
||||
// version: 17
|
||||
|
||||
//! Backend-agnostic read-only replay candidate browser commands.
|
||||
|
||||
@@ -31,8 +31,8 @@ pub(crate) struct DemoStoreReplayOptionsPayload {
|
||||
pub(crate) active_profile_name: std::string::String,
|
||||
/// Safe backend connection descriptor.
|
||||
pub(crate) connection_descriptor: std::string::String,
|
||||
/// Maximum rows accepted by one query.
|
||||
pub(crate) maximum_limit: u32,
|
||||
/// Fixed Store block size used by every replay-candidate listing.
|
||||
pub(crate) block_size: u16,
|
||||
/// Program identifiers enumerable from `ks_program_ids`.
|
||||
pub(crate) known_programs: std::vec::Vec<crate::DemoStoreReplayKnownProgramOption>,
|
||||
}
|
||||
@@ -65,8 +65,10 @@ pub(crate) struct DemoStoreReplayTransactionRequest {
|
||||
pub(crate) entity_kind: std::option::Option<std::string::String>,
|
||||
/// Optional exact entity value.
|
||||
pub(crate) entity_value: std::option::Option<std::string::String>,
|
||||
/// Maximum returned rows.
|
||||
pub(crate) limit: u32,
|
||||
/// Opaque cursor identifying the requested Store block.
|
||||
pub(crate) cursor: std::option::Option<std::string::String>,
|
||||
/// One-based Store block index maintained by the desktop navigation.
|
||||
pub(crate) block_index: u32,
|
||||
/// Orders newest slots first when true.
|
||||
pub(crate) newest_first: bool,
|
||||
}
|
||||
@@ -114,6 +116,20 @@ pub(crate) struct DemoStoreReplayTransactionRow {
|
||||
pub(crate) updated_at: std::string::String,
|
||||
}
|
||||
|
||||
/// One counted Store block of transaction replay candidates.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_app_demo_desktop/demo_store_replay_candidates/DemoStoreReplayTransactionPagePayload.ts"
|
||||
)]
|
||||
pub(crate) struct DemoStoreReplayTransactionPagePayload {
|
||||
/// Shared block metadata refreshed with this load.
|
||||
pub(crate) page: crate::DemoStoreBlockMetadata,
|
||||
/// Rows in the current Store block.
|
||||
pub(crate) rows: std::vec::Vec<crate::DemoStoreReplayTransactionRow>,
|
||||
}
|
||||
|
||||
/// UI request for bounded program summaries.
|
||||
#[derive(Clone, Debug, serde::Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -124,8 +140,10 @@ pub(crate) struct DemoStoreReplayTransactionRow {
|
||||
pub(crate) struct DemoStoreReplayProgramRequest {
|
||||
/// Optional partial program id search.
|
||||
pub(crate) program_id_contains: std::option::Option<std::string::String>,
|
||||
/// Maximum returned rows.
|
||||
pub(crate) limit: u32,
|
||||
/// Opaque cursor identifying the requested Store block.
|
||||
pub(crate) cursor: std::option::Option<std::string::String>,
|
||||
/// One-based Store block index maintained by the desktop navigation.
|
||||
pub(crate) block_index: u32,
|
||||
}
|
||||
|
||||
/// Aggregated program row shown by the replay candidate browser.
|
||||
@@ -160,6 +178,20 @@ pub(crate) struct DemoStoreReplayProgramRow {
|
||||
pub(crate) max_slot: i64,
|
||||
}
|
||||
|
||||
/// One counted Store block of program summaries.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_app_demo_desktop/demo_store_replay_candidates/DemoStoreReplayProgramPagePayload.ts"
|
||||
)]
|
||||
pub(crate) struct DemoStoreReplayProgramPagePayload {
|
||||
/// Shared block metadata refreshed with this load.
|
||||
pub(crate) page: crate::DemoStoreBlockMetadata,
|
||||
/// Rows in the current Store block.
|
||||
pub(crate) rows: std::vec::Vec<crate::DemoStoreReplayProgramRow>,
|
||||
}
|
||||
|
||||
/// UI request for bounded core entity summaries.
|
||||
#[derive(Clone, Debug, serde::Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -172,8 +204,10 @@ pub(crate) struct DemoStoreReplayEntityRequest {
|
||||
pub(crate) entity_kind: std::string::String,
|
||||
/// Optional partial entity value search.
|
||||
pub(crate) entity_value_contains: std::option::Option<std::string::String>,
|
||||
/// Maximum returned rows.
|
||||
pub(crate) limit: u32,
|
||||
/// Opaque cursor identifying the requested Store block.
|
||||
pub(crate) cursor: std::option::Option<std::string::String>,
|
||||
/// One-based Store block index maintained by the desktop navigation.
|
||||
pub(crate) block_index: u32,
|
||||
}
|
||||
|
||||
/// Aggregated core entity row shown by the replay candidate browser.
|
||||
@@ -202,6 +236,20 @@ pub(crate) struct DemoStoreReplayEntityRow {
|
||||
pub(crate) max_slot: i64,
|
||||
}
|
||||
|
||||
/// One counted Store block of mint, owner or account-key summaries.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_app_demo_desktop/demo_store_replay_candidates/DemoStoreReplayEntityPagePayload.ts"
|
||||
)]
|
||||
pub(crate) struct DemoStoreReplayEntityPagePayload {
|
||||
/// Shared block metadata refreshed with this load.
|
||||
pub(crate) page: crate::DemoStoreBlockMetadata,
|
||||
/// Rows in the current Store block.
|
||||
pub(crate) rows: std::vec::Vec<crate::DemoStoreReplayEntityRow>,
|
||||
}
|
||||
|
||||
/// Writes a bounded replay-candidate CSV file into `./data/exports_csv/`.
|
||||
pub(crate) async fn export_demo_store_replay_csv(
|
||||
file_name: std::string::String,
|
||||
@@ -264,7 +312,7 @@ pub(crate) async fn demo_store_replay_options(
|
||||
return std::result::Result::Ok(crate::DemoStoreReplayOptionsPayload {
|
||||
active_profile_name: profile.name,
|
||||
connection_descriptor,
|
||||
maximum_limit: ks_store::MAX_REPLAY_CANDIDATE_ROWS,
|
||||
block_size: crate::DEMO_STORE_BLOCK_SIZE,
|
||||
known_programs,
|
||||
});
|
||||
}
|
||||
@@ -273,7 +321,7 @@ pub(crate) async fn demo_store_replay_options(
|
||||
pub(crate) async fn load_demo_store_replay_transactions(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
request: crate::DemoStoreReplayTransactionRequest,
|
||||
) -> std::result::Result<std::vec::Vec<crate::DemoStoreReplayTransactionRow>, std::string::String> {
|
||||
) -> std::result::Result<crate::DemoStoreReplayTransactionPagePayload, std::string::String> {
|
||||
let program_scope_result = program_scope_from_code(request.program_scope.as_str());
|
||||
let program_scope = match program_scope_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -294,95 +342,132 @@ pub(crate) async fn load_demo_store_replay_transactions(
|
||||
program_scope,
|
||||
entity_kind,
|
||||
request.entity_value,
|
||||
request.limit,
|
||||
request.newest_first,
|
||||
);
|
||||
let filter = match filter_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let page_request_result = crate::demo_store_block_request(request.cursor);
|
||||
let page_request = match page_request_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let store_result = crate::shared_store(state.inner()).await;
|
||||
let store = match store_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let rows_result = store.replay_transaction_candidates(&filter).await;
|
||||
let rows = match rows_result {
|
||||
let page_result = store.replay_transaction_candidates(&filter, &page_request).await;
|
||||
let page = match page_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
tracing::debug!(target: crate::TRACING_TARGET, rows = rows.len(), "loaded replay transaction candidates");
|
||||
let mut output = std::vec::Vec::with_capacity(rows.len());
|
||||
for row in rows {
|
||||
output.push(transaction_row_from_store(row));
|
||||
let metadata_result =
|
||||
crate::demo_store_block_metadata(page.total_rows, page.next_cursor, request.block_index);
|
||||
let metadata = match metadata_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let mut rows = std::vec::Vec::with_capacity(page.rows.len());
|
||||
for row in page.rows {
|
||||
rows.push(transaction_row_from_store(row));
|
||||
}
|
||||
return std::result::Result::Ok(output);
|
||||
tracing::debug!(target: crate::TRACING_TARGET, rows = rows.len(), total_rows = %metadata.total_rows, block_index = metadata.block_index, total_blocks = metadata.total_blocks, "loaded replay transaction candidate block");
|
||||
return std::result::Result::Ok(crate::DemoStoreReplayTransactionPagePayload {
|
||||
page: metadata,
|
||||
rows,
|
||||
});
|
||||
}
|
||||
|
||||
/// Loads bounded program summaries from the active store.
|
||||
/// Loads one counted Store block of program summaries.
|
||||
pub(crate) async fn load_demo_store_replay_programs(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
request: crate::DemoStoreReplayProgramRequest,
|
||||
) -> std::result::Result<std::vec::Vec<crate::DemoStoreReplayProgramRow>, std::string::String> {
|
||||
let filter_result =
|
||||
ks_store::ReplayProgramFilter::new(request.program_id_contains, request.limit);
|
||||
) -> std::result::Result<crate::DemoStoreReplayProgramPagePayload, std::string::String> {
|
||||
let filter_result = ks_store::ReplayProgramFilter::new(request.program_id_contains);
|
||||
let filter = match filter_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let page_request_result = crate::demo_store_block_request(request.cursor);
|
||||
let page_request = match page_request_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let store_result = crate::shared_store(state.inner()).await;
|
||||
let store = match store_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let rows_result = store.replay_program_summaries(&filter).await;
|
||||
let rows = match rows_result {
|
||||
let page_result = store.replay_program_summaries(&filter, &page_request).await;
|
||||
let page = match page_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
tracing::debug!(target: crate::TRACING_TARGET, rows = rows.len(), "loaded replay program summaries");
|
||||
let mut output = std::vec::Vec::with_capacity(rows.len());
|
||||
for row in rows {
|
||||
output.push(program_row_from_store(row));
|
||||
let metadata_result =
|
||||
crate::demo_store_block_metadata(page.total_rows, page.next_cursor, request.block_index);
|
||||
let metadata = match metadata_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let mut rows = std::vec::Vec::with_capacity(page.rows.len());
|
||||
for row in page.rows {
|
||||
rows.push(program_row_from_store(row));
|
||||
}
|
||||
return std::result::Result::Ok(output);
|
||||
tracing::debug!(target: crate::TRACING_TARGET, rows = rows.len(), total_rows = %metadata.total_rows, block_index = metadata.block_index, total_blocks = metadata.total_blocks, "loaded replay program summary block");
|
||||
return std::result::Result::Ok(crate::DemoStoreReplayProgramPagePayload {
|
||||
page: metadata,
|
||||
rows,
|
||||
});
|
||||
}
|
||||
|
||||
/// Loads bounded mint, owner or account-key summaries from Core facts.
|
||||
/// Loads one counted Store block of mint, owner or account-key summaries.
|
||||
pub(crate) async fn load_demo_store_replay_entities(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
request: crate::DemoStoreReplayEntityRequest,
|
||||
) -> std::result::Result<std::vec::Vec<crate::DemoStoreReplayEntityRow>, std::string::String> {
|
||||
) -> std::result::Result<crate::DemoStoreReplayEntityPagePayload, std::string::String> {
|
||||
let entity_kind_result = entity_kind_from_code(request.entity_kind.as_str());
|
||||
let entity_kind = match entity_kind_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let filter_result = ks_store::ReplayEntityFilter::new(
|
||||
entity_kind,
|
||||
request.entity_value_contains,
|
||||
request.limit,
|
||||
);
|
||||
let filter_result =
|
||||
ks_store::ReplayEntityFilter::new(entity_kind, request.entity_value_contains);
|
||||
let filter = match filter_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let page_request_result = crate::demo_store_block_request(request.cursor);
|
||||
let page_request = match page_request_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let store_result = crate::shared_store(state.inner()).await;
|
||||
let store = match store_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let rows_result = store.replay_entity_summaries(&filter).await;
|
||||
let rows = match rows_result {
|
||||
let page_result = store.replay_entity_summaries(&filter, &page_request).await;
|
||||
let page = match page_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
tracing::debug!(target: crate::TRACING_TARGET, rows = rows.len(), "loaded replay entity summaries");
|
||||
let mut output = std::vec::Vec::with_capacity(rows.len());
|
||||
for row in rows {
|
||||
output.push(entity_row_from_store(row));
|
||||
let metadata_result =
|
||||
crate::demo_store_block_metadata(page.total_rows, page.next_cursor, request.block_index);
|
||||
let metadata = match metadata_result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let mut rows = std::vec::Vec::with_capacity(page.rows.len());
|
||||
for row in page.rows {
|
||||
rows.push(entity_row_from_store(row));
|
||||
}
|
||||
return std::result::Result::Ok(output);
|
||||
tracing::debug!(target: crate::TRACING_TARGET, rows = rows.len(), total_rows = %metadata.total_rows, block_index = metadata.block_index, total_blocks = metadata.total_blocks, entity_kind = request.entity_kind.as_str(), "loaded replay entity summary block");
|
||||
return std::result::Result::Ok(crate::DemoStoreReplayEntityPagePayload {
|
||||
page: metadata,
|
||||
rows,
|
||||
});
|
||||
}
|
||||
|
||||
fn transaction_row_from_store(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/lib.rs
|
||||
// version: 47
|
||||
// version: 50
|
||||
|
||||
//! Tauri desktop demo application for `khadhroony-bot3`.
|
||||
|
||||
@@ -133,6 +133,8 @@ pub(crate) use self::demo_decode_replay::DemoDecodeReplayRequest;
|
||||
pub(crate) use self::demo_decode_replay::DemoDecodeReplayRunGuard;
|
||||
/// Internal demo decode replay item.
|
||||
pub(crate) use self::demo_decode_replay::DemoDecodeReplaySummaryPayload;
|
||||
/// Counted Store block of transaction annotations.
|
||||
pub(crate) use self::demo_decode_replay::DemoTransactionAnnotationPagePayload;
|
||||
/// Internal demo decode replay item.
|
||||
pub(crate) use self::demo_decode_replay::DemoTransactionAnnotationRequest;
|
||||
/// Internal demo decode replay item.
|
||||
@@ -151,16 +153,18 @@ pub(crate) use self::demo_decode_replay::demo_decode_replay_options;
|
||||
pub(crate) use self::demo_devnet_common::DemoExecutionDevnetStoreReadinessPayload;
|
||||
/// Restores the shared single-execution state flag when a Devnet run finishes.
|
||||
pub(crate) use self::demo_devnet_common::DemoExecutionRunGuard;
|
||||
/// Prepares the Store selected by one compatible Devnet profile.
|
||||
pub(crate) use self::demo_devnet_common::demo_execution_devnet_prepare_profile;
|
||||
/// Loads the backend-only demo wallet password.
|
||||
pub(crate) use self::demo_devnet_common::demo_wallet_password;
|
||||
/// Returns whether the backend-only demo wallet password is configured.
|
||||
pub(crate) use self::demo_devnet_common::demo_wallet_password_configured;
|
||||
/// Converts the reusable scenario readiness report to the desktop TS-RS payload.
|
||||
pub(crate) use self::demo_devnet_common::devnet_store_readiness_payload;
|
||||
/// Serializes a diagnostic value to indented JSON without panicking.
|
||||
pub(crate) use self::demo_devnet_common::pretty_json;
|
||||
/// Resolves the temporary or persistent signer selected by one Devnet profile.
|
||||
pub(crate) use self::demo_devnet_common::resolve_devnet_execution_wallet;
|
||||
/// Selects and validates one Devnet profile by name.
|
||||
pub(crate) use self::demo_devnet_common::select_devnet_profile;
|
||||
/// Bridges Metadata execution progress to the Metadata desktop window.
|
||||
pub(crate) use self::demo_execution_metadata::DemoExecutionMetadataObserver;
|
||||
/// Progress event emitted by Metadata execution workflows.
|
||||
@@ -237,8 +241,6 @@ pub(crate) use self::demo_execution_solana_core::DemoExecutionSolanaCoreRequest;
|
||||
pub(crate) use self::demo_execution_solana_core::DemoExecutionSolanaCoreSummaryPayload;
|
||||
/// Maps a confirmation status to its stable UI code.
|
||||
pub(crate) use self::demo_execution_solana_core::confirmation_status_code;
|
||||
/// Returns compatible Devnet profiles and conservative defaults.
|
||||
pub(crate) use self::demo_execution_solana_core::demo_execution_devnet_prepare_profile;
|
||||
/// Requests cooperative cancellation before the next execution stage.
|
||||
pub(crate) use self::demo_execution_solana_core::demo_execution_solana_core_cancel;
|
||||
/// Executes one bounded System transfer simulation or Devnet submission.
|
||||
@@ -251,8 +253,6 @@ pub(crate) use self::demo_execution_solana_core::demo_execution_solana_core_opti
|
||||
pub(crate) use self::demo_execution_solana_core::demo_execution_spl_memo_execute;
|
||||
/// Maps an execution cluster to its stable UI code.
|
||||
pub(crate) use self::demo_execution_solana_core::execution_cluster_code;
|
||||
/// Selects and validates one Devnet profile by name.
|
||||
pub(crate) use self::demo_execution_solana_core::select_devnet_profile;
|
||||
/// Frontend payload for one independent Devnet SPL validation scenario.
|
||||
pub(crate) use self::demo_execution_spl::DevnetSplValidationScenarioPayload;
|
||||
/// Returns the complete ordered Devnet SPL validation inventory for milestone 0.4.6.
|
||||
@@ -283,6 +283,8 @@ pub(crate) use self::demo_spl_ata::DemoExecutionSplAtaSummaryPayload;
|
||||
pub(crate) use self::demo_spl_ata::DemoSplAtaDerivationPayload;
|
||||
/// Request used to derive the representative wallet ATA before execution.
|
||||
pub(crate) use self::demo_spl_ata::DemoSplAtaDerivationRequest;
|
||||
/// One counted Store block of ATA lifecycle journal rows.
|
||||
pub(crate) use self::demo_spl_ata::DemoSplAtaJournalPagePayload;
|
||||
/// Bounded ATA lifecycle journal request.
|
||||
pub(crate) use self::demo_spl_ata::DemoSplAtaJournalRequest;
|
||||
/// One UI-safe ATA lifecycle journal row.
|
||||
@@ -297,6 +299,8 @@ pub(crate) use self::demo_spl_ata::demo_spl_ata_journal;
|
||||
pub(crate) use self::demo_spl_token::DemoExecutionSplTokenRequest;
|
||||
/// UI-safe result of one checked SPL Token transfer orchestration.
|
||||
pub(crate) use self::demo_spl_token::DemoExecutionSplTokenSummaryPayload;
|
||||
/// One counted Store block of classic SPL Token journal rows.
|
||||
pub(crate) use self::demo_spl_token::DemoSplTokenJournalPagePayload;
|
||||
/// Bounded exact filters for the classic SPL Token materialized journal.
|
||||
pub(crate) use self::demo_spl_token::DemoSplTokenJournalRequest;
|
||||
/// UI-safe materialized classic SPL Token journal row.
|
||||
@@ -315,16 +319,24 @@ pub(crate) use self::demo_spl_token_2022::DemoSplToken2022FixturePayload;
|
||||
pub(crate) use self::demo_spl_token_2022::demo_execution_spl_token_2022_execute;
|
||||
/// Loads public Token-2022 fixture values without reading private key bytes.
|
||||
pub(crate) use self::demo_spl_token_2022::demo_spl_token_2022_fixture;
|
||||
/// Fixed Store block size used by desktop listings.
|
||||
pub(crate) use self::demo_store_common::DEMO_STORE_BLOCK_SIZE;
|
||||
/// UI-safe Store block pagination metadata.
|
||||
pub(crate) use self::demo_store_common::DemoStoreBlockMetadata;
|
||||
/// UI-safe logical store resource diagnostic snapshot.
|
||||
pub(crate) use self::demo_store_common::DemoStoreResourceSnapshot;
|
||||
/// Formats diagnostic statuses.
|
||||
pub(crate) use self::demo_store_common::debug_status;
|
||||
/// Calculates refreshed Store block metadata for desktop listings.
|
||||
pub(crate) use self::demo_store_common::demo_store_block_metadata;
|
||||
/// Builds one fixed-size Store block request for desktop listings.
|
||||
pub(crate) use self::demo_store_common::demo_store_block_request;
|
||||
/// Opens and verifies the configured store during startup.
|
||||
pub(crate) use self::demo_store_common::initialize_store_for_startup;
|
||||
/// Opens the configured backend-agnostic store.
|
||||
pub(crate) use self::demo_store_common::open_store;
|
||||
/// Clones the persistent application store.
|
||||
pub(crate) use self::demo_store_common::shared_store;
|
||||
/// Clones the shared persistent store held for one configured profile.
|
||||
pub(crate) use self::demo_store_common::shared_store_for_profile;
|
||||
/// Returns the safe connection descriptor exposed by the active store backend.
|
||||
pub(crate) use self::demo_store_common::store_connection_descriptor;
|
||||
/// Converts one logical store resource diagnostic.
|
||||
@@ -343,6 +355,8 @@ pub(crate) use self::demo_store_diag::load_demo_store_diag;
|
||||
pub(crate) use self::demo_store_raw::DemoStoreRawPayload;
|
||||
/// Loads read-only raw resource diagnostics from the active store.
|
||||
pub(crate) use self::demo_store_raw::load_demo_store_raw;
|
||||
/// Store replay entity page payload.
|
||||
pub(crate) use self::demo_store_replay_candidates::DemoStoreReplayEntityPagePayload;
|
||||
/// Store replay entity request.
|
||||
pub(crate) use self::demo_store_replay_candidates::DemoStoreReplayEntityRequest;
|
||||
/// Store replay entity row.
|
||||
@@ -351,10 +365,14 @@ pub(crate) use self::demo_store_replay_candidates::DemoStoreReplayEntityRow;
|
||||
pub(crate) use self::demo_store_replay_candidates::DemoStoreReplayKnownProgramOption;
|
||||
/// Store replay options payload.
|
||||
pub(crate) use self::demo_store_replay_candidates::DemoStoreReplayOptionsPayload;
|
||||
/// Store replay program page payload.
|
||||
pub(crate) use self::demo_store_replay_candidates::DemoStoreReplayProgramPagePayload;
|
||||
/// Store replay program request.
|
||||
pub(crate) use self::demo_store_replay_candidates::DemoStoreReplayProgramRequest;
|
||||
/// Store replay program row.
|
||||
pub(crate) use self::demo_store_replay_candidates::DemoStoreReplayProgramRow;
|
||||
/// Store replay transaction page payload.
|
||||
pub(crate) use self::demo_store_replay_candidates::DemoStoreReplayTransactionPagePayload;
|
||||
/// Store replay transaction request.
|
||||
pub(crate) use self::demo_store_replay_candidates::DemoStoreReplayTransactionRequest;
|
||||
/// Store replay transaction row.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/tauri.rs
|
||||
// version: 46
|
||||
// version: 47
|
||||
|
||||
//! Tauri runtime assembly and private command wrappers.
|
||||
|
||||
@@ -513,7 +513,7 @@ async fn demo_decode_replay_diagnostics(
|
||||
async fn demo_decode_replay_annotations(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
request: crate::DemoTransactionAnnotationRequest,
|
||||
) -> std::result::Result<std::vec::Vec<crate::DemoTransactionAnnotationRow>, std::string::String> {
|
||||
) -> std::result::Result<crate::DemoTransactionAnnotationPagePayload, std::string::String> {
|
||||
return crate::demo_decode_replay_annotations(state, request).await;
|
||||
}
|
||||
|
||||
@@ -605,7 +605,7 @@ async fn demo_store_replay_options(
|
||||
async fn load_demo_store_replay_transactions(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
request: crate::DemoStoreReplayTransactionRequest,
|
||||
) -> std::result::Result<std::vec::Vec<crate::DemoStoreReplayTransactionRow>, std::string::String> {
|
||||
) -> std::result::Result<crate::DemoStoreReplayTransactionPagePayload, std::string::String> {
|
||||
return crate::load_demo_store_replay_transactions(state, request).await;
|
||||
}
|
||||
|
||||
@@ -613,7 +613,7 @@ async fn load_demo_store_replay_transactions(
|
||||
async fn load_demo_store_replay_programs(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
request: crate::DemoStoreReplayProgramRequest,
|
||||
) -> std::result::Result<std::vec::Vec<crate::DemoStoreReplayProgramRow>, std::string::String> {
|
||||
) -> std::result::Result<crate::DemoStoreReplayProgramPagePayload, std::string::String> {
|
||||
return crate::load_demo_store_replay_programs(state, request).await;
|
||||
}
|
||||
|
||||
@@ -621,7 +621,7 @@ async fn load_demo_store_replay_programs(
|
||||
async fn load_demo_store_replay_entities(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
request: crate::DemoStoreReplayEntityRequest,
|
||||
) -> std::result::Result<std::vec::Vec<crate::DemoStoreReplayEntityRow>, std::string::String> {
|
||||
) -> std::result::Result<crate::DemoStoreReplayEntityPagePayload, std::string::String> {
|
||||
return crate::load_demo_store_replay_entities(state, request).await;
|
||||
}
|
||||
|
||||
@@ -857,7 +857,7 @@ async fn demo_execution_spl_token_execute(
|
||||
async fn demo_spl_token_journal(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
request: crate::DemoSplTokenJournalRequest,
|
||||
) -> std::result::Result<std::vec::Vec<crate::DemoSplTokenJournalRow>, std::string::String> {
|
||||
) -> std::result::Result<crate::DemoSplTokenJournalPagePayload, std::string::String> {
|
||||
return crate::demo_spl_token_journal(state, request).await;
|
||||
}
|
||||
|
||||
@@ -882,7 +882,7 @@ async fn demo_execution_spl_ata_execute(
|
||||
async fn demo_spl_ata_journal(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
request: crate::DemoSplAtaJournalRequest,
|
||||
) -> std::result::Result<std::vec::Vec<crate::DemoSplAtaJournalRow>, std::string::String> {
|
||||
) -> std::result::Result<crate::DemoSplAtaJournalPagePayload, std::string::String> {
|
||||
return crate::demo_spl_ata_journal(state, request).await;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user