Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ft username store contract #32

Merged
merged 9 commits into from
Apr 16, 2024
11 changes: 11 additions & 0 deletions onchain/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub mod interfaces;
use art_peace::ArtPeace;
use interfaces::{IArtPeace, IArtPeaceDispatcher, IArtPeaceDispatcherTrait, Pixel};


mod quests {
pub mod interfaces;
pub mod pixel_quest;
Expand Down Expand Up @@ -33,12 +34,22 @@ mod nfts {
};
}

mod username_store {
pub mod interfaces;
pub mod username_store;

use interfaces::{IUsernameStore, IUsernameStoreDispatcher, IUsernameStoreDispatcherTrait};
use username_store::UsernameStore;
}

mod mocks {
pub mod erc20_mock;
}

#[cfg(test)]
mod tests {
mod art_peace;
mod username_store;
pub(crate) mod utils;
}

36 changes: 36 additions & 0 deletions onchain/src/tests/username_store.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use snforge_std::{declare, ContractClassTrait};
use art_peace::username_store::interfaces::{
IUsernameStoreDispatcher, IUsernameStoreDispatcherTrait
};
use starknet::{ContractAddress, get_caller_address, get_contract_address, contract_address_const};

fn deploy_contract() -> ContractAddress {
let contract = declare("UsernameStore");

return contract.deploy(@ArrayTrait::new()).unwrap();
}

#[test]
fn test_claim_username() {
let contract_address = deploy_contract();
let dispatcher = IUsernameStoreDispatcher { contract_address };
dispatcher.claim_username('deal');

let username_address = dispatcher.get_username('deal');

assert(contract_address != username_address, 'Username not claimed');
}
#[test]
fn test_transfer_username() {
let contract_address = deploy_contract();
let dispatcher = IUsernameStoreDispatcher { contract_address };
dispatcher.claim_username('devsweet');

let second_contract_address = contract_address_const::<1>();

dispatcher.transfer_username('devsweet', second_contract_address);

let username_address = dispatcher.get_username('devsweet');

assert(username_address == second_contract_address, 'Username not Transferred');
}
8 changes: 8 additions & 0 deletions onchain/src/username_store/interfaces.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use starknet::ContractAddress;

#[starknet::interface]
pub trait IUsernameStore<TContractState> {
fn claim_username(ref self: TContractState, key: felt252);
fn transfer_username(ref self: TContractState, key: felt252, new_Address: ContractAddress);
fn get_username(ref self: TContractState, key: felt252) -> ContractAddress;
}
79 changes: 79 additions & 0 deletions onchain/src/username_store/username_store.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
pub mod UserNameClaimErrors {
pub const USERNAME_CLAIMED: felt252 = 'username_claimed';
pub const USERNAME_CANNOT_BE_TRANSFER: felt252 = 'username_cannot_be_transferred';
}

#[starknet::contract]
pub mod UsernameStore {
use starknet::{get_caller_address, ContractAddress, contract_address_const};
use art_peace::username_store::IUsernameStore;
use super::UserNameClaimErrors;

#[storage]
struct Storage {
usernames: LegacyMap::<felt252, ContractAddress>
}

#[event]
#[derive(Drop, starknet::Event)]
enum Event {
UserNameClaimed: UserNameClaimed,
UserNameTransferred: UserNameTransferred
}

#[derive(Drop, starknet::Event)]
struct UserNameClaimed {
#[key]
username: felt252,
address: ContractAddress
}

#[derive(Drop, starknet::Event)]
struct UserNameTransferred {
#[key]
username: felt252,
address: ContractAddress
}

#[abi(embed_v0)]
pub impl UsernameStore of IUsernameStore<ContractState> {
fn claim_username(ref self: ContractState, key: felt252) {
let mut username_address = self.usernames.read(key);

assert(
username_address == contract_address_const::<0>(),
UserNameClaimErrors::USERNAME_CLAIMED
);

self.usernames.write(key, get_caller_address());

self
.emit(
Event::UserNameClaimed(
UserNameClaimed { username: key, address: get_caller_address() }
)
)
}

fn transfer_username(ref self: ContractState, key: felt252, new_Address: ContractAddress) {
let username_address = self.usernames.read(key);

if username_address != get_caller_address() {
core::panic_with_felt252(UserNameClaimErrors::USERNAME_CANNOT_BE_TRANSFER);
}

self.usernames.write(key, new_Address);

self
.emit(
Event::UserNameTransferred(
UserNameTransferred { username: key, address: new_Address }
)
)
}

fn get_username(ref self: ContractState, key: felt252) -> ContractAddress {
self.usernames.read(key)
}
}
}