Skip to content

Commit

Permalink
Feat/game activity paginator (#22)
Browse files Browse the repository at this point in the history
* game activity paginator

* contract todo resolutions; frontend game activity finished with pagination and all distribution info

* game activity fe

* same on prudent pots neutron
  • Loading branch information
magiodev authored Jun 9, 2024
1 parent 8cb21ce commit b521b47
Show file tree
Hide file tree
Showing 15 changed files with 268 additions and 70 deletions.
3 changes: 0 additions & 3 deletions contracts/prudent-pots/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,6 @@ pub fn game_end(

// Ensure both or neither options are provided
if new_raffle_cw721_id.is_some() != new_raffle_cw721_addr.is_some() {
// TODO: Decide if we want the prizes to be part of whitelisted cw721_addrs in GameConfig,
// or if the whitelist should jsut be the ones that gives minBid discount eligibility
return Err(ContractError::InvalidRaffleNft {});
}

Expand Down Expand Up @@ -250,7 +248,6 @@ pub fn game_end(

// Iterate again the msgs generated to know how much tokens effectively we send,
// as total_losing_tokens contains also next game funds we want to preserve.
// TODO: Make this an helper function
let total_outgoing_raffle: Uint128 = raffle_msgs
.iter()
.filter_map(|msg| {
Expand Down
28 changes: 13 additions & 15 deletions contracts/prudent-pots/src/helpers/game_end.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub fn get_raffle_winner(
let mut max_total = Uint128::zero();
let mut winner: Option<String> = None;

// TODO: Early return if there is not raffle.denom_amount nor raffle.cw721_id
// TODO_FUTURE: Early return if there is not raffle.denom_amount nor raffle.cw721_id

// Traverse all player allocations
let all_allocations =
Expand All @@ -128,7 +128,6 @@ pub fn get_raffle_winner(
} else if total_in_winning_pots == max_total {
// In case of a tie, find the earliest bidder among the winning pots
let mut earliest_bid_time = u64::MAX;
// TODO: handle unwrap safely, but I think this should never happen
let mut current_winner = winner;

for &pot_id in winning_pots.iter() {
Expand Down Expand Up @@ -181,7 +180,7 @@ pub fn process_raffle_winner(
let game_config = GAME_CONFIG.load(deps.storage)?;
let raffle = RAFFLE.load(deps.storage)?;

// TODO: Early return here if there is no raffle
// TODO_FUTURE: Early return here if there is no raffle
// if raffle.nft_id && addr is none and denom_prize is_zero() return all default values.

let mut msgs = Vec::new();
Expand Down Expand Up @@ -225,24 +224,25 @@ pub fn process_raffle_winner(
amount: coins(prize_to_distribute.u128(), game_config.game_denom.clone()),
});
msgs.push(send_msg);
// Append attributes
raffle_response_attributes.extend(vec![attr(
"raffle_outgoing_tokens_winner",
recipient.to_string(),
)]);
}
// Append attributes
raffle_response_attributes.extend(vec![attr(
"raffle_outgoing_tokens_winner",
prize_to_distribute,
)]);

if !prize_to_treasury.is_zero() {
let send_msg = CosmosMsg::Bank(BankMsg::Send {
to_address: game_config.fee_address.to_string(),
amount: coins(prize_to_treasury.u128(), game_config.game_denom.clone()),
});
msgs.push(send_msg);
// Append attributes
raffle_response_attributes.extend(vec![attr(
"raffle_outgoing_tokens_treasury",
game_config.fee_address.to_string(),
)]);
}
// Append attributes
raffle_response_attributes.extend(vec![attr(
"raffle_outgoing_tokens_treasury",
prize_to_treasury,
)]);
}
None => {
// Scenarios are:
Expand Down Expand Up @@ -270,8 +270,6 @@ pub fn process_raffle_winner(
}

// Send the new NFTs for the next raffle prize if any to process
// TODO: Check if new_raffle_cw721_id is different from the old one and ensure the address is valid
// if new_raffle_cw721_id != raffle.cw721_token_id || new_raffle_cw721_addr != raffle.cw721_addr {}
if let (Some(cw721_id), Some(cw721_addr)) =
(new_raffle_cw721_id.clone(), new_raffle_cw721_addr.clone())
{
Expand Down
3 changes: 0 additions & 3 deletions contracts/prudent-pots/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ pub fn query_bid_range(deps: Deps, address: Option<String>) -> StdResult<BidRang
Ok(BidRangeResponse { min_bid, max_bid })
}

// TODO: query_bid_range_by_user so we avoid getting nft balance on frontend and we do on the contract.

pub fn query_pot_state(deps: Deps, pot_id: u8) -> StdResult<PotStateResponse> {
let pot = POT_STATES.load(deps.storage, pot_id)?;
Ok(PotStateResponse { pot })
Expand Down Expand Up @@ -118,7 +116,6 @@ pub fn query_raffle_winner(deps: Deps) -> StdResult<RaffleWinnerResponse> {
Ok(RaffleWinnerResponse { raffle_winner })
}

// TODO: This is returning Error: rpc error: code = Unknown desc = Error parsing into type prudent_pots::msg::QueryMsg: Invalid type: query wasm contract failed: unknown request
pub fn query_raffle_denom_split(deps: Deps) -> StdResult<RaffleDenomSplitResponse> {
let (prize_to_distribute, prize_to_treasury) = get_raffle_denom_prize_amounts(&deps).unwrap();

Expand Down
2 changes: 1 addition & 1 deletion contracts/prudent-pots/src/tests/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,4 @@ pub mod tests {
}
}

// TODO: setup_game_raffle_works
// TODO_FUTURE: setup_game_raffle_works
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn test_allocate_tokens_works() {
assert_eq!(pots_state, expected_pots_state);
}

// TODO: Test NFT allocation bid discount for Raffle NFT contract hodlers
// TODO_FUTURE: Test NFT allocation bid discount for Raffle NFT contract hodlers

#[test]
fn test_allocate_tokens_fails() {
Expand Down
1 change: 0 additions & 1 deletion contracts/prudent-pots/src/tests/integration/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ pub fn default_with_balances(
};
let cw721_addr = instantiate_cw721(&mut app, cw721_id, cw721_msg);

// TODO: Move this to another optional subsequent fixture we execute. we can avoid using 1 second and just increase time by GAME_DURATION then
// Instantiate Prudent Pots contract with 5 tokens (1 per pot). Conditionally based on Raffle option field.
let pp_id = app.store_code(pp_contract());
let pp_addr: Addr;
Expand Down
6 changes: 3 additions & 3 deletions contracts/prudent-pots/src/tests/integration/game_end.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ fn test_game_end_one_winner_simple_works() {
assert_approx_eq!(contract_balance.amount, pots_state_total_amount, "0.000001");
}

// TODO: fn test_game_end_multiple_winners_simple_works
// TODO_FUTURE: fn test_game_end_multiple_winners_simple_works

// We instantiate the contract with 5_000_000 "udenom"
// We do not play the first round.
Expand Down Expand Up @@ -427,6 +427,6 @@ fn test_game_end_one_winner_raffle_both_works() {
);
}

// TODO: fn test_game_end_multiple_winners_raffle_both_works
// TODO_FUTURE: fn test_game_end_multiple_winners_raffle_both_works

// TODO: fn test_game_end_multiple_winners_raffle_both_tie_works
// TODO_FUTURE: fn test_game_end_multiple_winners_raffle_both_tie_works
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// tests::integration::fixtures::{default_with_balances, DENOM_GAME},
// };

// TODO: Those cases are not very consistent now that we are not isntantiating with raffle.
// TODO_FUTURE: Those cases are not very consistent now that we are not isntantiating with raffle.

// #[test]
// fn test_instantiate_simple_works() {
Expand Down
6 changes: 3 additions & 3 deletions contracts/prudent-pots/src/tests/prepare_next_game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ mod tests {
// let reallocation_fee_pool = REALLOCATION_FEE_POOL.load(deps.as_mut().storage).unwrap();
// assert_eq!(reallocation_fee_pool, Uint128::zero());

// TODO: PlayerAllocations reset assertion
// TODO_FUTURE: PlayerAllocations reset assertion

// TODO: total_outgoing_tokens assertion variant!
// TODO_FUTURE: total_outgoing_tokens assertion variant!

// Verify pots have been allocated with initial funds, plus user's allocation and include the reallocation fee pool
for pot_id in 1..=5 {
Expand All @@ -57,5 +57,5 @@ mod tests {
}
}

// TODO: prepare_next_game_raffle_works
// TODO_FUTURE: prepare_next_game_raffle_works
}
9 changes: 5 additions & 4 deletions frontend-common/mixin/game.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {mapActions, mapGetters} from "vuex";
import {mapActions, mapGetters, mapMutations} from "vuex";

const mxGame = {
data() {
Expand All @@ -8,7 +8,7 @@ const mxGame = {
},

computed: {
...mapGetters(['userAddress', 'gameState']),
...mapGetters(['userAddress', 'gameState', "gameActivitySelectedRound"]),

timeLeftSeconds() {
if (!this.gameState) return null;
Expand Down Expand Up @@ -47,12 +47,14 @@ const mxGame = {
"fetchRaffleWinner",
"fetchRaffleDenomSplit"
]),
...mapMutations(['setGameActivitySelectedRound']),

async fetchOnce() {
await this.initUser();

await this.fetchGameConfig();
await this.fetchGameState();
this.setGameActivitySelectedRound(this.gameState.round_count) // set the current round for the paginated gameActivity fetch
await this.fetchAllPlayersAllocations() // this is also included in the fetchInterval, we do it twice only the first App render

// Init signer and querier
Expand All @@ -72,10 +74,9 @@ const mxGame = {
// Raffle
await this.fetchRaffle()
await this.fetchRaffleWinner()
// TODO: await this.fetchRaffleDenomSplit()
// try catch to ignore game activity errors
try {
this.fetchGameActivity()
await this.fetchGameActivity(this.gameActivitySelectedRound)
} catch (e) {
console.log(e)
}
Expand Down
2 changes: 1 addition & 1 deletion frontend-common/mixin/pot.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const mxPot = {

formattedPotNames(potIds) {
if (Array.isArray(potIds)) {
return potIds.map(potId => this.getPotName(potId)).join(', ');
return potIds.length ? potIds.map(potId => this.getPotName(potId)).join(', ') : "No winning pots";
}
return this.getPotName(potIds);
}
Expand Down
16 changes: 12 additions & 4 deletions frontend-common/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default createStore({
gameConfig: null,
gameState: null,
gameActivity: null,
gameActivitySelectedRound: null,

pots: [],
winningPots: [],
Expand Down Expand Up @@ -91,6 +92,10 @@ export default createStore({
return state.gameActivity;
},

gameActivitySelectedRound(state) {
return state.gameActivitySelectedRound;
},

allPlayersAllocations(state) {
return state.allPlayersAllocations;
},
Expand Down Expand Up @@ -171,6 +176,10 @@ export default createStore({
state.gameActivity = gameActivity;
},

setGameActivitySelectedRound(state, selectedRound) {
state.gameActivitySelectedRound = selectedRound;
},

setAllPlayersAllocations(state, allPlayersAllocations) {
state.allPlayersAllocations = allPlayersAllocations;
},
Expand Down Expand Up @@ -312,9 +321,10 @@ export default createStore({

let groupedByRoundCount = {};

// Fetch all rounds, that's why round_count is commented out
const data = await state.user.querier.searchTx([
{key: "wasm._contract_address", value: process.env.VUE_APP_CONTRACT},
{key: "wasm.round_count", value: state.gameState.round_count} // TODO: enhance
{key: "wasm.round_count", value: state.gameActivitySelectedRound.toString()}
]);

data.forEach(item => {
Expand Down Expand Up @@ -431,7 +441,7 @@ export default createStore({
const parts = metadata.name.split('#');
const id = parts.length > 1 ? parts[1] : null;

// TODO: create env var
// TODO_FUTURE: create env var
const imageUrl = `https://mintdao-ipfs.b-cdn.net/ipfs/${metadata.image.replace('ipfs://', '')}`

data.raffle.nft = {id, metadata, imageUrl}
Expand Down Expand Up @@ -468,8 +478,6 @@ export default createStore({

// CW721

// TODO: fetchCw721Approved

async fetchCw721Tokens({state, commit}) {
if (!state.user.querier) {
console.error("Querier is not initialized");
Expand Down
Loading

0 comments on commit b521b47

Please sign in to comment.