kaspa_consensus_client/
input.rs1#![allow(non_snake_case)]
6
7use crate::imports::*;
8use crate::result::Result;
9use crate::TransactionOutpoint;
10use crate::UtxoEntryReference;
11use kaspa_utils::hex::*;
12
13#[wasm_bindgen(typescript_custom_section)]
14const TS_TRANSACTION: &'static str = r#"
15/**
16 * Interface defines the structure of a transaction input.
17 *
18 * @category Consensus
19 */
20export interface ITransactionInput {
21 previousOutpoint: ITransactionOutpoint;
22 signatureScript?: HexString;
23 sequence: bigint;
24 sigOpCount: number;
25 utxo?: UtxoEntryReference;
26
27 /** Optional verbose data provided by RPC */
28 verboseData?: ITransactionInputVerboseData;
29}
30
31/**
32 * Option transaction input verbose data.
33 *
34 * @category Node RPC
35 */
36export interface ITransactionInputVerboseData { }
37
38"#;
39
40#[wasm_bindgen]
41extern "C" {
42 #[wasm_bindgen(typescript_type = "ITransactionInput | TransactionInput")]
45 pub type TransactionInputT;
46 #[wasm_bindgen(typescript_type = "(ITransactionInput | TransactionInput)[]")]
49 pub type TransactionInputArrayAsArgT;
50 #[wasm_bindgen(typescript_type = "TransactionInput[]")]
53 pub type TransactionInputArrayAsResultT;
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
58#[serde(rename_all = "camelCase")]
59pub struct TransactionInputInner {
60 pub previous_outpoint: TransactionOutpoint,
61 pub signature_script: Option<Vec<u8>>,
62 pub sequence: u64,
63 pub sig_op_count: u8,
64 pub utxo: Option<UtxoEntryReference>,
65}
66
67impl TransactionInputInner {
68 pub fn new(
69 previous_outpoint: TransactionOutpoint,
70 signature_script: Option<Vec<u8>>,
71 sequence: u64,
72 sig_op_count: u8,
73 utxo: Option<UtxoEntryReference>,
74 ) -> Self {
75 Self { previous_outpoint, signature_script, sequence, sig_op_count, utxo }
76 }
77}
78
79#[derive(Clone, Debug, Serialize, Deserialize, CastFromJs)]
82#[wasm_bindgen(inspectable)]
83pub struct TransactionInput {
84 inner: Arc<Mutex<TransactionInputInner>>,
85}
86
87impl TransactionInput {
88 pub fn new(
89 previous_outpoint: TransactionOutpoint,
90 signature_script: Option<Vec<u8>>,
91 sequence: u64,
92 sig_op_count: u8,
93 utxo: Option<UtxoEntryReference>,
94 ) -> Self {
95 let inner = TransactionInputInner::new(previous_outpoint, signature_script, sequence, sig_op_count, utxo);
96 Self { inner: Arc::new(Mutex::new(inner)) }
97 }
98
99 pub fn new_with_inner(inner: TransactionInputInner) -> Self {
100 Self { inner: Arc::new(Mutex::new(inner)) }
101 }
102
103 pub fn inner(&self) -> MutexGuard<'_, TransactionInputInner> {
104 self.inner.lock().unwrap()
105 }
106
107 pub fn sig_op_count(&self) -> u8 {
108 self.inner().sig_op_count
109 }
110
111 pub fn signature_script_length(&self) -> usize {
112 self.inner().signature_script.as_ref().map(|signature_script| signature_script.len()).unwrap_or_default()
113 }
114
115 pub fn utxo(&self) -> Option<UtxoEntryReference> {
116 self.inner().utxo.clone()
117 }
118}
119
120#[wasm_bindgen]
121impl TransactionInput {
122 #[wasm_bindgen(constructor)]
123 pub fn constructor(value: &TransactionInputT) -> Result<TransactionInput> {
124 Self::try_owned_from(value)
125 }
126
127 #[wasm_bindgen(getter = previousOutpoint)]
128 pub fn get_previous_outpoint(&self) -> TransactionOutpoint {
129 self.inner().previous_outpoint.clone()
130 }
131
132 #[wasm_bindgen(setter = previousOutpoint)]
133 pub fn set_previous_outpoint(&mut self, js_value: &JsValue) -> Result<()> {
134 match js_value.try_into() {
135 Ok(outpoint) => {
136 self.inner().previous_outpoint = outpoint;
137 Ok(())
138 }
139 Err(_) => Err(Error::custom("invalid outpoint script".to_string())),
140 }
141 }
142
143 #[wasm_bindgen(getter = signatureScript)]
144 pub fn get_signature_script_as_hex(&self) -> Option<String> {
145 self.inner().signature_script.as_ref().map(|script| script.to_hex())
146 }
147
148 #[wasm_bindgen(setter = signatureScript)]
149 pub fn set_signature_script_from_js_value(&mut self, js_value: JsValue) -> Result<()> {
150 match js_value.try_as_vec_u8() {
151 Ok(signature) => {
152 self.set_signature_script(signature);
153 Ok(())
154 }
155 Err(_) => Err(Error::custom("invalid signature script".to_string())),
156 }
157 }
158
159 #[wasm_bindgen(getter = sequence)]
160 pub fn get_sequence(&self) -> u64 {
161 self.inner().sequence
162 }
163
164 #[wasm_bindgen(setter = sequence)]
165 pub fn set_sequence(&mut self, sequence: u64) {
166 self.inner().sequence = sequence;
167 }
168
169 #[wasm_bindgen(getter = sigOpCount)]
170 pub fn get_sig_op_count(&self) -> u8 {
171 self.inner().sig_op_count
172 }
173
174 #[wasm_bindgen(setter = sigOpCount)]
175 pub fn set_sig_op_count(&mut self, sig_op_count: u8) {
176 self.inner().sig_op_count = sig_op_count;
177 }
178
179 #[wasm_bindgen(getter = utxo)]
180 pub fn get_utxo(&self) -> Option<UtxoEntryReference> {
181 self.inner().utxo.clone()
182 }
183}
184
185impl TransactionInput {
186 pub fn set_signature_script(&self, signature_script: Vec<u8>) {
187 self.inner().signature_script.replace(signature_script);
188 }
189
190 pub fn script_public_key(&self) -> Option<ScriptPublicKey> {
191 self.utxo().map(|utxo_ref| utxo_ref.utxo.script_public_key.clone())
192 }
193}
194
195impl AsRef<TransactionInput> for TransactionInput {
196 fn as_ref(&self) -> &TransactionInput {
197 self
198 }
199}
200
201impl TryCastFromJs for TransactionInput {
202 type Error = Error;
203 fn try_cast_from<'a, R>(value: &'a R) -> std::result::Result<Cast<Self>, Self::Error>
204 where
205 R: AsRef<JsValue> + 'a,
206 {
207 Self::resolve_cast(value, || {
208 if let Some(object) = Object::try_from(value.as_ref()) {
209 let previous_outpoint: TransactionOutpoint = object.get_value("previousOutpoint")?.as_ref().try_into()?;
210 let signature_script = object.get_vec_u8("signatureScript").ok();
211 let sequence = object.get_u64("sequence")?;
212 let sig_op_count = object.get_u8("sigOpCount")?;
213 let utxo = object.try_cast_into::<UtxoEntryReference>("utxo")?;
214 Ok(TransactionInput::new(previous_outpoint, signature_script, sequence, sig_op_count, utxo).into())
215 } else {
216 Err("TransactionInput must be an object".into())
217 }
218 })
219 }
220}
221
222impl From<cctx::TransactionInput> for TransactionInput {
223 fn from(tx_input: cctx::TransactionInput) -> Self {
224 TransactionInput::new(
225 tx_input.previous_outpoint.into(),
226 Some(tx_input.signature_script),
227 tx_input.sequence,
228 tx_input.sig_op_count,
229 None,
230 )
231 }
232}
233
234impl From<&TransactionInput> for cctx::TransactionInput {
235 fn from(tx_input: &TransactionInput) -> Self {
236 let inner = tx_input.inner();
237 cctx::TransactionInput::new(
238 inner.previous_outpoint.clone().into(),
239 inner.signature_script.clone().unwrap_or_default(),
241 inner.sequence,
242 inner.sig_op_count,
243 )
244 }
245}