diff --git a/token-dispenser/scripts/create-treasuries-2.sh b/token-dispenser/scripts/create-treasuries-2.sh new file mode 100755 index 00000000..6f8b1829 --- /dev/null +++ b/token-dispenser/scripts/create-treasuries-2.sh @@ -0,0 +1,22 @@ + +if [[ -z $SOLANA_RPC_URL || \ + -z $LEDGER_PUB_KEY || \ + -z $LEDGER_CLI_DERIVATION_PATH || \ + -z $MINT || \ + -z $APPROVE_AMOUNT || \ + -z $CONFIG_PDA ]]; then + echo "Error: One or more required environment variables are not set." + echo "SOLANA_RPC_URL: $SOLANA_RPC_URL" + echo "LEDGER_PUB_KEY: $LEDGER_PUB_KEY" + echo "LEDGER_CLI_DERIVATION_PATH: $LEDGER_CLI_DERIVATION_PATH" + echo "MINT: $MINT" + echo "APPROVE_AMOUNT: $APPROVE_AMOUNT" + echo "CONFIG_PDA: $CONFIG_PDA" + exit 1 +fi + +while IFS= read -r TREASURY; do + MINT=$MINT TREASURY=$TREASURY npx tsx ./ts/scripts/create-treasury.ts + + TREASURY=$TREASURY CONFIG_PDA=$CONFIG_PDA MINT_AMOUNT=$MINT_AMOUNT npx tsx ./ts/scripts/delegate-treasury.ts +done < "$(dirname "$0")/treasuries" diff --git a/token-dispenser/ts/scripts/create-treasury.ts b/token-dispenser/ts/scripts/create-treasury.ts new file mode 100644 index 00000000..7506be21 --- /dev/null +++ b/token-dispenser/ts/scripts/create-treasury.ts @@ -0,0 +1,91 @@ +import { + PublicKey, + SystemProgram, + AddressLookupTableProgram, + SYSVAR_INSTRUCTIONS_PUBKEY, + Keypair, + ComputeBudgetProgram, +} from "@solana/web3.js"; + +import { TokenDispenserSdk } from "../sdk"; +import { ledgerSignAndSend, ledgerSignAndSendV0 } from "./helpers"; +import { connection, getSigner, getEnv } from "./env"; +import { funders, tokenDispenserProgramId, treasuries } from "./config"; +import fs from "fs"; +import { envOrErr } from "../../../frontend/claim_sdk/index"; +import { + TOKEN_PROGRAM_ID, + createAccount, + getMint, + getAccountLenForMint, + createInitializeAccountInstruction, +} from "@solana/spl-token"; + +type Config = { + mint: PublicKey; + treasury: Keypair; +}; + +(async () => { + const config: Config = { + mint: new PublicKey(getEnv("MINT")), + treasury: Keypair.fromSecretKey( + new Uint8Array(loadJsonSync(`${getEnv("TREASURY")}.json`)) + ), + }; + + console.log( + "Creating token account for treasury: ", + config.treasury.publicKey.toBase58() + ); + + const signer = await getSigner(); + const signerPk = new PublicKey(await signer.getAddress()); + + const mintState = await getMint( + connection, + config.mint, + "confirmed", + TOKEN_PROGRAM_ID + ); + const space = getAccountLenForMint(mintState); + const lamports = await connection.getMinimumBalanceForRentExemption(space); + + const setComputePriceIx = ComputeBudgetProgram.setComputeUnitPrice({ + microLamports: 1_000_000, + }); + + const createAccountIx = SystemProgram.createAccount({ + fromPubkey: signerPk, + newAccountPubkey: config.treasury.publicKey, + space, + lamports, + programId: TOKEN_PROGRAM_ID, + }); + + const initializeInstructionIx = createInitializeAccountInstruction( + config.treasury.publicKey, + config.mint, + signerPk, + TOKEN_PROGRAM_ID + ); + + const result = await ledgerSignAndSend( + [setComputePriceIx, createAccountIx, initializeInstructionIx], + [config.treasury] + ); + + console.log( + `Token account ${config.treasury.publicKey.toBase58()} created. Signature: `, + result + ); +})(); + +function loadJsonSync(filePath: string): any { + if (!fs.existsSync(filePath)) { + throw new Error("File does not exist"); + } + + const fileContent = fs.readFileSync(filePath, "utf-8"); + return JSON.parse(fileContent); +} diff --git a/token-dispenser/ts/scripts/delegate-treasury.ts b/token-dispenser/ts/scripts/delegate-treasury.ts new file mode 100644 index 00000000..4b15acad --- /dev/null +++ b/token-dispenser/ts/scripts/delegate-treasury.ts @@ -0,0 +1,54 @@ +import { + PublicKey, + SystemProgram, + AddressLookupTableProgram, + SYSVAR_INSTRUCTIONS_PUBKEY, + Keypair, + ComputeBudgetProgram, +} from "@solana/web3.js"; + +import { ledgerSignAndSend, ledgerSignAndSendV0 } from "./helpers"; +import { connection, getSigner, getEnv } from "./env"; +import { createApproveInstruction } from "@solana/spl-token"; + +type Config = { + treasury: PublicKey; + configAccount: PublicKey; + approveAmount: bigint; +}; + +(async () => { + const config: Config = { + treasury: new PublicKey(getEnv("TREASURY")), + configAccount: new PublicKey(getEnv("CONFIG_PDA")), + approveAmount: BigInt(getEnv("APPROVE_AMOUNT")), + }; + + console.log( + `Delegating ${config.approveAmount} of treasury: `, + config.treasury.toBase58() + ); + + const signer = await getSigner(); + const signerPk = new PublicKey(await signer.getAddress()); + const setComputePriceIx = ComputeBudgetProgram.setComputeUnitPrice({ + microLamports: 1_000_000, + }); + + const approveInstruction = createApproveInstruction( + config.treasury, + config.configAccount, + signerPk, + config.approveAmount + ); + + const result = await ledgerSignAndSend( + [setComputePriceIx, approveInstruction], + [] + ); + + console.log( + `Token account ${config.treasury.toBase58()} delegated. Signature: `, + result + ); +})(); diff --git a/token-dispenser/ts/scripts/extend-lookup-table.ts b/token-dispenser/ts/scripts/extend-lookup-table.ts new file mode 100644 index 00000000..e496e1e1 --- /dev/null +++ b/token-dispenser/ts/scripts/extend-lookup-table.ts @@ -0,0 +1,43 @@ +import { + PublicKey, + SystemProgram, + AddressLookupTableProgram, + SYSVAR_INSTRUCTIONS_PUBKEY, +} from "@solana/web3.js"; + +import { TokenDispenserSdk } from "../sdk"; +import { ledgerSignAndSend, ledgerSignAndSendV0 } from "./helpers"; +import { connection, getSigner, getEnv } from "./env"; +import { funders, tokenDispenserProgramId, treasuries } from "./config"; +import { envOrErr } from "../../../frontend/claim_sdk/index"; +import { + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, +} from "@solana/spl-token"; + +type ExtendConfig = { + // Account Addresses (base58 encoded): + lookupTable: PublicKey; + tokenDispenser: string; +}; + +(async () => { + const config: ExtendConfig = { + lookupTable: new PublicKey(envOrErr("LOOKUP_TABLE")), + tokenDispenser: tokenDispenserProgramId, + }; + + const signer = await getSigner(); + const signerPk = new PublicKey(await signer.getAddress()); + + const extendAddressLooupTableIx = AddressLookupTableProgram.extendLookupTable( + { + payer: signerPk, + authority: signerPk, + lookupTable: config.lookupTable, + addresses: [...treasuries], + } + ); + + await ledgerSignAndSendV0([extendAddressLooupTableIx], []); +})();