mod storage_key;
mod utils;
pub mod address;
use crate::{Error, Metadata, error::MetadataError, metadata::DecodeWithMetadata};
use address::Address;
use alloc::vec::Vec;
#[doc(hidden)]
pub use utils::lookup_storage_entry_details;
pub fn validate<Addr: Address>(address: &Addr, metadata: &Metadata) -> Result<(), Error> {
let Some(hash) = address.validation_hash() else {
return Ok(());
};
let pallet_name = address.pallet_name();
let entry_name = address.entry_name();
let pallet_metadata = metadata.pallet_by_name_err(pallet_name)?;
let Some(expected_hash) = pallet_metadata.storage_hash(entry_name) else {
return Err(MetadataError::IncompatibleCodegen.into());
};
if expected_hash != hash {
return Err(MetadataError::IncompatibleCodegen.into());
}
Ok(())
}
pub fn get_address_bytes<Addr: Address>(
address: &Addr,
metadata: &Metadata,
) -> Result<Vec<u8>, Error> {
let mut bytes = Vec::new();
utils::write_storage_address_root_bytes(address, &mut bytes);
address.append_entry_bytes(metadata, &mut bytes)?;
Ok(bytes)
}
pub fn get_address_root_bytes<Addr: Address>(address: &Addr) -> Vec<u8> {
let mut bytes = Vec::new();
utils::write_storage_address_root_bytes(address, &mut bytes);
bytes
}
pub fn decode_value<Addr: Address>(
bytes: &mut &[u8],
address: &Addr,
metadata: &Metadata,
) -> Result<Addr::Target, Error> {
let pallet_name = address.pallet_name();
let entry_name = address.entry_name();
let (_, entry_metadata) =
utils::lookup_storage_entry_details(pallet_name, entry_name, metadata)?;
let value_ty_id = match entry_metadata.entry_type() {
subxt_metadata::StorageEntryType::Plain(ty) => *ty,
subxt_metadata::StorageEntryType::Map { value_ty, .. } => *value_ty,
};
let val = Addr::Target::decode_with_metadata(bytes, value_ty_id, metadata)?;
Ok(val)
}
pub fn default_value<Addr: Address>(
address: &Addr,
metadata: &Metadata,
) -> Result<Addr::Target, Error> {
let pallet_name = address.pallet_name();
let entry_name = address.entry_name();
let (_, entry_metadata) =
utils::lookup_storage_entry_details(pallet_name, entry_name, metadata)?;
let value_ty_id = match entry_metadata.entry_type() {
subxt_metadata::StorageEntryType::Plain(ty) => *ty,
subxt_metadata::StorageEntryType::Map { value_ty, .. } => *value_ty,
};
let default_bytes = entry_metadata.default_bytes();
let val = Addr::Target::decode_with_metadata(&mut &*default_bytes, value_ty_id, metadata)?;
Ok(val)
}