Skip to content

Commit 77b0d87

Browse files
authored
Merge pull request #13 from aji70/main
feat: Implement Account Creation Functions closes #5
2 parents f316287 + 72a4e7d commit 77b0d87

File tree

7 files changed

+187
-2
lines changed

7 files changed

+187
-2
lines changed

.tool-versions

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
scarb 2.8.4
2-
starknet-foundry 0.32.0
2+
starknet-foundry 0.39.0

src/base/types.cairo

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,11 @@
1-
1+
use starknet::ContractAddress;
2+
#[derive(Drop, Serde, starknet::Store)]
3+
pub struct TokenBoundAccount {
4+
pub id: u256,
5+
pub address: ContractAddress,
6+
pub user_name: felt252,
7+
pub init_param1: felt252,
8+
pub init_param2: felt252,
9+
pub created_at: u64,
10+
pub updated_at: u64,
11+
}

src/chainlib/ChainLib.cairo

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,90 @@
1+
#[starknet::contract]
2+
pub mod ChainLib {
3+
use starknet::storage::{
4+
Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess,
5+
StoragePointerWriteAccess,
6+
};
7+
use starknet::{ContractAddress, get_block_timestamp, get_caller_address};
8+
use crate::interfaces::IChainLib::IChainLib;
9+
use crate::base::types::{TokenBoundAccount};
110

11+
12+
#[storage]
13+
struct Storage {
14+
// Contract addresses for component management
15+
deployed: bool,
16+
current_account_id: u256,
17+
accounts: Map<u256, TokenBoundAccount>,
18+
accountsaddr: Map<ContractAddress, TokenBoundAccount>,
19+
next_course_id: u256,
20+
nuum: Map<u8, u8>,
21+
}
22+
23+
24+
#[constructor]
25+
fn constructor(ref self: ContractState) {
26+
// Store the values in contract state
27+
self.deployed.write(true);
28+
}
29+
30+
#[event]
31+
#[derive(Drop, starknet::Event)]
32+
pub enum Event {
33+
TokenBountAccountcreated: TokenBountAccountcreated,
34+
}
35+
36+
#[derive(Drop, starknet::Event)]
37+
pub struct TokenBountAccountcreated {
38+
pub id: u256,
39+
}
40+
41+
#[abi(embed_v0)]
42+
impl ChainLibNetImpl of IChainLib<ContractState> {
43+
fn create_token_account(
44+
ref self: ContractState, user_name: felt252, init_param1: felt252, init_param2: felt252,
45+
) -> u256 {
46+
// Validate input parameters.
47+
assert!(user_name != 0, "User name cannot be empty");
48+
assert!(init_param1 != 0, "Initialization parameter 1 cannot be empty");
49+
50+
// Retrieve the current account ID before incrementing.
51+
let account_id = self.current_account_id.read();
52+
53+
// Create a new token bound account struct.
54+
let new_token_bound_account = TokenBoundAccount {
55+
id: account_id,
56+
address: get_caller_address(),
57+
user_name: user_name,
58+
init_param1: init_param1,
59+
init_param2: init_param2,
60+
created_at: get_block_timestamp(),
61+
updated_at: get_block_timestamp(),
62+
};
63+
64+
// Store the new account in the accounts map.
65+
self.accounts.write(account_id, new_token_bound_account);
66+
67+
// Increment the account ID counter after using the current value.
68+
self.current_account_id.write(account_id + 1);
69+
70+
// Emit an event to signal the creation of the token bound account.
71+
self.emit(TokenBountAccountcreated { id: account_id });
72+
73+
account_id
74+
}
75+
76+
fn get_token_bound_account(ref self: ContractState, id: u256) -> TokenBoundAccount {
77+
let token_bound_account = self.accounts.read(id);
78+
token_bound_account
79+
}
80+
fn get_token_bound_account_by_owner(
81+
ref self: ContractState, address: ContractAddress
82+
) -> TokenBoundAccount {
83+
let token_bound_account = self.accountsaddr.read(address);
84+
token_bound_account
85+
}
86+
fn test_deployment(ref self: ContractState) -> bool {
87+
self.deployed.read()
88+
}
89+
}
90+
}

