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