import { KeyedAccountInfo, PublicKey } from '@solana/web3.js'; import { Account, AccountStatic, AsyncSigner, DecodedAccountData, InstructionReturn, decodeAccount, staticImplements, } from '@staratlas/data-source'; import { ClosePlayerCrewRecordInput, PlayerCrewRecordAccount, SageIDL, SageIDLProgram, } from './constants'; import { SageCrewConfig } from './sageCrewConfig'; /** * Check if two `PlayerCrewRecordAccount` instances are equal * @param data1 - first PlayerCrewRecordAccount * @param data2 - second PlayerCrewRecordAccount * @returns a boolean */ export function playerCrewRecordDataEquals( data1: PlayerCrewRecordAccount, data2: PlayerCrewRecordAccount, ): boolean { return ( data1.version === data2.version && data1.gameId.equals(data2.gameId) && data1.playerProfile.equals(data2.playerProfile) && data1.crewConfig.equals(data2.crewConfig) && data1.count === data2.count && data1.bump === data2.bump ); } @staticImplements>() export class PlayerCrewRecord implements Account { static readonly ACCOUNT_NAME: NonNullable< SageIDL['accounts'] >[number]['name'] = 'playerCrewRecord'; static readonly MIN_DATA_SIZE = 8 + // discriminator 1 + // version 32 + // gameId 32 + // playerProfile 32 + // crewConfig 4 + // count 1; // bump constructor( private _data: PlayerCrewRecordAccount, private _key: PublicKey, ) {} get data(): Readonly { return this._data; } get key(): PublicKey { return this._key; } /** * Find the PlayerCrewRecord account address * @param program - SAGE program * @param playerProfile - the player's profile * @param gameId - the SAGE game id * @returns The PDA and bump respectively */ static findAddress( program: SageIDLProgram, playerProfile: PublicKey, gameId: PublicKey, ): [PublicKey, number] { return PublicKey.findProgramAddressSync( [ Buffer.from('PlayerCrewRecord'), playerProfile.toBuffer(), gameId.toBuffer(), ], program.programId, ); } /** * Closes a PlayerCrewRecord and transfers crew to the Starbase * @param params - the params to this functions * @param params.program - SAGE program * @param params.key - the key authorized to run this instruction * @param params.fundsTo - recipient of the rent refund * @param params.profile - the profile with the required permissions for the instruction * @param params.profileFaction - the profile's faction * @param params.starbasePlayer - the Starbase player account for the profile at the Starbase * @param params.starbase - the Starbase (must be a central space station) * @param params.gameId - the SAGE game id * @param params.input - instruction input params * @returns InstructionReturn */ static closePlayerCrewRecord(params: { program: SageIDLProgram; key: AsyncSigner; fundsTo: PublicKey | 'funder'; profile: PublicKey; profileFaction: PublicKey; starbase: PublicKey; starbasePlayer: PublicKey; gameId: PublicKey; input: ClosePlayerCrewRecordInput; }): InstructionReturn { const { profile, profileFaction, key, fundsTo, program, starbase, starbasePlayer, gameId, input, } = params; return async (funder) => [ { instruction: await program.methods .closePlayerCrewRecord(input) .accountsStrict({ fundsTo: fundsTo === 'funder' ? funder.publicKey() : fundsTo, gameAndProfileAndFaction: { key: key.publicKey(), profile, profileFaction, gameId, }, starbaseAndStarbasePlayer: { starbase, starbasePlayer, }, crewRecord: this.findAddress(program, profile, gameId)[0], crewConfig: SageCrewConfig.findAddress(program, gameId)[0], }) .instruction(), signers: [key], }, ]; } static decodeData( account: KeyedAccountInfo, program: SageIDLProgram, ): DecodedAccountData { return decodeAccount(account, program, PlayerCrewRecord); } }