Skip to content

Commit

Permalink
Add calldata to quests to allow easier implementation of generic quests
Browse files Browse the repository at this point in the history
  • Loading branch information
b-j-roberts committed Apr 11, 2024
1 parent bf05739 commit 5c22c6c
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 26 deletions.
12 changes: 6 additions & 6 deletions onchain/src/art_peace.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -319,13 +319,13 @@ pub mod ArtPeace {
quests.span()
}

fn claim_daily_quest(ref self: ContractState, day_index: u32, quest_id: u32) {
fn claim_daily_quest(ref self: ContractState, day_index: u32, quest_id: u32, calldata: Span<felt252>) {
let now = starknet::get_block_timestamp();
assert!(now <= self.end_time.read());
// TODO: Only allow to claim the quest of the current day
let quest = self.daily_quests.read((day_index, quest_id));
let user = starknet::get_caller_address();
let reward = IQuestDispatcher { contract_address: quest }.claim(user);
let reward = IQuestDispatcher { contract_address: quest }.claim(user, calldata);
if reward > 0 {
self
.extra_pixels
Expand All @@ -336,12 +336,12 @@ pub mod ArtPeace {
}
}

fn claim_today_quest(ref self: ContractState, quest_id: u32) {
fn claim_today_quest(ref self: ContractState, quest_id: u32, calldata: Span<felt252>) {
let now = starknet::get_block_timestamp();
assert!(now <= self.end_time.read());
let quest = self.daily_quests.read((self.day_index.read(), quest_id));
let user = starknet::get_caller_address();
let reward = IQuestDispatcher { contract_address: quest }.claim(user);
let reward = IQuestDispatcher { contract_address: quest }.claim(user, calldata);
if reward > 0 {
self
.extra_pixels
Expand All @@ -352,12 +352,12 @@ pub mod ArtPeace {
}
}

fn claim_main_quest(ref self: ContractState, quest_id: u32) {
fn claim_main_quest(ref self: ContractState, quest_id: u32, calldata: Span<felt252>) {
let now = starknet::get_block_timestamp();
assert!(now <= self.end_time.read());
let quest = self.main_quests.read(quest_id);
let user = starknet::get_caller_address();
let reward = IQuestDispatcher { contract_address: quest }.claim(user);
let reward = IQuestDispatcher { contract_address: quest }.claim(user, calldata);
if reward > 0 {
self
.extra_pixels
Expand Down
6 changes: 3 additions & 3 deletions onchain/src/interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ pub trait IArtPeace<TContractState> {
fn get_main_quests(self: @TContractState) -> Span<starknet::ContractAddress>;

// Claim quests
fn claim_daily_quest(ref self: TContractState, day_index: u32, quest_id: u32);
fn claim_today_quest(ref self: TContractState, quest_id: u32);
fn claim_main_quest(ref self: TContractState, quest_id: u32);
fn claim_daily_quest(ref self: TContractState, day_index: u32, quest_id: u32, calldata: Span<felt252>);
fn claim_today_quest(ref self: TContractState, quest_id: u32, calldata: Span<felt252>);
fn claim_main_quest(ref self: TContractState, quest_id: u32, calldata: Span<felt252>);

// Stats
fn get_user_pixels_placed(self: @TContractState, user: starknet::ContractAddress) -> u32;
Expand Down
5 changes: 3 additions & 2 deletions onchain/src/quests/interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ use starknet::ContractAddress;
pub struct QuestClaimed {
pub user: ContractAddress,
pub reward: u32,
pub calldata: Span<felt252>,
}

#[starknet::interface]
pub trait IQuest<TContractState> {
// Return the reward for the quest.
fn get_reward(self: @TContractState) -> u32;
// Return if the user can claim the quest.
fn is_claimable(self: @TContractState, user: ContractAddress) -> bool;
fn is_claimable(self: @TContractState, user: ContractAddress, calldata: Span<felt252>) -> bool;
// Claim the quest.
fn claim(ref self: TContractState, user: ContractAddress) -> u32;
fn claim(ref self: TContractState, user: ContractAddress, calldata: Span<felt252>) -> u32;
}
9 changes: 4 additions & 5 deletions onchain/src/quests/pixel_quest.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,13 @@ mod PixelQuest {
}
}

// TODO: Test all
#[abi(embed_v0)]
impl PixelQuest of IQuest<ContractState> {
fn get_reward(self: @ContractState) -> u32 {
return self.reward.read();
}

fn is_claimable(self: @ContractState, user: ContractAddress) -> bool {
fn is_claimable(self: @ContractState, user: ContractAddress, calldata: Span<felt252>) -> bool {
let art_peace = self.art_peace.read();
if self.claimed.read(user) {
return false;
Expand All @@ -92,18 +91,18 @@ mod PixelQuest {
}
}

fn claim(ref self: ContractState, user: ContractAddress) -> u32 {
fn claim(ref self: ContractState, user: ContractAddress, calldata: Span<felt252>) -> u32 {
assert(
get_caller_address() == self.art_peace.read().contract_address,
'Only ArtPeace can claim quests'
);
if !self.is_claimable(user) {
if !self.is_claimable(user, calldata) {
return 0;
}

self.claimed.write(user, true);
let reward = self.reward.read();
self.emit(QuestClaimed { user: user, reward: reward });
self.emit(QuestClaimed { user, reward, calldata });
return reward;
}
}
Expand Down
22 changes: 12 additions & 10 deletions onchain/src/tests/art_peace.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ fn ART_PEACE_CONTRACT() -> ContractAddress {
contract_address_const::<'ArtPeace'>()
}

fn EMPTY_CALLDATA() -> Span<felt252> {
array![].span()
}

fn deploy_contract() -> ContractAddress {
let contract = snf::declare("ArtPeace");
let mut calldata = array![];
Expand Down Expand Up @@ -194,17 +198,17 @@ fn pixel_quest_test() {
let pos = x + y * WIDTH;
let color = 0x5;
art_peace.place_pixel(pos, color);
art_peace.claim_daily_quest(0, 0);
art_peace.claim_main_quest(0);
art_peace.claim_daily_quest(0, 0, EMPTY_CALLDATA());
art_peace.claim_main_quest(0, EMPTY_CALLDATA());
assert!(art_peace.get_extra_pixels_count() == 0, "Extra pixels are wrong after invalid claims");

warp_to_next_available_time(art_peace);
let x = 15;
let y = 25;
let color = 0x7;
art_peace.place_pixel_xy(x, y, color);
art_peace.claim_daily_quest(0, 0);
art_peace.claim_main_quest(0);
art_peace.claim_daily_quest(0, 0, EMPTY_CALLDATA());
art_peace.claim_main_quest(0, EMPTY_CALLDATA());
assert!(art_peace.get_extra_pixels_count() == 0, "Extra pixels are wrong after invalid claims");

warp_to_next_available_time(art_peace);
Expand All @@ -213,8 +217,8 @@ fn pixel_quest_test() {
let pos = x + y * WIDTH;
let color = 0x9;
art_peace.place_pixel(pos, color);
art_peace.claim_daily_quest(0, 0);
art_peace.claim_main_quest(0);
art_peace.claim_daily_quest(0, 0, EMPTY_CALLDATA());
art_peace.claim_main_quest(0, EMPTY_CALLDATA());
assert!(
art_peace.get_extra_pixels_count() == 10, "Extra pixels are wrong after daily quest claim"
);
Expand All @@ -224,8 +228,8 @@ fn pixel_quest_test() {
let y = 35;
let color = 0xB;
art_peace.place_pixel_xy(x, y, color);
art_peace.claim_daily_quest(0, 0);
art_peace.claim_main_quest(0);
art_peace.claim_daily_quest(0, 0, EMPTY_CALLDATA());
art_peace.claim_main_quest(0, EMPTY_CALLDATA());
assert!(
art_peace.get_extra_pixels_count() == 30, "Extra pixels are wrong after main quest claim"
);
Expand Down Expand Up @@ -339,5 +343,3 @@ fn increase_day_panic_test() {
art_peace.increase_day_index();
}
// TODO: test invalid template inputs


1 change: 1 addition & 0 deletions postgres/init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ CREATE TABLE Quests (
);
CREATE INDEX quests_dayIndex_index ON Quests (dayIndex);

-- TODO: Add calldata field
CREATE TABLE UserQuests (
key integer NOT NULL PRIMARY KEY,
userAddress char(64) NOT NULL,
Expand Down

0 comments on commit 5c22c6c

Please sign in to comment.