fuels_programs/calls/
contract_call.rs1use std::{collections::HashMap, fmt::Debug};
2
3use fuels_core::{
4 constants::DEFAULT_CALL_PARAMS_AMOUNT,
5 error,
6 types::{
7 Address, AssetId, ContractId, Selector, errors::Result, input::Input, output::Output,
8 param_types::ParamType,
9 },
10};
11
12use crate::{assembly::contract_call::ContractCallData, calls::utils::sealed};
13
14#[derive(Debug, Clone)]
15pub struct ContractCall {
17 pub contract_id: ContractId,
18 pub encoded_args: Result<Vec<u8>>,
19 pub encoded_selector: Selector,
20 pub call_parameters: CallParameters,
21 pub external_contracts: Vec<ContractId>,
22 pub output_param: ParamType,
23 pub is_payable: bool,
24 pub custom_assets: HashMap<(AssetId, Option<Address>), u64>,
25 pub inputs: Vec<Input>,
26 pub outputs: Vec<Output>,
27}
28
29impl ContractCall {
30 pub(crate) fn data(&self, base_asset_id: AssetId) -> Result<ContractCallData> {
31 let encoded_args = self
32 .encoded_args
33 .as_ref()
34 .map_err(|e| error!(Codec, "cannot encode contract call arguments: {e}"))?
35 .to_owned();
36
37 Ok(ContractCallData {
38 amount: self.call_parameters.amount(),
39 asset_id: self.call_parameters.asset_id().unwrap_or(base_asset_id),
40 contract_id: self.contract_id,
41 fn_selector_encoded: self.encoded_selector.clone(),
42 encoded_args,
43 gas_forwarded: self.call_parameters.gas_forwarded,
44 })
45 }
46
47 pub fn with_contract_id(self, contract_id: ContractId) -> Self {
48 ContractCall {
49 contract_id,
50 ..self
51 }
52 }
53
54 pub fn with_call_parameters(self, call_parameters: CallParameters) -> ContractCall {
55 ContractCall {
56 call_parameters,
57 ..self
58 }
59 }
60
61 pub fn add_custom_asset(&mut self, asset_id: AssetId, amount: u64, to: Option<Address>) {
62 *self.custom_assets.entry((asset_id, to)).or_default() += amount;
63 }
64
65 pub fn with_outputs(mut self, outputs: Vec<Output>) -> Self {
67 self.outputs = outputs;
68 self
69 }
70
71 pub fn with_inputs(mut self, inputs: Vec<Input>) -> Self {
73 self.inputs = inputs;
74 self
75 }
76}
77
78impl sealed::Sealed for ContractCall {}
79
80#[derive(Debug, Clone)]
81pub struct CallParameters {
82 amount: u64,
83 asset_id: Option<AssetId>,
84 gas_forwarded: Option<u64>,
85}
86
87impl CallParameters {
88 pub fn new(amount: u64, asset_id: AssetId, gas_forwarded: u64) -> Self {
89 Self {
90 amount,
91 asset_id: Some(asset_id),
92 gas_forwarded: Some(gas_forwarded),
93 }
94 }
95
96 pub fn with_amount(mut self, amount: u64) -> Self {
97 self.amount = amount;
98 self
99 }
100
101 pub fn amount(&self) -> u64 {
102 self.amount
103 }
104
105 pub fn with_asset_id(mut self, asset_id: AssetId) -> Self {
106 self.asset_id = Some(asset_id);
107 self
108 }
109
110 pub fn asset_id(&self) -> Option<AssetId> {
111 self.asset_id
112 }
113
114 pub fn with_gas_forwarded(mut self, gas_forwarded: u64) -> Self {
115 self.gas_forwarded = Some(gas_forwarded);
116 self
117 }
118
119 pub fn gas_forwarded(&self) -> Option<u64> {
120 self.gas_forwarded
121 }
122}
123
124impl Default for CallParameters {
125 fn default() -> Self {
126 Self {
127 amount: DEFAULT_CALL_PARAMS_AMOUNT,
128 asset_id: None,
129 gas_forwarded: None,
130 }
131 }
132}