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