fuels_accounts/
predicate.rs1use std::{fmt::Debug, fs};
2
3#[cfg(feature = "std")]
4use fuels_core::types::{AssetId, coin_type_id::CoinTypeId, input::Input};
5use fuels_core::{
6 Configurables, error,
7 types::{bech32::Bech32Address, errors::Result},
8};
9
10#[cfg(feature = "std")]
11use crate::accounts_utils::try_provider_error;
12#[cfg(feature = "std")]
13use crate::{Account, ViewOnlyAccount, provider::Provider};
14
15#[derive(Debug, Clone)]
16pub struct Predicate {
17 address: Bech32Address,
18 code: Vec<u8>,
19 data: Vec<u8>,
20 #[cfg(feature = "std")]
21 provider: Option<Provider>,
22}
23
24impl Predicate {
25 pub fn address(&self) -> &Bech32Address {
26 &self.address
27 }
28
29 pub fn code(&self) -> &[u8] {
30 &self.code
31 }
32
33 pub fn data(&self) -> &[u8] {
34 &self.data
35 }
36
37 pub fn calculate_address(code: &[u8]) -> Bech32Address {
38 fuel_tx::Input::predicate_owner(code).into()
39 }
40
41 pub fn load_from(file_path: &str) -> Result<Self> {
42 let code = fs::read(file_path).map_err(|e| {
43 error!(
44 IO,
45 "could not read predicate binary {file_path:?}. Reason: {e}"
46 )
47 })?;
48 Ok(Self::from_code(code))
49 }
50
51 pub fn from_code(code: Vec<u8>) -> Self {
52 Self {
53 address: Self::calculate_address(&code),
54 code,
55 data: Default::default(),
56 #[cfg(feature = "std")]
57 provider: None,
58 }
59 }
60
61 pub fn with_data(mut self, data: Vec<u8>) -> Self {
62 self.data = data;
63 self
64 }
65
66 pub fn with_code(self, code: Vec<u8>) -> Self {
67 let address = Self::calculate_address(&code);
68 Self {
69 code,
70 address,
71 ..self
72 }
73 }
74
75 pub fn with_configurables(mut self, configurables: impl Into<Configurables>) -> Self {
76 let configurables: Configurables = configurables.into();
77 configurables.update_constants_in(&mut self.code);
78 let address = Self::calculate_address(&self.code);
79 self.address = address;
80 self
81 }
82}
83
84#[cfg(feature = "std")]
85impl Predicate {
86 pub fn provider(&self) -> Option<&Provider> {
87 self.provider.as_ref()
88 }
89
90 pub fn set_provider(&mut self, provider: Provider) {
91 self.provider = Some(provider);
92 }
93
94 pub fn with_provider(self, provider: Provider) -> Self {
95 Self {
96 provider: Some(provider),
97 ..self
98 }
99 }
100}
101
102#[cfg(feature = "std")]
103#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
104impl ViewOnlyAccount for Predicate {
105 fn address(&self) -> &Bech32Address {
106 self.address()
107 }
108
109 fn try_provider(&self) -> Result<&Provider> {
110 self.provider.as_ref().ok_or_else(try_provider_error)
111 }
112
113 async fn get_asset_inputs_for_amount(
114 &self,
115 asset_id: AssetId,
116 amount: u128,
117 excluded_coins: Option<Vec<CoinTypeId>>,
118 ) -> Result<Vec<Input>> {
119 Ok(self
120 .get_spendable_resources(asset_id, amount, excluded_coins)
121 .await?
122 .into_iter()
123 .map(|resource| {
124 Input::resource_predicate(resource, self.code.clone(), self.data.clone())
125 })
126 .collect::<Vec<Input>>())
127 }
128}
129
130#[cfg(feature = "std")]
131impl Account for Predicate {}