From 7471ea62704ef61df413b883ef5d82aad268ad35 Mon Sep 17 00:00:00 2001 From: Proph3t Date: Fri, 14 Jun 2024 14:47:06 +0000 Subject: [PATCH] Add a script for merging conditional tokens (#233) --- Anchor.toml | 1 + scripts/mergeTokens.ts | 70 +++++++++++++++++++++++++++++++ sdk/src/ConditionalVaultClient.ts | 42 +++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 scripts/mergeTokens.ts diff --git a/Anchor.toml b/Anchor.toml index 216ace22..33b37858 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -27,6 +27,7 @@ send-tokens = "yarn run ts-node scripts/sendTokens.ts" crank = "yarn run ts-node scripts/crankTwap.ts" attach-metadata = "yarn run ts-node scripts/attachMetadata.ts" reclaim-tokens = "yarn run ts-node scripts/reclaimTokens.ts" +merge-tokens = "yarn run ts-node scripts/mergeTokens.ts" test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/*.ts" [test] diff --git a/scripts/mergeTokens.ts b/scripts/mergeTokens.ts new file mode 100644 index 00000000..1a74347e --- /dev/null +++ b/scripts/mergeTokens.ts @@ -0,0 +1,70 @@ +import * as anchor from "@coral-xyz/anchor"; +import { MEMO_PROGRAM_ID } from "@solana/spl-memo"; +import * as token from "@solana/spl-token"; +import { ComputeBudgetProgram, LAMPORTS_PER_SOL } from "@solana/web3.js"; +import { + AmmClient, + AutocratClient, + ConditionalVaultClient, +} from "@metadaoproject/futarchy"; +import { InstructionUtils } from "@metadaoproject/futarchy"; + +const { PublicKey, Keypair, SystemProgram } = anchor.web3; +const { BN, Program } = anchor; + +const provider = anchor.AnchorProvider.env(); +anchor.setProvider(provider); + +let autocratClient: AutocratClient = AutocratClient.createClient({ + provider: anchor.AnchorProvider.env(), +}); + +let ammClient: AmmClient = AmmClient.createClient({ + provider: anchor.AnchorProvider.env(), +}); + +let vaultClient: ConditionalVaultClient = ConditionalVaultClient.createClient({ + provider: anchor.AnchorProvider.env(), +}); + +const payer = provider.wallet["payer"]; + +const PROPOSAL = new PublicKey("MW1dKeDYgewceWuaSmDytdpwNzZDwABf1FuwJix923C"); + +async function main() { + const DAO = new PublicKey("ofvb3CPvEyRfD5az8PAqW6ATpPqVBeiB5zBnpPR5cgm"); + + const storedDao = await autocratClient.getDao(DAO); + console.log(storedDao); + + const { + passAmm, + failAmm, + baseVault, + quoteVault, + passBaseMint, + passQuoteMint, + failBaseMint, + failQuoteMint, + passLp, + failLp, + } = autocratClient.getProposalPdas( + PROPOSAL, + storedDao.tokenMint, + storedDao.usdcMint, + DAO + ); + + const basePassBalance = (await token.getOrCreateAssociatedTokenAccount(provider.connection, payer, passBaseMint, payer.publicKey)).amount; + const quotePassBalance = (await token.getOrCreateAssociatedTokenAccount(provider.connection, payer, passQuoteMint, payer.publicKey)).amount; + + await vaultClient.mergeConditionalTokensIx(baseVault, storedDao.tokenMint, new BN(basePassBalance.toString())) + .preInstructions([ + ComputeBudgetProgram.setComputeUnitLimit({ units: 150_000 }), + ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 100 }), + await vaultClient.mergeConditionalTokensIx(quoteVault, storedDao.usdcMint, new BN(quotePassBalance.toString())).instruction(), + ]) + .rpc(); +} + +main(); diff --git a/sdk/src/ConditionalVaultClient.ts b/sdk/src/ConditionalVaultClient.ts index 341ee9fb..e9feb0c5 100644 --- a/sdk/src/ConditionalVaultClient.ts +++ b/sdk/src/ConditionalVaultClient.ts @@ -289,6 +289,48 @@ export class ConditionalVaultClient { }); } + mergeConditionalTokensIx( + vault: PublicKey, + underlyingTokenMint: PublicKey, + amount: BN + ) { + const [conditionalOnFinalizeTokenMint] = getVaultFinalizeMintAddr( + this.vaultProgram.programId, + vault + ); + const [conditionalOnRevertTokenMint] = getVaultRevertMintAddr( + this.vaultProgram.programId, + vault + ); + + return this.vaultProgram.methods + .mergeConditionalTokensForUnderlyingTokens(amount) + .accounts({ + authority: this.provider.publicKey, + vault, + vaultUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ), + userUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + this.provider.publicKey, + true + ), + conditionalOnFinalizeTokenMint, + userConditionalOnFinalizeTokenAccount: getAssociatedTokenAddressSync( + conditionalOnFinalizeTokenMint, + this.provider.publicKey + ), + conditionalOnRevertTokenMint, + userConditionalOnRevertTokenAccount: getAssociatedTokenAddressSync( + conditionalOnRevertTokenMint, + this.provider.publicKey + ), + }); + } + async initializeVault( settlementAuthority: PublicKey, underlyingTokenMint: PublicKey