1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
use std::marker::PhantomData;

use ink_primitives::AccountId;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum TxStatus {
    #[default]
    Finalized,
    InBlock,
    Submitted,
}

/// Represents a call to a contract constructor.
#[derive(Debug, Clone)]
pub struct InstantiateCall<T: Send> {
    /// The code hash of the contract to instantiate.
    pub code_hash: [u8; 32],
    /// The encoded data of the call.
    pub data: Vec<u8>,
    /// The salt to use for the contract.
    pub salt: Vec<u8>,
    /// The value to be sent with the call.
    pub value: u128,
    /// The tx_status to wait on.
    pub tx_status: TxStatus,
    /// A marker for the type of contract to instantiate.
    _contract: PhantomData<T>,
}

impl<T: Send> InstantiateCall<T> {
    /// Create a new instantiate call.
    pub fn new(code_hash: [u8; 32], data: Vec<u8>) -> Self {
        Self {
            code_hash,
            data,
            salt: vec![],
            value: 0,
            tx_status: Default::default(),
            _contract: Default::default(),
        }
    }

    /// Set the salt to use for the instantiation.
    pub fn with_salt(mut self, salt: Vec<u8>) -> Self {
        self.salt = salt;
        self
    }

    /// Set the tx_status to wait on.
    pub fn with_tx_status(mut self, tx_status: TxStatus) -> Self {
        self.tx_status = tx_status;
        self
    }
}

/// Represents a contract call to a payable constructor that still needs the value transferred to be specified.
/// Use the `with_value()` method to set the value.
#[derive(Debug, Clone)]
pub struct InstantiateCallNeedsValue<T: Send> {
    /// The code hash of the contract to instantiate.
    pub code_hash: [u8; 32],
    /// The encoded data of the call.
    pub data: Vec<u8>,
    /// A marker for the type of contract to instantiate.
    _contract: PhantomData<T>,
}

impl<T: Send> InstantiateCallNeedsValue<T> {
    pub fn new(code_hash: [u8; 32], data: Vec<u8>) -> Self {
        Self {
            code_hash,
            data,
            _contract: Default::default(),
        }
    }

    pub fn with_value(self, value: u128) -> InstantiateCall<T> {
        InstantiateCall {
            value,
            ..InstantiateCall::new(self.code_hash, self.data)
        }
    }
}

/// Represents a mutating contract call to be made.
#[derive(Debug, Clone)]
pub struct ExecCall {
    /// The account id of the contract to call.
    pub account_id: AccountId,
    /// The encoded data of the call.
    pub data: Vec<u8>,
    /// The value to be sent with the call.
    pub value: u128,
    /// The tx_status to wait on.
    pub tx_status: TxStatus,
}

impl ExecCall {
    /// Create a new exec call.
    pub fn new(account_id: AccountId, data: Vec<u8>) -> Self {
        Self {
            account_id,
            data,
            value: 0,
            tx_status: Default::default(),
        }
    }

    pub fn with_tx_status(mut self, tx_status: TxStatus) -> Self {
        self.tx_status = tx_status;
        self
    }
}

/// Reperesents a contract call to a payable method that still needs the value transferred to be specified.
/// Use the `with_value()` method to set the value.
#[derive(Debug, Clone)]
pub struct ExecCallNeedsValue {
    /// The account id of the contract to call.
    pub account_id: AccountId,
    /// The encoded data of the call.
    pub data: Vec<u8>,
}

impl ExecCallNeedsValue {
    /// Create a new needs value call.
    pub fn new(account_id: AccountId, data: Vec<u8>) -> Self {
        Self { account_id, data }
    }

    /// Set the value to be sent with the call.
    pub fn with_value(self, value: u128) -> ExecCall {
        ExecCall {
            value,
            ..ExecCall::new(self.account_id, self.data)
        }
    }
}

/// Represents a read-only contract call to be made.
#[derive(Debug, Clone)]
pub struct ReadCall<T: scale::Decode + Send> {
    /// The account id of the contract to call.
    pub account_id: AccountId,
    /// The encoded data of the call.
    pub data: Vec<u8>,
    /// A marker for the type to decode the result into.
    _return_type: PhantomData<T>,
}

impl<T: scale::Decode + Send> ReadCall<T> {
    /// Create a new read call.
    pub fn new(account_id: AccountId, data: Vec<u8>) -> Self {
        Self {
            account_id,
            data,
            _return_type: Default::default(),
        }
    }
}

/// Represents a call to upload a contract.
pub struct UploadCall {
    /// The WASM code to upload.
    pub wasm: Vec<u8>,
    /// The expected code hash of the uploaded code.
    pub expected_code_hash: [u8; 32],
    /// The tx_status to wait on.
    pub tx_status: TxStatus,
}

impl UploadCall {
    /// Create a new upload call.
    pub fn new(wasm: Vec<u8>, expected_code_hash: [u8; 32]) -> Self {
        Self {
            wasm,
            expected_code_hash,
            tx_status: Default::default(),
        }
    }

    /// Set the tx_status to wait on.
    pub fn with_tx_status(mut self, tx_status: TxStatus) -> Self {
        self.tx_status = tx_status;
        self
    }
}