diff --git a/scripts/assets/CRED/CRED.json b/scripts/assets/CRED/CRED.json new file mode 100644 index 00000000..03fc602d --- /dev/null +++ b/scripts/assets/CRED/CRED.json @@ -0,0 +1,6 @@ +{ + "name": "Credible Finance", + "image": "https://raw.githubusercontent.com/metaDAOproject/programs/refs/heads/develop/scripts/assets/CRED/CRED.png", + "symbol": "CRED", + "description": "Move Money, FASTER." +} \ No newline at end of file diff --git a/scripts/assets/CRED/CRED.png b/scripts/assets/CRED/CRED.png new file mode 100644 index 00000000..5fbd8245 Binary files /dev/null and b/scripts/assets/CRED/CRED.png differ diff --git a/scripts/v0.7/credible/claimAllLaunchCredible.ts b/scripts/v0.7/credible/claimAllLaunchCredible.ts new file mode 100644 index 00000000..e69de29b diff --git a/scripts/v0.7/credible/complete.ts b/scripts/v0.7/credible/complete.ts new file mode 100644 index 00000000..c1a65aea --- /dev/null +++ b/scripts/v0.7/credible/complete.ts @@ -0,0 +1,94 @@ +import * as anchor from "@coral-xyz/anchor"; +import { + LaunchpadClient, + getLaunchAddr, +} from "@metadaoproject/programs/launchpad/v0.7"; +import { + PublicKey, + TransactionMessage, + VersionedTransaction, +} from "@solana/web3.js"; +import { createLookupTableForTransaction } from "../../utils/utils.js"; +import { token } from "@coral-xyz/anchor/dist/cjs/utils/index.js"; +import { TOKEN_SEED } from "./constants.js"; + +const provider = anchor.AnchorProvider.env(); +const payer = provider.wallet["payer"]; + +const launchpad: LaunchpadClient = LaunchpadClient.createClient({ provider }); + +export const completeLaunch = async () => { + // TODO: BEFORE RUNNING YOU NEED TO APPROVE THE FUNDING RECORDS + // SCRIPT MUST BE CREATED + const TOKEN = await PublicKey.createWithSeed( + payer.publicKey, + TOKEN_SEED, + token.TOKEN_PROGRAM_ID, + ); + console.log("Token address:", TOKEN.toBase58()); + + const [launch] = getLaunchAddr(undefined, TOKEN); + + if (launch === undefined) { + throw new Error( + "LAUNCH_TO_COMPLETE is not set. Please set it in the script.", + ); + } + + let launchAccount = await launchpad.fetchLaunch(launch); + + const tx = await launchpad + .completeLaunchIx({ + launch: launch, + baseMint: launchAccount.baseMint, + launchAuthority: payer.publicKey, + }) + .transaction(); + + const LUT = await createLookupTableForTransaction( + tx, + payer, + provider.connection, + ); + + // WE AWAIT THE LUT TO BE CREATED BEFORE GETTING THE BLOCKHASH AND CONTINUING.... + await Promise.resolve(new Promise((resolve) => setTimeout(resolve, 10000))); + const blockhash = (await provider.connection.getLatestBlockhash()).blockhash; + + const message = new TransactionMessage({ + payerKey: payer.publicKey, + recentBlockhash: blockhash, + instructions: tx.instructions, + }).compileToV0Message([LUT]); + + const vtx = new VersionedTransaction(message); + vtx.sign([payer]); + + const completeTxHash = await provider.connection.sendTransaction(vtx); + + console.log(`Complete launch transaction sent: ${completeTxHash}`); + + console.log("Launch completed successfully!"); + + console.log("Setting up performance package..."); + + // Refresh launch account to get the updated base mint + launchAccount = await launchpad.fetchLaunch(launch); + + // TODO: Review this as we will want to do this manually.. + const initializePerformancePackageTxHash = await launchpad + .initializePerformancePackageIx({ + launch: launch, + baseMint: launchAccount.baseMint, + payer: payer.publicKey, + }) + .rpc(); + + console.log( + `Initialize performance package transaction sent: ${initializePerformancePackageTxHash}`, + ); + + console.log("Performance package set up successfully!"); +}; + +completeLaunch().catch(console.error); diff --git a/scripts/v0.7/credible/constants.ts b/scripts/v0.7/credible/constants.ts new file mode 100644 index 00000000..325e116f --- /dev/null +++ b/scripts/v0.7/credible/constants.ts @@ -0,0 +1,35 @@ +import { PublicKey } from "@solana/web3.js"; + +// Token Details +export const TOKEN_SEED = "MFKO9GdJSBjq8CWO"; + +// Team Config Details +export const TEAM_ADDRESS = new PublicKey( + "44dNkVJsWPZfh3tvRyqpnwgkoL5RYqi3cWsE1d8wfviV", +); // Credible team squads address + +export const SPENDING_MEMBERS = [ + new PublicKey("44dNkVJsWPZfh3tvRyqpnwgkoL5RYqi3cWsE1d8wfviV"), + new PublicKey("4uhwwcipVRFczcCPCgZDkMgWaL8kGw7ht4k6HT3faw3g"), + new PublicKey("Fhz78PivwNKJ6JjCbNRj1QKEdgutecaQW8SqV54SkbgK"), +]; +// Even without a performance package, defaults need to be set +export const PERFORMANCE_PACKAGE_GRANTEE = new PublicKey( + "44dNkVJsWPZfh3tvRyqpnwgkoL5RYqi3cWsE1d8wfviV", // Placeholder for no performance package +); + +// Amount Details +export const MIN_GOAL = 2_000_000; // 2M USDC +export const SPENDING_LIMIT = 250_000; // 250k USDC +export const PERFORMANCE_PACKAGE_TOKEN_AMOUNT = 4_532_678; // 4_532_678 CRED +export const PERFORMANCE_PACKAGE_UNLOCK_MONTHS = 18; // 18 months +export const ADDITIONAL_CARVEOUT = 5_230_709; // 5_230_709 CRED +export const ADDITIONAL_CARVEOUT_RECIPIENT = new PublicKey( + "DVA4Q78r3N35gHFeKyMWEMP9jtv4f5joteDz3kMZTYjL", +); // Established Multisig For Credible Launch +// 2/3 Kollan Proph3t Pileks + +export const TOKEN_NAME = "Credible Finance"; +export const TOKEN_SYMBOL = "CRED"; +export const TOKEN_URI = + "https://raw.githubusercontent.com/metaDAOproject/programs/refs/heads/develop/scripts/assets/CRED/CRED.json"; diff --git a/scripts/v0.7/credible/end.ts b/scripts/v0.7/credible/end.ts new file mode 100644 index 00000000..f78bb9b6 --- /dev/null +++ b/scripts/v0.7/credible/end.ts @@ -0,0 +1,74 @@ +import * as anchor from "@coral-xyz/anchor"; +import { + LaunchpadClient, + getLaunchAddr, +} from "@metadaoproject/programs/launchpad/v0.7"; +import { ComputeBudgetProgram, PublicKey, Transaction } from "@solana/web3.js"; +import * as token from "@solana/spl-token"; +import { TOKEN_SEED } from "./constants.js"; + +const provider = anchor.AnchorProvider.env(); +const payer = provider.wallet["payer"]; + +const launchpad: LaunchpadClient = LaunchpadClient.createClient({ provider }); + +export const end = async () => { + const TOKEN = await PublicKey.createWithSeed( + payer.publicKey, + TOKEN_SEED, + token.TOKEN_PROGRAM_ID, + ); + console.log("Token address:", TOKEN.toBase58()); + + const [launch] = getLaunchAddr(undefined, TOKEN); + + const closeLaunchIx = await launchpad + .closeLaunchIx({ + launch, + }) + .instruction(); + + // Build transaction without compute budget first + const tx = new Transaction().add(closeLaunchIx); + + const { blockhash } = await provider.connection.getLatestBlockhash(); + tx.recentBlockhash = blockhash; + tx.feePayer = payer.publicKey; + + // Simulate transaction to get compute units used + tx.sign(payer); + const simulation = await provider.connection.simulateTransaction(tx); + + if (simulation.value.err) { + console.error("Transaction simulation failed:", simulation.value.err); + throw new Error( + `Simulation failed: ${JSON.stringify(simulation.value.err)}`, + ); + } + + const computeUnitsUsed = simulation.value.unitsConsumed || 200_000; + // Add 20% buffer to the compute units + const computeUnitsWithBuffer = Math.floor(computeUnitsUsed * 1.2); + + console.log(`Simulated compute units: ${computeUnitsUsed}`); + console.log(`Setting compute unit limit: ${computeUnitsWithBuffer}`); + + // Rebuild transaction with compute budget + const finalTx = new Transaction().add( + ComputeBudgetProgram.setComputeUnitLimit({ units: computeUnitsWithBuffer }), + closeLaunchIx, + ); + + finalTx.recentBlockhash = blockhash; + finalTx.feePayer = payer.publicKey; + finalTx.sign(payer); + + const txHash = await provider.connection.sendRawTransaction( + finalTx.serialize(), + ); + await provider.connection.confirmTransaction(txHash, "confirmed"); + + console.log("Launch closed", txHash); +}; + +end().catch(console.error); diff --git a/scripts/v0.7/credible/initialize.ts b/scripts/v0.7/credible/initialize.ts new file mode 100644 index 00000000..9cc2f8a3 --- /dev/null +++ b/scripts/v0.7/credible/initialize.ts @@ -0,0 +1,148 @@ +import * as anchor from "@coral-xyz/anchor"; +import { + LaunchpadClient, + getLaunchAddr, + getLaunchSignerAddr, +} from "@metadaoproject/programs/launchpad/v0.7"; +import { + ComputeBudgetProgram, + PublicKey, + SystemProgram, + Transaction, +} from "@solana/web3.js"; +import BN from "bn.js"; +import * as token from "@solana/spl-token"; +import { + TOKEN_SEED, + TOKEN_NAME, + TOKEN_SYMBOL, + TOKEN_URI, + MIN_GOAL, + SPENDING_LIMIT, + SPENDING_MEMBERS, + PERFORMANCE_PACKAGE_GRANTEE, + PERFORMANCE_PACKAGE_TOKEN_AMOUNT, + PERFORMANCE_PACKAGE_UNLOCK_MONTHS, + ADDITIONAL_CARVEOUT, + ADDITIONAL_CARVEOUT_RECIPIENT, + TEAM_ADDRESS, +} from "./constants.js"; + +const provider = anchor.AnchorProvider.env(); +const payer = provider.wallet["payer"]; + +const LAUNCH_AUTHORITY = payer.publicKey; + +const secondsPerDay = 86_400; +const numberOfDays = 4; +const launchDurationSeconds = secondsPerDay * numberOfDays; // 4 days + +const launchpad: LaunchpadClient = LaunchpadClient.createClient({ provider }); + +export const launch = async () => { + const lamports = await provider.connection.getMinimumBalanceForRentExemption( + token.MINT_SIZE, + ); + + const TOKEN = await PublicKey.createWithSeed( + payer.publicKey, + TOKEN_SEED, + token.TOKEN_PROGRAM_ID, + ); + console.log("Token address:", TOKEN.toBase58()); + + const [launch] = getLaunchAddr(undefined, TOKEN); + const [launchSigner] = getLaunchSignerAddr(undefined, launch); + + const createTokenAccountIx = SystemProgram.createAccountWithSeed({ + fromPubkey: payer.publicKey, + newAccountPubkey: TOKEN, + basePubkey: payer.publicKey, + seed: TOKEN_SEED, + lamports: lamports, + space: token.MINT_SIZE, + programId: token.TOKEN_PROGRAM_ID, + }); + + const initializeMintIx = token.createInitializeMint2Instruction( + TOKEN, + 6, + launchSigner, + null, + ); + + const launchIx = await launchpad + .initializeLaunchIx({ + tokenName: TOKEN_NAME, + tokenSymbol: TOKEN_SYMBOL, + tokenUri: TOKEN_URI, + minimumRaiseAmount: new BN(MIN_GOAL * 10 ** 6), + baseMint: TOKEN, + monthlySpendingLimitAmount: new BN(SPENDING_LIMIT * 10 ** 6), + monthlySpendingLimitMembers: SPENDING_MEMBERS, + performancePackageGrantee: PERFORMANCE_PACKAGE_GRANTEE, + performancePackageTokenAmount: new BN( + PERFORMANCE_PACKAGE_TOKEN_AMOUNT * 10 ** 6, + ), + monthsUntilInsidersCanUnlock: PERFORMANCE_PACKAGE_UNLOCK_MONTHS, + secondsForLaunch: launchDurationSeconds, + teamAddress: TEAM_ADDRESS, + additionalTokensAmount: ADDITIONAL_CARVEOUT + ? new BN(ADDITIONAL_CARVEOUT * 10 ** 6) + : undefined, + additionalTokensRecipient: ADDITIONAL_CARVEOUT_RECIPIENT, + launchAuthority: LAUNCH_AUTHORITY, + hasBidWall: false, + }) + .instruction(); + + // Build transaction without compute budget first + const tx = new Transaction().add( + createTokenAccountIx, + initializeMintIx, + launchIx, + ); + + const { blockhash } = await provider.connection.getLatestBlockhash(); + tx.recentBlockhash = blockhash; + tx.feePayer = payer.publicKey; + + // Simulate transaction to get compute units used + tx.sign(payer); + const simulation = await provider.connection.simulateTransaction(tx); + + if (simulation.value.err) { + console.error("Transaction simulation failed:", simulation.value.err); + throw new Error( + `Simulation failed: ${JSON.stringify(simulation.value.err)}`, + ); + } + + const computeUnitsUsed = simulation.value.unitsConsumed || 200_000; + // Add 20% buffer to the compute units + const computeUnitsWithBuffer = Math.floor(computeUnitsUsed * 1.2); + + console.log(`Simulated compute units: ${computeUnitsUsed}`); + console.log(`Setting compute unit limit: ${computeUnitsWithBuffer}`); + + // Rebuild transaction with compute budget + const finalTx = new Transaction().add( + ComputeBudgetProgram.setComputeUnitLimit({ units: computeUnitsWithBuffer }), + createTokenAccountIx, + initializeMintIx, + launchIx, + ); + + finalTx.recentBlockhash = blockhash; + finalTx.feePayer = payer.publicKey; + finalTx.sign(payer); + + const txHash = await provider.connection.sendRawTransaction( + finalTx.serialize(), + ); + await provider.connection.confirmTransaction(txHash, "confirmed"); + + console.log("Launch initialized", txHash); +}; + +launch().catch(console.error); diff --git a/scripts/v0.7/credible/start.ts b/scripts/v0.7/credible/start.ts new file mode 100644 index 00000000..9582ec04 --- /dev/null +++ b/scripts/v0.7/credible/start.ts @@ -0,0 +1,77 @@ +import * as anchor from "@coral-xyz/anchor"; +import { + LaunchpadClient, + getLaunchAddr, +} from "@metadaoproject/programs/launchpad/v0.7"; +import { ComputeBudgetProgram, PublicKey, Transaction } from "@solana/web3.js"; +import * as token from "@solana/spl-token"; +import { TOKEN_SEED } from "./constants.js"; + +const provider = anchor.AnchorProvider.env(); +const payer = provider.wallet["payer"]; + +const LAUNCH_AUTHORITY = payer.publicKey; + +const launchpad: LaunchpadClient = LaunchpadClient.createClient({ provider }); + +export const start = async () => { + const TOKEN = await PublicKey.createWithSeed( + payer.publicKey, + TOKEN_SEED, + token.TOKEN_PROGRAM_ID, + ); + console.log("Token address:", TOKEN.toBase58()); + + const [launch] = getLaunchAddr(undefined, TOKEN); + + const startLaunchIx = await launchpad + .startLaunchIx({ + launch, + launchAuthority: LAUNCH_AUTHORITY, + }) + .instruction(); + + // Build transaction without compute budget first + const tx = new Transaction().add(startLaunchIx); + + const { blockhash } = await provider.connection.getLatestBlockhash(); + tx.recentBlockhash = blockhash; + tx.feePayer = payer.publicKey; + + // Simulate transaction to get compute units used + tx.sign(payer); + const simulation = await provider.connection.simulateTransaction(tx); + + if (simulation.value.err) { + console.error("Transaction simulation failed:", simulation.value.err); + throw new Error( + `Simulation failed: ${JSON.stringify(simulation.value.err)}`, + ); + } + + const computeUnitsUsed = simulation.value.unitsConsumed || 200_000; + // Add 20% buffer to the compute units + const computeUnitsWithBuffer = Math.floor(computeUnitsUsed * 1.2); + + console.log(`Simulated compute units: ${computeUnitsUsed}`); + console.log(`Setting compute unit limit: ${computeUnitsWithBuffer}`); + + // Rebuild transaction with compute budget + const finalTx = new Transaction().add( + ComputeBudgetProgram.setComputeUnitLimit({ units: computeUnitsWithBuffer }), + startLaunchIx, + ); + + finalTx.recentBlockhash = blockhash; + finalTx.feePayer = payer.publicKey; + finalTx.sign(payer); + + const txHash = await provider.connection.sendRawTransaction( + finalTx.serialize(), + ); + await provider.connection.confirmTransaction(txHash, "confirmed"); + + console.log("Launch initialized", txHash); +}; + +start().catch(console.error);