testnumbat_wasm/types/interaction/
contract_deploy.rs

1use crate::{
2    api::SendApi,
3    types::{BigUint, CodeMetadata, ManagedAddress, ManagedBuffer, ManagedVec},
4    ContractCallArg,
5};
6
7use super::ManagedArgBuffer;
8
9/// Using max u64 to represent maximum possible gas,
10/// so that the value zero is not reserved and can be specified explicitly.
11/// Leaving the gas limit unspecified will replace it with `api.get_gas_left()`.
12const UNSPECIFIED_GAS_LIMIT: u64 = u64::MAX;
13
14#[must_use]
15pub struct ContractDeploy<SA>
16where
17    SA: SendApi + 'static,
18{
19    api: SA,
20    to: ManagedAddress<SA>, // only used for Upgrade, ignored for Deploy
21    rewa_payment: BigUint<SA>,
22    explicit_gas_limit: u64,
23    arg_buffer: ManagedArgBuffer<SA>,
24}
25
26/// Syntactical sugar to help macros to generate code easier.
27/// Unlike calling `ContractDeploy::<SA>::new`, here types can be inferred from the context.
28pub fn new_contract_deploy<SA>(api: SA, to: ManagedAddress<SA>) -> ContractDeploy<SA>
29where
30    SA: SendApi + 'static,
31{
32    let mut contract_deploy = ContractDeploy::<SA>::new(api);
33    contract_deploy.to = to;
34    contract_deploy
35}
36
37impl<SA> ContractDeploy<SA>
38where
39    SA: SendApi + 'static,
40{
41    pub fn new(api: SA) -> Self {
42        let zero = BigUint::zero(api.clone());
43        let zero_address = ManagedAddress::zero(api.clone());
44        let arg_buffer = ManagedArgBuffer::new_empty(api.clone());
45        ContractDeploy {
46            api,
47            to: zero_address,
48            rewa_payment: zero,
49            explicit_gas_limit: UNSPECIFIED_GAS_LIMIT,
50            arg_buffer,
51        }
52    }
53
54    pub fn with_rewa_transfer(mut self, payment_amount: BigUint<SA>) -> Self {
55        self.rewa_payment = payment_amount;
56        self
57    }
58
59    pub fn with_gas_limit(mut self, gas_limit: u64) -> Self {
60        self.explicit_gas_limit = gas_limit;
61        self
62    }
63
64    pub fn push_endpoint_arg<D: ContractCallArg>(&mut self, endpoint_arg: D) {
65        endpoint_arg.push_dyn_arg(&mut self.arg_buffer);
66    }
67
68    // pub fn get_mut_arg_buffer(&mut self) -> &mut ArgBuffer {
69    //     &mut self.arg_buffer
70    // }
71
72    // /// Provided for cases where we build the contract deploy by hand.
73    // pub fn push_argument_raw_bytes(&mut self, bytes: &[u8]) {
74    //     self.arg_buffer.push_argument_bytes(bytes);
75    // }
76
77    fn resolve_gas_limit(&self) -> u64 {
78        if self.explicit_gas_limit == UNSPECIFIED_GAS_LIMIT {
79            self.api.get_gas_left()
80        } else {
81            self.explicit_gas_limit
82        }
83    }
84}
85
86impl<SA> ContractDeploy<SA>
87where
88    SA: SendApi + 'static,
89{
90    /// Executes immediately, synchronously, and returns Some(Address) of the deployed contract.  
91    /// Will return None if the deploy fails.  
92    pub fn deploy_contract(
93        self,
94        code: &ManagedBuffer<SA>,
95        code_metadata: CodeMetadata,
96    ) -> (ManagedAddress<SA>, ManagedVec<SA, ManagedBuffer<SA>>) {
97        self.api.deploy_contract(
98            self.resolve_gas_limit(),
99            &self.rewa_payment,
100            code,
101            code_metadata,
102            &self.arg_buffer,
103        )
104    }
105
106    pub fn deploy_from_source(
107        self,
108        source_address: &ManagedAddress<SA>,
109        code_metadata: CodeMetadata,
110    ) -> (ManagedAddress<SA>, ManagedVec<SA, ManagedBuffer<SA>>) {
111        self.api.deploy_from_source_contract(
112            self.resolve_gas_limit(),
113            &self.rewa_payment,
114            source_address,
115            code_metadata,
116            &self.arg_buffer,
117        )
118    }
119
120    pub fn upgrade_contract(self, code: &ManagedBuffer<SA>, code_metadata: CodeMetadata) {
121        self.api.upgrade_contract(
122            &self.to,
123            self.resolve_gas_limit(),
124            &self.rewa_payment,
125            code,
126            code_metadata,
127            &self.arg_buffer,
128        );
129    }
130}