From 1e673739c14b0ceb5a31b1b12f7c75c83586b027 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Fri, 24 Oct 2025 15:12:02 +0200 Subject: [PATCH 01/18] Updates pyO3 and related so can be supported by Python 3.14 --- Cargo.lock | 55 +++++++++++++++++++++--------------------------------- Cargo.toml | 10 +++++----- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88fb112..32c5055 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,8 +31,6 @@ dependencies = [ "pyo3", "pyo3-log", "pythonize", - "scale-bits 0.4.0", - "scale-decode", "scale-info", "scale-value", "serde_json", @@ -179,9 +177,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "parity-scale-codec" @@ -233,11 +231,10 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.23.3" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e484fd2c8b4cb67ab05a318f1fd6fa8f199fcc30819f08f07d200809dba26c15" +checksum = "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383" dependencies = [ - "cfg-if", "indoc", "libc", "memoffset", @@ -251,19 +248,18 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.23.3" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e0469a84f208e20044b98965e1561028180219e35352a2afaf2b942beff3b" +checksum = "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f" dependencies = [ - "once_cell", "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.23.3" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1547a7f9966f6f1a0f0227564a9945fe36b90da5a93b3933fc3dc03fae372d" +checksum = "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105" dependencies = [ "libc", "pyo3-build-config", @@ -271,9 +267,9 @@ dependencies = [ [[package]] name = "pyo3-log" -version = "0.12.1" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5bb22b77965a7b5394e9aae9897a0607b51df5167561ffc3b02643b4200bc7" +checksum = "d359e20231345f21a3b5b6aea7e73f4dc97e1712ef3bfe2d88997ac6a308d784" dependencies = [ "arc-swap", "log", @@ -282,9 +278,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.23.3" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb6da8ec6fa5cedd1626c886fc8749bdcbb09424a86461eb8cdf096b7c33257" +checksum = "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -294,9 +290,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.23.3" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38a385202ff5a92791168b1136afae5059d3ac118457bb7bc304c197c2d33e7d" +checksum = "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf" dependencies = [ "heck", "proc-macro2", @@ -307,9 +303,9 @@ dependencies = [ [[package]] name = "pythonize" -version = "0.23.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91a6ee7a084f913f98d70cdc3ebec07e852b735ae3059a1500db2661265da9ff" +checksum = "11e06e4cff9be2bbf2bddf28a486ae619172ea57e79787f856572878c62dcfe2" dependencies = [ "pyo3", "serde", @@ -330,15 +326,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "scale-bits" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "036575c29af9b6e4866ffb7fa055dbf623fe7a9cc159b33786de6013a6969d89" -dependencies = [ - "parity-scale-codec", -] - [[package]] name = "scale-bits" version = "0.6.0" @@ -359,7 +346,7 @@ checksum = "e98f3262c250d90e700bb802eb704e1f841e03331c2eb815e46516c4edbf5b27" dependencies = [ "derive_more", "parity-scale-codec", - "scale-bits 0.6.0", + "scale-bits", "scale-type-resolver", "smallvec", ] @@ -372,7 +359,7 @@ checksum = "4ba0b9c48dc0eb20c60b083c29447c0c4617cb7c4a4c9fef72aa5c5bc539e15e" dependencies = [ "derive_more", "parity-scale-codec", - "scale-bits 0.6.0", + "scale-bits", "scale-type-resolver", "smallvec", ] @@ -422,7 +409,7 @@ dependencies = [ "either", "frame-metadata 15.1.0", "parity-scale-codec", - "scale-bits 0.6.0", + "scale-bits", "scale-decode", "scale-encode", "scale-info", @@ -491,9 +478,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.16" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" [[package]] name = "toml_datetime" diff --git a/Cargo.toml b/Cargo.toml index 5a53533..7671347 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ name = "bt_decode" crate-type = ["cdylib"] [dependencies.pyo3] -version = "0.23.3" +version = "0.26.0" features = ["extension-module"] [dependencies.custom_derive] @@ -21,15 +21,15 @@ path = "libs/custom-derive" [dependencies] frame-metadata = { version = "16.0.0", features = [ "current", "decode", "serde_full" ], default-features = false } -scale-decode = { version = "0.13.0", default-features = false } codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = [ "derive", ] } scale-info = { version = "2.11.2", features = [ "serde" ], default-features = false } serde_json = { version = "1.0.127", features = [ "alloc" ], default-features = false } -scale-bits = { version = "0.4.0", default-features = false } scale-value = { version = "0.16.2", default-features = false } -pythonize = "0.23.0" +pythonize = "0.26.0" log = { version = "0.4.25", default-features = false } -pyo3-log = { version = "0.12.1", default-features = false } +pyo3-log = { version = "0.13.1", default-features = false } +blake2 = "0.10" +base58 = "0.2" From feb91ebcc2ff332eb7be3925ba62c28237394b28 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Fri, 24 Oct 2025 16:07:03 +0200 Subject: [PATCH 02/18] Adjustments for pyo3 0.26 --- src/lib.rs | 197 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 135 insertions(+), 62 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1529f0d..d6d4fc3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,21 +2,27 @@ use codec::{Decode, Encode}; use custom_derive::pydecode; use frame_metadata::{RuntimeMetadata, RuntimeMetadataPrefixed}; use log; +use std::ffi::CString; use pyo3::prelude::*; +use pyo3::types::PyAny; // Implements ToPyObject for Compact where T is an unsigned integer. macro_rules! impl_UnsignedCompactIntoPy { - ( $($type:ty),* $(,)? ) => { + ($($type:ty),+) => { $( - impl IntoPy for Compact<$type> { - fn into_py(self, py: Python<'_>) -> PyObject { - let value: $type = self.0.into(); - - value.into_py(py) + impl<'py> IntoPyObject<'py> for Compact<$type> { + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + fn into_pyobject(self, py: Python<'py>) -> Result { + // Compact wraps codec::Compact in .0, extract inner value + let inner_value: $type = self.0.0; + Ok(inner_value.into_pyobject(py)?.into_any()) } } - )* + )+ }; } @@ -32,6 +38,8 @@ mod dyndecoder; mod bt_decode { use std::collections::HashMap; + use base58::ToBase58; + use blake2::{Blake2b512, Digest}; use dyndecoder::{fill_memo_using_well_known_types, get_type_id_from_type_string}; use frame_metadata::v15::RuntimeMetadataV15; use pyo3::types::{PyDict, PyInt, PyList, PyTuple}; @@ -44,6 +52,25 @@ mod bt_decode { use super::*; + fn account_id_to_ss58(account_id: [u8; 32], ss58_prefix: u16) -> String { + let mut data = Vec::with_capacity(35); + match ss58_prefix { + 0..=63 => data.push(ss58_prefix as u8), + 64..=16383 => { + data.push(((ss58_prefix & 0b0011_1111) | 0b0100_0000) as u8); + data.push((ss58_prefix >> 6) as u8); + } + _ => panic!("Invalid SS58 prefix"), + } + data.extend(account_id); + let checksum = Blake2b512::new() + .chain_update(b"SS58PRE") + .chain_update(&data) + .finalize(); + data.extend_from_slice(&checksum[..2]); + data.to_base58() + } + #[pyclass(name = "AxonInfo", get_all)] #[derive(Clone, Encode, Decode)] struct AxonInfo { @@ -319,12 +346,6 @@ mod bt_decode { serde_json::to_string(&self.metadata).unwrap() } - fn encode_to_metadata_option(&self) -> Vec { - let as_prefixed = RuntimeMetadataPrefixed::from(self.metadata.clone()); - let as_option = Some(as_prefixed.encode()); - as_option.encode() - } - #[staticmethod] fn decode_from_metadata_option(encoded_metadata_v15: &[u8]) -> Self { let option_vec = Option::>::decode(&mut &encoded_metadata_v15[..]) @@ -375,62 +396,117 @@ mod bt_decode { } } - fn composite_to_py_object(py: Python, value: Composite) -> PyResult> { + fn composite_to_py_object( + py: Python, + value: Composite, + legacy_account_id: bool, + ) -> PyResult> { match value { Composite::Named(inner_) => { - let dict = PyDict::new_bound(py); + let dict = PyDict::new(py); for (key, val) in inner_.iter() { - let val_py = value_to_pyobject(py, val.clone())?; + let val_py = value_to_pyobject(py, val.clone(), legacy_account_id)?; dict.set_item(key, val_py)?; } - - Ok(dict.to_object(py)) + Ok(dict.into_pyobject(py)?.into_any().unbind()) } Composite::Unnamed(inner_) => { - let tuple = PyTuple::new_bound( - py, - inner_ - .iter() - .map(|val| value_to_pyobject(py, val.clone())) - .collect::>>>()?, - ); - - Ok(tuple.to_object(py)) + let items: Vec> = inner_ + .iter() + .map(|val| value_to_pyobject(py, val.clone(), legacy_account_id)) + .collect::>>>()?; + if !legacy_account_id && inner_.len() == 1 && inner_[0].context == 1 { + // AccountIds are the only ones with context of 1, this will cause them to not be placed in a tuple + return Ok(items[0].clone_ref(py)); + } + let tuple = PyTuple::new(py, items); + Ok(tuple? + .get_item(0) + .expect("Failed to get item from tuple") + .unbind()) } } } - fn value_to_pyobject(py: Python, value: Value) -> PyResult> { + fn value_to_pyobject( + py: Python, + value: Value, + legacy_account_id: bool, + ) -> PyResult> { match value.value { ValueDef::::Primitive(inner) => { let value = match inner { - Primitive::U128(value) => value.to_object(py), - Primitive::U256(value) => value.to_object(py), - Primitive::I128(value) => value.to_object(py), - Primitive::I256(value) => value.to_object(py), - Primitive::Bool(value) => value.to_object(py), - Primitive::Char(value) => value.to_object(py), - Primitive::String(value) => value.to_object(py), + Primitive::U128(value) => value.into_pyobject(py)?.into_any().unbind(), + Primitive::U256(value) => value.into_pyobject(py)?.into_any().unbind(), + Primitive::I128(value) => value.into_pyobject(py)?.into_any().unbind(), + Primitive::I256(value) => value.into_pyobject(py)?.into_any().unbind(), + Primitive::Bool(value) => { + let bound = value.into_pyobject(py)?; + Bound::clone(&bound).into_any().unbind() + } + Primitive::Char(value) => value.into_pyobject(py)?.into_any().unbind(), + Primitive::String(value) => value.into_pyobject(py)?.into_any().unbind(), }; Ok(value) } ValueDef::::BitSequence(inner) => { - let value = inner.to_vec().to_object(py); + let value = inner.to_vec().into_pyobject(py)?.into_any().unbind(); Ok(value) } - ValueDef::::Composite(inner) => { - let value = composite_to_py_object(py, inner)?; + ValueDef::::Composite(composite) => { + if legacy_account_id { + let value = composite_to_py_object(py, composite, legacy_account_id)?; + return Ok(value); + } else { + match &composite { + Composite::Unnamed(ref inner) if inner.len() == 32 => { + let mut account_id_bytes: Vec = Vec::with_capacity(32); + + for val in inner.iter() { + match val.value { + ValueDef::::Primitive(Primitive::U128(byte)) => { + account_id_bytes.push(byte as u8); + } + _ => { + let value = composite_to_py_object( + py, + composite, + legacy_account_id, + )?; + return Ok(value); + } + } + } - Ok(value) + let account_id_array: [u8; 32] = + account_id_bytes.try_into().map_err(|_| { + PyErr::new::( + "Invalid AccountId length", + ) + })?; + + let ss58_address = account_id_to_ss58(account_id_array, 42); + Ok(ss58_address.as_str().into_pyobject(py)?.into_any().unbind()) + } + _ => { + let value = composite_to_py_object(py, composite, legacy_account_id)?; + Ok(value) + } + } + } } ValueDef::::Variant(inner) => { if inner.name == "None" || inner.name == "Some" { match inner.name.as_str() { "None" => Ok(py.None()), "Some" => { - let some = composite_to_py_object(py, inner.values.clone())?; + let some = composite_to_py_object( + py, + inner.values.clone(), + legacy_account_id, + )?; if inner.values.len() == 1 { let tuple = some .downcast_bound::(py) @@ -438,9 +514,9 @@ mod bt_decode { Ok(tuple .get_item(0) .expect("Failed to get item from tuple") - .to_object(py)) + .unbind()) } else { - Ok(some.to_object(py)) + Ok(some.into_pyobject(py)?.into_any().unbind()) } } _ => Err(PyErr::new::(format!( @@ -449,28 +525,25 @@ mod bt_decode { ))), } } else { - let value = PyDict::new_bound(py); + let value = PyDict::new(py); value.set_item( inner.name.clone(), - composite_to_py_object(py, inner.values)?, + composite_to_py_object(py, inner.values, legacy_account_id)?, )?; - Ok(value.to_object(py)) + Ok(value.into_pyobject(py)?.into_any().unbind()) } } } } fn py_isinstance(py: Python, value: &Py, type_name: &str) -> PyResult { - let locals = PyDict::new_bound(py); + let locals = PyDict::new(py); locals.set_item("value", value)?; - py.run_bound( - &format!("ret = isinstance(value, {})", type_name), - None, - Some(&locals), - ) - .map_err(|e| { + let code = CString::new(format!("ret = isinstance(value, {})", type_name)) + .expect("CString conversion failed"); + py.run(&code, None, Some(&locals)).map_err(|e| { PyErr::new::(format!( "Error checking isinstance of: {}: {:?}", type_name, e @@ -483,11 +556,10 @@ mod bt_decode { } fn py_is_positive(py: Python, value: &Py) -> PyResult { - let locals = PyDict::new_bound(py); + let locals = PyDict::new(py); locals.set_item("value", value)?; - py.run_bound("ret = value >= 0", None, Some(&locals)) - .unwrap(); + py.run(c"ret = value >= 0", None, Some(&locals))?; let ret = locals.get_item("ret").unwrap().unwrap(); let result = ret.extract::()?; @@ -495,11 +567,10 @@ mod bt_decode { } fn py_has_dict_method(py: Python, value: &Py) -> PyResult { - let locals = PyDict::new_bound(py); + let locals = PyDict::new(py); locals.set_item("value", value)?; - py.run_bound("ret = hasattr(value, \'__dict__\')", None, Some(&locals)) - .unwrap(); + py.run(c"ret = hasattr(value, '__dict__')", None, Some(&locals))?; let ret = locals.get_item("ret").unwrap().unwrap(); let result = ret.extract::()?; @@ -1036,12 +1107,13 @@ mod bt_decode { pyobject_to_value_no_option_check(py, to_encode, ty, type_id, portable_registry) } - #[pyfunction(name = "decode")] + #[pyfunction(name = "decode", signature = (type_string, portable_registry, encoded, legacy_account_id=true))] fn py_decode( py: Python, type_string: &str, portable_registry: &PyPortableRegistry, encoded: &[u8], + legacy_account_id: bool, ) -> PyResult> { // Create a memoization table for the type string to type id conversion let mut memo = HashMap::::new(); @@ -1063,15 +1135,16 @@ mod bt_decode { )) })?; - value_to_pyobject(py, decoded) + value_to_pyobject(py, decoded, legacy_account_id) } - #[pyfunction(name = "decode_list")] + #[pyfunction(name = "decode_list", signature = (list_type_strings, portable_registry, list_encoded, legacy_account_id=true))] fn py_decode_list( py: Python, list_type_strings: Vec, portable_registry: &PyPortableRegistry, list_encoded: Vec>, + legacy_account_id: bool, ) -> PyResult>> { // Create a memoization table for the type string to type id conversion let mut memo = HashMap::::new(); @@ -1099,7 +1172,7 @@ mod bt_decode { )) })?; - decoded_list.push(value_to_pyobject(py, decoded)?); + decoded_list.push(value_to_pyobject(py, decoded, legacy_account_id)?); } Ok(decoded_list) From e80544ac479e0aff92116a5902aa2bd44f93d00a Mon Sep 17 00:00:00 2001 From: bdhimes Date: Fri, 24 Oct 2025 16:09:30 +0200 Subject: [PATCH 03/18] Loosens requirements for toml py pkg --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cd4ed08..a3904a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ readme = "README.md" license = {file = "LICENSE"} keywords = ["substrate", "scale", "codec", "bittensor"] -dependencies = ["toml==0.10.0"] +dependencies = ["toml>=0.10.0"] requires-python = ">= 3.9" authors = [ From 8e8934498594debd2e00593196d3c2b164613c42 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Fri, 24 Oct 2025 16:27:47 +0200 Subject: [PATCH 04/18] Adds compatibility for windows build --- Cargo.lock | 32 ++++++++++++++++++++++++++++++++ Cargo.toml | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 32c5055..0d56e89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,6 +42,16 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +[[package]] +name = "cc" +version = "1.2.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" +dependencies = [ + "find-msvc-tools", + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -80,6 +90,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "find-msvc-tools" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" + [[package]] name = "frame-metadata" version = "15.1.0" @@ -252,6 +268,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f" dependencies = [ + "python3-dll-a", "target-lexicon", ] @@ -301,6 +318,15 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "python3-dll-a" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d381ef313ae70b4da5f95f8a4de773c6aa5cd28f73adec4b4a31df70b66780d8" +dependencies = [ + "cc", +] + [[package]] name = "pythonize" version = "0.26.0" @@ -448,6 +474,12 @@ dependencies = [ "serde", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "smallvec" version = "1.13.2" diff --git a/Cargo.toml b/Cargo.toml index 7671347..f18ef4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ crate-type = ["cdylib"] [dependencies.pyo3] version = "0.26.0" -features = ["extension-module"] +features = ["extension-module", "generate-import-lib"] [dependencies.custom_derive] path = "libs/custom-derive" From 26f9f1b19721c731342623d565e0f3770cca323e Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Mon, 27 Oct 2025 18:22:25 -0400 Subject: [PATCH 05/18] add py314 and bump maturin GH action --- .github/workflows/CI.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2f5745c..1803a29 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -39,10 +39,10 @@ jobs: python-version: "3.10" - name: Build wheels - uses: PyO3/maturin-action@v1.44.0 + uses: PyO3/maturin-action@v1.49.4 with: target: ${{ matrix.platform.target }} - args: --release --out dist --interpreter python3.9 python3.10 python3.11 python3.12 python3.13 + args: --release --out dist --interpreter python3.9 python3.10 python3.11 python3.12 python3.13 python3.14 sccache: 'true' manylinux: auto before-script-linux: | @@ -76,10 +76,10 @@ jobs: architecture: ${{ matrix.platform.target }} - name: Build wheels - uses: PyO3/maturin-action@v1.44.0 + uses: PyO3/maturin-action@v1.49.4 with: target: ${{ matrix.platform.target }} - args: --release --out dist --interpreter python3.9 python3.10 python3.11 python3.12 python3.13 + args: --release --out dist --interpreter python3.9 python3.10 python3.11 python3.12 python3.13 python3.14 sccache: 'true' - name: Upload wheels @@ -104,10 +104,10 @@ jobs: python-version: "3.10" - name: Build wheels - uses: PyO3/maturin-action@v1 + uses: PyO3/maturin-action@v1.49.4 with: target: ${{ matrix.platform.target }} - args: --release --out dist --interpreter python3.9 python3.10 python3.11 python3.12 python3.13 + args: --release --out dist --interpreter python3.9 python3.10 python3.11 python3.12 python3.13 python3.14 sccache: 'true' - name: Upload wheels @@ -121,7 +121,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Build sdist - uses: PyO3/maturin-action@v1.44.0 + uses: PyO3/maturin-action@v1.49.4 with: command: sdist args: --out dist @@ -154,7 +154,7 @@ jobs: subject-path: 'wheels-*/*' - name: Publish to PyPI - uses: PyO3/maturin-action@v1 + uses: PyO3/maturin-action@v1.49.4 with: command: upload args: --non-interactive --skip-existing wheels-*/* From 1452d451f3c2ab9cd1506424ce7dbd755cd4b2ed Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Mon, 27 Oct 2025 19:06:39 -0400 Subject: [PATCH 06/18] idk --- src/lib.rs | 62 +++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d6d4fc3..089e5c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -396,11 +396,11 @@ mod bt_decode { } } - fn composite_to_py_object( - py: Python, + fn composite_to_py_object<'py>( + py: Python<'py>, value: Composite, legacy_account_id: bool, - ) -> PyResult> { + ) -> PyResult> { match value { Composite::Named(inner_) => { let dict = PyDict::new(py); @@ -408,50 +408,47 @@ mod bt_decode { let val_py = value_to_pyobject(py, val.clone(), legacy_account_id)?; dict.set_item(key, val_py)?; } - Ok(dict.into_pyobject(py)?.into_any().unbind()) + Ok(dict.into_pyobject(py)?.into_any()) } Composite::Unnamed(inner_) => { - let items: Vec> = inner_ + let items: Vec> = inner_ .iter() .map(|val| value_to_pyobject(py, val.clone(), legacy_account_id)) - .collect::>>>()?; + .collect::>>>()?; if !legacy_account_id && inner_.len() == 1 && inner_[0].context == 1 { // AccountIds are the only ones with context of 1, this will cause them to not be placed in a tuple - return Ok(items[0].clone_ref(py)); + return Ok(items[0].clone()); } let tuple = PyTuple::new(py, items); - Ok(tuple? - .get_item(0) - .expect("Failed to get item from tuple") - .unbind()) + Ok(tuple.unwrap().into_any()) } } } - fn value_to_pyobject( - py: Python, + fn value_to_pyobject<'py>( + py: Python<'py>, value: Value, legacy_account_id: bool, - ) -> PyResult> { + ) -> PyResult> { match value.value { ValueDef::::Primitive(inner) => { let value = match inner { - Primitive::U128(value) => value.into_pyobject(py)?.into_any().unbind(), - Primitive::U256(value) => value.into_pyobject(py)?.into_any().unbind(), - Primitive::I128(value) => value.into_pyobject(py)?.into_any().unbind(), - Primitive::I256(value) => value.into_pyobject(py)?.into_any().unbind(), + Primitive::U128(value) => value.into_pyobject(py)?.into_any(), + Primitive::U256(value) => value.into_pyobject(py)?.into_any(), + Primitive::I128(value) => value.into_pyobject(py)?.into_any(), + Primitive::I256(value) => value.into_pyobject(py)?.into_any(), Primitive::Bool(value) => { let bound = value.into_pyobject(py)?; - Bound::clone(&bound).into_any().unbind() + Bound::clone(&bound).into_any() } - Primitive::Char(value) => value.into_pyobject(py)?.into_any().unbind(), - Primitive::String(value) => value.into_pyobject(py)?.into_any().unbind(), + Primitive::Char(value) => value.into_pyobject(py)?.into_any(), + Primitive::String(value) => value.into_pyobject(py)?.into_any(), }; Ok(value) } ValueDef::::BitSequence(inner) => { - let value = inner.to_vec().into_pyobject(py)?.into_any().unbind(); + let value = inner.to_vec().into_pyobject(py)?.into_any(); Ok(value) } @@ -488,7 +485,7 @@ mod bt_decode { })?; let ss58_address = account_id_to_ss58(account_id_array, 42); - Ok(ss58_address.as_str().into_pyobject(py)?.into_any().unbind()) + Ok(ss58_address.as_str().into_pyobject(py)?.into_any()) } _ => { let value = composite_to_py_object(py, composite, legacy_account_id)?; @@ -500,7 +497,7 @@ mod bt_decode { ValueDef::::Variant(inner) => { if inner.name == "None" || inner.name == "Some" { match inner.name.as_str() { - "None" => Ok(py.None()), + "None" => Ok(py.None().into_bound(py)), "Some" => { let some = composite_to_py_object( py, @@ -509,14 +506,11 @@ mod bt_decode { )?; if inner.values.len() == 1 { let tuple = some - .downcast_bound::(py) + .downcast::() .expect("Failed to downcast back to a tuple"); - Ok(tuple - .get_item(0) - .expect("Failed to get item from tuple") - .unbind()) + Ok(tuple.get_item(0).expect("Failed to get item from tuple")) } else { - Ok(some.into_pyobject(py)?.into_any().unbind()) + Ok(some.into_pyobject(py)?.into_any()) } } _ => Err(PyErr::new::(format!( @@ -531,7 +525,7 @@ mod bt_decode { composite_to_py_object(py, inner.values, legacy_account_id)?, )?; - Ok(value.into_pyobject(py)?.into_any().unbind()) + Ok(value.into_pyobject(py)?.into_any()) } } } @@ -1135,7 +1129,7 @@ mod bt_decode { )) })?; - value_to_pyobject(py, decoded, legacy_account_id) + value_to_pyobject(py, decoded, legacy_account_id).map(|value| value.unbind()) } #[pyfunction(name = "decode_list", signature = (list_type_strings, portable_registry, list_encoded, legacy_account_id=true))] @@ -1172,7 +1166,9 @@ mod bt_decode { )) })?; - decoded_list.push(value_to_pyobject(py, decoded, legacy_account_id)?); + decoded_list.push( + value_to_pyobject(py, decoded, legacy_account_id).map(|value| value.unbind())?, + ); } Ok(decoded_list) From bda760e5b12b645ac5aca013f619ea250db9c3c3 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 28 Oct 2025 10:36:46 -0400 Subject: [PATCH 07/18] chore: lock --- Cargo.lock | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 0d56e89..c276329 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,10 +20,36 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "base58" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bt_decode" version = "0.7.0" dependencies = [ + "base58", + "blake2", "custom_derive", "frame-metadata 16.0.0", "log", @@ -58,6 +84,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "custom_derive" version = "0.2.0" @@ -78,6 +114,17 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + [[package]] name = "either" version = "1.13.0" @@ -119,6 +166,16 @@ dependencies = [ "serde", ] +[[package]] +name = "generic-array" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -486,6 +543,12 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "1.0.109" @@ -531,6 +594,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + [[package]] name = "unicode-ident" version = "1.0.12" @@ -543,6 +612,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "winnow" version = "0.5.40" From d43b30d5abeb86dc9735f449cee22192c5547817 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 28 Oct 2025 10:37:04 -0400 Subject: [PATCH 08/18] chore: fmt --- src/lib.rs | 111 ++++++++++------------------------------------------- 1 file changed, 20 insertions(+), 91 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 089e5c2..5aa72ac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,8 +38,6 @@ mod dyndecoder; mod bt_decode { use std::collections::HashMap; - use base58::ToBase58; - use blake2::{Blake2b512, Digest}; use dyndecoder::{fill_memo_using_well_known_types, get_type_id_from_type_string}; use frame_metadata::v15::RuntimeMetadataV15; use pyo3::types::{PyDict, PyInt, PyList, PyTuple}; @@ -52,25 +50,6 @@ mod bt_decode { use super::*; - fn account_id_to_ss58(account_id: [u8; 32], ss58_prefix: u16) -> String { - let mut data = Vec::with_capacity(35); - match ss58_prefix { - 0..=63 => data.push(ss58_prefix as u8), - 64..=16383 => { - data.push(((ss58_prefix & 0b0011_1111) | 0b0100_0000) as u8); - data.push((ss58_prefix >> 6) as u8); - } - _ => panic!("Invalid SS58 prefix"), - } - data.extend(account_id); - let checksum = Blake2b512::new() - .chain_update(b"SS58PRE") - .chain_update(&data) - .finalize(); - data.extend_from_slice(&checksum[..2]); - data.to_base58() - } - #[pyclass(name = "AxonInfo", get_all)] #[derive(Clone, Encode, Decode)] struct AxonInfo { @@ -399,37 +378,32 @@ mod bt_decode { fn composite_to_py_object<'py>( py: Python<'py>, value: Composite, - legacy_account_id: bool, ) -> PyResult> { match value { Composite::Named(inner_) => { let dict = PyDict::new(py); for (key, val) in inner_.iter() { - let val_py = value_to_pyobject(py, val.clone(), legacy_account_id)?; + let val_py = value_to_pyobject(py, val.clone())?; dict.set_item(key, val_py)?; } + Ok(dict.into_pyobject(py)?.into_any()) } Composite::Unnamed(inner_) => { - let items: Vec> = inner_ - .iter() - .map(|val| value_to_pyobject(py, val.clone(), legacy_account_id)) - .collect::>>>()?; - if !legacy_account_id && inner_.len() == 1 && inner_[0].context == 1 { - // AccountIds are the only ones with context of 1, this will cause them to not be placed in a tuple - return Ok(items[0].clone()); - } - let tuple = PyTuple::new(py, items); + let tuple = PyTuple::new( + py, + inner_ + .iter() + .map(|val| value_to_pyobject(py, val.clone())) + .collect::>>>()?, + ); + Ok(tuple.unwrap().into_any()) } } } - fn value_to_pyobject<'py>( - py: Python<'py>, - value: Value, - legacy_account_id: bool, - ) -> PyResult> { + fn value_to_pyobject<'py>(py: Python<'py>, value: Value) -> PyResult> { match value.value { ValueDef::::Primitive(inner) => { let value = match inner { @@ -452,58 +426,17 @@ mod bt_decode { Ok(value) } - ValueDef::::Composite(composite) => { - if legacy_account_id { - let value = composite_to_py_object(py, composite, legacy_account_id)?; - return Ok(value); - } else { - match &composite { - Composite::Unnamed(ref inner) if inner.len() == 32 => { - let mut account_id_bytes: Vec = Vec::with_capacity(32); - - for val in inner.iter() { - match val.value { - ValueDef::::Primitive(Primitive::U128(byte)) => { - account_id_bytes.push(byte as u8); - } - _ => { - let value = composite_to_py_object( - py, - composite, - legacy_account_id, - )?; - return Ok(value); - } - } - } + ValueDef::::Composite(inner) => { + let value = composite_to_py_object(py, inner)?; - let account_id_array: [u8; 32] = - account_id_bytes.try_into().map_err(|_| { - PyErr::new::( - "Invalid AccountId length", - ) - })?; - - let ss58_address = account_id_to_ss58(account_id_array, 42); - Ok(ss58_address.as_str().into_pyobject(py)?.into_any()) - } - _ => { - let value = composite_to_py_object(py, composite, legacy_account_id)?; - Ok(value) - } - } - } + Ok(value) } ValueDef::::Variant(inner) => { if inner.name == "None" || inner.name == "Some" { match inner.name.as_str() { "None" => Ok(py.None().into_bound(py)), "Some" => { - let some = composite_to_py_object( - py, - inner.values.clone(), - legacy_account_id, - )?; + let some = composite_to_py_object(py, inner.values.clone())?; if inner.values.len() == 1 { let tuple = some .downcast::() @@ -522,7 +455,7 @@ mod bt_decode { let value = PyDict::new(py); value.set_item( inner.name.clone(), - composite_to_py_object(py, inner.values, legacy_account_id)?, + composite_to_py_object(py, inner.values)?, )?; Ok(value.into_pyobject(py)?.into_any()) @@ -1101,13 +1034,12 @@ mod bt_decode { pyobject_to_value_no_option_check(py, to_encode, ty, type_id, portable_registry) } - #[pyfunction(name = "decode", signature = (type_string, portable_registry, encoded, legacy_account_id=true))] + #[pyfunction(name = "decode")] fn py_decode( py: Python, type_string: &str, portable_registry: &PyPortableRegistry, encoded: &[u8], - legacy_account_id: bool, ) -> PyResult> { // Create a memoization table for the type string to type id conversion let mut memo = HashMap::::new(); @@ -1129,16 +1061,15 @@ mod bt_decode { )) })?; - value_to_pyobject(py, decoded, legacy_account_id).map(|value| value.unbind()) + value_to_pyobject(py, decoded).map(|value| value.unbind()) } - #[pyfunction(name = "decode_list", signature = (list_type_strings, portable_registry, list_encoded, legacy_account_id=true))] + #[pyfunction(name = "decode_list")] fn py_decode_list( py: Python, list_type_strings: Vec, portable_registry: &PyPortableRegistry, list_encoded: Vec>, - legacy_account_id: bool, ) -> PyResult>> { // Create a memoization table for the type string to type id conversion let mut memo = HashMap::::new(); @@ -1166,9 +1097,7 @@ mod bt_decode { )) })?; - decoded_list.push( - value_to_pyobject(py, decoded, legacy_account_id).map(|value| value.unbind())?, - ); + decoded_list.push(value_to_pyobject(py, decoded).map(|value| value.unbind())?); } Ok(decoded_list) From e3a159adc82f3d7bc0997969ad2f6d221df80089 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 28 Oct 2025 15:24:42 -0400 Subject: [PATCH 09/18] idk --- src/lib.rs | 111 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 91 insertions(+), 20 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5aa72ac..089e5c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,6 +38,8 @@ mod dyndecoder; mod bt_decode { use std::collections::HashMap; + use base58::ToBase58; + use blake2::{Blake2b512, Digest}; use dyndecoder::{fill_memo_using_well_known_types, get_type_id_from_type_string}; use frame_metadata::v15::RuntimeMetadataV15; use pyo3::types::{PyDict, PyInt, PyList, PyTuple}; @@ -50,6 +52,25 @@ mod bt_decode { use super::*; + fn account_id_to_ss58(account_id: [u8; 32], ss58_prefix: u16) -> String { + let mut data = Vec::with_capacity(35); + match ss58_prefix { + 0..=63 => data.push(ss58_prefix as u8), + 64..=16383 => { + data.push(((ss58_prefix & 0b0011_1111) | 0b0100_0000) as u8); + data.push((ss58_prefix >> 6) as u8); + } + _ => panic!("Invalid SS58 prefix"), + } + data.extend(account_id); + let checksum = Blake2b512::new() + .chain_update(b"SS58PRE") + .chain_update(&data) + .finalize(); + data.extend_from_slice(&checksum[..2]); + data.to_base58() + } + #[pyclass(name = "AxonInfo", get_all)] #[derive(Clone, Encode, Decode)] struct AxonInfo { @@ -378,32 +399,37 @@ mod bt_decode { fn composite_to_py_object<'py>( py: Python<'py>, value: Composite, + legacy_account_id: bool, ) -> PyResult> { match value { Composite::Named(inner_) => { let dict = PyDict::new(py); for (key, val) in inner_.iter() { - let val_py = value_to_pyobject(py, val.clone())?; + let val_py = value_to_pyobject(py, val.clone(), legacy_account_id)?; dict.set_item(key, val_py)?; } - Ok(dict.into_pyobject(py)?.into_any()) } Composite::Unnamed(inner_) => { - let tuple = PyTuple::new( - py, - inner_ - .iter() - .map(|val| value_to_pyobject(py, val.clone())) - .collect::>>>()?, - ); - + let items: Vec> = inner_ + .iter() + .map(|val| value_to_pyobject(py, val.clone(), legacy_account_id)) + .collect::>>>()?; + if !legacy_account_id && inner_.len() == 1 && inner_[0].context == 1 { + // AccountIds are the only ones with context of 1, this will cause them to not be placed in a tuple + return Ok(items[0].clone()); + } + let tuple = PyTuple::new(py, items); Ok(tuple.unwrap().into_any()) } } } - fn value_to_pyobject<'py>(py: Python<'py>, value: Value) -> PyResult> { + fn value_to_pyobject<'py>( + py: Python<'py>, + value: Value, + legacy_account_id: bool, + ) -> PyResult> { match value.value { ValueDef::::Primitive(inner) => { let value = match inner { @@ -426,17 +452,58 @@ mod bt_decode { Ok(value) } - ValueDef::::Composite(inner) => { - let value = composite_to_py_object(py, inner)?; + ValueDef::::Composite(composite) => { + if legacy_account_id { + let value = composite_to_py_object(py, composite, legacy_account_id)?; + return Ok(value); + } else { + match &composite { + Composite::Unnamed(ref inner) if inner.len() == 32 => { + let mut account_id_bytes: Vec = Vec::with_capacity(32); + + for val in inner.iter() { + match val.value { + ValueDef::::Primitive(Primitive::U128(byte)) => { + account_id_bytes.push(byte as u8); + } + _ => { + let value = composite_to_py_object( + py, + composite, + legacy_account_id, + )?; + return Ok(value); + } + } + } - Ok(value) + let account_id_array: [u8; 32] = + account_id_bytes.try_into().map_err(|_| { + PyErr::new::( + "Invalid AccountId length", + ) + })?; + + let ss58_address = account_id_to_ss58(account_id_array, 42); + Ok(ss58_address.as_str().into_pyobject(py)?.into_any()) + } + _ => { + let value = composite_to_py_object(py, composite, legacy_account_id)?; + Ok(value) + } + } + } } ValueDef::::Variant(inner) => { if inner.name == "None" || inner.name == "Some" { match inner.name.as_str() { "None" => Ok(py.None().into_bound(py)), "Some" => { - let some = composite_to_py_object(py, inner.values.clone())?; + let some = composite_to_py_object( + py, + inner.values.clone(), + legacy_account_id, + )?; if inner.values.len() == 1 { let tuple = some .downcast::() @@ -455,7 +522,7 @@ mod bt_decode { let value = PyDict::new(py); value.set_item( inner.name.clone(), - composite_to_py_object(py, inner.values)?, + composite_to_py_object(py, inner.values, legacy_account_id)?, )?; Ok(value.into_pyobject(py)?.into_any()) @@ -1034,12 +1101,13 @@ mod bt_decode { pyobject_to_value_no_option_check(py, to_encode, ty, type_id, portable_registry) } - #[pyfunction(name = "decode")] + #[pyfunction(name = "decode", signature = (type_string, portable_registry, encoded, legacy_account_id=true))] fn py_decode( py: Python, type_string: &str, portable_registry: &PyPortableRegistry, encoded: &[u8], + legacy_account_id: bool, ) -> PyResult> { // Create a memoization table for the type string to type id conversion let mut memo = HashMap::::new(); @@ -1061,15 +1129,16 @@ mod bt_decode { )) })?; - value_to_pyobject(py, decoded).map(|value| value.unbind()) + value_to_pyobject(py, decoded, legacy_account_id).map(|value| value.unbind()) } - #[pyfunction(name = "decode_list")] + #[pyfunction(name = "decode_list", signature = (list_type_strings, portable_registry, list_encoded, legacy_account_id=true))] fn py_decode_list( py: Python, list_type_strings: Vec, portable_registry: &PyPortableRegistry, list_encoded: Vec>, + legacy_account_id: bool, ) -> PyResult>> { // Create a memoization table for the type string to type id conversion let mut memo = HashMap::::new(); @@ -1097,7 +1166,9 @@ mod bt_decode { )) })?; - decoded_list.push(value_to_pyobject(py, decoded).map(|value| value.unbind())?); + decoded_list.push( + value_to_pyobject(py, decoded, legacy_account_id).map(|value| value.unbind())?, + ); } Ok(decoded_list) From 5231c95289afb29115ffbebe80c752b910330cf4 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 28 Oct 2025 15:24:43 -0400 Subject: [PATCH 10/18] Removes the AccountId decoding --- src/lib.rs | 111 ++++++++++------------------------------------------- 1 file changed, 20 insertions(+), 91 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 089e5c2..5aa72ac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,8 +38,6 @@ mod dyndecoder; mod bt_decode { use std::collections::HashMap; - use base58::ToBase58; - use blake2::{Blake2b512, Digest}; use dyndecoder::{fill_memo_using_well_known_types, get_type_id_from_type_string}; use frame_metadata::v15::RuntimeMetadataV15; use pyo3::types::{PyDict, PyInt, PyList, PyTuple}; @@ -52,25 +50,6 @@ mod bt_decode { use super::*; - fn account_id_to_ss58(account_id: [u8; 32], ss58_prefix: u16) -> String { - let mut data = Vec::with_capacity(35); - match ss58_prefix { - 0..=63 => data.push(ss58_prefix as u8), - 64..=16383 => { - data.push(((ss58_prefix & 0b0011_1111) | 0b0100_0000) as u8); - data.push((ss58_prefix >> 6) as u8); - } - _ => panic!("Invalid SS58 prefix"), - } - data.extend(account_id); - let checksum = Blake2b512::new() - .chain_update(b"SS58PRE") - .chain_update(&data) - .finalize(); - data.extend_from_slice(&checksum[..2]); - data.to_base58() - } - #[pyclass(name = "AxonInfo", get_all)] #[derive(Clone, Encode, Decode)] struct AxonInfo { @@ -399,37 +378,32 @@ mod bt_decode { fn composite_to_py_object<'py>( py: Python<'py>, value: Composite, - legacy_account_id: bool, ) -> PyResult> { match value { Composite::Named(inner_) => { let dict = PyDict::new(py); for (key, val) in inner_.iter() { - let val_py = value_to_pyobject(py, val.clone(), legacy_account_id)?; + let val_py = value_to_pyobject(py, val.clone())?; dict.set_item(key, val_py)?; } + Ok(dict.into_pyobject(py)?.into_any()) } Composite::Unnamed(inner_) => { - let items: Vec> = inner_ - .iter() - .map(|val| value_to_pyobject(py, val.clone(), legacy_account_id)) - .collect::>>>()?; - if !legacy_account_id && inner_.len() == 1 && inner_[0].context == 1 { - // AccountIds are the only ones with context of 1, this will cause them to not be placed in a tuple - return Ok(items[0].clone()); - } - let tuple = PyTuple::new(py, items); + let tuple = PyTuple::new( + py, + inner_ + .iter() + .map(|val| value_to_pyobject(py, val.clone())) + .collect::>>>()?, + ); + Ok(tuple.unwrap().into_any()) } } } - fn value_to_pyobject<'py>( - py: Python<'py>, - value: Value, - legacy_account_id: bool, - ) -> PyResult> { + fn value_to_pyobject<'py>(py: Python<'py>, value: Value) -> PyResult> { match value.value { ValueDef::::Primitive(inner) => { let value = match inner { @@ -452,58 +426,17 @@ mod bt_decode { Ok(value) } - ValueDef::::Composite(composite) => { - if legacy_account_id { - let value = composite_to_py_object(py, composite, legacy_account_id)?; - return Ok(value); - } else { - match &composite { - Composite::Unnamed(ref inner) if inner.len() == 32 => { - let mut account_id_bytes: Vec = Vec::with_capacity(32); - - for val in inner.iter() { - match val.value { - ValueDef::::Primitive(Primitive::U128(byte)) => { - account_id_bytes.push(byte as u8); - } - _ => { - let value = composite_to_py_object( - py, - composite, - legacy_account_id, - )?; - return Ok(value); - } - } - } + ValueDef::::Composite(inner) => { + let value = composite_to_py_object(py, inner)?; - let account_id_array: [u8; 32] = - account_id_bytes.try_into().map_err(|_| { - PyErr::new::( - "Invalid AccountId length", - ) - })?; - - let ss58_address = account_id_to_ss58(account_id_array, 42); - Ok(ss58_address.as_str().into_pyobject(py)?.into_any()) - } - _ => { - let value = composite_to_py_object(py, composite, legacy_account_id)?; - Ok(value) - } - } - } + Ok(value) } ValueDef::::Variant(inner) => { if inner.name == "None" || inner.name == "Some" { match inner.name.as_str() { "None" => Ok(py.None().into_bound(py)), "Some" => { - let some = composite_to_py_object( - py, - inner.values.clone(), - legacy_account_id, - )?; + let some = composite_to_py_object(py, inner.values.clone())?; if inner.values.len() == 1 { let tuple = some .downcast::() @@ -522,7 +455,7 @@ mod bt_decode { let value = PyDict::new(py); value.set_item( inner.name.clone(), - composite_to_py_object(py, inner.values, legacy_account_id)?, + composite_to_py_object(py, inner.values)?, )?; Ok(value.into_pyobject(py)?.into_any()) @@ -1101,13 +1034,12 @@ mod bt_decode { pyobject_to_value_no_option_check(py, to_encode, ty, type_id, portable_registry) } - #[pyfunction(name = "decode", signature = (type_string, portable_registry, encoded, legacy_account_id=true))] + #[pyfunction(name = "decode")] fn py_decode( py: Python, type_string: &str, portable_registry: &PyPortableRegistry, encoded: &[u8], - legacy_account_id: bool, ) -> PyResult> { // Create a memoization table for the type string to type id conversion let mut memo = HashMap::::new(); @@ -1129,16 +1061,15 @@ mod bt_decode { )) })?; - value_to_pyobject(py, decoded, legacy_account_id).map(|value| value.unbind()) + value_to_pyobject(py, decoded).map(|value| value.unbind()) } - #[pyfunction(name = "decode_list", signature = (list_type_strings, portable_registry, list_encoded, legacy_account_id=true))] + #[pyfunction(name = "decode_list")] fn py_decode_list( py: Python, list_type_strings: Vec, portable_registry: &PyPortableRegistry, list_encoded: Vec>, - legacy_account_id: bool, ) -> PyResult>> { // Create a memoization table for the type string to type id conversion let mut memo = HashMap::::new(); @@ -1166,9 +1097,7 @@ mod bt_decode { )) })?; - decoded_list.push( - value_to_pyobject(py, decoded, legacy_account_id).map(|value| value.unbind())?, - ); + decoded_list.push(value_to_pyobject(py, decoded).map(|value| value.unbind())?); } Ok(decoded_list) From 3405e4fb61b6f32e1cb76d0319c06631a816b61c Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 28 Oct 2025 15:24:43 -0400 Subject: [PATCH 11/18] add encode fn to metadata (#36) --- src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 5aa72ac..7e72492 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -325,6 +325,12 @@ mod bt_decode { serde_json::to_string(&self.metadata).unwrap() } + fn encode_to_metadata_option(&self) -> Vec { + let as_prefixed = RuntimeMetadataPrefixed::from(self.metadata.clone()); + let as_option = Some(as_prefixed.encode()); + as_option.encode() + } + #[staticmethod] fn decode_from_metadata_option(encoded_metadata_v15: &[u8]) -> Self { let option_vec = Option::>::decode(&mut &encoded_metadata_v15[..]) From 1d9b1a03eb5b704f08375d8265ca0cccde0f0de5 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 28 Oct 2025 15:24:44 -0400 Subject: [PATCH 12/18] add generate-import-lib for maturin windows --- Cargo.lock | 8 ++++---- Cargo.toml | 14 +++++++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c276329..102d7c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,9 +70,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "cc" -version = "1.2.39" +version = "1.2.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" +checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" dependencies = [ "find-msvc-tools", "shlex", @@ -139,9 +139,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "find-msvc-tools" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" [[package]] name = "frame-metadata" diff --git a/Cargo.toml b/Cargo.toml index f18ef4a..83b7ed0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,13 +20,21 @@ features = ["extension-module", "generate-import-lib"] path = "libs/custom-derive" [dependencies] -frame-metadata = { version = "16.0.0", features = [ "current", "decode", "serde_full" ], default-features = false } +frame-metadata = { version = "16.0.0", features = [ + "current", + "decode", + "serde_full", +], default-features = false } codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = [ "derive", ] } -scale-info = { version = "2.11.2", features = [ "serde" ], default-features = false } -serde_json = { version = "1.0.127", features = [ "alloc" ], default-features = false } +scale-info = { version = "2.11.2", features = [ + "serde", +], default-features = false } +serde_json = { version = "1.0.127", features = [ + "alloc", +], default-features = false } scale-value = { version = "0.16.2", default-features = false } pythonize = "0.26.0" log = { version = "0.4.25", default-features = false } From 085fadc65e0ab5370ce8011e48c0efacc0d2467a Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 28 Oct 2025 15:24:44 -0400 Subject: [PATCH 13/18] bump python action --- .github/workflows/CI.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 1803a29..fd2652e 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -34,7 +34,7 @@ jobs: with: platforms: arm64 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: "3.10" @@ -70,7 +70,7 @@ jobs: target: x86 steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: "3.10" architecture: ${{ matrix.platform.target }} @@ -99,7 +99,7 @@ jobs: target: aarch64 steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: "3.10" From e34698dd8ab10b2daf08d2623c91acbcb3ca8be6 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 28 Oct 2025 15:24:44 -0400 Subject: [PATCH 14/18] try specifying 2_28 for arm --- .github/workflows/CI.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index fd2652e..f4805b0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -39,12 +39,12 @@ jobs: python-version: "3.10" - name: Build wheels - uses: PyO3/maturin-action@v1.49.4 + uses: PyO3/maturin-action@v1.44 with: target: ${{ matrix.platform.target }} args: --release --out dist --interpreter python3.9 python3.10 python3.11 python3.12 python3.13 python3.14 sccache: 'true' - manylinux: auto + manylinux: ${{ matrix.platform.target == 'aarch64' && '2_28' || 'auto' }} before-script-linux: | # run this installation and add CFLAGS only for aarch64 if [ "${{ matrix.platform.target }}" = "aarch64" ]; then From 83658afa8c384b7eef61c2bf0e9c0d7d5014c834 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 28 Oct 2025 15:24:45 -0400 Subject: [PATCH 15/18] oops use correct maturin action ver --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f4805b0..988cfce 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -39,7 +39,7 @@ jobs: python-version: "3.10" - name: Build wheels - uses: PyO3/maturin-action@v1.44 + uses: PyO3/maturin-action@v1.49.4 with: target: ${{ matrix.platform.target }} args: --release --out dist --interpreter python3.9 python3.10 python3.11 python3.12 python3.13 python3.14 From 30afd767abe8568a4970038961066a9062ce4133 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 28 Oct 2025 15:24:45 -0400 Subject: [PATCH 16/18] libssl already in the latest image --- .github/workflows/CI.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 988cfce..e74ab7d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -44,12 +44,10 @@ jobs: target: ${{ matrix.platform.target }} args: --release --out dist --interpreter python3.9 python3.10 python3.11 python3.12 python3.13 python3.14 sccache: 'true' - manylinux: ${{ matrix.platform.target == 'aarch64' && '2_28' || 'auto' }} + manylinux: auto before-script-linux: | # run this installation and add CFLAGS only for aarch64 if [ "${{ matrix.platform.target }}" = "aarch64" ]; then - apt-get update - apt-get install -y pkg-config libssl-dev export CFLAGS="-D__ARM_ARCH=8" fi From 95d4afaf460f468e81912484a1a25039864aa7bd Mon Sep 17 00:00:00 2001 From: bdhimes Date: Tue, 28 Oct 2025 21:39:08 +0200 Subject: [PATCH 17/18] Remove cargo.lock from git --- .gitignore | 4 +- Cargo.lock | 628 ----------------------------------------------------- 2 files changed, 3 insertions(+), 629 deletions(-) delete mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index 54825f8..83931af 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ target *.egg-info __pycache__ # IDE -.vscode \ No newline at end of file +.vscode + +Cargo.lock \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 102d7c9..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,628 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "arc-swap" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "base58" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" - -[[package]] -name = "blake2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" -dependencies = [ - "digest", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bt_decode" -version = "0.7.0" -dependencies = [ - "base58", - "blake2", - "custom_derive", - "frame-metadata 16.0.0", - "log", - "parity-scale-codec", - "pyo3", - "pyo3-log", - "pythonize", - "scale-info", - "scale-value", - "serde_json", -] - -[[package]] -name = "byte-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - -[[package]] -name = "cc" -version = "1.2.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" -dependencies = [ - "find-msvc-tools", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "custom_derive" -version = "0.2.0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "derive_more" -version = "0.99.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "find-msvc-tools" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" - -[[package]] -name = "frame-metadata" -version = "15.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "878babb0b136e731cc77ec2fd883ff02745ff21e6fb662729953d44923df009c" -dependencies = [ - "cfg-if", - "parity-scale-codec", - "scale-info", -] - -[[package]] -name = "frame-metadata" -version = "16.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cf1549fba25a6fcac22785b61698317d958e96cac72a59102ea45b9ae64692" -dependencies = [ - "cfg-if", - "parity-scale-codec", - "scale-info", - "serde", -] - -[[package]] -name = "generic-array" -version = "0.14.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "indexmap" -version = "2.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "indoc" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "libc" -version = "0.2.172" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" - -[[package]] -name = "log" -version = "0.4.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "parity-scale-codec" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" -dependencies = [ - "arrayvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "portable-atomic" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" - -[[package]] -name = "proc-macro-crate" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "pyo3" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383" -dependencies = [ - "indoc", - "libc", - "memoffset", - "once_cell", - "portable-atomic", - "pyo3-build-config", - "pyo3-ffi", - "pyo3-macros", - "unindent", -] - -[[package]] -name = "pyo3-build-config" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f" -dependencies = [ - "python3-dll-a", - "target-lexicon", -] - -[[package]] -name = "pyo3-ffi" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105" -dependencies = [ - "libc", - "pyo3-build-config", -] - -[[package]] -name = "pyo3-log" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d359e20231345f21a3b5b6aea7e73f4dc97e1712ef3bfe2d88997ac6a308d784" -dependencies = [ - "arc-swap", - "log", - "pyo3", -] - -[[package]] -name = "pyo3-macros" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded" -dependencies = [ - "proc-macro2", - "pyo3-macros-backend", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "pyo3-macros-backend" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf" -dependencies = [ - "heck", - "proc-macro2", - "pyo3-build-config", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "python3-dll-a" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d381ef313ae70b4da5f95f8a4de773c6aa5cd28f73adec4b4a31df70b66780d8" -dependencies = [ - "cc", -] - -[[package]] -name = "pythonize" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11e06e4cff9be2bbf2bddf28a486ae619172ea57e79787f856572878c62dcfe2" -dependencies = [ - "pyo3", - "serde", -] - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "scale-bits" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57b1e7f6b65ed1f04e79a85a57d755ad56d76fdf1e9bddcc9ae14f71fcdcf54" -dependencies = [ - "parity-scale-codec", - "scale-info", - "scale-type-resolver", - "serde", -] - -[[package]] -name = "scale-decode" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e98f3262c250d90e700bb802eb704e1f841e03331c2eb815e46516c4edbf5b27" -dependencies = [ - "derive_more", - "parity-scale-codec", - "scale-bits", - "scale-type-resolver", - "smallvec", -] - -[[package]] -name = "scale-encode" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ba0b9c48dc0eb20c60b083c29447c0c4617cb7c4a4c9fef72aa5c5bc539e15e" -dependencies = [ - "derive_more", - "parity-scale-codec", - "scale-bits", - "scale-type-resolver", - "smallvec", -] - -[[package]] -name = "scale-info" -version = "2.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" -dependencies = [ - "cfg-if", - "derive_more", - "parity-scale-codec", - "scale-info-derive", - "serde", -] - -[[package]] -name = "scale-info-derive" -version = "2.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "scale-type-resolver" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0cded6518aa0bd6c1be2b88ac81bf7044992f0f154bfbabd5ad34f43512abcb" -dependencies = [ - "scale-info", - "smallvec", -] - -[[package]] -name = "scale-value" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4d772cfb7569e03868400344a1695d16560bf62b86b918604773607d39ec84" -dependencies = [ - "derive_more", - "either", - "frame-metadata 15.1.0", - "parity-scale-codec", - "scale-bits", - "scale-decode", - "scale-encode", - "scale-info", - "scale-type-resolver", -] - -[[package]] -name = "serde" -version = "1.0.209" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.209" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "serde_json" -version = "1.0.127" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "target-lexicon" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" - -[[package]] -name = "toml_datetime" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" - -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow", -] - -[[package]] -name = "typenum" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unindent" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] From 1cd730721462c1459b764230fafc4c48e55fd31d Mon Sep 17 00:00:00 2001 From: bdhimes Date: Tue, 28 Oct 2025 21:43:14 +0200 Subject: [PATCH 18/18] Add Cargo.lock back. It's supposed to help with supply chain attacks. --- .gitignore | 2 - Cargo.lock | 628 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 628 insertions(+), 2 deletions(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index 83931af..99f5798 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,3 @@ target __pycache__ # IDE .vscode - -Cargo.lock \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..102d7c9 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,628 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "base58" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bt_decode" +version = "0.7.0" +dependencies = [ + "base58", + "blake2", + "custom_derive", + "frame-metadata 16.0.0", + "log", + "parity-scale-codec", + "pyo3", + "pyo3-log", + "pythonize", + "scale-info", + "scale-value", + "serde_json", +] + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "cc" +version = "1.2.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "custom_derive" +version = "0.2.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + +[[package]] +name = "frame-metadata" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "878babb0b136e731cc77ec2fd883ff02745ff21e6fb662729953d44923df009c" +dependencies = [ + "cfg-if", + "parity-scale-codec", + "scale-info", +] + +[[package]] +name = "frame-metadata" +version = "16.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cf1549fba25a6fcac22785b61698317d958e96cac72a59102ea45b9ae64692" +dependencies = [ + "cfg-if", + "parity-scale-codec", + "scale-info", + "serde", +] + +[[package]] +name = "generic-array" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "libc" +version = "0.2.172" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" + +[[package]] +name = "log" +version = "0.4.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "parity-scale-codec" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +dependencies = [ + "arrayvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "portable-atomic" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pyo3" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383" +dependencies = [ + "indoc", + "libc", + "memoffset", + "once_cell", + "portable-atomic", + "pyo3-build-config", + "pyo3-ffi", + "pyo3-macros", + "unindent", +] + +[[package]] +name = "pyo3-build-config" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f" +dependencies = [ + "python3-dll-a", + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105" +dependencies = [ + "libc", + "pyo3-build-config", +] + +[[package]] +name = "pyo3-log" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d359e20231345f21a3b5b6aea7e73f4dc97e1712ef3bfe2d88997ac6a308d784" +dependencies = [ + "arc-swap", + "log", + "pyo3", +] + +[[package]] +name = "pyo3-macros" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded" +dependencies = [ + "proc-macro2", + "pyo3-macros-backend", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "pyo3-macros-backend" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf" +dependencies = [ + "heck", + "proc-macro2", + "pyo3-build-config", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "python3-dll-a" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d381ef313ae70b4da5f95f8a4de773c6aa5cd28f73adec4b4a31df70b66780d8" +dependencies = [ + "cc", +] + +[[package]] +name = "pythonize" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11e06e4cff9be2bbf2bddf28a486ae619172ea57e79787f856572878c62dcfe2" +dependencies = [ + "pyo3", + "serde", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "scale-bits" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57b1e7f6b65ed1f04e79a85a57d755ad56d76fdf1e9bddcc9ae14f71fcdcf54" +dependencies = [ + "parity-scale-codec", + "scale-info", + "scale-type-resolver", + "serde", +] + +[[package]] +name = "scale-decode" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e98f3262c250d90e700bb802eb704e1f841e03331c2eb815e46516c4edbf5b27" +dependencies = [ + "derive_more", + "parity-scale-codec", + "scale-bits", + "scale-type-resolver", + "smallvec", +] + +[[package]] +name = "scale-encode" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ba0b9c48dc0eb20c60b083c29447c0c4617cb7c4a4c9fef72aa5c5bc539e15e" +dependencies = [ + "derive_more", + "parity-scale-codec", + "scale-bits", + "scale-type-resolver", + "smallvec", +] + +[[package]] +name = "scale-info" +version = "2.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", + "serde", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "scale-type-resolver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0cded6518aa0bd6c1be2b88ac81bf7044992f0f154bfbabd5ad34f43512abcb" +dependencies = [ + "scale-info", + "smallvec", +] + +[[package]] +name = "scale-value" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4d772cfb7569e03868400344a1695d16560bf62b86b918604773607d39ec84" +dependencies = [ + "derive_more", + "either", + "frame-metadata 15.1.0", + "parity-scale-codec", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-info", + "scale-type-resolver", +] + +[[package]] +name = "serde" +version = "1.0.209" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.209" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "serde_json" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "target-lexicon" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" + +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unindent" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +]