Problem
In packages/rs-dpp/src/state_transition/mod.rs, the StateTransition enum derives Serialize (behind state-transition-serde-conversion feature), but serde_json::to_string_pretty(&state_transition) fails with "key must be a string" for any variant that contains BTreeMap<PlatformAddress, ...> (e.g. AddressFundsTransfer, AddressFundingFromAssetLock, AddressCreditWithdrawal, IdentityCreateFromAddresses, IdentityTopUpFromAddresses, IdentityCreditTransferToAddresses).
This happens because PlatformAddress is an enum that serializes as a complex structure, not a string, and JSON requires all object keys to be strings.
Every individual variant type already implements StateTransitionJsonConvert (which has a to_json() method that properly converts through platform_value::Value, stringifying identifiers and binary data). But the top-level StateTransition enum itself does NOT implement it, forcing consumers to match on all 15 variants manually.
Proposed Fix
Add an impl StateTransitionJsonConvert<'_> for StateTransition that dispatches to each variant's to_json(). This should go in a new file packages/rs-dpp/src/state_transition/json_conversion.rs (gated behind #[cfg(feature = "state-transition-json-conversion")]), similar to how value_conversion.rs or other dispatch files are structured. The implementation:
#[cfg(feature = "state-transition-json-conversion")]
impl StateTransitionJsonConvert<'_> for StateTransition {
fn to_json(
&self,
options: JsonStateTransitionSerializationOptions,
) -> Result<serde_json::Value, ProtocolError> {
match self {
StateTransition::DataContractCreate(st) => st.to_json(options),
StateTransition::DataContractUpdate(st) => st.to_json(options),
StateTransition::Batch(st) => st.to_json(options),
StateTransition::IdentityCreate(st) => st.to_json(options),
StateTransition::IdentityTopUp(st) => st.to_json(options),
StateTransition::IdentityCreditWithdrawal(st) => st.to_json(options),
StateTransition::IdentityUpdate(st) => st.to_json(options),
StateTransition::IdentityCreditTransfer(st) => st.to_json(options),
StateTransition::MasternodeVote(st) => st.to_json(options),
StateTransition::IdentityCreditTransferToAddresses(st) => st.to_json(options),
StateTransition::IdentityCreateFromAddresses(st) => st.to_json(options),
StateTransition::IdentityTopUpFromAddresses(st) => st.to_json(options),
StateTransition::AddressFundsTransfer(st) => st.to_json(options),
StateTransition::AddressFundingFromAssetLock(st) => st.to_json(options),
StateTransition::AddressCreditWithdrawal(st) => st.to_json(options),
}
}
}
Note: StateTransitionJsonConvert has a blanket default to_json() that calls self.to_object() (from StateTransitionValueConvert). Since StateTransitionValueConvert is also not implemented for the top-level enum, the explicit override above is needed. It may also make sense to implement StateTransitionValueConvert for StateTransition with the same dispatch pattern.
Also consider adding state-transition-json-conversion to the dash-sdk-features list in packages/rs-dpp/Cargo.toml so SDK consumers get it by default.
Problem
In
packages/rs-dpp/src/state_transition/mod.rs, theStateTransitionenum derivesSerialize(behindstate-transition-serde-conversionfeature), butserde_json::to_string_pretty(&state_transition)fails with "key must be a string" for any variant that containsBTreeMap<PlatformAddress, ...>(e.g.AddressFundsTransfer,AddressFundingFromAssetLock,AddressCreditWithdrawal,IdentityCreateFromAddresses,IdentityTopUpFromAddresses,IdentityCreditTransferToAddresses).This happens because
PlatformAddressis an enum that serializes as a complex structure, not a string, and JSON requires all object keys to be strings.Every individual variant type already implements
StateTransitionJsonConvert(which has ato_json()method that properly converts throughplatform_value::Value, stringifying identifiers and binary data). But the top-levelStateTransitionenum itself does NOT implement it, forcing consumers to match on all 15 variants manually.Proposed Fix
Add an
impl StateTransitionJsonConvert<'_> for StateTransitionthat dispatches to each variant'sto_json(). This should go in a new filepackages/rs-dpp/src/state_transition/json_conversion.rs(gated behind#[cfg(feature = "state-transition-json-conversion")]), similar to howvalue_conversion.rsor other dispatch files are structured. The implementation:Note:
StateTransitionJsonConverthas a blanket defaultto_json()that callsself.to_object()(fromStateTransitionValueConvert). SinceStateTransitionValueConvertis also not implemented for the top-level enum, the explicit override above is needed. It may also make sense to implementStateTransitionValueConvertforStateTransitionwith the same dispatch pattern.Also consider adding
state-transition-json-conversionto thedash-sdk-featureslist inpackages/rs-dpp/Cargo.tomlso SDK consumers get it by default.