From ae0b8bb94840f87d1217bbd9c702e32e2b9112b5 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 24 Oct 2023 11:45:15 -0700 Subject: [PATCH] Add str conversions for types for JSON (#313) * Add str conversions for PublicKey * doc * rem * account id * strkey types * docs * fix * upd * accurate docs * fix * doc * fix * fix * fix * fix * fix * fix * fix * fix * fix * upd * remove todo --- Cargo.lock | 17 ++ Cargo.toml | 5 +- Makefile | 8 +- src/curr/generated.rs | 140 ++++++------- src/curr/mod.rs | 2 + src/curr/str.rs | 222 +++++++++++++++++++++ src/next/generated.rs | 119 ++++++----- tests/{tx_serde.rs => serde.rs} | 19 ++ tests/serde_tx.rs | 88 +++++++++ tests/str.rs | 336 ++++++++++++++++++++++++++++++++ 10 files changed, 829 insertions(+), 127 deletions(-) create mode 100644 src/curr/str.rs rename tests/{tx_serde.rs => serde.rs} (75%) create mode 100644 tests/serde_tx.rs create mode 100644 tests/str.rs diff --git a/Cargo.lock b/Cargo.lock index 687c65a9..afdf9a97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base32" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" + [[package]] name = "base64" version = "0.13.0" @@ -468,6 +474,16 @@ dependencies = [ "syn 2.0.15", ] +[[package]] +name = "stellar-strkey" +version = "0.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0689070126ca7f2effc2c5726584446db52190f0cef043c02eb4040a711c11" +dependencies = [ + "base32", + "thiserror", +] + [[package]] name = "stellar-xdr" version = "20.0.0-rc1" @@ -480,6 +496,7 @@ dependencies = [ "serde", "serde_json", "serde_with", + "stellar-strkey", "thiserror", ] diff --git a/Cargo.toml b/Cargo.toml index 7a009d8f..433fdb59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ doctest = false crate-git-revision = "0.0.6" [dependencies] +stellar-strkey = { version = "0.0.7", optional = true } base64 = { version = "0.13.0", optional = true } serde = { version = "1.0.139", features = ["derive"], optional = true } serde_with = { version = "3.0.0", optional = true } @@ -33,7 +34,7 @@ serde_json = "1.0.89" [features] default = ["std", "curr"] -std = ["alloc"] +std = ["alloc", "dep:stellar-strkey"] alloc = ["dep:hex"] curr = [] next = [] @@ -41,7 +42,7 @@ next = [] # Features dependent on optional dependencies. base64 = ["std", "dep:base64"] serde = ["alloc", "dep:serde", "dep:serde_with", "hex/serde"] -serde_json = ["serde", "dep:serde_json"] +serde_json = ["std", "serde", "dep:serde_json"] arbitrary = ["std", "dep:arbitrary"] hex = [] diff --git a/Makefile b/Makefile index 7593cbdc..2f32508a 100644 --- a/Makefile +++ b/Makefile @@ -2,9 +2,11 @@ export RUSTFLAGS=-Dwarnings -Dclippy::all -Dclippy::pedantic CARGO_HACK_ARGS=--feature-powerset --exclude-features default --group-features base64,serde,arbitrary,hex -XDRGEN_VERSION=b405294c CARGO_DOC_ARGS?=--open +XDRGEN_VERSION=64612a24 +XDRGEN_TYPES_CUSTOM_STR_IMPL=PublicKey,AccountId,MuxedAccount,MuxedAccountMed25519,SignerKey,SignerKeyEd25519SignedPayload,NodeId + all: build test test: @@ -35,12 +37,12 @@ ifeq ($(LOCAL_XDRGEN),) docker run -i --rm -v $$PWD:/wd -w /wd docker.io/library/ruby:latest /bin/bash -c '\ gem install specific_install -v 0.3.8 && \ gem specific_install https://github.com/stellar/xdrgen.git -b $(XDRGEN_VERSION) && \ - xdrgen --language rust --namespace generated --output src/curr $^ \ + xdrgen --language rust --namespace generated --output src/curr --rust-types-custom-str-impl $(XDRGEN_TYPES_CUSTOM_STR_IMPL) $^ \ ' else docker run -i --rm -v $$PWD/../xdrgen:/xdrgen -v $$PWD:/wd -w /wd docker.io/library/ruby:latest /bin/bash -c '\ pushd /xdrgen && bundle install --deployment && rake install && popd && \ - xdrgen --language rust --namespace generated --output src/curr $^ \ + xdrgen --language rust --namespace generated --output src/curr --rust-types-custom-str-impl $(XDRGEN_TYPES_CUSTOM_STR_IMPL) $^ \ ' endif rustfmt $@ diff --git a/src/curr/generated.rs b/src/curr/generated.rs index fc532a94..13915e95 100644 --- a/src/curr/generated.rs +++ b/src/curr/generated.rs @@ -2360,12 +2360,13 @@ mod test { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct Value(pub BytesM); impl From for BytesM { @@ -3929,12 +3930,13 @@ pub const CONTRACT_COST_COUNT_LIMIT: u64 = 1024; // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct ContractCostParams(pub VecM); impl From for VecM { @@ -8104,12 +8106,13 @@ pub const SCSYMBOL_LIMIT: u64 = 32; // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct ScVec(pub VecM); impl From for VecM { @@ -8206,12 +8209,13 @@ impl AsRef<[ScVal]> for ScVec { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct ScMap(pub VecM); impl From for VecM { @@ -8308,12 +8312,13 @@ impl AsRef<[ScMapEntry]> for ScMap { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct ScBytes(pub BytesM); impl From for BytesM { @@ -8410,12 +8415,13 @@ impl AsRef<[u8]> for ScBytes { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct ScString(pub StringM); impl From for StringM { @@ -8512,12 +8518,13 @@ impl AsRef<[u8]> for ScString { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct ScSymbol(pub StringM<32>); impl From for StringM<32> { @@ -9398,24 +9405,23 @@ impl WriteXdr for PersistedScpState { )] pub struct Thresholds(pub [u8; 4]); -impl core::fmt::Display for Thresholds { +impl core::fmt::Debug for Thresholds { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; + write!(f, "Thresholds(")?; for b in v { write!(f, "{b:02x}")?; } + write!(f, ")")?; Ok(()) } } - -impl core::fmt::Debug for Thresholds { +impl core::fmt::Display for Thresholds { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; - write!(f, "Thresholds(")?; for b in v { write!(f, "{b:02x}")?; } - write!(f, ")")?; Ok(()) } } @@ -9509,12 +9515,13 @@ impl AsRef<[u8]> for Thresholds { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct String32(pub StringM<32>); impl From for StringM<32> { @@ -9611,12 +9618,13 @@ impl AsRef<[u8]> for String32 { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct String64(pub StringM<64>); impl From for StringM<64> { @@ -9713,12 +9721,12 @@ impl AsRef<[u8]> for String64 { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct SequenceNumber(pub i64); impl From for i64 { @@ -9766,12 +9774,13 @@ impl WriteXdr for SequenceNumber { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct DataValue(pub BytesM<64>); impl From for BytesM<64> { @@ -9868,12 +9877,12 @@ impl AsRef<[u8]> for DataValue { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct PoolId(pub Hash); impl From for Hash { @@ -9927,24 +9936,23 @@ impl WriteXdr for PoolId { )] pub struct AssetCode4(pub [u8; 4]); -impl core::fmt::Display for AssetCode4 { +impl core::fmt::Debug for AssetCode4 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; + write!(f, "AssetCode4(")?; for b in v { write!(f, "{b:02x}")?; } + write!(f, ")")?; Ok(()) } } - -impl core::fmt::Debug for AssetCode4 { +impl core::fmt::Display for AssetCode4 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; - write!(f, "AssetCode4(")?; for b in v { write!(f, "{b:02x}")?; } - write!(f, ")")?; Ok(()) } } @@ -10044,24 +10052,23 @@ impl AsRef<[u8]> for AssetCode4 { )] pub struct AssetCode12(pub [u8; 12]); -impl core::fmt::Display for AssetCode12 { +impl core::fmt::Debug for AssetCode12 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; + write!(f, "AssetCode12(")?; for b in v { write!(f, "{b:02x}")?; } + write!(f, ")")?; Ok(()) } } - -impl core::fmt::Debug for AssetCode12 { +impl core::fmt::Display for AssetCode12 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; - write!(f, "AssetCode12(")?; for b in v { write!(f, "{b:02x}")?; } - write!(f, ")")?; Ok(()) } } @@ -11137,12 +11144,12 @@ pub const MAX_SIGNERS: u64 = 20; // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct SponsorshipDescriptor(pub Option); impl From for Option { @@ -16081,12 +16088,13 @@ impl WriteXdr for EnvelopeType { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct UpgradeType(pub BytesM<128>); impl From for BytesM<128> { @@ -19266,12 +19274,13 @@ impl WriteXdr for LedgerEntryChange { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct LedgerEntryChanges(pub VecM); impl From for VecM { @@ -21732,12 +21741,13 @@ impl WriteXdr for SignedSurveyRequestMessage { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct EncryptedBody(pub BytesM<64000>); impl From for BytesM<64000> { @@ -22029,12 +22039,13 @@ impl WriteXdr for PeerStats { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct PeerStatList(pub VecM); impl From for VecM { @@ -22357,12 +22368,13 @@ pub const TX_ADVERT_VECTOR_MAX_SIZE: u64 = 1000; // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct TxAdvertVector(pub VecM); impl From for VecM { @@ -22504,12 +22516,13 @@ pub const TX_DEMAND_VECTOR_MAX_SIZE: u64 = 1000; // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct TxDemandVector(pub VecM); impl From for VecM { @@ -23199,8 +23212,7 @@ impl WriteXdr for LiquidityPoolParameters { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] pub struct MuxedAccountMed25519 { pub id: u64, @@ -23249,8 +23261,7 @@ impl WriteXdr for MuxedAccountMed25519 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] #[allow(clippy::large_enum_variant)] pub enum MuxedAccount { @@ -39312,24 +39323,23 @@ impl WriteXdr for TransactionResult { )] pub struct Hash(pub [u8; 32]); -impl core::fmt::Display for Hash { +impl core::fmt::Debug for Hash { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; + write!(f, "Hash(")?; for b in v { write!(f, "{b:02x}")?; } + write!(f, ")")?; Ok(()) } } - -impl core::fmt::Debug for Hash { +impl core::fmt::Display for Hash { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; - write!(f, "Hash(")?; for b in v { write!(f, "{b:02x}")?; } - write!(f, ")")?; Ok(()) } } @@ -39429,24 +39439,23 @@ impl AsRef<[u8]> for Hash { )] pub struct Uint256(pub [u8; 32]); -impl core::fmt::Display for Uint256 { +impl core::fmt::Debug for Uint256 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; + write!(f, "Uint256(")?; for b in v { write!(f, "{b:02x}")?; } + write!(f, ")")?; Ok(()) } } - -impl core::fmt::Debug for Uint256 { +impl core::fmt::Display for Uint256 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; - write!(f, "Uint256(")?; for b in v { write!(f, "{b:02x}")?; } - write!(f, ")")?; Ok(()) } } @@ -39564,12 +39573,12 @@ pub type Int64 = i64; // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct TimePoint(pub u64); impl From for u64 { @@ -39617,12 +39626,12 @@ impl WriteXdr for TimePoint { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct Duration(pub u64); impl From for u64 { @@ -40120,8 +40129,7 @@ impl WriteXdr for SignerKeyType { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] #[allow(clippy::large_enum_variant)] pub enum PublicKey { @@ -40221,8 +40229,7 @@ impl WriteXdr for PublicKey { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] pub struct SignerKeyEd25519SignedPayload { pub ed25519: Uint256, @@ -40279,8 +40286,7 @@ impl WriteXdr for SignerKeyEd25519SignedPayload { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] #[allow(clippy::large_enum_variant)] pub enum SignerKey { @@ -40393,12 +40399,13 @@ impl WriteXdr for SignerKey { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct Signature(pub BytesM<64>); impl From for BytesM<64> { @@ -40501,24 +40508,23 @@ impl AsRef<[u8]> for Signature { )] pub struct SignatureHint(pub [u8; 4]); -impl core::fmt::Display for SignatureHint { +impl core::fmt::Debug for SignatureHint { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; + write!(f, "SignatureHint(")?; for b in v { write!(f, "{b:02x}")?; } + write!(f, ")")?; Ok(()) } } - -impl core::fmt::Debug for SignatureHint { +impl core::fmt::Display for SignatureHint { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; - write!(f, "SignatureHint(")?; for b in v { write!(f, "{b:02x}")?; } - write!(f, ")")?; Ok(()) } } @@ -40612,12 +40618,11 @@ impl AsRef<[u8]> for SignatureHint { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[derive(Debug)] pub struct NodeId(pub PublicKey); impl From for PublicKey { @@ -40665,12 +40670,11 @@ impl WriteXdr for NodeId { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[derive(Debug)] pub struct AccountId(pub PublicKey); impl From for PublicKey { diff --git a/src/curr/mod.rs b/src/curr/mod.rs index a36c0299..8ab0180c 100644 --- a/src/curr/mod.rs +++ b/src/curr/mod.rs @@ -1,6 +1,8 @@ mod generated; pub use generated::*; +mod str; + mod scval_conversions; pub use scval_conversions::*; diff --git a/src/curr/str.rs b/src/curr/str.rs new file mode 100644 index 00000000..55c4a5be --- /dev/null +++ b/src/curr/str.rs @@ -0,0 +1,222 @@ +//# Custom string representations of the following types, also used for JSON +//# formatting. +//# +//# The types that has impls in this file are given to the xdrgen +//# --rust-types-custom-str-impl cli option, so that xdrgen does not generate +//# FromStr and Display impls for them. +//# +//# ## Strkey Types (SEP-23) +//# - PublicKey +//# - AccountId +//# - MuxedAccount +//# - MuxedAccountMed25519 +//# - SignerKey +//# - SignerKeyEd25519SignedPayload +//# - NodeId +#![cfg(feature = "std")] + +use super::{ + AccountId, Error, MuxedAccount, MuxedAccountMed25519, NodeId, PublicKey, SignerKey, + SignerKeyEd25519SignedPayload, Uint256, +}; + +impl From for Error { + fn from(_: stellar_strkey::DecodeError) -> Self { + Error::Invalid + } +} + +impl core::fmt::Display for PublicKey { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + PublicKey::PublicKeyTypeEd25519(Uint256(k)) => { + let k = stellar_strkey::ed25519::PublicKey::from_payload(k) + .map_err(|_| std::fmt::Error)?; + let s = k.to_string(); + f.write_str(&s)?; + } + } + Ok(()) + } +} + +impl core::str::FromStr for PublicKey { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + let stellar_strkey::ed25519::PublicKey(k) = + stellar_strkey::ed25519::PublicKey::from_str(s)?; + Ok(PublicKey::PublicKeyTypeEd25519(Uint256(k))) + } +} + +impl core::fmt::Display for AccountId { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + self.0.fmt(f) + } +} + +impl core::str::FromStr for AccountId { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + Ok(AccountId(PublicKey::from_str(s)?)) + } +} + +impl core::fmt::Display for MuxedAccountMed25519 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let MuxedAccountMed25519 { + ed25519: Uint256(ed25519), + id, + } = self; + let k = stellar_strkey::ed25519::MuxedAccount { + ed25519: *ed25519, + id: *id, + }; + let s = k.to_string(); + f.write_str(&s)?; + Ok(()) + } +} + +impl core::str::FromStr for MuxedAccountMed25519 { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + let stellar_strkey::ed25519::MuxedAccount { ed25519, id } = + stellar_strkey::ed25519::MuxedAccount::from_str(s)?; + Ok(MuxedAccountMed25519 { + ed25519: Uint256(ed25519), + id, + }) + } +} + +impl core::str::FromStr for MuxedAccount { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + let strkey = stellar_strkey::Strkey::from_str(s)?; + match strkey { + stellar_strkey::Strkey::PublicKeyEd25519(stellar_strkey::ed25519::PublicKey(k)) => { + Ok(MuxedAccount::Ed25519(Uint256(k))) + } + stellar_strkey::Strkey::MuxedAccountEd25519( + stellar_strkey::ed25519::MuxedAccount { ed25519, id }, + ) => Ok(MuxedAccount::MuxedEd25519(MuxedAccountMed25519 { + ed25519: Uint256(ed25519), + id, + })), + stellar_strkey::Strkey::PrivateKeyEd25519(_) + | stellar_strkey::Strkey::PreAuthTx(_) + | stellar_strkey::Strkey::HashX(_) + | stellar_strkey::Strkey::SignedPayloadEd25519(_) + | stellar_strkey::Strkey::Contract(_) => Err(Error::Invalid), + } + } +} + +impl core::fmt::Display for MuxedAccount { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + MuxedAccount::Ed25519(Uint256(k)) => { + let k = stellar_strkey::ed25519::PublicKey(*k); + let s = k.to_string(); + f.write_str(&s)?; + } + MuxedAccount::MuxedEd25519(m) => m.fmt(f)?, + } + Ok(()) + } +} + +impl core::fmt::Display for NodeId { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + self.0.fmt(f) + } +} + +impl core::str::FromStr for NodeId { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + Ok(NodeId(PublicKey::from_str(s)?)) + } +} + +impl core::fmt::Display for SignerKeyEd25519SignedPayload { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let SignerKeyEd25519SignedPayload { + ed25519: Uint256(ed25519), + payload, + } = self; + let k = stellar_strkey::ed25519::SignedPayload { + ed25519: *ed25519, + payload: payload.into(), + }; + let s = k.to_string(); + f.write_str(&s)?; + Ok(()) + } +} + +impl core::str::FromStr for SignerKeyEd25519SignedPayload { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + let stellar_strkey::ed25519::SignedPayload { ed25519, payload } = + stellar_strkey::ed25519::SignedPayload::from_str(s)?; + Ok(SignerKeyEd25519SignedPayload { + ed25519: Uint256(ed25519), + payload: payload.try_into()?, + }) + } +} + +impl core::str::FromStr for SignerKey { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + let strkey = stellar_strkey::Strkey::from_str(s)?; + match strkey { + stellar_strkey::Strkey::PublicKeyEd25519(stellar_strkey::ed25519::PublicKey(k)) => { + Ok(SignerKey::Ed25519(Uint256(k))) + } + stellar_strkey::Strkey::PreAuthTx(stellar_strkey::PreAuthTx(h)) => { + Ok(SignerKey::PreAuthTx(Uint256(h))) + } + stellar_strkey::Strkey::HashX(stellar_strkey::HashX(h)) => { + Ok(SignerKey::HashX(Uint256(h))) + } + stellar_strkey::Strkey::SignedPayloadEd25519( + stellar_strkey::ed25519::SignedPayload { ed25519, payload }, + ) => Ok(SignerKey::Ed25519SignedPayload( + SignerKeyEd25519SignedPayload { + ed25519: Uint256(ed25519), + payload: payload.try_into()?, + }, + )), + stellar_strkey::Strkey::PrivateKeyEd25519(_) + | stellar_strkey::Strkey::Contract(_) + | stellar_strkey::Strkey::MuxedAccountEd25519(_) => Err(Error::Invalid), + } + } +} + +impl core::fmt::Display for SignerKey { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + SignerKey::Ed25519(Uint256(k)) => { + let k = stellar_strkey::ed25519::PublicKey(*k); + let s = k.to_string(); + f.write_str(&s)?; + } + SignerKey::PreAuthTx(Uint256(h)) => { + let k = stellar_strkey::PreAuthTx(*h); + let s = k.to_string(); + f.write_str(&s)?; + } + SignerKey::HashX(Uint256(h)) => { + let k = stellar_strkey::HashX(*h); + let s = k.to_string(); + f.write_str(&s)?; + } + SignerKey::Ed25519SignedPayload(p) => p.fmt(f)?, + } + Ok(()) + } +} diff --git a/src/next/generated.rs b/src/next/generated.rs index 998abefc..107c18f8 100644 --- a/src/next/generated.rs +++ b/src/next/generated.rs @@ -2360,12 +2360,13 @@ mod test { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct Value(pub BytesM); impl From for BytesM { @@ -3929,12 +3930,13 @@ pub const CONTRACT_COST_COUNT_LIMIT: u64 = 1024; // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct ContractCostParams(pub VecM); impl From for VecM { @@ -8104,12 +8106,13 @@ pub const SCSYMBOL_LIMIT: u64 = 32; // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct ScVec(pub VecM); impl From for VecM { @@ -8206,12 +8209,13 @@ impl AsRef<[ScVal]> for ScVec { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct ScMap(pub VecM); impl From for VecM { @@ -8308,12 +8312,13 @@ impl AsRef<[ScMapEntry]> for ScMap { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct ScBytes(pub BytesM); impl From for BytesM { @@ -8410,12 +8415,13 @@ impl AsRef<[u8]> for ScBytes { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct ScString(pub StringM); impl From for StringM { @@ -8512,12 +8518,13 @@ impl AsRef<[u8]> for ScString { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct ScSymbol(pub StringM<32>); impl From for StringM<32> { @@ -9398,24 +9405,23 @@ impl WriteXdr for PersistedScpState { )] pub struct Thresholds(pub [u8; 4]); -impl core::fmt::Display for Thresholds { +impl core::fmt::Debug for Thresholds { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; + write!(f, "Thresholds(")?; for b in v { write!(f, "{b:02x}")?; } + write!(f, ")")?; Ok(()) } } - -impl core::fmt::Debug for Thresholds { +impl core::fmt::Display for Thresholds { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; - write!(f, "Thresholds(")?; for b in v { write!(f, "{b:02x}")?; } - write!(f, ")")?; Ok(()) } } @@ -9509,12 +9515,13 @@ impl AsRef<[u8]> for Thresholds { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct String32(pub StringM<32>); impl From for StringM<32> { @@ -9611,12 +9618,13 @@ impl AsRef<[u8]> for String32 { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct String64(pub StringM<64>); impl From for StringM<64> { @@ -9713,12 +9721,12 @@ impl AsRef<[u8]> for String64 { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct SequenceNumber(pub i64); impl From for i64 { @@ -9766,12 +9774,13 @@ impl WriteXdr for SequenceNumber { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct DataValue(pub BytesM<64>); impl From for BytesM<64> { @@ -9868,12 +9877,12 @@ impl AsRef<[u8]> for DataValue { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct PoolId(pub Hash); impl From for Hash { @@ -9927,24 +9936,23 @@ impl WriteXdr for PoolId { )] pub struct AssetCode4(pub [u8; 4]); -impl core::fmt::Display for AssetCode4 { +impl core::fmt::Debug for AssetCode4 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; + write!(f, "AssetCode4(")?; for b in v { write!(f, "{b:02x}")?; } + write!(f, ")")?; Ok(()) } } - -impl core::fmt::Debug for AssetCode4 { +impl core::fmt::Display for AssetCode4 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; - write!(f, "AssetCode4(")?; for b in v { write!(f, "{b:02x}")?; } - write!(f, ")")?; Ok(()) } } @@ -10044,24 +10052,23 @@ impl AsRef<[u8]> for AssetCode4 { )] pub struct AssetCode12(pub [u8; 12]); -impl core::fmt::Display for AssetCode12 { +impl core::fmt::Debug for AssetCode12 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; + write!(f, "AssetCode12(")?; for b in v { write!(f, "{b:02x}")?; } + write!(f, ")")?; Ok(()) } } - -impl core::fmt::Debug for AssetCode12 { +impl core::fmt::Display for AssetCode12 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; - write!(f, "AssetCode12(")?; for b in v { write!(f, "{b:02x}")?; } - write!(f, ")")?; Ok(()) } } @@ -11137,12 +11144,12 @@ pub const MAX_SIGNERS: u64 = 20; // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct SponsorshipDescriptor(pub Option); impl From for Option { @@ -16081,12 +16088,13 @@ impl WriteXdr for EnvelopeType { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct UpgradeType(pub BytesM<128>); impl From for BytesM<128> { @@ -19266,12 +19274,13 @@ impl WriteXdr for LedgerEntryChange { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct LedgerEntryChanges(pub VecM); impl From for VecM { @@ -21732,12 +21741,13 @@ impl WriteXdr for SignedSurveyRequestMessage { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct EncryptedBody(pub BytesM<64000>); impl From for BytesM<64000> { @@ -22029,12 +22039,13 @@ impl WriteXdr for PeerStats { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct PeerStatList(pub VecM); impl From for VecM { @@ -22357,12 +22368,13 @@ pub const TX_ADVERT_VECTOR_MAX_SIZE: u64 = 1000; // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct TxAdvertVector(pub VecM); impl From for VecM { @@ -22504,12 +22516,13 @@ pub const TX_DEMAND_VECTOR_MAX_SIZE: u64 = 1000; // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct TxDemandVector(pub VecM); impl From for VecM { @@ -39312,24 +39325,23 @@ impl WriteXdr for TransactionResult { )] pub struct Hash(pub [u8; 32]); -impl core::fmt::Display for Hash { +impl core::fmt::Debug for Hash { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; + write!(f, "Hash(")?; for b in v { write!(f, "{b:02x}")?; } + write!(f, ")")?; Ok(()) } } - -impl core::fmt::Debug for Hash { +impl core::fmt::Display for Hash { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; - write!(f, "Hash(")?; for b in v { write!(f, "{b:02x}")?; } - write!(f, ")")?; Ok(()) } } @@ -39429,24 +39441,23 @@ impl AsRef<[u8]> for Hash { )] pub struct Uint256(pub [u8; 32]); -impl core::fmt::Display for Uint256 { +impl core::fmt::Debug for Uint256 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; + write!(f, "Uint256(")?; for b in v { write!(f, "{b:02x}")?; } + write!(f, ")")?; Ok(()) } } - -impl core::fmt::Debug for Uint256 { +impl core::fmt::Display for Uint256 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; - write!(f, "Uint256(")?; for b in v { write!(f, "{b:02x}")?; } - write!(f, ")")?; Ok(()) } } @@ -39564,12 +39575,12 @@ pub type Int64 = i64; // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct TimePoint(pub u64); impl From for u64 { @@ -39617,12 +39628,12 @@ impl WriteXdr for TimePoint { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct Duration(pub u64); impl From for u64 { @@ -40393,12 +40404,13 @@ impl WriteXdr for SignerKey { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Default, Debug)] +#[derive(Default)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct Signature(pub BytesM<64>); impl From for BytesM<64> { @@ -40501,24 +40513,23 @@ impl AsRef<[u8]> for Signature { )] pub struct SignatureHint(pub [u8; 4]); -impl core::fmt::Display for SignatureHint { +impl core::fmt::Debug for SignatureHint { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; + write!(f, "SignatureHint(")?; for b in v { write!(f, "{b:02x}")?; } + write!(f, ")")?; Ok(()) } } - -impl core::fmt::Debug for SignatureHint { +impl core::fmt::Display for SignatureHint { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let v = &self.0; - write!(f, "SignatureHint(")?; for b in v { write!(f, "{b:02x}")?; } - write!(f, ")")?; Ok(()) } } @@ -40612,12 +40623,12 @@ impl AsRef<[u8]> for SignatureHint { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct NodeId(pub PublicKey); impl From for PublicKey { @@ -40665,12 +40676,12 @@ impl WriteXdr for NodeId { // #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[derive(Debug)] #[cfg_attr( all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[derive(Debug)] pub struct AccountId(pub PublicKey); impl From for PublicKey { diff --git a/tests/tx_serde.rs b/tests/serde.rs similarity index 75% rename from tests/tx_serde.rs rename to tests/serde.rs index fd17dabf..55d7cb03 100644 --- a/tests/tx_serde.rs +++ b/tests/serde.rs @@ -11,6 +11,12 @@ use stellar_xdr::next as stellar_xdr; use stellar_xdr::{BytesM, Hash, StringM, VecM}; +#[cfg(feature = "curr")] +use stellar_xdr::AccountId; + +#[cfg(feature = "curr")] +use std::str::FromStr; + #[test] fn test_serde_ser() -> Result<(), Box> { assert_eq!( @@ -31,6 +37,13 @@ fn test_serde_ser() -> Result<(), Box> { )?)?, "\"3031323334353637383930313233343536373839303133343536373839303132\"" ); + #[cfg(feature = "curr")] + assert_eq!( + serde_json::to_string(&AccountId::from_str( + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF" + )?)?, + "\"GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF\"" + ); Ok(()) } @@ -54,5 +67,11 @@ fn test_serde_der() -> Result<(), Box> { <_ as TryInto>::try_into(*b"01234567890123456789013456789012")?, ); + #[cfg(feature = "curr")] + assert_eq!( + AccountId::from_str("GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF")?, + serde_json::from_str("\"GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF\"")?, + ); + Ok(()) } diff --git a/tests/serde_tx.rs b/tests/serde_tx.rs new file mode 100644 index 00000000..9ec4904c --- /dev/null +++ b/tests/serde_tx.rs @@ -0,0 +1,88 @@ +#![cfg(feature = "curr")] +#![cfg(all(feature = "std", feature = "serde"))] + +use stellar_xdr::curr as stellar_xdr; + +use stellar_xdr::{ + AccountId, AlphaNum4, AssetCode4, ChangeTrustAsset, ChangeTrustOp, Memo, MuxedAccount, + Operation, OperationBody, Preconditions, SequenceNumber, Transaction, TransactionEnvelope, + TransactionExt, TransactionV1Envelope, Uint256, +}; + +#[cfg(feature = "curr")] +#[test] +fn test_serde_tx() -> Result<(), Box> { + let te = TransactionEnvelope::Tx(TransactionV1Envelope { + tx: Transaction { + source_account: MuxedAccount::Ed25519(Uint256([ + 0x3c, 0xb3, 0x61, 0xab, 0x62, 0x4b, 0x10, 0x70, 0x4c, 0x6c, 0xcf, 0x4f, 0xdb, 0x1e, + 0x40, 0x79, 0xd2, 0x3d, 0x68, 0xec, 0x2c, 0xd3, 0x22, 0xc2, 0x28, 0x34, 0xc4, 0x1a, + 0xe1, 0xe6, 0x4b, 0xd3, + ])), + fee: 0, + seq_num: SequenceNumber(1), + cond: Preconditions::None, + memo: Memo::Text("Stellar".as_bytes().try_into()?), + operations: [Operation { + source_account: Some(MuxedAccount::Ed25519(Uint256([ + 0x9b, 0x9f, 0xfa, 0xba, 0xcf, 0x46, 0x65, 0xb3, 0x57, 0x29, 0x76, 0xfb, 0x85, + 0x09, 0x79, 0xcb, 0xc7, 0x6b, 0x9d, 0x67, 0x9c, 0x6b, 0xca, 0xeb, 0xd5, 0x9b, + 0xbf, 0xb3, 0x43, 0xe8, 0xe9, 0x46, + ]))), + body: OperationBody::ChangeTrust(ChangeTrustOp { + line: ChangeTrustAsset::CreditAlphanum4(AlphaNum4 { + asset_code: AssetCode4(*b"ABCD"), + issuer: AccountId(stellar_xdr::PublicKey::PublicKeyTypeEd25519(Uint256([ + 0x43, 0xd0, 0x9f, 0x49, 0x2a, 0x2a, 0xe3, 0xaa, 0x0a, 0xed, 0x8e, 0xce, + 0xdc, 0xb2, 0x26, 0xa4, 0xf7, 0x50, 0xa9, 0x0e, 0xcb, 0x4e, 0x09, 0xf9, + 0xac, 0x76, 0x4a, 0x55, 0x37, 0xca, 0xd8, 0x77, + ]))), + }), + limit: i64::MAX, + }), + }] + .to_vec() + .try_into()?, + ext: TransactionExt::V0, + }, + signatures: [].try_into()?, + }); + let s = serde_json::to_string_pretty(&te)?; + println!("{s}"); + assert_eq!( + s, + r#"{ + "tx": { + "tx": { + "source_account": "GA6LGYNLMJFRA4CMNTHU7WY6IB45EPLI5QWNGIWCFA2MIGXB4ZF5GQGY", + "fee": 0, + "seq_num": 1, + "cond": "none", + "memo": { + "text": "Stellar" + }, + "operations": [ + { + "source_account": "GCNZ76V2Z5DGLM2XFF3PXBIJPHF4O245M6OGXSXL2WN37M2D5DUUNSOO", + "body": { + "change_trust": { + "line": { + "credit_alphanum4": { + "asset_code": "41424344", + "issuer": "GBB5BH2JFIVOHKQK5WHM5XFSE2SPOUFJB3FU4CPZVR3EUVJXZLMHOLOM" + } + }, + "limit": 9223372036854775807 + } + } + } + ], + "ext": "v0" + }, + "signatures": [] + } +}"#, + ); + + Ok(()) +} diff --git a/tests/str.rs b/tests/str.rs new file mode 100644 index 00000000..d23efd92 --- /dev/null +++ b/tests/str.rs @@ -0,0 +1,336 @@ +#![cfg(feature = "curr")] +#![cfg(feature = "std")] + +use stellar_xdr::curr as stellar_xdr; + +use stellar_xdr::{ + AccountId, MuxedAccount, MuxedAccountMed25519, NodeId, PublicKey, SignerKey, + SignerKeyEd25519SignedPayload, Uint256, +}; + +use std::str::FromStr; + +#[test] +fn public_key_from_str() { + let v = PublicKey::from_str("GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF"); + assert_eq!(v, Ok(PublicKey::PublicKeyTypeEd25519(Uint256([0; 32])))); +} + +#[test] +fn public_key_to_string() { + let s = PublicKey::PublicKeyTypeEd25519(Uint256([0; 32])).to_string(); + assert_eq!( + s, + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF" + ); +} + +#[test] +fn account_id_from_str() { + let v = AccountId::from_str("GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF"); + assert_eq!( + v, + Ok(AccountId(PublicKey::PublicKeyTypeEd25519(Uint256([0; 32])))) + ); +} + +#[test] +fn account_id_to_string() { + let s = AccountId(PublicKey::PublicKeyTypeEd25519(Uint256([0; 32]))).to_string(); + assert_eq!( + s, + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF" + ); +} + +#[test] +fn muxed_account_med_25519_to_string() { + let s = MuxedAccountMed25519 { + ed25519: Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, + 0x05, 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, + 0xfc, 0x7f, 0xe8, 0x9a, + ]), + id: 9_223_372_036_854_775_808, + } + .to_string(); + assert_eq!( + s, + "MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVAAAAAAAAAAAAAJLK" + ); +} + +#[test] +fn muxed_account_med_25519_from_str() { + let v = MuxedAccountMed25519::from_str( + "MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVAAAAAAAAAAAAAJLK", + ); + assert_eq!( + v, + Ok(MuxedAccountMed25519 { + ed25519: Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, + 0x05, 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, + 0xfc, 0x7f, 0xe8, 0x9a, + ]), + id: 9_223_372_036_854_775_808, + }), + ); +} + +#[test] +fn muxed_account_to_string_with_ed25519() { + let s = MuxedAccount::Ed25519(Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, 0x05, + 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, 0xfc, 0x7f, + 0xe8, 0x9a, + ])) + .to_string(); + assert_eq!( + s, + "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ" + ); +} + +#[test] +fn muxed_account_from_str_with_ed25519() { + let v = MuxedAccount::from_str("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"); + assert_eq!( + v, + Ok(MuxedAccount::Ed25519(Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, + 0x05, 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, + 0xfc, 0x7f, 0xe8, 0x9a, + ]))), + ); +} + +#[test] +fn muxed_account_to_string_with_muxed_ed25519() { + let s = MuxedAccount::MuxedEd25519(MuxedAccountMed25519 { + ed25519: Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, + 0x05, 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, + 0xfc, 0x7f, 0xe8, 0x9a, + ]), + id: 9_223_372_036_854_775_808, + }) + .to_string(); + assert_eq!( + s, + "MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVAAAAAAAAAAAAAJLK" + ); +} + +#[test] +fn muxed_account_from_str_with_muxed_ed25519() { + let v = MuxedAccount::from_str( + "MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVAAAAAAAAAAAAAJLK", + ); + assert_eq!( + v, + Ok(MuxedAccount::MuxedEd25519(MuxedAccountMed25519 { + ed25519: Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, + 0x05, 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, + 0xfc, 0x7f, 0xe8, 0x9a, + ]), + id: 9_223_372_036_854_775_808, + })), + ); +} + +#[test] +fn node_id_from_str() { + let v = NodeId::from_str("GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF"); + assert_eq!( + v, + Ok(NodeId(PublicKey::PublicKeyTypeEd25519(Uint256([0; 32])))) + ); +} + +#[test] +fn node_id_to_string() { + let s = NodeId(PublicKey::PublicKeyTypeEd25519(Uint256([0; 32]))).to_string(); + assert_eq!( + s, + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF" + ); +} + +#[test] +fn signer_key_ed25519_signed_payload_to_string() { + let s = SignerKeyEd25519SignedPayload { + ed25519: Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, + 0x05, 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, + 0xfc, 0x7f, 0xe8, 0x9a, + ]), + payload: [ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, + ] + .try_into() + .unwrap(), + } + .to_string(); + assert_eq!( + s, + "PA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAQACAQDAQCQMBYIBEFAWDANBYHRAEISCMKBKFQXDAMRUGY4DUPB6IBZGM" + ); +} + +#[test] +fn signer_key_ed25519_signed_payload_from_str() { + let v = SignerKeyEd25519SignedPayload::from_str( + "PA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAQACAQDAQCQMBYIBEFAWDANBYHRAEISCMKBKFQXDAMRUGY4DUPB6IBZGM", + ); + assert_eq!( + v, + Ok(SignerKeyEd25519SignedPayload { + ed25519: Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, + 0x05, 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, + 0xfc, 0x7f, 0xe8, 0x9a, + ]), + payload: [ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20 + ] + .try_into() + .unwrap(), + }), + ); +} + +#[test] +fn signer_key_to_string_with_ed25519() { + let s = SignerKey::Ed25519(Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, 0x05, + 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, 0xfc, 0x7f, + 0xe8, 0x9a, + ])) + .to_string(); + assert_eq!( + s, + "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ" + ); +} + +#[test] +fn signer_key_from_str_with_ed25519() { + let v = SignerKey::from_str("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"); + assert_eq!( + v, + Ok(SignerKey::Ed25519(Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, + 0x05, 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, + 0xfc, 0x7f, 0xe8, 0x9a, + ]),)), + ); +} + +#[test] +fn signer_key_to_string_with_pre_auth_tx() { + let s = SignerKey::PreAuthTx(Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, 0x05, + 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, 0xfc, 0x7f, + 0xe8, 0x9a, + ])) + .to_string(); + assert_eq!( + s, + "TA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUPUI" + ); +} + +#[test] +fn signer_key_from_str_with_pre_auth_tx() { + let v = SignerKey::from_str("TA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUPUI"); + assert_eq!( + v, + Ok(SignerKey::PreAuthTx(Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, + 0x05, 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, + 0xfc, 0x7f, 0xe8, 0x9a, + ]),)), + ); +} + +#[test] +fn signer_key_to_string_with_hash_x() { + let s = SignerKey::HashX(Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, 0x05, + 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, 0xfc, 0x7f, + 0xe8, 0x9a, + ])) + .to_string(); + assert_eq!( + s, + "XA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVLRR" + ); +} + +#[test] +fn signer_key_from_str_with_hash_x() { + let v = SignerKey::from_str("XA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVLRR"); + assert_eq!( + v, + Ok(SignerKey::HashX(Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, + 0x05, 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, + 0xfc, 0x7f, 0xe8, 0x9a, + ]),)), + ); +} + +#[test] +fn signer_key_to_string_with_signed_payload_ed25519() { + let s = SignerKey::Ed25519SignedPayload(SignerKeyEd25519SignedPayload { + ed25519: Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, + 0x05, 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, 0x7a, 0x03, + 0xfc, 0x7f, 0xe8, 0x9a, + ]), + payload: [ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, + ] + .try_into() + .unwrap(), + }) + .to_string(); + assert_eq!( + s, + "PA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAQACAQDAQCQMBYIBEFAWDANBYHRAEISCMKBKFQXDAMRUGY4DUPB6IBZGM" + ); +} + +#[test] +fn signer_key_from_str_with_signed_payload_ed25519() { + let v = SignerKey::from_str( + "PA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAQACAQDAQCQMBYIBEFAWDANBYHRAEISCMKBKFQXDAMRUGY4DUPB6IBZGM", + ); + assert_eq!( + v, + Ok(SignerKey::Ed25519SignedPayload( + SignerKeyEd25519SignedPayload { + ed25519: Uint256([ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, 0x71, 0xd0, 0x4c, 0xcc, 0x90, + 0xf7, 0x05, 0x51, 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, 0xfb, 0x0d, + 0x7a, 0x03, 0xfc, 0x7f, 0xe8, 0x9a, + ]), + payload: [ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, + 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 + ] + .try_into() + .unwrap(), + } + )), + ); +}