1pub mod delegate;
2
3pub use near_primitives_core::global_contract::GlobalContractIdentifier;
6
7use crate::{
8 deterministic_account_id::DeterministicAccountStateInit, trie_key::GlobalContractCodeIdentifier,
9};
10use borsh::{BorshDeserialize, BorshSerialize};
11use near_crypto::PublicKey;
12use near_primitives_core::{
13 account::AccessKey,
14 types::{AccountId, Balance, Gas},
15};
16use near_schema_checker_lib::ProtocolSchema;
17use serde_with::base64::Base64;
18use serde_with::serde_as;
19use std::fmt;
20use std::sync::Arc;
21
22pub fn base64(s: &[u8]) -> String {
23 use base64::Engine;
24 base64::engine::general_purpose::STANDARD.encode(s)
25}
26
27#[derive(
29 BorshSerialize,
30 BorshDeserialize,
31 PartialEq,
32 Eq,
33 Clone,
34 Debug,
35 serde::Serialize,
36 serde::Deserialize,
37 ProtocolSchema,
38)]
39#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
40pub struct AddKeyAction {
41 pub public_key: PublicKey,
43 pub access_key: AccessKey,
45}
46
47#[derive(
49 BorshSerialize,
50 BorshDeserialize,
51 PartialEq,
52 Eq,
53 Clone,
54 Debug,
55 serde::Serialize,
56 serde::Deserialize,
57 ProtocolSchema,
58)]
59#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
60pub struct CreateAccountAction {}
61
62#[derive(
63 BorshSerialize,
64 BorshDeserialize,
65 PartialEq,
66 Eq,
67 Clone,
68 Debug,
69 serde::Serialize,
70 serde::Deserialize,
71 ProtocolSchema,
72)]
73#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
74pub struct DeleteAccountAction {
75 pub beneficiary_id: AccountId,
76}
77
78#[derive(
79 BorshSerialize,
80 BorshDeserialize,
81 PartialEq,
82 Eq,
83 Clone,
84 Debug,
85 serde::Serialize,
86 serde::Deserialize,
87 ProtocolSchema,
88)]
89#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
90pub struct DeleteKeyAction {
91 pub public_key: PublicKey,
93}
94
95#[serde_as]
97#[derive(
98 BorshSerialize,
99 BorshDeserialize,
100 serde::Serialize,
101 serde::Deserialize,
102 PartialEq,
103 Eq,
104 Clone,
105 ProtocolSchema,
106)]
107#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
108pub struct DeployContractAction {
109 #[serde_as(as = "Base64")]
111 #[cfg_attr(feature = "schemars", schemars(with = "String"))]
112 pub code: Vec<u8>,
113}
114
115impl fmt::Debug for DeployContractAction {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 f.debug_struct("DeployContractAction")
118 .field("code", &format_args!("{}", base64(&self.code)))
119 .finish()
120 }
121}
122
123#[derive(
124 BorshSerialize,
125 BorshDeserialize,
126 serde::Serialize,
127 serde::Deserialize,
128 PartialEq,
129 Eq,
130 Clone,
131 ProtocolSchema,
132 Debug,
133)]
134#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
135#[repr(u8)]
136pub enum GlobalContractDeployMode {
137 CodeHash,
141 AccountId,
145}
146
147#[serde_as]
149#[derive(
150 BorshSerialize,
151 BorshDeserialize,
152 serde::Serialize,
153 serde::Deserialize,
154 PartialEq,
155 Eq,
156 Clone,
157 ProtocolSchema,
158)]
159#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
160pub struct DeployGlobalContractAction {
161 #[serde_as(as = "Base64")]
163 #[cfg_attr(feature = "schemars", schemars(with = "String"))]
164 pub code: Arc<[u8]>,
165
166 pub deploy_mode: GlobalContractDeployMode,
167}
168
169impl fmt::Debug for DeployGlobalContractAction {
170 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171 f.debug_struct("DeployGlobalContractAction")
172 .field("code", &format_args!("{}", base64(&self.code)))
173 .field("deploy_mode", &format_args!("{:?}", &self.deploy_mode))
174 .finish()
175 }
176}
177
178impl From<GlobalContractCodeIdentifier> for GlobalContractIdentifier {
179 fn from(identifier: GlobalContractCodeIdentifier) -> Self {
180 match identifier {
181 GlobalContractCodeIdentifier::CodeHash(hash) => {
182 GlobalContractIdentifier::CodeHash(hash)
183 }
184 GlobalContractCodeIdentifier::AccountId(account_id) => {
185 GlobalContractIdentifier::AccountId(account_id)
186 }
187 }
188 }
189}
190
191#[derive(
193 BorshSerialize,
194 BorshDeserialize,
195 serde::Serialize,
196 serde::Deserialize,
197 PartialEq,
198 Eq,
199 Clone,
200 ProtocolSchema,
201 Debug,
202)]
203#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
204pub struct UseGlobalContractAction {
205 pub contract_identifier: GlobalContractIdentifier,
206}
207
208#[serde_as]
209#[derive(
210 BorshSerialize,
211 BorshDeserialize,
212 serde::Serialize,
213 serde::Deserialize,
214 PartialEq,
215 Eq,
216 Clone,
217 ProtocolSchema,
218 Debug,
219)]
220#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
221pub struct DeterministicStateInitAction {
222 pub state_init: DeterministicAccountStateInit,
223 pub deposit: Balance,
224}
225
226#[serde_as]
227#[derive(
228 BorshSerialize,
229 BorshDeserialize,
230 serde::Serialize,
231 serde::Deserialize,
232 PartialEq,
233 Eq,
234 Clone,
235 ProtocolSchema,
236)]
237#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
238pub struct FunctionCallAction {
239 pub method_name: String,
240 #[serde_as(as = "Base64")]
241 #[cfg_attr(feature = "schemars", schemars(with = "String"))]
242 pub args: Vec<u8>,
243 pub gas: Gas,
244 pub deposit: Balance,
245}
246
247impl fmt::Debug for FunctionCallAction {
248 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
249 f.debug_struct("FunctionCallAction")
250 .field("method_name", &format_args!("{}", &self.method_name))
251 .field("args", &format_args!("{}", base64(&self.args)))
252 .field("gas", &format_args!("{}", &self.gas))
253 .field("deposit", &format_args!("{}", &self.deposit))
254 .finish()
255 }
256}
257
258#[derive(
260 BorshSerialize,
261 BorshDeserialize,
262 PartialEq,
263 Eq,
264 Clone,
265 Debug,
266 serde::Serialize,
267 serde::Deserialize,
268 ProtocolSchema,
269)]
270#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
271pub struct StakeAction {
272 pub stake: Balance,
274 pub public_key: PublicKey,
276}
277
278#[derive(
279 BorshSerialize,
280 BorshDeserialize,
281 PartialEq,
282 Eq,
283 Clone,
284 Debug,
285 serde::Serialize,
286 serde::Deserialize,
287 ProtocolSchema,
288)]
289#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
290pub struct TransferAction {
291 pub deposit: Balance,
292}
293
294#[derive(
295 BorshSerialize,
296 BorshDeserialize,
297 PartialEq,
298 Eq,
299 Debug,
300 Clone,
301 serde::Serialize,
302 serde::Deserialize,
303 strum::AsRefStr,
304 ProtocolSchema,
305)]
306#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
307#[borsh(use_discriminant = true)]
308#[repr(u8)]
309pub enum Action {
310 CreateAccount(CreateAccountAction) = 0,
314 DeployContract(DeployContractAction) = 1,
316 FunctionCall(Box<FunctionCallAction>) = 2,
317 Transfer(TransferAction) = 3,
318 Stake(Box<StakeAction>) = 4,
319 AddKey(Box<AddKeyAction>) = 5,
320 DeleteKey(Box<DeleteKeyAction>) = 6,
321 DeleteAccount(DeleteAccountAction) = 7,
322 Delegate(Box<delegate::SignedDelegateAction>) = 8,
323 DeployGlobalContract(DeployGlobalContractAction) = 9,
324 UseGlobalContract(Box<UseGlobalContractAction>) = 10,
325 DeterministicStateInit(Box<DeterministicStateInitAction>) = 11,
326}
327
328const _: () = assert!(
329 std::mem::size_of::<Action>() <= 32,
333 "Action <= 32 bytes for performance reasons, see #9451"
334);
335
336impl Action {
337 pub fn get_prepaid_gas(&self) -> Gas {
338 match self {
339 Action::FunctionCall(a) => a.gas,
340 _ => Gas::ZERO,
341 }
342 }
343 pub fn get_deposit_balance(&self) -> Balance {
344 match self {
345 Action::FunctionCall(a) => a.deposit,
346 Action::Transfer(a) => a.deposit,
347 Action::DeterministicStateInit(a) => a.deposit,
348 _ => Balance::ZERO,
349 }
350 }
351}
352
353impl From<CreateAccountAction> for Action {
354 fn from(create_account_action: CreateAccountAction) -> Self {
355 Self::CreateAccount(create_account_action)
356 }
357}
358
359impl From<DeployContractAction> for Action {
360 fn from(deploy_contract_action: DeployContractAction) -> Self {
361 Self::DeployContract(deploy_contract_action)
362 }
363}
364
365impl From<DeployGlobalContractAction> for Action {
366 fn from(deploy_global_contract_action: DeployGlobalContractAction) -> Self {
367 Self::DeployGlobalContract(deploy_global_contract_action)
368 }
369}
370
371impl From<FunctionCallAction> for Action {
372 fn from(function_call_action: FunctionCallAction) -> Self {
373 Self::FunctionCall(Box::new(function_call_action))
374 }
375}
376
377impl From<TransferAction> for Action {
378 fn from(transfer_action: TransferAction) -> Self {
379 Self::Transfer(transfer_action)
380 }
381}
382
383impl From<StakeAction> for Action {
384 fn from(stake_action: StakeAction) -> Self {
385 Self::Stake(Box::new(stake_action))
386 }
387}
388
389impl From<AddKeyAction> for Action {
390 fn from(add_key_action: AddKeyAction) -> Self {
391 Self::AddKey(Box::new(add_key_action))
392 }
393}
394
395impl From<DeleteKeyAction> for Action {
396 fn from(delete_key_action: DeleteKeyAction) -> Self {
397 Self::DeleteKey(Box::new(delete_key_action))
398 }
399}
400
401impl From<DeleteAccountAction> for Action {
402 fn from(delete_account_action: DeleteAccountAction) -> Self {
403 Self::DeleteAccount(delete_account_action)
404 }
405}