kaspa_consensus_client/
output.rs

1//!
2//! Implementation of the client-side [`TransactionOutput`] used by the [`Transaction`] struct.
3//!
4
5#![allow(non_snake_case)]
6
7use crate::imports::*;
8
9#[wasm_bindgen(typescript_custom_section)]
10const TS_TRANSACTION_OUTPUT: &'static str = r#"
11/**
12 * Interface defining the structure of a transaction output.
13 * 
14 * @category Consensus
15 */
16export interface ITransactionOutput {
17    value: bigint;
18    scriptPublicKey: IScriptPublicKey | HexString;
19
20    /** Optional verbose data provided by RPC */
21    verboseData?: ITransactionOutputVerboseData;
22}
23
24/**
25 * TransactionOutput verbose data.
26 * 
27 * @category Node RPC
28 */
29export interface ITransactionOutputVerboseData {
30    scriptPublicKeyType : string;
31    scriptPublicKeyAddress : string;
32}
33"#;
34
35#[wasm_bindgen]
36extern "C" {
37    /// WASM (TypeScript) type representing `ITransactionOutput | TransactionOutput`
38    /// @category Consensus
39    #[wasm_bindgen(typescript_type = "ITransactionOutput | TransactionOutput")]
40    pub type TransactionOutputT;
41    /// WASM (TypeScript) type representing `ITransactionOutput[] | TransactionOutput[]`
42    /// @category Consensus
43    #[wasm_bindgen(typescript_type = "(ITransactionOutput | TransactionOutput)[]")]
44    pub type TransactionOutputArrayAsArgT;
45    /// WASM (TypeScript) type representing `TransactionOutput[]`
46    /// @category Consensus
47    #[wasm_bindgen(typescript_type = "TransactionOutput[]")]
48    pub type TransactionOutputArrayAsResultT;
49}
50
51/// Inner type used by [`TransactionOutput`]
52#[derive(Debug, Clone, Serialize, Deserialize)]
53#[serde(rename_all = "camelCase")]
54pub struct TransactionOutputInner {
55    pub value: u64,
56    pub script_public_key: ScriptPublicKey,
57}
58
59/// Represents a Kaspad transaction output
60/// @category Consensus
61#[derive(Clone, Debug, Serialize, Deserialize, CastFromJs)]
62#[serde(rename_all = "camelCase")]
63#[wasm_bindgen(inspectable)]
64pub struct TransactionOutput {
65    inner: Arc<Mutex<TransactionOutputInner>>,
66}
67
68impl TransactionOutput {
69    pub fn new(value: u64, script_public_key: ScriptPublicKey) -> TransactionOutput {
70        Self { inner: Arc::new(Mutex::new(TransactionOutputInner { value, script_public_key })) }
71    }
72
73    pub fn new_with_inner(inner: TransactionOutputInner) -> Self {
74        Self { inner: Arc::new(Mutex::new(inner)) }
75    }
76
77    pub fn inner(&self) -> MutexGuard<'_, TransactionOutputInner> {
78        self.inner.lock().unwrap()
79    }
80
81    pub fn script_public_key_length(&self) -> usize {
82        self.inner().script_public_key.script().len()
83    }
84}
85
86#[wasm_bindgen]
87impl TransactionOutput {
88    #[wasm_bindgen(constructor)]
89    /// TransactionOutput constructor
90    pub fn ctor(value: u64, script_public_key: &ScriptPublicKey) -> TransactionOutput {
91        Self { inner: Arc::new(Mutex::new(TransactionOutputInner { value, script_public_key: script_public_key.clone() })) }
92    }
93
94    #[wasm_bindgen(getter, js_name = value)]
95    pub fn value(&self) -> u64 {
96        self.inner().value
97    }
98
99    #[wasm_bindgen(setter, js_name = value)]
100    pub fn set_value(&self, v: u64) {
101        self.inner().value = v;
102    }
103
104    #[wasm_bindgen(getter, js_name = scriptPublicKey)]
105    pub fn get_script_public_key(&self) -> ScriptPublicKey {
106        self.inner().script_public_key.clone()
107    }
108
109    #[wasm_bindgen(setter, js_name = scriptPublicKey)]
110    pub fn set_script_public_key(&self, v: &ScriptPublicKey) {
111        self.inner().script_public_key = v.clone();
112    }
113}
114
115impl AsRef<TransactionOutput> for TransactionOutput {
116    fn as_ref(&self) -> &TransactionOutput {
117        self
118    }
119}
120
121impl From<cctx::TransactionOutput> for TransactionOutput {
122    fn from(output: cctx::TransactionOutput) -> Self {
123        TransactionOutput::new(output.value, output.script_public_key)
124    }
125}
126
127impl From<&cctx::TransactionOutput> for TransactionOutput {
128    fn from(output: &cctx::TransactionOutput) -> Self {
129        TransactionOutput::new(output.value, output.script_public_key.clone())
130    }
131}
132
133impl From<&TransactionOutput> for cctx::TransactionOutput {
134    fn from(output: &TransactionOutput) -> Self {
135        let inner = output.inner();
136        cctx::TransactionOutput::new(inner.value, inner.script_public_key.clone())
137    }
138}
139
140impl TryCastFromJs for TransactionOutput {
141    type Error = Error;
142    fn try_cast_from<'a, R>(value: &'a R) -> std::result::Result<Cast<Self>, Self::Error>
143    where
144        R: AsRef<JsValue> + 'a,
145    {
146        Self::resolve_cast(value, || {
147            if let Some(object) = Object::try_from(value.as_ref()) {
148                let value = object.get_u64("value")?;
149                let script_public_key = ScriptPublicKey::try_owned_from(object.get_value("scriptPublicKey")?)?;
150                Ok(TransactionOutput::new(value, script_public_key).into())
151            } else {
152                Err("TransactionInput must be an object".into())
153            }
154        })
155    }
156}