whisky/builder/tx_in.rs
1use super::{TxBuilder, WData, WRedeemer};
2
3use crate::*;
4
5impl TxBuilder {
6 /// ## Transaction building method
7 ///
8 /// Indicate that the transaction is spending a Plutus script in the TxBuilder instance
9 ///
10 /// ### Arguments
11 ///
12 /// * `language_version` - The language version of the script
13 ///
14 /// ### Returns
15 ///
16 /// * `Self` - The TxBuilder instance
17 pub fn spending_plutus_script(&mut self, language_version: &LanguageVersion) -> &mut Self {
18 match language_version {
19 LanguageVersion::V1 => self.spending_plutus_script_v1(),
20 LanguageVersion::V2 => self.spending_plutus_script_v2(),
21 LanguageVersion::V3 => self.spending_plutus_script_v3(),
22 }
23 }
24
25 /// ## Transaction building method
26 ///
27 /// Indicate that the transaction is spending a Plutus script v1 in the TxBuilder instance
28 ///
29 /// ### Returns
30 ///
31 /// * `Self` - The TxBuilder instance
32 pub fn spending_plutus_script_v1(&mut self) -> &mut Self {
33 self.adding_script_input = Some(LanguageVersion::V1);
34 self
35 }
36 /// ## Transaction building method
37 ///
38 /// Indicate that the transaction is spending a Plutus script v2 in the TxBuilder instance
39 ///
40 /// ### Returns
41 ///
42 /// * `Self` - The TxBuilder instance
43 pub fn spending_plutus_script_v2(&mut self) -> &mut Self {
44 self.adding_script_input = Some(LanguageVersion::V2);
45 self
46 }
47 /// ## Transaction building method
48 ///
49 /// Indicate that the transaction is spending a Plutus script v3 in the TxBuilder instance
50 ///
51 /// ### Returns
52 ///
53 /// * `Self` - The TxBuilder instance
54 pub fn spending_plutus_script_v3(&mut self) -> &mut Self {
55 self.adding_script_input = Some(LanguageVersion::V3);
56 self
57 }
58
59 /// ## Transaction building method
60 ///
61 /// Add a transaction input to the TxBuilder instance
62 ///
63 /// ### Arguments
64 ///
65 /// * `tx_hash` - The transaction hash
66 /// * `tx_index` - The transaction index
67 /// * `amount` - The amount of assets
68 /// * `address` - The address
69 ///
70 /// ### Returns
71 ///
72 /// * `Self` - The TxBuilder instance
73 pub fn tx_in(
74 &mut self,
75 tx_hash: &str,
76 tx_index: u32,
77 amount: &[Asset],
78 address: &str,
79 ) -> &mut Self {
80 if self.tx_in_item.is_some() {
81 self.queue_input();
82 }
83 match self.adding_script_input {
84 Some(_) => {
85 let item = TxIn::ScriptTxIn(ScriptTxIn {
86 tx_in: TxInParameter {
87 tx_hash: tx_hash.to_string(),
88 tx_index,
89 amount: Some(amount.to_vec()),
90 address: Some(address.to_string()),
91 },
92 script_tx_in: ScriptTxInParameter {
93 script_source: None,
94 datum_source: None,
95 redeemer: None,
96 },
97 });
98 self.tx_in_item = Some(item);
99 }
100 None => {
101 let item = TxIn::PubKeyTxIn(PubKeyTxIn {
102 tx_in: TxInParameter {
103 tx_hash: tx_hash.to_string(),
104 tx_index,
105 amount: Some(amount.to_vec()),
106 address: Some(address.to_string()),
107 },
108 });
109 self.tx_in_item = Some(item);
110 }
111 }
112 self
113 }
114
115 /// ## Transaction building method
116 ///
117 /// Add a transaction input script to the TxBuilder instance
118 ///
119 /// ### Arguments
120 ///
121 /// * `script_cbor` - The script in CBOR format
122 /// * `version` - The language version, leave as None for Native scripts
123 ///
124 /// ### Returns
125 ///
126 /// * `Self` - The TxBuilder instance
127 pub fn tx_in_script(&mut self, script_cbor: &str) -> &mut Self {
128 let tx_in_item = self.tx_in_item.take();
129 if tx_in_item.is_none() {
130 panic!("Undefined input")
131 }
132 let tx_in_item = tx_in_item.unwrap();
133 match tx_in_item {
134 TxIn::PubKeyTxIn(input) => {
135 self.tx_in_item = Some(TxIn::SimpleScriptTxIn(SimpleScriptTxIn {
136 tx_in: input.tx_in,
137 simple_script_tx_in: SimpleScriptTxInParameter::ProvidedSimpleScriptSource(
138 ProvidedSimpleScriptSource {
139 script_cbor: script_cbor.to_string(),
140 },
141 ),
142 }))
143 }
144 TxIn::ScriptTxIn(mut input) => {
145 input.script_tx_in.script_source =
146 Some(ScriptSource::ProvidedScriptSource(ProvidedScriptSource {
147 script_cbor: script_cbor.to_string(),
148 language_version: self
149 .adding_script_input
150 .clone()
151 .expect("Plutus script must have version specified"),
152 }));
153 self.adding_script_input = None;
154 self.tx_in_item = Some(TxIn::ScriptTxIn(input));
155 }
156
157 // Technically this should be unreachable, but it's here for completeness
158 TxIn::SimpleScriptTxIn(mut input) => {
159 input.simple_script_tx_in = SimpleScriptTxInParameter::ProvidedSimpleScriptSource(
160 ProvidedSimpleScriptSource {
161 script_cbor: script_cbor.to_string(),
162 },
163 );
164 self.tx_in_item = Some(TxIn::SimpleScriptTxIn(input));
165 }
166 }
167 self
168 }
169
170 /// ## Transaction building method
171 ///
172 /// Set the transaction input datum value in the TxBuilder instance
173 ///
174 /// ### Arguments
175 ///
176 /// * `data` - The datum value
177 ///
178 /// ### Returns
179 ///
180 /// * `Self` - The TxBuilder instance
181 pub fn tx_in_datum_value(&mut self, data: &WData) -> &mut Self {
182 let tx_in_item = self.tx_in_item.take();
183 if tx_in_item.is_none() {
184 panic!("Undefined input")
185 }
186 let tx_in_item = tx_in_item.unwrap();
187 match tx_in_item {
188 TxIn::PubKeyTxIn(_) => panic!("Datum cannot be defined for a pubkey tx in"),
189 TxIn::SimpleScriptTxIn(_) => {
190 panic!("Datum cannot be defined for a simple script tx in")
191 }
192 TxIn::ScriptTxIn(mut input) => match data.to_cbor() {
193 Ok(raw_data) => {
194 input.script_tx_in.datum_source =
195 Some(DatumSource::ProvidedDatumSource(ProvidedDatumSource {
196 data: raw_data.to_string(),
197 }));
198 self.tx_in_item = Some(TxIn::ScriptTxIn(input));
199 }
200 Err(_) => {
201 panic!("Error converting datum to CBOR");
202 }
203 },
204 }
205 self
206 }
207
208 /// ## Transaction building method
209 ///
210 /// Indicate that the transaction input has an inline datum in the TxBuilder instance
211 ///
212 /// ### Returns
213 ///
214 /// * `Self` - The TxBuilder instance
215 pub fn tx_in_inline_datum_present(&mut self) -> &mut Self {
216 let tx_in_item = self.tx_in_item.take();
217 if tx_in_item.is_none() {
218 panic!("Undefined input")
219 }
220 let tx_in_item = tx_in_item.unwrap();
221 match tx_in_item {
222 TxIn::PubKeyTxIn(_) => panic!("Datum cannot be defined for a pubkey tx in"),
223 TxIn::SimpleScriptTxIn(_) => {
224 panic!("Datum cannot be defined for a simple script tx in")
225 }
226 TxIn::ScriptTxIn(mut input) => {
227 input.script_tx_in.datum_source =
228 Some(DatumSource::InlineDatumSource(InlineDatumSource {
229 tx_hash: input.tx_in.tx_hash.clone(),
230 tx_index: input.tx_in.tx_index,
231 }));
232 self.tx_in_item = Some(TxIn::ScriptTxIn(input));
233 }
234 }
235 self
236 }
237
238 /// ## Transaction building method
239 ///
240 /// Set the transaction input redeemer value in the TxBuilder instance
241 ///
242 /// ### Arguments
243 ///
244 /// * `redeemer` - The redeemer value
245 ///
246 /// ### Returns
247 ///
248 /// * `Self` - The TxBuilder instance
249 pub fn tx_in_redeemer_value(&mut self, redeemer: &WRedeemer) -> &mut Self {
250 let tx_in_item = self.tx_in_item.take();
251 if tx_in_item.is_none() {
252 panic!("Undefined input")
253 }
254 let tx_in_item = tx_in_item.unwrap();
255 match tx_in_item {
256 TxIn::PubKeyTxIn(_) => panic!("Redeemer cannot be defined for a pubkey tx in"),
257 TxIn::SimpleScriptTxIn(_) => {
258 panic!("Redeemer cannot be defined for a simple script tx in")
259 }
260 TxIn::ScriptTxIn(mut input) => match redeemer.data.to_cbor() {
261 Ok(raw_redeemer) => {
262 input.script_tx_in.redeemer = Some(Redeemer {
263 data: raw_redeemer,
264 ex_units: redeemer.clone().ex_units,
265 });
266 self.tx_in_item = Some(TxIn::ScriptTxIn(input));
267 }
268 Err(_) => {
269 panic!("Error converting redeemer to CBOR");
270 }
271 },
272 }
273 self
274 }
275
276 /// ## Transaction building method
277 ///
278 /// Add a spending transaction input reference to the TxBuilder instance
279 ///
280 /// ### Arguments
281 ///
282 /// * `tx_hash` - The transaction hash
283 /// * `tx_index` - The transaction index
284 /// * `script_hash` - The spending script hash
285 /// * `script_size` - Size of the script
286 ///
287 /// ### Returns
288 ///
289 /// * `Self` - The TxBuilder instance
290 pub fn spending_tx_in_reference(
291 &mut self,
292 tx_hash: &str,
293 tx_index: u32,
294 script_hash: &str,
295 script_size: usize,
296 ) -> &mut Self {
297 let tx_in_item = self.tx_in_item.take();
298 if tx_in_item.is_none() {
299 panic!("Undefined output")
300 }
301 let tx_in_item = tx_in_item.unwrap();
302 match tx_in_item {
303 TxIn::PubKeyTxIn(_) => panic!("Script reference cannot be defined for a pubkey tx in"),
304 TxIn::SimpleScriptTxIn(_) => {
305 panic!("Script reference cannot be defined for a simple script tx in")
306 }
307 TxIn::ScriptTxIn(mut input) => {
308 input.script_tx_in.script_source =
309 Some(ScriptSource::InlineScriptSource(InlineScriptSource {
310 ref_tx_in: RefTxIn {
311 tx_hash: tx_hash.to_string(),
312 tx_index,
313 // Script size is already accounted for in script source
314 script_size: None,
315 },
316 script_hash: script_hash.to_string(),
317 language_version: self
318 .adding_script_input
319 .clone()
320 .expect("Plutus script must have version specified"),
321 script_size,
322 }));
323 self.tx_in_item = Some(TxIn::ScriptTxIn(input));
324 }
325 }
326 self
327 }
328
329 /// ## Transaction building method
330 ///
331 /// Indicate that the spending reference transaction input has an inline datum in the TxBuilder instance
332 ///
333 /// ### Returns
334 ///
335 /// * `Self` - The TxBuilder instance
336 pub fn spending_reference_tx_in_inline_datum_present(&mut self) -> &mut Self {
337 self.tx_in_inline_datum_present()
338 }
339
340 /// ## Transaction building method
341 ///
342 /// Set the spending reference transaction input redeemer value in the TxBuilder instance
343 ///
344 /// ### Arguments
345 ///
346 /// * `redeemer` - The redeemer value
347 ///
348 /// ### Returns
349 ///
350 /// * `Self` - The TxBuilder instance
351 pub fn spending_reference_tx_in_redeemer_value(&mut self, redeemer: &WRedeemer) -> &mut Self {
352 self.tx_in_redeemer_value(redeemer)
353 }
354
355 /// ## Transaction building method
356 ///
357 /// Add a read-only transaction input reference to the TxBuilder instance
358 ///
359 /// ### Arguments
360 ///
361 /// * `tx_hash` - The transaction hash
362 /// * `tx_index` - The transaction index
363 /// * `script_size` - The size of the script contained at the reference input (None if it doesn't contain a script)
364 ///
365 /// ### Returns
366 ///
367 /// * `Self` - The TxBuilder instance
368 pub fn read_only_tx_in_reference(
369 &mut self,
370 tx_hash: &str,
371 tx_index: u32,
372 script_size: Option<usize>,
373 ) -> &mut Self {
374 self.tx_builder_body.reference_inputs.push(RefTxIn {
375 tx_hash: tx_hash.to_string(),
376 tx_index,
377 script_size,
378 });
379 self
380 }
381
382 /// ## Transaction building method
383 ///
384 /// Add a transaction input collateral to the TxBuilder instance
385 ///
386 /// ### Arguments
387 ///
388 /// * `tx_hash` - The transaction hash
389 /// * `tx_index` - The transaction index
390 /// * `amount` - The amount of assets
391 /// * `address` - The address
392 ///
393 /// ### Returns
394 ///
395 /// * `Self` - The TxBuilder instance
396 pub fn tx_in_collateral(
397 &mut self,
398 tx_hash: &str,
399 tx_index: u32,
400 amount: &[Asset],
401 address: &str,
402 ) -> &mut Self {
403 let collateral_item = self.collateral_item.take();
404 if let Some(collateral_item) = collateral_item {
405 self.tx_builder_body.collaterals.push(collateral_item);
406 }
407 self.collateral_item = Some(PubKeyTxIn {
408 tx_in: TxInParameter {
409 tx_hash: tx_hash.to_string(),
410 tx_index,
411 amount: Some(amount.to_vec()),
412 address: Some(address.to_string()),
413 },
414 });
415 self
416 }
417}