This first script highlights tournaments setup taken by the Tournament Authority, the Authority has full control over configuration, point and reward distribution.
import { Http } from"@raindrop-studios/events-client";// tournament authority controls the tournamentconstauthority=newHttp.Tournaments.Client(`${os.homedir()}/.config/solana/id.json`,"mainnet-beta");// create a tournament with a max size of 4 participants// do not require any Token Gates or Entry Fee to be paid// keep track of the tournament pubkey returned, all data can be retrieved from this// DETAILS:// An optional Entry Fee can be added that participants must pay to enter the tournament// An optional Token Gate can be added which participants are required to own to be eligible to enter the tournament// Both of these optional arguments can be required togetherconsttournament=awaitauthority.createTournament("<tournament-name>",4,null,null);// Add a token reward, this will move the token(s) into tournament escrow// DETAILS:// unlimited rewards are allowed// collected entry fees can be moved into reward escrow// rewards can be added throughout the tournament// 'rewardMint' must be an already existing mint account created on solana// 'rewardAmount' must be a whole number and factor in decimals// Example: 1 $USDC is '100000' because $USDC has 6 decimalsawaitauthority.addReward("<tournamentPubkey>","<rewardMint>","<rewardAmount>");
With the Tournament configured, participants can now enter the tournament
import { Http } from"@raindrop-studios/events-client";// A Participant initializes their client to enter the tournamentconstparticipant=newHttp.Tournaments.Client(`${os.homedir()}/.config/solana/id.json`,"mainnet-beta");// participant now enters the tournamentawaitparticipant.enterTournament("<tournamentPubkey>");
Once all participants have entered, it's time to start the tournament. When the tournament moves into the started state, no more participants can join.
// start the tournamentawaitauthority.startTournament("<tournamentPubkey>");
Now that the tournament has started, it's time to create a tournament round. A round is simply a collection of matches in which participants face off against each other.
// As this is the first round, the roundIndex is 0// The roundIndex tracks which matches belong to a roundawaitauthority.createRound("<tournamentPubkey>", roundIndex =0);
After the round of matches have been created, it's time to select which participants face each other in each match, this is completely up to the Tournament Authority
// get the list of matches for this roundconstmatches=awaitauthority.getMatchesByRound("<tournamentPubkey>", roundIndex =0, finalized =false);// get the list of tournament participants eligible for this round (all of them in this example)constparticipants=awaitauthority.getParticipantsForRound("<tournamentPubkey>", roundIndex =0);// enter each participant into the match of your choosing// NOTE: this code only enters 1 participant into 1 match, it's open endedawaitauthority.enterMatch("<tournamentPubkey>","<matchPubkey>","<participantPubkey>");
~Matches are now played off chain~
Once the matches finish, it's time to tell Tournaments who won!
// get the list of matches for this roundconstmatches=awaitauthority.getMatchesByRound("<tournamentPubkey>", roundIndex =0, finalized =false);// get the list of tournament participants eligible for this round (all of them in this example)constparticipants=awaitauthority.getParticipantsForRound("<tournamentPubkey>", roundIndex =0);// end the matchawaitauthority.endMatch("<tournamentPubkey>","<matchPubkey>");// set the result of the matchawaitauthority.setMatchResult("<tournamentPubkey>","<matchPubkey>","<winnerPubkey>")
At this point, a full round of a tournament has been played out off-chain and the results have been written on-chain. Repeat this flow until a tournament winner has been determined. For each round, increment the roundIndex by 1.
Lets say the final tournament standings have been determined, it's time to wrap this up!
// end the tournament, no more matches can be playedawaittournamentAuthority.endTournament("<tournamentPubkey>");// get the final standings of the tournament// the first participant in the returned array has the most points// DETAILS:// For each round the match winner is awarded 1 point// Use points to keep track of participant progressconstfinalStandings=awaittournamentAuthority.getStandings("<tournamentPubkey>");// get a reward accountconstrewards=awaittournamentAuthority.getRewards("<tournamentPubkey>");constrewardData=awaittournamentAuthority.getReward(rewards[0]);// In our simple tournament, it's winner take all// distribute our rewards to the winner// NOTE: rewards can be distributed to any number of participantsawaittournamentAuthority.distributeReward("<tournamentPubkey>", finalStandings[0][0],rewardData.address,rewardData.balance);// Once rewards have been distributed, finalize the tournament to make it immutableawaittournamentAuthority.finalizeTournament("<tournamentPubkey>");