use rand_xoshiro::rand_core::SeedableRng;
use crate::account::{AccountId, AccountIdV0, AccountIdVersion, AccountStorageMode, AccountType};
pub const ACCOUNT_ID_SENDER: u128 = account_id(
AccountType::RegularAccountImmutableCode,
AccountStorageMode::Private,
0xfabb_ccde,
);
pub const ACCOUNT_ID_PRIVATE_SENDER: u128 = account_id(
AccountType::RegularAccountImmutableCode,
AccountStorageMode::Private,
0xbfcc_dcee,
);
pub const ACCOUNT_ID_REGULAR_PRIVATE_ACCOUNT_UPDATABLE_CODE: u128 = account_id(
AccountType::RegularAccountUpdatableCode,
AccountStorageMode::Private,
0xccdd_eeff,
);
pub const ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE: u128 = account_id(
AccountType::RegularAccountImmutableCode,
AccountStorageMode::Public,
0xaabb_ccdd,
);
pub const ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE_2: u128 = account_id(
AccountType::RegularAccountImmutableCode,
AccountStorageMode::Public,
0xbbcc_ddee,
);
pub const ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE: u128 = account_id(
AccountType::RegularAccountUpdatableCode,
AccountStorageMode::Public,
0xacdd_eefc,
);
pub const ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE_ON_CHAIN_2: u128 = account_id(
AccountType::RegularAccountUpdatableCode,
AccountStorageMode::Public,
0xeeff_ccdd,
);
pub const ACCOUNT_ID_REGULAR_NETWORK_ACCOUNT_IMMUTABLE_CODE: u128 = account_id(
AccountType::RegularAccountImmutableCode,
AccountStorageMode::Network,
0xaacc_bbdd,
);
pub const ACCOUNT_ID_PRIVATE_FUNGIBLE_FAUCET: u128 =
account_id(AccountType::FungibleFaucet, AccountStorageMode::Private, 0xfabb_cddd);
pub const ACCOUNT_ID_NATIVE_ASSET_FAUCET: u128 =
account_id(AccountType::FungibleFaucet, AccountStorageMode::Public, 0xabcd_acde);
pub const ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET: u128 =
account_id(AccountType::FungibleFaucet, AccountStorageMode::Public, 0xaabc_bcde);
pub const ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_1: u128 =
account_id(AccountType::FungibleFaucet, AccountStorageMode::Public, 0xbaca_ddef);
pub const ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_2: u128 =
account_id(AccountType::FungibleFaucet, AccountStorageMode::Public, 0xccdb_eefa);
pub const ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_3: u128 =
account_id(AccountType::FungibleFaucet, AccountStorageMode::Public, 0xeeff_cc99);
pub const ACCOUNT_ID_NETWORK_FUNGIBLE_FAUCET: u128 =
account_id(AccountType::FungibleFaucet, AccountStorageMode::Network, 0xaabc_bcdf);
pub const ACCOUNT_ID_PRIVATE_NON_FUNGIBLE_FAUCET: u128 =
account_id(AccountType::NonFungibleFaucet, AccountStorageMode::Private, 0xaabc_ccde);
pub const ACCOUNT_ID_PUBLIC_NON_FUNGIBLE_FAUCET: u128 =
account_id(AccountType::NonFungibleFaucet, AccountStorageMode::Public, 0xbcca_ddef);
pub const ACCOUNT_ID_PUBLIC_NON_FUNGIBLE_FAUCET_1: u128 =
account_id(AccountType::NonFungibleFaucet, AccountStorageMode::Public, 0xccdf_eefa);
pub const ACCOUNT_ID_NETWORK_NON_FUNGIBLE_FAUCET: u128 =
account_id(AccountType::NonFungibleFaucet, AccountStorageMode::Network, 0xabbc_ffde);
pub const ACCOUNT_ID_MAX_ONES: u128 =
account_id(AccountType::NonFungibleFaucet, AccountStorageMode::Public, 0)
| 0x7fff_ffff_ffff_ff00_7fff_ffff_ffff_ff00;
pub const ACCOUNT_ID_MAX_ZEROES: u128 =
account_id(AccountType::NonFungibleFaucet, AccountStorageMode::Private, 0x001f_0000);
pub const fn account_id(
account_type: AccountType,
storage_mode: AccountStorageMode,
random: u32,
) -> u128 {
let mut prefix: u64 = 0;
prefix |= (account_type as u64) << AccountIdV0::TYPE_SHIFT;
prefix |= (storage_mode as u64) << AccountIdV0::STORAGE_MODE_SHIFT;
let random_1st_felt_upper = random & 0xff00_0000;
let random_1st_felt_lower = random & 0x00ff_0000;
let random_2nd_felt_upper = random & 0x0000_ff00;
let random_2nd_felt_lower = random & 0x0000_00ff;
prefix |= (random_1st_felt_upper as u64) << 32;
prefix |= (random_1st_felt_lower as u64) >> 8;
let mut id = (prefix as u128) << 64;
id |= (random_2nd_felt_upper as u128) << 32;
id |= (random_2nd_felt_lower as u128) << 8;
id
}
pub struct AccountIdBuilder {
account_type: Option<AccountType>,
storage_mode: Option<AccountStorageMode>,
}
impl AccountIdBuilder {
pub fn new() -> Self {
Self { account_type: None, storage_mode: None }
}
pub fn account_type(mut self, account_type: AccountType) -> Self {
self.account_type = Some(account_type);
self
}
pub fn storage_mode(mut self, storage_mode: AccountStorageMode) -> Self {
self.storage_mode = Some(storage_mode);
self
}
pub fn build_with_rng<R: rand::Rng + ?Sized>(self, rng: &mut R) -> AccountId {
let account_type = match self.account_type {
Some(account_type) => account_type,
None => rng.random(),
};
let storage_mode = match self.storage_mode {
Some(storage_mode) => storage_mode,
None => rng.random(),
};
AccountId::dummy(rng.random(), AccountIdVersion::Version0, account_type, storage_mode)
}
pub fn build_with_seed(self, rng_seed: [u8; 32]) -> AccountId {
#[cfg(not(target_pointer_width = "64"))]
let mut rng = {
let rng_seed: [u8; 16] = rng_seed.as_slice()[0..16]
.try_into()
.expect("we should have sliced off 16 elements");
rand_xoshiro::Xoshiro128PlusPlus::from_seed(rng_seed)
};
#[cfg(target_pointer_width = "64")]
let mut rng = rand_xoshiro::Xoshiro256PlusPlus::from_seed(rng_seed);
self.build_with_rng(&mut rng)
}
}
impl Default for AccountIdBuilder {
fn default() -> Self {
Self::new()
}
}