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