From 5cdc9b06872de083c3b6e9faed70139faf929b59 Mon Sep 17 00:00:00 2001 From: Gabriele Picco Date: Thu, 28 Dec 2023 23:04:02 +0100 Subject: [PATCH] :sparkles: Add configurable option to allow multiple scores per player Add configurable option wether to allow or not multiple scores per player --- client/sdk/src/idl/soar.ts | 4646 ++++++++--------- client/sdk/src/idl/tens.ts | 580 +- .../sdk/src/instructions/rawInstructions.ts | 8 +- client/sdk/src/soar.program.ts | 8 +- client/sdk/src/types.ts | 3 + client/tests/soar.ts | 423 +- .../soar/src/instructions/add_leaderboard.rs | 6 + .../soar/src/instructions/submit_score.rs | 31 +- .../src/instructions/update_leaderboard.rs | 12 + programs/soar/src/lib.rs | 15 +- 10 files changed, 2836 insertions(+), 2896 deletions(-) diff --git a/client/sdk/src/idl/soar.ts b/client/sdk/src/idl/soar.ts index 2b9a4eb..3e03bd7 100644 --- a/client/sdk/src/idl/soar.ts +++ b/client/sdk/src/idl/soar.ts @@ -1,525 +1,532 @@ export type Soar = { - "version": "0.1.0", - "name": "soar", - "constants": [ - { - "name": "MAX_TITLE_LEN", - "type": { - "defined": "usize" - }, - "value": "30" - }, - { - "name": "MAX_DESCRIPTION_LEN", - "type": { - "defined": "usize" - }, - "value": "200" + version: "0.1.0"; + name: "soar"; + constants: [ + { + name: "MAX_TITLE_LEN"; + type: { + defined: "usize"; + }; + value: "30"; + }, + { + name: "MAX_DESCRIPTION_LEN"; + type: { + defined: "usize"; + }; + value: "200"; } - ], - "instructions": [ + ]; + instructions: [ { - "name": "initializeGame", - "docs": [ - "Initialize a new [Game] and register its [LeaderBoard]." - ], - "accounts": [ + name: "initializeGame"; + docs: ["Initialize a new [Game] and register its [LeaderBoard]."]; + accounts: [ { - "name": "creator", - "isMut": true, - "isSigner": true + name: "creator"; + isMut: true; + isSigner: true; }, { - "name": "game", - "isMut": true, - "isSigner": true + name: "game"; + isMut: true; + isSigner: true; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; } - ], - "args": [ + ]; + args: [ { - "name": "gameMeta", - "type": { - "defined": "GameAttributes" - } + name: "gameMeta"; + type: { + defined: "GameAttributes"; + }; }, { - "name": "gameAuth", - "type": { - "vec": "publicKey" - } + name: "gameAuth"; + type: { + vec: "publicKey"; + }; } - ] + ]; }, { - "name": "updateGame", - "docs": [ - "Update a [Game]'s meta-information or authority list." - ], - "accounts": [ + name: "updateGame"; + docs: ["Update a [Game]'s meta-information or authority list."]; + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority"; + isMut: false; + isSigner: true; }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer"; + isMut: true; + isSigner: true; }, { - "name": "game", - "isMut": true, - "isSigner": false + name: "game"; + isMut: true; + isSigner: false; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; } - ], - "args": [ - { - "name": "newMeta", - "type": { - "option": { - "defined": "GameAttributes" - } - } - }, - { - "name": "newAuth", - "type": { - "option": { - "vec": "publicKey" - } - } + ]; + args: [ + { + name: "newMeta"; + type: { + option: { + defined: "GameAttributes"; + }; + }; + }, + { + name: "newAuth"; + type: { + option: { + vec: "publicKey"; + }; + }; } - ] + ]; }, { - "name": "addAchievement", - "docs": [ + name: "addAchievement"; + docs: [ "Add a new [Achievement] that can be attained for a particular [Game]." - ], - "accounts": [ + ]; + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority"; + isMut: false; + isSigner: true; }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer"; + isMut: true; + isSigner: true; }, { - "name": "game", - "isMut": true, - "isSigner": false + name: "game"; + isMut: true; + isSigner: false; }, { - "name": "newAchievement", - "isMut": true, - "isSigner": false + name: "newAchievement"; + isMut: true; + isSigner: false; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; } - ], - "args": [ + ]; + args: [ { - "name": "title", - "type": "string" + name: "title"; + type: "string"; }, { - "name": "description", - "type": "string" + name: "description"; + type: "string"; }, { - "name": "nftMeta", - "type": "publicKey" + name: "nftMeta"; + type: "publicKey"; } - ] + ]; }, { - "name": "updateAchievement", - "docs": [ - "Update an [Achievement]'s meta information." - ], - "accounts": [ + name: "updateAchievement"; + docs: ["Update an [Achievement]'s meta information."]; + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority"; + isMut: false; + isSigner: true; }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game"; + isMut: false; + isSigner: false; }, { - "name": "achievement", - "isMut": true, - "isSigner": false + name: "achievement"; + isMut: true; + isSigner: false; } - ], - "args": [ + ]; + args: [ { - "name": "newTitle", - "type": { - "option": "string" - } + name: "newTitle"; + type: { + option: "string"; + }; }, { - "name": "newDescription", - "type": { - "option": "string" - } + name: "newDescription"; + type: { + option: "string"; + }; }, { - "name": "nftMeta", - "type": { - "option": "publicKey" - } + name: "nftMeta"; + type: { + option: "publicKey"; + }; } - ] + ]; }, { - "name": "addLeaderboard", - "docs": [ - "Overwrite the active [LeaderBoard] and set a newly created one." - ], - "accounts": [ + name: "addLeaderboard"; + docs: ["Overwrite the active [LeaderBoard] and set a newly created one."]; + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority"; + isMut: false; + isSigner: true; }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer"; + isMut: true; + isSigner: true; }, { - "name": "game", - "isMut": true, - "isSigner": false + name: "game"; + isMut: true; + isSigner: false; }, { - "name": "leaderboard", - "isMut": true, - "isSigner": false + name: "leaderboard"; + isMut: true; + isSigner: false; }, { - "name": "topEntries", - "isMut": true, - "isSigner": false, - "isOptional": true + name: "topEntries"; + isMut: true; + isSigner: false; + isOptional: true; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; } - ], - "args": [ + ]; + args: [ { - "name": "input", - "type": { - "defined": "RegisterLeaderBoardInput" - } + name: "input"; + type: { + defined: "RegisterLeaderBoardInput"; + }; } - ] + ]; }, { - "name": "updateLeaderboard", - "docs": [ - "Update's a leaderboard's description and nft metadata information." - ], - "accounts": [ + name: "updateLeaderboard"; + docs: [ + "Update's a leaderboard's description, nft metadata information, min/max score, or whether", + "or not multiple scores are allowed for a single player." + ]; + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority"; + isMut: false; + isSigner: true; }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game"; + isMut: false; + isSigner: false; }, { - "name": "leaderboard", - "isMut": true, - "isSigner": false + name: "leaderboard"; + isMut: true; + isSigner: false; } - ], - "args": [ + ]; + args: [ { - "name": "newDescription", - "type": { - "option": "string" - } + name: "newDescription"; + type: { + option: "string"; + }; }, { - "name": "newNftMeta", - "type": { - "option": "publicKey" - } + name: "newNftMeta"; + type: { + option: "publicKey"; + }; + }, + { + name: "newMinScore"; + type: { + option: "u64"; + }; + }, + { + name: "newMaxScore"; + type: { + option: "u64"; + }; + }, + { + name: "newAllowMultipleScores"; + type: { + option: "bool"; + }; } - ] + ]; }, { - "name": "initializePlayer", - "docs": [ - "Create a [Player] account for a particular user." - ], - "accounts": [ + name: "initializePlayer"; + docs: ["Create a [Player] account for a particular user."]; + accounts: [ { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer"; + isMut: true; + isSigner: true; }, { - "name": "user", - "isMut": false, - "isSigner": true + name: "user"; + isMut: false; + isSigner: true; }, { - "name": "playerAccount", - "isMut": true, - "isSigner": false + name: "playerAccount"; + isMut: true; + isSigner: false; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; } - ], - "args": [ + ]; + args: [ { - "name": "username", - "type": "string" + name: "username"; + type: "string"; }, { - "name": "nftMeta", - "type": "publicKey" + name: "nftMeta"; + type: "publicKey"; } - ] + ]; }, { - "name": "updatePlayer", - "docs": [ - "Update the username or nft_meta for a [Player] account." - ], - "accounts": [ + name: "updatePlayer"; + docs: ["Update the username or nft_meta for a [Player] account."]; + accounts: [ { - "name": "user", - "isMut": false, - "isSigner": true + name: "user"; + isMut: false; + isSigner: true; }, { - "name": "playerAccount", - "isMut": true, - "isSigner": false + name: "playerAccount"; + isMut: true; + isSigner: false; } - ], - "args": [ + ]; + args: [ { - "name": "username", - "type": { - "option": "string" - } + name: "username"; + type: { + option: "string"; + }; }, { - "name": "nftMeta", - "type": { - "option": "publicKey" - } + name: "nftMeta"; + type: { + option: "publicKey"; + }; } - ] + ]; }, { - "name": "registerPlayer", - "docs": [ + name: "registerPlayer"; + docs: [ "Register a [Player] for a particular [Leaderboard], resulting in a newly-", "created [PlayerEntryList] account." - ], - "accounts": [ + ]; + accounts: [ { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer"; + isMut: true; + isSigner: true; }, { - "name": "user", - "isMut": false, - "isSigner": true + name: "user"; + isMut: false; + isSigner: true; }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount"; + isMut: false; + isSigner: false; }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game"; + isMut: false; + isSigner: false; }, { - "name": "leaderboard", - "isMut": false, - "isSigner": false + name: "leaderboard"; + isMut: false; + isSigner: false; }, { - "name": "newList", - "isMut": true, - "isSigner": false + name: "newList"; + isMut: true; + isSigner: false; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; } - ], - "args": [] + ]; + args: []; }, { - "name": "submitScore", - "docs": [ + name: "submitScore"; + docs: [ "Submit a score for a player and have it timestamped and added to the [PlayerEntryList].", "Optionally increase the player's rank if needed.", "", "This instruction automatically resizes the [PlayerScoresList] account if needed." - ], - "accounts": [ + ]; + accounts: [ { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer"; + isMut: true; + isSigner: true; }, { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority"; + isMut: false; + isSigner: true; }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount"; + isMut: false; + isSigner: false; }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game"; + isMut: false; + isSigner: false; }, { - "name": "leaderboard", - "isMut": false, - "isSigner": false + name: "leaderboard"; + isMut: false; + isSigner: false; }, { - "name": "playerScores", - "isMut": true, - "isSigner": false + name: "playerScores"; + isMut: true; + isSigner: false; }, { - "name": "topEntries", - "isMut": true, - "isSigner": false, - "isOptional": true + name: "topEntries"; + isMut: true; + isSigner: false; + isOptional: true; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; } - ], - "args": [ + ]; + args: [ { - "name": "score", - "type": "u64" + name: "score"; + type: "u64"; } - ] + ]; }, { - "name": "initiateMerge", - "docs": [ + name: "initiateMerge"; + docs: [ "Initialize a new merge account and await approval from the verified users of all the", "specified [Player] accounts.", "", "A merge is complete when all the users of the [Player] account keys referenced in it", "have signed to set their approval to `true`." - ], - "accounts": [ + ]; + accounts: [ { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer"; + isMut: true; + isSigner: true; }, { - "name": "user", - "isMut": false, - "isSigner": true + name: "user"; + isMut: false; + isSigner: true; }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount"; + isMut: false; + isSigner: false; }, { - "name": "mergeAccount", - "isMut": true, - "isSigner": true + name: "mergeAccount"; + isMut: true; + isSigner: true; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; } - ], - "args": [ + ]; + args: [ { - "name": "keys", - "type": { - "vec": "publicKey" - } + name: "keys"; + type: { + vec: "publicKey"; + }; } - ] + ]; }, { - "name": "approveMerge", - "docs": [ + name: "approveMerge"; + docs: [ "Register merge confirmation for a particular [Player] account included in a [Merged]." - ], - "accounts": [ + ]; + accounts: [ { - "name": "user", - "isMut": false, - "isSigner": true + name: "user"; + isMut: false; + isSigner: true; }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount"; + isMut: false; + isSigner: false; }, { - "name": "mergeAccount", - "isMut": true, - "isSigner": false + name: "mergeAccount"; + isMut: true; + isSigner: false; } - ], - "args": [] + ]; + args: []; }, { - "name": "unlockPlayerAchievement", - "docs": [ + name: "unlockPlayerAchievement"; + docs: [ "Unlock a [PlayerAchievement] account without minting a reward.", "", "Used `ONLY` for custom rewards mechanism to setup a [PlayerAchievement] account that", @@ -528,1853 +535,1740 @@ export type Soar = { "Since claim instructions like [claim_ft_reward] and [claim_nft_reward] for reward types", "defined by this program try to initialize this account and will fail if it already exists,", "calling this means opting out of using these functions." - ], - "accounts": [ + ]; + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority"; + isMut: false; + isSigner: true; }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer"; + isMut: true; + isSigner: true; }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount"; + isMut: false; + isSigner: false; }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game"; + isMut: false; + isSigner: false; }, { - "name": "achievement", - "isMut": false, - "isSigner": false + name: "achievement"; + isMut: false; + isSigner: false; }, { - "name": "playerAchievement", - "isMut": true, - "isSigner": false + name: "playerAchievement"; + isMut: true; + isSigner: false; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; } - ], - "args": [] + ]; + args: []; }, { - "name": "addFtReward", - "docs": [ + name: "addFtReward"; + docs: [ "Add a fungible token [Reward] to an [Achievement] to mint to users on unlock.", "", "Overwrites the current reward if one exists." - ], - "accounts": [ + ]; + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority"; + isMut: false; + isSigner: true; }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer"; + isMut: true; + isSigner: true; }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game"; + isMut: false; + isSigner: false; }, { - "name": "achievement", - "isMut": true, - "isSigner": false + name: "achievement"; + isMut: true; + isSigner: false; }, { - "name": "newReward", - "isMut": true, - "isSigner": true + name: "newReward"; + isMut: true; + isSigner: true; }, { - "name": "rewardTokenMint", - "isMut": false, - "isSigner": false + name: "rewardTokenMint"; + isMut: false; + isSigner: false; }, { - "name": "delegateFromTokenAccount", - "isMut": true, - "isSigner": false + name: "delegateFromTokenAccount"; + isMut: true; + isSigner: false; }, { - "name": "tokenAccountOwner", - "isMut": false, - "isSigner": true + name: "tokenAccountOwner"; + isMut: false; + isSigner: true; }, { - "name": "tokenProgram", - "isMut": false, - "isSigner": false + name: "tokenProgram"; + isMut: false; + isSigner: false; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; } - ], - "args": [ + ]; + args: [ { - "name": "input", - "type": { - "defined": "AddNewRewardInput" - } + name: "input"; + type: { + defined: "AddNewRewardInput"; + }; } - ] + ]; }, { - "name": "addNftReward", - "docs": [ + name: "addNftReward"; + docs: [ "Add a nft [Reward] to an [Achievement] to mint to users on unlock.", "", "Overwrites the current reward if one exists." - ], - "accounts": [ + ]; + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority"; + isMut: false; + isSigner: true; }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer"; + isMut: true; + isSigner: true; }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game"; + isMut: false; + isSigner: false; }, { - "name": "achievement", - "isMut": true, - "isSigner": false + name: "achievement"; + isMut: true; + isSigner: false; }, { - "name": "newReward", - "isMut": true, - "isSigner": true + name: "newReward"; + isMut: true; + isSigner: true; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; }, { - "name": "rewardCollectionMint", - "isMut": false, - "isSigner": false, - "isOptional": true + name: "rewardCollectionMint"; + isMut: false; + isSigner: false; + isOptional: true; }, { - "name": "collectionUpdateAuth", - "isMut": false, - "isSigner": true, - "isOptional": true + name: "collectionUpdateAuth"; + isMut: false; + isSigner: true; + isOptional: true; }, { - "name": "collectionMetadata", - "isMut": true, - "isSigner": false, - "isOptional": true + name: "collectionMetadata"; + isMut: true; + isSigner: false; + isOptional: true; }, { - "name": "tokenMetadataProgram", - "isMut": false, - "isSigner": false, - "isOptional": true + name: "tokenMetadataProgram"; + isMut: false; + isSigner: false; + isOptional: true; } - ], - "args": [ + ]; + args: [ { - "name": "input", - "type": { - "defined": "AddNewRewardInput" - } + name: "input"; + type: { + defined: "AddNewRewardInput"; + }; } - ] + ]; }, { - "name": "claimFtReward", - "docs": [ + name: "claimFtReward"; + docs: [ "Mint an NFT reward for unlocking a [PlayerAchievement] account.", "", "This will attempt to create a [PlayerAchievement] account and fail if it already exists.", "", "Relevant `ONLY` if an FT reward is specified for that achievement." - ], - "accounts": [ + ]; + accounts: [ { - "name": "user", - "isMut": false, - "isSigner": false + name: "user"; + isMut: false; + isSigner: false; }, { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority"; + isMut: false; + isSigner: true; }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer"; + isMut: true; + isSigner: true; }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game"; + isMut: false; + isSigner: false; }, { - "name": "achievement", - "isMut": false, - "isSigner": false + name: "achievement"; + isMut: false; + isSigner: false; }, { - "name": "reward", - "isMut": true, - "isSigner": false + name: "reward"; + isMut: true; + isSigner: false; }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount"; + isMut: false; + isSigner: false; }, { - "name": "playerAchievement", - "isMut": true, - "isSigner": false + name: "playerAchievement"; + isMut: true; + isSigner: false; }, { - "name": "sourceTokenAccount", - "isMut": true, - "isSigner": false + name: "sourceTokenAccount"; + isMut: true; + isSigner: false; }, { - "name": "userTokenAccount", - "isMut": true, - "isSigner": false + name: "userTokenAccount"; + isMut: true; + isSigner: false; }, { - "name": "tokenProgram", - "isMut": false, - "isSigner": false + name: "tokenProgram"; + isMut: false; + isSigner: false; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; } - ], - "args": [] + ]; + args: []; }, { - "name": "claimNftReward", - "docs": [ + name: "claimNftReward"; + docs: [ "Mint an NFT reward for unlocking a [PlayerAchievement] account.", "", "This will attempt to create a [PlayerAchievement] account and fail if it already exists.", "", "Relevant `ONLY` if an NFT reward is specified for that achievement." - ], - "accounts": [ + ]; + accounts: [ { - "name": "user", - "isMut": false, - "isSigner": false + name: "user"; + isMut: false; + isSigner: false; }, { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority"; + isMut: false; + isSigner: true; }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game"; + isMut: false; + isSigner: false; }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer"; + isMut: true; + isSigner: true; }, { - "name": "achievement", - "isMut": false, - "isSigner": false + name: "achievement"; + isMut: false; + isSigner: false; }, { - "name": "reward", - "isMut": true, - "isSigner": false + name: "reward"; + isMut: true; + isSigner: false; }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount"; + isMut: false; + isSigner: false; }, { - "name": "playerAchievement", - "isMut": true, - "isSigner": false + name: "playerAchievement"; + isMut: true; + isSigner: false; }, { - "name": "claim", - "isMut": true, - "isSigner": false + name: "claim"; + isMut: true; + isSigner: false; }, { - "name": "newMint", - "isMut": true, - "isSigner": true + name: "newMint"; + isMut: true; + isSigner: true; }, { - "name": "newMetadata", - "isMut": true, - "isSigner": false + name: "newMetadata"; + isMut: true; + isSigner: false; }, { - "name": "newMasterEdition", - "isMut": true, - "isSigner": false + name: "newMasterEdition"; + isMut: true; + isSigner: false; }, { - "name": "mintTo", - "isMut": true, - "isSigner": false + name: "mintTo"; + isMut: true; + isSigner: false; }, { - "name": "tokenMetadataProgram", - "isMut": false, - "isSigner": false + name: "tokenMetadataProgram"; + isMut: false; + isSigner: false; }, { - "name": "associatedTokenProgram", - "isMut": false, - "isSigner": false + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; }, { - "name": "tokenProgram", - "isMut": false, - "isSigner": false + name: "tokenProgram"; + isMut: false; + isSigner: false; }, { - "name": "rent", - "isMut": false, - "isSigner": false + name: "rent"; + isMut: false; + isSigner: false; } - ], - "args": [] + ]; + args: []; }, { - "name": "verifyNftReward", - "docs": [ + name: "verifyNftReward"; + docs: [ "Verify NFT reward as belonging to a particular collection.", "", "Optional: Only relevant if an NFT reward is specified and the reward's", "`collection_mint` is Some(...)" - ], - "accounts": [ + ]; + accounts: [ { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer"; + isMut: true; + isSigner: true; }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game"; + isMut: false; + isSigner: false; }, { - "name": "achievement", - "isMut": false, - "isSigner": false + name: "achievement"; + isMut: false; + isSigner: false; }, { - "name": "reward", - "isMut": false, - "isSigner": false + name: "reward"; + isMut: false; + isSigner: false; }, { - "name": "user", - "isMut": false, - "isSigner": true + name: "user"; + isMut: false; + isSigner: true; }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount"; + isMut: false; + isSigner: false; }, { - "name": "claim", - "isMut": false, - "isSigner": false + name: "claim"; + isMut: false; + isSigner: false; }, { - "name": "playerAchievement", - "isMut": false, - "isSigner": false + name: "playerAchievement"; + isMut: false; + isSigner: false; }, { - "name": "mint", - "isMut": false, - "isSigner": false + name: "mint"; + isMut: false; + isSigner: false; }, { - "name": "metadataToVerify", - "isMut": true, - "isSigner": false + name: "metadataToVerify"; + isMut: true; + isSigner: false; }, { - "name": "collectionMint", - "isMut": false, - "isSigner": false + name: "collectionMint"; + isMut: false; + isSigner: false; }, { - "name": "collectionMetadata", - "isMut": true, - "isSigner": false + name: "collectionMetadata"; + isMut: true; + isSigner: false; }, { - "name": "collectionEdition", - "isMut": false, - "isSigner": false + name: "collectionEdition"; + isMut: false; + isSigner: false; }, { - "name": "tokenMetadataProgram", - "isMut": false, - "isSigner": false + name: "tokenMetadataProgram"; + isMut: false; + isSigner: false; } - ], - "args": [] + ]; + args: []; } - ], - "accounts": [ + ]; + accounts: [ { - "name": "achievement", - "docs": [ + name: "achievement"; + docs: [ "Represents an achievement(with optional rewards) for this game", "that can be attained by players.", "", - "PDA with seeds = `[b\"achievement\", game.key().as_ref(), &id.to_le_bytes()]`", + 'PDA with seeds = `[b"achievement", game.key().as_ref(), &id.to_le_bytes()]`', "", "`id` is an incrementing index stored in the game account." - ], - "type": { - "kind": "struct", - "fields": [ + ]; + type: { + kind: "struct"; + fields: [ { - "name": "game", - "docs": [ + name: "game"; + docs: [ "Public key of the game account this achievement is derived from." - ], - "type": "publicKey" + ]; + type: "publicKey"; }, { - "name": "id", - "docs": [ + name: "id"; + docs: [ "The achievement_count of the game account when this account was", "created, also used as a seed for its PDA." - ], - "type": "u64" + ]; + type: "u64"; }, { - "name": "title", - "docs": [ - "Achievement title." - ], - "type": "string" + name: "title"; + docs: ["Achievement title."]; + type: "string"; }, { - "name": "description", - "docs": [ - "Achievement description." - ], - "type": "string" + name: "description"; + docs: ["Achievement description."]; + type: "string"; }, { - "name": "nftMeta", - "docs": [ + name: "nftMeta"; + docs: [ "Public key of a nft metadata account describing this achievement." - ], - "type": "publicKey" + ]; + type: "publicKey"; }, { - "name": "reward", - "docs": [ + name: "reward"; + docs: [ "Optional: Specify a reward to players for unlocking this achievement." - ], - "type": { - "option": "publicKey" - } + ]; + type: { + option: "publicKey"; + }; } - ] - } + ]; + }; }, { - "name": "game", - "docs": [ - "An account representing a single game." - ], - "type": { - "kind": "struct", - "fields": [ + name: "game"; + docs: ["An account representing a single game."]; + type: { + kind: "struct"; + fields: [ { - "name": "meta", - "docs": [ - "Game meta-information." - ], - "type": { - "defined": "GameAttributes" - } + name: "meta"; + docs: ["Game meta-information."]; + type: { + defined: "GameAttributes"; + }; }, { - "name": "leaderboardCount", - "docs": [ + name: "leaderboardCount"; + docs: [ "Number of leaderboards this game has created. Used both", "in determining the most recent leaderboard address, and", "as a seed for the next leaderboard." - ], - "type": "u64" + ]; + type: "u64"; }, { - "name": "achievementCount", - "docs": [ + name: "achievementCount"; + docs: [ "Number of achievements that exist for this game. Also", "used to determine the u64 seed for the next achievement." - ], - "type": "u64" + ]; + type: "u64"; }, { - "name": "auth", - "docs": [ + name: "auth"; + docs: [ "A collection of pubkeys which each represent a valid", "authority for this game." - ], - "type": { - "vec": "publicKey" - } + ]; + type: { + vec: "publicKey"; + }; } - ] - } + ]; + }; }, { - "name": "leaderBoard", - "docs": [ + name: "leaderBoard"; + docs: [ "Represents a [Game][super::Game]'s leaderboard.", "", - "Seeds: `[b\"leaderboard\", game.key().as_ref(), &id.to_le_bytes()]`" - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "id", - "docs": [ + 'Seeds: `[b"leaderboard", game.key().as_ref(), &id.to_le_bytes()]`' + ]; + type: { + kind: "struct"; + fields: [ + { + name: "id"; + docs: [ "The leaderboard's id, used in deriving its address from the game." - ], - "type": "u64" + ]; + type: "u64"; }, { - "name": "game", - "docs": [ - "The game this leaderboard belongs to and is derived from." - ], - "type": "publicKey" + name: "game"; + docs: ["The game this leaderboard belongs to and is derived from."]; + type: "publicKey"; }, { - "name": "description", - "docs": [ - "Leaderboard description." - ], - "type": "string" + name: "description"; + docs: ["Leaderboard description."]; + type: "string"; }, { - "name": "nftMeta", - "docs": [ + name: "nftMeta"; + docs: [ "Pubkey of an nft metadata account that describes this leaderboard." - ], - "type": "publicKey" + ]; + type: "publicKey"; }, { - "name": "decimals", - "docs": [ - "Used to contextualize scores for this leaderboard." - ], - "type": "u8" + name: "decimals"; + docs: ["Used to contextualize scores for this leaderboard."]; + type: "u8"; }, { - "name": "minScore", - "docs": [ - "Minimum possible score for this leaderboard." - ], - "type": "u64" + name: "minScore"; + docs: ["Minimum possible score for this leaderboard."]; + type: "u64"; }, { - "name": "maxScore", - "docs": [ - "Maximum possible score for this leaderboard." - ], - "type": "u64" + name: "maxScore"; + docs: ["Maximum possible score for this leaderboard."]; + type: "u64"; }, { - "name": "allowMultipleScores", - "docs": [ + name: "allowMultipleScores"; + docs: [ "Whether or not multiple scores are allowed for a single player." - ], - "type": "bool" + ]; + type: "bool"; }, { - "name": "topEntries", - "docs": [ - "Top [entries](ScoreEntry) for a leaderboard." - ], - "type": { - "option": "publicKey" - } + name: "topEntries"; + docs: ["Top [entries](ScoreEntry) for a leaderboard."]; + type: { + option: "publicKey"; + }; } - ] - } + ]; + }; }, { - "name": "merged", - "docs": [ + name: "merged"; + docs: [ "An account that represents a single user's ownership of", "multiple [Player][super::Player] accounts." - ], - "type": { - "kind": "struct", - "fields": [ + ]; + type: { + kind: "struct"; + fields: [ { - "name": "initiator", - "docs": [ - "The user that initialized this merge." - ], - "type": "publicKey" + name: "initiator"; + docs: ["The user that initialized this merge."]; + type: "publicKey"; }, { - "name": "approvals", - "docs": [ + name: "approvals"; + docs: [ "Details of all the player accounts to be merged with the main_user's." - ], - "type": { - "vec": { - "defined": "MergeApproval" - } - } + ]; + type: { + vec: { + defined: "MergeApproval"; + }; + }; }, { - "name": "mergeComplete", - "docs": [ + name: "mergeComplete"; + docs: [ "Set to true when every user in `others` has registered their approval." - ], - "type": "bool" + ]; + type: "bool"; } - ] - } + ]; + }; }, { - "name": "playerAchievement", - "docs": [ + name: "playerAchievement"; + docs: [ "Represents a player's status for a particular [Achievement](super::Achievement).", "", - "Seeds = `[b\"player-achievement\", player.key().as_ref(), achievement.key().as_ref()]`." - ], - "type": { - "kind": "struct", - "fields": [ + 'Seeds = `[b"player-achievement", player.key().as_ref(), achievement.key().as_ref()]`.' + ]; + type: { + kind: "struct"; + fields: [ { - "name": "playerAccount", - "docs": [ - "The user's [player][super::Player] account." - ], - "type": "publicKey" + name: "playerAccount"; + docs: ["The user's [player][super::Player] account."]; + type: "publicKey"; }, { - "name": "achievement", - "docs": [ - "The key of the achievement unlocked for this player." - ], - "type": "publicKey" + name: "achievement"; + docs: ["The key of the achievement unlocked for this player."]; + type: "publicKey"; }, { - "name": "timestamp", - "docs": [ - "Timestamp showing when this achievement was unlocked." - ], - "type": "i64" + name: "timestamp"; + docs: ["Timestamp showing when this achievement was unlocked."]; + type: "i64"; }, { - "name": "unlocked", - "docs": [ - "A player's unlock status for this achievement." - ], - "type": "bool" + name: "unlocked"; + docs: ["A player's unlock status for this achievement."]; + type: "bool"; }, { - "name": "claimed", - "docs": [ - "Whether or not this player has claimed their reward." - ], - "type": "bool" + name: "claimed"; + docs: ["Whether or not this player has claimed their reward."]; + type: "bool"; } - ] - } + ]; + }; }, { - "name": "playerScoresList", - "docs": [ + name: "playerScoresList"; + docs: [ "Holds a list of a [player][super::Player]'s [scores][ScoreEntry])", "for a particular [LeaderBoard].", "", - "Seeds: `[b\"player-scores-list\", player_account.key().as_ref(), leaderboard.key().as_ref()]`" - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "playerAccount", - "docs": [ + 'Seeds: `[b"player-scores-list", player_account.key().as_ref(), leaderboard.key().as_ref()]`' + ]; + type: { + kind: "struct"; + fields: [ + { + name: "playerAccount"; + docs: [ "The player[super::Player] account this entry is derived from" - ], - "type": "publicKey" + ]; + type: "publicKey"; }, { - "name": "leaderboard", - "docs": [ - "The id of the specific leaderboard." - ], - "type": "publicKey" + name: "leaderboard"; + docs: ["The id of the specific leaderboard."]; + type: "publicKey"; }, { - "name": "allocCount", - "docs": [ + name: "allocCount"; + docs: [ "Max number of [scores][ScoreEntry] the current space allocation supports." - ], - "type": "u16" + ]; + type: "u16"; }, { - "name": "scores", - "docs": [ - "Collection of [scores][ScoreEntry]." - ], - "type": { - "vec": { - "defined": "ScoreEntry" - } - } + name: "scores"; + docs: ["Collection of [scores][ScoreEntry]."]; + type: { + vec: { + defined: "ScoreEntry"; + }; + }; } - ] - } + ]; + }; }, { - "name": "player", - "docs": [ + name: "player"; + docs: [ "An account representing a player.", "", - "Seeds: `[b\"player\", user.key().as_ref()]`" - ], - "type": { - "kind": "struct", - "fields": [ + 'Seeds: `[b"player", user.key().as_ref()]`' + ]; + type: { + kind: "struct"; + fields: [ { - "name": "user", - "docs": [ - "The wallet that owns this player-info account" - ], - "type": "publicKey" + name: "user"; + docs: ["The wallet that owns this player-info account"]; + type: "publicKey"; }, { - "name": "username", - "docs": [ - "The player's username." - ], - "type": "string" + name: "username"; + docs: ["The player's username."]; + type: "string"; }, { - "name": "nftMeta", - "docs": [ - "Metadata to represent this player." - ], - "type": "publicKey" + name: "nftMeta"; + docs: ["Metadata to represent this player."]; + type: "publicKey"; } - ] - } + ]; + }; }, { - "name": "nftClaim", - "type": { - "kind": "struct", - "fields": [] - } + name: "nftClaim"; + type: { + kind: "struct"; + fields: []; + }; }, { - "name": "reward", - "docs": [ - "An account representing a reward for a given achievement." - ], - "type": { - "kind": "struct", - "fields": [ + name: "reward"; + docs: ["An account representing a reward for a given achievement."]; + type: { + kind: "struct"; + fields: [ { - "name": "achievement", - "docs": [ - "The achievement this reward is given for." - ], - "type": "publicKey" + name: "achievement"; + docs: ["The achievement this reward is given for."]; + type: "publicKey"; }, { - "name": "availableSpots", - "docs": [ - "Number of available reward spots." - ], - "type": "u64" + name: "availableSpots"; + docs: ["Number of available reward spots."]; + type: "u64"; }, { - "name": "reward", - "docs": [ + name: "reward"; + docs: [ "The reward kind. Current supports Nft and Ft rewards only." - ], - "type": { - "defined": "RewardKind" - } + ]; + type: { + defined: "RewardKind"; + }; } - ] - } + ]; + }; }, { - "name": "leaderTopEntries", - "docs": [ + name: "leaderTopEntries"; + docs: [ "Keeps track of a sorted list of top scores for a leaderboard.", "", - "Seeds = [b\"top-scores\", leaderboard.key().as_ref()]" - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "isAscending", - "docs": [ - "Arrangement order." - ], - "type": "bool" - }, - { - "name": "topScores", - "docs": [ - "Top scores." - ], - "type": { - "vec": { - "defined": "LeaderBoardScore" - } - } - } - ] - } + 'Seeds = [b"top-scores", leaderboard.key().as_ref()]' + ]; + type: { + kind: "struct"; + fields: [ + { + name: "isAscending"; + docs: ["Arrangement order."]; + type: "bool"; + }, + { + name: "topScores"; + docs: ["Top scores."]; + type: { + vec: { + defined: "LeaderBoardScore"; + }; + }; + } + ]; + }; } - ], - "types": [ + ]; + types: [ { - "name": "GameAttributes", - "docs": [ - "A type that represents game-specific information." - ], - "type": { - "kind": "struct", - "fields": [ + name: "GameAttributes"; + docs: ["A type that represents game-specific information."]; + type: { + kind: "struct"; + fields: [ { - "name": "title", - "docs": [ - "The title of the game, max length = 30 bytes." - ], - "type": "string" + name: "title"; + docs: ["The title of the game, max length = 30 bytes."]; + type: "string"; }, { - "name": "description", - "docs": [ - "The game description, max length = 200 bytes." - ], - "type": "string" + name: "description"; + docs: ["The game description, max length = 200 bytes."]; + type: "string"; }, { - "name": "genre", - "docs": [ - "The game's [genre](super::Genre), as a u8." - ], - "type": "u8" + name: "genre"; + docs: ["The game's [genre](super::Genre), as a u8."]; + type: "u8"; }, { - "name": "gameType", - "docs": [ - "The game's [type](super::GameType), as a u8." - ], - "type": "u8" + name: "gameType"; + docs: ["The game's [type](super::GameType), as a u8."]; + type: "u8"; }, { - "name": "nftMeta", - "docs": [ - "An nft metadata account describing the game." - ], - "type": "publicKey" + name: "nftMeta"; + docs: ["An nft metadata account describing the game."]; + type: "publicKey"; } - ] - } + ]; + }; }, { - "name": "ScoreEntry", - "docs": [ - "A single score entry for a player." - ], - "type": { - "kind": "struct", - "fields": [ + name: "ScoreEntry"; + docs: ["A single score entry for a player."]; + type: { + kind: "struct"; + fields: [ { - "name": "score", - "docs": [ - "The player's score." - ], - "type": "u64" + name: "score"; + docs: ["The player's score."]; + type: "u64"; }, { - "name": "timestamp", - "docs": [ - "When this entry was made." - ], - "type": "i64" + name: "timestamp"; + docs: ["When this entry was made."]; + type: "i64"; } - ] - } + ]; + }; }, { - "name": "MergeApproval", - "docs": [ + name: "MergeApproval"; + docs: [ "Represents a [Player][super::Player] account involved in a merge", "and if that account's user/authority has granted approval." - ], - "type": { - "kind": "struct", - "fields": [ + ]; + type: { + kind: "struct"; + fields: [ { - "name": "key", - "docs": [ - "The player_account pubkey." - ], - "type": "publicKey" + name: "key"; + docs: ["The player_account pubkey."]; + type: "publicKey"; }, { - "name": "approved", - "docs": [ - "User's approval status." - ], - "type": "bool" + name: "approved"; + docs: ["User's approval status."]; + type: "bool"; } - ] - } + ]; + }; }, { - "name": "LeaderBoardScore", - "docs": [ - "An single entry to a [LeaderTopEntries]." - ], - "type": { - "kind": "struct", - "fields": [ + name: "LeaderBoardScore"; + docs: ["An single entry to a [LeaderTopEntries]."]; + type: { + kind: "struct"; + fields: [ { - "name": "player", - "docs": [ - "The player" - ], - "type": "publicKey" + name: "player"; + docs: ["The player"]; + type: "publicKey"; }, { - "name": "entry", - "docs": [ - "The user's [score][super::ScoreEntry]." - ], - "type": { - "defined": "ScoreEntry" - } + name: "entry"; + docs: ["The user's [score][super::ScoreEntry]."]; + type: { + defined: "ScoreEntry"; + }; } - ] - } + ]; + }; }, { - "name": "RegisterLeaderBoardInput", - "docs": [ - "Parameters needed when registering a leaderboard." - ], - "type": { - "kind": "struct", - "fields": [ + name: "RegisterLeaderBoardInput"; + docs: ["Parameters needed when registering a leaderboard."]; + type: { + kind: "struct"; + fields: [ { - "name": "description", - "docs": [ - "Leaderboard description." - ], - "type": "string" + name: "description"; + docs: ["Leaderboard description."]; + type: "string"; }, { - "name": "nftMeta", - "docs": [ - "Nft metadata representing the leaderboard." - ], - "type": "publicKey" + name: "nftMeta"; + docs: ["Nft metadata representing the leaderboard."]; + type: "publicKey"; }, { - "name": "decimals", - "docs": [ + name: "decimals"; + docs: [ "Specify the decimals score values are represented in. Defaults to `0` if [None]." - ], - "type": { - "option": "u8" - } + ]; + type: { + option: "u8"; + }; }, { - "name": "minScore", - "docs": [ + name: "minScore"; + docs: [ "Specifies minimum allowed score. Defaults to `u64::MIN` if [None]." - ], - "type": { - "option": "u64" - } + ]; + type: { + option: "u64"; + }; }, { - "name": "maxScore", - "docs": [ + name: "maxScore"; + docs: [ "Specifies maximum allowed score. Defaults to `u64::MAX` if [None]." - ], - "type": { - "option": "u64" - } + ]; + type: { + option: "u64"; + }; }, { - "name": "scoresToRetain", - "docs": [ - "Number of top scores to store on-chain." - ], - "type": "u8" + name: "scoresToRetain"; + docs: ["Number of top scores to store on-chain."]; + type: "u8"; }, { - "name": "isAscending", - "docs": [ + name: "isAscending"; + docs: [ "Order by which scores are stored. `true` for ascending, `false` for descending." - ], - "type": "bool" + ]; + type: "bool"; }, { - "name": "allowMultipleScores", - "docs": [ + name: "allowMultipleScores"; + docs: [ "Whether or not multiple scores are kept in the leaderboard for a single player." - ], - "type": "bool" + ]; + type: "bool"; } - ] - } + ]; + }; }, { - "name": "AddNewRewardInput", - "docs": [ - "Input to add a new reward for an achievement." - ], - "type": { - "kind": "struct", - "fields": [ + name: "AddNewRewardInput"; + docs: ["Input to add a new reward for an achievement."]; + type: { + kind: "struct"; + fields: [ { - "name": "availableSpots", - "docs": [ - "Number of rewards to be given out." - ], - "type": "u64" + name: "availableSpots"; + docs: ["Number of rewards to be given out."]; + type: "u64"; }, { - "name": "kind", - "docs": [ - "Specific reward kind." - ], - "type": { - "defined": "RewardKindInput" - } + name: "kind"; + docs: ["Specific reward kind."]; + type: { + defined: "RewardKindInput"; + }; } - ] - } + ]; + }; }, { - "name": "GameType", - "type": { - "kind": "enum", - "variants": [ + name: "GameType"; + type: { + kind: "enum"; + variants: [ { - "name": "Mobile" + name: "Mobile"; }, { - "name": "Desktop" + name: "Desktop"; }, { - "name": "Web" + name: "Web"; }, { - "name": "Unspecified" + name: "Unspecified"; } - ] - } + ]; + }; }, { - "name": "Genre", - "type": { - "kind": "enum", - "variants": [ + name: "Genre"; + type: { + kind: "enum"; + variants: [ { - "name": "Rpg" + name: "Rpg"; }, { - "name": "Mmo" + name: "Mmo"; }, { - "name": "Action" + name: "Action"; }, { - "name": "Adventure" + name: "Adventure"; }, { - "name": "Puzzle" + name: "Puzzle"; }, { - "name": "Casual" + name: "Casual"; }, { - "name": "Unspecified" + name: "Unspecified"; } - ] - } + ]; + }; }, { - "name": "RewardKind", - "docs": [ - "The kind of reward to be given out." - ], - "type": { - "kind": "enum", - "variants": [ + name: "RewardKind"; + docs: ["The kind of reward to be given out."]; + type: { + kind: "enum"; + variants: [ { - "name": "FungibleToken", - "fields": [ + name: "FungibleToken"; + fields: [ { - "name": "mint", - "docs": [ - "The mint of the token to be given out." - ], - "type": "publicKey" + name: "mint"; + docs: ["The mint of the token to be given out."]; + type: "publicKey"; }, { - "name": "account", - "docs": [ - "The token account to withdraw from." - ], - "type": "publicKey" + name: "account"; + docs: ["The token account to withdraw from."]; + type: "publicKey"; }, { - "name": "amount", - "docs": [ - "Reward amount per user." - ], - "type": "u64" + name: "amount"; + docs: ["Reward amount per user."]; + type: "u64"; } - ] + ]; }, { - "name": "NonFungibleToken", - "fields": [ + name: "NonFungibleToken"; + fields: [ { - "name": "uri", - "docs": [ - "URI of the NFT to be minted." - ], - "type": "string" + name: "uri"; + docs: ["URI of the NFT to be minted."]; + type: "string"; }, { - "name": "name", - "docs": [ - "Name of the NFT to be minted." - ], - "type": "string" + name: "name"; + docs: ["Name of the NFT to be minted."]; + type: "string"; }, { - "name": "symbol", - "docs": [ - "Symbol of the NFT to be minted." - ], - "type": "string" + name: "symbol"; + docs: ["Symbol of the NFT to be minted."]; + type: "string"; }, { - "name": "minted", - "docs": [ - "Total NFTs minted so far." - ], - "type": "u64" + name: "minted"; + docs: ["Total NFTs minted so far."]; + type: "u64"; }, { - "name": "collection", - "docs": [ + name: "collection"; + docs: [ "Optional field for a collection mint used for", "verifying minted rewards." - ], - "type": { - "option": "publicKey" - } + ]; + type: { + option: "publicKey"; + }; } - ] + ]; } - ] - } + ]; + }; }, { - "name": "RewardKindInput", - "docs": [ - "Specific variant of [AddNewRewardInput]." - ], - "type": { - "kind": "enum", - "variants": [ + name: "RewardKindInput"; + docs: ["Specific variant of [AddNewRewardInput]."]; + type: { + kind: "enum"; + variants: [ { - "name": "Ft", - "fields": [ + name: "Ft"; + fields: [ { - "name": "deposit", - "docs": [ + name: "deposit"; + docs: [ "Amount to be delegated to this program's PDA", "so it can spend for reward claims." - ], - "type": "u64" + ]; + type: "u64"; }, { - "name": "amount", - "docs": [ - "Amount given to a single user." - ], - "type": "u64" + name: "amount"; + docs: ["Amount given to a single user."]; + type: "u64"; } - ] + ]; }, { - "name": "Nft", - "fields": [ + name: "Nft"; + fields: [ { - "name": "uri", - "docs": [ - "Uri of the minted nft." - ], - "type": "string" + name: "uri"; + docs: ["Uri of the minted nft."]; + type: "string"; }, { - "name": "name", - "docs": [ - "Name of the minted nft." - ], - "type": "string" + name: "name"; + docs: ["Name of the minted nft."]; + type: "string"; }, { - "name": "symbol", - "docs": [ - "Symbol of the minted nft." - ], - "type": "string" + name: "symbol"; + docs: ["Symbol of the minted nft."]; + type: "string"; } - ] + ]; } - ] - } + ]; + }; } - ], - "errors": [ + ]; + errors: [ { - "code": 6000, - "name": "InvalidFieldLength", - "msg": "Exceeded max length for field." + code: 6000; + name: "InvalidFieldLength"; + msg: "Exceeded max length for field."; }, { - "code": 6001, - "name": "InvalidAuthority", - "msg": "Invalid authority for instruction" + code: 6001; + name: "InvalidAuthority"; + msg: "Invalid authority for instruction"; }, { - "code": 6002, - "name": "MissingSignature", - "msg": "An expected signature isn't present" + code: 6002; + name: "MissingSignature"; + msg: "An expected signature isn't present"; }, { - "code": 6003, - "name": "NoRewardForAchievement", - "msg": "Reward not specified for this achievement" + code: 6003; + name: "NoRewardForAchievement"; + msg: "Reward not specified for this achievement"; }, { - "code": 6004, - "name": "AccountNotPartOfMerge", - "msg": "The merge account does not include this player account" + code: 6004; + name: "AccountNotPartOfMerge"; + msg: "The merge account does not include this player account"; }, { - "code": 6005, - "name": "ScoreNotWithinBounds", - "msg": "Tried to input score that is below the minimum or above the maximum" + code: 6005; + name: "ScoreNotWithinBounds"; + msg: "Tried to input score that is below the minimum or above the maximum"; }, { - "code": 6006, - "name": "MissingExpectedAccount", - "msg": "An optional but expected account is missing" + code: 6006; + name: "MissingExpectedAccount"; + msg: "An optional but expected account is missing"; }, { - "code": 6007, - "name": "InvalidRewardKind", - "msg": "Invalid reward kind for this instruction" + code: 6007; + name: "InvalidRewardKind"; + msg: "Invalid reward kind for this instruction"; }, { - "code": 6008, - "name": "NoAvailableRewards", - "msg": "No more rewards are being given out for this game" + code: 6008; + name: "NoAvailableRewards"; + msg: "No more rewards are being given out for this game"; } - ] + ]; }; export const IDL: Soar = { - "version": "0.1.0", - "name": "soar", - "constants": [ + version: "0.1.0", + name: "soar", + constants: [ { - "name": "MAX_TITLE_LEN", - "type": { - "defined": "usize" + name: "MAX_TITLE_LEN", + type: { + defined: "usize", }, - "value": "30" + value: "30", }, { - "name": "MAX_DESCRIPTION_LEN", - "type": { - "defined": "usize" + name: "MAX_DESCRIPTION_LEN", + type: { + defined: "usize", }, - "value": "200" - } + value: "200", + }, ], - "instructions": [ + instructions: [ { - "name": "initializeGame", - "docs": [ - "Initialize a new [Game] and register its [LeaderBoard]." - ], - "accounts": [ + name: "initializeGame", + docs: ["Initialize a new [Game] and register its [LeaderBoard]."], + accounts: [ { - "name": "creator", - "isMut": true, - "isSigner": true + name: "creator", + isMut: true, + isSigner: true, }, { - "name": "game", - "isMut": true, - "isSigner": true + name: "game", + isMut: true, + isSigner: true, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } + name: "systemProgram", + isMut: false, + isSigner: false, + }, ], - "args": [ + args: [ { - "name": "gameMeta", - "type": { - "defined": "GameAttributes" - } + name: "gameMeta", + type: { + defined: "GameAttributes", + }, }, { - "name": "gameAuth", - "type": { - "vec": "publicKey" - } - } - ] + name: "gameAuth", + type: { + vec: "publicKey", + }, + }, + ], }, { - "name": "updateGame", - "docs": [ - "Update a [Game]'s meta-information or authority list." - ], - "accounts": [ + name: "updateGame", + docs: ["Update a [Game]'s meta-information or authority list."], + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority", + isMut: false, + isSigner: true, }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer", + isMut: true, + isSigner: true, }, { - "name": "game", - "isMut": true, - "isSigner": false + name: "game", + isMut: true, + isSigner: false, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } + name: "systemProgram", + isMut: false, + isSigner: false, + }, ], - "args": [ + args: [ { - "name": "newMeta", - "type": { - "option": { - "defined": "GameAttributes" - } - } + name: "newMeta", + type: { + option: { + defined: "GameAttributes", + }, + }, }, { - "name": "newAuth", - "type": { - "option": { - "vec": "publicKey" - } - } - } - ] + name: "newAuth", + type: { + option: { + vec: "publicKey", + }, + }, + }, + ], }, { - "name": "addAchievement", - "docs": [ - "Add a new [Achievement] that can be attained for a particular [Game]." + name: "addAchievement", + docs: [ + "Add a new [Achievement] that can be attained for a particular [Game].", ], - "accounts": [ + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority", + isMut: false, + isSigner: true, }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer", + isMut: true, + isSigner: true, }, { - "name": "game", - "isMut": true, - "isSigner": false + name: "game", + isMut: true, + isSigner: false, }, { - "name": "newAchievement", - "isMut": true, - "isSigner": false + name: "newAchievement", + isMut: true, + isSigner: false, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } + name: "systemProgram", + isMut: false, + isSigner: false, + }, ], - "args": [ + args: [ { - "name": "title", - "type": "string" + name: "title", + type: "string", }, { - "name": "description", - "type": "string" + name: "description", + type: "string", }, { - "name": "nftMeta", - "type": "publicKey" - } - ] + name: "nftMeta", + type: "publicKey", + }, + ], }, { - "name": "updateAchievement", - "docs": [ - "Update an [Achievement]'s meta information." - ], - "accounts": [ + name: "updateAchievement", + docs: ["Update an [Achievement]'s meta information."], + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority", + isMut: false, + isSigner: true, }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game", + isMut: false, + isSigner: false, }, { - "name": "achievement", - "isMut": true, - "isSigner": false - } + name: "achievement", + isMut: true, + isSigner: false, + }, ], - "args": [ + args: [ { - "name": "newTitle", - "type": { - "option": "string" - } + name: "newTitle", + type: { + option: "string", + }, }, { - "name": "newDescription", - "type": { - "option": "string" - } + name: "newDescription", + type: { + option: "string", + }, }, { - "name": "nftMeta", - "type": { - "option": "publicKey" - } - } - ] + name: "nftMeta", + type: { + option: "publicKey", + }, + }, + ], }, { - "name": "addLeaderboard", - "docs": [ - "Overwrite the active [LeaderBoard] and set a newly created one." - ], - "accounts": [ + name: "addLeaderboard", + docs: ["Overwrite the active [LeaderBoard] and set a newly created one."], + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority", + isMut: false, + isSigner: true, }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer", + isMut: true, + isSigner: true, }, { - "name": "game", - "isMut": true, - "isSigner": false + name: "game", + isMut: true, + isSigner: false, }, { - "name": "leaderboard", - "isMut": true, - "isSigner": false + name: "leaderboard", + isMut: true, + isSigner: false, }, { - "name": "topEntries", - "isMut": true, - "isSigner": false, - "isOptional": true + name: "topEntries", + isMut: true, + isSigner: false, + isOptional: true, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } + name: "systemProgram", + isMut: false, + isSigner: false, + }, ], - "args": [ + args: [ { - "name": "input", - "type": { - "defined": "RegisterLeaderBoardInput" - } - } - ] + name: "input", + type: { + defined: "RegisterLeaderBoardInput", + }, + }, + ], }, { - "name": "updateLeaderboard", - "docs": [ - "Update's a leaderboard's description and nft metadata information." + name: "updateLeaderboard", + docs: [ + "Update's a leaderboard's description, nft metadata information, min/max score, or whether", + "or not multiple scores are allowed for a single player.", ], - "accounts": [ + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority", + isMut: false, + isSigner: true, }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game", + isMut: false, + isSigner: false, }, { - "name": "leaderboard", - "isMut": true, - "isSigner": false - } + name: "leaderboard", + isMut: true, + isSigner: false, + }, ], - "args": [ + args: [ { - "name": "newDescription", - "type": { - "option": "string" - } + name: "newDescription", + type: { + option: "string", + }, }, { - "name": "newNftMeta", - "type": { - "option": "publicKey" - } - } - ] + name: "newNftMeta", + type: { + option: "publicKey", + }, + }, + { + name: "newMinScore", + type: { + option: "u64", + }, + }, + { + name: "newMaxScore", + type: { + option: "u64", + }, + }, + { + name: "newAllowMultipleScores", + type: { + option: "bool", + }, + }, + ], }, { - "name": "initializePlayer", - "docs": [ - "Create a [Player] account for a particular user." - ], - "accounts": [ + name: "initializePlayer", + docs: ["Create a [Player] account for a particular user."], + accounts: [ { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer", + isMut: true, + isSigner: true, }, { - "name": "user", - "isMut": false, - "isSigner": true + name: "user", + isMut: false, + isSigner: true, }, { - "name": "playerAccount", - "isMut": true, - "isSigner": false + name: "playerAccount", + isMut: true, + isSigner: false, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } + name: "systemProgram", + isMut: false, + isSigner: false, + }, ], - "args": [ + args: [ { - "name": "username", - "type": "string" + name: "username", + type: "string", }, { - "name": "nftMeta", - "type": "publicKey" - } - ] + name: "nftMeta", + type: "publicKey", + }, + ], }, { - "name": "updatePlayer", - "docs": [ - "Update the username or nft_meta for a [Player] account." - ], - "accounts": [ + name: "updatePlayer", + docs: ["Update the username or nft_meta for a [Player] account."], + accounts: [ { - "name": "user", - "isMut": false, - "isSigner": true + name: "user", + isMut: false, + isSigner: true, }, { - "name": "playerAccount", - "isMut": true, - "isSigner": false - } + name: "playerAccount", + isMut: true, + isSigner: false, + }, ], - "args": [ + args: [ { - "name": "username", - "type": { - "option": "string" - } + name: "username", + type: { + option: "string", + }, }, { - "name": "nftMeta", - "type": { - "option": "publicKey" - } - } - ] + name: "nftMeta", + type: { + option: "publicKey", + }, + }, + ], }, { - "name": "registerPlayer", - "docs": [ + name: "registerPlayer", + docs: [ "Register a [Player] for a particular [Leaderboard], resulting in a newly-", - "created [PlayerEntryList] account." + "created [PlayerEntryList] account.", ], - "accounts": [ + accounts: [ { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer", + isMut: true, + isSigner: true, }, { - "name": "user", - "isMut": false, - "isSigner": true + name: "user", + isMut: false, + isSigner: true, }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount", + isMut: false, + isSigner: false, }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game", + isMut: false, + isSigner: false, }, { - "name": "leaderboard", - "isMut": false, - "isSigner": false + name: "leaderboard", + isMut: false, + isSigner: false, }, { - "name": "newList", - "isMut": true, - "isSigner": false + name: "newList", + isMut: true, + isSigner: false, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } + name: "systemProgram", + isMut: false, + isSigner: false, + }, ], - "args": [] + args: [], }, { - "name": "submitScore", - "docs": [ + name: "submitScore", + docs: [ "Submit a score for a player and have it timestamped and added to the [PlayerEntryList].", "Optionally increase the player's rank if needed.", "", - "This instruction automatically resizes the [PlayerScoresList] account if needed." + "This instruction automatically resizes the [PlayerScoresList] account if needed.", ], - "accounts": [ + accounts: [ { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer", + isMut: true, + isSigner: true, }, { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority", + isMut: false, + isSigner: true, }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount", + isMut: false, + isSigner: false, }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game", + isMut: false, + isSigner: false, }, { - "name": "leaderboard", - "isMut": false, - "isSigner": false + name: "leaderboard", + isMut: false, + isSigner: false, }, { - "name": "playerScores", - "isMut": true, - "isSigner": false + name: "playerScores", + isMut: true, + isSigner: false, }, { - "name": "topEntries", - "isMut": true, - "isSigner": false, - "isOptional": true + name: "topEntries", + isMut: true, + isSigner: false, + isOptional: true, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } + name: "systemProgram", + isMut: false, + isSigner: false, + }, ], - "args": [ + args: [ { - "name": "score", - "type": "u64" - } - ] + name: "score", + type: "u64", + }, + ], }, { - "name": "initiateMerge", - "docs": [ + name: "initiateMerge", + docs: [ "Initialize a new merge account and await approval from the verified users of all the", "specified [Player] accounts.", "", "A merge is complete when all the users of the [Player] account keys referenced in it", - "have signed to set their approval to `true`." + "have signed to set their approval to `true`.", ], - "accounts": [ + accounts: [ { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer", + isMut: true, + isSigner: true, }, { - "name": "user", - "isMut": false, - "isSigner": true + name: "user", + isMut: false, + isSigner: true, }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount", + isMut: false, + isSigner: false, }, { - "name": "mergeAccount", - "isMut": true, - "isSigner": true + name: "mergeAccount", + isMut: true, + isSigner: true, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } + name: "systemProgram", + isMut: false, + isSigner: false, + }, ], - "args": [ + args: [ { - "name": "keys", - "type": { - "vec": "publicKey" - } - } - ] + name: "keys", + type: { + vec: "publicKey", + }, + }, + ], }, { - "name": "approveMerge", - "docs": [ - "Register merge confirmation for a particular [Player] account included in a [Merged]." + name: "approveMerge", + docs: [ + "Register merge confirmation for a particular [Player] account included in a [Merged].", ], - "accounts": [ + accounts: [ { - "name": "user", - "isMut": false, - "isSigner": true + name: "user", + isMut: false, + isSigner: true, }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount", + isMut: false, + isSigner: false, }, { - "name": "mergeAccount", - "isMut": true, - "isSigner": false - } + name: "mergeAccount", + isMut: true, + isSigner: false, + }, ], - "args": [] + args: [], }, { - "name": "unlockPlayerAchievement", - "docs": [ + name: "unlockPlayerAchievement", + docs: [ "Unlock a [PlayerAchievement] account without minting a reward.", "", "Used `ONLY` for custom rewards mechanism to setup a [PlayerAchievement] account that", @@ -2382,1328 +2276,1208 @@ export const IDL: Soar = { "", "Since claim instructions like [claim_ft_reward] and [claim_nft_reward] for reward types", "defined by this program try to initialize this account and will fail if it already exists,", - "calling this means opting out of using these functions." + "calling this means opting out of using these functions.", ], - "accounts": [ + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority", + isMut: false, + isSigner: true, }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer", + isMut: true, + isSigner: true, }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount", + isMut: false, + isSigner: false, }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game", + isMut: false, + isSigner: false, }, { - "name": "achievement", - "isMut": false, - "isSigner": false + name: "achievement", + isMut: false, + isSigner: false, }, { - "name": "playerAchievement", - "isMut": true, - "isSigner": false + name: "playerAchievement", + isMut: true, + isSigner: false, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } + name: "systemProgram", + isMut: false, + isSigner: false, + }, ], - "args": [] + args: [], }, { - "name": "addFtReward", - "docs": [ + name: "addFtReward", + docs: [ "Add a fungible token [Reward] to an [Achievement] to mint to users on unlock.", "", - "Overwrites the current reward if one exists." + "Overwrites the current reward if one exists.", ], - "accounts": [ + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority", + isMut: false, + isSigner: true, }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer", + isMut: true, + isSigner: true, }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game", + isMut: false, + isSigner: false, }, { - "name": "achievement", - "isMut": true, - "isSigner": false + name: "achievement", + isMut: true, + isSigner: false, }, { - "name": "newReward", - "isMut": true, - "isSigner": true + name: "newReward", + isMut: true, + isSigner: true, }, { - "name": "rewardTokenMint", - "isMut": false, - "isSigner": false + name: "rewardTokenMint", + isMut: false, + isSigner: false, }, { - "name": "delegateFromTokenAccount", - "isMut": true, - "isSigner": false + name: "delegateFromTokenAccount", + isMut: true, + isSigner: false, }, { - "name": "tokenAccountOwner", - "isMut": false, - "isSigner": true + name: "tokenAccountOwner", + isMut: false, + isSigner: true, }, { - "name": "tokenProgram", - "isMut": false, - "isSigner": false + name: "tokenProgram", + isMut: false, + isSigner: false, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } + name: "systemProgram", + isMut: false, + isSigner: false, + }, ], - "args": [ + args: [ { - "name": "input", - "type": { - "defined": "AddNewRewardInput" - } - } - ] + name: "input", + type: { + defined: "AddNewRewardInput", + }, + }, + ], }, { - "name": "addNftReward", - "docs": [ + name: "addNftReward", + docs: [ "Add a nft [Reward] to an [Achievement] to mint to users on unlock.", "", - "Overwrites the current reward if one exists." + "Overwrites the current reward if one exists.", ], - "accounts": [ + accounts: [ { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority", + isMut: false, + isSigner: true, }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer", + isMut: true, + isSigner: true, }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game", + isMut: false, + isSigner: false, }, { - "name": "achievement", - "isMut": true, - "isSigner": false + name: "achievement", + isMut: true, + isSigner: false, }, { - "name": "newReward", - "isMut": true, - "isSigner": true + name: "newReward", + isMut: true, + isSigner: true, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram", + isMut: false, + isSigner: false, }, { - "name": "rewardCollectionMint", - "isMut": false, - "isSigner": false, - "isOptional": true + name: "rewardCollectionMint", + isMut: false, + isSigner: false, + isOptional: true, }, { - "name": "collectionUpdateAuth", - "isMut": false, - "isSigner": true, - "isOptional": true + name: "collectionUpdateAuth", + isMut: false, + isSigner: true, + isOptional: true, }, { - "name": "collectionMetadata", - "isMut": true, - "isSigner": false, - "isOptional": true + name: "collectionMetadata", + isMut: true, + isSigner: false, + isOptional: true, }, { - "name": "tokenMetadataProgram", - "isMut": false, - "isSigner": false, - "isOptional": true - } + name: "tokenMetadataProgram", + isMut: false, + isSigner: false, + isOptional: true, + }, ], - "args": [ + args: [ { - "name": "input", - "type": { - "defined": "AddNewRewardInput" - } - } - ] + name: "input", + type: { + defined: "AddNewRewardInput", + }, + }, + ], }, { - "name": "claimFtReward", - "docs": [ + name: "claimFtReward", + docs: [ "Mint an NFT reward for unlocking a [PlayerAchievement] account.", "", "This will attempt to create a [PlayerAchievement] account and fail if it already exists.", "", - "Relevant `ONLY` if an FT reward is specified for that achievement." + "Relevant `ONLY` if an FT reward is specified for that achievement.", ], - "accounts": [ + accounts: [ { - "name": "user", - "isMut": false, - "isSigner": false + name: "user", + isMut: false, + isSigner: false, }, { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority", + isMut: false, + isSigner: true, }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer", + isMut: true, + isSigner: true, }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game", + isMut: false, + isSigner: false, }, { - "name": "achievement", - "isMut": false, - "isSigner": false + name: "achievement", + isMut: false, + isSigner: false, }, { - "name": "reward", - "isMut": true, - "isSigner": false + name: "reward", + isMut: true, + isSigner: false, }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount", + isMut: false, + isSigner: false, }, { - "name": "playerAchievement", - "isMut": true, - "isSigner": false + name: "playerAchievement", + isMut: true, + isSigner: false, }, { - "name": "sourceTokenAccount", - "isMut": true, - "isSigner": false + name: "sourceTokenAccount", + isMut: true, + isSigner: false, }, { - "name": "userTokenAccount", - "isMut": true, - "isSigner": false + name: "userTokenAccount", + isMut: true, + isSigner: false, }, { - "name": "tokenProgram", - "isMut": false, - "isSigner": false + name: "tokenProgram", + isMut: false, + isSigner: false, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } + name: "systemProgram", + isMut: false, + isSigner: false, + }, ], - "args": [] + args: [], }, { - "name": "claimNftReward", - "docs": [ + name: "claimNftReward", + docs: [ "Mint an NFT reward for unlocking a [PlayerAchievement] account.", "", "This will attempt to create a [PlayerAchievement] account and fail if it already exists.", "", - "Relevant `ONLY` if an NFT reward is specified for that achievement." + "Relevant `ONLY` if an NFT reward is specified for that achievement.", ], - "accounts": [ + accounts: [ { - "name": "user", - "isMut": false, - "isSigner": false + name: "user", + isMut: false, + isSigner: false, }, { - "name": "authority", - "isMut": false, - "isSigner": true + name: "authority", + isMut: false, + isSigner: true, }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game", + isMut: false, + isSigner: false, }, { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer", + isMut: true, + isSigner: true, }, { - "name": "achievement", - "isMut": false, - "isSigner": false + name: "achievement", + isMut: false, + isSigner: false, }, { - "name": "reward", - "isMut": true, - "isSigner": false + name: "reward", + isMut: true, + isSigner: false, }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount", + isMut: false, + isSigner: false, }, { - "name": "playerAchievement", - "isMut": true, - "isSigner": false + name: "playerAchievement", + isMut: true, + isSigner: false, }, { - "name": "claim", - "isMut": true, - "isSigner": false + name: "claim", + isMut: true, + isSigner: false, }, { - "name": "newMint", - "isMut": true, - "isSigner": true + name: "newMint", + isMut: true, + isSigner: true, }, { - "name": "newMetadata", - "isMut": true, - "isSigner": false + name: "newMetadata", + isMut: true, + isSigner: false, }, { - "name": "newMasterEdition", - "isMut": true, - "isSigner": false + name: "newMasterEdition", + isMut: true, + isSigner: false, }, { - "name": "mintTo", - "isMut": true, - "isSigner": false + name: "mintTo", + isMut: true, + isSigner: false, }, { - "name": "tokenMetadataProgram", - "isMut": false, - "isSigner": false + name: "tokenMetadataProgram", + isMut: false, + isSigner: false, }, { - "name": "associatedTokenProgram", - "isMut": false, - "isSigner": false + name: "associatedTokenProgram", + isMut: false, + isSigner: false, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram", + isMut: false, + isSigner: false, }, { - "name": "tokenProgram", - "isMut": false, - "isSigner": false + name: "tokenProgram", + isMut: false, + isSigner: false, }, { - "name": "rent", - "isMut": false, - "isSigner": false - } + name: "rent", + isMut: false, + isSigner: false, + }, ], - "args": [] + args: [], }, { - "name": "verifyNftReward", - "docs": [ + name: "verifyNftReward", + docs: [ "Verify NFT reward as belonging to a particular collection.", "", "Optional: Only relevant if an NFT reward is specified and the reward's", - "`collection_mint` is Some(...)" + "`collection_mint` is Some(...)", ], - "accounts": [ + accounts: [ { - "name": "payer", - "isMut": true, - "isSigner": true + name: "payer", + isMut: true, + isSigner: true, }, { - "name": "game", - "isMut": false, - "isSigner": false + name: "game", + isMut: false, + isSigner: false, }, { - "name": "achievement", - "isMut": false, - "isSigner": false + name: "achievement", + isMut: false, + isSigner: false, }, { - "name": "reward", - "isMut": false, - "isSigner": false + name: "reward", + isMut: false, + isSigner: false, }, { - "name": "user", - "isMut": false, - "isSigner": true + name: "user", + isMut: false, + isSigner: true, }, { - "name": "playerAccount", - "isMut": false, - "isSigner": false + name: "playerAccount", + isMut: false, + isSigner: false, }, { - "name": "claim", - "isMut": false, - "isSigner": false + name: "claim", + isMut: false, + isSigner: false, }, { - "name": "playerAchievement", - "isMut": false, - "isSigner": false + name: "playerAchievement", + isMut: false, + isSigner: false, }, { - "name": "mint", - "isMut": false, - "isSigner": false + name: "mint", + isMut: false, + isSigner: false, }, { - "name": "metadataToVerify", - "isMut": true, - "isSigner": false + name: "metadataToVerify", + isMut: true, + isSigner: false, }, { - "name": "collectionMint", - "isMut": false, - "isSigner": false + name: "collectionMint", + isMut: false, + isSigner: false, }, { - "name": "collectionMetadata", - "isMut": true, - "isSigner": false + name: "collectionMetadata", + isMut: true, + isSigner: false, }, { - "name": "collectionEdition", - "isMut": false, - "isSigner": false + name: "collectionEdition", + isMut: false, + isSigner: false, }, { - "name": "tokenMetadataProgram", - "isMut": false, - "isSigner": false - } + name: "tokenMetadataProgram", + isMut: false, + isSigner: false, + }, ], - "args": [] - } + args: [], + }, ], - "accounts": [ + accounts: [ { - "name": "achievement", - "docs": [ + name: "achievement", + docs: [ "Represents an achievement(with optional rewards) for this game", "that can be attained by players.", "", - "PDA with seeds = `[b\"achievement\", game.key().as_ref(), &id.to_le_bytes()]`", + 'PDA with seeds = `[b"achievement", game.key().as_ref(), &id.to_le_bytes()]`', "", - "`id` is an incrementing index stored in the game account." + "`id` is an incrementing index stored in the game account.", ], - "type": { - "kind": "struct", - "fields": [ + type: { + kind: "struct", + fields: [ { - "name": "game", - "docs": [ - "Public key of the game account this achievement is derived from." + name: "game", + docs: [ + "Public key of the game account this achievement is derived from.", ], - "type": "publicKey" + type: "publicKey", }, { - "name": "id", - "docs": [ + name: "id", + docs: [ "The achievement_count of the game account when this account was", - "created, also used as a seed for its PDA." + "created, also used as a seed for its PDA.", ], - "type": "u64" + type: "u64", }, { - "name": "title", - "docs": [ - "Achievement title." - ], - "type": "string" + name: "title", + docs: ["Achievement title."], + type: "string", }, { - "name": "description", - "docs": [ - "Achievement description." - ], - "type": "string" + name: "description", + docs: ["Achievement description."], + type: "string", }, { - "name": "nftMeta", - "docs": [ - "Public key of a nft metadata account describing this achievement." + name: "nftMeta", + docs: [ + "Public key of a nft metadata account describing this achievement.", ], - "type": "publicKey" + type: "publicKey", }, { - "name": "reward", - "docs": [ - "Optional: Specify a reward to players for unlocking this achievement." + name: "reward", + docs: [ + "Optional: Specify a reward to players for unlocking this achievement.", ], - "type": { - "option": "publicKey" - } - } - ] - } + type: { + option: "publicKey", + }, + }, + ], + }, }, { - "name": "game", - "docs": [ - "An account representing a single game." - ], - "type": { - "kind": "struct", - "fields": [ + name: "game", + docs: ["An account representing a single game."], + type: { + kind: "struct", + fields: [ { - "name": "meta", - "docs": [ - "Game meta-information." - ], - "type": { - "defined": "GameAttributes" - } + name: "meta", + docs: ["Game meta-information."], + type: { + defined: "GameAttributes", + }, }, { - "name": "leaderboardCount", - "docs": [ + name: "leaderboardCount", + docs: [ "Number of leaderboards this game has created. Used both", "in determining the most recent leaderboard address, and", - "as a seed for the next leaderboard." + "as a seed for the next leaderboard.", ], - "type": "u64" + type: "u64", }, { - "name": "achievementCount", - "docs": [ + name: "achievementCount", + docs: [ "Number of achievements that exist for this game. Also", - "used to determine the u64 seed for the next achievement." + "used to determine the u64 seed for the next achievement.", ], - "type": "u64" + type: "u64", }, { - "name": "auth", - "docs": [ + name: "auth", + docs: [ "A collection of pubkeys which each represent a valid", - "authority for this game." + "authority for this game.", ], - "type": { - "vec": "publicKey" - } - } - ] - } + type: { + vec: "publicKey", + }, + }, + ], + }, }, { - "name": "leaderBoard", - "docs": [ + name: "leaderBoard", + docs: [ "Represents a [Game][super::Game]'s leaderboard.", "", - "Seeds: `[b\"leaderboard\", game.key().as_ref(), &id.to_le_bytes()]`" + 'Seeds: `[b"leaderboard", game.key().as_ref(), &id.to_le_bytes()]`', ], - "type": { - "kind": "struct", - "fields": [ + type: { + kind: "struct", + fields: [ { - "name": "id", - "docs": [ - "The leaderboard's id, used in deriving its address from the game." + name: "id", + docs: [ + "The leaderboard's id, used in deriving its address from the game.", ], - "type": "u64" + type: "u64", }, { - "name": "game", - "docs": [ - "The game this leaderboard belongs to and is derived from." - ], - "type": "publicKey" + name: "game", + docs: ["The game this leaderboard belongs to and is derived from."], + type: "publicKey", }, { - "name": "description", - "docs": [ - "Leaderboard description." - ], - "type": "string" + name: "description", + docs: ["Leaderboard description."], + type: "string", }, { - "name": "nftMeta", - "docs": [ - "Pubkey of an nft metadata account that describes this leaderboard." + name: "nftMeta", + docs: [ + "Pubkey of an nft metadata account that describes this leaderboard.", ], - "type": "publicKey" + type: "publicKey", }, { - "name": "decimals", - "docs": [ - "Used to contextualize scores for this leaderboard." - ], - "type": "u8" + name: "decimals", + docs: ["Used to contextualize scores for this leaderboard."], + type: "u8", }, { - "name": "minScore", - "docs": [ - "Minimum possible score for this leaderboard." - ], - "type": "u64" + name: "minScore", + docs: ["Minimum possible score for this leaderboard."], + type: "u64", }, { - "name": "maxScore", - "docs": [ - "Maximum possible score for this leaderboard." - ], - "type": "u64" + name: "maxScore", + docs: ["Maximum possible score for this leaderboard."], + type: "u64", }, { - "name": "allowMultipleScores", - "docs": [ - "Whether or not multiple scores are allowed for a single player." + name: "allowMultipleScores", + docs: [ + "Whether or not multiple scores are allowed for a single player.", ], - "type": "bool" + type: "bool", }, { - "name": "topEntries", - "docs": [ - "Top [entries](ScoreEntry) for a leaderboard." - ], - "type": { - "option": "publicKey" - } - } - ] - } + name: "topEntries", + docs: ["Top [entries](ScoreEntry) for a leaderboard."], + type: { + option: "publicKey", + }, + }, + ], + }, }, { - "name": "merged", - "docs": [ + name: "merged", + docs: [ "An account that represents a single user's ownership of", - "multiple [Player][super::Player] accounts." + "multiple [Player][super::Player] accounts.", ], - "type": { - "kind": "struct", - "fields": [ + type: { + kind: "struct", + fields: [ { - "name": "initiator", - "docs": [ - "The user that initialized this merge." - ], - "type": "publicKey" + name: "initiator", + docs: ["The user that initialized this merge."], + type: "publicKey", }, { - "name": "approvals", - "docs": [ - "Details of all the player accounts to be merged with the main_user's." + name: "approvals", + docs: [ + "Details of all the player accounts to be merged with the main_user's.", ], - "type": { - "vec": { - "defined": "MergeApproval" - } - } + type: { + vec: { + defined: "MergeApproval", + }, + }, }, { - "name": "mergeComplete", - "docs": [ - "Set to true when every user in `others` has registered their approval." + name: "mergeComplete", + docs: [ + "Set to true when every user in `others` has registered their approval.", ], - "type": "bool" - } - ] - } + type: "bool", + }, + ], + }, }, { - "name": "playerAchievement", - "docs": [ + name: "playerAchievement", + docs: [ "Represents a player's status for a particular [Achievement](super::Achievement).", "", - "Seeds = `[b\"player-achievement\", player.key().as_ref(), achievement.key().as_ref()]`." + 'Seeds = `[b"player-achievement", player.key().as_ref(), achievement.key().as_ref()]`.', ], - "type": { - "kind": "struct", - "fields": [ + type: { + kind: "struct", + fields: [ { - "name": "playerAccount", - "docs": [ - "The user's [player][super::Player] account." - ], - "type": "publicKey" + name: "playerAccount", + docs: ["The user's [player][super::Player] account."], + type: "publicKey", }, { - "name": "achievement", - "docs": [ - "The key of the achievement unlocked for this player." - ], - "type": "publicKey" + name: "achievement", + docs: ["The key of the achievement unlocked for this player."], + type: "publicKey", }, { - "name": "timestamp", - "docs": [ - "Timestamp showing when this achievement was unlocked." - ], - "type": "i64" + name: "timestamp", + docs: ["Timestamp showing when this achievement was unlocked."], + type: "i64", }, { - "name": "unlocked", - "docs": [ - "A player's unlock status for this achievement." - ], - "type": "bool" + name: "unlocked", + docs: ["A player's unlock status for this achievement."], + type: "bool", }, { - "name": "claimed", - "docs": [ - "Whether or not this player has claimed their reward." - ], - "type": "bool" - } - ] - } + name: "claimed", + docs: ["Whether or not this player has claimed their reward."], + type: "bool", + }, + ], + }, }, { - "name": "playerScoresList", - "docs": [ + name: "playerScoresList", + docs: [ "Holds a list of a [player][super::Player]'s [scores][ScoreEntry])", "for a particular [LeaderBoard].", "", - "Seeds: `[b\"player-scores-list\", player_account.key().as_ref(), leaderboard.key().as_ref()]`" + 'Seeds: `[b"player-scores-list", player_account.key().as_ref(), leaderboard.key().as_ref()]`', ], - "type": { - "kind": "struct", - "fields": [ + type: { + kind: "struct", + fields: [ { - "name": "playerAccount", - "docs": [ - "The player[super::Player] account this entry is derived from" + name: "playerAccount", + docs: [ + "The player[super::Player] account this entry is derived from", ], - "type": "publicKey" + type: "publicKey", }, { - "name": "leaderboard", - "docs": [ - "The id of the specific leaderboard." - ], - "type": "publicKey" + name: "leaderboard", + docs: ["The id of the specific leaderboard."], + type: "publicKey", }, { - "name": "allocCount", - "docs": [ - "Max number of [scores][ScoreEntry] the current space allocation supports." + name: "allocCount", + docs: [ + "Max number of [scores][ScoreEntry] the current space allocation supports.", ], - "type": "u16" + type: "u16", }, { - "name": "scores", - "docs": [ - "Collection of [scores][ScoreEntry]." - ], - "type": { - "vec": { - "defined": "ScoreEntry" - } - } - } - ] - } + name: "scores", + docs: ["Collection of [scores][ScoreEntry]."], + type: { + vec: { + defined: "ScoreEntry", + }, + }, + }, + ], + }, }, { - "name": "player", - "docs": [ + name: "player", + docs: [ "An account representing a player.", "", - "Seeds: `[b\"player\", user.key().as_ref()]`" + 'Seeds: `[b"player", user.key().as_ref()]`', ], - "type": { - "kind": "struct", - "fields": [ + type: { + kind: "struct", + fields: [ { - "name": "user", - "docs": [ - "The wallet that owns this player-info account" - ], - "type": "publicKey" + name: "user", + docs: ["The wallet that owns this player-info account"], + type: "publicKey", }, { - "name": "username", - "docs": [ - "The player's username." - ], - "type": "string" + name: "username", + docs: ["The player's username."], + type: "string", }, { - "name": "nftMeta", - "docs": [ - "Metadata to represent this player." - ], - "type": "publicKey" - } - ] - } + name: "nftMeta", + docs: ["Metadata to represent this player."], + type: "publicKey", + }, + ], + }, }, { - "name": "nftClaim", - "type": { - "kind": "struct", - "fields": [] - } + name: "nftClaim", + type: { + kind: "struct", + fields: [], + }, }, { - "name": "reward", - "docs": [ - "An account representing a reward for a given achievement." - ], - "type": { - "kind": "struct", - "fields": [ + name: "reward", + docs: ["An account representing a reward for a given achievement."], + type: { + kind: "struct", + fields: [ { - "name": "achievement", - "docs": [ - "The achievement this reward is given for." - ], - "type": "publicKey" + name: "achievement", + docs: ["The achievement this reward is given for."], + type: "publicKey", }, { - "name": "availableSpots", - "docs": [ - "Number of available reward spots." - ], - "type": "u64" + name: "availableSpots", + docs: ["Number of available reward spots."], + type: "u64", }, { - "name": "reward", - "docs": [ - "The reward kind. Current supports Nft and Ft rewards only." + name: "reward", + docs: [ + "The reward kind. Current supports Nft and Ft rewards only.", ], - "type": { - "defined": "RewardKind" - } - } - ] - } + type: { + defined: "RewardKind", + }, + }, + ], + }, }, { - "name": "leaderTopEntries", - "docs": [ + name: "leaderTopEntries", + docs: [ "Keeps track of a sorted list of top scores for a leaderboard.", "", - "Seeds = [b\"top-scores\", leaderboard.key().as_ref()]" + 'Seeds = [b"top-scores", leaderboard.key().as_ref()]', ], - "type": { - "kind": "struct", - "fields": [ + type: { + kind: "struct", + fields: [ { - "name": "isAscending", - "docs": [ - "Arrangement order." - ], - "type": "bool" + name: "isAscending", + docs: ["Arrangement order."], + type: "bool", }, { - "name": "topScores", - "docs": [ - "Top scores." - ], - "type": { - "vec": { - "defined": "LeaderBoardScore" - } - } - } - ] - } - } + name: "topScores", + docs: ["Top scores."], + type: { + vec: { + defined: "LeaderBoardScore", + }, + }, + }, + ], + }, + }, ], - "types": [ + types: [ { - "name": "GameAttributes", - "docs": [ - "A type that represents game-specific information." - ], - "type": { - "kind": "struct", - "fields": [ + name: "GameAttributes", + docs: ["A type that represents game-specific information."], + type: { + kind: "struct", + fields: [ { - "name": "title", - "docs": [ - "The title of the game, max length = 30 bytes." - ], - "type": "string" + name: "title", + docs: ["The title of the game, max length = 30 bytes."], + type: "string", }, { - "name": "description", - "docs": [ - "The game description, max length = 200 bytes." - ], - "type": "string" + name: "description", + docs: ["The game description, max length = 200 bytes."], + type: "string", }, { - "name": "genre", - "docs": [ - "The game's [genre](super::Genre), as a u8." - ], - "type": "u8" + name: "genre", + docs: ["The game's [genre](super::Genre), as a u8."], + type: "u8", }, { - "name": "gameType", - "docs": [ - "The game's [type](super::GameType), as a u8." - ], - "type": "u8" + name: "gameType", + docs: ["The game's [type](super::GameType), as a u8."], + type: "u8", }, { - "name": "nftMeta", - "docs": [ - "An nft metadata account describing the game." - ], - "type": "publicKey" - } - ] - } + name: "nftMeta", + docs: ["An nft metadata account describing the game."], + type: "publicKey", + }, + ], + }, }, { - "name": "ScoreEntry", - "docs": [ - "A single score entry for a player." - ], - "type": { - "kind": "struct", - "fields": [ + name: "ScoreEntry", + docs: ["A single score entry for a player."], + type: { + kind: "struct", + fields: [ { - "name": "score", - "docs": [ - "The player's score." - ], - "type": "u64" + name: "score", + docs: ["The player's score."], + type: "u64", }, { - "name": "timestamp", - "docs": [ - "When this entry was made." - ], - "type": "i64" - } - ] - } + name: "timestamp", + docs: ["When this entry was made."], + type: "i64", + }, + ], + }, }, { - "name": "MergeApproval", - "docs": [ + name: "MergeApproval", + docs: [ "Represents a [Player][super::Player] account involved in a merge", - "and if that account's user/authority has granted approval." + "and if that account's user/authority has granted approval.", ], - "type": { - "kind": "struct", - "fields": [ + type: { + kind: "struct", + fields: [ { - "name": "key", - "docs": [ - "The player_account pubkey." - ], - "type": "publicKey" + name: "key", + docs: ["The player_account pubkey."], + type: "publicKey", }, { - "name": "approved", - "docs": [ - "User's approval status." - ], - "type": "bool" - } - ] - } + name: "approved", + docs: ["User's approval status."], + type: "bool", + }, + ], + }, }, { - "name": "LeaderBoardScore", - "docs": [ - "An single entry to a [LeaderTopEntries]." - ], - "type": { - "kind": "struct", - "fields": [ + name: "LeaderBoardScore", + docs: ["An single entry to a [LeaderTopEntries]."], + type: { + kind: "struct", + fields: [ { - "name": "player", - "docs": [ - "The player" - ], - "type": "publicKey" + name: "player", + docs: ["The player"], + type: "publicKey", }, { - "name": "entry", - "docs": [ - "The user's [score][super::ScoreEntry]." - ], - "type": { - "defined": "ScoreEntry" - } - } - ] - } + name: "entry", + docs: ["The user's [score][super::ScoreEntry]."], + type: { + defined: "ScoreEntry", + }, + }, + ], + }, }, { - "name": "RegisterLeaderBoardInput", - "docs": [ - "Parameters needed when registering a leaderboard." - ], - "type": { - "kind": "struct", - "fields": [ + name: "RegisterLeaderBoardInput", + docs: ["Parameters needed when registering a leaderboard."], + type: { + kind: "struct", + fields: [ { - "name": "description", - "docs": [ - "Leaderboard description." - ], - "type": "string" + name: "description", + docs: ["Leaderboard description."], + type: "string", }, { - "name": "nftMeta", - "docs": [ - "Nft metadata representing the leaderboard." - ], - "type": "publicKey" + name: "nftMeta", + docs: ["Nft metadata representing the leaderboard."], + type: "publicKey", }, { - "name": "decimals", - "docs": [ - "Specify the decimals score values are represented in. Defaults to `0` if [None]." + name: "decimals", + docs: [ + "Specify the decimals score values are represented in. Defaults to `0` if [None].", ], - "type": { - "option": "u8" - } + type: { + option: "u8", + }, }, { - "name": "minScore", - "docs": [ - "Specifies minimum allowed score. Defaults to `u64::MIN` if [None]." + name: "minScore", + docs: [ + "Specifies minimum allowed score. Defaults to `u64::MIN` if [None].", ], - "type": { - "option": "u64" - } + type: { + option: "u64", + }, }, { - "name": "maxScore", - "docs": [ - "Specifies maximum allowed score. Defaults to `u64::MAX` if [None]." + name: "maxScore", + docs: [ + "Specifies maximum allowed score. Defaults to `u64::MAX` if [None].", ], - "type": { - "option": "u64" - } + type: { + option: "u64", + }, }, { - "name": "scoresToRetain", - "docs": [ - "Number of top scores to store on-chain." - ], - "type": "u8" + name: "scoresToRetain", + docs: ["Number of top scores to store on-chain."], + type: "u8", }, { - "name": "isAscending", - "docs": [ - "Order by which scores are stored. `true` for ascending, `false` for descending." + name: "isAscending", + docs: [ + "Order by which scores are stored. `true` for ascending, `false` for descending.", ], - "type": "bool" + type: "bool", }, { - "name": "allowMultipleScores", - "docs": [ - "Whether or not multiple scores are kept in the leaderboard for a single player." + name: "allowMultipleScores", + docs: [ + "Whether or not multiple scores are kept in the leaderboard for a single player.", ], - "type": "bool" - } - ] - } + type: "bool", + }, + ], + }, }, { - "name": "AddNewRewardInput", - "docs": [ - "Input to add a new reward for an achievement." - ], - "type": { - "kind": "struct", - "fields": [ + name: "AddNewRewardInput", + docs: ["Input to add a new reward for an achievement."], + type: { + kind: "struct", + fields: [ { - "name": "availableSpots", - "docs": [ - "Number of rewards to be given out." - ], - "type": "u64" + name: "availableSpots", + docs: ["Number of rewards to be given out."], + type: "u64", }, { - "name": "kind", - "docs": [ - "Specific reward kind." - ], - "type": { - "defined": "RewardKindInput" - } - } - ] - } + name: "kind", + docs: ["Specific reward kind."], + type: { + defined: "RewardKindInput", + }, + }, + ], + }, }, { - "name": "GameType", - "type": { - "kind": "enum", - "variants": [ + name: "GameType", + type: { + kind: "enum", + variants: [ { - "name": "Mobile" + name: "Mobile", }, { - "name": "Desktop" + name: "Desktop", }, { - "name": "Web" + name: "Web", }, { - "name": "Unspecified" - } - ] - } + name: "Unspecified", + }, + ], + }, }, { - "name": "Genre", - "type": { - "kind": "enum", - "variants": [ + name: "Genre", + type: { + kind: "enum", + variants: [ { - "name": "Rpg" + name: "Rpg", }, { - "name": "Mmo" + name: "Mmo", }, { - "name": "Action" + name: "Action", }, { - "name": "Adventure" + name: "Adventure", }, { - "name": "Puzzle" + name: "Puzzle", }, { - "name": "Casual" + name: "Casual", }, { - "name": "Unspecified" - } - ] - } + name: "Unspecified", + }, + ], + }, }, { - "name": "RewardKind", - "docs": [ - "The kind of reward to be given out." - ], - "type": { - "kind": "enum", - "variants": [ + name: "RewardKind", + docs: ["The kind of reward to be given out."], + type: { + kind: "enum", + variants: [ { - "name": "FungibleToken", - "fields": [ + name: "FungibleToken", + fields: [ { - "name": "mint", - "docs": [ - "The mint of the token to be given out." - ], - "type": "publicKey" + name: "mint", + docs: ["The mint of the token to be given out."], + type: "publicKey", }, { - "name": "account", - "docs": [ - "The token account to withdraw from." - ], - "type": "publicKey" + name: "account", + docs: ["The token account to withdraw from."], + type: "publicKey", }, { - "name": "amount", - "docs": [ - "Reward amount per user." - ], - "type": "u64" - } - ] + name: "amount", + docs: ["Reward amount per user."], + type: "u64", + }, + ], }, { - "name": "NonFungibleToken", - "fields": [ + name: "NonFungibleToken", + fields: [ { - "name": "uri", - "docs": [ - "URI of the NFT to be minted." - ], - "type": "string" + name: "uri", + docs: ["URI of the NFT to be minted."], + type: "string", }, { - "name": "name", - "docs": [ - "Name of the NFT to be minted." - ], - "type": "string" + name: "name", + docs: ["Name of the NFT to be minted."], + type: "string", }, { - "name": "symbol", - "docs": [ - "Symbol of the NFT to be minted." - ], - "type": "string" + name: "symbol", + docs: ["Symbol of the NFT to be minted."], + type: "string", }, { - "name": "minted", - "docs": [ - "Total NFTs minted so far." - ], - "type": "u64" + name: "minted", + docs: ["Total NFTs minted so far."], + type: "u64", }, { - "name": "collection", - "docs": [ + name: "collection", + docs: [ "Optional field for a collection mint used for", - "verifying minted rewards." + "verifying minted rewards.", ], - "type": { - "option": "publicKey" - } - } - ] - } - ] - } + type: { + option: "publicKey", + }, + }, + ], + }, + ], + }, }, { - "name": "RewardKindInput", - "docs": [ - "Specific variant of [AddNewRewardInput]." - ], - "type": { - "kind": "enum", - "variants": [ + name: "RewardKindInput", + docs: ["Specific variant of [AddNewRewardInput]."], + type: { + kind: "enum", + variants: [ { - "name": "Ft", - "fields": [ + name: "Ft", + fields: [ { - "name": "deposit", - "docs": [ + name: "deposit", + docs: [ "Amount to be delegated to this program's PDA", - "so it can spend for reward claims." + "so it can spend for reward claims.", ], - "type": "u64" + type: "u64", }, { - "name": "amount", - "docs": [ - "Amount given to a single user." - ], - "type": "u64" - } - ] + name: "amount", + docs: ["Amount given to a single user."], + type: "u64", + }, + ], }, { - "name": "Nft", - "fields": [ + name: "Nft", + fields: [ { - "name": "uri", - "docs": [ - "Uri of the minted nft." - ], - "type": "string" + name: "uri", + docs: ["Uri of the minted nft."], + type: "string", }, { - "name": "name", - "docs": [ - "Name of the minted nft." - ], - "type": "string" + name: "name", + docs: ["Name of the minted nft."], + type: "string", }, { - "name": "symbol", - "docs": [ - "Symbol of the minted nft." - ], - "type": "string" - } - ] - } - ] - } - } + name: "symbol", + docs: ["Symbol of the minted nft."], + type: "string", + }, + ], + }, + ], + }, + }, ], - "errors": [ + errors: [ { - "code": 6000, - "name": "InvalidFieldLength", - "msg": "Exceeded max length for field." + code: 6000, + name: "InvalidFieldLength", + msg: "Exceeded max length for field.", }, { - "code": 6001, - "name": "InvalidAuthority", - "msg": "Invalid authority for instruction" + code: 6001, + name: "InvalidAuthority", + msg: "Invalid authority for instruction", }, { - "code": 6002, - "name": "MissingSignature", - "msg": "An expected signature isn't present" + code: 6002, + name: "MissingSignature", + msg: "An expected signature isn't present", }, { - "code": 6003, - "name": "NoRewardForAchievement", - "msg": "Reward not specified for this achievement" + code: 6003, + name: "NoRewardForAchievement", + msg: "Reward not specified for this achievement", }, { - "code": 6004, - "name": "AccountNotPartOfMerge", - "msg": "The merge account does not include this player account" + code: 6004, + name: "AccountNotPartOfMerge", + msg: "The merge account does not include this player account", }, { - "code": 6005, - "name": "ScoreNotWithinBounds", - "msg": "Tried to input score that is below the minimum or above the maximum" + code: 6005, + name: "ScoreNotWithinBounds", + msg: "Tried to input score that is below the minimum or above the maximum", }, { - "code": 6006, - "name": "MissingExpectedAccount", - "msg": "An optional but expected account is missing" + code: 6006, + name: "MissingExpectedAccount", + msg: "An optional but expected account is missing", }, { - "code": 6007, - "name": "InvalidRewardKind", - "msg": "Invalid reward kind for this instruction" + code: 6007, + name: "InvalidRewardKind", + msg: "Invalid reward kind for this instruction", }, { - "code": 6008, - "name": "NoAvailableRewards", - "msg": "No more rewards are being given out for this game" - } - ] + code: 6008, + name: "NoAvailableRewards", + msg: "No more rewards are being given out for this game", + }, + ], }; diff --git a/client/sdk/src/idl/tens.ts b/client/sdk/src/idl/tens.ts index b3ce2a1..58bd267 100644 --- a/client/sdk/src/idl/tens.ts +++ b/client/sdk/src/idl/tens.ts @@ -1,457 +1,433 @@ -export type Tens = { - "version": "0.1.0", - "name": "tens", - "instructions": [ +export interface Tens { + version: "0.1.0"; + name: "tens"; + instructions: [ { - "name": "register", - "accounts": [ + name: "register"; + accounts: [ { - "name": "signer", - "isMut": true, - "isSigner": true + name: "signer"; + isMut: true; + isSigner: true; }, { - "name": "tensState", - "isMut": true, - "isSigner": false + name: "tensState"; + isMut: true; + isSigner: false; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; } - ], - "args": [ + ]; + args: [ { - "name": "soarState", - "type": "publicKey" + name: "soarState"; + type: "publicKey"; }, { - "name": "soarLeaderboard", - "type": "publicKey" + name: "soarLeaderboard"; + type: "publicKey"; }, { - "name": "soarLeaderboardTopEntries", - "type": "publicKey" + name: "soarLeaderboardTopEntries"; + type: "publicKey"; } - ] + ]; }, { - "name": "makeMove", - "accounts": [ + name: "makeMove"; + accounts: [ { - "name": "user", - "isMut": true, - "isSigner": true + name: "user"; + isMut: true; + isSigner: true; }, { - "name": "tensState", - "isMut": true, - "isSigner": false + name: "tensState"; + isMut: true; + isSigner: false; }, { - "name": "soarState", - "isMut": false, - "isSigner": false + name: "soarState"; + isMut: false; + isSigner: false; }, { - "name": "soarLeaderboard", - "isMut": false, - "isSigner": false + name: "soarLeaderboard"; + isMut: false; + isSigner: false; }, { - "name": "soarPlayerAccount", - "isMut": false, - "isSigner": false + name: "soarPlayerAccount"; + isMut: false; + isSigner: false; }, { - "name": "soarPlayerScores", - "isMut": true, - "isSigner": false + name: "soarPlayerScores"; + isMut: true; + isSigner: false; }, { - "name": "soarTopEntries", - "isMut": true, - "isSigner": false, - "isOptional": true + name: "soarTopEntries"; + isMut: true; + isSigner: false; + isOptional: true; }, { - "name": "soarProgram", - "isMut": false, - "isSigner": false + name: "soarProgram"; + isMut: false; + isSigner: false; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; } - ], - "args": [] + ]; + args: []; }, { - "name": "claimReward", - "accounts": [ + name: "claimReward"; + accounts: [ { - "name": "user", - "isMut": true, - "isSigner": true + name: "user"; + isMut: true; + isSigner: true; }, { - "name": "tensState", - "isMut": true, - "isSigner": false + name: "tensState"; + isMut: true; + isSigner: false; }, { - "name": "playerAccount", - "isMut": true, - "isSigner": false + name: "playerAccount"; + isMut: true; + isSigner: false; }, { - "name": "soarPlayerScores", - "isMut": false, - "isSigner": false + name: "soarPlayerScores"; + isMut: false; + isSigner: false; }, { - "name": "soarTopEntries", - "isMut": false, - "isSigner": false + name: "soarTopEntries"; + isMut: false; + isSigner: false; }, { - "name": "soarState", - "isMut": false, - "isSigner": false + name: "soarState"; + isMut: false; + isSigner: false; }, { - "name": "soarAchievement", - "isMut": false, - "isSigner": false + name: "soarAchievement"; + isMut: false; + isSigner: false; }, { - "name": "soarReward", - "isMut": true, - "isSigner": false + name: "soarReward"; + isMut: true; + isSigner: false; }, { - "name": "soarPlayerAchievement", - "isMut": true, - "isSigner": false + name: "soarPlayerAchievement"; + isMut: true; + isSigner: false; }, { - "name": "sourceTokenAccount", - "isMut": true, - "isSigner": false + name: "sourceTokenAccount"; + isMut: true; + isSigner: false; }, { - "name": "userTokenAccount", - "isMut": true, - "isSigner": false + name: "userTokenAccount"; + isMut: true; + isSigner: false; }, { - "name": "tokenProgram", - "isMut": false, - "isSigner": false + name: "tokenProgram"; + isMut: false; + isSigner: false; }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram"; + isMut: false; + isSigner: false; }, { - "name": "soarProgram", - "isMut": false, - "isSigner": false + name: "soarProgram"; + isMut: false; + isSigner: false; } - ], - "args": [] + ]; + args: []; } - ], - "accounts": [ + ]; + accounts: [ { - "name": "tens", - "docs": [ - "A simple game." - ], - "type": { - "kind": "struct", - "fields": [ + name: "tens"; + docs: ["A simple game."]; + type: { + kind: "struct"; + fields: [ { - "name": "counter", - "docs": [ - "The game counter." - ], - "type": "u64" + name: "counter"; + docs: ["The game counter."]; + type: "u64"; }, { - "name": "soar", - "docs": [ - "The SOAR keys for this program." - ], - "type": { - "defined": "SoarKeysStorage" - } + name: "soar"; + docs: ["The SOAR keys for this program."]; + type: { + defined: "SoarKeysStorage"; + }; } - ] - } + ]; + }; } - ], - "types": [ + ]; + types: [ { - "name": "SoarKeysStorage", - "type": { - "kind": "struct", - "fields": [ + name: "SoarKeysStorage"; + type: { + kind: "struct"; + fields: [ { - "name": "state", - "docs": [ - "The soar state for this game." - ], - "type": "publicKey" + name: "state"; + docs: ["The soar state for this game."]; + type: "publicKey"; }, { - "name": "leaderboard", - "docs": [ - "The soar leaderboard for this game." - ], - "type": "publicKey" + name: "leaderboard"; + docs: ["The soar leaderboard for this game."]; + type: "publicKey"; }, { - "name": "topEntries", - "docs": [ - "The soar top-entries account for this game." - ], - "type": "publicKey" + name: "topEntries"; + docs: ["The soar top-entries account for this game."]; + type: "publicKey"; } - ] - } + ]; + }; } - ] -}; + ]; +} export const IDL: Tens = { - "version": "0.1.0", - "name": "tens", - "instructions": [ + version: "0.1.0", + name: "tens", + instructions: [ { - "name": "register", - "accounts": [ + name: "register", + accounts: [ { - "name": "signer", - "isMut": true, - "isSigner": true + name: "signer", + isMut: true, + isSigner: true, }, { - "name": "tensState", - "isMut": true, - "isSigner": false + name: "tensState", + isMut: true, + isSigner: false, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } + name: "systemProgram", + isMut: false, + isSigner: false, + }, ], - "args": [ + args: [ { - "name": "soarState", - "type": "publicKey" + name: "soarState", + type: "publicKey", }, { - "name": "soarLeaderboard", - "type": "publicKey" + name: "soarLeaderboard", + type: "publicKey", }, { - "name": "soarLeaderboardTopEntries", - "type": "publicKey" - } - ] + name: "soarLeaderboardTopEntries", + type: "publicKey", + }, + ], }, { - "name": "makeMove", - "accounts": [ + name: "makeMove", + accounts: [ { - "name": "user", - "isMut": true, - "isSigner": true + name: "user", + isMut: true, + isSigner: true, }, { - "name": "tensState", - "isMut": true, - "isSigner": false + name: "tensState", + isMut: true, + isSigner: false, }, { - "name": "soarState", - "isMut": false, - "isSigner": false + name: "soarState", + isMut: false, + isSigner: false, }, { - "name": "soarLeaderboard", - "isMut": false, - "isSigner": false + name: "soarLeaderboard", + isMut: false, + isSigner: false, }, { - "name": "soarPlayerAccount", - "isMut": false, - "isSigner": false + name: "soarPlayerAccount", + isMut: false, + isSigner: false, }, { - "name": "soarPlayerScores", - "isMut": true, - "isSigner": false + name: "soarPlayerScores", + isMut: true, + isSigner: false, }, { - "name": "soarTopEntries", - "isMut": true, - "isSigner": false, - "isOptional": true + name: "soarTopEntries", + isMut: true, + isSigner: false, + isOptional: true, }, { - "name": "soarProgram", - "isMut": false, - "isSigner": false + name: "soarProgram", + isMut: false, + isSigner: false, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } + name: "systemProgram", + isMut: false, + isSigner: false, + }, ], - "args": [] + args: [], }, { - "name": "claimReward", - "accounts": [ + name: "claimReward", + accounts: [ { - "name": "user", - "isMut": true, - "isSigner": true + name: "user", + isMut: true, + isSigner: true, }, { - "name": "tensState", - "isMut": true, - "isSigner": false + name: "tensState", + isMut: true, + isSigner: false, }, { - "name": "playerAccount", - "isMut": true, - "isSigner": false + name: "playerAccount", + isMut: true, + isSigner: false, }, { - "name": "soarPlayerScores", - "isMut": false, - "isSigner": false + name: "soarPlayerScores", + isMut: false, + isSigner: false, }, { - "name": "soarTopEntries", - "isMut": false, - "isSigner": false + name: "soarTopEntries", + isMut: false, + isSigner: false, }, { - "name": "soarState", - "isMut": false, - "isSigner": false + name: "soarState", + isMut: false, + isSigner: false, }, { - "name": "soarAchievement", - "isMut": false, - "isSigner": false + name: "soarAchievement", + isMut: false, + isSigner: false, }, { - "name": "soarReward", - "isMut": true, - "isSigner": false + name: "soarReward", + isMut: true, + isSigner: false, }, { - "name": "soarPlayerAchievement", - "isMut": true, - "isSigner": false + name: "soarPlayerAchievement", + isMut: true, + isSigner: false, }, { - "name": "sourceTokenAccount", - "isMut": true, - "isSigner": false + name: "sourceTokenAccount", + isMut: true, + isSigner: false, }, { - "name": "userTokenAccount", - "isMut": true, - "isSigner": false + name: "userTokenAccount", + isMut: true, + isSigner: false, }, { - "name": "tokenProgram", - "isMut": false, - "isSigner": false + name: "tokenProgram", + isMut: false, + isSigner: false, }, { - "name": "systemProgram", - "isMut": false, - "isSigner": false + name: "systemProgram", + isMut: false, + isSigner: false, }, { - "name": "soarProgram", - "isMut": false, - "isSigner": false - } + name: "soarProgram", + isMut: false, + isSigner: false, + }, ], - "args": [] - } + args: [], + }, ], - "accounts": [ + accounts: [ { - "name": "tens", - "docs": [ - "A simple game." - ], - "type": { - "kind": "struct", - "fields": [ + name: "tens", + docs: ["A simple game."], + type: { + kind: "struct", + fields: [ { - "name": "counter", - "docs": [ - "The game counter." - ], - "type": "u64" + name: "counter", + docs: ["The game counter."], + type: "u64", }, { - "name": "soar", - "docs": [ - "The SOAR keys for this program." - ], - "type": { - "defined": "SoarKeysStorage" - } - } - ] - } - } + name: "soar", + docs: ["The SOAR keys for this program."], + type: { + defined: "SoarKeysStorage", + }, + }, + ], + }, + }, ], - "types": [ + types: [ { - "name": "SoarKeysStorage", - "type": { - "kind": "struct", - "fields": [ + name: "SoarKeysStorage", + type: { + kind: "struct", + fields: [ { - "name": "state", - "docs": [ - "The soar state for this game." - ], - "type": "publicKey" + name: "state", + docs: ["The soar state for this game."], + type: "publicKey", }, { - "name": "leaderboard", - "docs": [ - "The soar leaderboard for this game." - ], - "type": "publicKey" + name: "leaderboard", + docs: ["The soar leaderboard for this game."], + type: "publicKey", }, { - "name": "topEntries", - "docs": [ - "The soar top-entries account for this game." - ], - "type": "publicKey" - } - ] - } - } - ] + name: "topEntries", + docs: ["The soar top-entries account for this game."], + type: "publicKey", + }, + ], + }, + }, + ], }; diff --git a/client/sdk/src/instructions/rawInstructions.ts b/client/sdk/src/instructions/rawInstructions.ts index 14e3266..ab0cfd2 100644 --- a/client/sdk/src/instructions/rawInstructions.ts +++ b/client/sdk/src/instructions/rawInstructions.ts @@ -325,7 +325,13 @@ export const updateLeaderBoardInstruction = async ( pre?: TransactionInstruction[] ): Promise => { return program.methods - .updateLeaderboard(args.newDescription, args.newNftMeta) + .updateLeaderboard( + args.newDescription, + args.newNftMeta, + args.newMinScore, + args.newMaxScore, + args.newAllowMultipleScores + ) .accounts(accounts) .preInstructions(pre ?? []) .instruction(); diff --git a/client/sdk/src/soar.program.ts b/client/sdk/src/soar.program.ts index c83e652..f0eec91 100644 --- a/client/sdk/src/soar.program.ts +++ b/client/sdk/src/soar.program.ts @@ -269,7 +269,10 @@ export class SoarProgram { authority: PublicKey, leaderboard: PublicKey, newDescription?: string, - newNftMeta?: PublicKey + newNftMeta?: PublicKey, + newMinScore?: BN, + newMaxScore?: BN, + newAllowMultipleScores?: boolean ): Promise { this.builder.clean(); if (newDescription === undefined && newNftMeta === undefined) { @@ -282,6 +285,9 @@ export class SoarProgram { { newDescription: newDescription ?? null, newNftMeta: newNftMeta ?? null, + newMinScore: newMinScore ?? null, + newMaxScore: newMaxScore ?? null, + newAllowMultipleScores: newAllowMultipleScores ?? null, }, authority, leaderboard diff --git a/client/sdk/src/types.ts b/client/sdk/src/types.ts index c128298..3a68010 100644 --- a/client/sdk/src/types.ts +++ b/client/sdk/src/types.ts @@ -136,6 +136,9 @@ export interface UpdateGameArgs { export interface UpdateLeaderboardArgs { newDescription: string | null; newNftMeta: PublicKey | null; + newMinScore: BN | null; + newMaxScore: BN | null; + newAllowMultipleScores: boolean | null; } export interface UpdatePlayerArgs { newUsername: string | null; diff --git a/client/tests/soar.ts b/client/tests/soar.ts index 89b28db..4bfca77 100644 --- a/client/tests/soar.ts +++ b/client/tests/soar.ts @@ -205,7 +205,7 @@ describe("soar", () => { decimals, minScore, maxScore, - true + true ); await client.sendAndConfirmTransaction(transaction, [auths[1]]); leaderBoards.push(newLeaderBoard); @@ -976,8 +976,6 @@ describe("soar", () => { expect(account.claimed).to.be.true; }); - - it("Check scores order allowing multiple scores per player, dec order", async () => { const expectedDescription = "LeaderBoard2"; const expectedNftMeta = Keypair.generate().publicKey; @@ -988,83 +986,100 @@ describe("soar", () => { const maxScore = new BN(100); const { newLeaderBoard, topEntries, transaction } = - await gameClient.addLeaderBoard( - auths[1].publicKey, - expectedDescription, - expectedNftMeta, - scoresToRetain, - isAscending, - decimals, - minScore, - maxScore, - true - ); + await gameClient.addLeaderBoard( + auths[1].publicKey, + expectedDescription, + expectedNftMeta, + scoresToRetain, + isAscending, + decimals, + minScore, + maxScore, + true + ); await client.sendAndConfirmTransaction(transaction, [auths[1]]); const info = await gameClient.program.fetchLeaderBoardAccount( - newLeaderBoard + newLeaderBoard ); // Check that leaderboard is set up to accept multiple scores per player expect(info.allowMultipleScores).to.be.true; const { transaction: txRegisterUser, newList } = - await client.registerPlayerEntryForLeaderBoard( - user1.publicKey, - newLeaderBoard - ); + await client.registerPlayerEntryForLeaderBoard( + user1.publicKey, + newLeaderBoard + ); await client.sendAndConfirmTransaction(txRegisterUser, [user1]); // Submit a score for user1 const score1 = new BN(80); - const {transaction: txScore1} = await client.submitScoreToLeaderBoard( - user1.publicKey, - auths[1].publicKey, - newLeaderBoard, - score1 + const { transaction: txScore1 } = await client.submitScoreToLeaderBoard( + user1.publicKey, + auths[1].publicKey, + newLeaderBoard, + score1 ); await client.sendAndConfirmTransaction(txScore1, [auths[1]]); - let entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount(topEntries); - const user1P = client.utils.derivePlayerAddress(user1.publicKey)[0].toBase58(); + let entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount( + topEntries + ); + const user1P = client.utils + .derivePlayerAddress(user1.publicKey)[0] + .toBase58(); expect(entries.isAscending).to.be.false; expect(entries.topScores.length).to.equal(scoresToRetain); - expect(entries.topScores[0].entry.score.toNumber()).to.equal(score1.toNumber()); + expect(entries.topScores[0].entry.score.toNumber()).to.equal( + score1.toNumber() + ); expect(entries.topScores[0].player.toBase58()).to.equal(user1P); expect(entries.topScores[1].entry.score.toNumber()).to.equal(0); // Submit a second score for user1 const score2 = new BN(90); - const {transaction: txScore2} = await client.submitScoreToLeaderBoard( - user1.publicKey, - auths[1].publicKey, - newLeaderBoard, - score2 + const { transaction: txScore2 } = await client.submitScoreToLeaderBoard( + user1.publicKey, + auths[1].publicKey, + newLeaderBoard, + score2 ); await client.sendAndConfirmTransaction(txScore2, [auths[1]]); - entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount(topEntries); - expect(entries.topScores[0].entry.score.toNumber()).to.equal(score2.toNumber()); + entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount( + topEntries + ); + expect(entries.topScores[0].entry.score.toNumber()).to.equal( + score2.toNumber() + ); expect(entries.topScores[0].player.toBase58()).to.equal(user1P); - expect(entries.topScores[1].entry.score.toNumber()).to.equal(score1.toNumber()); + expect(entries.topScores[1].entry.score.toNumber()).to.equal( + score1.toNumber() + ); expect(entries.topScores[1].player.toBase58()).to.equal(user1P); // Submit a third score for user1 const score3 = new BN(70); - const {transaction: txScore3} = await client.submitScoreToLeaderBoard( - user1.publicKey, - auths[1].publicKey, - newLeaderBoard, - score3 + const { transaction: txScore3 } = await client.submitScoreToLeaderBoard( + user1.publicKey, + auths[1].publicKey, + newLeaderBoard, + score3 ); await client.sendAndConfirmTransaction(txScore3, [auths[1]]); - entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount(topEntries); - expect(entries.topScores[0].entry.score.toNumber()).to.equal(score2.toNumber()); + entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount( + topEntries + ); + expect(entries.topScores[0].entry.score.toNumber()).to.equal( + score2.toNumber() + ); expect(entries.topScores[0].player.toBase58()).to.equal(user1P); - expect(entries.topScores[1].entry.score.toNumber()).to.equal(score1.toNumber()); + expect(entries.topScores[1].entry.score.toNumber()).to.equal( + score1.toNumber() + ); expect(entries.topScores[1].player.toBase58()).to.equal(user1P); - }); it("Check scores order, don't allow multiple scores per player, dec order", async () => { @@ -1077,98 +1092,116 @@ describe("soar", () => { const maxScore = new BN(100); const { newLeaderBoard, topEntries, transaction } = - await gameClient.addLeaderBoard( - auths[1].publicKey, - expectedDescription, - expectedNftMeta, - scoresToRetain, - isAscending, - decimals, - minScore, - maxScore, - false - ); + await gameClient.addLeaderBoard( + auths[1].publicKey, + expectedDescription, + expectedNftMeta, + scoresToRetain, + isAscending, + decimals, + minScore, + maxScore, + false + ); await client.sendAndConfirmTransaction(transaction, [auths[1]]); const info = await gameClient.program.fetchLeaderBoardAccount( - newLeaderBoard + newLeaderBoard ); // Check that leaderboard is set up to accept multiple scores per player expect(info.allowMultipleScores).to.be.false; const { transaction: txRegisterUser, newList } = - await client.registerPlayerEntryForLeaderBoard( - user1.publicKey, - newLeaderBoard - ); + await client.registerPlayerEntryForLeaderBoard( + user1.publicKey, + newLeaderBoard + ); await client.sendAndConfirmTransaction(txRegisterUser, [user1]); // Submit a score for user1 const score1 = new BN(80); - const {transaction: txScore1} = await client.submitScoreToLeaderBoard( - user1.publicKey, - auths[1].publicKey, - newLeaderBoard, - score1 + const { transaction: txScore1 } = await client.submitScoreToLeaderBoard( + user1.publicKey, + auths[1].publicKey, + newLeaderBoard, + score1 ); await client.sendAndConfirmTransaction(txScore1, [auths[1]]); - let entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount(topEntries); - const user1P = client.utils.derivePlayerAddress(user1.publicKey)[0].toBase58(); + let entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount( + topEntries + ); + const user1P = client.utils + .derivePlayerAddress(user1.publicKey)[0] + .toBase58(); expect(entries.isAscending).to.be.false; expect(entries.topScores.length).to.equal(scoresToRetain); - expect(entries.topScores[0].entry.score.toNumber()).to.equal(score1.toNumber()); + expect(entries.topScores[0].entry.score.toNumber()).to.equal( + score1.toNumber() + ); expect(entries.topScores[0].player.toBase58()).to.equal(user1P); expect(entries.topScores[1].entry.score.toNumber()).to.equal(0); // Submit a second score for user1 const score2 = new BN(90); - const {transaction: txScore2} = await client.submitScoreToLeaderBoard( - user1.publicKey, - auths[1].publicKey, - newLeaderBoard, - score2 + const { transaction: txScore2 } = await client.submitScoreToLeaderBoard( + user1.publicKey, + auths[1].publicKey, + newLeaderBoard, + score2 ); await client.sendAndConfirmTransaction(txScore2, [auths[1]]); - entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount(topEntries); - expect(entries.topScores[0].entry.score.toNumber()).to.equal(score2.toNumber()); + entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount( + topEntries + ); + expect(entries.topScores[0].entry.score.toNumber()).to.equal( + score2.toNumber() + ); expect(entries.topScores[0].player.toBase58()).to.equal(user1P); expect(entries.topScores[1].entry.score.toNumber()).to.equal(0); // Submit a third score for user1 const score3 = new BN(70); - const {transaction: txScore3} = await client.submitScoreToLeaderBoard( - user1.publicKey, - auths[1].publicKey, - newLeaderBoard, - score3 + const { transaction: txScore3 } = await client.submitScoreToLeaderBoard( + user1.publicKey, + auths[1].publicKey, + newLeaderBoard, + score3 ); await client.sendAndConfirmTransaction(txScore3, [auths[1]]); // Submit a new score for user2 - const user2P = client.utils.derivePlayerAddress(user2.publicKey)[0].toBase58(); + const user2P = client.utils + .derivePlayerAddress(user2.publicKey)[0] + .toBase58(); const { transaction: txRegisterUser2 } = - await client.registerPlayerEntryForLeaderBoard( - user2.publicKey, - newLeaderBoard - ); + await client.registerPlayerEntryForLeaderBoard( + user2.publicKey, + newLeaderBoard + ); await client.sendAndConfirmTransaction(txRegisterUser2, [user2]); const score4 = new BN(70); - const {transaction: txScore4} = await client.submitScoreToLeaderBoard( - user2.publicKey, - auths[1].publicKey, - newLeaderBoard, - score4 + const { transaction: txScore4 } = await client.submitScoreToLeaderBoard( + user2.publicKey, + auths[1].publicKey, + newLeaderBoard, + score4 ); await client.sendAndConfirmTransaction(txScore4, [auths[1]]); - entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount(topEntries); - expect(entries.topScores[0].entry.score.toNumber()).to.equal(score2.toNumber()); + entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount( + topEntries + ); + expect(entries.topScores[0].entry.score.toNumber()).to.equal( + score2.toNumber() + ); expect(entries.topScores[0].player.toBase58()).to.equal(user1P); - expect(entries.topScores[1].entry.score.toNumber()).to.equal(score4.toNumber()); + expect(entries.topScores[1].entry.score.toNumber()).to.equal( + score4.toNumber() + ); expect(entries.topScores[1].player.toBase58()).to.equal(user2P); }); @@ -1182,75 +1215,183 @@ describe("soar", () => { const maxScore = new BN(100); const { newLeaderBoard, topEntries, transaction } = - await gameClient.addLeaderBoard( - auths[1].publicKey, - expectedDescription, - expectedNftMeta, - scoresToRetain, - isAscending, - decimals, - minScore, - maxScore, - true - ); + await gameClient.addLeaderBoard( + auths[1].publicKey, + expectedDescription, + expectedNftMeta, + scoresToRetain, + isAscending, + decimals, + minScore, + maxScore, + true + ); await client.sendAndConfirmTransaction(transaction, [auths[1]]); - console.log("leaderboard", newLeaderBoard.toBase58()); - - const info = await gameClient.program.fetchLeaderBoardAccount(newLeaderBoard); + const info = await gameClient.program.fetchLeaderBoardAccount( + newLeaderBoard + ); // Check that leaderboard is set up to accept multiple scores per player expect(info.allowMultipleScores).to.be.true; const { transaction: txRegisterUser, newList } = - await client.registerPlayerEntryForLeaderBoard( - user1.publicKey, - newLeaderBoard - ); + await client.registerPlayerEntryForLeaderBoard( + user1.publicKey, + newLeaderBoard + ); await client.sendAndConfirmTransaction(txRegisterUser, [user1]); // Submit a score for user1 const score1 = new BN(80); - const {transaction: txScore1} = await client.submitScoreToLeaderBoard( - user1.publicKey, - auths[1].publicKey, - newLeaderBoard, - score1 + const { transaction: txScore1 } = await client.submitScoreToLeaderBoard( + user1.publicKey, + auths[1].publicKey, + newLeaderBoard, + score1 ); await client.sendAndConfirmTransaction(txScore1, [auths[1]]); - let entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount(topEntries); - const user1P = client.utils.derivePlayerAddress(user1.publicKey)[0].toBase58(); + let entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount( + topEntries + ); + const user1P = client.utils + .derivePlayerAddress(user1.publicKey)[0] + .toBase58(); expect(entries.isAscending).to.be.true; expect(entries.topScores.length).to.equal(scoresToRetain); - expect(entries.topScores[0].entry.score.toNumber()).to.equal(score1.toNumber()); + expect(entries.topScores[0].entry.score.toNumber()).to.equal( + score1.toNumber() + ); expect(entries.topScores[0].player.toBase58()).to.equal(user1P); - expect(entries.topScores[1].entry.score.toNumber()).to.equal(0); + expect(entries.topScores[1].entry.score.toNumber()).to.equal( + maxScore.toNumber() + ); // Submit a second score for user1 - // const score2 = new BN(90); - // const {transaction: txScore2} = await client.submitScoreToLeaderBoard( - // user1.publicKey, - // auths[1].publicKey, - // newLeaderBoard, - // score2 - // ); - // await client.sendAndConfirmTransaction(txScore2, [auths[1]]); - // - // entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount(topEntries); - // expect(entries.topScores[0].entry.score.toNumber()).to.equal(score2.toNumber()); - // expect(entries.topScores[0].player.toBase58()).to.equal(user1P); - // expect(entries.topScores[1].entry.score.toNumber()).to.equal(0); + const score2 = new BN(90); + const { transaction: txScore2 } = await client.submitScoreToLeaderBoard( + user1.publicKey, + auths[1].publicKey, + newLeaderBoard, + score2 + ); + await client.sendAndConfirmTransaction(txScore2, [auths[1]]); + + entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount( + topEntries + ); + expect(entries.topScores[0].entry.score.toNumber()).to.equal( + score1.toNumber() + ); + expect(entries.topScores[0].player.toBase58()).to.equal(user1P); + expect(entries.topScores[1].entry.score.toNumber()).to.equal( + score2.toNumber() + ); + expect(entries.topScores[1].player.toBase58()).to.equal(user1P); // Submit a third score for user1 - // const score3 = new BN(70); - // const {transaction: txScore3} = await client.submitScoreToLeaderBoard( - // user1.publicKey, - // auths[1].publicKey, - // newLeaderBoard, - // score3 - // ); - // await client.sendAndConfirmTransaction(txScore3, [auths[1]]); + const score3 = new BN(70); + const { transaction: txScore3 } = await client.submitScoreToLeaderBoard( + user1.publicKey, + auths[1].publicKey, + newLeaderBoard, + score3 + ); + await client.sendAndConfirmTransaction(txScore3, [auths[1]]); + entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount( + topEntries + ); + expect(entries.topScores[0].entry.score.toNumber()).to.equal( + score3.toNumber() + ); + expect(entries.topScores[0].player.toBase58()).to.equal(user1P); + expect(entries.topScores[1].entry.score.toNumber()).to.equal( + score1.toNumber() + ); + expect(entries.topScores[1].player.toBase58()).to.equal(user1P); }); + it("Check scores order, does not allow multiple scores per player, asc order", async () => { + const expectedDescription = "LeaderBoard2"; + const expectedNftMeta = Keypair.generate().publicKey; + const scoresToRetain = 2; + const isAscending = true; // descending order + const decimals = 0; + const minScore = new BN(0); + const maxScore = new BN(100); + + const { newLeaderBoard, topEntries, transaction } = + await gameClient.addLeaderBoard( + auths[1].publicKey, + expectedDescription, + expectedNftMeta, + scoresToRetain, + isAscending, + decimals, + minScore, + maxScore, + false + ); + await client.sendAndConfirmTransaction(transaction, [auths[1]]); + + console.log("leaderboard", newLeaderBoard.toBase58()); + + const info = await gameClient.program.fetchLeaderBoardAccount( + newLeaderBoard + ); + + // Check that leaderboard is set up to not accept multiple scores per player + expect(info.allowMultipleScores).to.be.false; + + const { transaction: txRegisterUser, newList } = + await client.registerPlayerEntryForLeaderBoard( + user1.publicKey, + newLeaderBoard + ); + await client.sendAndConfirmTransaction(txRegisterUser, [user1]); + + // Submit a score for user1 + const score1 = new BN(80); + const { transaction: txScore1 } = await client.submitScoreToLeaderBoard( + user1.publicKey, + auths[1].publicKey, + newLeaderBoard, + score1 + ); + await client.sendAndConfirmTransaction(txScore1, [auths[1]]); + + // Submit a second score for user1 + const score2 = new BN(90); + const { transaction: txScore2 } = await client.submitScoreToLeaderBoard( + user1.publicKey, + auths[1].publicKey, + newLeaderBoard, + score2 + ); + await client.sendAndConfirmTransaction(txScore2, [auths[1]]); + + // Submit a third score for user1 + const score3 = new BN(70); + const { transaction: txScore3 } = await client.submitScoreToLeaderBoard( + user1.publicKey, + auths[1].publicKey, + newLeaderBoard, + score3 + ); + await client.sendAndConfirmTransaction(txScore3, [auths[1]]); + let entries = await gameClient.program.fetchLeaderBoardTopEntriesAccount( + topEntries + ); + const user1P = client.utils + .derivePlayerAddress(user1.publicKey)[0] + .toBase58(); + expect(entries.topScores[0].entry.score.toNumber()).to.equal( + score3.toNumber() + ); + expect(entries.topScores[0].player.toBase58()).to.equal(user1P); + expect(entries.topScores[1].entry.score.toNumber()).to.equal( + maxScore.toNumber() + ); + }); }); diff --git a/programs/soar/src/instructions/add_leaderboard.rs b/programs/soar/src/instructions/add_leaderboard.rs index 7779a7f..b3c3bf8 100644 --- a/programs/soar/src/instructions/add_leaderboard.rs +++ b/programs/soar/src/instructions/add_leaderboard.rs @@ -32,6 +32,12 @@ pub fn handler(ctx: Context, input: RegisterLeaderBoardInput) -> top_entries.is_ascending = order; top_entries.top_scores = vec![LeaderBoardScore::default(); retain_count as usize]; + + if top_entries.is_ascending { + top_entries.top_scores.iter_mut().for_each(|s| { + s.entry.score = ctx.accounts.leaderboard.max_score; + }); + } ctx.accounts.leaderboard.top_entries = Some(top_entries.key()); } diff --git a/programs/soar/src/instructions/submit_score.rs b/programs/soar/src/instructions/submit_score.rs index db45be4..534370d 100644 --- a/programs/soar/src/instructions/submit_score.rs +++ b/programs/soar/src/instructions/submit_score.rs @@ -55,29 +55,34 @@ pub fn handler(ctx: Context, score: u64) -> Result<()> { require_keys_eq!(leaderboard.top_entries.unwrap(), top_entries.key()); let mut score_entry = LeaderBoardScore::new(player_key, entry); let is_ascending = top_entries.is_ascending; + let last_index = top_entries.top_scores.len() - 1; + let mut index = last_index; let scores = &mut top_entries.top_scores; - if is_ascending && entry.score > scores[0].entry.score { - if ctx.accounts.leaderboard.allow_multiple_scores { - scores[0] = score_entry; - }else{ - if let Some(idx) = scores.iter().position(|s| s.player != player_key) { - let min_user_entry = if score_entry.entry.score < scores[idx].entry.score { score_entry } else { scores[idx].clone() }; - scores[idx] = min_user_entry; + if is_ascending && entry.score < scores[last_index].entry.score { + if !ctx.accounts.leaderboard.allow_multiple_scores { + if let Some(idx) = scores.iter().position(|s| s.player == player_key) { + index = idx; + score_entry = if score_entry.entry.score < scores[idx].entry.score { + score_entry + } else { + scores[idx].clone() + }; } } + scores[index] = score_entry; scores.sort_by(|a, b| a.entry.score.cmp(&b.entry.score)); } else if !is_ascending && entry.score > scores[last_index].entry.score { - let mut index = last_index; if !ctx.accounts.leaderboard.allow_multiple_scores { - msg!("Allow multiple scores is false"); - msg!("Player key: {}", player_key.to_string()); if let Some(idx) = scores.iter().position(|s| s.player == player_key) { - msg!("Found index: {}", idx); index = idx; - score_entry = if score_entry.entry.score > scores[idx].entry.score { score_entry } else { scores[idx].clone() }; - }else { msg!("No index found"); } + score_entry = if score_entry.entry.score > scores[idx].entry.score { + score_entry + } else { + scores[idx].clone() + }; + } } scores[index] = score_entry; scores.sort_by(|a, b| b.entry.score.cmp(&a.entry.score)); diff --git a/programs/soar/src/instructions/update_leaderboard.rs b/programs/soar/src/instructions/update_leaderboard.rs index 916664e..972b4e7 100644 --- a/programs/soar/src/instructions/update_leaderboard.rs +++ b/programs/soar/src/instructions/update_leaderboard.rs @@ -6,6 +6,9 @@ pub fn handler( ctx: Context, new_description: Option, new_nft_meta: Option, + new_min_score: Option, + new_max_score: Option, + new_allow_multiple_scores: Option, ) -> Result<()> { let leaderboard = &mut ctx.accounts.leaderboard; @@ -15,6 +18,15 @@ pub fn handler( if let Some(nft_meta) = new_nft_meta { leaderboard.nft_meta = nft_meta; } + if let Some(max_score) = new_max_score { + leaderboard.max_score = max_score; + } + if let Some(min_score) = new_min_score { + leaderboard.min_score = min_score; + } + if let Some(allow_multiple_scores) = new_allow_multiple_scores { + leaderboard.allow_multiple_scores = allow_multiple_scores; + } leaderboard.check()?; Ok(()) diff --git a/programs/soar/src/lib.rs b/programs/soar/src/lib.rs index aef1de3..78702a1 100644 --- a/programs/soar/src/lib.rs +++ b/programs/soar/src/lib.rs @@ -79,13 +79,24 @@ pub mod soar { add_leaderboard::handler(ctx, input) } - /// Update's a leaderboard's description and nft metadata information. + /// Update's a leaderboard's description, nft metadata information, min/max score, or whether + /// or not multiple scores are allowed for a single player. pub fn update_leaderboard( ctx: Context, new_description: Option, new_nft_meta: Option, + new_min_score: Option, + new_max_score: Option, + new_allow_multiple_scores: Option, ) -> Result<()> { - update_leaderboard::handler(ctx, new_description, new_nft_meta) + update_leaderboard::handler( + ctx, + new_description, + new_nft_meta, + new_min_score, + new_max_score, + new_allow_multiple_scores, + ) } /// Create a [Player] account for a particular user.