avail_rust_client/
extensions.rs1use crate::subxt_signer::{SecretUri, sr25519::Keypair};
2use avail_rust_core::{AccountId, H256};
3
4#[cfg(feature = "generated_metadata")]
5use crate::subxt_core::tx::payload::DefaultPayload;
6#[cfg(feature = "generated_metadata")]
7use crate::{Client, SubmittableTransaction};
8#[cfg(feature = "generated_metadata")]
9use avail_rust_core::TransactionCall;
10
11pub trait H256Ext {
12 fn from_str(s: &str) -> Result<H256, String>;
13}
14
15impl H256Ext for H256 {
16 fn from_str(s: &str) -> Result<H256, String> {
17 let mut s = s;
18 if s.starts_with("0x") {
19 s = &s[2..];
20 }
21
22 if s.len() != 64 {
23 let msg = std::format!(
24 "Failed to convert string to H256. Expected 64 bytes got {}. Input string: {}",
25 s.len(),
26 s
27 );
28 return Err(msg);
29 }
30
31 let block_hash = hex::decode(s).map_err(|e| e.to_string())?;
32 let block_hash = TryInto::<[u8; 32]>::try_into(block_hash);
33 match block_hash {
34 Ok(v) => Ok(H256(v)),
35 Err(e) => {
36 let msg = std::format!("Failed to covert decoded string to H256. Input {:?}", e);
37 Err(msg)
38 },
39 }
40 }
41}
42
43pub trait AccountIdExt {
44 fn from_str(value: &str) -> Result<AccountId, String>;
45 fn from_slice(value: &[u8]) -> Result<AccountId, String>;
46}
47
48impl AccountIdExt for AccountId {
49 fn from_str(value: &str) -> Result<AccountId, String> {
50 value.parse().map_err(|e| std::format!("{:?}", e))
51 }
52
53 fn from_slice(value: &[u8]) -> Result<AccountId, String> {
54 let account_id: [u8; 32] = match value.try_into() {
55 Ok(x) => x,
56 Err(err) => return Err(err.to_string()),
57 };
58
59 Ok(AccountId { 0: account_id })
60 }
61}
62
63pub trait SecretUriExt {
64 fn from_str(value: &str) -> Result<SecretUri, String>;
65}
66
67impl SecretUriExt for SecretUri {
68 fn from_str(value: &str) -> Result<SecretUri, String> {
69 value.parse().map_err(|e| std::format!("{:?}", e))
70 }
71}
72
73pub trait KeypairExt {
74 fn from_str(value: &str) -> Result<Keypair, String>;
75 fn account_id(&self) -> AccountId;
76}
77
78impl KeypairExt for Keypair {
79 fn from_str(value: &str) -> Result<Keypair, String> {
80 let secret_uri = SecretUri::from_str(value).map_err(|e| e.to_string())?;
81 let keypair = Keypair::from_uri(&secret_uri).map_err(|e| e.to_string())?;
82 Ok(keypair)
83 }
84
85 fn account_id(&self) -> AccountId {
86 self.public_key().to_account_id()
87 }
88}
89
90#[cfg(feature = "generated_metadata")]
91pub trait DefaultPayloadExt {
92 fn to_transaction_call(&self, client: &Client) -> Result<TransactionCall, String>;
93 fn to_submittable_transaction(&self, client: Client) -> Result<SubmittableTransaction, String>;
94}
95
96#[cfg(feature = "generated_metadata")]
97impl<CallData: crate::codec::Encode> DefaultPayloadExt for DefaultPayload<CallData> {
98 fn to_transaction_call(&self, client: &Client) -> Result<TransactionCall, String> {
99 let pallet_name = self.pallet_name();
100 let call_name = self.call_name();
101
102 let metadata = client.online_client().metadata();
103 let Some(pallet) = metadata.pallet_by_name(pallet_name) else {
104 return Err("Failed to find pallet index".into());
105 };
106 let Some(call_variant) = pallet.call_variant_by_name(call_name) else {
107 return Err("Failed to find call index".into());
108 };
109
110 let pallet_index = pallet.index();
111 let call_index = call_variant.index;
112 let call_data = self.call_data().encode();
113
114 let value = TransactionCall::new(pallet_index, call_index, call_data);
115
116 Ok(value)
117 }
118
119 fn to_submittable_transaction(&self, client: Client) -> Result<SubmittableTransaction, String> {
120 let call = self.to_transaction_call(&client)?;
121 let value = SubmittableTransaction::new(client, call);
122
123 Ok(value)
124 }
125}