Skip to main content

casper_contract/contract_api/
entity.rs

1//! Functions for managing accounts.
2
3use alloc::vec::Vec;
4use core::convert::TryFrom;
5
6use casper_types::{
7    account::{
8        AccountHash, AddKeyFailure, RemoveKeyFailure, SetThresholdFailure, UpdateKeyFailure,
9    },
10    addressable_entity::{ActionType, Weight},
11    bytesrepr, URef, UREF_SERIALIZED_LENGTH,
12};
13
14use super::to_ptr;
15use crate::{contract_api, ext_ffi, unwrap_or_revert::UnwrapOrRevert};
16
17/// Retrieves the ID of the account's main purse.
18pub fn get_main_purse() -> URef {
19    let dest_non_null_ptr = contract_api::alloc_bytes(UREF_SERIALIZED_LENGTH);
20    let bytes = unsafe {
21        ext_ffi::casper_get_main_purse(dest_non_null_ptr.as_ptr());
22        Vec::from_raw_parts(
23            dest_non_null_ptr.as_ptr(),
24            UREF_SERIALIZED_LENGTH,
25            UREF_SERIALIZED_LENGTH,
26        )
27    };
28    bytesrepr::deserialize(bytes).unwrap_or_revert()
29}
30
31/// Sets the given [`ActionType`]'s threshold to the provided value.
32pub fn set_action_threshold(
33    action_type: ActionType,
34    threshold: Weight,
35) -> Result<(), SetThresholdFailure> {
36    let action_type = action_type as u32;
37    let threshold = threshold.value().into();
38    let result = unsafe { ext_ffi::casper_set_action_threshold(action_type, threshold) };
39    if result == 0 {
40        Ok(())
41    } else {
42        Err(SetThresholdFailure::try_from(result).unwrap_or_revert())
43    }
44}
45
46/// Adds the given [`AccountHash`] with associated [`Weight`] to the account's associated keys.
47pub fn add_associated_key(account_hash: AccountHash, weight: Weight) -> Result<(), AddKeyFailure> {
48    let (account_hash_ptr, account_hash_size, _bytes) = to_ptr(account_hash);
49    // Cast of u8 (weight) into i32 is assumed to be always safe
50    let result = unsafe {
51        ext_ffi::casper_add_associated_key(
52            account_hash_ptr,
53            account_hash_size,
54            weight.value().into(),
55        )
56    };
57    if result == 0 {
58        Ok(())
59    } else {
60        Err(AddKeyFailure::try_from(result).unwrap_or_revert())
61    }
62}
63
64/// Removes the given [`AccountHash`] from the account's associated keys.
65pub fn remove_associated_key(account_hash: AccountHash) -> Result<(), RemoveKeyFailure> {
66    let (account_hash_ptr, account_hash_size, _bytes) = to_ptr(account_hash);
67    let result =
68        unsafe { ext_ffi::casper_remove_associated_key(account_hash_ptr, account_hash_size) };
69    if result == 0 {
70        Ok(())
71    } else {
72        Err(RemoveKeyFailure::try_from(result).unwrap_or_revert())
73    }
74}
75
76/// Updates the [`Weight`] of the given [`AccountHash`] in the account's associated keys.
77pub fn update_associated_key(
78    account_hash: AccountHash,
79    weight: Weight,
80) -> Result<(), UpdateKeyFailure> {
81    let (account_hash_ptr, account_hash_size, _bytes) = to_ptr(account_hash);
82    // Cast of u8 (weight) into i32 is assumed to be always safe
83    let result = unsafe {
84        ext_ffi::casper_update_associated_key(
85            account_hash_ptr,
86            account_hash_size,
87            weight.value().into(),
88        )
89    };
90    if result == 0 {
91        Ok(())
92    } else {
93        Err(UpdateKeyFailure::try_from(result).unwrap_or_revert())
94    }
95}