diff --git a/packages/wasm-sdk/api-definitions.json b/packages/wasm-sdk/api-definitions.json
index 67e39c11d6..4e959b3c52 100644
--- a/packages/wasm-sdk/api-definitions.json
+++ b/packages/wasm-sdk/api-definitions.json
@@ -848,6 +848,7 @@
"getEvonodesProposedEpochBlocksByIds": {
"label": "Get Evonodes Proposed Epoch Blocks by IDs",
"description": "Get proposed blocks by evonode IDs",
+ "supportsProof": false,
"inputs": [
{
"name": "epoch",
@@ -867,6 +868,7 @@
"getEvonodesProposedEpochBlocksByRange": {
"label": "Get Evonodes Proposed Epoch Blocks by Range",
"description": "Get proposed blocks by range",
+ "supportsProof": false,
"inputs": [
{
"name": "epoch",
@@ -1121,11 +1123,13 @@
"getStatus": {
"label": "Get Status",
"description": "Get system status",
+ "supportsProof": false,
"inputs": []
},
"getCurrentQuorumsInfo": {
"label": "Get Current Quorums Info",
"description": "Get information about current quorums",
+ "supportsProof": false,
"inputs": []
},
"getPrefundedSpecializedBalance": {
@@ -1167,6 +1171,7 @@
"waitForStateTransitionResult": {
"label": "Wait for State Transition Result",
"description": "Internal query to wait for and retrieve the result of a previously submitted state transition",
+ "supportsProof": false,
"inputs": [
{
"name": "stateTransitionHash",
diff --git a/packages/wasm-sdk/index.html b/packages/wasm-sdk/index.html
index 93f8083832..a830f4dbad 100644
--- a/packages/wasm-sdk/index.html
+++ b/packages/wasm-sdk/index.html
@@ -161,6 +161,10 @@
Query Parameters
+
+ Note: this query does not provide cryptographic proof verification.
+
+
@@ -4171,6 +4175,7 @@ Results
document.getElementById('queryType').style.display = 'none';
document.getElementById('queryInputs').style.display = 'none';
document.getElementById('proofToggleContainer').style.display = 'none';
+ document.getElementById('noProofInfoContainer').style.display = 'none';
document.getElementById('executeQuery').style.display = 'none';
document.getElementById('queryDescription').style.display = 'none';
});
@@ -4190,6 +4195,7 @@ Results
// Hide inputs and button
queryInputs.style.display = 'none';
document.getElementById('proofToggleContainer').style.display = 'none';
+ document.getElementById('noProofInfoContainer').style.display = 'none';
executeButton.style.display = 'none';
queryDescription.style.display = 'none';
@@ -4364,12 +4370,22 @@ Results
queryInputs.style.display = 'block';
executeButton.style.display = 'block';
- // Show proof toggle for queries only
+ // Show proof toggle for queries that support proofs
const proofToggleContainer = document.getElementById('proofToggleContainer');
+ const noProofInfoContainer = document.getElementById('noProofInfoContainer');
if (operationType === 'queries') {
- proofToggleContainer.style.display = 'block';
+ // Check if query supports proof (defaults to true if not specified)
+ const supportsProof = definition?.supportsProof !== false;
+ if (supportsProof) {
+ proofToggleContainer.style.display = 'block';
+ noProofInfoContainer.style.display = 'none';
+ } else {
+ proofToggleContainer.style.display = 'none';
+ noProofInfoContainer.style.display = 'block';
+ }
} else {
proofToggleContainer.style.display = 'none';
+ noProofInfoContainer.style.display = 'none';
}
// Update button text based on operation type
@@ -4454,6 +4470,7 @@ Results
} else {
queryInputs.style.display = 'none';
document.getElementById('proofToggleContainer').style.display = 'none';
+ document.getElementById('noProofInfoContainer').style.display = 'none';
executeButton.style.display = 'none';
queryDescription.style.display = 'none';
}
diff --git a/packages/wasm-sdk/src/queries/system.rs b/packages/wasm-sdk/src/queries/system.rs
index e34d781fd7..90d0d8999d 100644
--- a/packages/wasm-sdk/src/queries/system.rs
+++ b/packages/wasm-sdk/src/queries/system.rs
@@ -5,13 +5,103 @@ use serde::{Serialize, Deserialize};
use serde::ser::Serialize as _;
use dash_sdk::dpp::core_types::validator_set::v0::ValidatorSetV0Getters;
+// Response structures for the gRPC getStatus endpoint
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
-struct PlatformStatus {
- version: u32,
- network: String,
- block_height: Option,
- core_height: Option,
+struct StatusResponse {
+ version: StatusVersion,
+ node: StatusNode,
+ chain: StatusChain,
+ network: StatusNetwork,
+ state_sync: StatusStateSync,
+ time: StatusTime,
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+struct StatusVersion {
+ software: StatusSoftware,
+ protocol: StatusProtocol,
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+struct StatusSoftware {
+ dapi: String,
+ drive: Option,
+ tenderdash: Option,
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+struct StatusProtocol {
+ tenderdash: StatusTenderdashProtocol,
+ drive: StatusDriveProtocol,
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+struct StatusTenderdashProtocol {
+ p2p: u32,
+ block: u32,
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+struct StatusDriveProtocol {
+ latest: u32,
+ current: u32,
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+struct StatusNode {
+ id: String,
+ pro_tx_hash: Option,
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+struct StatusChain {
+ catching_up: bool,
+ latest_block_hash: String,
+ latest_app_hash: String,
+ latest_block_height: String,
+ earliest_block_hash: String,
+ earliest_app_hash: String,
+ earliest_block_height: String,
+ max_peer_block_height: String,
+ core_chain_locked_height: Option,
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+struct StatusNetwork {
+ chain_id: String,
+ peers_count: u32,
+ listening: bool,
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+struct StatusStateSync {
+ total_synced_time: String,
+ remaining_time: String,
+ total_snapshots: u32,
+ chunk_process_avg_time: String,
+ snapshot_height: String,
+ snapshot_chunks_count: String,
+ backfilled_blocks: String,
+ backfill_blocks_total: String,
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+struct StatusTime {
+ local: String,
+ block: Option,
+ genesis: Option,
+ epoch: Option,
}
#[derive(Serialize, Deserialize, Debug)]
@@ -61,38 +151,160 @@ struct PathElement {
#[wasm_bindgen]
pub async fn get_status(sdk: &WasmSdk) -> Result {
- use dash_sdk::platform::fetch_current_no_parameters::FetchCurrent;
- use dash_sdk::dpp::block::extended_epoch_info::ExtendedEpochInfo;
- use dash_sdk::dpp::block::extended_epoch_info::v0::ExtendedEpochInfoV0Getters;
-
- // Get the network from SDK
- let network_str = match sdk.network {
- dash_sdk::dpp::dashcore::Network::Dash => "mainnet",
- dash_sdk::dpp::dashcore::Network::Testnet => "testnet",
- dash_sdk::dpp::dashcore::Network::Devnet => "devnet",
- dash_sdk::dpp::dashcore::Network::Regtest => "regtest",
- _ => "unknown",
- }.to_string();
-
- // Try to fetch current epoch info to get block heights
- let (block_height, core_height) = match ExtendedEpochInfo::fetch_current(sdk.as_ref()).await {
- Ok(epoch_info) => {
- // Extract heights from epoch info
- let platform_height = Some(epoch_info.first_block_height());
- let core_height = Some(epoch_info.first_core_block_height() as u64);
- (platform_height, core_height)
- }
- Err(_) => {
- // If we can't fetch epoch info, heights remain None
- (None, None)
- }
+ use dapi_grpc::platform::v0::get_status_request::{Version, GetStatusRequestV0};
+ use dapi_grpc::platform::v0::GetStatusRequest;
+ use dash_sdk::RequestSettings;
+ use rs_dapi_client::DapiRequestExecutor;
+
+ // Create the gRPC request
+ let request = GetStatusRequest {
+ version: Some(Version::V0(GetStatusRequestV0 {})),
};
- let status = PlatformStatus {
- version: sdk.version(),
- network: network_str,
- block_height,
- core_height,
+ // Execute the request
+ let response = sdk
+ .as_ref()
+ .execute(request, RequestSettings::default())
+ .await
+ .map_err(|e| JsError::new(&format!("Failed to get status: {}", e)))?;
+
+ // Parse the response
+ use dapi_grpc::platform::v0::get_status_response::Version as ResponseVersion;
+
+ let v0_response = match response.inner.version {
+ Some(ResponseVersion::V0(v0)) => v0,
+ None => return Err(JsError::new("No version in GetStatus response")),
+ };
+
+ // Map the response to our StatusResponse structure
+ let status = StatusResponse {
+ version: StatusVersion {
+ software: StatusSoftware {
+ dapi: v0_response.version.as_ref()
+ .map(|v| v.software.as_ref())
+ .flatten()
+ .map(|s| s.dapi.clone())
+ .unwrap_or_else(|| "unknown".to_string()),
+ drive: v0_response.version.as_ref()
+ .and_then(|v| v.software.as_ref())
+ .and_then(|s| s.drive.clone()),
+ tenderdash: v0_response.version.as_ref()
+ .and_then(|v| v.software.as_ref())
+ .and_then(|s| s.tenderdash.clone()),
+ },
+ protocol: StatusProtocol {
+ tenderdash: StatusTenderdashProtocol {
+ p2p: v0_response.version.as_ref()
+ .and_then(|v| v.protocol.as_ref())
+ .and_then(|p| p.tenderdash.as_ref())
+ .map(|t| t.p2p)
+ .unwrap_or(0),
+ block: v0_response.version.as_ref()
+ .and_then(|v| v.protocol.as_ref())
+ .and_then(|p| p.tenderdash.as_ref())
+ .map(|t| t.block)
+ .unwrap_or(0),
+ },
+ drive: StatusDriveProtocol {
+ latest: v0_response.version.as_ref()
+ .and_then(|v| v.protocol.as_ref())
+ .and_then(|p| p.drive.as_ref())
+ .map(|d| d.latest)
+ .unwrap_or(0),
+ current: v0_response.version.as_ref()
+ .and_then(|v| v.protocol.as_ref())
+ .and_then(|p| p.drive.as_ref())
+ .map(|d| d.current)
+ .unwrap_or(0),
+ },
+ },
+ },
+ node: StatusNode {
+ id: v0_response.node.as_ref()
+ .map(|n| hex::encode(&n.id))
+ .unwrap_or_else(|| "unknown".to_string()),
+ pro_tx_hash: v0_response.node.as_ref()
+ .and_then(|n| n.pro_tx_hash.as_ref())
+ .map(|hash| hex::encode(hash)),
+ },
+ chain: StatusChain {
+ catching_up: v0_response.chain.as_ref()
+ .map(|c| c.catching_up)
+ .unwrap_or(false),
+ latest_block_hash: v0_response.chain.as_ref()
+ .map(|c| hex::encode(&c.latest_block_hash))
+ .unwrap_or_else(|| "unknown".to_string()),
+ latest_app_hash: v0_response.chain.as_ref()
+ .map(|c| hex::encode(&c.latest_app_hash))
+ .unwrap_or_else(|| "unknown".to_string()),
+ latest_block_height: v0_response.chain.as_ref()
+ .map(|c| c.latest_block_height.to_string())
+ .unwrap_or_else(|| "0".to_string()),
+ earliest_block_hash: v0_response.chain.as_ref()
+ .map(|c| hex::encode(&c.earliest_block_hash))
+ .unwrap_or_else(|| "unknown".to_string()),
+ earliest_app_hash: v0_response.chain.as_ref()
+ .map(|c| hex::encode(&c.earliest_app_hash))
+ .unwrap_or_else(|| "unknown".to_string()),
+ earliest_block_height: v0_response.chain.as_ref()
+ .map(|c| c.earliest_block_height.to_string())
+ .unwrap_or_else(|| "0".to_string()),
+ max_peer_block_height: v0_response.chain.as_ref()
+ .map(|c| c.max_peer_block_height.to_string())
+ .unwrap_or_else(|| "0".to_string()),
+ core_chain_locked_height: v0_response.chain.as_ref()
+ .and_then(|c| c.core_chain_locked_height),
+ },
+ network: StatusNetwork {
+ chain_id: v0_response.network.as_ref()
+ .map(|n| n.chain_id.clone())
+ .unwrap_or_else(|| "unknown".to_string()),
+ peers_count: v0_response.network.as_ref()
+ .map(|n| n.peers_count)
+ .unwrap_or(0),
+ listening: v0_response.network.as_ref()
+ .map(|n| n.listening)
+ .unwrap_or(false),
+ },
+ state_sync: StatusStateSync {
+ total_synced_time: v0_response.state_sync.as_ref()
+ .map(|s| s.total_synced_time.to_string())
+ .unwrap_or_else(|| "0".to_string()),
+ remaining_time: v0_response.state_sync.as_ref()
+ .map(|s| s.remaining_time.to_string())
+ .unwrap_or_else(|| "0".to_string()),
+ total_snapshots: v0_response.state_sync.as_ref()
+ .map(|s| s.total_snapshots)
+ .unwrap_or(0),
+ chunk_process_avg_time: v0_response.state_sync.as_ref()
+ .map(|s| s.chunk_process_avg_time.to_string())
+ .unwrap_or_else(|| "0".to_string()),
+ snapshot_height: v0_response.state_sync.as_ref()
+ .map(|s| s.snapshot_height.to_string())
+ .unwrap_or_else(|| "0".to_string()),
+ snapshot_chunks_count: v0_response.state_sync.as_ref()
+ .map(|s| s.snapshot_chunks_count.to_string())
+ .unwrap_or_else(|| "0".to_string()),
+ backfilled_blocks: v0_response.state_sync.as_ref()
+ .map(|s| s.backfilled_blocks.to_string())
+ .unwrap_or_else(|| "0".to_string()),
+ backfill_blocks_total: v0_response.state_sync.as_ref()
+ .map(|s| s.backfill_blocks_total.to_string())
+ .unwrap_or_else(|| "0".to_string()),
+ },
+ time: StatusTime {
+ local: v0_response.time.as_ref()
+ .map(|t| t.local.to_string())
+ .unwrap_or_else(|| "0".to_string()),
+ block: v0_response.time.as_ref()
+ .and_then(|t| t.block)
+ .map(|b| b.to_string()),
+ genesis: v0_response.time.as_ref()
+ .and_then(|t| t.genesis)
+ .map(|g| g.to_string()),
+ epoch: v0_response.time.as_ref()
+ .and_then(|t| t.epoch),
+ },
};
serde_wasm_bindgen::to_value(&status)
diff --git a/packages/wasm-sdk/test/ui-automation/tests/query-execution.spec.js b/packages/wasm-sdk/test/ui-automation/tests/query-execution.spec.js
index 6a03e604f3..cfa1610556 100644
--- a/packages/wasm-sdk/test/ui-automation/tests/query-execution.spec.js
+++ b/packages/wasm-sdk/test/ui-automation/tests/query-execution.spec.js
@@ -496,7 +496,9 @@ test.describe('WASM SDK Query Execution Tests', () => {
needsParameters: false,
validateFn: (result) => {
expect(result).toBeDefined();
- expect(result).toContain('version');
+ expect(Object.keys(JSON.parse(result))).toEqual(expect.arrayContaining([
+ 'version', 'node', 'chain', 'network', 'stateSync', 'time'
+ ]));
}
},
{