kaspa_grpc_core/convert/
tx.rs

1use crate::protowire;
2use crate::{from, try_from};
3use kaspa_rpc_core::{FromRpcHex, RpcError, RpcHash, RpcResult, RpcScriptVec, ToRpcHex};
4use std::str::FromStr;
5
6// ----------------------------------------------------------------------------
7// rpc_core to protowire
8// ----------------------------------------------------------------------------
9
10from!(item: &kaspa_rpc_core::RpcTransaction, protowire::RpcTransaction, {
11    Self {
12        version: item.version.into(),
13        inputs: item.inputs.iter().map(protowire::RpcTransactionInput::from).collect(),
14        outputs: item.outputs.iter().map(protowire::RpcTransactionOutput::from).collect(),
15        lock_time: item.lock_time,
16        subnetwork_id: item.subnetwork_id.to_string(),
17        gas: item.gas,
18        payload: item.payload.to_rpc_hex(),
19        mass: item.mass,
20        verbose_data: item.verbose_data.as_ref().map(|x| x.into()),
21    }
22});
23
24from!(item: &kaspa_rpc_core::RpcTransactionInput, protowire::RpcTransactionInput, {
25    Self {
26        previous_outpoint: Some((&item.previous_outpoint).into()),
27        signature_script: item.signature_script.to_rpc_hex(),
28        sequence: item.sequence,
29        sig_op_count: item.sig_op_count.into(),
30        verbose_data: item.verbose_data.as_ref().map(|x| x.into()),
31    }
32});
33
34from!(item: &kaspa_rpc_core::RpcTransactionOutput, protowire::RpcTransactionOutput, {
35    Self {
36        amount: item.value,
37        script_public_key: Some((&item.script_public_key).into()),
38        verbose_data: item.verbose_data.as_ref().map(|x| x.into()),
39    }
40});
41
42from!(item: &kaspa_rpc_core::RpcTransactionOutpoint, protowire::RpcOutpoint, {
43    Self { transaction_id: item.transaction_id.to_string(), index: item.index }
44});
45
46from!(item: &kaspa_rpc_core::RpcUtxoEntry, protowire::RpcUtxoEntry, {
47    Self {
48        amount: item.amount,
49        script_public_key: Some((&item.script_public_key).into()),
50        block_daa_score: item.block_daa_score,
51        is_coinbase: item.is_coinbase,
52    }
53});
54
55from!(item: &kaspa_rpc_core::RpcScriptPublicKey, protowire::RpcScriptPublicKey, {
56    Self { version: item.version().into(), script_public_key: item.script().to_rpc_hex() }
57});
58
59from!(item: &kaspa_rpc_core::RpcTransactionVerboseData, protowire::RpcTransactionVerboseData, {
60    Self {
61        transaction_id: item.transaction_id.to_string(),
62        hash: item.hash.to_string(),
63        compute_mass: item.compute_mass,
64        block_hash: item.block_hash.to_string(),
65        block_time: item.block_time,
66    }
67});
68
69from!(&kaspa_rpc_core::RpcTransactionInputVerboseData, protowire::RpcTransactionInputVerboseData);
70
71from!(item: &kaspa_rpc_core::RpcTransactionOutputVerboseData, protowire::RpcTransactionOutputVerboseData, {
72    Self {
73        script_public_key_type: item.script_public_key_type.to_string(),
74        script_public_key_address: (&item.script_public_key_address).into(),
75    }
76});
77
78from!(item: &kaspa_rpc_core::RpcAcceptedTransactionIds, protowire::RpcAcceptedTransactionIds, {
79    Self {
80        accepting_block_hash: item.accepting_block_hash.to_string(),
81        accepted_transaction_ids: item.accepted_transaction_ids.iter().map(|x| x.to_string()).collect(),
82    }
83});
84
85from!(item: &kaspa_rpc_core::RpcUtxosByAddressesEntry, protowire::RpcUtxosByAddressesEntry, {
86    Self {
87        address: item.address.as_ref().map_or("".to_string(), |x| x.into()),
88        outpoint: Some((&item.outpoint).into()),
89        utxo_entry: Some((&item.utxo_entry).into()),
90    }
91});
92
93// ----------------------------------------------------------------------------
94// protowire to rpc_core
95// ----------------------------------------------------------------------------
96
97try_from!(item: &protowire::RpcTransaction, kaspa_rpc_core::RpcTransaction, {
98    Self {
99        version: item.version.try_into()?,
100        inputs: item
101            .inputs
102            .iter()
103            .map(kaspa_rpc_core::RpcTransactionInput::try_from)
104            .collect::<RpcResult<Vec<kaspa_rpc_core::RpcTransactionInput>>>()?,
105        outputs: item
106            .outputs
107            .iter()
108            .map(kaspa_rpc_core::RpcTransactionOutput::try_from)
109            .collect::<RpcResult<Vec<kaspa_rpc_core::RpcTransactionOutput>>>()?,
110        lock_time: item.lock_time,
111        subnetwork_id: kaspa_rpc_core::RpcSubnetworkId::from_str(&item.subnetwork_id)?,
112        gas: item.gas,
113        payload: Vec::from_rpc_hex(&item.payload)?,
114        mass: item.mass,
115        verbose_data: item.verbose_data.as_ref().map(kaspa_rpc_core::RpcTransactionVerboseData::try_from).transpose()?,
116    }
117});
118
119try_from!(item: &protowire::RpcTransactionInput, kaspa_rpc_core::RpcTransactionInput, {
120    Self {
121        previous_outpoint: item
122            .previous_outpoint
123            .as_ref()
124            .ok_or_else(|| RpcError::MissingRpcFieldError("RpcTransactionInput".to_string(), "previous_outpoint".to_string()))?
125            .try_into()?,
126        signature_script: Vec::from_rpc_hex(&item.signature_script)?,
127        sequence: item.sequence,
128        sig_op_count: item.sig_op_count.try_into()?,
129        verbose_data: item.verbose_data.as_ref().map(kaspa_rpc_core::RpcTransactionInputVerboseData::try_from).transpose()?,
130    }
131});
132
133try_from!(item: &protowire::RpcTransactionOutput, kaspa_rpc_core::RpcTransactionOutput, {
134    Self {
135        value: item.amount,
136        script_public_key: item
137            .script_public_key
138            .as_ref()
139            .ok_or_else(|| RpcError::MissingRpcFieldError("RpcTransactionOutput".to_string(), "script_public_key".to_string()))?
140            .try_into()?,
141        verbose_data: item.verbose_data.as_ref().map(kaspa_rpc_core::RpcTransactionOutputVerboseData::try_from).transpose()?,
142    }
143});
144
145try_from!(item: &protowire::RpcOutpoint, kaspa_rpc_core::RpcTransactionOutpoint, {
146    Self { transaction_id: RpcHash::from_str(&item.transaction_id)?, index: item.index }
147});
148
149try_from!(item: &protowire::RpcUtxoEntry, kaspa_rpc_core::RpcUtxoEntry, {
150    Self {
151        amount: item.amount,
152        script_public_key: item
153            .script_public_key
154            .as_ref()
155            .ok_or_else(|| RpcError::MissingRpcFieldError("RpcTransactionOutput".to_string(), "script_public_key".to_string()))?
156            .try_into()?,
157        block_daa_score: item.block_daa_score,
158        is_coinbase: item.is_coinbase,
159    }
160});
161
162try_from!(item: &protowire::RpcScriptPublicKey, kaspa_rpc_core::RpcScriptPublicKey, {
163    Self::new(u16::try_from(item.version)?, RpcScriptVec::from_rpc_hex(item.script_public_key.as_str())?)
164});
165
166try_from!(item: &protowire::RpcTransactionVerboseData, kaspa_rpc_core::RpcTransactionVerboseData, {
167    Self {
168        transaction_id: RpcHash::from_str(&item.transaction_id)?,
169        hash: RpcHash::from_str(&item.hash)?,
170        compute_mass: item.compute_mass,
171        block_hash: RpcHash::from_str(&item.block_hash)?,
172        block_time: item.block_time,
173    }
174});
175
176try_from!(&protowire::RpcTransactionInputVerboseData, kaspa_rpc_core::RpcTransactionInputVerboseData);
177
178try_from!(item: &protowire::RpcTransactionOutputVerboseData, kaspa_rpc_core::RpcTransactionOutputVerboseData, {
179    Self {
180        script_public_key_type: item.script_public_key_type.as_str().try_into()?,
181        script_public_key_address: item.script_public_key_address.as_str().try_into()?,
182    }
183});
184
185try_from!(item: &protowire::RpcAcceptedTransactionIds, kaspa_rpc_core::RpcAcceptedTransactionIds, {
186    Self {
187        accepting_block_hash: RpcHash::from_str(&item.accepting_block_hash)?,
188        accepted_transaction_ids: item.accepted_transaction_ids.iter().map(|x| RpcHash::from_str(x)).collect::<Result<Vec<_>, _>>()?,
189    }
190});
191
192try_from!(item: &protowire::RpcUtxosByAddressesEntry, kaspa_rpc_core::RpcUtxosByAddressesEntry, {
193    let address = if item.address.is_empty() { None } else { Some(item.address.as_str().try_into()?) };
194    Self {
195        address,
196        outpoint: item
197            .outpoint
198            .as_ref()
199            .ok_or_else(|| RpcError::MissingRpcFieldError("UtxosByAddressesEntry".to_string(), "outpoint".to_string()))?
200            .try_into()?,
201        utxo_entry: item
202            .utxo_entry
203            .as_ref()
204            .ok_or_else(|| RpcError::MissingRpcFieldError("UtxosByAddressesEntry".to_string(), "utxo_entry".to_string()))?
205            .try_into()?,
206    }
207});