Problem
The SDK's PlatformVersion is set at build time via SdkBuilder::with_version() and stored as a fixed &'static PlatformVersion inside SdkInstance. There is no mechanism to update it at runtime based on the actual network state.
This causes two problems:
-
Feature gating: Applications cannot determine which Platform features are available on the connected network. For example, shielded transactions (ZK) will only be available starting from Platform v3.1 (protocol version 12+). Without knowing the network's actual protocol version, the app cannot hide unavailable features.
-
Version mismatch: If the SDK is compiled with protocol version 12 but the connected network is still on version 11, state transitions built with v12 serialization may be rejected. The SDK should ideally match the network's version.
Current State
SdkBuilder::with_version() sets the version at initialization — &'static PlatformVersion
Sdk::version() returns the build-time version, never updated
ExtendedEpochInfo::fetch_current() returns protocol_version() — the live network protocol version from the current epoch
PlatformVersion::get(version: u32) can look up the &'static PlatformVersion for a given protocol version number
PlatformVersionCurrentVersion::set_current() exists as a global RwLock setter in DPP, but the SDK doesn't use it
Proposed Solution
1. Add Sdk::update_version_from_network() method
impl Sdk {
/// Fetch the current epoch info from the network and update the SDK's
/// protocol version to match. Call this periodically (e.g., on epoch change)
/// or after initial connection.
pub async fn update_version_from_network(&self) -> Result<&'static PlatformVersion, Error> {
let epoch_info = ExtendedEpochInfo::fetch_current(self).await?;
let network_version = epoch_info.protocol_version();
let platform_version = PlatformVersion::get(network_version)?;
self.set_version(platform_version);
Ok(platform_version)
}
}
2. Add Sdk::set_version() runtime setter
The current SdkInstance stores version: &'static PlatformVersion as a plain field. To allow runtime updates:
- Wrap the version field in an
ArcSwap<&'static PlatformVersion> or similar lock-free atomic pointer
- Add
pub fn set_version(&self, version: &'static PlatformVersion) that updates the stored version
Sdk::version() continues to return &'static PlatformVersion — reads are zero-cost with ArcSwap::load()
3. Expose Sdk::protocol_version() convenience method
impl Sdk {
/// Returns the numeric protocol version (e.g., 11, 12).
pub fn protocol_version(&self) -> u32 {
self.version().protocol_version
}
}
4. Also update PlatformVersionCurrentVersion::set_current()
When set_version() is called, also call PlatformVersionCurrentVersion::set_current() so that DPP code using the global version stays in sync.
Use Cases
Feature gating in Dash Evo Tool
// After connecting to network:
sdk.update_version_from_network().await?;
// Gate shielded features:
if sdk.protocol_version() >= 12 {
// Show shielded tab, enable shielded MCP tools
}
Automatic version tracking
// On each epoch info refresh (periodic task):
let epoch_info = ExtendedEpochInfo::fetch_current(&sdk).await?;
let new_version = epoch_info.protocol_version();
if new_version != sdk.protocol_version() {
sdk.set_version(PlatformVersion::get(new_version)?);
tracing::info!("Platform protocol version updated: {new_version}");
}
Files Affected
| File |
Change |
packages/rs-sdk/src/sdk.rs |
Add set_version(), update_version_from_network(), protocol_version() |
packages/rs-sdk/src/sdk.rs (SdkInstance) |
Wrap version field in ArcSwap or similar |
Acceptance Criteria
🤖 Co-authored by Claudius the Magnificent AI Agent
Problem
The SDK's
PlatformVersionis set at build time viaSdkBuilder::with_version()and stored as a fixed&'static PlatformVersioninsideSdkInstance. There is no mechanism to update it at runtime based on the actual network state.This causes two problems:
Feature gating: Applications cannot determine which Platform features are available on the connected network. For example, shielded transactions (ZK) will only be available starting from Platform v3.1 (protocol version 12+). Without knowing the network's actual protocol version, the app cannot hide unavailable features.
Version mismatch: If the SDK is compiled with protocol version 12 but the connected network is still on version 11, state transitions built with v12 serialization may be rejected. The SDK should ideally match the network's version.
Current State
SdkBuilder::with_version()sets the version at initialization —&'static PlatformVersionSdk::version()returns the build-time version, never updatedExtendedEpochInfo::fetch_current()returnsprotocol_version()— the live network protocol version from the current epochPlatformVersion::get(version: u32)can look up the&'static PlatformVersionfor a given protocol version numberPlatformVersionCurrentVersion::set_current()exists as a globalRwLocksetter in DPP, but the SDK doesn't use itProposed Solution
1. Add
Sdk::update_version_from_network()method2. Add
Sdk::set_version()runtime setterThe current
SdkInstancestoresversion: &'static PlatformVersionas a plain field. To allow runtime updates:ArcSwap<&'static PlatformVersion>or similar lock-free atomic pointerpub fn set_version(&self, version: &'static PlatformVersion)that updates the stored versionSdk::version()continues to return&'static PlatformVersion— reads are zero-cost withArcSwap::load()3. Expose
Sdk::protocol_version()convenience method4. Also update
PlatformVersionCurrentVersion::set_current()When
set_version()is called, also callPlatformVersionCurrentVersion::set_current()so that DPP code using the global version stays in sync.Use Cases
Feature gating in Dash Evo Tool
Automatic version tracking
Files Affected
packages/rs-sdk/src/sdk.rsset_version(),update_version_from_network(),protocol_version()packages/rs-sdk/src/sdk.rs(SdkInstance)versionfield inArcSwapor similarAcceptance Criteria
Sdk::set_version()updates the protocol version at runtimeSdk::update_version_from_network()fetches epoch info and updates versionSdk::protocol_version()returns the numeric protocol versionPlatformVersionCurrentVersion::set_current()is called on version updateSdk::version()remains backward-compatible (returns&'static PlatformVersion)version()duringset_version()are safe🤖 Co-authored by Claudius the Magnificent AI Agent