src/interfaces/IChainLib.cairo

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,16 @@
1+
use starknet::ContractAddress;
2+
use crate::base::types::{TokenBoundAccount};
13

4+
#[starknet::interface]
5+
pub trait IChainLib<TContractState> {
6+
// Course Management
7+
fn create_token_account(
8+
ref self: TContractState, user_name: felt252, init_param1: felt252, init_param2: felt252,
9+
) -> u256;
10+
11+
fn get_token_bound_account(ref self: TContractState, id: u256) -> TokenBoundAccount;
12+
fn get_token_bound_account_by_owner(
13+
ref self: TContractState, address: ContractAddress
14+
) -> TokenBoundAccount;
15+
fn test_deployment(ref self: TContractState) -> bool;
16+
}

src/lib.cairo

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
pub mod base {
2+
pub mod errors;
3+
pub mod types;
4+
}
15
pub mod chainlib {
26
pub mod ChainLib;
37
}
8+
pub mod interfaces {
9+
pub mod IChainLib;
10+
}
11+

tests/lib.cairo

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#[cfg(test)]
2+
pub mod test_ChainLib;
3+

tests/test_ChainLib.cairo

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,61 @@
1+
// Import the contract modules
2+
use chain_lib::chainlib::ChainLib;
13

4+
use chain_lib::interfaces::IChainLib::{IChainLib, IChainLibDispatcher, IChainLibDispatcherTrait};
5+
use snforge_std::{CheatSpan, ContractClassTrait, DeclareResultTrait, cheat_caller_address, declare};
6+
use starknet::ContractAddress;
7+
use starknet::class_hash::ClassHash;
8+
use starknet::contract_address::contract_address_const;
9+
use starknet::testing::{set_caller_address, set_contract_address};
10+
11+
12+
fn setup() -> ContractAddress {
13+
let declare_result = declare("ChainLib");
14+
assert(declare_result.is_ok(), 'Contract declaration failed');
15+
16+
let contract_class = declare_result.unwrap().contract_class();
17+
let mut calldata = array![];
18+
19+
let deploy_result = contract_class.deploy(@calldata);
20+
assert(deploy_result.is_ok(), 'Contract deployment failed');
21+
22+
let (contract_address, _) = deploy_result.unwrap();
23+
24+
(contract_address)
25+
}
26+
27+
#[test]
28+
fn test_initial_data() {
29+
let contract_address = setup();
30+
31+
let dispatcher = IChainLibDispatcher { contract_address };
32+
33+
// Ensure dispatcher methods exist
34+
let deployed = dispatcher.test_deployment();
35+
36+
assert(deployed == true, 'deployment failed');
37+
}
38+
39+
40+
#[test]
41+
fn test_create_token_bount_account() {
42+
let contract_address = setup();
43+
let dispatcher = IChainLibDispatcher { contract_address };
44+
45+
// Test input values
46+
let user_name: felt252 = 'John';
47+
let init_param1: felt252 = '[email protected]';
48+
let init_param2: felt252 = 'john is a boy';
49+
50+
// Call create_claim
51+
let account_id = dispatcher.create_token_account(user_name, init_param1, init_param2);
52+
53+
// Validate that the claim ID is correctly incremented
54+
assert(account_id == 0, 'account_id should start from 0');
55+
56+
// Retrieve the claim to verify it was stored correctly
57+
let token_bound_account = dispatcher.get_token_bound_account(account_id);
58+
assert(token_bound_account.user_name == user_name, 'namemismatch');
59+
assert(token_bound_account.init_param1 == init_param1, 'init_param1 mismatch');
60+
assert(token_bound_account.init_param2 == init_param2, 'init_param2 mismatch');
61+
}

0 commit comments

Comments
 (0)