Skip to content

Commit 9ecb1de

Browse files
thephezclaude
andauthored
feat(sdk)!: provide all getStatus info (#2729)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 958ff1d commit 9ecb1de

4 files changed

Lines changed: 274 additions & 38 deletions

File tree

packages/wasm-sdk/api-definitions.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,7 @@
848848
"getEvonodesProposedEpochBlocksByIds": {
849849
"label": "Get Evonodes Proposed Epoch Blocks by IDs",
850850
"description": "Get proposed blocks by evonode IDs",
851+
"supportsProof": false,
851852
"inputs": [
852853
{
853854
"name": "epoch",
@@ -867,6 +868,7 @@
867868
"getEvonodesProposedEpochBlocksByRange": {
868869
"label": "Get Evonodes Proposed Epoch Blocks by Range",
869870
"description": "Get proposed blocks by range",
871+
"supportsProof": false,
870872
"inputs": [
871873
{
872874
"name": "epoch",
@@ -1121,11 +1123,13 @@
11211123
"getStatus": {
11221124
"label": "Get Status",
11231125
"description": "Get system status",
1126+
"supportsProof": false,
11241127
"inputs": []
11251128
},
11261129
"getCurrentQuorumsInfo": {
11271130
"label": "Get Current Quorums Info",
11281131
"description": "Get information about current quorums",
1132+
"supportsProof": false,
11291133
"inputs": []
11301134
},
11311135
"getPrefundedSpecializedBalance": {
@@ -1167,6 +1171,7 @@
11671171
"waitForStateTransitionResult": {
11681172
"label": "Wait for State Transition Result",
11691173
"description": "Internal query to wait for and retrieve the result of a previously submitted state transition",
1174+
"supportsProof": false,
11701175
"inputs": [
11711176
{
11721177
"name": "stateTransitionHash",

packages/wasm-sdk/index.html

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ <h4 id="queryTitle">Query Parameters</h4>
161161
</label>
162162
</div>
163163

164+
<div class="no-proof-info" style="display: none; margin: 15px 0; padding: 10px; background-color: #f8f9fa; border: 1px solid #e9ecef; border-radius: 4px; text-align: center;" id="noProofInfoContainer">
165+
<span style="color: #6c757d; font-size: 0.9em;">Note: this query does not provide cryptographic proof verification.</span>
166+
</div>
167+
164168
<button id="executeQuery" class="execute-button" style="display: none;">Execute Query</button>
165169
</div>
166170
</div>
@@ -4171,6 +4175,7 @@ <h2>Results</h2>
41714175
document.getElementById('queryType').style.display = 'none';
41724176
document.getElementById('queryInputs').style.display = 'none';
41734177
document.getElementById('proofToggleContainer').style.display = 'none';
4178+
document.getElementById('noProofInfoContainer').style.display = 'none';
41744179
document.getElementById('executeQuery').style.display = 'none';
41754180
document.getElementById('queryDescription').style.display = 'none';
41764181
});
@@ -4190,6 +4195,7 @@ <h2>Results</h2>
41904195
// Hide inputs and button
41914196
queryInputs.style.display = 'none';
41924197
document.getElementById('proofToggleContainer').style.display = 'none';
4198+
document.getElementById('noProofInfoContainer').style.display = 'none';
41934199
executeButton.style.display = 'none';
41944200
queryDescription.style.display = 'none';
41954201

@@ -4364,12 +4370,22 @@ <h2>Results</h2>
43644370
queryInputs.style.display = 'block';
43654371
executeButton.style.display = 'block';
43664372

4367-
// Show proof toggle for queries only
4373+
// Show proof toggle for queries that support proofs
43684374
const proofToggleContainer = document.getElementById('proofToggleContainer');
4375+
const noProofInfoContainer = document.getElementById('noProofInfoContainer');
43694376
if (operationType === 'queries') {
4370-
proofToggleContainer.style.display = 'block';
4377+
// Check if query supports proof (defaults to true if not specified)
4378+
const supportsProof = definition?.supportsProof !== false;
4379+
if (supportsProof) {
4380+
proofToggleContainer.style.display = 'block';
4381+
noProofInfoContainer.style.display = 'none';
4382+
} else {
4383+
proofToggleContainer.style.display = 'none';
4384+
noProofInfoContainer.style.display = 'block';
4385+
}
43714386
} else {
43724387
proofToggleContainer.style.display = 'none';
4388+
noProofInfoContainer.style.display = 'none';
43734389
}
43744390

43754391
// Update button text based on operation type
@@ -4454,6 +4470,7 @@ <h2>Results</h2>
44544470
} else {
44554471
queryInputs.style.display = 'none';
44564472
document.getElementById('proofToggleContainer').style.display = 'none';
4473+
document.getElementById('noProofInfoContainer').style.display = 'none';
44574474
executeButton.style.display = 'none';
44584475
queryDescription.style.display = 'none';
44594476
}

packages/wasm-sdk/src/queries/system.rs

Lines changed: 247 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,103 @@ use serde::{Serialize, Deserialize};
55
use serde::ser::Serialize as _;
66
use dash_sdk::dpp::core_types::validator_set::v0::ValidatorSetV0Getters;
77

8+
// Response structures for the gRPC getStatus endpoint
89
#[derive(Serialize, Deserialize, Debug)]
910
#[serde(rename_all = "camelCase")]
10-
struct PlatformStatus {
11-
version: u32,
12-
network: String,
13-
block_height: Option<u64>,
14-
core_height: Option<u64>,
11+
struct StatusResponse {
12+
version: StatusVersion,
13+
node: StatusNode,
14+
chain: StatusChain,
15+
network: StatusNetwork,
16+
state_sync: StatusStateSync,
17+
time: StatusTime,
18+
}
19+
20+
#[derive(Serialize, Deserialize, Debug)]
21+
#[serde(rename_all = "camelCase")]
22+
struct StatusVersion {
23+
software: StatusSoftware,
24+
protocol: StatusProtocol,
25+
}
26+
27+
#[derive(Serialize, Deserialize, Debug)]
28+
#[serde(rename_all = "camelCase")]
29+
struct StatusSoftware {
30+
dapi: String,
31+
drive: Option<String>,
32+
tenderdash: Option<String>,
33+
}
34+
35+
#[derive(Serialize, Deserialize, Debug)]
36+
#[serde(rename_all = "camelCase")]
37+
struct StatusProtocol {
38+
tenderdash: StatusTenderdashProtocol,
39+
drive: StatusDriveProtocol,
40+
}
41+
42+
#[derive(Serialize, Deserialize, Debug)]
43+
#[serde(rename_all = "camelCase")]
44+
struct StatusTenderdashProtocol {
45+
p2p: u32,
46+
block: u32,
47+
}
48+
49+
#[derive(Serialize, Deserialize, Debug)]
50+
#[serde(rename_all = "camelCase")]
51+
struct StatusDriveProtocol {
52+
latest: u32,
53+
current: u32,
54+
}
55+
56+
#[derive(Serialize, Deserialize, Debug)]
57+
#[serde(rename_all = "camelCase")]
58+
struct StatusNode {
59+
id: String,
60+
pro_tx_hash: Option<String>,
61+
}
62+
63+
#[derive(Serialize, Deserialize, Debug)]
64+
#[serde(rename_all = "camelCase")]
65+
struct StatusChain {
66+
catching_up: bool,
67+
latest_block_hash: String,
68+
latest_app_hash: String,
69+
latest_block_height: String,
70+
earliest_block_hash: String,
71+
earliest_app_hash: String,
72+
earliest_block_height: String,
73+
max_peer_block_height: String,
74+
core_chain_locked_height: Option<u32>,
75+
}
76+
77+
#[derive(Serialize, Deserialize, Debug)]
78+
#[serde(rename_all = "camelCase")]
79+
struct StatusNetwork {
80+
chain_id: String,
81+
peers_count: u32,
82+
listening: bool,
83+
}
84+
85+
#[derive(Serialize, Deserialize, Debug)]
86+
#[serde(rename_all = "camelCase")]
87+
struct StatusStateSync {
88+
total_synced_time: String,
89+
remaining_time: String,
90+
total_snapshots: u32,
91+
chunk_process_avg_time: String,
92+
snapshot_height: String,
93+
snapshot_chunks_count: String,
94+
backfilled_blocks: String,
95+
backfill_blocks_total: String,
96+
}
97+
98+
#[derive(Serialize, Deserialize, Debug)]
99+
#[serde(rename_all = "camelCase")]
100+
struct StatusTime {
101+
local: String,
102+
block: Option<String>,
103+
genesis: Option<String>,
104+
epoch: Option<u32>,
15105
}
16106

17107
#[derive(Serialize, Deserialize, Debug)]
@@ -61,38 +151,160 @@ struct PathElement {
61151

62152
#[wasm_bindgen]
63153
pub async fn get_status(sdk: &WasmSdk) -> Result<JsValue, JsError> {
64-
use dash_sdk::platform::fetch_current_no_parameters::FetchCurrent;
65-
use dash_sdk::dpp::block::extended_epoch_info::ExtendedEpochInfo;
66-
use dash_sdk::dpp::block::extended_epoch_info::v0::ExtendedEpochInfoV0Getters;
67-
68-
// Get the network from SDK
69-
let network_str = match sdk.network {
70-
dash_sdk::dpp::dashcore::Network::Dash => "mainnet",
71-
dash_sdk::dpp::dashcore::Network::Testnet => "testnet",
72-
dash_sdk::dpp::dashcore::Network::Devnet => "devnet",
73-
dash_sdk::dpp::dashcore::Network::Regtest => "regtest",
74-
_ => "unknown",
75-
}.to_string();
76-
77-
// Try to fetch current epoch info to get block heights
78-
let (block_height, core_height) = match ExtendedEpochInfo::fetch_current(sdk.as_ref()).await {
79-
Ok(epoch_info) => {
80-
// Extract heights from epoch info
81-
let platform_height = Some(epoch_info.first_block_height());
82-
let core_height = Some(epoch_info.first_core_block_height() as u64);
83-
(platform_height, core_height)
84-
}
85-
Err(_) => {
86-
// If we can't fetch epoch info, heights remain None
87-
(None, None)
88-
}
154+
use dapi_grpc::platform::v0::get_status_request::{Version, GetStatusRequestV0};
155+
use dapi_grpc::platform::v0::GetStatusRequest;
156+
use dash_sdk::RequestSettings;
157+
use rs_dapi_client::DapiRequestExecutor;
158+
159+
// Create the gRPC request
160+
let request = GetStatusRequest {
161+
version: Some(Version::V0(GetStatusRequestV0 {})),
89162
};
90163

91-
let status = PlatformStatus {
92-
version: sdk.version(),
93-
network: network_str,
94-
block_height,
95-
core_height,
164+
// Execute the request
165+
let response = sdk
166+
.as_ref()
167+
.execute(request, RequestSettings::default())
168+
.await
169+
.map_err(|e| JsError::new(&format!("Failed to get status: {}", e)))?;
170+
171+
// Parse the response
172+
use dapi_grpc::platform::v0::get_status_response::Version as ResponseVersion;
173+
174+
let v0_response = match response.inner.version {
175+
Some(ResponseVersion::V0(v0)) => v0,
176+
None => return Err(JsError::new("No version in GetStatus response")),
177+
};
178+
179+
// Map the response to our StatusResponse structure
180+
let status = StatusResponse {
181+
version: StatusVersion {
182+
software: StatusSoftware {
183+
dapi: v0_response.version.as_ref()
184+
.map(|v| v.software.as_ref())
185+
.flatten()
186+
.map(|s| s.dapi.clone())
187+
.unwrap_or_else(|| "unknown".to_string()),
188+
drive: v0_response.version.as_ref()
189+
.and_then(|v| v.software.as_ref())
190+
.and_then(|s| s.drive.clone()),
191+
tenderdash: v0_response.version.as_ref()
192+
.and_then(|v| v.software.as_ref())
193+
.and_then(|s| s.tenderdash.clone()),
194+
},
195+
protocol: StatusProtocol {
196+
tenderdash: StatusTenderdashProtocol {
197+
p2p: v0_response.version.as_ref()
198+
.and_then(|v| v.protocol.as_ref())
199+
.and_then(|p| p.tenderdash.as_ref())
200+
.map(|t| t.p2p)
201+
.unwrap_or(0),
202+
block: v0_response.version.as_ref()
203+
.and_then(|v| v.protocol.as_ref())
204+
.and_then(|p| p.tenderdash.as_ref())
205+
.map(|t| t.block)
206+
.unwrap_or(0),
207+
},
208+
drive: StatusDriveProtocol {
209+
latest: v0_response.version.as_ref()
210+
.and_then(|v| v.protocol.as_ref())
211+
.and_then(|p| p.drive.as_ref())
212+
.map(|d| d.latest)
213+
.unwrap_or(0),
214+
current: v0_response.version.as_ref()
215+
.and_then(|v| v.protocol.as_ref())
216+
.and_then(|p| p.drive.as_ref())
217+
.map(|d| d.current)
218+
.unwrap_or(0),
219+
},
220+
},
221+
},
222+
node: StatusNode {
223+
id: v0_response.node.as_ref()
224+
.map(|n| hex::encode(&n.id))
225+
.unwrap_or_else(|| "unknown".to_string()),
226+
pro_tx_hash: v0_response.node.as_ref()
227+
.and_then(|n| n.pro_tx_hash.as_ref())
228+
.map(|hash| hex::encode(hash)),
229+
},
230+
chain: StatusChain {
231+
catching_up: v0_response.chain.as_ref()
232+
.map(|c| c.catching_up)
233+
.unwrap_or(false),
234+
latest_block_hash: v0_response.chain.as_ref()
235+
.map(|c| hex::encode(&c.latest_block_hash))
236+
.unwrap_or_else(|| "unknown".to_string()),
237+
latest_app_hash: v0_response.chain.as_ref()
238+
.map(|c| hex::encode(&c.latest_app_hash))
239+
.unwrap_or_else(|| "unknown".to_string()),
240+
latest_block_height: v0_response.chain.as_ref()
241+
.map(|c| c.latest_block_height.to_string())
242+
.unwrap_or_else(|| "0".to_string()),
243+
earliest_block_hash: v0_response.chain.as_ref()
244+
.map(|c| hex::encode(&c.earliest_block_hash))
245+
.unwrap_or_else(|| "unknown".to_string()),
246+
earliest_app_hash: v0_response.chain.as_ref()
247+
.map(|c| hex::encode(&c.earliest_app_hash))
248+
.unwrap_or_else(|| "unknown".to_string()),
249+
earliest_block_height: v0_response.chain.as_ref()
250+
.map(|c| c.earliest_block_height.to_string())
251+
.unwrap_or_else(|| "0".to_string()),
252+
max_peer_block_height: v0_response.chain.as_ref()
253+
.map(|c| c.max_peer_block_height.to_string())
254+
.unwrap_or_else(|| "0".to_string()),
255+
core_chain_locked_height: v0_response.chain.as_ref()
256+
.and_then(|c| c.core_chain_locked_height),
257+
},
258+
network: StatusNetwork {
259+
chain_id: v0_response.network.as_ref()
260+
.map(|n| n.chain_id.clone())
261+
.unwrap_or_else(|| "unknown".to_string()),
262+
peers_count: v0_response.network.as_ref()
263+
.map(|n| n.peers_count)
264+
.unwrap_or(0),
265+
listening: v0_response.network.as_ref()
266+
.map(|n| n.listening)
267+
.unwrap_or(false),
268+
},
269+
state_sync: StatusStateSync {
270+
total_synced_time: v0_response.state_sync.as_ref()
271+
.map(|s| s.total_synced_time.to_string())
272+
.unwrap_or_else(|| "0".to_string()),
273+
remaining_time: v0_response.state_sync.as_ref()
274+
.map(|s| s.remaining_time.to_string())
275+
.unwrap_or_else(|| "0".to_string()),
276+
total_snapshots: v0_response.state_sync.as_ref()
277+
.map(|s| s.total_snapshots)
278+
.unwrap_or(0),
279+
chunk_process_avg_time: v0_response.state_sync.as_ref()
280+
.map(|s| s.chunk_process_avg_time.to_string())
281+
.unwrap_or_else(|| "0".to_string()),
282+
snapshot_height: v0_response.state_sync.as_ref()
283+
.map(|s| s.snapshot_height.to_string())
284+
.unwrap_or_else(|| "0".to_string()),
285+
snapshot_chunks_count: v0_response.state_sync.as_ref()
286+
.map(|s| s.snapshot_chunks_count.to_string())
287+
.unwrap_or_else(|| "0".to_string()),
288+
backfilled_blocks: v0_response.state_sync.as_ref()
289+
.map(|s| s.backfilled_blocks.to_string())
290+
.unwrap_or_else(|| "0".to_string()),
291+
backfill_blocks_total: v0_response.state_sync.as_ref()
292+
.map(|s| s.backfill_blocks_total.to_string())
293+
.unwrap_or_else(|| "0".to_string()),
294+
},
295+
time: StatusTime {
296+
local: v0_response.time.as_ref()
297+
.map(|t| t.local.to_string())
298+
.unwrap_or_else(|| "0".to_string()),
299+
block: v0_response.time.as_ref()
300+
.and_then(|t| t.block)
301+
.map(|b| b.to_string()),
302+
genesis: v0_response.time.as_ref()
303+
.and_then(|t| t.genesis)
304+
.map(|g| g.to_string()),
305+
epoch: v0_response.time.as_ref()
306+
.and_then(|t| t.epoch),
307+
},
96308
};
97309

98310
serde_wasm_bindgen::to_value(&status)

0 commit comments

Comments
 (0)