1use crate::{AccountId, AccountIdLike};
2use codec::{Decode, Encode};
3use sp_crypto_hashing::blake2_256;
4
5pub fn decode_already_decoded<I: codec::Input>(input: &mut I) -> Result<Vec<u8>, codec::Error> {
6 let length = input.remaining_len()?;
7 let Some(length) = length else {
8 return Err("Failed to decode transaction".into());
9 };
10 if length == 0 {
11 return Ok(Vec::new());
12 }
13 let mut value = vec![0u8; length];
14 input.read(&mut value)?;
15 Ok(value)
16}
17
18pub fn account_id_from_str(value: &str) -> Result<AccountId, String> {
19 if value.starts_with("0x") {
20 let decoded = const_hex::decode(value.trim_start_matches("0x")).map_err(|e| e.to_string())?;
22 return account_id_from_slice(&decoded);
23 }
24
25 value.parse().map_err(|e| std::format!("{:?}", e))
26}
27
28pub fn account_id_from_slice(value: &[u8]) -> Result<AccountId, String> {
29 let account_id: [u8; 32] = match value.try_into() {
30 Ok(x) => x,
31 Err(err) => return Err(err.to_string()),
32 };
33
34 Ok(AccountId { 0: account_id })
35}
36
37pub fn multi_account_id(who: &[impl Into<AccountIdLike> + Clone], threshold: u16) -> AccountId {
40 let who: Vec<AccountIdLike> = who.iter().map(|x| x.clone().into()).collect();
41 let mut who: Vec<AccountId> = who
42 .into_iter()
43 .map(|x| AccountId::try_from(x).expect("Malformed string is passed for AccountId"))
44 .collect();
45
46 who.sort();
47
48 let entropy = (b"modlpy/utilisuba", who, threshold).using_encoded(blake2_256);
49 Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref()))
50 .expect("infinite length input; no invalid inputs for type; qed")
51}
52
53struct TrailingZeroInput<'a>(&'a [u8]);
55
56impl<'a> TrailingZeroInput<'a> {
57 pub fn new(data: &'a [u8]) -> Self {
59 Self(data)
60 }
61
62 }
67
68impl<'a> codec::Input for TrailingZeroInput<'a> {
69 fn remaining_len(&mut self) -> Result<Option<usize>, codec::Error> {
70 Ok(None)
71 }
72
73 fn read(&mut self, into: &mut [u8]) -> Result<(), codec::Error> {
74 let len_from_inner = into.len().min(self.0.len());
75 into[..len_from_inner].copy_from_slice(&self.0[..len_from_inner]);
76 for i in &mut into[len_from_inner..] {
77 *i = 0;
78 }
79 self.0 = &self.0[len_from_inner..];
80
81 Ok(())
82 }
83}