diff --git a/package.json b/package.json index 0ea2c07..1398777 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "update-types": "cp target/types/drift_competitions.ts ts/sdk/src/types/drift_competitions.ts && prettier --write ts/sdk/src/types/drift_competitions.ts", "update-idl": "cp target/idl/drift_competitions.json ts/sdk/src/idl/drift_competitions.json", "settle-competition": "ts-node -T scripts/settleCompetitionRound.ts", - "mine-entries": "ts-node -T scripts/mineAdditionalEntries.ts" + "mine-entries": "ts-node -T scripts/mineAdditionalEntries.ts", + "donate": "ts-node -T scripts/donateForEntries.ts" }, "dependencies": { "@coral-xyz/anchor": "^0.26.0", diff --git a/scripts/donateForEntries.ts b/scripts/donateForEntries.ts new file mode 100644 index 0000000..9b38a7c --- /dev/null +++ b/scripts/donateForEntries.ts @@ -0,0 +1,110 @@ +import * as anchor from '@coral-xyz/anchor'; +import { Program } from '@coral-xyz/anchor'; +import { DriftCompetitions } from '../ts/sdk/src/types/drift_competitions'; +import { CompetitionsClient } from '../ts/sdk/src'; +import { DriftClient, PublicKey, isVariant } from '@drift-labs/sdk'; +import dotenv from 'dotenv'; +import { getCompetitorAddressSync } from '../ts/sdk/src/addresses'; +import { program, Option } from 'commander'; + +dotenv.config(); + +function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} +const ENV = 'mainnet-beta'; + +const RPC_ENDPOINT = + process.env.RPC_OVERRIDE ?? 'https://api.' + ENV + '.solana.com'; + +async function donateForEntries(provider, authority: PublicKey, t: number, m: number) { + // Configure client to use the provider. + anchor.setProvider(provider); + + const payer = (provider.wallet as anchor.Wallet).payer; + console.log(`Payer: ${payer.publicKey}`); + console.log(`Recipient: ${authority}`); + + console.log('m:', m, 't:', t); + + const marketIndex = Number(m); + const tokenAmountNoPrecision = Number(t); + + const driftClient = new DriftClient({ + connection: provider.connection, + wallet: provider.wallet, + authority: authority, + spotMarketIndexes: [marketIndex], + }); + + await driftClient.subscribe(); + + const competitionClient = new CompetitionsClient({ + driftClient, + }); + + const program = competitionClient.program as Program; + + const name = 'sweepstakes'; + const competitionKey = competitionClient.getCompetitionPublicKey(name); + + const competitorKey = getCompetitorAddressSync( + competitionClient.program.programId, + competitionKey, + authority + ); + + const spotMarket = competitionClient.driftClient.getSpotMarketAccount(marketIndex); + + const tokenAmount = new anchor.BN(tokenAmountNoPrecision * 10 ** 6); + + const entries = competitionClient.getEntriesForDonation(tokenAmount, spotMarket); + + console.log('entries:', entries.toNumber()); + + const tokenAccount = await driftClient.getAssociatedTokenAccount(marketIndex); + + const txSig = await competitionClient.claimMultipleEntries(entries, tokenAccount, competitionKey, competitorKey); + + console.log(txSig); + + console.log('DONE!'); +} + +if (!process.env.ANCHOR_WALLET) { + throw new Error('ANCHOR_WALLET must be set.'); +} +require('dotenv').config(); +program + .option( + '--authority ', + 'authority of competition account for mining entries' + ) + .option('-t, --number-of-tokens ', 'number of tokens to donate') + .option('-m, --market-index ', 'market index to donate for') + .parse(); +const opts = program.opts(); + +if (!opts.authority) { + throw new Error('authority not set'); +} + +if (!opts.numberOfTokens) { + throw new Error('number of tokens not set'); +} + +if (!opts.marketIndex) { + throw new Error('market index not set'); +} + +console.log('RPC:', RPC_ENDPOINT); +donateForEntries( + anchor.AnchorProvider.local(RPC_ENDPOINT, { + preflightCommitment: 'confirmed', + skipPreflight: true, + commitment: 'confirmed', + }), + new PublicKey(opts.authority), + opts.numberOfTokens, + opts.marketIndex +); diff --git a/ts/sdk/src/competitionClient.ts b/ts/sdk/src/competitionClient.ts index d9f902e..878bb5b 100644 --- a/ts/sdk/src/competitionClient.ts +++ b/ts/sdk/src/competitionClient.ts @@ -10,7 +10,7 @@ import { QUOTE_PRECISION, PERCENTAGE_PRECISION, fetchLogs, - getSpotMarketVaultPublicKey, + getSpotMarketVaultPublicKey, SpotMarketAccount, PRICE_PRECISION, } from '@drift-labs/sdk'; import { Program } from '@coral-xyz/anchor'; import { DriftCompetitions, IDL } from './types/drift_competitions'; @@ -742,4 +742,10 @@ export class CompetitionsClient { return events; } + + public getEntriesForDonation(tokenAmount: BN, spotMarket: SpotMarketAccount) { + const strictPrice = BN.min(spotMarket.historicalOracleData.lastOraclePriceTwap5Min, spotMarket.historicalOracleData.lastOraclePrice); + + return tokenAmount.mul(strictPrice).muln(20000).div(PRICE_PRECISION).divn(10 ** spotMarket.decimals); + } } diff --git a/ts/sdk/src/idl/drift_competitions.json b/ts/sdk/src/idl/drift_competitions.json index ae8024f..415ac7f 100644 --- a/ts/sdk/src/idl/drift_competitions.json +++ b/ts/sdk/src/idl/drift_competitions.json @@ -1294,5 +1294,8 @@ "name": "CompetitorHasPendingInsuranceWithdraw", "msg": "CompetitorHasPendingInsuranceWithdraw" } - ] + ], + "metadata": { + "address": "DraWMeQX9LfzQQSYoeBwHAgM5JcqFkgrX7GbTfjzVMVL" + } } \ No newline at end of file