use std::fmt::Display;
use borsh::{BorshDeserialize, BorshSerialize};
use derive_more::{From, Into};
use pyo3::prelude::*;
use serde::{Deserialize, Serialize};
use solders_macros::{common_methods, pyhash, richcmp_eq_only, EnumIntoPy};
use solders_traits::{common_methods_default, PyHash, RichcmpEqualityOnly};
use near_primitives::{
account::{
AccessKey as AccessKeyOriginal, AccessKeyPermission as AccessKeyPermissionOriginal,
Account as AccountOriginal, AccountVersion as AccountVersionOriginal,
FunctionCallPermission as FunctionCallPermissionOriginal,
},
types::{Balance, Nonce, StorageUsage},
};
use crate::{
add_classes, add_union, crypto_hash::CryptoHash, py_from_bytes_general_via_borsh,
pybytes_general_via_borsh,
};
#[pyclass(module = "pyonear.account")]
#[derive(
BorshSerialize,
BorshDeserialize,
Serialize,
Deserialize,
PartialEq,
Eq,
Debug,
Clone,
Copy,
Hash,
)]
pub enum AccountVersion {
V1,
}
impl PyHash for AccountVersion {}
#[pyhash]
#[pymethods]
impl AccountVersion {}
impl Default for AccountVersion {
fn default() -> Self {
AccountVersionOriginal::default().into()
}
}
impl From<AccountVersionOriginal> for AccountVersion {
fn from(v: AccountVersionOriginal) -> Self {
match v {
AccountVersionOriginal::V1 => Self::V1,
}
}
}
impl From<AccountVersion> for AccountVersionOriginal {
fn from(v: AccountVersion) -> Self {
match v {
AccountVersion::V1 => Self::V1,
}
}
}
#[pyclass(module = "pyonear.account", subclass)]
#[derive(
Serialize,
Deserialize,
PartialEq,
Eq,
Debug,
Clone,
From,
Into,
BorshDeserialize,
BorshSerialize,
)]
pub struct Account(pub AccountOriginal);
#[richcmp_eq_only]
#[common_methods]
#[pymethods]
impl Account {
#[classattr]
pub const MAX_ACCOUNT_DELETION_STORAGE_USAGE: u64 =
AccountOriginal::MAX_ACCOUNT_DELETION_STORAGE_USAGE;
#[new]
pub fn new(
amount: Balance,
locked: Balance,
code_hash: CryptoHash,
storage_usage: StorageUsage,
) -> Self {
AccountOriginal::new(amount, locked, code_hash.into(), storage_usage).into()
}
#[getter]
pub fn amount(&self) -> Balance {
self.0.amount()
}
#[getter]
pub fn locked(&self) -> Balance {
self.0.locked()
}
#[getter]
pub fn code_hash(&self) -> CryptoHash {
self.0.code_hash().into()
}
#[getter]
pub fn storage_usage(&self) -> StorageUsage {
self.0.storage_usage()
}
#[getter]
pub fn version(&self) -> AccountVersion {
self.0.version().into()
}
#[setter]
pub fn set_amount(&mut self, amount: Balance) {
self.0.set_amount(amount);
}
#[setter]
pub fn set_locked(&mut self, locked: Balance) {
self.0.set_locked(locked);
}
#[setter]
pub fn set_code_hash(&mut self, code_hash: CryptoHash) {
self.0.set_code_hash(code_hash.into());
}
#[setter]
pub fn set_storage_usage(&mut self, storage_usage: StorageUsage) {
self.0.set_storage_usage(storage_usage);
}
#[setter]
pub fn set_version(&mut self, version: AccountVersion) {
self.0.set_version(version.into());
}
}
impl RichcmpEqualityOnly for Account {}
py_from_bytes_general_via_borsh!(Account);
pybytes_general_via_borsh!(Account);
impl Display for Account {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
common_methods_default!(Account);
#[pyclass(module = "pyonear.account", subclass)]
#[derive(
BorshSerialize,
BorshDeserialize,
Serialize,
Deserialize,
PartialEq,
Eq,
Hash,
Clone,
Debug,
From,
Into,
)]
pub struct AccessKey(pub AccessKeyOriginal);
impl PyHash for AccessKey {}
#[richcmp_eq_only]
#[common_methods]
#[pyhash]
#[pymethods]
impl AccessKey {
#[new]
pub fn new(nonce: Nonce, permission: AccessKeyPermission) -> Self {
AccessKeyOriginal {
nonce,
permission: permission.into(),
}
.into()
}
#[getter]
pub fn nonce(&self) -> Nonce {
self.0.nonce
}
#[getter]
pub fn permission(&self) -> AccessKeyPermission {
self.0.permission.clone().into()
}
#[classattr]
pub const ACCESS_KEY_NONCE_RANGE_MULTIPLIER: u64 =
AccessKeyOriginal::ACCESS_KEY_NONCE_RANGE_MULTIPLIER;
#[staticmethod]
pub fn full_access() -> Self {
AccessKeyOriginal::full_access().into()
}
}
pybytes_general_via_borsh!(AccessKey);
py_from_bytes_general_via_borsh!(AccessKey);
impl RichcmpEqualityOnly for AccessKey {}
impl Display for AccessKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
common_methods_default!(AccessKey);
#[derive(PartialEq, Eq, Hash, Clone, Debug, FromPyObject, EnumIntoPy)]
pub enum AccessKeyPermission {
FunctionCall(FunctionCallPermission),
Fieldless(AccessKeyPermissionFieldless),
}
impl From<AccessKeyPermissionOriginal> for AccessKeyPermission {
fn from(p: AccessKeyPermissionOriginal) -> Self {
match p {
AccessKeyPermissionOriginal::FullAccess => {
Self::Fieldless(AccessKeyPermissionFieldless::FullAccess)
}
AccessKeyPermissionOriginal::FunctionCall(p) => Self::FunctionCall(p.into()),
}
}
}
impl From<AccessKeyPermission> for AccessKeyPermissionOriginal {
fn from(p: AccessKeyPermission) -> Self {
match p {
AccessKeyPermission::Fieldless(v) => match v {
AccessKeyPermissionFieldless::FullAccess => Self::FullAccess,
},
AccessKeyPermission::FunctionCall(p) => Self::FunctionCall(p.into()),
}
}
}
#[pyclass(module = "pyonear.account")]
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum AccessKeyPermissionFieldless {
FullAccess,
}
impl PyHash for AccessKeyPermissionFieldless {}
#[pyhash]
#[pymethods]
impl AccessKeyPermissionFieldless {}
#[pyclass(module = "pyonear.account", subclass)]
#[derive(
BorshSerialize,
BorshDeserialize,
Serialize,
Deserialize,
PartialEq,
Eq,
Hash,
Clone,
Debug,
From,
Into,
)]
pub struct FunctionCallPermission(pub FunctionCallPermissionOriginal);
impl PyHash for FunctionCallPermission {}
#[richcmp_eq_only]
#[common_methods]
#[pyhash]
#[pymethods]
impl FunctionCallPermission {
#[new]
pub fn new(receiver_id: String, method_names: Vec<String>, allowance: Option<Balance>) -> Self {
FunctionCallPermissionOriginal {
allowance,
receiver_id,
method_names,
}
.into()
}
#[getter]
pub fn allowance(&self) -> Option<Balance> {
self.0.allowance
}
#[getter]
pub fn receiver_id(&self) -> String {
self.0.receiver_id.clone()
}
#[getter]
pub fn method_names(&self) -> Vec<String> {
self.0.method_names.clone()
}
}
impl Display for FunctionCallPermission {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
impl RichcmpEqualityOnly for FunctionCallPermission {}
common_methods_default!(FunctionCallPermission);
pybytes_general_via_borsh!(FunctionCallPermission);
py_from_bytes_general_via_borsh!(FunctionCallPermission);
pub(crate) fn create_account_mod(py: Python<'_>) -> PyResult<&PyModule> {
let m = PyModule::new(py, "account")?;
add_classes!(
m,
FunctionCallPermission,
AccessKeyPermissionFieldless,
FunctionCallPermission,
FunctionCallPermission,
AccessKey,
Account,
AccountVersion
);
add_union!(
"AccessKeyPermission",
m,
py,
FunctionCallPermission,
AccessKeyPermissionFieldless
)?;
Ok(m)
}