1pub mod delegate;
2
3use borsh::{BorshDeserialize, BorshSerialize};
4use serde_with::base64::Base64;
5use serde_with::serde_as;
6use std::fmt;
7use unc_crypto::PublicKey;
8use unc_primitives_core::{
9 account::AccessKey,
10 serialize::dec_format,
11 types::{AccountId, Balance, Gas},
12};
13
14fn base64(s: &[u8]) -> String {
15 use base64::Engine;
16 base64::engine::general_purpose::STANDARD.encode(s)
17}
18
19#[derive(
20 BorshSerialize,
21 BorshDeserialize,
22 PartialEq,
23 Eq,
24 Clone,
25 Debug,
26 serde::Serialize,
27 serde::Deserialize,
28)]
29pub struct AddKeyAction {
30 pub public_key: PublicKey,
32 pub access_key: AccessKey,
34}
35
36#[derive(
38 BorshSerialize,
39 BorshDeserialize,
40 PartialEq,
41 Eq,
42 Clone,
43 Debug,
44 serde::Serialize,
45 serde::Deserialize,
46)]
47pub struct CreateAccountAction {}
48
49#[derive(
50 BorshSerialize,
51 BorshDeserialize,
52 PartialEq,
53 Eq,
54 Clone,
55 Debug,
56 serde::Serialize,
57 serde::Deserialize,
58)]
59pub struct DeleteAccountAction {
60 pub beneficiary_id: AccountId,
61}
62
63#[derive(
64 BorshSerialize,
65 BorshDeserialize,
66 PartialEq,
67 Eq,
68 Clone,
69 Debug,
70 serde::Serialize,
71 serde::Deserialize,
72)]
73pub struct DeleteKeyAction {
74 pub public_key: PublicKey,
76}
77
78#[serde_as]
80#[derive(
81 BorshSerialize, BorshDeserialize, serde::Serialize, serde::Deserialize, PartialEq, Eq, Clone,
82)]
83pub struct DeployContractAction {
84 #[serde_as(as = "Base64")]
86 pub code: Vec<u8>,
87}
88
89impl fmt::Debug for DeployContractAction {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 f.debug_struct("DeployContractAction")
92 .field("code", &format_args!("{}", base64(&self.code)))
93 .finish()
94 }
95}
96
97#[serde_as]
98#[derive(
99 BorshSerialize, BorshDeserialize, serde::Serialize, serde::Deserialize, PartialEq, Eq, Clone,
100)]
101pub struct FunctionCallAction {
102 pub method_name: String,
103 #[serde_as(as = "Base64")]
104 pub args: Vec<u8>,
105 pub gas: Gas,
106 #[serde(with = "dec_format")]
107 pub deposit: Balance,
108}
109
110impl fmt::Debug for FunctionCallAction {
111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112 f.debug_struct("FunctionCallAction")
113 .field("method_name", &format_args!("{}", &self.method_name))
114 .field("args", &format_args!("{}", base64(&self.args)))
115 .field("gas", &format_args!("{}", &self.gas))
116 .field("deposit", &format_args!("{}", &self.deposit))
117 .finish()
118 }
119}
120
121#[derive(
123 BorshSerialize,
124 BorshDeserialize,
125 PartialEq,
126 Eq,
127 Clone,
128 Debug,
129 serde::Serialize,
130 serde::Deserialize,
131)]
132pub struct PledgeAction {
133 #[serde(with = "dec_format")]
135 pub pledge: Balance,
136 pub public_key: PublicKey,
138}
139
140#[derive(
141 BorshSerialize,
142 BorshDeserialize,
143 PartialEq,
144 Eq,
145 Clone,
146 Debug,
147 serde::Serialize,
148 serde::Deserialize,
149)]
150pub struct TransferAction {
151 #[serde(with = "dec_format")]
152 pub deposit: Balance,
153}
154
155#[serde_as]
156#[derive(
157 BorshSerialize, BorshDeserialize, serde::Serialize, serde::Deserialize, PartialEq, Eq, Clone,
158)]
159pub struct RegisterRsa2048KeysAction {
160 pub public_key: PublicKey,
163 pub operation_type: u8,
165 #[serde_as(as = "Base64")]
167 pub args: Vec<u8>,
168}
169
170impl fmt::Debug for RegisterRsa2048KeysAction {
171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 f.debug_struct("RegisterRsa2048KeysAction")
173 .field("public_key", &format_args!("{}", &self.public_key))
174 .field("operation_type", &format_args!("{}", &self.operation_type))
175 .field("args", &format_args!("{}", base64(&self.args)))
176 .finish()
177 }
178}
179
180#[serde_as]
181#[derive(
182 BorshSerialize, BorshDeserialize, serde::Serialize, serde::Deserialize, PartialEq, Eq, Clone,
183)]
184pub struct CreateRsa2048ChallengeAction {
185 pub public_key: PublicKey,
188 pub challenge_key: PublicKey,
190 #[serde_as(as = "Base64")]
192 pub args: Vec<u8>,
193}
194
195impl fmt::Debug for CreateRsa2048ChallengeAction {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197 f.debug_struct("CreateRsa2048ChallengeAction")
198 .field("public_key", &format_args!("{}", &self.public_key))
199 .field("challenge_key", &format_args!("{}", &self.challenge_key))
200 .field("args", &format_args!("{}", base64(&self.args)))
201 .finish()
202 }
203}
204
205#[derive(
206 BorshSerialize,
207 BorshDeserialize,
208 PartialEq,
209 Eq,
210 Debug,
211 Clone,
212 serde::Serialize,
213 serde::Deserialize,
214 strum::AsRefStr,
215)]
216pub enum Action {
217 CreateAccount(CreateAccountAction),
221 DeployContract(DeployContractAction),
223 FunctionCall(Box<FunctionCallAction>),
224 Transfer(TransferAction),
225 Pledge(Box<PledgeAction>),
226 AddKey(Box<AddKeyAction>),
227 DeleteKey(Box<DeleteKeyAction>),
228 DeleteAccount(DeleteAccountAction),
229 Delegate(Box<delegate::SignedDelegateAction>),
230 RegisterRsa2048Keys(Box<RegisterRsa2048KeysAction>),
231 CreateRsa2048Challenge(Box<CreateRsa2048ChallengeAction>),
232}
233
234const _: () = assert!(
235 std::mem::size_of::<Action>() <= 32,
239 "Action <= 32 bytes for performance reasons, see #9451"
240);
241
242impl Action {
243 pub fn get_prepaid_gas(&self) -> Gas {
244 match self {
245 Action::FunctionCall(a) => a.gas,
246 _ => 0,
247 }
248 }
249 pub fn get_deposit_balance(&self) -> Balance {
250 match self {
251 Action::FunctionCall(a) => a.deposit,
252 Action::Transfer(a) => a.deposit,
253 _ => 0,
254 }
255 }
256}
257
258impl From<CreateAccountAction> for Action {
259 fn from(create_account_action: CreateAccountAction) -> Self {
260 Self::CreateAccount(create_account_action)
261 }
262}
263
264impl From<DeployContractAction> for Action {
265 fn from(deploy_contract_action: DeployContractAction) -> Self {
266 Self::DeployContract(deploy_contract_action)
267 }
268}
269
270impl From<FunctionCallAction> for Action {
271 fn from(function_call_action: FunctionCallAction) -> Self {
272 Self::FunctionCall(Box::new(function_call_action))
273 }
274}
275
276impl From<TransferAction> for Action {
277 fn from(transfer_action: TransferAction) -> Self {
278 Self::Transfer(transfer_action)
279 }
280}
281
282impl From<PledgeAction> for Action {
283 fn from(pledge_action: PledgeAction) -> Self {
284 Self::Pledge(Box::new(pledge_action))
285 }
286}
287
288impl From<AddKeyAction> for Action {
289 fn from(add_key_action: AddKeyAction) -> Self {
290 Self::AddKey(Box::new(add_key_action))
291 }
292}
293
294impl From<DeleteKeyAction> for Action {
295 fn from(delete_key_action: DeleteKeyAction) -> Self {
296 Self::DeleteKey(Box::new(delete_key_action))
297 }
298}
299
300impl From<DeleteAccountAction> for Action {
301 fn from(delete_account_action: DeleteAccountAction) -> Self {
302 Self::DeleteAccount(delete_account_action)
303 }
304}
305
306impl From<RegisterRsa2048KeysAction> for Action {
307 fn from(rsa2048_keys_action: RegisterRsa2048KeysAction) -> Self {
308 Self::RegisterRsa2048Keys(Box::new(rsa2048_keys_action))
309 }
310}
311
312impl From<CreateRsa2048ChallengeAction> for Action {
313 fn from(create_rsa2048_challenge_action: CreateRsa2048ChallengeAction) -> Self {
314 Self::CreateRsa2048Challenge(Box::new(create_rsa2048_challenge_action))
315 }
316}