Skip to content

Commit 9f315db

Browse files
committed
fix: tests still fail
2 parents 1e9fdd2 + 49f101d commit 9f315db

20 files changed

Lines changed: 1062 additions & 76 deletions

File tree

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ members = [
66
"contracts/shared",
77
"contracts/reserve_contract",
88
"contracts/native_transfer",
9+
"contracts/account_factory",
10+
"contracts/claim_verifier",
911
]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[package]
2+
name = "account-factory"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
crate-type = ["rlib", "cdylib"]
8+
9+
[dependencies]
10+
soroban-sdk = "22.0.0"
11+
bridgelet-shared = { path = "../shared" }
12+
ephemeral_account = { path = "../ephemeral_account" }
13+
14+
[dev-dependencies]
15+
soroban-sdk = { version = "22.0.0", features = ["testutils"] }
16+
bridgelet-shared = { path = "../shared", features = ["testutils"] }
17+
ephemeral_account = { path = "../ephemeral_account", features = ["testutils"] }
18+
19+
[features]
20+
testutils = ["soroban-sdk/testutils"]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use soroban_sdk::contracterror;
2+
3+
#[contracterror]
4+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
5+
pub enum Error {
6+
NotInitialized = 1,
7+
AlreadyInitialized = 2,
8+
DeploymentFailed = 3,
9+
Unauthorized = 4,
10+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use soroban_sdk::{contracttype, symbol_short, Address, Env};
2+
3+
#[contracttype]
4+
#[derive(Clone, Debug, Eq, PartialEq)]
5+
pub struct AccountDeployed {
6+
pub account_address: Address,
7+
pub creator: Address,
8+
pub expiry_ledger: u32,
9+
}
10+
11+
pub fn emit_account_deployed(
12+
env: &Env,
13+
account_address: Address,
14+
creator: Address,
15+
expiry_ledger: u32,
16+
) {
17+
let event = AccountDeployed {
18+
account_address,
19+
creator,
20+
expiry_ledger,
21+
};
22+
env.events().publish((symbol_short!("deployed"),), event);
23+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#![no_std]
2+
3+
mod errors;
4+
mod events;
5+
mod storage;
6+
#[cfg(test)]
7+
mod test;
8+
9+
use soroban_sdk::{contract, contractimpl, xdr::ToXdr, Address, Bytes, BytesN, Env};
10+
11+
pub use errors::Error;
12+
pub use events::AccountDeployed;
13+
pub use storage::DataKey;
14+
15+
#[contract]
16+
pub struct AccountFactoryContract;
17+
18+
#[contractimpl]
19+
impl AccountFactoryContract {
20+
/// Initialize the factory with admin and ephemeral account wasm hash.
21+
pub fn initialize(
22+
env: Env,
23+
admin: Address,
24+
ephemeral_wasm_hash: BytesN<32>,
25+
) -> Result<(), Error> {
26+
if storage::has_admin(&env) {
27+
return Err(Error::AlreadyInitialized);
28+
}
29+
30+
admin.require_auth();
31+
32+
storage::set_admin(&env, &admin);
33+
storage::set_ephemeral_wasm_hash(&env, &ephemeral_wasm_hash);
34+
35+
Ok(())
36+
}
37+
38+
/// Deploy and initialize a new ephemeral account contract instance.
39+
pub fn create_account(
40+
env: Env,
41+
creator: Address,
42+
expiry_ledger: u32,
43+
recovery_address: Address,
44+
native_transfer_address: Address,
45+
claim_verifier_address: Address,
46+
) -> Result<Address, Error> {
47+
let wasm_hash = storage::get_ephemeral_wasm_hash(&env).ok_or(Error::NotInitialized)?;
48+
49+
creator.require_auth();
50+
51+
let salt = Self::account_salt(&env, &creator, expiry_ledger);
52+
let deployed_address = env
53+
.deployer()
54+
.with_current_contract(salt)
55+
.deploy_v2(wasm_hash, ());
56+
57+
let account_client =
58+
ephemeral_account::EphemeralAccountContractClient::new(&env, &deployed_address);
59+
account_client.initialize(
60+
&creator,
61+
&expiry_ledger,
62+
&recovery_address,
63+
&native_transfer_address,
64+
&claim_verifier_address,
65+
);
66+
67+
storage::add_deployed_account(&env, &creator, &deployed_address);
68+
events::emit_account_deployed(&env, deployed_address.clone(), creator, expiry_ledger);
69+
70+
Ok(deployed_address)
71+
}
72+
73+
/// Get all accounts deployed by a specific creator.
74+
pub fn get_accounts_by_creator(env: Env, creator: Address) -> soroban_sdk::Vec<Address> {
75+
storage::get_accounts_by_creator(&env, &creator)
76+
}
77+
78+
/// Get all deployed accounts.
79+
pub fn get_all_accounts(env: Env) -> soroban_sdk::Vec<Address> {
80+
storage::get_all_accounts(&env)
81+
}
82+
83+
fn account_salt(env: &Env, creator: &Address, expiry_ledger: u32) -> BytesN<32> {
84+
let mut salt_preimage = Bytes::new(env);
85+
salt_preimage.append(&creator.to_xdr(env));
86+
salt_preimage.append(&expiry_ledger.to_xdr(env));
87+
salt_preimage.append(&env.ledger().sequence().to_xdr(env));
88+
89+
env.crypto().sha256(&salt_preimage).into()
90+
}
91+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use soroban_sdk::{contracttype, Address, BytesN, Env, Map, Vec};
2+
3+
#[contracttype]
4+
#[derive(Clone)]
5+
pub enum DataKey {
6+
Admin,
7+
EphemeralWasmHash,
8+
DeployedAccounts,
9+
AllAccounts,
10+
}
11+
12+
pub fn set_admin(env: &Env, admin: &Address) {
13+
env.storage().instance().set(&DataKey::Admin, admin);
14+
}
15+
16+
pub fn has_admin(env: &Env) -> bool {
17+
env.storage().instance().has(&DataKey::Admin)
18+
}
19+
20+
pub fn set_ephemeral_wasm_hash(env: &Env, hash: &BytesN<32>) {
21+
env.storage()
22+
.instance()
23+
.set(&DataKey::EphemeralWasmHash, hash);
24+
}
25+
26+
pub fn get_ephemeral_wasm_hash(env: &Env) -> Option<BytesN<32>> {
27+
env.storage().instance().get(&DataKey::EphemeralWasmHash)
28+
}
29+
30+
pub fn add_deployed_account(env: &Env, creator: &Address, account: &Address) {
31+
let mut by_creator: Map<Address, Vec<Address>> = env
32+
.storage()
33+
.instance()
34+
.get(&DataKey::DeployedAccounts)
35+
.unwrap_or_else(|| Map::new(env));
36+
37+
let mut creator_accounts = by_creator
38+
.get(creator.clone())
39+
.unwrap_or_else(|| Vec::new(env));
40+
creator_accounts.push_back(account.clone());
41+
by_creator.set(creator.clone(), creator_accounts);
42+
43+
env.storage()
44+
.instance()
45+
.set(&DataKey::DeployedAccounts, &by_creator);
46+
47+
let mut all_accounts: Vec<Address> = env
48+
.storage()
49+
.instance()
50+
.get(&DataKey::AllAccounts)
51+
.unwrap_or_else(|| Vec::new(env));
52+
all_accounts.push_back(account.clone());
53+
env.storage()
54+
.instance()
55+
.set(&DataKey::AllAccounts, &all_accounts);
56+
}
57+
58+
pub fn get_accounts_by_creator(env: &Env, creator: &Address) -> Vec<Address> {
59+
let by_creator: Map<Address, Vec<Address>> = env
60+
.storage()
61+
.instance()
62+
.get(&DataKey::DeployedAccounts)
63+
.unwrap_or_else(|| Map::new(env));
64+
65+
by_creator
66+
.get(creator.clone())
67+
.unwrap_or_else(|| Vec::new(env))
68+
}
69+
70+
pub fn get_all_accounts(env: &Env) -> Vec<Address> {
71+
env.storage()
72+
.instance()
73+
.get(&DataKey::AllAccounts)
74+
.unwrap_or_else(|| Vec::new(env))
75+
}

0 commit comments

Comments
 (0)