diff --git a/soroban-contract/contracts/tba_account/src/lib.rs b/soroban-contract/contracts/tba_account/src/lib.rs
index e69de29..1b32aab 100644
--- a/soroban-contract/contracts/tba_account/src/lib.rs
+++ b/soroban-contract/contracts/tba_account/src/lib.rs
@@ -0,0 +1,240 @@
+#![no_std]
+use soroban_sdk::{
+ contract, contractimpl, contracttype, Address, BytesN, Env, Vec, Symbol, Val,
+ auth::Context,
+};
+
+#[contract]
+pub struct TbaAccount;
+
+#[contracttype]
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum DataKey {
+ TokenContract, // Address of the NFT contract
+ TokenId, // Specific NFT token ID (u128)
+ ImplementationHash, // Hash used for deployment (u256)
+ Salt, // Deployment salt (u256)
+ Initialized, // Init flag
+ Nonce, // Transaction nonce counter
+}
+
+// Helper functions for storage
+fn get_token_contract(env: &Env) -> Address {
+ env.storage()
+ .instance()
+ .get(&DataKey::TokenContract)
+ .expect("Contract not initialized")
+}
+
+fn set_token_contract(env: &Env, token_contract: &Address) {
+ env.storage().instance().set(&DataKey::TokenContract, token_contract);
+}
+
+fn get_token_id(env: &Env) -> u128 {
+ env.storage()
+ .instance()
+ .get(&DataKey::TokenId)
+ .expect("Contract not initialized")
+}
+
+fn set_token_id(env: &Env, token_id: &u128) {
+ env.storage().instance().set(&DataKey::TokenId, token_id);
+}
+
+fn get_implementation_hash(env: &Env) -> BytesN<32> {
+ env.storage()
+ .instance()
+ .get(&DataKey::ImplementationHash)
+ .expect("Contract not initialized")
+}
+
+fn set_implementation_hash(env: &Env, implementation_hash: &BytesN<32>) {
+ env.storage()
+ .instance()
+ .set(&DataKey::ImplementationHash, implementation_hash);
+}
+
+fn get_salt(env: &Env) -> BytesN<32> {
+ env.storage()
+ .instance()
+ .get(&DataKey::Salt)
+ .expect("Contract not initialized")
+}
+
+fn set_salt(env: &Env, salt: &BytesN<32>) {
+ env.storage().instance().set(&DataKey::Salt, salt);
+}
+
+fn is_initialized(env: &Env) -> bool {
+ env.storage()
+ .instance()
+ .get(&DataKey::Initialized)
+ .unwrap_or(false)
+}
+
+fn set_initialized(env: &Env, initialized: &bool) {
+ env.storage().instance().set(&DataKey::Initialized, initialized);
+}
+
+fn get_nonce(env: &Env) -> u64 {
+ env.storage()
+ .instance()
+ .get(&DataKey::Nonce)
+ .unwrap_or(0u64)
+}
+
+fn increment_nonce(env: &Env) -> u64 {
+ let current_nonce = get_nonce(env);
+ let new_nonce = current_nonce + 1;
+ env.storage().instance().set(&DataKey::Nonce, &new_nonce);
+ new_nonce
+}
+
+#[contracttype]
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct TransactionExecutedEvent {
+ pub to: Address,
+ pub func: Symbol,
+ pub nonce: u64,
+}
+
+// Helper function to get NFT owner by calling the NFT contract
+fn get_nft_owner(env: &Env, nft_contract: &Address, token_id: u128) -> Address {
+ // Call the NFT contract's owner_of function
+ // Using invoke_contract to call the owner_of function on the NFT contract
+ env.invoke_contract::
(
+ nft_contract,
+ &soroban_sdk::symbol_short!("owner_of"),
+ soroban_sdk::vec![&env, Val::from_payload(token_id as u64)],
+ )
+}
+
+#[contractimpl]
+impl TbaAccount {
+ /// Initialize the TBA account with NFT ownership details
+ /// This should be called once after deployment by the Registry
+ pub fn initialize(
+ env: Env,
+ token_contract: Address,
+ token_id: u128,
+ implementation_hash: BytesN<32>,
+ salt: BytesN<32>,
+ ) {
+ // Prevent re-initialization
+ if is_initialized(&env) {
+ panic!("Contract already initialized");
+ }
+
+ // Store all parameters
+ set_token_contract(&env, &token_contract);
+ set_token_id(&env, &token_id);
+ set_implementation_hash(&env, &implementation_hash);
+ set_salt(&env, &salt);
+ set_initialized(&env, &true);
+ }
+
+ /// Get the NFT contract address
+ pub fn token_contract(env: Env) -> Address {
+ get_token_contract(&env)
+ }
+
+ /// Get the token ID
+ pub fn token_id(env: Env) -> u128 {
+ get_token_id(&env)
+ }
+
+ /// Get the current owner of the NFT (by querying the NFT contract)
+ pub fn owner(env: Env) -> Address {
+ let token_contract = get_token_contract(&env);
+ let token_id = get_token_id(&env);
+ get_nft_owner(&env, &token_contract, token_id)
+ }
+
+ /// Get token details as a tuple: (chain_id, token_contract, token_id)
+ /// This matches the ERC-6551 pattern for compatibility
+ /// Note: chain_id is set to 0 as Soroban doesn't expose chain_id in the same way
+ pub fn token(env: Env) -> (u32, Address, u128) {
+ // Soroban doesn't have chain_id exposed, using 0 as placeholder
+ // In production, this could be set during initialization
+ let chain_id = 0u32;
+ let token_contract = get_token_contract(&env);
+ let token_id = get_token_id(&env);
+ (chain_id, token_contract, token_id)
+ }
+
+ /// Get the current nonce
+ pub fn nonce(env: Env) -> u64 {
+ get_nonce(&env)
+ }
+
+ /// Execute a transaction to another contract
+ /// Only the current NFT owner can execute transactions
+ /// This function increments the nonce and emits an event
+ pub fn execute(
+ env: Env,
+ to: Address,
+ func: Symbol,
+ args: Vec,
+ ) -> Vec {
+ // Verify contract is initialized
+ if !is_initialized(&env) {
+ panic!("Contract not initialized");
+ }
+
+ // Get the NFT owner and verify authorization
+ let token_contract = get_token_contract(&env);
+ let token_id = get_token_id(&env);
+ let owner = get_nft_owner(&env, &token_contract, token_id);
+
+ // Require authorization from the NFT owner
+ owner.require_auth();
+
+ // Increment nonce
+ let nonce = increment_nonce(&env);
+
+ // Emit transaction executed event
+ let event = TransactionExecutedEvent {
+ to: to.clone(),
+ func: func.clone(),
+ nonce,
+ };
+ env.events().publish(
+ (Symbol::new(&env, "executed"), Symbol::new(&env, "TransactionExecuted")),
+ event,
+ );
+
+ // Invoke the target contract
+ env.invoke_contract::>(&to, &func, args)
+ }
+
+ /// CustomAccountInterface implementation: Check authorization
+ /// Only the current NFT owner can authorize transactions
+ pub fn __check_auth(
+ env: Env,
+ signature_payload: BytesN<32>,
+ signatures: Vec>,
+ auth_context: Vec,
+ ) {
+ // Get the NFT contract and token ID
+ let token_contract = get_token_contract(&env);
+ let token_id = get_token_id(&env);
+
+ // Get the current owner of the NFT
+ let owner = get_nft_owner(&env, &token_contract, token_id);
+
+ // Verify that the owner has authorized this transaction
+ // The require_auth_for_args will check if the owner has signed
+ owner.require_auth_for_args(
+ soroban_sdk::vec![
+ &env,
+ Val::from(signature_payload),
+ Val::from(signatures),
+ Val::from(auth_context),
+ ],
+ );
+ }
+}
+
+#[cfg(test)]
+mod test;
+
diff --git a/soroban-contract/contracts/tba_account/src/test.rs b/soroban-contract/contracts/tba_account/src/test.rs
new file mode 100644
index 0000000..15ddb0c
--- /dev/null
+++ b/soroban-contract/contracts/tba_account/src/test.rs
@@ -0,0 +1,126 @@
+#![cfg(test)]
+
+use super::*;
+use soroban_sdk::{
+ testutils::Address as _,
+ vec, Address, BytesN, Env, Symbol,
+};
+
+// Mock NFT contract for testing
+#[contract]
+pub struct MockNftContract;
+
+#[contractimpl]
+impl MockNftContract {
+ pub fn owner_of(_env: Env, _token_id: u128) -> Address {
+ // Simple mock: return a generated address
+ // In real tests, you'd maintain a mapping of token_id -> owner
+ // For now, we'll use a generated address for testing
+ // This is a placeholder - actual tests would need proper NFT contract integration
+ Address::generate(&_env)
+ }
+}
+
+// Helper to create test environment
+fn create_test_env() -> Env {
+ let env = Env::default();
+ env
+}
+
+#[test]
+fn test_initialize() {
+ let env = create_test_env();
+ let contract_id = env.register(TbaAccount, ());
+ let client = TbaAccountClient::new(&env, &contract_id);
+
+ let nft_contract = Address::generate(&env);
+ let token_id = 1u128;
+ let impl_hash = BytesN::from_array(&env, &[1u8; 32]);
+ let salt = BytesN::from_array(&env, &[2u8; 32]);
+
+ // Initialize should succeed
+ client.initialize(&nft_contract, &token_id, &impl_hash, &salt);
+
+ // Verify initialization
+ assert_eq!(client.token_contract(), nft_contract);
+ assert_eq!(client.token_id(), token_id);
+}
+
+#[test]
+#[should_panic(expected = "Contract already initialized")]
+fn test_initialize_twice_panics() {
+ let env = create_test_env();
+ let contract_id = env.register(TbaAccount, ());
+ let client = TbaAccountClient::new(&env, &contract_id);
+
+ let nft_contract = Address::generate(&env);
+ let token_id = 1u128;
+ let impl_hash = BytesN::from_array(&env, &[1u8; 32]);
+ let salt = BytesN::from_array(&env, &[2u8; 32]);
+
+ // First initialization
+ client.initialize(&nft_contract, &token_id, &impl_hash, &salt);
+
+ // Second initialization should panic
+ client.initialize(&nft_contract, &token_id, &impl_hash, &salt);
+}
+
+#[test]
+fn test_getter_functions() {
+ let env = create_test_env();
+ let contract_id = env.register(TbaAccount, ());
+ let client = TbaAccountClient::new(&env, &contract_id);
+
+ let nft_contract = Address::generate(&env);
+ let token_id = 42u128;
+ let impl_hash = BytesN::from_array(&env, &[1u8; 32]);
+ let salt = BytesN::from_array(&env, &[2u8; 32]);
+
+ client.initialize(&nft_contract, &token_id, &impl_hash, &salt);
+
+ // Test getters
+ assert_eq!(client.token_contract(), nft_contract);
+ assert_eq!(client.token_id(), token_id);
+
+ let (chain_id, contract_addr, id) = client.token();
+ assert_eq!(chain_id, 0u32); // We set it to 0
+ assert_eq!(contract_addr, nft_contract);
+ assert_eq!(id, token_id);
+}
+
+#[test]
+fn test_nonce_initial_value() {
+ let env = create_test_env();
+ let contract_id = env.register(TbaAccount, ());
+ let client = TbaAccountClient::new(&env, &contract_id);
+
+ let nft_contract = Address::generate(&env);
+ let token_id = 1u128;
+ let impl_hash = BytesN::from_array(&env, &[1u8; 32]);
+ let salt = BytesN::from_array(&env, &[2u8; 32]);
+
+ client.initialize(&nft_contract, &token_id, &impl_hash, &salt);
+
+ // Nonce should start at 0
+ assert_eq!(client.nonce(), 0u64);
+}
+
+#[test]
+#[should_panic(expected = "Contract not initialized")]
+fn test_execute_before_initialization_panics() {
+ let env = create_test_env();
+ let contract_id = env.register(TbaAccount, ());
+ let client = TbaAccountClient::new(&env, &contract_id);
+
+ let target = Address::generate(&env);
+ let func = Symbol::new(&env, "test_func");
+ let args = vec![&env];
+
+ // Execute should panic if not initialized
+ client.execute(&target, &func, &args);
+}
+
+// Note: Testing execute with actual authorization requires more complex setup
+// with proper NFT contract integration and auth simulation.
+// These tests verify the basic structure and initialization.
+
diff --git a/soroban-contract/contracts/tba_account/test_snapshots/test/test_double_initialize.1.json b/soroban-contract/contracts/tba_account/test_snapshots/test/test_double_initialize.1.json
new file mode 100644
index 0000000..07f6ea0
--- /dev/null
+++ b/soroban-contract/contracts/tba_account/test_snapshots/test/test_double_initialize.1.json
@@ -0,0 +1,141 @@
+{
+ "generators": {
+ "address": 2,
+ "nonce": 0
+ },
+ "auth": [
+ [],
+ [],
+ []
+ ],
+ "ledger": {
+ "protocol_version": 22,
+ "sequence_number": 0,
+ "timestamp": 0,
+ "network_id": "0000000000000000000000000000000000000000000000000000000000000000",
+ "base_reserve": 0,
+ "min_persistent_entry_ttl": 4096,
+ "min_temp_entry_ttl": 16,
+ "max_entry_ttl": 6312000,
+ "ledger_entries": [
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": [
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "ImplementationHash"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Initialized"
+ }
+ ]
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Salt"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "0101010101010101010101010101010101010101010101010101010101010101"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TokenContract"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TokenId"
+ }
+ ]
+ },
+ "val": {
+ "u128": {
+ "hi": 0,
+ "lo": 1
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ No newline at end of file
diff --git a/soroban-contract/contracts/tba_account/test_snapshots/test/test_execute_before_initialization_panics.1.json b/soroban-contract/contracts/tba_account/test_snapshots/test/test_execute_before_initialization_panics.1.json
new file mode 100644
index 0000000..5655749
--- /dev/null
+++ b/soroban-contract/contracts/tba_account/test_snapshots/test/test_execute_before_initialization_panics.1.json
@@ -0,0 +1,76 @@
+{
+ "generators": {
+ "address": 2,
+ "nonce": 0
+ },
+ "auth": [
+ [],
+ []
+ ],
+ "ledger": {
+ "protocol_version": 22,
+ "sequence_number": 0,
+ "timestamp": 0,
+ "network_id": "0000000000000000000000000000000000000000000000000000000000000000",
+ "base_reserve": 0,
+ "min_persistent_entry_ttl": 4096,
+ "min_temp_entry_ttl": 16,
+ "max_entry_ttl": 6312000,
+ "ledger_entries": [
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": null
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ No newline at end of file
diff --git a/soroban-contract/contracts/tba_account/test_snapshots/test/test_getter_before_init.1.json b/soroban-contract/contracts/tba_account/test_snapshots/test/test_getter_before_init.1.json
new file mode 100644
index 0000000..a90f00a
--- /dev/null
+++ b/soroban-contract/contracts/tba_account/test_snapshots/test/test_getter_before_init.1.json
@@ -0,0 +1,76 @@
+{
+ "generators": {
+ "address": 1,
+ "nonce": 0
+ },
+ "auth": [
+ [],
+ []
+ ],
+ "ledger": {
+ "protocol_version": 22,
+ "sequence_number": 0,
+ "timestamp": 0,
+ "network_id": "0000000000000000000000000000000000000000000000000000000000000000",
+ "base_reserve": 0,
+ "min_persistent_entry_ttl": 4096,
+ "min_temp_entry_ttl": 16,
+ "max_entry_ttl": 6312000,
+ "ledger_entries": [
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": null
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ No newline at end of file
diff --git a/soroban-contract/contracts/tba_account/test_snapshots/test/test_getter_functions.1.json b/soroban-contract/contracts/tba_account/test_snapshots/test/test_getter_functions.1.json
new file mode 100644
index 0000000..fb73b70
--- /dev/null
+++ b/soroban-contract/contracts/tba_account/test_snapshots/test/test_getter_functions.1.json
@@ -0,0 +1,143 @@
+{
+ "generators": {
+ "address": 2,
+ "nonce": 0
+ },
+ "auth": [
+ [],
+ [],
+ [],
+ [],
+ []
+ ],
+ "ledger": {
+ "protocol_version": 22,
+ "sequence_number": 0,
+ "timestamp": 0,
+ "network_id": "0000000000000000000000000000000000000000000000000000000000000000",
+ "base_reserve": 0,
+ "min_persistent_entry_ttl": 4096,
+ "min_temp_entry_ttl": 16,
+ "max_entry_ttl": 6312000,
+ "ledger_entries": [
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": [
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "ImplementationHash"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "0101010101010101010101010101010101010101010101010101010101010101"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Initialized"
+ }
+ ]
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Salt"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "0202020202020202020202020202020202020202020202020202020202020202"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TokenContract"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TokenId"
+ }
+ ]
+ },
+ "val": {
+ "u128": {
+ "hi": 0,
+ "lo": 42
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ No newline at end of file
diff --git a/soroban-contract/contracts/tba_account/test_snapshots/test/test_initialize.1.json b/soroban-contract/contracts/tba_account/test_snapshots/test/test_initialize.1.json
new file mode 100644
index 0000000..289c76f
--- /dev/null
+++ b/soroban-contract/contracts/tba_account/test_snapshots/test/test_initialize.1.json
@@ -0,0 +1,142 @@
+{
+ "generators": {
+ "address": 2,
+ "nonce": 0
+ },
+ "auth": [
+ [],
+ [],
+ [],
+ []
+ ],
+ "ledger": {
+ "protocol_version": 22,
+ "sequence_number": 0,
+ "timestamp": 0,
+ "network_id": "0000000000000000000000000000000000000000000000000000000000000000",
+ "base_reserve": 0,
+ "min_persistent_entry_ttl": 4096,
+ "min_temp_entry_ttl": 16,
+ "max_entry_ttl": 6312000,
+ "ledger_entries": [
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": [
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "ImplementationHash"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "0101010101010101010101010101010101010101010101010101010101010101"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Initialized"
+ }
+ ]
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Salt"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "0202020202020202020202020202020202020202020202020202020202020202"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TokenContract"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TokenId"
+ }
+ ]
+ },
+ "val": {
+ "u128": {
+ "hi": 0,
+ "lo": 1
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ No newline at end of file
diff --git a/soroban-contract/contracts/tba_account/test_snapshots/test/test_initialize_twice_panics.1.json b/soroban-contract/contracts/tba_account/test_snapshots/test/test_initialize_twice_panics.1.json
new file mode 100644
index 0000000..899a7db
--- /dev/null
+++ b/soroban-contract/contracts/tba_account/test_snapshots/test/test_initialize_twice_panics.1.json
@@ -0,0 +1,141 @@
+{
+ "generators": {
+ "address": 2,
+ "nonce": 0
+ },
+ "auth": [
+ [],
+ [],
+ []
+ ],
+ "ledger": {
+ "protocol_version": 22,
+ "sequence_number": 0,
+ "timestamp": 0,
+ "network_id": "0000000000000000000000000000000000000000000000000000000000000000",
+ "base_reserve": 0,
+ "min_persistent_entry_ttl": 4096,
+ "min_temp_entry_ttl": 16,
+ "max_entry_ttl": 6312000,
+ "ledger_entries": [
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": [
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "ImplementationHash"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "0101010101010101010101010101010101010101010101010101010101010101"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Initialized"
+ }
+ ]
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Salt"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "0202020202020202020202020202020202020202020202020202020202020202"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TokenContract"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TokenId"
+ }
+ ]
+ },
+ "val": {
+ "u128": {
+ "hi": 0,
+ "lo": 1
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ No newline at end of file
diff --git a/soroban-contract/contracts/tba_account/test_snapshots/test/test_nonce_initial_value.1.json b/soroban-contract/contracts/tba_account/test_snapshots/test/test_nonce_initial_value.1.json
new file mode 100644
index 0000000..899a7db
--- /dev/null
+++ b/soroban-contract/contracts/tba_account/test_snapshots/test/test_nonce_initial_value.1.json
@@ -0,0 +1,141 @@
+{
+ "generators": {
+ "address": 2,
+ "nonce": 0
+ },
+ "auth": [
+ [],
+ [],
+ []
+ ],
+ "ledger": {
+ "protocol_version": 22,
+ "sequence_number": 0,
+ "timestamp": 0,
+ "network_id": "0000000000000000000000000000000000000000000000000000000000000000",
+ "base_reserve": 0,
+ "min_persistent_entry_ttl": 4096,
+ "min_temp_entry_ttl": 16,
+ "max_entry_ttl": 6312000,
+ "ledger_entries": [
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": [
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "ImplementationHash"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "0101010101010101010101010101010101010101010101010101010101010101"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Initialized"
+ }
+ ]
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Salt"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "0202020202020202020202020202020202020202020202020202020202020202"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TokenContract"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TokenId"
+ }
+ ]
+ },
+ "val": {
+ "u128": {
+ "hi": 0,
+ "lo": 1
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ No newline at end of file
diff --git a/soroban-contract/contracts/tba_account/test_snapshots/test/test_token_function.1.json b/soroban-contract/contracts/tba_account/test_snapshots/test/test_token_function.1.json
new file mode 100644
index 0000000..5a10820
--- /dev/null
+++ b/soroban-contract/contracts/tba_account/test_snapshots/test/test_token_function.1.json
@@ -0,0 +1,141 @@
+{
+ "generators": {
+ "address": 2,
+ "nonce": 0
+ },
+ "auth": [
+ [],
+ [],
+ []
+ ],
+ "ledger": {
+ "protocol_version": 22,
+ "sequence_number": 0,
+ "timestamp": 0,
+ "network_id": "0000000000000000000000000000000000000000000000000000000000000000",
+ "base_reserve": 0,
+ "min_persistent_entry_ttl": 4096,
+ "min_temp_entry_ttl": 16,
+ "max_entry_ttl": 6312000,
+ "ledger_entries": [
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": [
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "ImplementationHash"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Initialized"
+ }
+ ]
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Salt"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "0101010101010101010101010101010101010101010101010101010101010101"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TokenContract"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TokenId"
+ }
+ ]
+ },
+ "val": {
+ "u128": {
+ "hi": 0,
+ "lo": 42
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ No newline at end of file