use rand_xoshiro::rand_core::SeedableRng;
use crate::account::{AccountId, AccountIdV1, AccountIdVersion, AccountType};
pub const ACCOUNT_ID_SENDER: u128 = account_id(AccountType::Private, 0xfabb_ccde);
pub const ACCOUNT_ID_PRIVATE_SENDER: u128 = account_id(AccountType::Private, 0xbfcc_dcee);
pub const ACCOUNT_ID_REGULAR_PRIVATE_ACCOUNT_UPDATABLE_CODE: u128 =
account_id(AccountType::Private, 0xccdd_eeff);
pub const ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE: u128 =
account_id(AccountType::Public, 0xaabb_ccdd);
pub const ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE_2: u128 =
account_id(AccountType::Public, 0xbbcc_ddee);
pub const ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE: u128 =
account_id(AccountType::Public, 0xacdd_eefc);
pub const ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE_ON_CHAIN_2: u128 =
account_id(AccountType::Public, 0xeeff_ccdd);
pub const ACCOUNT_ID_PRIVATE_FUNGIBLE_FAUCET: u128 = account_id(AccountType::Private, 0xfabb_cddd);
pub const ACCOUNT_ID_FEE_FAUCET: u128 = account_id(AccountType::Public, 0xabcd_acde);
pub const ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET: u128 = account_id(AccountType::Public, 0xaabc_bcde);
pub const ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_1: u128 = account_id(AccountType::Public, 0xbaca_ddef);
pub const ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_2: u128 = account_id(AccountType::Public, 0xccdb_eefa);
pub const ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_3: u128 = account_id(AccountType::Public, 0xeeff_cc99);
pub const ACCOUNT_ID_PRIVATE_NON_FUNGIBLE_FAUCET: u128 =
account_id(AccountType::Private, 0xaabc_ccde);
pub const ACCOUNT_ID_PUBLIC_NON_FUNGIBLE_FAUCET: u128 =
account_id(AccountType::Public, 0xbcca_ddef);
pub const ACCOUNT_ID_PUBLIC_NON_FUNGIBLE_FAUCET_1: u128 =
account_id(AccountType::Public, 0xccdf_eefa);
pub const ACCOUNT_ID_MAX_ONES: u128 =
account_id(AccountType::Public, 0) | 0x7fff_ffff_ffff_ff00_7fff_ffff_ffff_ff00;
pub const ACCOUNT_ID_MAX_ZEROES: u128 = account_id(AccountType::Private, 0x0000_0000);
pub const fn account_id(account_type: AccountType, random: u32) -> u128 {
let mut prefix: u64 = 0;
prefix |= AccountIdVersion::Version1 as u64;
prefix |= (account_type as u64) << AccountIdV1::ACCOUNT_TYPE_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>,
}
impl AccountIdBuilder {
pub fn new() -> Self {
Self { account_type: None }
}
pub fn account_type(mut self, account_type: AccountType) -> Self {
self.account_type = Some(account_type);
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(),
};
AccountId::dummy(rng.random(), AccountIdVersion::Version1, account_type)
}
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()
}
}