diff --git a/package-lock.json b/package-lock.json index 6aa2c8b66..12d6b62c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,8 @@ "ts-mocha": "^10.0.0", "tsx": "^4.7.1", "typescript": "^4.3.5" - } + }, + "version": "0.5.0-alpha.1" }, "node_modules/@babel/runtime": { "version": "7.25.4", @@ -5611,5 +5612,6 @@ "solana-bankrun": "^0.2.0" } } - } + }, + "version": "0.5.0-alpha.1" } diff --git a/package.json b/package.json index d2e9cc222..096406fb2 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "dependencies": { "@coral-xyz/anchor": "0.29.0", "@inquirer/prompts": "^7.3.3", - "@metadaoproject/futarchy": "0.4.0-alpha.75", + "@metadaoproject/futarchy": "0.5.0-alpha.1", "@metaplex-foundation/mpl-token-metadata": "^3.2.0", "@metaplex-foundation/umi": "^0.9.1", "@metaplex-foundation/umi-bundle-defaults": "^0.9.1", @@ -46,5 +46,6 @@ "tsx": "^4.7.1", "typescript": "^4.3.5" }, - "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e", + "version": "0.5.0-alpha.1" } diff --git a/sdk/package.json b/sdk/package.json index 686a7f68d..4206a9a05 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@metadaoproject/futarchy", - "version": "0.4.0-alpha.75", + "version": "0.5.0-alpha.1", "type": "module", "main": "dist/index.js", "module": "dist/index.js", @@ -12,12 +12,13 @@ "exports": { ".": "./dist/index.js", "./v0.3": "./dist/v0.3/index.js", - "./v0.4": "./dist/v0.4/index.js" + "./v0.4": "./dist/v0.4/index.js", + "./v0.5": "./dist/v0.5/index.js" }, "scripts": { "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check", - "build": "rm -rf ./dist && cp ../target/types/* ./src/v0.4/types && yarn lint:fix && yarn tsc" + "build": "rm -rf ./dist && cp ../target/types/* ./src/v0.5/types && yarn lint:fix && yarn tsc" }, "dependencies": { "@coral-xyz/anchor": "^0.29.0", @@ -25,7 +26,6 @@ "@metaplex-foundation/umi-bundle-defaults": "^0.9.2", "@metaplex-foundation/umi-uploader-bundlr": "^0.9.2", "@noble/hashes": "^1.4.0", - "@solana/spl-memo": "^0.2.5", "@solana/spl-token": "^0.3.7", "@solana/web3.js": "^1.74.0", "bn.js": "^5.2.1", diff --git a/sdk/src/v0.4/AutocratClient.ts b/sdk/src/v0.4/AutocratClient.ts index 5387d862b..3aa690c9b 100644 --- a/sdk/src/v0.4/AutocratClient.ts +++ b/sdk/src/v0.4/AutocratClient.ts @@ -574,6 +574,7 @@ export class AutocratClient { proposer: PublicKey = this.provider.publicKey ) { let [proposal] = getProposalAddr(this.autocrat.programId, proposer, nonce); + const [daoTreasury] = getDaoTreasuryAddr(this.autocrat.programId, dao); const { baseVault, quoteVault, passAmm, failAmm } = this.getProposalPdas( proposal, baseMint, @@ -592,12 +593,12 @@ export class AutocratClient { const passLpVaultAccount = getAssociatedTokenAddressSync( passLp, - proposal, + daoTreasury, true ); const failLpVaultAccount = getAssociatedTokenAddressSync( failLp, - proposal, + daoTreasury, true ); @@ -632,7 +633,21 @@ export class AutocratClient { passLpVaultAccount, failLpVaultAccount, proposer, - }); + }) + .preInstructions([ + createAssociatedTokenAccountIdempotentInstruction( + proposer, + passLpVaultAccount, + daoTreasury, + passLp + ), + createAssociatedTokenAccountIdempotentInstruction( + proposer, + failLpVaultAccount, + daoTreasury, + failLp + ), + ]); } async finalizeProposal(proposal: PublicKey) { @@ -688,9 +703,18 @@ export class AutocratClient { // quoteVault, passLpUserAccount: getAssociatedTokenAddressSync(passLp, proposer, true), failLpUserAccount: getAssociatedTokenAddressSync(failLp, proposer, true), - passLpVaultAccount: getAssociatedTokenAddressSync(passLp, proposal, true), - failLpVaultAccount: getAssociatedTokenAddressSync(failLp, proposal, true), + passLpVaultAccount: getAssociatedTokenAddressSync( + passLp, + daoTreasury, + true + ), + failLpVaultAccount: getAssociatedTokenAddressSync( + failLp, + daoTreasury, + true + ), vaultProgram: this.vaultClient.vaultProgram.programId, + treasury: daoTreasury, vaultEventAuthority, }); } diff --git a/sdk/src/v0.4/constants.ts b/sdk/src/v0.4/constants.ts index cda9338df..1b25fd677 100644 --- a/sdk/src/v0.4/constants.ts +++ b/sdk/src/v0.4/constants.ts @@ -11,12 +11,6 @@ export const AMM_PROGRAM_ID = new PublicKey( export const CONDITIONAL_VAULT_PROGRAM_ID = new PublicKey( "VLTX1ishMBbcX3rdBWGssxawAo1Q2X2qxYFYqiGodVg" ); -export const LAUNCHPAD_PROGRAM_ID = new PublicKey( - "AfJJJ5UqxhBKoE3grkKAZZsoXDE9kncbMKvqSHGsCNrE" -); -export const SHARED_LIQUIDITY_MANAGER_PROGRAM_ID = new PublicKey( - "EoJc1PYxZbnCjszampLcwJGYcB5Md47jM4oSQacRtD4d" -); export const MPL_TOKEN_METADATA_PROGRAM_ID = new PublicKey( "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" @@ -45,6 +39,10 @@ export const USDC_DECIMALS = 6; export const AUTOCRAT_LUTS: PublicKey[] = []; +export const LAUNCHPAD_PROGRAM_ID = new PublicKey( + "AfJJJ5UqxhBKoE3grkKAZZsoXDE9kncbMKvqSHGsCNrE" +); + export const RAYDIUM_AUTHORITY = PublicKey.findProgramAddressSync( [anchor.utils.bytes.utf8.encode("vault_and_lp_mint_auth_seed")], RAYDIUM_CP_SWAP_PROGRAM_ID diff --git a/sdk/src/v0.4/index.ts b/sdk/src/v0.4/index.ts index 32591eead..06af1cf6c 100644 --- a/sdk/src/v0.4/index.ts +++ b/sdk/src/v0.4/index.ts @@ -5,4 +5,3 @@ export * from "./AmmClient.js"; export * from "./AutocratClient.js"; export * from "./ConditionalVaultClient.js"; export * from "./LaunchpadClient.js"; -export * from "./SharedLiquidityManagerClient.js"; diff --git a/sdk/src/v0.4/types/amm.ts b/sdk/src/v0.4/types/amm.ts index e821c753c..457efe875 100644 --- a/sdk/src/v0.4/types/amm.ts +++ b/sdk/src/v0.4/types/amm.ts @@ -342,14 +342,6 @@ export type Amm = { { name: "seqNum"; type: "u64"; - }, - { - name: "vaultAtaBase"; - type: "publicKey"; - }, - { - name: "vaultAtaQuote"; - type: "publicKey"; } ]; }; @@ -1175,14 +1167,6 @@ export const IDL: Amm = { name: "seqNum", type: "u64", }, - { - name: "vaultAtaBase", - type: "publicKey", - }, - { - name: "vaultAtaQuote", - type: "publicKey", - }, ], }, }, diff --git a/sdk/src/v0.4/types/autocrat.ts b/sdk/src/v0.4/types/autocrat.ts index fcda41be9..c250e7ac0 100644 --- a/sdk/src/v0.4/types/autocrat.ts +++ b/sdk/src/v0.4/types/autocrat.ts @@ -123,11 +123,6 @@ export type Autocrat = { isMut: true; isSigner: true; }, - { - name: "payer"; - isMut: true; - isSigner: true; - }, { name: "tokenProgram"; isMut: false; @@ -138,11 +133,6 @@ export type Autocrat = { isMut: false; isSigner: false; }, - { - name: "associatedTokenProgram"; - isMut: false; - isSigner: false; - }, { name: "eventAuthority"; isMut: false; @@ -191,6 +181,11 @@ export type Autocrat = { isMut: true; isSigner: false; }, + { + name: "treasury"; + isMut: false; + isSigner: false; + }, { name: "passLpUserAccount"; isMut: true; @@ -1006,16 +1001,6 @@ export type Autocrat = { code: 6011; name: "InsufficientLpTokenLock"; msg: "The LP tokens passed in have less liquidity than the DAO's `min_quote_futarchic_liquidity` or `min_base_futachic_liquidity`"; - }, - { - code: 6012; - name: "ProposalDurationTooShort"; - msg: "Proposal duration must be longer than TWAP start delay"; - }, - { - code: 6013; - name: "QuestionMustBeBinary"; - msg: "Question must have exactly 2 outcomes for binary futarchy"; } ]; }; @@ -1145,11 +1130,6 @@ export const IDL: Autocrat = { isMut: true, isSigner: true, }, - { - name: "payer", - isMut: true, - isSigner: true, - }, { name: "tokenProgram", isMut: false, @@ -1160,11 +1140,6 @@ export const IDL: Autocrat = { isMut: false, isSigner: false, }, - { - name: "associatedTokenProgram", - isMut: false, - isSigner: false, - }, { name: "eventAuthority", isMut: false, @@ -1213,6 +1188,11 @@ export const IDL: Autocrat = { isMut: true, isSigner: false, }, + { + name: "treasury", + isMut: false, + isSigner: false, + }, { name: "passLpUserAccount", isMut: true, @@ -2029,15 +2009,5 @@ export const IDL: Autocrat = { name: "InsufficientLpTokenLock", msg: "The LP tokens passed in have less liquidity than the DAO's `min_quote_futarchic_liquidity` or `min_base_futachic_liquidity`", }, - { - code: 6012, - name: "ProposalDurationTooShort", - msg: "Proposal duration must be longer than TWAP start delay", - }, - { - code: 6013, - name: "QuestionMustBeBinary", - msg: "Question must have exactly 2 outcomes for binary futarchy", - }, ], }; diff --git a/sdk/src/v0.4/types/conditional_vault.ts b/sdk/src/v0.4/types/conditional_vault.ts index fd83c4bf3..a4c563cd3 100644 --- a/sdk/src/v0.4/types/conditional_vault.ts +++ b/sdk/src/v0.4/types/conditional_vault.ts @@ -914,11 +914,6 @@ export type ConditionalVault = { code: 6015; name: "ConditionalTokenMetadataAlreadySet"; msg: "Conditional token metadata already set"; - }, - { - code: 6016; - name: "UnauthorizedConditionalTokenAccount"; - msg: "Conditional token account is not owned by the authority"; } ]; }; @@ -1840,10 +1835,5 @@ export const IDL: ConditionalVault = { name: "ConditionalTokenMetadataAlreadySet", msg: "Conditional token metadata already set", }, - { - code: 6016, - name: "UnauthorizedConditionalTokenAccount", - msg: "Conditional token account is not owned by the authority", - }, ], }; diff --git a/sdk/src/v0.4/types/index.ts b/sdk/src/v0.4/types/index.ts index d8696f80d..dd2c33f34 100644 --- a/sdk/src/v0.4/types/index.ts +++ b/sdk/src/v0.4/types/index.ts @@ -16,12 +16,6 @@ import { } from "./conditional_vault.js"; export { ConditionalVaultProgram, ConditionalVaultIDL }; -import { - SharedLiquidityManager as SharedLiquidityManagerProgram, - IDL as SharedLiquidityManagerIDL, -} from "./shared_liquidity_manager.js"; -export { SharedLiquidityManagerProgram, SharedLiquidityManagerIDL }; - export { LowercaseKeys } from "./utils.js"; import type { IdlAccounts, IdlTypes, IdlEvents } from "@coral-xyz/anchor"; @@ -42,10 +36,6 @@ export type Proposal = IdlAccounts["proposal"]; export type Amm = IdlAccounts["amm"]; export type Launch = IdlAccounts["launch"]; export type FundingRecord = IdlAccounts["fundingRecord"]; -export type SharedLiquidityPool = - IdlAccounts["sharedLiquidityPool"]; -export type SharedLiquidityPoolPosition = - IdlAccounts["liquidityPosition"]; export type SwapEvent = IdlEvents["SwapEvent"]; export type AddLiquidityEvent = IdlEvents["AddLiquidityEvent"]; diff --git a/sdk/src/v0.4/utils/pda.ts b/sdk/src/v0.4/utils/pda.ts index 1df1c1dc1..fc31ec2f8 100644 --- a/sdk/src/v0.4/utils/pda.ts +++ b/sdk/src/v0.4/utils/pda.ts @@ -13,7 +13,6 @@ import { DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID, MPL_TOKEN_METADATA_PROGRAM_ID, RAYDIUM_CP_SWAP_PROGRAM_ID, - SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, } from "../constants.js"; import { LAUNCHPAD_PROGRAM_ID } from "../constants.js"; @@ -204,34 +203,6 @@ export const getLiquidityPoolAddr = ( ); }; -export const getSharedLiquidityPoolAddr = ( - programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, - dao: PublicKey, - creator: PublicKey, - proposalStakeRateThresholdBps: number -): [PublicKey, number] => { - return PublicKey.findProgramAddressSync( - [ - Buffer.from("sl_pool"), - dao.toBuffer(), - creator.toBuffer(), - new BN(proposalStakeRateThresholdBps).toArrayLike(Buffer, "le", 2), - ], - programId - ); -}; - -export const getSlPoolPositionAddr = ( - programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, - slPool: PublicKey, - user: PublicKey -): [PublicKey, number] => { - return PublicKey.findProgramAddressSync( - [Buffer.from("sl_pool_position"), slPool.toBuffer(), user.toBuffer()], - programId - ); -}; - export const getRaydiumCpmmLpMintAddr = ( poolState: PublicKey, isDevnet: boolean @@ -244,80 +215,3 @@ export const getRaydiumCpmmLpMintAddr = ( programId ); }; - -export const getRaydiumCpmmPoolVaultAddr = ( - poolState: PublicKey, - token: PublicKey, - isDevnet: boolean -): [PublicKey, number] => { - const programId = isDevnet - ? DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID - : RAYDIUM_CP_SWAP_PROGRAM_ID; - return PublicKey.findProgramAddressSync( - [ - utils.bytes.utf8.encode("pool_vault"), - poolState.toBuffer(), - token.toBuffer(), - ], - programId - ); -}; - -export const getRaydiumCpmmObservationStateAddr = ( - poolState: PublicKey, - isDevnet: boolean -): [PublicKey, number] => { - const programId = isDevnet - ? DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID - : RAYDIUM_CP_SWAP_PROGRAM_ID; - return PublicKey.findProgramAddressSync( - [utils.bytes.utf8.encode("observation"), poolState.toBuffer()], - programId - ); -}; - -export const getSharedLiquidityPoolSignerAddr = ( - programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, - slPool: PublicKey -): [PublicKey, number] => { - return PublicKey.findProgramAddressSync( - [Buffer.from("sl_pool_signer"), slPool.toBuffer()], - programId - ); -}; - -export const getSpotPoolAddr = ( - programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, - slPool: PublicKey, - index: number -): [PublicKey, number] => { - return PublicKey.findProgramAddressSync( - [ - utils.bytes.utf8.encode("spot_pool"), - slPool.toBuffer(), - new BN(index).toArrayLike(Buffer, "le", 4), - ], - programId - ); -}; - -export const getDraftProposalAddr = ( - programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, - nonce: BN -): [PublicKey, number] => { - return PublicKey.findProgramAddressSync( - [Buffer.from("draft_proposal"), nonce.toArrayLike(Buffer, "le", 8)], - programId - ); -}; - -export const getStakeRecordAddr = ( - programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, - draftProposal: PublicKey, - staker: PublicKey -): [PublicKey, number] => { - return PublicKey.findProgramAddressSync( - [Buffer.from("stake_record"), draftProposal.toBuffer(), staker.toBuffer()], - programId - ); -}; diff --git a/sdk/src/v0.5/AmmClient.ts b/sdk/src/v0.5/AmmClient.ts new file mode 100644 index 000000000..2dca891d2 --- /dev/null +++ b/sdk/src/v0.5/AmmClient.ts @@ -0,0 +1,381 @@ +import { AnchorProvider, IdlTypes, Program } from "@coral-xyz/anchor"; +import { + AccountInfo, + AddressLookupTableAccount, + Keypair, + PublicKey, +} from "@solana/web3.js"; + +import { Amm as AmmIDLType, IDL as AmmIDL } from "./types/amm.js"; + +import BN from "bn.js"; +import { AMM_PROGRAM_ID } from "./constants.js"; +import { Amm, LowercaseKeys } from "./types/index.js"; +import { getAmmLpMintAddr, getAmmAddr } from "./utils/pda.js"; +// import { MethodsBuilder } from "@coral-xyz/anchor/dist/cjs/program/namespace/methods"; +import { + MintLayout, + unpackMint, + getAssociatedTokenAddressSync, + createAssociatedTokenAccountIdempotentInstruction, +} from "@solana/spl-token"; +import { AmmMath, PriceMath } from "./utils/priceMath.js"; + +export type SwapType = LowercaseKeys["SwapType"]>; + +export type CreateAmmClientParams = { + provider: AnchorProvider; + ammProgramId?: PublicKey; +}; + +export class AmmClient { + public readonly provider: AnchorProvider; + public readonly program: Program; + public readonly luts: AddressLookupTableAccount[]; + + constructor( + provider: AnchorProvider, + ammProgramId: PublicKey, + luts: AddressLookupTableAccount[] + ) { + this.provider = provider; + this.program = new Program(AmmIDL, ammProgramId, provider); + this.luts = luts; + } + + public static createClient( + createAutocratClientParams: CreateAmmClientParams + ): AmmClient { + let { provider, ammProgramId: programId } = createAutocratClientParams; + + const luts: AddressLookupTableAccount[] = []; + + return new AmmClient(provider, programId || AMM_PROGRAM_ID, luts); + } + + getProgramId(): PublicKey { + return this.program.programId; + } + + async getAmm(amm: PublicKey): Promise { + return await this.program.account.amm.fetch(amm); + } + + async fetchAmm(amm: PublicKey): Promise { + return await this.program.account.amm.fetchNullable(amm); + } + + async deserializeAmm(accountInfo: AccountInfo): Promise { + return this.program.coder.accounts.decode("amm", accountInfo.data); + } + + async createAmm( + proposal: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey, + twapStartDelaySlots: BN, + twapInitialObservation: number, + twapMaxObservationChangePerUpdate?: number + ): Promise { + if (!twapMaxObservationChangePerUpdate) { + twapMaxObservationChangePerUpdate = twapInitialObservation * 0.02; + } + let [amm] = getAmmAddr(this.getProgramId(), baseMint, quoteMint); + + let baseDecimals = unpackMint( + baseMint, + await this.provider.connection.getAccountInfo(baseMint) + ).decimals; + let quoteDecimals = unpackMint( + quoteMint, + await this.provider.connection.getAccountInfo(quoteMint) + ).decimals; + + let [twapFirstObservationScaled, twapMaxObservationChangePerUpdateScaled] = + PriceMath.getAmmPrices( + baseDecimals, + quoteDecimals, + twapInitialObservation, + twapMaxObservationChangePerUpdate + ); + + await this.initializeAmmIx( + baseMint, + quoteMint, + twapStartDelaySlots, + twapFirstObservationScaled, + twapMaxObservationChangePerUpdateScaled + ).rpc(); + + return amm; + } + + // both twap values need to be scaled beforehand + initializeAmmIx( + baseMint: PublicKey, + quoteMint: PublicKey, + twapStartDelaySlots: BN, + twapInitialObservation: BN, + twapMaxObservationChangePerUpdate: BN + ) { + let [amm] = getAmmAddr(this.getProgramId(), baseMint, quoteMint); + let [lpMint] = getAmmLpMintAddr(this.getProgramId(), amm); + + let vaultAtaBase = getAssociatedTokenAddressSync(baseMint, amm, true); + let vaultAtaQuote = getAssociatedTokenAddressSync(quoteMint, amm, true); + + return this.program.methods + .createAmm({ + twapInitialObservation, + twapMaxObservationChangePerUpdate, + twapStartDelaySlots, + }) + .accounts({ + user: this.provider.publicKey, + amm, + lpMint, + baseMint, + quoteMint, + vaultAtaBase, + vaultAtaQuote, + }); + } + + async addLiquidity( + amm: PublicKey, + quoteAmount?: number, + baseAmount?: number + ) { + let storedAmm = await this.getAmm(amm); + + let lpMintSupply = unpackMint( + storedAmm.lpMint, + await this.provider.connection.getAccountInfo(storedAmm.lpMint) + ).supply; + + let quoteAmountCasted: BN | undefined; + let baseAmountCasted: BN | undefined; + + if (quoteAmount != undefined) { + let quoteDecimals = unpackMint( + storedAmm.quoteMint, + await this.provider.connection.getAccountInfo(storedAmm.quoteMint) + ).decimals; + quoteAmountCasted = new BN(quoteAmount).mul( + new BN(10).pow(new BN(quoteDecimals)) + ); + } + + if (baseAmount != undefined) { + let baseDecimals = unpackMint( + storedAmm.baseMint, + await this.provider.connection.getAccountInfo(storedAmm.baseMint) + ).decimals; + baseAmountCasted = new BN(baseAmount).mul( + new BN(10).pow(new BN(baseDecimals)) + ); + } + + if (lpMintSupply == 0n) { + if (quoteAmount == undefined || baseAmount == undefined) { + throw new Error( + "No pool created yet, you need to specify both base and quote" + ); + } + + // console.log(quoteAmountCasted?.toString()); + // console.log(baseAmountCasted?.toString()) + + return await this.addLiquidityIx( + amm, + storedAmm.baseMint, + storedAmm.quoteMint, + quoteAmountCasted as BN, + baseAmountCasted as BN, + new BN(0) + ).rpc(); + } + + // quoteAmount == undefined ? undefined : new BN(quoteAmount); + // let baseAmountCasted: BN | undefined = + // baseAmount == undefined ? undefined : new BN(baseAmount); + + let sim = AmmMath.simulateAddLiquidity( + storedAmm.baseAmount, + storedAmm.quoteAmount, + Number(lpMintSupply), + baseAmountCasted, + quoteAmountCasted + ); + + await this.addLiquidityIx( + amm, + storedAmm.baseMint, + storedAmm.quoteMint, + sim.quoteAmount, + sim.baseAmount, + sim.expectedLpTokens + ).rpc(); + } + + addLiquidityIx( + amm: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey, + quoteAmount: BN, + maxBaseAmount: BN, + minLpTokens: BN, + user: PublicKey = this.provider.publicKey + ) { + const [lpMint] = getAmmLpMintAddr(this.program.programId, amm); + + const userLpAccount = getAssociatedTokenAddressSync(lpMint, user, true); + + return this.program.methods + .addLiquidity({ + quoteAmount, + maxBaseAmount, + minLpTokens, + }) + .accounts({ + user, + amm, + lpMint, + userLpAccount, + userBaseAccount: getAssociatedTokenAddressSync(baseMint, user, true), + userQuoteAccount: getAssociatedTokenAddressSync(quoteMint, user, true), + vaultAtaBase: getAssociatedTokenAddressSync(baseMint, amm, true), + vaultAtaQuote: getAssociatedTokenAddressSync(quoteMint, amm, true), + }) + .preInstructions([ + createAssociatedTokenAccountIdempotentInstruction( + user, + userLpAccount, + user, + lpMint + ), + ]); + } + + removeLiquidityIx( + ammAddr: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey, + lpTokensToBurn: BN, + minBaseAmount: BN, + minQuoteAmount: BN + ) { + const [lpMint] = getAmmLpMintAddr(this.program.programId, ammAddr); + + return this.program.methods + .removeLiquidity({ + lpTokensToBurn, + minBaseAmount, + minQuoteAmount, + }) + .accounts({ + user: this.provider.publicKey, + amm: ammAddr, + lpMint, + userLpAccount: getAssociatedTokenAddressSync( + lpMint, + this.provider.publicKey, + true + ), + userBaseAccount: getAssociatedTokenAddressSync( + baseMint, + this.provider.publicKey, + true + ), + userQuoteAccount: getAssociatedTokenAddressSync( + quoteMint, + this.provider.publicKey, + true + ), + vaultAtaBase: getAssociatedTokenAddressSync(baseMint, ammAddr, true), + vaultAtaQuote: getAssociatedTokenAddressSync(quoteMint, ammAddr, true), + }); + } + + async swap( + amm: PublicKey, + swapType: SwapType, + inputAmount: number, + outputAmountMin: number + ) { + const storedAmm = await this.getAmm(amm); + + let quoteDecimals = await this.getDecimals(storedAmm.quoteMint); + let baseDecimals = await this.getDecimals(storedAmm.baseMint); + + let inputAmountScaled: BN; + let outputAmountMinScaled: BN; + if (swapType.buy) { + inputAmountScaled = PriceMath.scale(inputAmount, quoteDecimals); + outputAmountMinScaled = PriceMath.scale(outputAmountMin, baseDecimals); + } else { + inputAmountScaled = PriceMath.scale(inputAmount, baseDecimals); + outputAmountMinScaled = PriceMath.scale(outputAmountMin, quoteDecimals); + } + + return await this.swapIx( + amm, + storedAmm.baseMint, + storedAmm.quoteMint, + swapType, + inputAmountScaled, + outputAmountMinScaled + ).rpc(); + } + + swapIx( + amm: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey, + swapType: SwapType, + inputAmount: BN, + outputAmountMin: BN, + user: PublicKey = this.provider.publicKey + ) { + const receivingToken = swapType.buy ? baseMint : quoteMint; + + return this.program.methods + .swap({ + swapType, + inputAmount, + outputAmountMin, + }) + .accounts({ + user, + amm, + userBaseAccount: getAssociatedTokenAddressSync(baseMint, user, true), + userQuoteAccount: getAssociatedTokenAddressSync(quoteMint, user, true), + vaultAtaBase: getAssociatedTokenAddressSync(baseMint, amm, true), + vaultAtaQuote: getAssociatedTokenAddressSync(quoteMint, amm, true), + }) + .preInstructions([ + // create the receiving token account if it doesn't exist + createAssociatedTokenAccountIdempotentInstruction( + user, + getAssociatedTokenAddressSync(receivingToken, user, true), + user, + receivingToken + ), + ]); + } + + async crankThatTwap(amm: PublicKey) { + return this.crankThatTwapIx(amm).rpc(); + } + + crankThatTwapIx(amm: PublicKey) { + return this.program.methods.crankThatTwap().accounts({ + amm, + }); + } + + async getDecimals(mint: PublicKey): Promise { + return unpackMint(mint, await this.provider.connection.getAccountInfo(mint)) + .decimals; + } +} diff --git a/sdk/src/v0.5/AutocratClient.ts b/sdk/src/v0.5/AutocratClient.ts new file mode 100644 index 000000000..5387d862b --- /dev/null +++ b/sdk/src/v0.5/AutocratClient.ts @@ -0,0 +1,773 @@ +import { AnchorProvider, IdlTypes, Program } from "@coral-xyz/anchor"; +import { + AccountInfo, + AccountMeta, + AddressLookupTableAccount, + ComputeBudgetProgram, + Connection, + Keypair, + PublicKey, + Transaction, + TransactionInstruction, +} from "@solana/web3.js"; +import { PriceMath } from "./utils/priceMath.js"; +import { ProposalInstruction, InitializeDaoParams } from "./types/index.js"; + +import { Autocrat, IDL as AutocratIDL } from "./types/autocrat.js"; +import { + ConditionalVault, + IDL as ConditionalVaultIDL, +} from "./types/conditional_vault.js"; + +import BN from "bn.js"; +import { + AMM_PROGRAM_ID, + AUTOCRAT_PROGRAM_ID, + CONDITIONAL_VAULT_PROGRAM_ID, + MAINNET_USDC, + USDC_DECIMALS, +} from "./constants.js"; +import { + DEFAULT_CU_PRICE, + InstructionUtils, + MaxCUs, + getAmmAddr, + getAmmLpMintAddr, + getConditionalTokenMintAddr, + getDaoTreasuryAddr, + getEventAuthorityAddr, + getProposalAddr, + getQuestionAddr, + getVaultAddr, +} from "./utils/index.js"; +import { ConditionalVaultClient } from "./ConditionalVaultClient.js"; +import { AmmClient } from "./AmmClient.js"; +import { + createAssociatedTokenAccountIdempotentInstruction, + getAssociatedTokenAddressSync, + unpackMint, +} from "@solana/spl-token"; +import { sha256 } from "@noble/hashes/sha256"; +import { Dao, Proposal } from "./types/index.js"; + +export type CreateClientParams = { + provider: AnchorProvider; + autocratProgramId?: PublicKey; + conditionalVaultProgramId?: PublicKey; + ammProgramId?: PublicKey; +}; + +export type ProposalVaults = { + baseVault: PublicKey; + quoteVault: PublicKey; +}; + +export class AutocratClient { + public readonly provider: AnchorProvider; + public readonly autocrat: Program; + public readonly vaultClient: ConditionalVaultClient; + public readonly ammClient: AmmClient; + public readonly luts: AddressLookupTableAccount[]; + + constructor( + provider: AnchorProvider, + autocratProgramId: PublicKey, + conditionalVaultProgramId: PublicKey, + ammProgramId: PublicKey, + luts: AddressLookupTableAccount[] + ) { + this.provider = provider; + this.autocrat = new Program( + AutocratIDL, + autocratProgramId, + provider + ); + this.vaultClient = ConditionalVaultClient.createClient({ + provider, + conditionalVaultProgramId, + }); + this.ammClient = AmmClient.createClient({ provider, ammProgramId }); + this.luts = luts; + } + + public static createClient( + createAutocratClientParams: CreateClientParams + ): AutocratClient { + let { + provider, + autocratProgramId, + conditionalVaultProgramId, + ammProgramId, + } = createAutocratClientParams; + + const luts: AddressLookupTableAccount[] = []; + + return new AutocratClient( + provider, + autocratProgramId || AUTOCRAT_PROGRAM_ID, + conditionalVaultProgramId || CONDITIONAL_VAULT_PROGRAM_ID, + ammProgramId || AMM_PROGRAM_ID, + luts + ); + } + + getProgramId(): PublicKey { + return this.autocrat.programId; + } + + async getProposal(proposal: PublicKey): Promise { + return this.autocrat.account.proposal.fetch(proposal); + } + + async getDao(dao: PublicKey): Promise { + return this.autocrat.account.dao.fetch(dao); + } + + async fetchProposal(proposal: PublicKey): Promise { + return this.autocrat.account.proposal.fetchNullable(proposal); + } + + async fetchDao(dao: PublicKey): Promise { + return this.autocrat.account.dao.fetchNullable(dao); + } + + async deserializeProposal( + accountInfo: AccountInfo + ): Promise { + return this.autocrat.coder.accounts.decode("proposal", accountInfo.data); + } + + async deserializeDao(accountInfo: AccountInfo): Promise { + return this.autocrat.coder.accounts.decode("dao", accountInfo.data); + } + + getProposalPdas( + proposal: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey, + dao: PublicKey + ): { + question: PublicKey; + baseVault: PublicKey; + quoteVault: PublicKey; + passBaseMint: PublicKey; + passQuoteMint: PublicKey; + failBaseMint: PublicKey; + failQuoteMint: PublicKey; + passAmm: PublicKey; + failAmm: PublicKey; + passLp: PublicKey; + failLp: PublicKey; + } { + let vaultProgramId = this.vaultClient.vaultProgram.programId; + const [question] = getQuestionAddr( + vaultProgramId, + sha256(`Will ${proposal} pass?/FAIL/PASS`), + proposal, + 2 + ); + const [daoTreasury] = getDaoTreasuryAddr(this.autocrat.programId, dao); + const [baseVault] = getVaultAddr( + this.vaultClient.vaultProgram.programId, + question, + baseMint + ); + const [quoteVault] = getVaultAddr( + this.vaultClient.vaultProgram.programId, + question, + quoteMint + ); + + const [failBaseMint] = getConditionalTokenMintAddr( + vaultProgramId, + baseVault, + 0 + ); + const [failQuoteMint] = getConditionalTokenMintAddr( + vaultProgramId, + quoteVault, + 0 + ); + + const [passBaseMint] = getConditionalTokenMintAddr( + vaultProgramId, + baseVault, + 1 + ); + const [passQuoteMint] = getConditionalTokenMintAddr( + vaultProgramId, + quoteVault, + 1 + ); + + const [passAmm] = getAmmAddr( + this.ammClient.program.programId, + passBaseMint, + passQuoteMint + ); + const [failAmm] = getAmmAddr( + this.ammClient.program.programId, + failBaseMint, + failQuoteMint + ); + + const [passLp] = getAmmLpMintAddr( + this.ammClient.program.programId, + passAmm + ); + const [failLp] = getAmmLpMintAddr( + this.ammClient.program.programId, + failAmm + ); + + return { + question, + baseVault, + quoteVault, + passBaseMint, + passQuoteMint, + failBaseMint, + failQuoteMint, + passAmm, + failAmm, + passLp, + failLp, + }; + } + + async initializeDao( + tokenMint: PublicKey, + tokenPriceUiAmount: number, + minBaseFutarchicLiquidity: number, + minQuoteFutarchicLiquidity: number, + usdcMint: PublicKey = MAINNET_USDC, + daoKeypair: Keypair = Keypair.generate(), + twapStartDelaySlots: BN + ): Promise { + let tokenDecimals = unpackMint( + tokenMint, + await this.provider.connection.getAccountInfo(tokenMint) + ).decimals; + + let scaledPrice = PriceMath.getAmmPrice( + tokenPriceUiAmount, + tokenDecimals, + USDC_DECIMALS + ); + + // console.log( + // PriceMath.getHumanPrice(scaledPrice, tokenDecimals, USDC_DECIMALS) + // ); + + await this.initializeDaoIx( + daoKeypair, + tokenMint, + { + twapStartDelaySlots, + twapInitialObservation: scaledPrice, + twapMaxObservationChangePerUpdate: scaledPrice.divn(50), + minQuoteFutarchicLiquidity: new BN(minQuoteFutarchicLiquidity).mul( + new BN(10).pow(new BN(USDC_DECIMALS)) + ), + minBaseFutarchicLiquidity: new BN(minBaseFutarchicLiquidity).mul( + new BN(10).pow(new BN(tokenDecimals)) + ), + passThresholdBps: null, + slotsPerProposal: null, + }, + usdcMint + ) + .postInstructions([ + ComputeBudgetProgram.setComputeUnitLimit({ + units: MaxCUs.initializeDao, + }), + ComputeBudgetProgram.setComputeUnitPrice({ + microLamports: DEFAULT_CU_PRICE, + }), + ]) + .rpc({ maxRetries: 5 }); + + return daoKeypair.publicKey; + } + + initializeDaoIx( + daoKeypair: Keypair, + tokenMint: PublicKey, + params: InitializeDaoParams, + usdcMint: PublicKey = MAINNET_USDC + ) { + return this.autocrat.methods + .initializeDao(params) + .accounts({ + dao: daoKeypair.publicKey, + tokenMint, + usdcMint, + }) + .signers([daoKeypair]); + } + + async initializeProposal( + dao: PublicKey, + descriptionUrl: string, + instruction: ProposalInstruction, + baseTokensToLP: BN, + quoteTokensToLP: BN + ): Promise { + const storedDao = await this.getDao(dao); + + const nonce = new BN(Math.random() * 2 ** 50); + + let [proposal] = getProposalAddr( + this.autocrat.programId, + this.provider.publicKey, + nonce + ); + + await this.vaultClient.initializeQuestion( + sha256(`Will ${proposal} pass?/FAIL/PASS`), + proposal, + 2 + ); + + const { + baseVault, + quoteVault, + passAmm, + failAmm, + passBaseMint, + passQuoteMint, + failBaseMint, + failQuoteMint, + question, + } = this.getProposalPdas( + proposal, + storedDao.tokenMint, + storedDao.usdcMint, + dao + ); + + // it's important that these happen in a single atomic transaction + await this.vaultClient + .initializeVaultIx(question, storedDao.tokenMint, 2) + .postInstructions( + await InstructionUtils.getInstructions( + this.vaultClient.initializeVaultIx(question, storedDao.usdcMint, 2), + this.ammClient.initializeAmmIx( + passBaseMint, + passQuoteMint, + storedDao.twapStartDelaySlots, + storedDao.twapInitialObservation, + storedDao.twapMaxObservationChangePerUpdate + ), + this.ammClient.initializeAmmIx( + failBaseMint, + failQuoteMint, + storedDao.twapStartDelaySlots, + storedDao.twapInitialObservation, + storedDao.twapMaxObservationChangePerUpdate + ) + ) + ) + .rpc(); + + await this.vaultClient + .splitTokensIx( + question, + baseVault, + storedDao.tokenMint, + baseTokensToLP, + 2 + ) + .postInstructions( + await InstructionUtils.getInstructions( + this.vaultClient.splitTokensIx( + question, + quoteVault, + storedDao.usdcMint, + quoteTokensToLP, + 2 + ) + ) + ) + .rpc(); + + await this.ammClient + .addLiquidityIx( + passAmm, + passBaseMint, + passQuoteMint, + quoteTokensToLP, + baseTokensToLP, + new BN(0) + ) + .postInstructions( + await InstructionUtils.getInstructions( + this.ammClient.addLiquidityIx( + failAmm, + failBaseMint, + failQuoteMint, + quoteTokensToLP, + baseTokensToLP, + new BN(0) + ) + ) + ) + .rpc(); + + // this is how many original tokens are created + const lpTokens = quoteTokensToLP; + + await this.initializeProposalIx( + descriptionUrl, + instruction, + dao, + storedDao.tokenMint, + storedDao.usdcMint, + lpTokens, + lpTokens, + nonce, + question + ).rpc(); + + return proposal; + } + + // async createProposalTxAndPDAs( + // dao: PublicKey, + // descriptionUrl: string, + // instruction: ProposalInstruction, + // baseTokensToLP: BN, + // quoteTokensToLP: BN + // ): Promise< + // [ + // Transaction[], + // { + // proposalAcct: PublicKey; + // baseCondVaultAcct: PublicKey; + // quoteCondVaultAcct: PublicKey; + // passMarketAcct: PublicKey; + // failMarketAcct: PublicKey; + // } + // ] + // > { + // const storedDao = await this.getDao(dao); + + // const nonce = new BN(Math.random() * 2 ** 50); + + // let [proposal] = getProposalAddr( + // this.autocrat.programId, + // this.provider.publicKey, + // nonce + // ); + + // const { + // baseVault, + // quoteVault, + // passAmm, + // failAmm, + // passBaseMint, + // passQuoteMint, + // failBaseMint, + // failQuoteMint, + // } = this.getProposalPdas( + // proposal, + // storedDao.tokenMint, + // storedDao.usdcMint, + // dao + // ); + + // // it's important that these happen in a single atomic transaction + // const initVaultTx = await this.vaultClient + // .initializeVaultIx(proposal, storedDao.tokenMint) + // .postInstructions( + // await InstructionUtils.getInstructions( + // this.vaultClient.initializeVaultIx(proposal, storedDao.usdcMint), + // this.ammClient.createAmmIx( + // passBaseMint, + // passQuoteMint, + // storedDao.twapInitialObservation, + // storedDao.twapMaxObservationChangePerUpdate + // ), + // this.ammClient.createAmmIx( + // failBaseMint, + // failQuoteMint, + // storedDao.twapInitialObservation, + // storedDao.twapMaxObservationChangePerUpdate + // ) + // ) + // ) + // .transaction(); + + // const mintConditionalTokensTx = await this.vaultClient + // .mintConditionalTokensIx(baseVault, storedDao.tokenMint, baseTokensToLP) + // .postInstructions( + // await InstructionUtils.getInstructions( + // this.vaultClient.mintConditionalTokensIx( + // quoteVault, + // storedDao.usdcMint, + // quoteTokensToLP + // ) + // ) + // ) + // .transaction(); + + // const addLiquidityTx = await this.ammClient + // .addLiquidityIx( + // passAmm, + // passBaseMint, + // passQuoteMint, + // quoteTokensToLP, + // baseTokensToLP, + // new BN(0) + // ) + // .postInstructions( + // await InstructionUtils.getInstructions( + // this.ammClient.addLiquidityIx( + // failAmm, + // failBaseMint, + // failQuoteMint, + // quoteTokensToLP, + // baseTokensToLP, + // new BN(0) + // ) + // ) + // ) + // .transaction(); + + // // this is how many original tokens are created + // const lpTokens = quoteTokensToLP; + + // const initTx = await this.initializeProposalIx( + // descriptionUrl, + // instruction, + // dao, + // storedDao.tokenMint, + // storedDao.usdcMint, + // lpTokens, + // lpTokens, + // nonce, + // question + // ).transaction(); + + // return [ + // [initVaultTx, mintConditionalTokensTx, addLiquidityTx, initTx], + // { + // baseCondVaultAcct: baseVault, + // quoteCondVaultAcct: quoteVault, + // failMarketAcct: failAmm, + // passMarketAcct: passAmm, + // proposalAcct: proposal, + // }, + // ]; + // } + + initializeProposalIx( + descriptionUrl: string, + instruction: ProposalInstruction, + dao: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey, + passLpTokensToLock: BN, + failLpTokensToLock: BN, + nonce: BN, + question: PublicKey, + proposer: PublicKey = this.provider.publicKey + ) { + let [proposal] = getProposalAddr(this.autocrat.programId, proposer, nonce); + const { baseVault, quoteVault, passAmm, failAmm } = this.getProposalPdas( + proposal, + baseMint, + quoteMint, + dao + ); + + const [passLp] = getAmmLpMintAddr( + this.ammClient.program.programId, + passAmm + ); + const [failLp] = getAmmLpMintAddr( + this.ammClient.program.programId, + failAmm + ); + + const passLpVaultAccount = getAssociatedTokenAddressSync( + passLp, + proposal, + true + ); + const failLpVaultAccount = getAssociatedTokenAddressSync( + failLp, + proposal, + true + ); + + return this.autocrat.methods + .initializeProposal({ + descriptionUrl, + instruction, + passLpTokensToLock, + failLpTokensToLock, + nonce, + }) + .accounts({ + question, + proposal, + dao, + baseVault, + quoteVault, + passAmm, + failAmm, + passLpMint: passLp, + failLpMint: failLp, + passLpUserAccount: getAssociatedTokenAddressSync( + passLp, + proposer, + true + ), + failLpUserAccount: getAssociatedTokenAddressSync( + failLp, + proposer, + true + ), + passLpVaultAccount, + failLpVaultAccount, + proposer, + }); + } + + async finalizeProposal(proposal: PublicKey) { + let storedProposal = await this.getProposal(proposal); + let storedDao = await this.getDao(storedProposal.dao); + + return this.finalizeProposalIx( + proposal, + storedProposal.instruction, + storedProposal.dao, + storedDao.tokenMint, + storedDao.usdcMint, + storedProposal.proposer + ).rpc(); + } + + finalizeProposalIx( + proposal: PublicKey, + instruction: any, + dao: PublicKey, + daoToken: PublicKey, + usdc: PublicKey, + proposer: PublicKey + ) { + let vaultProgramId = this.vaultClient.vaultProgram.programId; + + const [daoTreasury] = getDaoTreasuryAddr(this.autocrat.programId, dao); + const { question, passAmm, failAmm } = this.getProposalPdas( + proposal, + daoToken, + usdc, + dao + ); + + const [passLp] = getAmmLpMintAddr( + this.ammClient.program.programId, + passAmm + ); + const [failLp] = getAmmLpMintAddr( + this.ammClient.program.programId, + failAmm + ); + + const [vaultEventAuthority] = getEventAuthorityAddr(vaultProgramId); + + return this.autocrat.methods.finalizeProposal().accounts({ + proposal, + passAmm, + failAmm, + dao, + question, + // baseVault, + // quoteVault, + passLpUserAccount: getAssociatedTokenAddressSync(passLp, proposer, true), + failLpUserAccount: getAssociatedTokenAddressSync(failLp, proposer, true), + passLpVaultAccount: getAssociatedTokenAddressSync(passLp, proposal, true), + failLpVaultAccount: getAssociatedTokenAddressSync(failLp, proposal, true), + vaultProgram: this.vaultClient.vaultProgram.programId, + vaultEventAuthority, + }); + } + + async executeProposal(proposal: PublicKey) { + let storedProposal = await this.getProposal(proposal); + + return this.executeProposalIx( + proposal, + storedProposal.dao, + storedProposal.instruction + ).rpc(); + } + + executeProposalIx(proposal: PublicKey, dao: PublicKey, instruction: any) { + const [daoTreasury] = getDaoTreasuryAddr(this.autocrat.programId, dao); + return this.autocrat.methods + .executeProposal() + .accounts({ + proposal, + dao, + // daoTreasury, + }) + .remainingAccounts( + instruction.accounts + .concat({ + pubkey: instruction.programId, + isWritable: false, + isSigner: false, + }) + .map((meta: AccountMeta) => + meta.pubkey.equals(daoTreasury) + ? { ...meta, isSigner: false } + : meta + ) + ); + } + + // cranks the TWAPs of multiple proposals' markets. there's a limit on the + // number of proposals you can pass in, which I can't determine rn because + // there aren't enough proposals on devnet + async crankProposalMarkets( + proposals: PublicKey[], + priorityFeeMicroLamports: number + ) { + const amms: PublicKey[] = []; + + for (const proposal of proposals) { + const storedProposal = await this.getProposal(proposal); + amms.push(storedProposal.passAmm); + amms.push(storedProposal.failAmm); + } + + while (true) { + let ixs: TransactionInstruction[] = []; + + for (const amm of amms) { + ixs.push(await this.ammClient.crankThatTwapIx(amm).instruction()); + } + + let tx = new Transaction(); + tx.add( + ComputeBudgetProgram.setComputeUnitLimit({ units: 4_000 * ixs.length }) + ); + tx.add( + ComputeBudgetProgram.setComputeUnitPrice({ + microLamports: priorityFeeMicroLamports, + }) + ); + tx.add(...ixs); + try { + await this.provider.sendAndConfirm(tx); + } catch (err) { + console.log("err", err); + } + + await new Promise((resolve) => setTimeout(resolve, 65 * 1000)); // 65,000 milliseconds = 1 minute and 5 seconds + } + } +} diff --git a/sdk/src/v0.5/ConditionalVaultClient.ts b/sdk/src/v0.5/ConditionalVaultClient.ts new file mode 100644 index 000000000..ee3f0a36d --- /dev/null +++ b/sdk/src/v0.5/ConditionalVaultClient.ts @@ -0,0 +1,475 @@ +import { AnchorProvider, Program, utils } from "@coral-xyz/anchor"; +import { + AccountInfo, + AddressLookupTableAccount, + Keypair, + PublicKey, + SystemProgram, +} from "@solana/web3.js"; + +import { ConditionalVaultProgram, ConditionalVaultIDL } from "./types/index.js"; + +import BN from "bn.js"; +import { + CONDITIONAL_VAULT_PROGRAM_ID, + MPL_TOKEN_METADATA_PROGRAM_ID, +} from "./constants.js"; +import { + getQuestionAddr, + getMetadataAddr, + getVaultAddr, + getConditionalTokenMintAddr, +} from "./utils/index.js"; +import { + createAssociatedTokenAccountIdempotentInstruction, + createAssociatedTokenAccountInstruction, + getAssociatedTokenAddressSync, + TOKEN_PROGRAM_ID, +} from "@solana/spl-token"; +import { ConditionalVault, Question } from "./types/index.js"; + +export type CreateVaultClientParams = { + provider: AnchorProvider; + conditionalVaultProgramId?: PublicKey; +}; + +export class ConditionalVaultClient { + public readonly provider: AnchorProvider; + public readonly vaultProgram: Program; + + constructor(provider: AnchorProvider, conditionalVaultProgramId: PublicKey) { + this.provider = provider; + this.vaultProgram = new Program( + ConditionalVaultIDL, + conditionalVaultProgramId, + provider + ); + } + + public static createClient( + createVaultClientParams: CreateVaultClientParams + ): ConditionalVaultClient { + let { provider, conditionalVaultProgramId } = createVaultClientParams; + + return new ConditionalVaultClient( + provider, + conditionalVaultProgramId || CONDITIONAL_VAULT_PROGRAM_ID + ); + } + + async fetchQuestion(question: PublicKey): Promise { + return this.vaultProgram.account.question.fetchNullable(question); + } + + async fetchVault(vault: PublicKey): Promise { + return this.vaultProgram.account.conditionalVault.fetchNullable(vault); + } + + async deserializeQuestion( + accountInfo: AccountInfo + ): Promise { + return this.vaultProgram.coder.accounts.decode( + "question", + accountInfo.data + ); + } + + async deserializeVault( + accountInfo: AccountInfo + ): Promise { + return this.vaultProgram.coder.accounts.decode( + "conditionalVault", + accountInfo.data + ); + } + + initializeQuestionIx( + questionId: Uint8Array, + oracle: PublicKey, + numOutcomes: number + ) { + const [question] = getQuestionAddr( + this.vaultProgram.programId, + questionId, + oracle, + numOutcomes + ); + + return this.vaultProgram.methods + .initializeQuestion({ + questionId: Array.from(questionId), + oracle, + numOutcomes, + }) + .accounts({ + question, + }); + } + + async initializeQuestion( + questionId: Uint8Array, + oracle: PublicKey, + numOutcomes: number + ): Promise { + const [question] = getQuestionAddr( + this.vaultProgram.programId, + questionId, + oracle, + numOutcomes + ); + + await this.initializeQuestionIx(questionId, oracle, numOutcomes).rpc(); + + return question; + } + + initializeVaultIx( + question: PublicKey, + underlyingTokenMint: PublicKey, + numOutcomes: number, + payer: PublicKey = this.provider.publicKey + ) { + const [vault] = getVaultAddr( + this.vaultProgram.programId, + question, + underlyingTokenMint + ); + + let conditionalTokenMintAddrs = []; + for (let i = 0; i < numOutcomes; i++) { + const [conditionalTokenMint] = getConditionalTokenMintAddr( + this.vaultProgram.programId, + vault, + i + ); + conditionalTokenMintAddrs.push(conditionalTokenMint); + } + + const vaultUnderlyingTokenAccount = getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ); + + return this.vaultProgram.methods + .initializeConditionalVault() + .accounts({ + vault, + question, + underlyingTokenMint, + vaultUnderlyingTokenAccount, + }) + .preInstructions([ + createAssociatedTokenAccountIdempotentInstruction( + payer, + vaultUnderlyingTokenAccount, + vault, + underlyingTokenMint + ), + ]) + .remainingAccounts( + conditionalTokenMintAddrs.map((conditionalTokenMint) => { + return { + pubkey: conditionalTokenMint, + isWritable: true, + isSigner: false, + }; + }) + ); + } + + // TODO remove `numOucomes` + + async initializeVault( + question: PublicKey, + underlyingTokenMint: PublicKey, + numOutcomes: number + ): Promise { + const [vault] = getVaultAddr( + this.vaultProgram.programId, + question, + underlyingTokenMint + ); + + await this.initializeVaultIx( + question, + underlyingTokenMint, + numOutcomes + ).rpc(); + + return vault; + } + + resolveQuestionIx( + question: PublicKey, + oracle: Keypair, + payoutNumerators: number[] + ) { + return this.vaultProgram.methods + .resolveQuestion({ + payoutNumerators, + }) + .accounts({ + question, + oracle: oracle.publicKey, + }) + .signers([oracle]); + } + + getConditionalTokenMints(vault: PublicKey, numOutcomes: number): PublicKey[] { + let conditionalTokenMintAddrs = []; + for (let i = 0; i < numOutcomes; i++) { + const [conditionalTokenMint] = getConditionalTokenMintAddr( + this.vaultProgram.programId, + vault, + i + ); + conditionalTokenMintAddrs.push(conditionalTokenMint); + } + return conditionalTokenMintAddrs; + } + + getRemainingAccounts( + conditionalTokenMints: PublicKey[], + userConditionalAccounts: PublicKey[] + ) { + return conditionalTokenMints + .concat(userConditionalAccounts) + .map((account) => ({ + pubkey: account, + isWritable: true, + isSigner: false, + })); + } + + // Helper method to get conditional token accounts and instructions + getConditionalTokenAccountsAndInstructions( + vault: PublicKey, + numOutcomes: number, + user: PublicKey = this.provider.publicKey, + payer: PublicKey = this.provider.publicKey + ) { + const conditionalTokenMintAddrs = this.getConditionalTokenMints( + vault, + numOutcomes + ); + const userConditionalAccounts = conditionalTokenMintAddrs.map((mint) => + getAssociatedTokenAddressSync(mint, user, true) + ); + + const preInstructions = conditionalTokenMintAddrs.map((mint) => + createAssociatedTokenAccountIdempotentInstruction( + payer, + getAssociatedTokenAddressSync(mint, user, true), + user, + mint + ) + ); + + const remainingAccounts = this.getRemainingAccounts( + conditionalTokenMintAddrs, + userConditionalAccounts + ); + + return { userConditionalAccounts, preInstructions, remainingAccounts }; + } + + splitTokensIx( + question: PublicKey, + vault: PublicKey, + underlyingTokenMint: PublicKey, + amount: BN, + numOutcomes: number, + user: PublicKey = this.provider.publicKey, + payer: PublicKey = this.provider.publicKey + ) { + const { preInstructions, remainingAccounts } = + this.getConditionalTokenAccountsAndInstructions( + vault, + numOutcomes, + user, + payer + ); + + return this.vaultProgram.methods + .splitTokens(amount) + .accounts({ + question, + authority: user, + vault, + vaultUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ), + userUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + user, + true + ), + }) + .preInstructions(preInstructions) + .remainingAccounts(remainingAccounts); + } + + mergeTokensIx( + question: PublicKey, + vault: PublicKey, + underlyingTokenMint: PublicKey, + amount: BN, + numOutcomes: number, + user: PublicKey = this.provider.publicKey, + payer: PublicKey = this.provider.publicKey + ) { + let conditionalTokenMintAddrs = this.getConditionalTokenMints( + vault, + numOutcomes + ); + + let userConditionalAccounts = []; + for (let conditionalTokenMint of conditionalTokenMintAddrs) { + userConditionalAccounts.push( + getAssociatedTokenAddressSync(conditionalTokenMint, user, true) + ); + } + + let ix = this.vaultProgram.methods + .mergeTokens(amount) + .accounts({ + question, + authority: user, + vault, + vaultUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ), + userUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + user, + true + ), + }) + .preInstructions( + conditionalTokenMintAddrs.map((conditionalTokenMint) => { + return createAssociatedTokenAccountIdempotentInstruction( + payer, + getAssociatedTokenAddressSync(conditionalTokenMint, user, true), + user, + conditionalTokenMint + ); + }) + ) + .remainingAccounts( + conditionalTokenMintAddrs + .concat(userConditionalAccounts) + .map((conditionalTokenMint) => { + return { + pubkey: conditionalTokenMint, + isWritable: true, + isSigner: false, + }; + }) + ); + + return ix; + } + + redeemTokensIx( + question: PublicKey, + vault: PublicKey, + underlyingTokenMint: PublicKey, + numOutcomes: number, + user: PublicKey = this.provider.publicKey, + payer: PublicKey = this.provider.publicKey + ) { + let conditionalTokenMintAddrs = []; + for (let i = 0; i < numOutcomes; i++) { + const [conditionalTokenMint] = getConditionalTokenMintAddr( + this.vaultProgram.programId, + vault, + i + ); + conditionalTokenMintAddrs.push(conditionalTokenMint); + } + + let userConditionalAccounts = []; + for (let conditionalTokenMint of conditionalTokenMintAddrs) { + userConditionalAccounts.push( + getAssociatedTokenAddressSync(conditionalTokenMint, user, true) + ); + } + + let ix = this.vaultProgram.methods + .redeemTokens() + .accounts({ + question, + authority: user, + vault, + vaultUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + vault, + true + ), + userUnderlyingTokenAccount: getAssociatedTokenAddressSync( + underlyingTokenMint, + user, + true + ), + }) + .preInstructions( + conditionalTokenMintAddrs.map((conditionalTokenMint) => { + return createAssociatedTokenAccountIdempotentInstruction( + payer, + getAssociatedTokenAddressSync(conditionalTokenMint, user, true), + user, + conditionalTokenMint + ); + }) + ) + .remainingAccounts( + conditionalTokenMintAddrs + .concat(userConditionalAccounts) + .map((conditionalTokenMint) => { + return { + pubkey: conditionalTokenMint, + isWritable: true, + isSigner: false, + }; + }) + ); + + return ix; + } + + addMetadataToConditionalTokensIx( + vault: PublicKey, + index: number, + name: string, + symbol: string, + uri: string, + payer: PublicKey = this.provider.publicKey + ) { + const [conditionalTokenMint] = getConditionalTokenMintAddr( + this.vaultProgram.programId, + vault, + index + ); + + const [conditionalTokenMetadata] = getMetadataAddr(conditionalTokenMint); + + return this.vaultProgram.methods + .addMetadataToConditionalTokens({ + name, + symbol, + uri, + }) + .accounts({ + payer, + vault, + conditionalTokenMint, + conditionalTokenMetadata, + tokenMetadataProgram: MPL_TOKEN_METADATA_PROGRAM_ID, + }); + } +} diff --git a/sdk/src/v0.5/LaunchpadClient.ts b/sdk/src/v0.5/LaunchpadClient.ts new file mode 100644 index 000000000..c2b6a6ce5 --- /dev/null +++ b/sdk/src/v0.5/LaunchpadClient.ts @@ -0,0 +1,411 @@ +import { AnchorProvider, Program } from "@coral-xyz/anchor"; +import { + PublicKey, + Keypair, + AccountInfo, + ComputeBudgetProgram, +} from "@solana/web3.js"; +import { Launchpad, IDL as LaunchpadIDL } from "./types/launchpad.js"; +import { + LAUNCHPAD_PROGRAM_ID, + RAYDIUM_AUTHORITY, + LOW_FEE_RAYDIUM_CONFIG, + RAYDIUM_CP_SWAP_PROGRAM_ID, + RAYDIUM_CREATE_POOL_FEE_RECEIVE, + DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID, + DEVNET_RAYDIUM_AUTHORITY, + DEVNET_LOW_FEE_RAYDIUM_CONFIG, + DEVNET_RAYDIUM_CREATE_POOL_FEE_RECEIVE, + MPL_TOKEN_METADATA_PROGRAM_ID, + MAINNET_USDC, + DEVNET_USDC, +} from "./constants.js"; +import { + createAssociatedTokenAccountIdempotentInstruction, + getAssociatedTokenAddressSync, +} from "@solana/spl-token"; +import { BN } from "@coral-xyz/anchor"; +import { FundingRecord, Launch } from "./types/index.js"; +import { + getDaoTreasuryAddr, + getEventAuthorityAddr, + getFundingRecordAddr, + getLaunchAddr, + getLaunchDaoAddr, + getLaunchSignerAddr, + getLiquidityPoolAddr, + getMetadataAddr, + getRaydiumCpmmLpMintAddr, +} from "./utils/pda.js"; +import { AutocratClient } from "./AutocratClient.js"; +import * as anchor from "@coral-xyz/anchor"; + +export type CreateLaunchpadClientParams = { + provider: AnchorProvider; + launchpadProgramId?: PublicKey; + autocratProgramId?: PublicKey; + conditionalVaultProgramId?: PublicKey; + ammProgramId?: PublicKey; +}; + +export class LaunchpadClient { + public launchpad: Program; + public provider: AnchorProvider; + public autocratClient: AutocratClient; + + private constructor(params: CreateLaunchpadClientParams) { + this.provider = params.provider; + this.launchpad = new Program( + LaunchpadIDL, + params.launchpadProgramId || LAUNCHPAD_PROGRAM_ID, + this.provider + ); + this.autocratClient = AutocratClient.createClient({ + provider: this.provider, + autocratProgramId: params.autocratProgramId, + conditionalVaultProgramId: params.conditionalVaultProgramId, + ammProgramId: params.ammProgramId, + }); + } + + static createClient(params: CreateLaunchpadClientParams): LaunchpadClient { + return new LaunchpadClient(params); + } + + getProgramId(): PublicKey { + return this.launchpad.programId; + } + + async getLaunch(launch: PublicKey): Promise { + return await this.launchpad.account.launch.fetch(launch); + } + + async fetchLaunch(launch: PublicKey): Promise { + return await this.launchpad.account.launch.fetchNullable(launch); + } + + async deserializeLaunch(accountInfo: AccountInfo): Promise { + return this.launchpad.coder.accounts.decode("launch", accountInfo.data); + } + + async getFundingRecord(fundingRecord: PublicKey): Promise { + return await this.launchpad.account.fundingRecord.fetch(fundingRecord); + } + + async fetchFundingRecord( + fundingRecord: PublicKey + ): Promise { + return await this.launchpad.account.fundingRecord.fetchNullable( + fundingRecord + ); + } + + async deserializeFundingRecord( + accountInfo: AccountInfo + ): Promise { + return this.launchpad.coder.accounts.decode( + "fundingRecord", + accountInfo.data + ); + } + + initializeLaunchIx( + tokenName: string, + tokenSymbol: string, + tokenUri: string, + minimumRaiseAmount: BN, + secondsForLaunch: number, + tokenMint: PublicKey, + launchAuthority: PublicKey = this.provider.publicKey, + isDevnet: boolean = false, + payer: PublicKey = this.provider.publicKey + ) { + const USDC = isDevnet ? DEVNET_USDC : MAINNET_USDC; + + const [launch] = getLaunchAddr(this.launchpad.programId, tokenMint); + const [launchSigner] = getLaunchSignerAddr( + this.launchpad.programId, + launch + ); + const usdcVault = getAssociatedTokenAddressSync(USDC, launchSigner, true); + + const tokenVault = getAssociatedTokenAddressSync( + tokenMint, + launchSigner, + true + ); + const [tokenMetadata] = getMetadataAddr(tokenMint); + + return this.launchpad.methods + .initializeLaunch({ + minimumRaiseAmount, + secondsForLaunch, + tokenName, + tokenSymbol, + tokenUri, + }) + .accounts({ + launch, + launchSigner, + usdcVault, + tokenVault, + launchAuthority, + usdcMint: USDC, + tokenMint, + tokenMetadata, + tokenMetadataProgram: MPL_TOKEN_METADATA_PROGRAM_ID, + payer, + }) + .preInstructions([ + createAssociatedTokenAccountIdempotentInstruction( + payer, + getAssociatedTokenAddressSync(USDC, launchSigner, true), + launchSigner, + USDC + ), + ]); + // .signers([tokenMintKp]); + } + + startLaunchIx( + launch: PublicKey, + launchAuthority: PublicKey = this.provider.publicKey + ) { + return this.launchpad.methods.startLaunch().accounts({ + launch, + launchAuthority, + }); + } + + fundIx( + launch: PublicKey, + amount: BN, + funder: PublicKey = this.provider.publicKey, + isDevnet: boolean = false + ) { + const USDC = isDevnet ? DEVNET_USDC : MAINNET_USDC; + + const [launchSigner] = getLaunchSignerAddr( + this.launchpad.programId, + launch + ); + const launchUsdcVault = getAssociatedTokenAddressSync( + USDC, + launchSigner, + true + ); + const funderUsdcAccount = getAssociatedTokenAddressSync(USDC, funder, true); + const [fundingRecord] = getFundingRecordAddr( + this.launchpad.programId, + launch, + funder + ); + + return this.launchpad.methods.fund(amount).accounts({ + launch, + launchUsdcVault, + fundingRecord, + funder, + funderUsdcAccount, + launchSigner, + }); + } + + completeLaunchIx( + launch: PublicKey, + tokenMint: PublicKey, + isDevnet: boolean = false + ) { + const USDC = isDevnet ? DEVNET_USDC : MAINNET_USDC; + + const [launchSigner] = getLaunchSignerAddr( + this.launchpad.programId, + launch + ); + const launchUsdcVault = getAssociatedTokenAddressSync( + USDC, + launchSigner, + true + ); + const launchTokenVault = getAssociatedTokenAddressSync( + tokenMint, + launchSigner, + true + ); + + // const daoKp = Keypair.generate(); + const [dao] = getLaunchDaoAddr(this.launchpad.programId, launch); + const [daoTreasury] = getDaoTreasuryAddr( + this.autocratClient.getProgramId(), + dao + ); + const treasuryUsdcAccount = getAssociatedTokenAddressSync( + USDC, + daoTreasury, + true + ); + + const [poolState] = getLiquidityPoolAddr(this.launchpad.programId, dao); + + const cpSwapProgramId = isDevnet + ? DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID + : RAYDIUM_CP_SWAP_PROGRAM_ID; + + const [lpMint] = getRaydiumCpmmLpMintAddr(poolState, isDevnet); + + const lpVault = getAssociatedTokenAddressSync(lpMint, launchSigner, true); + + const [poolTokenVault] = PublicKey.findProgramAddressSync( + [ + anchor.utils.bytes.utf8.encode("pool_vault"), + poolState.toBuffer(), + tokenMint.toBuffer(), + ], + cpSwapProgramId + ); + + const [poolUsdcVault] = PublicKey.findProgramAddressSync( + [ + anchor.utils.bytes.utf8.encode("pool_vault"), + poolState.toBuffer(), + USDC.toBuffer(), + ], + cpSwapProgramId + ); + + const [observationState] = PublicKey.findProgramAddressSync( + [anchor.utils.bytes.utf8.encode("observation"), poolState.toBuffer()], + cpSwapProgramId + ); + + const [autocratEventAuthority] = getEventAuthorityAddr( + this.autocratClient.getProgramId() + ); + + const [tokenMetadata] = getMetadataAddr(tokenMint); + + return this.launchpad.methods + .completeLaunch() + .accounts({ + launch, + launchSigner, + launchUsdcVault, + launchTokenVault, + dao, + daoTreasury, + treasuryUsdcAccount, + treasuryLpAccount: getAssociatedTokenAddressSync( + lpMint, + daoTreasury, + true + ), + usdcMint: USDC, + tokenMint, + tokenMetadata, + lpMint, + lpVault, + poolTokenVault, + poolUsdcVault, + poolState, + observationState, + cpSwapProgram: cpSwapProgramId, + authority: isDevnet ? DEVNET_RAYDIUM_AUTHORITY : RAYDIUM_AUTHORITY, + ammConfig: isDevnet + ? DEVNET_LOW_FEE_RAYDIUM_CONFIG + : LOW_FEE_RAYDIUM_CONFIG, + createPoolFee: isDevnet + ? DEVNET_RAYDIUM_CREATE_POOL_FEE_RECEIVE + : RAYDIUM_CREATE_POOL_FEE_RECEIVE, + autocratProgram: this.autocratClient.getProgramId(), + tokenMetadataProgram: MPL_TOKEN_METADATA_PROGRAM_ID, + autocratEventAuthority, + }) + .preInstructions([ + createAssociatedTokenAccountIdempotentInstruction( + this.provider.publicKey, + treasuryUsdcAccount, + daoTreasury, + USDC + ), + ]); + } + + refundIx( + launch: PublicKey, + funder: PublicKey = this.provider.publicKey, + isDevnet: boolean = false + ) { + const USDC = isDevnet ? DEVNET_USDC : MAINNET_USDC; + + const [launchSigner] = getLaunchSignerAddr( + this.launchpad.programId, + launch + ); + + const [fundingRecord] = getFundingRecordAddr( + this.launchpad.programId, + launch, + funder + ); + + const launchUsdcVault = getAssociatedTokenAddressSync( + USDC, + launchSigner, + true + ); + const funderUsdcAccount = getAssociatedTokenAddressSync(USDC, funder, true); + + return this.launchpad.methods.refund().accounts({ + launch, + launchSigner, + launchUsdcVault, + funder, + funderUsdcAccount, + fundingRecord, + }); + } + + claimIx( + launch: PublicKey, + tokenMint: PublicKey, + funder: PublicKey = this.provider.publicKey + ) { + const [launchSigner] = getLaunchSignerAddr( + this.launchpad.programId, + launch + ); + const [fundingRecord] = getFundingRecordAddr( + this.launchpad.programId, + launch, + funder + ); + + return this.launchpad.methods + .claim() + .accounts({ + launch, + fundingRecord, + launchSigner, + funder, + funderTokenAccount: getAssociatedTokenAddressSync( + tokenMint, + funder, + true + ), + tokenMint, + launchTokenVault: getAssociatedTokenAddressSync( + tokenMint, + launchSigner, + true + ), + }) + .preInstructions([ + createAssociatedTokenAccountIdempotentInstruction( + this.provider.publicKey, + getAssociatedTokenAddressSync(tokenMint, funder, true), + funder, + tokenMint + ), + ]); + } +} diff --git a/sdk/src/v0.4/SharedLiquidityManagerClient.ts b/sdk/src/v0.5/SharedLiquidityManagerClient.ts similarity index 100% rename from sdk/src/v0.4/SharedLiquidityManagerClient.ts rename to sdk/src/v0.5/SharedLiquidityManagerClient.ts diff --git a/sdk/src/v0.5/constants.ts b/sdk/src/v0.5/constants.ts new file mode 100644 index 000000000..cda9338df --- /dev/null +++ b/sdk/src/v0.5/constants.ts @@ -0,0 +1,76 @@ +import { PublicKey } from "@solana/web3.js"; +import * as anchor from "@coral-xyz/anchor"; +import { BN } from "bn.js"; + +export const AUTOCRAT_PROGRAM_ID = new PublicKey( + "autowMzCbM29YXMgVG3T62Hkgo7RcyrvgQQkd54fDQL" +); +export const AMM_PROGRAM_ID = new PublicKey( + "AMMyu265tkBpRW21iGQxKGLaves3gKm2JcMUqfXNSpqD" +); +export const CONDITIONAL_VAULT_PROGRAM_ID = new PublicKey( + "VLTX1ishMBbcX3rdBWGssxawAo1Q2X2qxYFYqiGodVg" +); +export const LAUNCHPAD_PROGRAM_ID = new PublicKey( + "AfJJJ5UqxhBKoE3grkKAZZsoXDE9kncbMKvqSHGsCNrE" +); +export const SHARED_LIQUIDITY_MANAGER_PROGRAM_ID = new PublicKey( + "EoJc1PYxZbnCjszampLcwJGYcB5Md47jM4oSQacRtD4d" +); + +export const MPL_TOKEN_METADATA_PROGRAM_ID = new PublicKey( + "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" +); + +export const RAYDIUM_CP_SWAP_PROGRAM_ID = new PublicKey( + "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C" +); + +export const DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID = new PublicKey( + "CPMDWBwJDtYax9qW7AyRuVC19Cc4L4Vcy4n2BHAbHkCW" +); + +export const META_MINT = new PublicKey( + "3gN1WVEJwSHNWjo7hr87DgZp6zkf8kWgAJD29DmfE2Gr" +); +export const MAINNET_USDC = new PublicKey( + "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" +); + +export const DEVNET_USDC = new PublicKey( + "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" +); + +export const USDC_DECIMALS = 6; + +export const AUTOCRAT_LUTS: PublicKey[] = []; + +export const RAYDIUM_AUTHORITY = PublicKey.findProgramAddressSync( + [anchor.utils.bytes.utf8.encode("vault_and_lp_mint_auth_seed")], + RAYDIUM_CP_SWAP_PROGRAM_ID +)[0]; + +export const DEVNET_RAYDIUM_AUTHORITY = PublicKey.findProgramAddressSync( + [anchor.utils.bytes.utf8.encode("vault_and_lp_mint_auth_seed")], + DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID +)[0]; + +export const LOW_FEE_RAYDIUM_CONFIG = new PublicKey( + "D4FPEruKEHrG5TenZ2mpDGEfu1iUvTiqBxvpU8HLBvC2" +); + +export const DEVNET_LOW_FEE_RAYDIUM_CONFIG = PublicKey.findProgramAddressSync( + [ + anchor.utils.bytes.utf8.encode("amm_config"), + new BN(0).toArrayLike(Buffer, "be", 2), + ], + DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID +)[0]; + +export const RAYDIUM_CREATE_POOL_FEE_RECEIVE = new PublicKey( + "DNXgeM9EiiaAbaWvwjHj9fQQLAX5ZsfHyvmYUNRAdNC8" +); + +export const DEVNET_RAYDIUM_CREATE_POOL_FEE_RECEIVE = new PublicKey( + "G11FKBRaAkHAKuLCgLM6K6NUc9rTjPAznRCjZifrTQe2" +); diff --git a/sdk/src/v0.5/index.ts b/sdk/src/v0.5/index.ts new file mode 100644 index 000000000..32591eead --- /dev/null +++ b/sdk/src/v0.5/index.ts @@ -0,0 +1,8 @@ +export * from "./types/index.js"; +export * from "./utils/index.js"; +export * from "./constants.js"; +export * from "./AmmClient.js"; +export * from "./AutocratClient.js"; +export * from "./ConditionalVaultClient.js"; +export * from "./LaunchpadClient.js"; +export * from "./SharedLiquidityManagerClient.js"; diff --git a/sdk/src/v0.5/types/amm.ts b/sdk/src/v0.5/types/amm.ts new file mode 100644 index 000000000..e821c753c --- /dev/null +++ b/sdk/src/v0.5/types/amm.ts @@ -0,0 +1,1663 @@ +export type Amm = { + version: "0.4.1"; + name: "amm"; + instructions: [ + { + name: "createAmm"; + accounts: [ + { + name: "user"; + isMut: true; + isSigner: true; + }, + { + name: "amm"; + isMut: true; + isSigner: false; + }, + { + name: "lpMint"; + isMut: true; + isSigner: false; + }, + { + name: "baseMint"; + isMut: false; + isSigner: false; + }, + { + name: "quoteMint"; + isMut: false; + isSigner: false; + }, + { + name: "vaultAtaBase"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaQuote"; + isMut: true; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "CreateAmmArgs"; + }; + } + ]; + }, + { + name: "addLiquidity"; + accounts: [ + { + name: "user"; + isMut: true; + isSigner: true; + }, + { + name: "amm"; + isMut: true; + isSigner: false; + }, + { + name: "lpMint"; + isMut: true; + isSigner: false; + }, + { + name: "userLpAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userBaseAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userQuoteAccount"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaBase"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaQuote"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "AddLiquidityArgs"; + }; + } + ]; + }, + { + name: "removeLiquidity"; + accounts: [ + { + name: "user"; + isMut: true; + isSigner: true; + }, + { + name: "amm"; + isMut: true; + isSigner: false; + }, + { + name: "lpMint"; + isMut: true; + isSigner: false; + }, + { + name: "userLpAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userBaseAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userQuoteAccount"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaBase"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaQuote"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "RemoveLiquidityArgs"; + }; + } + ]; + }, + { + name: "swap"; + accounts: [ + { + name: "user"; + isMut: true; + isSigner: true; + }, + { + name: "amm"; + isMut: true; + isSigner: false; + }, + { + name: "userBaseAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userQuoteAccount"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaBase"; + isMut: true; + isSigner: false; + }, + { + name: "vaultAtaQuote"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "SwapArgs"; + }; + } + ]; + }, + { + name: "crankThatTwap"; + accounts: [ + { + name: "amm"; + isMut: true; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: []; + } + ]; + accounts: [ + { + name: "amm"; + type: { + kind: "struct"; + fields: [ + { + name: "bump"; + type: "u8"; + }, + { + name: "createdAtSlot"; + type: "u64"; + }, + { + name: "lpMint"; + type: "publicKey"; + }, + { + name: "baseMint"; + type: "publicKey"; + }, + { + name: "quoteMint"; + type: "publicKey"; + }, + { + name: "baseMintDecimals"; + type: "u8"; + }, + { + name: "quoteMintDecimals"; + type: "u8"; + }, + { + name: "baseAmount"; + type: "u64"; + }, + { + name: "quoteAmount"; + type: "u64"; + }, + { + name: "oracle"; + type: { + defined: "TwapOracle"; + }; + }, + { + name: "seqNum"; + type: "u64"; + }, + { + name: "vaultAtaBase"; + type: "publicKey"; + }, + { + name: "vaultAtaQuote"; + type: "publicKey"; + } + ]; + }; + } + ]; + types: [ + { + name: "CommonFields"; + type: { + kind: "struct"; + fields: [ + { + name: "slot"; + type: "u64"; + }, + { + name: "unixTimestamp"; + type: "i64"; + }, + { + name: "user"; + type: "publicKey"; + }, + { + name: "amm"; + type: "publicKey"; + }, + { + name: "postBaseReserves"; + type: "u64"; + }, + { + name: "postQuoteReserves"; + type: "u64"; + }, + { + name: "oracleLastPrice"; + type: "u128"; + }, + { + name: "oracleLastObservation"; + type: "u128"; + }, + { + name: "oracleAggregator"; + type: "u128"; + }, + { + name: "seqNum"; + type: "u64"; + } + ]; + }; + }, + { + name: "AddLiquidityArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "quoteAmount"; + docs: ["How much quote token you will deposit to the pool"]; + type: "u64"; + }, + { + name: "maxBaseAmount"; + docs: ["The maximum base token you will deposit to the pool"]; + type: "u64"; + }, + { + name: "minLpTokens"; + docs: ["The minimum LP token you will get back"]; + type: "u64"; + } + ]; + }; + }, + { + name: "CreateAmmArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "twapInitialObservation"; + type: "u128"; + }, + { + name: "twapMaxObservationChangePerUpdate"; + type: "u128"; + }, + { + name: "twapStartDelaySlots"; + type: "u64"; + } + ]; + }; + }, + { + name: "RemoveLiquidityArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "lpTokensToBurn"; + type: "u64"; + }, + { + name: "minQuoteAmount"; + type: "u64"; + }, + { + name: "minBaseAmount"; + type: "u64"; + } + ]; + }; + }, + { + name: "SwapArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "swapType"; + type: { + defined: "SwapType"; + }; + }, + { + name: "inputAmount"; + type: "u64"; + }, + { + name: "outputAmountMin"; + type: "u64"; + } + ]; + }; + }, + { + name: "TwapOracle"; + type: { + kind: "struct"; + fields: [ + { + name: "lastUpdatedSlot"; + type: "u64"; + }, + { + name: "lastPrice"; + docs: [ + "A price is the number of quote units per base unit multiplied by 1e12.", + "You cannot simply divide by 1e12 to get a price you can display in the UI", + "because the base and quote decimals may be different. Instead, do:", + "ui_price = (price * (10**(base_decimals - quote_decimals))) / 1e12" + ]; + type: "u128"; + }, + { + name: "lastObservation"; + docs: [ + "If we did a raw TWAP over prices, someone could push the TWAP heavily with", + "a few extremely large outliers. So we use observations, which can only move", + "by `max_observation_change_per_update` per update." + ]; + type: "u128"; + }, + { + name: "aggregator"; + docs: [ + "Running sum of slots_per_last_update * last_observation.", + "", + "Assuming latest observations are as big as possible (u64::MAX * 1e12),", + "we can store 18 million slots worth of observations, which turns out to", + "be ~85 days worth of slots.", + "", + "Assuming that latest observations are 100x smaller than they could theoretically", + "be, we can store 8500 days (23 years) worth of them. Even this is a very", + "very conservative assumption - META/USDC prices should be between 1e9 and", + "1e15, which would overflow after 1e15 years worth of slots.", + "", + "So in the case of an overflow, the aggregator rolls back to 0. It's the", + "client's responsibility to sanity check the assets or to handle an", + "aggregator at T2 being smaller than an aggregator at T1." + ]; + type: "u128"; + }, + { + name: "maxObservationChangePerUpdate"; + docs: ["The most that an observation can change per update."]; + type: "u128"; + }, + { + name: "initialObservation"; + docs: ["What the initial `latest_observation` is set to."]; + type: "u128"; + }, + { + name: "startDelaySlots"; + docs: [ + "Number of slots after amm.created_at_slot to start recording TWAP" + ]; + type: "u64"; + } + ]; + }; + }, + { + name: "SwapType"; + type: { + kind: "enum"; + variants: [ + { + name: "Buy"; + }, + { + name: "Sell"; + } + ]; + }; + } + ]; + events: [ + { + name: "SwapEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "inputAmount"; + type: "u64"; + index: false; + }, + { + name: "outputAmount"; + type: "u64"; + index: false; + }, + { + name: "swapType"; + type: { + defined: "SwapType"; + }; + index: false; + } + ]; + }, + { + name: "AddLiquidityEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "quoteAmount"; + type: "u64"; + index: false; + }, + { + name: "maxBaseAmount"; + type: "u64"; + index: false; + }, + { + name: "minLpTokens"; + type: "u64"; + index: false; + }, + { + name: "baseAmount"; + type: "u64"; + index: false; + }, + { + name: "lpTokensMinted"; + type: "u64"; + index: false; + } + ]; + }, + { + name: "RemoveLiquidityEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "lpTokensBurned"; + type: "u64"; + index: false; + }, + { + name: "minQuoteAmount"; + type: "u64"; + index: false; + }, + { + name: "minBaseAmount"; + type: "u64"; + index: false; + }, + { + name: "baseAmount"; + type: "u64"; + index: false; + }, + { + name: "quoteAmount"; + type: "u64"; + index: false; + } + ]; + }, + { + name: "CreateAmmEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "twapInitialObservation"; + type: "u128"; + index: false; + }, + { + name: "twapMaxObservationChangePerUpdate"; + type: "u128"; + index: false; + }, + { + name: "lpMint"; + type: "publicKey"; + index: false; + }, + { + name: "baseMint"; + type: "publicKey"; + index: false; + }, + { + name: "quoteMint"; + type: "publicKey"; + index: false; + }, + { + name: "vaultAtaBase"; + type: "publicKey"; + index: false; + }, + { + name: "vaultAtaQuote"; + type: "publicKey"; + index: false; + } + ]; + }, + { + name: "CrankThatTwapEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + } + ]; + } + ]; + errors: [ + { + code: 6000; + name: "AssertFailed"; + msg: "An assertion failed"; + }, + { + code: 6001; + name: "NoSlotsPassed"; + msg: "Can't get a TWAP before some observations have been stored"; + }, + { + code: 6002; + name: "NoReserves"; + msg: "Can't swap through a pool without token reserves on either side"; + }, + { + code: 6003; + name: "InputAmountOverflow"; + msg: "Input token amount is too large for a swap, causes overflow"; + }, + { + code: 6004; + name: "AddLiquidityCalculationError"; + msg: "Add liquidity calculation error"; + }, + { + code: 6005; + name: "DecimalScaleError"; + msg: "Error in decimal scale conversion"; + }, + { + code: 6006; + name: "SameTokenMints"; + msg: "You can't create an AMM pool where the token mints are the same"; + }, + { + code: 6007; + name: "SwapSlippageExceeded"; + msg: "A user wouldn't have gotten back their `output_amount_min`, reverting"; + }, + { + code: 6008; + name: "InsufficientBalance"; + msg: "The user had insufficient balance to do this"; + }, + { + code: 6009; + name: "ZeroLiquidityRemove"; + msg: "Must remove a non-zero amount of liquidity"; + }, + { + code: 6010; + name: "ZeroLiquidityToAdd"; + msg: "Cannot add liquidity with 0 tokens on either side"; + }, + { + code: 6011; + name: "ZeroMinLpTokens"; + msg: "Must specify a non-zero `min_lp_tokens` when adding to an existing pool"; + }, + { + code: 6012; + name: "AddLiquiditySlippageExceeded"; + msg: "LP wouldn't have gotten back `lp_token_min`"; + }, + { + code: 6013; + name: "AddLiquidityMaxBaseExceeded"; + msg: "LP would have spent more than `max_base_amount`"; + }, + { + code: 6014; + name: "InsufficientQuoteAmount"; + msg: "`quote_amount` must be greater than 100000000 when initializing a pool"; + }, + { + code: 6015; + name: "ZeroSwapAmount"; + msg: "Users must swap a non-zero amount"; + }, + { + code: 6016; + name: "ConstantProductInvariantFailed"; + msg: "K should always be increasing"; + }, + { + code: 6017; + name: "CastingOverflow"; + msg: "Casting has caused an overflow"; + } + ]; +}; + +export const IDL: Amm = { + version: "0.4.1", + name: "amm", + instructions: [ + { + name: "createAmm", + accounts: [ + { + name: "user", + isMut: true, + isSigner: true, + }, + { + name: "amm", + isMut: true, + isSigner: false, + }, + { + name: "lpMint", + isMut: true, + isSigner: false, + }, + { + name: "baseMint", + isMut: false, + isSigner: false, + }, + { + name: "quoteMint", + isMut: false, + isSigner: false, + }, + { + name: "vaultAtaBase", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaQuote", + isMut: true, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "CreateAmmArgs", + }, + }, + ], + }, + { + name: "addLiquidity", + accounts: [ + { + name: "user", + isMut: true, + isSigner: true, + }, + { + name: "amm", + isMut: true, + isSigner: false, + }, + { + name: "lpMint", + isMut: true, + isSigner: false, + }, + { + name: "userLpAccount", + isMut: true, + isSigner: false, + }, + { + name: "userBaseAccount", + isMut: true, + isSigner: false, + }, + { + name: "userQuoteAccount", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaBase", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaQuote", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "AddLiquidityArgs", + }, + }, + ], + }, + { + name: "removeLiquidity", + accounts: [ + { + name: "user", + isMut: true, + isSigner: true, + }, + { + name: "amm", + isMut: true, + isSigner: false, + }, + { + name: "lpMint", + isMut: true, + isSigner: false, + }, + { + name: "userLpAccount", + isMut: true, + isSigner: false, + }, + { + name: "userBaseAccount", + isMut: true, + isSigner: false, + }, + { + name: "userQuoteAccount", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaBase", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaQuote", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "RemoveLiquidityArgs", + }, + }, + ], + }, + { + name: "swap", + accounts: [ + { + name: "user", + isMut: true, + isSigner: true, + }, + { + name: "amm", + isMut: true, + isSigner: false, + }, + { + name: "userBaseAccount", + isMut: true, + isSigner: false, + }, + { + name: "userQuoteAccount", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaBase", + isMut: true, + isSigner: false, + }, + { + name: "vaultAtaQuote", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "SwapArgs", + }, + }, + ], + }, + { + name: "crankThatTwap", + accounts: [ + { + name: "amm", + isMut: true, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + ], + accounts: [ + { + name: "amm", + type: { + kind: "struct", + fields: [ + { + name: "bump", + type: "u8", + }, + { + name: "createdAtSlot", + type: "u64", + }, + { + name: "lpMint", + type: "publicKey", + }, + { + name: "baseMint", + type: "publicKey", + }, + { + name: "quoteMint", + type: "publicKey", + }, + { + name: "baseMintDecimals", + type: "u8", + }, + { + name: "quoteMintDecimals", + type: "u8", + }, + { + name: "baseAmount", + type: "u64", + }, + { + name: "quoteAmount", + type: "u64", + }, + { + name: "oracle", + type: { + defined: "TwapOracle", + }, + }, + { + name: "seqNum", + type: "u64", + }, + { + name: "vaultAtaBase", + type: "publicKey", + }, + { + name: "vaultAtaQuote", + type: "publicKey", + }, + ], + }, + }, + ], + types: [ + { + name: "CommonFields", + type: { + kind: "struct", + fields: [ + { + name: "slot", + type: "u64", + }, + { + name: "unixTimestamp", + type: "i64", + }, + { + name: "user", + type: "publicKey", + }, + { + name: "amm", + type: "publicKey", + }, + { + name: "postBaseReserves", + type: "u64", + }, + { + name: "postQuoteReserves", + type: "u64", + }, + { + name: "oracleLastPrice", + type: "u128", + }, + { + name: "oracleLastObservation", + type: "u128", + }, + { + name: "oracleAggregator", + type: "u128", + }, + { + name: "seqNum", + type: "u64", + }, + ], + }, + }, + { + name: "AddLiquidityArgs", + type: { + kind: "struct", + fields: [ + { + name: "quoteAmount", + docs: ["How much quote token you will deposit to the pool"], + type: "u64", + }, + { + name: "maxBaseAmount", + docs: ["The maximum base token you will deposit to the pool"], + type: "u64", + }, + { + name: "minLpTokens", + docs: ["The minimum LP token you will get back"], + type: "u64", + }, + ], + }, + }, + { + name: "CreateAmmArgs", + type: { + kind: "struct", + fields: [ + { + name: "twapInitialObservation", + type: "u128", + }, + { + name: "twapMaxObservationChangePerUpdate", + type: "u128", + }, + { + name: "twapStartDelaySlots", + type: "u64", + }, + ], + }, + }, + { + name: "RemoveLiquidityArgs", + type: { + kind: "struct", + fields: [ + { + name: "lpTokensToBurn", + type: "u64", + }, + { + name: "minQuoteAmount", + type: "u64", + }, + { + name: "minBaseAmount", + type: "u64", + }, + ], + }, + }, + { + name: "SwapArgs", + type: { + kind: "struct", + fields: [ + { + name: "swapType", + type: { + defined: "SwapType", + }, + }, + { + name: "inputAmount", + type: "u64", + }, + { + name: "outputAmountMin", + type: "u64", + }, + ], + }, + }, + { + name: "TwapOracle", + type: { + kind: "struct", + fields: [ + { + name: "lastUpdatedSlot", + type: "u64", + }, + { + name: "lastPrice", + docs: [ + "A price is the number of quote units per base unit multiplied by 1e12.", + "You cannot simply divide by 1e12 to get a price you can display in the UI", + "because the base and quote decimals may be different. Instead, do:", + "ui_price = (price * (10**(base_decimals - quote_decimals))) / 1e12", + ], + type: "u128", + }, + { + name: "lastObservation", + docs: [ + "If we did a raw TWAP over prices, someone could push the TWAP heavily with", + "a few extremely large outliers. So we use observations, which can only move", + "by `max_observation_change_per_update` per update.", + ], + type: "u128", + }, + { + name: "aggregator", + docs: [ + "Running sum of slots_per_last_update * last_observation.", + "", + "Assuming latest observations are as big as possible (u64::MAX * 1e12),", + "we can store 18 million slots worth of observations, which turns out to", + "be ~85 days worth of slots.", + "", + "Assuming that latest observations are 100x smaller than they could theoretically", + "be, we can store 8500 days (23 years) worth of them. Even this is a very", + "very conservative assumption - META/USDC prices should be between 1e9 and", + "1e15, which would overflow after 1e15 years worth of slots.", + "", + "So in the case of an overflow, the aggregator rolls back to 0. It's the", + "client's responsibility to sanity check the assets or to handle an", + "aggregator at T2 being smaller than an aggregator at T1.", + ], + type: "u128", + }, + { + name: "maxObservationChangePerUpdate", + docs: ["The most that an observation can change per update."], + type: "u128", + }, + { + name: "initialObservation", + docs: ["What the initial `latest_observation` is set to."], + type: "u128", + }, + { + name: "startDelaySlots", + docs: [ + "Number of slots after amm.created_at_slot to start recording TWAP", + ], + type: "u64", + }, + ], + }, + }, + { + name: "SwapType", + type: { + kind: "enum", + variants: [ + { + name: "Buy", + }, + { + name: "Sell", + }, + ], + }, + }, + ], + events: [ + { + name: "SwapEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "inputAmount", + type: "u64", + index: false, + }, + { + name: "outputAmount", + type: "u64", + index: false, + }, + { + name: "swapType", + type: { + defined: "SwapType", + }, + index: false, + }, + ], + }, + { + name: "AddLiquidityEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "quoteAmount", + type: "u64", + index: false, + }, + { + name: "maxBaseAmount", + type: "u64", + index: false, + }, + { + name: "minLpTokens", + type: "u64", + index: false, + }, + { + name: "baseAmount", + type: "u64", + index: false, + }, + { + name: "lpTokensMinted", + type: "u64", + index: false, + }, + ], + }, + { + name: "RemoveLiquidityEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "lpTokensBurned", + type: "u64", + index: false, + }, + { + name: "minQuoteAmount", + type: "u64", + index: false, + }, + { + name: "minBaseAmount", + type: "u64", + index: false, + }, + { + name: "baseAmount", + type: "u64", + index: false, + }, + { + name: "quoteAmount", + type: "u64", + index: false, + }, + ], + }, + { + name: "CreateAmmEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "twapInitialObservation", + type: "u128", + index: false, + }, + { + name: "twapMaxObservationChangePerUpdate", + type: "u128", + index: false, + }, + { + name: "lpMint", + type: "publicKey", + index: false, + }, + { + name: "baseMint", + type: "publicKey", + index: false, + }, + { + name: "quoteMint", + type: "publicKey", + index: false, + }, + { + name: "vaultAtaBase", + type: "publicKey", + index: false, + }, + { + name: "vaultAtaQuote", + type: "publicKey", + index: false, + }, + ], + }, + { + name: "CrankThatTwapEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + ], + }, + ], + errors: [ + { + code: 6000, + name: "AssertFailed", + msg: "An assertion failed", + }, + { + code: 6001, + name: "NoSlotsPassed", + msg: "Can't get a TWAP before some observations have been stored", + }, + { + code: 6002, + name: "NoReserves", + msg: "Can't swap through a pool without token reserves on either side", + }, + { + code: 6003, + name: "InputAmountOverflow", + msg: "Input token amount is too large for a swap, causes overflow", + }, + { + code: 6004, + name: "AddLiquidityCalculationError", + msg: "Add liquidity calculation error", + }, + { + code: 6005, + name: "DecimalScaleError", + msg: "Error in decimal scale conversion", + }, + { + code: 6006, + name: "SameTokenMints", + msg: "You can't create an AMM pool where the token mints are the same", + }, + { + code: 6007, + name: "SwapSlippageExceeded", + msg: "A user wouldn't have gotten back their `output_amount_min`, reverting", + }, + { + code: 6008, + name: "InsufficientBalance", + msg: "The user had insufficient balance to do this", + }, + { + code: 6009, + name: "ZeroLiquidityRemove", + msg: "Must remove a non-zero amount of liquidity", + }, + { + code: 6010, + name: "ZeroLiquidityToAdd", + msg: "Cannot add liquidity with 0 tokens on either side", + }, + { + code: 6011, + name: "ZeroMinLpTokens", + msg: "Must specify a non-zero `min_lp_tokens` when adding to an existing pool", + }, + { + code: 6012, + name: "AddLiquiditySlippageExceeded", + msg: "LP wouldn't have gotten back `lp_token_min`", + }, + { + code: 6013, + name: "AddLiquidityMaxBaseExceeded", + msg: "LP would have spent more than `max_base_amount`", + }, + { + code: 6014, + name: "InsufficientQuoteAmount", + msg: "`quote_amount` must be greater than 100000000 when initializing a pool", + }, + { + code: 6015, + name: "ZeroSwapAmount", + msg: "Users must swap a non-zero amount", + }, + { + code: 6016, + name: "ConstantProductInvariantFailed", + msg: "K should always be increasing", + }, + { + code: 6017, + name: "CastingOverflow", + msg: "Casting has caused an overflow", + }, + ], +}; diff --git a/sdk/src/v0.5/types/autocrat.ts b/sdk/src/v0.5/types/autocrat.ts new file mode 100644 index 000000000..fcda41be9 --- /dev/null +++ b/sdk/src/v0.5/types/autocrat.ts @@ -0,0 +1,2043 @@ +export type Autocrat = { + version: "0.4.2"; + name: "autocrat"; + instructions: [ + { + name: "initializeDao"; + accounts: [ + { + name: "dao"; + isMut: true; + isSigner: true; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenMint"; + isMut: false; + isSigner: false; + }, + { + name: "usdcMint"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "params"; + type: { + defined: "InitializeDaoParams"; + }; + } + ]; + }, + { + name: "initializeProposal"; + accounts: [ + { + name: "proposal"; + isMut: true; + isSigner: false; + }, + { + name: "dao"; + isMut: true; + isSigner: false; + }, + { + name: "question"; + isMut: false; + isSigner: false; + }, + { + name: "quoteVault"; + isMut: false; + isSigner: false; + }, + { + name: "baseVault"; + isMut: false; + isSigner: false; + }, + { + name: "passAmm"; + isMut: false; + isSigner: false; + }, + { + name: "passLpMint"; + isMut: false; + isSigner: false; + }, + { + name: "failLpMint"; + isMut: false; + isSigner: false; + }, + { + name: "failAmm"; + isMut: false; + isSigner: false; + }, + { + name: "passLpUserAccount"; + isMut: true; + isSigner: false; + }, + { + name: "failLpUserAccount"; + isMut: true; + isSigner: false; + }, + { + name: "passLpVaultAccount"; + isMut: true; + isSigner: false; + }, + { + name: "failLpVaultAccount"; + isMut: true; + isSigner: false; + }, + { + name: "proposer"; + isMut: true; + isSigner: true; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "params"; + type: { + defined: "InitializeProposalParams"; + }; + } + ]; + }, + { + name: "finalizeProposal"; + accounts: [ + { + name: "proposal"; + isMut: true; + isSigner: false; + }, + { + name: "passAmm"; + isMut: false; + isSigner: false; + }, + { + name: "failAmm"; + isMut: false; + isSigner: false; + }, + { + name: "dao"; + isMut: false; + isSigner: false; + }, + { + name: "question"; + isMut: true; + isSigner: false; + }, + { + name: "passLpUserAccount"; + isMut: true; + isSigner: false; + }, + { + name: "failLpUserAccount"; + isMut: true; + isSigner: false; + }, + { + name: "passLpVaultAccount"; + isMut: true; + isSigner: false; + }, + { + name: "failLpVaultAccount"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "vaultProgram"; + isMut: false; + isSigner: false; + }, + { + name: "vaultEventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: []; + }, + { + name: "executeProposal"; + accounts: [ + { + name: "proposal"; + isMut: true; + isSigner: false; + }, + { + name: "dao"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: []; + }, + { + name: "updateDao"; + accounts: [ + { + name: "dao"; + isMut: true; + isSigner: false; + }, + { + name: "treasury"; + isMut: false; + isSigner: true; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "daoParams"; + type: { + defined: "UpdateDaoParams"; + }; + } + ]; + } + ]; + accounts: [ + { + name: "dao"; + type: { + kind: "struct"; + fields: [ + { + name: "treasuryPdaBump"; + type: "u8"; + }, + { + name: "treasury"; + type: "publicKey"; + }, + { + name: "tokenMint"; + type: "publicKey"; + }, + { + name: "usdcMint"; + type: "publicKey"; + }, + { + name: "proposalCount"; + type: "u32"; + }, + { + name: "passThresholdBps"; + type: "u16"; + }, + { + name: "slotsPerProposal"; + type: "u64"; + }, + { + name: "twapInitialObservation"; + docs: [ + "For manipulation-resistance the TWAP is a time-weighted average observation,", + "where observation tries to approximate price but can only move by", + "`twap_max_observation_change_per_update` per update. Because it can only move", + "a little bit per update, you need to check that it has a good initial observation.", + "Otherwise, an attacker could create a very high initial observation in the pass", + "market and a very low one in the fail market to force the proposal to pass.", + "", + "We recommend setting an initial observation around the spot price of the token,", + "and max observation change per update around 2% the spot price of the token.", + "For example, if the spot price of META is $400, we'd recommend setting an initial", + "observation of 400 (converted into the AMM prices) and a max observation change per", + "update of 8 (also converted into the AMM prices). Observations can be updated once", + "a minute, so 2% allows the proposal market to reach double the spot price or 0", + "in 50 minutes." + ]; + type: "u128"; + }, + { + name: "twapMaxObservationChangePerUpdate"; + type: "u128"; + }, + { + name: "twapStartDelaySlots"; + docs: [ + "Forces TWAP calculation to start after amm.created_at_slot + twap_start_delay_slots" + ]; + type: "u64"; + }, + { + name: "minQuoteFutarchicLiquidity"; + docs: [ + "As an anti-spam measure and to help liquidity, you need to lock up some liquidity", + "in both futarchic markets in order to create a proposal.", + "", + "For example, for META, we can use a `min_quote_futarchic_liquidity` of", + "5000 * 1_000_000 (5000 USDC) and a `min_base_futarchic_liquidity` of", + "10 * 1_000_000_000 (10 META)." + ]; + type: "u64"; + }, + { + name: "minBaseFutarchicLiquidity"; + type: "u64"; + }, + { + name: "seqNum"; + type: "u64"; + } + ]; + }; + }, + { + name: "proposal"; + type: { + kind: "struct"; + fields: [ + { + name: "number"; + type: "u32"; + }, + { + name: "proposer"; + type: "publicKey"; + }, + { + name: "descriptionUrl"; + type: "string"; + }, + { + name: "slotEnqueued"; + type: "u64"; + }, + { + name: "state"; + type: { + defined: "ProposalState"; + }; + }, + { + name: "instruction"; + type: { + defined: "ProposalInstruction"; + }; + }, + { + name: "passAmm"; + type: "publicKey"; + }, + { + name: "failAmm"; + type: "publicKey"; + }, + { + name: "baseVault"; + type: "publicKey"; + }, + { + name: "quoteVault"; + type: "publicKey"; + }, + { + name: "dao"; + type: "publicKey"; + }, + { + name: "passLpTokensLocked"; + type: "u64"; + }, + { + name: "failLpTokensLocked"; + type: "u64"; + }, + { + name: "nonce"; + docs: [ + "We need to include a per-proposer nonce to prevent some weird proposal", + "front-running edge cases. Using a `u64` means that proposers are unlikely", + "to run into collisions, even if they generate nonces randomly - I've run", + "the math :D" + ]; + type: "u64"; + }, + { + name: "pdaBump"; + type: "u8"; + }, + { + name: "question"; + type: "publicKey"; + }, + { + name: "durationInSlots"; + type: "u64"; + } + ]; + }; + } + ]; + types: [ + { + name: "CommonFields"; + type: { + kind: "struct"; + fields: [ + { + name: "slot"; + type: "u64"; + }, + { + name: "unixTimestamp"; + type: "i64"; + } + ]; + }; + }, + { + name: "InitializeDaoParams"; + type: { + kind: "struct"; + fields: [ + { + name: "twapInitialObservation"; + type: "u128"; + }, + { + name: "twapMaxObservationChangePerUpdate"; + type: "u128"; + }, + { + name: "twapStartDelaySlots"; + type: "u64"; + }, + { + name: "minQuoteFutarchicLiquidity"; + type: "u64"; + }, + { + name: "minBaseFutarchicLiquidity"; + type: "u64"; + }, + { + name: "passThresholdBps"; + type: { + option: "u16"; + }; + }, + { + name: "slotsPerProposal"; + type: { + option: "u64"; + }; + } + ]; + }; + }, + { + name: "InitializeProposalParams"; + type: { + kind: "struct"; + fields: [ + { + name: "descriptionUrl"; + type: "string"; + }, + { + name: "instruction"; + type: { + defined: "ProposalInstruction"; + }; + }, + { + name: "passLpTokensToLock"; + type: "u64"; + }, + { + name: "failLpTokensToLock"; + type: "u64"; + }, + { + name: "nonce"; + type: "u64"; + } + ]; + }; + }, + { + name: "UpdateDaoParams"; + type: { + kind: "struct"; + fields: [ + { + name: "passThresholdBps"; + type: { + option: "u16"; + }; + }, + { + name: "slotsPerProposal"; + type: { + option: "u64"; + }; + }, + { + name: "twapInitialObservation"; + type: { + option: "u128"; + }; + }, + { + name: "twapMaxObservationChangePerUpdate"; + type: { + option: "u128"; + }; + }, + { + name: "minQuoteFutarchicLiquidity"; + type: { + option: "u64"; + }; + }, + { + name: "minBaseFutarchicLiquidity"; + type: { + option: "u64"; + }; + } + ]; + }; + }, + { + name: "ProposalAccount"; + type: { + kind: "struct"; + fields: [ + { + name: "pubkey"; + type: "publicKey"; + }, + { + name: "isSigner"; + type: "bool"; + }, + { + name: "isWritable"; + type: "bool"; + } + ]; + }; + }, + { + name: "ProposalInstruction"; + type: { + kind: "struct"; + fields: [ + { + name: "programId"; + type: "publicKey"; + }, + { + name: "accounts"; + type: { + vec: { + defined: "ProposalAccount"; + }; + }; + }, + { + name: "data"; + type: "bytes"; + } + ]; + }; + }, + { + name: "ProposalState"; + type: { + kind: "enum"; + variants: [ + { + name: "Pending"; + }, + { + name: "Passed"; + }, + { + name: "Failed"; + }, + { + name: "Executed"; + } + ]; + }; + } + ]; + events: [ + { + name: "InitializeDaoEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "dao"; + type: "publicKey"; + index: false; + }, + { + name: "tokenMint"; + type: "publicKey"; + index: false; + }, + { + name: "usdcMint"; + type: "publicKey"; + index: false; + }, + { + name: "treasury"; + type: "publicKey"; + index: false; + }, + { + name: "passThresholdBps"; + type: "u16"; + index: false; + }, + { + name: "slotsPerProposal"; + type: "u64"; + index: false; + }, + { + name: "twapInitialObservation"; + type: "u128"; + index: false; + }, + { + name: "twapMaxObservationChangePerUpdate"; + type: "u128"; + index: false; + }, + { + name: "minQuoteFutarchicLiquidity"; + type: "u64"; + index: false; + }, + { + name: "minBaseFutarchicLiquidity"; + type: "u64"; + index: false; + } + ]; + }, + { + name: "UpdateDaoEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "dao"; + type: "publicKey"; + index: false; + }, + { + name: "passThresholdBps"; + type: "u16"; + index: false; + }, + { + name: "slotsPerProposal"; + type: "u64"; + index: false; + }, + { + name: "twapInitialObservation"; + type: "u128"; + index: false; + }, + { + name: "twapMaxObservationChangePerUpdate"; + type: "u128"; + index: false; + }, + { + name: "minQuoteFutarchicLiquidity"; + type: "u64"; + index: false; + }, + { + name: "minBaseFutarchicLiquidity"; + type: "u64"; + index: false; + } + ]; + }, + { + name: "InitializeProposalEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "proposal"; + type: "publicKey"; + index: false; + }, + { + name: "dao"; + type: "publicKey"; + index: false; + }, + { + name: "question"; + type: "publicKey"; + index: false; + }, + { + name: "quoteVault"; + type: "publicKey"; + index: false; + }, + { + name: "baseVault"; + type: "publicKey"; + index: false; + }, + { + name: "passAmm"; + type: "publicKey"; + index: false; + }, + { + name: "failAmm"; + type: "publicKey"; + index: false; + }, + { + name: "passLpMint"; + type: "publicKey"; + index: false; + }, + { + name: "failLpMint"; + type: "publicKey"; + index: false; + }, + { + name: "proposer"; + type: "publicKey"; + index: false; + }, + { + name: "nonce"; + type: "u64"; + index: false; + }, + { + name: "number"; + type: "u32"; + index: false; + }, + { + name: "passLpTokensLocked"; + type: "u64"; + index: false; + }, + { + name: "failLpTokensLocked"; + type: "u64"; + index: false; + }, + { + name: "pdaBump"; + type: "u8"; + index: false; + }, + { + name: "instruction"; + type: { + defined: "ProposalInstruction"; + }; + index: false; + }, + { + name: "durationInSlots"; + type: "u64"; + index: false; + } + ]; + }, + { + name: "FinalizeProposalEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "proposal"; + type: "publicKey"; + index: false; + }, + { + name: "dao"; + type: "publicKey"; + index: false; + }, + { + name: "passMarketTwap"; + type: "u128"; + index: false; + }, + { + name: "failMarketTwap"; + type: "u128"; + index: false; + }, + { + name: "threshold"; + type: "u128"; + index: false; + }, + { + name: "state"; + type: { + defined: "ProposalState"; + }; + index: false; + } + ]; + }, + { + name: "ExecuteProposalEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "proposal"; + type: "publicKey"; + index: false; + }, + { + name: "dao"; + type: "publicKey"; + index: false; + } + ]; + } + ]; + errors: [ + { + code: 6000; + name: "AmmTooOld"; + msg: "Amms must have been created within 5 minutes (counted in slots) of proposal initialization"; + }, + { + code: 6001; + name: "InvalidInitialObservation"; + msg: "An amm has an `initial_observation` that doesn't match the `dao`'s config"; + }, + { + code: 6002; + name: "InvalidMaxObservationChange"; + msg: "An amm has a `max_observation_change_per_update` that doesn't match the `dao`'s config"; + }, + { + code: 6003; + name: "InvalidStartDelaySlots"; + msg: "An amm has a `start_delay_slots` that doesn't match the `dao`'s config"; + }, + { + code: 6004; + name: "InvalidSettlementAuthority"; + msg: "One of the vaults has an invalid `settlement_authority`"; + }, + { + code: 6005; + name: "ProposalTooYoung"; + msg: "Proposal is too young to be executed or rejected"; + }, + { + code: 6006; + name: "MarketsTooYoung"; + msg: "Markets too young for proposal to be finalized. TWAP might need to be cranked"; + }, + { + code: 6007; + name: "ProposalAlreadyFinalized"; + msg: "This proposal has already been finalized"; + }, + { + code: 6008; + name: "InvalidVaultNonce"; + msg: "A conditional vault has an invalid nonce. A nonce should encode the proposal number"; + }, + { + code: 6009; + name: "ProposalNotPassed"; + msg: "This proposal can't be executed because it isn't in the passed state"; + }, + { + code: 6010; + name: "InsufficientLpTokenBalance"; + msg: "The proposer has fewer pass or fail LP tokens than they requested to lock"; + }, + { + code: 6011; + name: "InsufficientLpTokenLock"; + msg: "The LP tokens passed in have less liquidity than the DAO's `min_quote_futarchic_liquidity` or `min_base_futachic_liquidity`"; + }, + { + code: 6012; + name: "ProposalDurationTooShort"; + msg: "Proposal duration must be longer than TWAP start delay"; + }, + { + code: 6013; + name: "QuestionMustBeBinary"; + msg: "Question must have exactly 2 outcomes for binary futarchy"; + } + ]; +}; + +export const IDL: Autocrat = { + version: "0.4.2", + name: "autocrat", + instructions: [ + { + name: "initializeDao", + accounts: [ + { + name: "dao", + isMut: true, + isSigner: true, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenMint", + isMut: false, + isSigner: false, + }, + { + name: "usdcMint", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "params", + type: { + defined: "InitializeDaoParams", + }, + }, + ], + }, + { + name: "initializeProposal", + accounts: [ + { + name: "proposal", + isMut: true, + isSigner: false, + }, + { + name: "dao", + isMut: true, + isSigner: false, + }, + { + name: "question", + isMut: false, + isSigner: false, + }, + { + name: "quoteVault", + isMut: false, + isSigner: false, + }, + { + name: "baseVault", + isMut: false, + isSigner: false, + }, + { + name: "passAmm", + isMut: false, + isSigner: false, + }, + { + name: "passLpMint", + isMut: false, + isSigner: false, + }, + { + name: "failLpMint", + isMut: false, + isSigner: false, + }, + { + name: "failAmm", + isMut: false, + isSigner: false, + }, + { + name: "passLpUserAccount", + isMut: true, + isSigner: false, + }, + { + name: "failLpUserAccount", + isMut: true, + isSigner: false, + }, + { + name: "passLpVaultAccount", + isMut: true, + isSigner: false, + }, + { + name: "failLpVaultAccount", + isMut: true, + isSigner: false, + }, + { + name: "proposer", + isMut: true, + isSigner: true, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "params", + type: { + defined: "InitializeProposalParams", + }, + }, + ], + }, + { + name: "finalizeProposal", + accounts: [ + { + name: "proposal", + isMut: true, + isSigner: false, + }, + { + name: "passAmm", + isMut: false, + isSigner: false, + }, + { + name: "failAmm", + isMut: false, + isSigner: false, + }, + { + name: "dao", + isMut: false, + isSigner: false, + }, + { + name: "question", + isMut: true, + isSigner: false, + }, + { + name: "passLpUserAccount", + isMut: true, + isSigner: false, + }, + { + name: "failLpUserAccount", + isMut: true, + isSigner: false, + }, + { + name: "passLpVaultAccount", + isMut: true, + isSigner: false, + }, + { + name: "failLpVaultAccount", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "vaultProgram", + isMut: false, + isSigner: false, + }, + { + name: "vaultEventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: "executeProposal", + accounts: [ + { + name: "proposal", + isMut: true, + isSigner: false, + }, + { + name: "dao", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: "updateDao", + accounts: [ + { + name: "dao", + isMut: true, + isSigner: false, + }, + { + name: "treasury", + isMut: false, + isSigner: true, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "daoParams", + type: { + defined: "UpdateDaoParams", + }, + }, + ], + }, + ], + accounts: [ + { + name: "dao", + type: { + kind: "struct", + fields: [ + { + name: "treasuryPdaBump", + type: "u8", + }, + { + name: "treasury", + type: "publicKey", + }, + { + name: "tokenMint", + type: "publicKey", + }, + { + name: "usdcMint", + type: "publicKey", + }, + { + name: "proposalCount", + type: "u32", + }, + { + name: "passThresholdBps", + type: "u16", + }, + { + name: "slotsPerProposal", + type: "u64", + }, + { + name: "twapInitialObservation", + docs: [ + "For manipulation-resistance the TWAP is a time-weighted average observation,", + "where observation tries to approximate price but can only move by", + "`twap_max_observation_change_per_update` per update. Because it can only move", + "a little bit per update, you need to check that it has a good initial observation.", + "Otherwise, an attacker could create a very high initial observation in the pass", + "market and a very low one in the fail market to force the proposal to pass.", + "", + "We recommend setting an initial observation around the spot price of the token,", + "and max observation change per update around 2% the spot price of the token.", + "For example, if the spot price of META is $400, we'd recommend setting an initial", + "observation of 400 (converted into the AMM prices) and a max observation change per", + "update of 8 (also converted into the AMM prices). Observations can be updated once", + "a minute, so 2% allows the proposal market to reach double the spot price or 0", + "in 50 minutes.", + ], + type: "u128", + }, + { + name: "twapMaxObservationChangePerUpdate", + type: "u128", + }, + { + name: "twapStartDelaySlots", + docs: [ + "Forces TWAP calculation to start after amm.created_at_slot + twap_start_delay_slots", + ], + type: "u64", + }, + { + name: "minQuoteFutarchicLiquidity", + docs: [ + "As an anti-spam measure and to help liquidity, you need to lock up some liquidity", + "in both futarchic markets in order to create a proposal.", + "", + "For example, for META, we can use a `min_quote_futarchic_liquidity` of", + "5000 * 1_000_000 (5000 USDC) and a `min_base_futarchic_liquidity` of", + "10 * 1_000_000_000 (10 META).", + ], + type: "u64", + }, + { + name: "minBaseFutarchicLiquidity", + type: "u64", + }, + { + name: "seqNum", + type: "u64", + }, + ], + }, + }, + { + name: "proposal", + type: { + kind: "struct", + fields: [ + { + name: "number", + type: "u32", + }, + { + name: "proposer", + type: "publicKey", + }, + { + name: "descriptionUrl", + type: "string", + }, + { + name: "slotEnqueued", + type: "u64", + }, + { + name: "state", + type: { + defined: "ProposalState", + }, + }, + { + name: "instruction", + type: { + defined: "ProposalInstruction", + }, + }, + { + name: "passAmm", + type: "publicKey", + }, + { + name: "failAmm", + type: "publicKey", + }, + { + name: "baseVault", + type: "publicKey", + }, + { + name: "quoteVault", + type: "publicKey", + }, + { + name: "dao", + type: "publicKey", + }, + { + name: "passLpTokensLocked", + type: "u64", + }, + { + name: "failLpTokensLocked", + type: "u64", + }, + { + name: "nonce", + docs: [ + "We need to include a per-proposer nonce to prevent some weird proposal", + "front-running edge cases. Using a `u64` means that proposers are unlikely", + "to run into collisions, even if they generate nonces randomly - I've run", + "the math :D", + ], + type: "u64", + }, + { + name: "pdaBump", + type: "u8", + }, + { + name: "question", + type: "publicKey", + }, + { + name: "durationInSlots", + type: "u64", + }, + ], + }, + }, + ], + types: [ + { + name: "CommonFields", + type: { + kind: "struct", + fields: [ + { + name: "slot", + type: "u64", + }, + { + name: "unixTimestamp", + type: "i64", + }, + ], + }, + }, + { + name: "InitializeDaoParams", + type: { + kind: "struct", + fields: [ + { + name: "twapInitialObservation", + type: "u128", + }, + { + name: "twapMaxObservationChangePerUpdate", + type: "u128", + }, + { + name: "twapStartDelaySlots", + type: "u64", + }, + { + name: "minQuoteFutarchicLiquidity", + type: "u64", + }, + { + name: "minBaseFutarchicLiquidity", + type: "u64", + }, + { + name: "passThresholdBps", + type: { + option: "u16", + }, + }, + { + name: "slotsPerProposal", + type: { + option: "u64", + }, + }, + ], + }, + }, + { + name: "InitializeProposalParams", + type: { + kind: "struct", + fields: [ + { + name: "descriptionUrl", + type: "string", + }, + { + name: "instruction", + type: { + defined: "ProposalInstruction", + }, + }, + { + name: "passLpTokensToLock", + type: "u64", + }, + { + name: "failLpTokensToLock", + type: "u64", + }, + { + name: "nonce", + type: "u64", + }, + ], + }, + }, + { + name: "UpdateDaoParams", + type: { + kind: "struct", + fields: [ + { + name: "passThresholdBps", + type: { + option: "u16", + }, + }, + { + name: "slotsPerProposal", + type: { + option: "u64", + }, + }, + { + name: "twapInitialObservation", + type: { + option: "u128", + }, + }, + { + name: "twapMaxObservationChangePerUpdate", + type: { + option: "u128", + }, + }, + { + name: "minQuoteFutarchicLiquidity", + type: { + option: "u64", + }, + }, + { + name: "minBaseFutarchicLiquidity", + type: { + option: "u64", + }, + }, + ], + }, + }, + { + name: "ProposalAccount", + type: { + kind: "struct", + fields: [ + { + name: "pubkey", + type: "publicKey", + }, + { + name: "isSigner", + type: "bool", + }, + { + name: "isWritable", + type: "bool", + }, + ], + }, + }, + { + name: "ProposalInstruction", + type: { + kind: "struct", + fields: [ + { + name: "programId", + type: "publicKey", + }, + { + name: "accounts", + type: { + vec: { + defined: "ProposalAccount", + }, + }, + }, + { + name: "data", + type: "bytes", + }, + ], + }, + }, + { + name: "ProposalState", + type: { + kind: "enum", + variants: [ + { + name: "Pending", + }, + { + name: "Passed", + }, + { + name: "Failed", + }, + { + name: "Executed", + }, + ], + }, + }, + ], + events: [ + { + name: "InitializeDaoEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "dao", + type: "publicKey", + index: false, + }, + { + name: "tokenMint", + type: "publicKey", + index: false, + }, + { + name: "usdcMint", + type: "publicKey", + index: false, + }, + { + name: "treasury", + type: "publicKey", + index: false, + }, + { + name: "passThresholdBps", + type: "u16", + index: false, + }, + { + name: "slotsPerProposal", + type: "u64", + index: false, + }, + { + name: "twapInitialObservation", + type: "u128", + index: false, + }, + { + name: "twapMaxObservationChangePerUpdate", + type: "u128", + index: false, + }, + { + name: "minQuoteFutarchicLiquidity", + type: "u64", + index: false, + }, + { + name: "minBaseFutarchicLiquidity", + type: "u64", + index: false, + }, + ], + }, + { + name: "UpdateDaoEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "dao", + type: "publicKey", + index: false, + }, + { + name: "passThresholdBps", + type: "u16", + index: false, + }, + { + name: "slotsPerProposal", + type: "u64", + index: false, + }, + { + name: "twapInitialObservation", + type: "u128", + index: false, + }, + { + name: "twapMaxObservationChangePerUpdate", + type: "u128", + index: false, + }, + { + name: "minQuoteFutarchicLiquidity", + type: "u64", + index: false, + }, + { + name: "minBaseFutarchicLiquidity", + type: "u64", + index: false, + }, + ], + }, + { + name: "InitializeProposalEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "proposal", + type: "publicKey", + index: false, + }, + { + name: "dao", + type: "publicKey", + index: false, + }, + { + name: "question", + type: "publicKey", + index: false, + }, + { + name: "quoteVault", + type: "publicKey", + index: false, + }, + { + name: "baseVault", + type: "publicKey", + index: false, + }, + { + name: "passAmm", + type: "publicKey", + index: false, + }, + { + name: "failAmm", + type: "publicKey", + index: false, + }, + { + name: "passLpMint", + type: "publicKey", + index: false, + }, + { + name: "failLpMint", + type: "publicKey", + index: false, + }, + { + name: "proposer", + type: "publicKey", + index: false, + }, + { + name: "nonce", + type: "u64", + index: false, + }, + { + name: "number", + type: "u32", + index: false, + }, + { + name: "passLpTokensLocked", + type: "u64", + index: false, + }, + { + name: "failLpTokensLocked", + type: "u64", + index: false, + }, + { + name: "pdaBump", + type: "u8", + index: false, + }, + { + name: "instruction", + type: { + defined: "ProposalInstruction", + }, + index: false, + }, + { + name: "durationInSlots", + type: "u64", + index: false, + }, + ], + }, + { + name: "FinalizeProposalEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "proposal", + type: "publicKey", + index: false, + }, + { + name: "dao", + type: "publicKey", + index: false, + }, + { + name: "passMarketTwap", + type: "u128", + index: false, + }, + { + name: "failMarketTwap", + type: "u128", + index: false, + }, + { + name: "threshold", + type: "u128", + index: false, + }, + { + name: "state", + type: { + defined: "ProposalState", + }, + index: false, + }, + ], + }, + { + name: "ExecuteProposalEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "proposal", + type: "publicKey", + index: false, + }, + { + name: "dao", + type: "publicKey", + index: false, + }, + ], + }, + ], + errors: [ + { + code: 6000, + name: "AmmTooOld", + msg: "Amms must have been created within 5 minutes (counted in slots) of proposal initialization", + }, + { + code: 6001, + name: "InvalidInitialObservation", + msg: "An amm has an `initial_observation` that doesn't match the `dao`'s config", + }, + { + code: 6002, + name: "InvalidMaxObservationChange", + msg: "An amm has a `max_observation_change_per_update` that doesn't match the `dao`'s config", + }, + { + code: 6003, + name: "InvalidStartDelaySlots", + msg: "An amm has a `start_delay_slots` that doesn't match the `dao`'s config", + }, + { + code: 6004, + name: "InvalidSettlementAuthority", + msg: "One of the vaults has an invalid `settlement_authority`", + }, + { + code: 6005, + name: "ProposalTooYoung", + msg: "Proposal is too young to be executed or rejected", + }, + { + code: 6006, + name: "MarketsTooYoung", + msg: "Markets too young for proposal to be finalized. TWAP might need to be cranked", + }, + { + code: 6007, + name: "ProposalAlreadyFinalized", + msg: "This proposal has already been finalized", + }, + { + code: 6008, + name: "InvalidVaultNonce", + msg: "A conditional vault has an invalid nonce. A nonce should encode the proposal number", + }, + { + code: 6009, + name: "ProposalNotPassed", + msg: "This proposal can't be executed because it isn't in the passed state", + }, + { + code: 6010, + name: "InsufficientLpTokenBalance", + msg: "The proposer has fewer pass or fail LP tokens than they requested to lock", + }, + { + code: 6011, + name: "InsufficientLpTokenLock", + msg: "The LP tokens passed in have less liquidity than the DAO's `min_quote_futarchic_liquidity` or `min_base_futachic_liquidity`", + }, + { + code: 6012, + name: "ProposalDurationTooShort", + msg: "Proposal duration must be longer than TWAP start delay", + }, + { + code: 6013, + name: "QuestionMustBeBinary", + msg: "Question must have exactly 2 outcomes for binary futarchy", + }, + ], +}; diff --git a/sdk/src/v0.5/types/autocrat_migrator.ts b/sdk/src/v0.5/types/autocrat_migrator.ts new file mode 100644 index 000000000..05f5d3fca --- /dev/null +++ b/sdk/src/v0.5/types/autocrat_migrator.ts @@ -0,0 +1,237 @@ +export type AutocratMigrator = { + version: "0.1.0"; + name: "autocrat_migrator"; + instructions: [ + { + name: "multiTransfer2"; + accounts: [ + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "authority"; + isMut: true; + isSigner: true; + }, + { + name: "from0"; + isMut: true; + isSigner: false; + }, + { + name: "to0"; + isMut: true; + isSigner: false; + }, + { + name: "from1"; + isMut: true; + isSigner: false; + }, + { + name: "to1"; + isMut: true; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "lamportReceiver"; + isMut: true; + isSigner: false; + } + ]; + args: []; + }, + { + name: "multiTransfer4"; + accounts: [ + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "authority"; + isMut: true; + isSigner: true; + }, + { + name: "from0"; + isMut: true; + isSigner: false; + }, + { + name: "to0"; + isMut: true; + isSigner: false; + }, + { + name: "from1"; + isMut: true; + isSigner: false; + }, + { + name: "to1"; + isMut: true; + isSigner: false; + }, + { + name: "from2"; + isMut: true; + isSigner: false; + }, + { + name: "to2"; + isMut: true; + isSigner: false; + }, + { + name: "from3"; + isMut: true; + isSigner: false; + }, + { + name: "to3"; + isMut: true; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "lamportReceiver"; + isMut: true; + isSigner: false; + } + ]; + args: []; + } + ]; +}; + +export const IDL: AutocratMigrator = { + version: "0.1.0", + name: "autocrat_migrator", + instructions: [ + { + name: "multiTransfer2", + accounts: [ + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "authority", + isMut: true, + isSigner: true, + }, + { + name: "from0", + isMut: true, + isSigner: false, + }, + { + name: "to0", + isMut: true, + isSigner: false, + }, + { + name: "from1", + isMut: true, + isSigner: false, + }, + { + name: "to1", + isMut: true, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "lamportReceiver", + isMut: true, + isSigner: false, + }, + ], + args: [], + }, + { + name: "multiTransfer4", + accounts: [ + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "authority", + isMut: true, + isSigner: true, + }, + { + name: "from0", + isMut: true, + isSigner: false, + }, + { + name: "to0", + isMut: true, + isSigner: false, + }, + { + name: "from1", + isMut: true, + isSigner: false, + }, + { + name: "to1", + isMut: true, + isSigner: false, + }, + { + name: "from2", + isMut: true, + isSigner: false, + }, + { + name: "to2", + isMut: true, + isSigner: false, + }, + { + name: "from3", + isMut: true, + isSigner: false, + }, + { + name: "to3", + isMut: true, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "lamportReceiver", + isMut: true, + isSigner: false, + }, + ], + args: [], + }, + ], +}; diff --git a/sdk/src/v0.5/types/conditional_vault.ts b/sdk/src/v0.5/types/conditional_vault.ts new file mode 100644 index 000000000..fd83c4bf3 --- /dev/null +++ b/sdk/src/v0.5/types/conditional_vault.ts @@ -0,0 +1,1849 @@ +export type ConditionalVault = { + version: "0.4.0"; + name: "conditional_vault"; + instructions: [ + { + name: "initializeQuestion"; + accounts: [ + { + name: "question"; + isMut: true; + isSigner: false; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "InitializeQuestionArgs"; + }; + } + ]; + }, + { + name: "resolveQuestion"; + accounts: [ + { + name: "question"; + isMut: true; + isSigner: false; + }, + { + name: "oracle"; + isMut: false; + isSigner: true; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "ResolveQuestionArgs"; + }; + } + ]; + }, + { + name: "initializeConditionalVault"; + accounts: [ + { + name: "vault"; + isMut: true; + isSigner: false; + }, + { + name: "question"; + isMut: false; + isSigner: false; + }, + { + name: "underlyingTokenMint"; + isMut: false; + isSigner: false; + }, + { + name: "vaultUnderlyingTokenAccount"; + isMut: false; + isSigner: false; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: []; + }, + { + name: "splitTokens"; + accounts: [ + { + name: "question"; + isMut: false; + isSigner: false; + }, + { + name: "vault"; + isMut: true; + isSigner: false; + }, + { + name: "vaultUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "authority"; + isMut: false; + isSigner: true; + }, + { + name: "userUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "amount"; + type: "u64"; + } + ]; + }, + { + name: "mergeTokens"; + accounts: [ + { + name: "question"; + isMut: false; + isSigner: false; + }, + { + name: "vault"; + isMut: true; + isSigner: false; + }, + { + name: "vaultUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "authority"; + isMut: false; + isSigner: true; + }, + { + name: "userUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "amount"; + type: "u64"; + } + ]; + }, + { + name: "redeemTokens"; + accounts: [ + { + name: "question"; + isMut: false; + isSigner: false; + }, + { + name: "vault"; + isMut: true; + isSigner: false; + }, + { + name: "vaultUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "authority"; + isMut: false; + isSigner: true; + }, + { + name: "userUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: []; + }, + { + name: "addMetadataToConditionalTokens"; + accounts: [ + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "vault"; + isMut: true; + isSigner: false; + }, + { + name: "conditionalTokenMint"; + isMut: true; + isSigner: false; + }, + { + name: "conditionalTokenMetadata"; + isMut: true; + isSigner: false; + }, + { + name: "tokenMetadataProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "rent"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "AddMetadataToConditionalTokensArgs"; + }; + } + ]; + } + ]; + accounts: [ + { + name: "conditionalVault"; + type: { + kind: "struct"; + fields: [ + { + name: "question"; + type: "publicKey"; + }, + { + name: "underlyingTokenMint"; + type: "publicKey"; + }, + { + name: "underlyingTokenAccount"; + type: "publicKey"; + }, + { + name: "conditionalTokenMints"; + type: { + vec: "publicKey"; + }; + }, + { + name: "pdaBump"; + type: "u8"; + }, + { + name: "decimals"; + type: "u8"; + }, + { + name: "seqNum"; + type: "u64"; + } + ]; + }; + }, + { + name: "question"; + docs: [ + "Questions represent statements about future events.", + "", + "These statements include:", + '- "Will this proposal pass?"', + '- "Who, if anyone, will be hired?"', + '- "How effective will the grant committee deem this grant?"', + "", + 'Questions have 2 or more possible outcomes. For a question like "will this', + 'proposal pass," the outcomes are "yes" and "no." For a question like "who', + 'will be hired," the outcomes could be "Alice," "Bob," and "neither."', + "", + 'Outcomes resolve to a number between 0 and 1. Binary questions like "will', + 'this proposal pass" have outcomes that resolve to exactly 0 or 1. You can', + 'also have questions with scalar outcomes. For example, the question "how', + 'effective will the grant committee deem this grant" could have two outcomes:', + '"ineffective" and "effective." If the grant committee deems the grant 70%', + 'effective, the "effective" outcome would resolve to 0.7 and the "ineffective"', + "outcome would resolve to 0.3.", + "", + "Once resolved, the sum of all outcome resolutions is exactly 1." + ]; + type: { + kind: "struct"; + fields: [ + { + name: "questionId"; + type: { + array: ["u8", 32]; + }; + }, + { + name: "oracle"; + type: "publicKey"; + }, + { + name: "payoutNumerators"; + type: { + vec: "u32"; + }; + }, + { + name: "payoutDenominator"; + type: "u32"; + } + ]; + }; + } + ]; + types: [ + { + name: "CommonFields"; + type: { + kind: "struct"; + fields: [ + { + name: "slot"; + type: "u64"; + }, + { + name: "unixTimestamp"; + type: "i64"; + } + ]; + }; + }, + { + name: "AddMetadataToConditionalTokensArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "name"; + type: "string"; + }, + { + name: "symbol"; + type: "string"; + }, + { + name: "uri"; + type: "string"; + } + ]; + }; + }, + { + name: "InitializeQuestionArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "questionId"; + type: { + array: ["u8", 32]; + }; + }, + { + name: "oracle"; + type: "publicKey"; + }, + { + name: "numOutcomes"; + type: "u8"; + } + ]; + }; + }, + { + name: "ResolveQuestionArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "payoutNumerators"; + type: { + vec: "u32"; + }; + } + ]; + }; + }, + { + name: "VaultStatus"; + type: { + kind: "enum"; + variants: [ + { + name: "Active"; + }, + { + name: "Finalized"; + }, + { + name: "Reverted"; + } + ]; + }; + } + ]; + events: [ + { + name: "AddMetadataToConditionalTokensEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "vault"; + type: "publicKey"; + index: false; + }, + { + name: "conditionalTokenMint"; + type: "publicKey"; + index: false; + }, + { + name: "conditionalTokenMetadata"; + type: "publicKey"; + index: false; + }, + { + name: "name"; + type: "string"; + index: false; + }, + { + name: "symbol"; + type: "string"; + index: false; + }, + { + name: "uri"; + type: "string"; + index: false; + }, + { + name: "seqNum"; + type: "u64"; + index: false; + } + ]; + }, + { + name: "InitializeConditionalVaultEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "vault"; + type: "publicKey"; + index: false; + }, + { + name: "question"; + type: "publicKey"; + index: false; + }, + { + name: "underlyingTokenMint"; + type: "publicKey"; + index: false; + }, + { + name: "vaultUnderlyingTokenAccount"; + type: "publicKey"; + index: false; + }, + { + name: "conditionalTokenMints"; + type: { + vec: "publicKey"; + }; + index: false; + }, + { + name: "pdaBump"; + type: "u8"; + index: false; + }, + { + name: "seqNum"; + type: "u64"; + index: false; + } + ]; + }, + { + name: "InitializeQuestionEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "questionId"; + type: { + array: ["u8", 32]; + }; + index: false; + }, + { + name: "oracle"; + type: "publicKey"; + index: false; + }, + { + name: "numOutcomes"; + type: "u8"; + index: false; + }, + { + name: "question"; + type: "publicKey"; + index: false; + } + ]; + }, + { + name: "MergeTokensEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "user"; + type: "publicKey"; + index: false; + }, + { + name: "vault"; + type: "publicKey"; + index: false; + }, + { + name: "amount"; + type: "u64"; + index: false; + }, + { + name: "postUserUnderlyingBalance"; + type: "u64"; + index: false; + }, + { + name: "postVaultUnderlyingBalance"; + type: "u64"; + index: false; + }, + { + name: "postUserConditionalTokenBalances"; + type: { + vec: "u64"; + }; + index: false; + }, + { + name: "postConditionalTokenSupplies"; + type: { + vec: "u64"; + }; + index: false; + }, + { + name: "seqNum"; + type: "u64"; + index: false; + } + ]; + }, + { + name: "RedeemTokensEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "user"; + type: "publicKey"; + index: false; + }, + { + name: "vault"; + type: "publicKey"; + index: false; + }, + { + name: "amount"; + type: "u64"; + index: false; + }, + { + name: "postUserUnderlyingBalance"; + type: "u64"; + index: false; + }, + { + name: "postVaultUnderlyingBalance"; + type: "u64"; + index: false; + }, + { + name: "postConditionalTokenSupplies"; + type: { + vec: "u64"; + }; + index: false; + }, + { + name: "seqNum"; + type: "u64"; + index: false; + } + ]; + }, + { + name: "ResolveQuestionEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "question"; + type: "publicKey"; + index: false; + }, + { + name: "payoutNumerators"; + type: { + vec: "u32"; + }; + index: false; + } + ]; + }, + { + name: "SplitTokensEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "user"; + type: "publicKey"; + index: false; + }, + { + name: "vault"; + type: "publicKey"; + index: false; + }, + { + name: "amount"; + type: "u64"; + index: false; + }, + { + name: "postUserUnderlyingBalance"; + type: "u64"; + index: false; + }, + { + name: "postVaultUnderlyingBalance"; + type: "u64"; + index: false; + }, + { + name: "postUserConditionalTokenBalances"; + type: { + vec: "u64"; + }; + index: false; + }, + { + name: "postConditionalTokenSupplies"; + type: { + vec: "u64"; + }; + index: false; + }, + { + name: "seqNum"; + type: "u64"; + index: false; + } + ]; + } + ]; + errors: [ + { + code: 6000; + name: "AssertFailed"; + msg: "An assertion failed"; + }, + { + code: 6001; + name: "InsufficientUnderlyingTokens"; + msg: "Insufficient underlying token balance to mint this amount of conditional tokens"; + }, + { + code: 6002; + name: "InsufficientConditionalTokens"; + msg: "Insufficient conditional token balance to merge this `amount`"; + }, + { + code: 6003; + name: "InvalidVaultUnderlyingTokenAccount"; + msg: "This `vault_underlying_token_account` is not this vault's `underlying_token_account`"; + }, + { + code: 6004; + name: "InvalidConditionalTokenMint"; + msg: "This conditional token mint is not this vault's conditional token mint"; + }, + { + code: 6005; + name: "CantRedeemConditionalTokens"; + msg: "Question needs to be resolved before users can redeem conditional tokens for underlying tokens"; + }, + { + code: 6006; + name: "InsufficientNumConditions"; + msg: "Questions need 2 or more conditions"; + }, + { + code: 6007; + name: "InvalidNumPayoutNumerators"; + msg: "Invalid number of payout numerators"; + }, + { + code: 6008; + name: "InvalidConditionals"; + msg: "Client needs to pass in the list of conditional mints for a vault followed by the user's token accounts for those tokens"; + }, + { + code: 6009; + name: "ConditionalMintMismatch"; + msg: "Conditional mint not in vault"; + }, + { + code: 6010; + name: "BadConditionalMint"; + msg: "Unable to deserialize a conditional token mint"; + }, + { + code: 6011; + name: "BadConditionalTokenAccount"; + msg: "Unable to deserialize a conditional token account"; + }, + { + code: 6012; + name: "ConditionalTokenMintMismatch"; + msg: "User conditional token account mint does not match conditional mint"; + }, + { + code: 6013; + name: "PayoutZero"; + msg: "Payouts must sum to 1 or more"; + }, + { + code: 6014; + name: "QuestionAlreadyResolved"; + msg: "Question already resolved"; + }, + { + code: 6015; + name: "ConditionalTokenMetadataAlreadySet"; + msg: "Conditional token metadata already set"; + }, + { + code: 6016; + name: "UnauthorizedConditionalTokenAccount"; + msg: "Conditional token account is not owned by the authority"; + } + ]; +}; + +export const IDL: ConditionalVault = { + version: "0.4.0", + name: "conditional_vault", + instructions: [ + { + name: "initializeQuestion", + accounts: [ + { + name: "question", + isMut: true, + isSigner: false, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "InitializeQuestionArgs", + }, + }, + ], + }, + { + name: "resolveQuestion", + accounts: [ + { + name: "question", + isMut: true, + isSigner: false, + }, + { + name: "oracle", + isMut: false, + isSigner: true, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "ResolveQuestionArgs", + }, + }, + ], + }, + { + name: "initializeConditionalVault", + accounts: [ + { + name: "vault", + isMut: true, + isSigner: false, + }, + { + name: "question", + isMut: false, + isSigner: false, + }, + { + name: "underlyingTokenMint", + isMut: false, + isSigner: false, + }, + { + name: "vaultUnderlyingTokenAccount", + isMut: false, + isSigner: false, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: "splitTokens", + accounts: [ + { + name: "question", + isMut: false, + isSigner: false, + }, + { + name: "vault", + isMut: true, + isSigner: false, + }, + { + name: "vaultUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "authority", + isMut: false, + isSigner: true, + }, + { + name: "userUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "amount", + type: "u64", + }, + ], + }, + { + name: "mergeTokens", + accounts: [ + { + name: "question", + isMut: false, + isSigner: false, + }, + { + name: "vault", + isMut: true, + isSigner: false, + }, + { + name: "vaultUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "authority", + isMut: false, + isSigner: true, + }, + { + name: "userUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "amount", + type: "u64", + }, + ], + }, + { + name: "redeemTokens", + accounts: [ + { + name: "question", + isMut: false, + isSigner: false, + }, + { + name: "vault", + isMut: true, + isSigner: false, + }, + { + name: "vaultUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "authority", + isMut: false, + isSigner: true, + }, + { + name: "userUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: "addMetadataToConditionalTokens", + accounts: [ + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "vault", + isMut: true, + isSigner: false, + }, + { + name: "conditionalTokenMint", + isMut: true, + isSigner: false, + }, + { + name: "conditionalTokenMetadata", + isMut: true, + isSigner: false, + }, + { + name: "tokenMetadataProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "rent", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "AddMetadataToConditionalTokensArgs", + }, + }, + ], + }, + ], + accounts: [ + { + name: "conditionalVault", + type: { + kind: "struct", + fields: [ + { + name: "question", + type: "publicKey", + }, + { + name: "underlyingTokenMint", + type: "publicKey", + }, + { + name: "underlyingTokenAccount", + type: "publicKey", + }, + { + name: "conditionalTokenMints", + type: { + vec: "publicKey", + }, + }, + { + name: "pdaBump", + type: "u8", + }, + { + name: "decimals", + type: "u8", + }, + { + name: "seqNum", + type: "u64", + }, + ], + }, + }, + { + name: "question", + docs: [ + "Questions represent statements about future events.", + "", + "These statements include:", + '- "Will this proposal pass?"', + '- "Who, if anyone, will be hired?"', + '- "How effective will the grant committee deem this grant?"', + "", + 'Questions have 2 or more possible outcomes. For a question like "will this', + 'proposal pass," the outcomes are "yes" and "no." For a question like "who', + 'will be hired," the outcomes could be "Alice," "Bob," and "neither."', + "", + 'Outcomes resolve to a number between 0 and 1. Binary questions like "will', + 'this proposal pass" have outcomes that resolve to exactly 0 or 1. You can', + 'also have questions with scalar outcomes. For example, the question "how', + 'effective will the grant committee deem this grant" could have two outcomes:', + '"ineffective" and "effective." If the grant committee deems the grant 70%', + 'effective, the "effective" outcome would resolve to 0.7 and the "ineffective"', + "outcome would resolve to 0.3.", + "", + "Once resolved, the sum of all outcome resolutions is exactly 1.", + ], + type: { + kind: "struct", + fields: [ + { + name: "questionId", + type: { + array: ["u8", 32], + }, + }, + { + name: "oracle", + type: "publicKey", + }, + { + name: "payoutNumerators", + type: { + vec: "u32", + }, + }, + { + name: "payoutDenominator", + type: "u32", + }, + ], + }, + }, + ], + types: [ + { + name: "CommonFields", + type: { + kind: "struct", + fields: [ + { + name: "slot", + type: "u64", + }, + { + name: "unixTimestamp", + type: "i64", + }, + ], + }, + }, + { + name: "AddMetadataToConditionalTokensArgs", + type: { + kind: "struct", + fields: [ + { + name: "name", + type: "string", + }, + { + name: "symbol", + type: "string", + }, + { + name: "uri", + type: "string", + }, + ], + }, + }, + { + name: "InitializeQuestionArgs", + type: { + kind: "struct", + fields: [ + { + name: "questionId", + type: { + array: ["u8", 32], + }, + }, + { + name: "oracle", + type: "publicKey", + }, + { + name: "numOutcomes", + type: "u8", + }, + ], + }, + }, + { + name: "ResolveQuestionArgs", + type: { + kind: "struct", + fields: [ + { + name: "payoutNumerators", + type: { + vec: "u32", + }, + }, + ], + }, + }, + { + name: "VaultStatus", + type: { + kind: "enum", + variants: [ + { + name: "Active", + }, + { + name: "Finalized", + }, + { + name: "Reverted", + }, + ], + }, + }, + ], + events: [ + { + name: "AddMetadataToConditionalTokensEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "vault", + type: "publicKey", + index: false, + }, + { + name: "conditionalTokenMint", + type: "publicKey", + index: false, + }, + { + name: "conditionalTokenMetadata", + type: "publicKey", + index: false, + }, + { + name: "name", + type: "string", + index: false, + }, + { + name: "symbol", + type: "string", + index: false, + }, + { + name: "uri", + type: "string", + index: false, + }, + { + name: "seqNum", + type: "u64", + index: false, + }, + ], + }, + { + name: "InitializeConditionalVaultEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "vault", + type: "publicKey", + index: false, + }, + { + name: "question", + type: "publicKey", + index: false, + }, + { + name: "underlyingTokenMint", + type: "publicKey", + index: false, + }, + { + name: "vaultUnderlyingTokenAccount", + type: "publicKey", + index: false, + }, + { + name: "conditionalTokenMints", + type: { + vec: "publicKey", + }, + index: false, + }, + { + name: "pdaBump", + type: "u8", + index: false, + }, + { + name: "seqNum", + type: "u64", + index: false, + }, + ], + }, + { + name: "InitializeQuestionEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "questionId", + type: { + array: ["u8", 32], + }, + index: false, + }, + { + name: "oracle", + type: "publicKey", + index: false, + }, + { + name: "numOutcomes", + type: "u8", + index: false, + }, + { + name: "question", + type: "publicKey", + index: false, + }, + ], + }, + { + name: "MergeTokensEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "user", + type: "publicKey", + index: false, + }, + { + name: "vault", + type: "publicKey", + index: false, + }, + { + name: "amount", + type: "u64", + index: false, + }, + { + name: "postUserUnderlyingBalance", + type: "u64", + index: false, + }, + { + name: "postVaultUnderlyingBalance", + type: "u64", + index: false, + }, + { + name: "postUserConditionalTokenBalances", + type: { + vec: "u64", + }, + index: false, + }, + { + name: "postConditionalTokenSupplies", + type: { + vec: "u64", + }, + index: false, + }, + { + name: "seqNum", + type: "u64", + index: false, + }, + ], + }, + { + name: "RedeemTokensEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "user", + type: "publicKey", + index: false, + }, + { + name: "vault", + type: "publicKey", + index: false, + }, + { + name: "amount", + type: "u64", + index: false, + }, + { + name: "postUserUnderlyingBalance", + type: "u64", + index: false, + }, + { + name: "postVaultUnderlyingBalance", + type: "u64", + index: false, + }, + { + name: "postConditionalTokenSupplies", + type: { + vec: "u64", + }, + index: false, + }, + { + name: "seqNum", + type: "u64", + index: false, + }, + ], + }, + { + name: "ResolveQuestionEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "question", + type: "publicKey", + index: false, + }, + { + name: "payoutNumerators", + type: { + vec: "u32", + }, + index: false, + }, + ], + }, + { + name: "SplitTokensEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "user", + type: "publicKey", + index: false, + }, + { + name: "vault", + type: "publicKey", + index: false, + }, + { + name: "amount", + type: "u64", + index: false, + }, + { + name: "postUserUnderlyingBalance", + type: "u64", + index: false, + }, + { + name: "postVaultUnderlyingBalance", + type: "u64", + index: false, + }, + { + name: "postUserConditionalTokenBalances", + type: { + vec: "u64", + }, + index: false, + }, + { + name: "postConditionalTokenSupplies", + type: { + vec: "u64", + }, + index: false, + }, + { + name: "seqNum", + type: "u64", + index: false, + }, + ], + }, + ], + errors: [ + { + code: 6000, + name: "AssertFailed", + msg: "An assertion failed", + }, + { + code: 6001, + name: "InsufficientUnderlyingTokens", + msg: "Insufficient underlying token balance to mint this amount of conditional tokens", + }, + { + code: 6002, + name: "InsufficientConditionalTokens", + msg: "Insufficient conditional token balance to merge this `amount`", + }, + { + code: 6003, + name: "InvalidVaultUnderlyingTokenAccount", + msg: "This `vault_underlying_token_account` is not this vault's `underlying_token_account`", + }, + { + code: 6004, + name: "InvalidConditionalTokenMint", + msg: "This conditional token mint is not this vault's conditional token mint", + }, + { + code: 6005, + name: "CantRedeemConditionalTokens", + msg: "Question needs to be resolved before users can redeem conditional tokens for underlying tokens", + }, + { + code: 6006, + name: "InsufficientNumConditions", + msg: "Questions need 2 or more conditions", + }, + { + code: 6007, + name: "InvalidNumPayoutNumerators", + msg: "Invalid number of payout numerators", + }, + { + code: 6008, + name: "InvalidConditionals", + msg: "Client needs to pass in the list of conditional mints for a vault followed by the user's token accounts for those tokens", + }, + { + code: 6009, + name: "ConditionalMintMismatch", + msg: "Conditional mint not in vault", + }, + { + code: 6010, + name: "BadConditionalMint", + msg: "Unable to deserialize a conditional token mint", + }, + { + code: 6011, + name: "BadConditionalTokenAccount", + msg: "Unable to deserialize a conditional token account", + }, + { + code: 6012, + name: "ConditionalTokenMintMismatch", + msg: "User conditional token account mint does not match conditional mint", + }, + { + code: 6013, + name: "PayoutZero", + msg: "Payouts must sum to 1 or more", + }, + { + code: 6014, + name: "QuestionAlreadyResolved", + msg: "Question already resolved", + }, + { + code: 6015, + name: "ConditionalTokenMetadataAlreadySet", + msg: "Conditional token metadata already set", + }, + { + code: 6016, + name: "UnauthorizedConditionalTokenAccount", + msg: "Conditional token account is not owned by the authority", + }, + ], +}; diff --git a/sdk/src/v0.4/types/futarchy_amm.ts b/sdk/src/v0.5/types/futarchy_amm.ts similarity index 100% rename from sdk/src/v0.4/types/futarchy_amm.ts rename to sdk/src/v0.5/types/futarchy_amm.ts diff --git a/sdk/src/v0.5/types/index.ts b/sdk/src/v0.5/types/index.ts new file mode 100644 index 000000000..d8696f80d --- /dev/null +++ b/sdk/src/v0.5/types/index.ts @@ -0,0 +1,119 @@ +import { Autocrat as AutocratProgram, IDL as AutocratIDL } from "./autocrat.js"; +export { AutocratProgram, AutocratIDL }; + +import { Amm as AmmProgram, IDL as AmmIDL } from "./amm.js"; +export { AmmProgram, AmmIDL }; + +import { + Launchpad as LaunchpadProgram, + IDL as LaunchpadIDL, +} from "./launchpad.js"; +export { LaunchpadProgram, LaunchpadIDL }; + +import { + ConditionalVault as ConditionalVaultProgram, + IDL as ConditionalVaultIDL, +} from "./conditional_vault.js"; +export { ConditionalVaultProgram, ConditionalVaultIDL }; + +import { + SharedLiquidityManager as SharedLiquidityManagerProgram, + IDL as SharedLiquidityManagerIDL, +} from "./shared_liquidity_manager.js"; +export { SharedLiquidityManagerProgram, SharedLiquidityManagerIDL }; + +export { LowercaseKeys } from "./utils.js"; + +import type { IdlAccounts, IdlTypes, IdlEvents } from "@coral-xyz/anchor"; +import { PublicKey } from "@solana/web3.js"; + +export type Question = IdlAccounts["question"]; +export type ConditionalVault = + IdlAccounts["conditionalVault"]; + +export type InitializeDaoParams = + IdlTypes["InitializeDaoParams"]; +export type UpdateDaoParams = IdlTypes["UpdateDaoParams"]; +export type ProposalInstruction = + IdlTypes["ProposalInstruction"]; + +export type Dao = IdlAccounts["dao"]; +export type Proposal = IdlAccounts["proposal"]; +export type Amm = IdlAccounts["amm"]; +export type Launch = IdlAccounts["launch"]; +export type FundingRecord = IdlAccounts["fundingRecord"]; +export type SharedLiquidityPool = + IdlAccounts["sharedLiquidityPool"]; +export type SharedLiquidityPoolPosition = + IdlAccounts["liquidityPosition"]; + +export type SwapEvent = IdlEvents["SwapEvent"]; +export type AddLiquidityEvent = IdlEvents["AddLiquidityEvent"]; +export type RemoveLiquidityEvent = + IdlEvents["RemoveLiquidityEvent"]; +export type CreateAmmEvent = IdlEvents["CreateAmmEvent"]; +export type CrankThatTwapEvent = IdlEvents["CrankThatTwapEvent"]; +export type AmmEvent = + | SwapEvent + | AddLiquidityEvent + | RemoveLiquidityEvent + | CreateAmmEvent + | CrankThatTwapEvent; + +export type AddMetadataToConditionalTokensEvent = + IdlEvents["AddMetadataToConditionalTokensEvent"]; +export type InitializeConditionalVaultEvent = + IdlEvents["InitializeConditionalVaultEvent"]; +export type InitializeQuestionEvent = + IdlEvents["InitializeQuestionEvent"]; +export type MergeTokensEvent = + IdlEvents["MergeTokensEvent"]; +export type RedeemTokensEvent = + IdlEvents["RedeemTokensEvent"]; +export type ResolveQuestionEvent = + IdlEvents["ResolveQuestionEvent"]; +export type SplitTokensEvent = + IdlEvents["SplitTokensEvent"]; +export type ConditionalVaultEvent = + | AddMetadataToConditionalTokensEvent + | InitializeConditionalVaultEvent + | InitializeQuestionEvent + | MergeTokensEvent + | RedeemTokensEvent + | ResolveQuestionEvent + | SplitTokensEvent; + +export type LaunchClaimEvent = IdlEvents["LaunchClaimEvent"]; +export type LaunchCompletedEvent = + IdlEvents["LaunchCompletedEvent"]; +export type LaunchFundedEvent = + IdlEvents["LaunchFundedEvent"]; +export type LaunchInitializedEvent = + IdlEvents["LaunchInitializedEvent"]; +export type LaunchRefundedEvent = + IdlEvents["LaunchRefundedEvent"]; +export type LaunchStartedEvent = + IdlEvents["LaunchStartedEvent"]; +export type LaunchpadEvent = + | LaunchClaimEvent + | LaunchCompletedEvent + | LaunchFundedEvent + | LaunchInitializedEvent + | LaunchRefundedEvent + | LaunchStartedEvent; + +export type InitializeDaoEvent = + IdlEvents["InitializeDaoEvent"]; +export type UpdateDaoEvent = IdlEvents["UpdateDaoEvent"]; +export type InitializeProposalEvent = + IdlEvents["InitializeProposalEvent"]; +export type FinalizeProposalEvent = + IdlEvents["FinalizeProposalEvent"]; +export type ExecuteProposalEvent = + IdlEvents["ExecuteProposalEvent"]; +export type AutocratEvent = + | InitializeDaoEvent + | UpdateDaoEvent + | InitializeProposalEvent + | FinalizeProposalEvent + | ExecuteProposalEvent; diff --git a/sdk/src/v0.5/types/launchpad.ts b/sdk/src/v0.5/types/launchpad.ts new file mode 100644 index 000000000..3a2aa4f17 --- /dev/null +++ b/sdk/src/v0.5/types/launchpad.ts @@ -0,0 +1,1999 @@ +export type Launchpad = { + version: "0.4.1"; + name: "launchpad"; + instructions: [ + { + name: "initializeLaunch"; + accounts: [ + { + name: "launch"; + isMut: true; + isSigner: false; + }, + { + name: "tokenMint"; + isMut: true; + isSigner: false; + }, + { + name: "tokenMetadata"; + isMut: true; + isSigner: false; + }, + { + name: "launchSigner"; + isMut: false; + isSigner: false; + }, + { + name: "usdcVault"; + isMut: true; + isSigner: false; + }, + { + name: "tokenVault"; + isMut: true; + isSigner: false; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "launchAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "usdcMint"; + isMut: false; + isSigner: false; + }, + { + name: "rent"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenMetadataProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "args"; + type: { + defined: "InitializeLaunchArgs"; + }; + } + ]; + }, + { + name: "startLaunch"; + accounts: [ + { + name: "launch"; + isMut: true; + isSigner: false; + }, + { + name: "launchAuthority"; + isMut: false; + isSigner: true; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: []; + }, + { + name: "fund"; + accounts: [ + { + name: "launch"; + isMut: true; + isSigner: false; + }, + { + name: "fundingRecord"; + isMut: true; + isSigner: false; + }, + { + name: "launchSigner"; + isMut: false; + isSigner: false; + }, + { + name: "launchUsdcVault"; + isMut: true; + isSigner: false; + }, + { + name: "funder"; + isMut: false; + isSigner: true; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "funderUsdcAccount"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "amount"; + type: "u64"; + } + ]; + }, + { + name: "completeLaunch"; + accounts: [ + { + name: "launch"; + isMut: true; + isSigner: false; + }, + { + name: "tokenMetadata"; + isMut: true; + isSigner: false; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "launchSigner"; + isMut: true; + isSigner: false; + }, + { + name: "authority"; + isMut: false; + isSigner: false; + }, + { + name: "launchUsdcVault"; + isMut: true; + isSigner: false; + }, + { + name: "launchTokenVault"; + isMut: true; + isSigner: false; + }, + { + name: "treasuryUsdcAccount"; + isMut: true; + isSigner: false; + }, + { + name: "treasuryLpAccount"; + isMut: true; + isSigner: false; + }, + { + name: "ammConfig"; + isMut: true; + isSigner: false; + docs: [ + "Use the lowest fee pool, can see fees at https://api-v3.raydium.io/main/cpmm-config" + ]; + }, + { + name: "poolState"; + isMut: true; + isSigner: false; + }, + { + name: "tokenMint"; + isMut: true; + isSigner: false; + }, + { + name: "usdcMint"; + isMut: false; + isSigner: false; + }, + { + name: "lpMint"; + isMut: true; + isSigner: false; + }, + { + name: "lpVault"; + isMut: true; + isSigner: false; + }, + { + name: "poolTokenVault"; + isMut: true; + isSigner: false; + }, + { + name: "poolUsdcVault"; + isMut: true; + isSigner: false; + }, + { + name: "createPoolFee"; + isMut: true; + isSigner: false; + docs: ["create pool fee account"]; + }, + { + name: "observationState"; + isMut: true; + isSigner: false; + }, + { + name: "dao"; + isMut: true; + isSigner: false; + }, + { + name: "daoTreasury"; + isMut: false; + isSigner: false; + }, + { + name: "cpSwapProgram"; + isMut: false; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "autocratProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenMetadataProgram"; + isMut: false; + isSigner: false; + }, + { + name: "autocratEventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "rent"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: []; + }, + { + name: "refund"; + accounts: [ + { + name: "launch"; + isMut: true; + isSigner: false; + }, + { + name: "fundingRecord"; + isMut: true; + isSigner: false; + }, + { + name: "launchUsdcVault"; + isMut: true; + isSigner: false; + }, + { + name: "launchSigner"; + isMut: false; + isSigner: false; + }, + { + name: "funder"; + isMut: true; + isSigner: true; + }, + { + name: "funderUsdcAccount"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: []; + }, + { + name: "claim"; + accounts: [ + { + name: "launch"; + isMut: true; + isSigner: false; + }, + { + name: "fundingRecord"; + isMut: true; + isSigner: false; + }, + { + name: "launchSigner"; + isMut: false; + isSigner: false; + }, + { + name: "tokenMint"; + isMut: true; + isSigner: false; + }, + { + name: "launchTokenVault"; + isMut: true; + isSigner: false; + }, + { + name: "funder"; + isMut: false; + isSigner: false; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "funderTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: []; + } + ]; + accounts: [ + { + name: "fundingRecord"; + type: { + kind: "struct"; + fields: [ + { + name: "pdaBump"; + docs: ["The PDA bump."]; + type: "u8"; + }, + { + name: "funder"; + docs: ["The funder."]; + type: "publicKey"; + }, + { + name: "launch"; + docs: ["The launch."]; + type: "publicKey"; + }, + { + name: "committedAmount"; + docs: ["The amount of USDC that has been committed by the funder."]; + type: "u64"; + }, + { + name: "seqNum"; + docs: [ + "The sequence number of this funding record. Useful for sorting events." + ]; + type: "u64"; + } + ]; + }; + }, + { + name: "launch"; + type: { + kind: "struct"; + fields: [ + { + name: "pdaBump"; + docs: ["The PDA bump."]; + type: "u8"; + }, + { + name: "minimumRaiseAmount"; + docs: [ + "The minimum amount of USDC that must be raised, otherwise", + "everyone can get their USDC back." + ]; + type: "u64"; + }, + { + name: "launchAuthority"; + docs: ["The account that can start the launch."]; + type: "publicKey"; + }, + { + name: "launchSigner"; + docs: [ + "The launch signer address. Needed because Raydium pools need a SOL payer and this PDA can't hold SOL." + ]; + type: "publicKey"; + }, + { + name: "launchSignerPdaBump"; + docs: ["The PDA bump for the launch signer."]; + type: "u8"; + }, + { + name: "launchUsdcVault"; + docs: [ + "The USDC vault that will hold the USDC raised until the launch is over." + ]; + type: "publicKey"; + }, + { + name: "launchTokenVault"; + docs: ["The token vault, used to send tokens to Raydium."]; + type: "publicKey"; + }, + { + name: "tokenMint"; + docs: [ + "The token that will be minted to funders and that will control the DAO." + ]; + type: "publicKey"; + }, + { + name: "usdcMint"; + docs: ["The USDC mint."]; + type: "publicKey"; + }, + { + name: "unixTimestampStarted"; + docs: ["The unix timestamp when the launch was started."]; + type: "i64"; + }, + { + name: "totalCommittedAmount"; + docs: ["The amount of USDC that has been committed by the users."]; + type: "u64"; + }, + { + name: "state"; + docs: ["The state of the launch."]; + type: { + defined: "LaunchState"; + }; + }, + { + name: "seqNum"; + docs: [ + "The sequence number of this launch. Useful for sorting events." + ]; + type: "u64"; + }, + { + name: "secondsForLaunch"; + docs: ["The number of seconds that the launch will be live for."]; + type: "u32"; + }, + { + name: "dao"; + docs: ["The DAO, if the launch is complete."]; + type: { + option: "publicKey"; + }; + }, + { + name: "daoTreasury"; + docs: [ + "The DAO treasury that USDC / LP is sent to, if the launch is complete." + ]; + type: { + option: "publicKey"; + }; + } + ]; + }; + } + ]; + types: [ + { + name: "CommonFields"; + type: { + kind: "struct"; + fields: [ + { + name: "slot"; + type: "u64"; + }, + { + name: "unixTimestamp"; + type: "i64"; + }, + { + name: "launchSeqNum"; + type: "u64"; + } + ]; + }; + }, + { + name: "InitializeLaunchArgs"; + type: { + kind: "struct"; + fields: [ + { + name: "minimumRaiseAmount"; + type: "u64"; + }, + { + name: "secondsForLaunch"; + type: "u32"; + }, + { + name: "tokenName"; + type: "string"; + }, + { + name: "tokenSymbol"; + type: "string"; + }, + { + name: "tokenUri"; + type: "string"; + } + ]; + }; + }, + { + name: "LaunchState"; + type: { + kind: "enum"; + variants: [ + { + name: "Initialized"; + }, + { + name: "Live"; + }, + { + name: "Complete"; + }, + { + name: "Refunding"; + } + ]; + }; + } + ]; + events: [ + { + name: "LaunchInitializedEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "launch"; + type: "publicKey"; + index: false; + }, + { + name: "minimumRaiseAmount"; + type: "u64"; + index: false; + }, + { + name: "launchAuthority"; + type: "publicKey"; + index: false; + }, + { + name: "launchSigner"; + type: "publicKey"; + index: false; + }, + { + name: "launchSignerPdaBump"; + type: "u8"; + index: false; + }, + { + name: "launchUsdcVault"; + type: "publicKey"; + index: false; + }, + { + name: "launchTokenVault"; + type: "publicKey"; + index: false; + }, + { + name: "tokenMint"; + type: "publicKey"; + index: false; + }, + { + name: "usdcMint"; + type: "publicKey"; + index: false; + }, + { + name: "pdaBump"; + type: "u8"; + index: false; + }, + { + name: "secondsForLaunch"; + type: "u32"; + index: false; + } + ]; + }, + { + name: "LaunchStartedEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "launch"; + type: "publicKey"; + index: false; + }, + { + name: "launchAuthority"; + type: "publicKey"; + index: false; + }, + { + name: "slotStarted"; + type: "u64"; + index: false; + } + ]; + }, + { + name: "LaunchFundedEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "fundingRecord"; + type: "publicKey"; + index: false; + }, + { + name: "launch"; + type: "publicKey"; + index: false; + }, + { + name: "funder"; + type: "publicKey"; + index: false; + }, + { + name: "amount"; + type: "u64"; + index: false; + }, + { + name: "totalCommittedByFunder"; + type: "u64"; + index: false; + }, + { + name: "totalCommitted"; + type: "u64"; + index: false; + }, + { + name: "fundingRecordSeqNum"; + type: "u64"; + index: false; + } + ]; + }, + { + name: "LaunchCompletedEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "launch"; + type: "publicKey"; + index: false; + }, + { + name: "finalState"; + type: { + defined: "LaunchState"; + }; + index: false; + }, + { + name: "totalCommitted"; + type: "u64"; + index: false; + }, + { + name: "dao"; + type: { + option: "publicKey"; + }; + index: false; + }, + { + name: "daoTreasury"; + type: { + option: "publicKey"; + }; + index: false; + } + ]; + }, + { + name: "LaunchRefundedEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "launch"; + type: "publicKey"; + index: false; + }, + { + name: "funder"; + type: "publicKey"; + index: false; + }, + { + name: "usdcRefunded"; + type: "u64"; + index: false; + }, + { + name: "fundingRecord"; + type: "publicKey"; + index: false; + } + ]; + }, + { + name: "LaunchClaimEvent"; + fields: [ + { + name: "common"; + type: { + defined: "CommonFields"; + }; + index: false; + }, + { + name: "launch"; + type: "publicKey"; + index: false; + }, + { + name: "funder"; + type: "publicKey"; + index: false; + }, + { + name: "tokensClaimed"; + type: "u64"; + index: false; + }, + { + name: "fundingRecord"; + type: "publicKey"; + index: false; + } + ]; + } + ]; + errors: [ + { + code: 6000; + name: "InvalidAmount"; + msg: "Invalid amount"; + }, + { + code: 6001; + name: "SupplyNonZero"; + msg: "Supply must be zero"; + }, + { + code: 6002; + name: "InvalidSecondsForLaunch"; + msg: "Launch period must be between 1 hour and 2 weeks"; + }, + { + code: 6003; + name: "InsufficientFunds"; + msg: "Insufficient funds"; + }, + { + code: 6004; + name: "InvalidTokenKey"; + msg: "Token mint key must end in 'meta'"; + }, + { + code: 6005; + name: "InvalidLaunchState"; + msg: "Invalid launch state"; + }, + { + code: 6006; + name: "LaunchPeriodNotOver"; + msg: "Launch period not over"; + }, + { + code: 6007; + name: "LaunchExpired"; + msg: "Launch is complete, no more funding allowed"; + }, + { + code: 6008; + name: "LaunchNotRefunding"; + msg: "Launch needs to be in refunding state to get a refund"; + }, + { + code: 6009; + name: "LaunchNotInitialized"; + msg: "Launch must be initialized to be started"; + }, + { + code: 6010; + name: "FreezeAuthoritySet"; + msg: "Freeze authority can't be set on launchpad tokens"; + } + ]; +}; + +export const IDL: Launchpad = { + version: "0.4.1", + name: "launchpad", + instructions: [ + { + name: "initializeLaunch", + accounts: [ + { + name: "launch", + isMut: true, + isSigner: false, + }, + { + name: "tokenMint", + isMut: true, + isSigner: false, + }, + { + name: "tokenMetadata", + isMut: true, + isSigner: false, + }, + { + name: "launchSigner", + isMut: false, + isSigner: false, + }, + { + name: "usdcVault", + isMut: true, + isSigner: false, + }, + { + name: "tokenVault", + isMut: true, + isSigner: false, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "launchAuthority", + isMut: false, + isSigner: false, + }, + { + name: "usdcMint", + isMut: false, + isSigner: false, + }, + { + name: "rent", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenMetadataProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "args", + type: { + defined: "InitializeLaunchArgs", + }, + }, + ], + }, + { + name: "startLaunch", + accounts: [ + { + name: "launch", + isMut: true, + isSigner: false, + }, + { + name: "launchAuthority", + isMut: false, + isSigner: true, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: "fund", + accounts: [ + { + name: "launch", + isMut: true, + isSigner: false, + }, + { + name: "fundingRecord", + isMut: true, + isSigner: false, + }, + { + name: "launchSigner", + isMut: false, + isSigner: false, + }, + { + name: "launchUsdcVault", + isMut: true, + isSigner: false, + }, + { + name: "funder", + isMut: false, + isSigner: true, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "funderUsdcAccount", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "amount", + type: "u64", + }, + ], + }, + { + name: "completeLaunch", + accounts: [ + { + name: "launch", + isMut: true, + isSigner: false, + }, + { + name: "tokenMetadata", + isMut: true, + isSigner: false, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "launchSigner", + isMut: true, + isSigner: false, + }, + { + name: "authority", + isMut: false, + isSigner: false, + }, + { + name: "launchUsdcVault", + isMut: true, + isSigner: false, + }, + { + name: "launchTokenVault", + isMut: true, + isSigner: false, + }, + { + name: "treasuryUsdcAccount", + isMut: true, + isSigner: false, + }, + { + name: "treasuryLpAccount", + isMut: true, + isSigner: false, + }, + { + name: "ammConfig", + isMut: true, + isSigner: false, + docs: [ + "Use the lowest fee pool, can see fees at https://api-v3.raydium.io/main/cpmm-config", + ], + }, + { + name: "poolState", + isMut: true, + isSigner: false, + }, + { + name: "tokenMint", + isMut: true, + isSigner: false, + }, + { + name: "usdcMint", + isMut: false, + isSigner: false, + }, + { + name: "lpMint", + isMut: true, + isSigner: false, + }, + { + name: "lpVault", + isMut: true, + isSigner: false, + }, + { + name: "poolTokenVault", + isMut: true, + isSigner: false, + }, + { + name: "poolUsdcVault", + isMut: true, + isSigner: false, + }, + { + name: "createPoolFee", + isMut: true, + isSigner: false, + docs: ["create pool fee account"], + }, + { + name: "observationState", + isMut: true, + isSigner: false, + }, + { + name: "dao", + isMut: true, + isSigner: false, + }, + { + name: "daoTreasury", + isMut: false, + isSigner: false, + }, + { + name: "cpSwapProgram", + isMut: false, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "autocratProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenMetadataProgram", + isMut: false, + isSigner: false, + }, + { + name: "autocratEventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "rent", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: "refund", + accounts: [ + { + name: "launch", + isMut: true, + isSigner: false, + }, + { + name: "fundingRecord", + isMut: true, + isSigner: false, + }, + { + name: "launchUsdcVault", + isMut: true, + isSigner: false, + }, + { + name: "launchSigner", + isMut: false, + isSigner: false, + }, + { + name: "funder", + isMut: true, + isSigner: true, + }, + { + name: "funderUsdcAccount", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: "claim", + accounts: [ + { + name: "launch", + isMut: true, + isSigner: false, + }, + { + name: "fundingRecord", + isMut: true, + isSigner: false, + }, + { + name: "launchSigner", + isMut: false, + isSigner: false, + }, + { + name: "tokenMint", + isMut: true, + isSigner: false, + }, + { + name: "launchTokenVault", + isMut: true, + isSigner: false, + }, + { + name: "funder", + isMut: false, + isSigner: false, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "funderTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + ], + accounts: [ + { + name: "fundingRecord", + type: { + kind: "struct", + fields: [ + { + name: "pdaBump", + docs: ["The PDA bump."], + type: "u8", + }, + { + name: "funder", + docs: ["The funder."], + type: "publicKey", + }, + { + name: "launch", + docs: ["The launch."], + type: "publicKey", + }, + { + name: "committedAmount", + docs: ["The amount of USDC that has been committed by the funder."], + type: "u64", + }, + { + name: "seqNum", + docs: [ + "The sequence number of this funding record. Useful for sorting events.", + ], + type: "u64", + }, + ], + }, + }, + { + name: "launch", + type: { + kind: "struct", + fields: [ + { + name: "pdaBump", + docs: ["The PDA bump."], + type: "u8", + }, + { + name: "minimumRaiseAmount", + docs: [ + "The minimum amount of USDC that must be raised, otherwise", + "everyone can get their USDC back.", + ], + type: "u64", + }, + { + name: "launchAuthority", + docs: ["The account that can start the launch."], + type: "publicKey", + }, + { + name: "launchSigner", + docs: [ + "The launch signer address. Needed because Raydium pools need a SOL payer and this PDA can't hold SOL.", + ], + type: "publicKey", + }, + { + name: "launchSignerPdaBump", + docs: ["The PDA bump for the launch signer."], + type: "u8", + }, + { + name: "launchUsdcVault", + docs: [ + "The USDC vault that will hold the USDC raised until the launch is over.", + ], + type: "publicKey", + }, + { + name: "launchTokenVault", + docs: ["The token vault, used to send tokens to Raydium."], + type: "publicKey", + }, + { + name: "tokenMint", + docs: [ + "The token that will be minted to funders and that will control the DAO.", + ], + type: "publicKey", + }, + { + name: "usdcMint", + docs: ["The USDC mint."], + type: "publicKey", + }, + { + name: "unixTimestampStarted", + docs: ["The unix timestamp when the launch was started."], + type: "i64", + }, + { + name: "totalCommittedAmount", + docs: ["The amount of USDC that has been committed by the users."], + type: "u64", + }, + { + name: "state", + docs: ["The state of the launch."], + type: { + defined: "LaunchState", + }, + }, + { + name: "seqNum", + docs: [ + "The sequence number of this launch. Useful for sorting events.", + ], + type: "u64", + }, + { + name: "secondsForLaunch", + docs: ["The number of seconds that the launch will be live for."], + type: "u32", + }, + { + name: "dao", + docs: ["The DAO, if the launch is complete."], + type: { + option: "publicKey", + }, + }, + { + name: "daoTreasury", + docs: [ + "The DAO treasury that USDC / LP is sent to, if the launch is complete.", + ], + type: { + option: "publicKey", + }, + }, + ], + }, + }, + ], + types: [ + { + name: "CommonFields", + type: { + kind: "struct", + fields: [ + { + name: "slot", + type: "u64", + }, + { + name: "unixTimestamp", + type: "i64", + }, + { + name: "launchSeqNum", + type: "u64", + }, + ], + }, + }, + { + name: "InitializeLaunchArgs", + type: { + kind: "struct", + fields: [ + { + name: "minimumRaiseAmount", + type: "u64", + }, + { + name: "secondsForLaunch", + type: "u32", + }, + { + name: "tokenName", + type: "string", + }, + { + name: "tokenSymbol", + type: "string", + }, + { + name: "tokenUri", + type: "string", + }, + ], + }, + }, + { + name: "LaunchState", + type: { + kind: "enum", + variants: [ + { + name: "Initialized", + }, + { + name: "Live", + }, + { + name: "Complete", + }, + { + name: "Refunding", + }, + ], + }, + }, + ], + events: [ + { + name: "LaunchInitializedEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "launch", + type: "publicKey", + index: false, + }, + { + name: "minimumRaiseAmount", + type: "u64", + index: false, + }, + { + name: "launchAuthority", + type: "publicKey", + index: false, + }, + { + name: "launchSigner", + type: "publicKey", + index: false, + }, + { + name: "launchSignerPdaBump", + type: "u8", + index: false, + }, + { + name: "launchUsdcVault", + type: "publicKey", + index: false, + }, + { + name: "launchTokenVault", + type: "publicKey", + index: false, + }, + { + name: "tokenMint", + type: "publicKey", + index: false, + }, + { + name: "usdcMint", + type: "publicKey", + index: false, + }, + { + name: "pdaBump", + type: "u8", + index: false, + }, + { + name: "secondsForLaunch", + type: "u32", + index: false, + }, + ], + }, + { + name: "LaunchStartedEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "launch", + type: "publicKey", + index: false, + }, + { + name: "launchAuthority", + type: "publicKey", + index: false, + }, + { + name: "slotStarted", + type: "u64", + index: false, + }, + ], + }, + { + name: "LaunchFundedEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "fundingRecord", + type: "publicKey", + index: false, + }, + { + name: "launch", + type: "publicKey", + index: false, + }, + { + name: "funder", + type: "publicKey", + index: false, + }, + { + name: "amount", + type: "u64", + index: false, + }, + { + name: "totalCommittedByFunder", + type: "u64", + index: false, + }, + { + name: "totalCommitted", + type: "u64", + index: false, + }, + { + name: "fundingRecordSeqNum", + type: "u64", + index: false, + }, + ], + }, + { + name: "LaunchCompletedEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "launch", + type: "publicKey", + index: false, + }, + { + name: "finalState", + type: { + defined: "LaunchState", + }, + index: false, + }, + { + name: "totalCommitted", + type: "u64", + index: false, + }, + { + name: "dao", + type: { + option: "publicKey", + }, + index: false, + }, + { + name: "daoTreasury", + type: { + option: "publicKey", + }, + index: false, + }, + ], + }, + { + name: "LaunchRefundedEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "launch", + type: "publicKey", + index: false, + }, + { + name: "funder", + type: "publicKey", + index: false, + }, + { + name: "usdcRefunded", + type: "u64", + index: false, + }, + { + name: "fundingRecord", + type: "publicKey", + index: false, + }, + ], + }, + { + name: "LaunchClaimEvent", + fields: [ + { + name: "common", + type: { + defined: "CommonFields", + }, + index: false, + }, + { + name: "launch", + type: "publicKey", + index: false, + }, + { + name: "funder", + type: "publicKey", + index: false, + }, + { + name: "tokensClaimed", + type: "u64", + index: false, + }, + { + name: "fundingRecord", + type: "publicKey", + index: false, + }, + ], + }, + ], + errors: [ + { + code: 6000, + name: "InvalidAmount", + msg: "Invalid amount", + }, + { + code: 6001, + name: "SupplyNonZero", + msg: "Supply must be zero", + }, + { + code: 6002, + name: "InvalidSecondsForLaunch", + msg: "Launch period must be between 1 hour and 2 weeks", + }, + { + code: 6003, + name: "InsufficientFunds", + msg: "Insufficient funds", + }, + { + code: 6004, + name: "InvalidTokenKey", + msg: "Token mint key must end in 'meta'", + }, + { + code: 6005, + name: "InvalidLaunchState", + msg: "Invalid launch state", + }, + { + code: 6006, + name: "LaunchPeriodNotOver", + msg: "Launch period not over", + }, + { + code: 6007, + name: "LaunchExpired", + msg: "Launch is complete, no more funding allowed", + }, + { + code: 6008, + name: "LaunchNotRefunding", + msg: "Launch needs to be in refunding state to get a refund", + }, + { + code: 6009, + name: "LaunchNotInitialized", + msg: "Launch must be initialized to be started", + }, + { + code: 6010, + name: "FreezeAuthoritySet", + msg: "Freeze authority can't be set on launchpad tokens", + }, + ], +}; diff --git a/sdk/src/v0.5/types/optimistic_timelock.ts b/sdk/src/v0.5/types/optimistic_timelock.ts new file mode 100644 index 000000000..dda1fa469 --- /dev/null +++ b/sdk/src/v0.5/types/optimistic_timelock.ts @@ -0,0 +1,1023 @@ +export type OptimisticTimelock = { + version: "0.3.0"; + name: "optimistic_timelock"; + instructions: [ + { + name: "createTimelock"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: false; + }, + { + name: "timelock"; + isMut: true; + isSigner: true; + } + ]; + args: [ + { + name: "authority"; + type: "publicKey"; + }, + { + name: "delayInSlots"; + type: "u64"; + }, + { + name: "enqueuers"; + type: { + vec: "publicKey"; + }; + }, + { + name: "enqueuerCooldownSlots"; + type: "u64"; + } + ]; + }, + { + name: "setDelayInSlots"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + } + ]; + args: [ + { + name: "delayInSlots"; + type: "u64"; + } + ]; + }, + { + name: "setAuthority"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + } + ]; + args: [ + { + name: "authority"; + type: "publicKey"; + } + ]; + }, + { + name: "setOptimisticProposerCooldownSlots"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + } + ]; + args: [ + { + name: "cooldownSlots"; + type: "u64"; + } + ]; + }, + { + name: "addOptimisticProposer"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + } + ]; + args: [ + { + name: "enqueuer"; + type: "publicKey"; + } + ]; + }, + { + name: "removeOptimisticProposer"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + } + ]; + args: [ + { + name: "optimisticProposer"; + type: "publicKey"; + } + ]; + }, + { + name: "createTransactionBatch"; + accounts: [ + { + name: "transactionBatchAuthority"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: false; + isSigner: false; + }, + { + name: "transactionBatch"; + isMut: true; + isSigner: true; + } + ]; + args: []; + }, + { + name: "addTransaction"; + accounts: [ + { + name: "transactionBatchAuthority"; + isMut: false; + isSigner: true; + }, + { + name: "transactionBatch"; + isMut: true; + isSigner: false; + } + ]; + args: [ + { + name: "programId"; + type: "publicKey"; + }, + { + name: "accounts"; + type: { + vec: { + defined: "TransactionAccount"; + }; + }; + }, + { + name: "data"; + type: "bytes"; + } + ]; + }, + { + name: "sealTransactionBatch"; + accounts: [ + { + name: "transactionBatchAuthority"; + isMut: false; + isSigner: true; + }, + { + name: "transactionBatch"; + isMut: true; + isSigner: false; + } + ]; + args: []; + }, + { + name: "enqueueTransactionBatch"; + accounts: [ + { + name: "authority"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + }, + { + name: "transactionBatch"; + isMut: true; + isSigner: false; + } + ]; + args: []; + }, + { + name: "cancelTransactionBatch"; + accounts: [ + { + name: "authority"; + isMut: false; + isSigner: true; + }, + { + name: "timelock"; + isMut: true; + isSigner: false; + }, + { + name: "transactionBatch"; + isMut: true; + isSigner: false; + } + ]; + args: []; + }, + { + name: "executeTransactionBatch"; + accounts: [ + { + name: "timelockSigner"; + isMut: false; + isSigner: false; + }, + { + name: "timelock"; + isMut: false; + isSigner: false; + }, + { + name: "transactionBatch"; + isMut: true; + isSigner: false; + } + ]; + args: []; + } + ]; + accounts: [ + { + name: "timelock"; + type: { + kind: "struct"; + fields: [ + { + name: "authority"; + type: "publicKey"; + }, + { + name: "signerBump"; + type: "u8"; + }, + { + name: "delayInSlots"; + type: "u64"; + }, + { + name: "optimisticProposers"; + type: { + vec: { + defined: "OptimisticProposer"; + }; + }; + }, + { + name: "optimisticProposerCooldownSlots"; + docs: [ + "The cooldown period for enqueuers to prevent spamming the timelock." + ]; + type: "u64"; + } + ]; + }; + }, + { + name: "transactionBatch"; + type: { + kind: "struct"; + fields: [ + { + name: "status"; + type: { + defined: "TransactionBatchStatus"; + }; + }, + { + name: "transactions"; + type: { + vec: { + defined: "Transaction"; + }; + }; + }, + { + name: "timelock"; + type: "publicKey"; + }, + { + name: "enqueuedSlot"; + type: "u64"; + }, + { + name: "transactionBatchAuthority"; + type: "publicKey"; + }, + { + name: "enqueuerType"; + type: { + defined: "AuthorityType"; + }; + } + ]; + }; + } + ]; + types: [ + { + name: "OptimisticProposer"; + type: { + kind: "struct"; + fields: [ + { + name: "pubkey"; + type: "publicKey"; + }, + { + name: "lastSlotEnqueued"; + type: "u64"; + } + ]; + }; + }, + { + name: "Transaction"; + type: { + kind: "struct"; + fields: [ + { + name: "programId"; + type: "publicKey"; + }, + { + name: "accounts"; + type: { + vec: { + defined: "TransactionAccount"; + }; + }; + }, + { + name: "data"; + type: "bytes"; + }, + { + name: "didExecute"; + type: "bool"; + } + ]; + }; + }, + { + name: "TransactionAccount"; + type: { + kind: "struct"; + fields: [ + { + name: "pubkey"; + type: "publicKey"; + }, + { + name: "isSigner"; + type: "bool"; + }, + { + name: "isWritable"; + type: "bool"; + } + ]; + }; + }, + { + name: "AuthorityType"; + type: { + kind: "enum"; + variants: [ + { + name: "OptimisticProposer"; + }, + { + name: "TimelockAuthority"; + } + ]; + }; + }, + { + name: "TransactionBatchStatus"; + type: { + kind: "enum"; + variants: [ + { + name: "Created"; + }, + { + name: "Sealed"; + }, + { + name: "Enqueued"; + }, + { + name: "Cancelled"; + }, + { + name: "Executed"; + } + ]; + }; + } + ]; + errors: [ + { + code: 6000; + name: "NotReady"; + msg: "This transaction is not yet ready to be executed"; + }, + { + code: 6001; + name: "CannotAddTransactions"; + msg: "Can only add instructions when transaction batch status is `Created`"; + }, + { + code: 6002; + name: "CannotSealTransactionBatch"; + msg: "Can only seal the transaction batch when status is `Created`"; + }, + { + code: 6003; + name: "CannotEnqueueTransactionBatch"; + msg: "Can only enqueue the timelock running once the status is `Sealed`"; + }, + { + code: 6004; + name: "CannotCancelTimelock"; + msg: "Can only cancel the transactions if the status `Enqueued`"; + }, + { + code: 6005; + name: "CanOnlyCancelDuringTimelockPeriod"; + msg: "Can only cancel the transactions during the timelock period"; + }, + { + code: 6006; + name: "CannotExecuteTransactions"; + msg: "Can only execute the transactions if the status is `Enqueued`"; + }, + { + code: 6007; + name: "NoAuthority"; + msg: "The signer is neither the timelock authority nor an optimistic proposer"; + }, + { + code: 6008; + name: "InsufficientPermissions"; + msg: "Optimistic proposers can't cancel transaction batches enqueued by the timelock authority"; + }, + { + code: 6009; + name: "OptimisticProposerCooldown"; + msg: "This optimistic proposer is still in its cooldown period"; + } + ]; +}; + +export const IDL: OptimisticTimelock = { + version: "0.3.0", + name: "optimistic_timelock", + instructions: [ + { + name: "createTimelock", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: false, + }, + { + name: "timelock", + isMut: true, + isSigner: true, + }, + ], + args: [ + { + name: "authority", + type: "publicKey", + }, + { + name: "delayInSlots", + type: "u64", + }, + { + name: "enqueuers", + type: { + vec: "publicKey", + }, + }, + { + name: "enqueuerCooldownSlots", + type: "u64", + }, + ], + }, + { + name: "setDelayInSlots", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + ], + args: [ + { + name: "delayInSlots", + type: "u64", + }, + ], + }, + { + name: "setAuthority", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + ], + args: [ + { + name: "authority", + type: "publicKey", + }, + ], + }, + { + name: "setOptimisticProposerCooldownSlots", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + ], + args: [ + { + name: "cooldownSlots", + type: "u64", + }, + ], + }, + { + name: "addOptimisticProposer", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + ], + args: [ + { + name: "enqueuer", + type: "publicKey", + }, + ], + }, + { + name: "removeOptimisticProposer", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + ], + args: [ + { + name: "optimisticProposer", + type: "publicKey", + }, + ], + }, + { + name: "createTransactionBatch", + accounts: [ + { + name: "transactionBatchAuthority", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: false, + isSigner: false, + }, + { + name: "transactionBatch", + isMut: true, + isSigner: true, + }, + ], + args: [], + }, + { + name: "addTransaction", + accounts: [ + { + name: "transactionBatchAuthority", + isMut: false, + isSigner: true, + }, + { + name: "transactionBatch", + isMut: true, + isSigner: false, + }, + ], + args: [ + { + name: "programId", + type: "publicKey", + }, + { + name: "accounts", + type: { + vec: { + defined: "TransactionAccount", + }, + }, + }, + { + name: "data", + type: "bytes", + }, + ], + }, + { + name: "sealTransactionBatch", + accounts: [ + { + name: "transactionBatchAuthority", + isMut: false, + isSigner: true, + }, + { + name: "transactionBatch", + isMut: true, + isSigner: false, + }, + ], + args: [], + }, + { + name: "enqueueTransactionBatch", + accounts: [ + { + name: "authority", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + { + name: "transactionBatch", + isMut: true, + isSigner: false, + }, + ], + args: [], + }, + { + name: "cancelTransactionBatch", + accounts: [ + { + name: "authority", + isMut: false, + isSigner: true, + }, + { + name: "timelock", + isMut: true, + isSigner: false, + }, + { + name: "transactionBatch", + isMut: true, + isSigner: false, + }, + ], + args: [], + }, + { + name: "executeTransactionBatch", + accounts: [ + { + name: "timelockSigner", + isMut: false, + isSigner: false, + }, + { + name: "timelock", + isMut: false, + isSigner: false, + }, + { + name: "transactionBatch", + isMut: true, + isSigner: false, + }, + ], + args: [], + }, + ], + accounts: [ + { + name: "timelock", + type: { + kind: "struct", + fields: [ + { + name: "authority", + type: "publicKey", + }, + { + name: "signerBump", + type: "u8", + }, + { + name: "delayInSlots", + type: "u64", + }, + { + name: "optimisticProposers", + type: { + vec: { + defined: "OptimisticProposer", + }, + }, + }, + { + name: "optimisticProposerCooldownSlots", + docs: [ + "The cooldown period for enqueuers to prevent spamming the timelock.", + ], + type: "u64", + }, + ], + }, + }, + { + name: "transactionBatch", + type: { + kind: "struct", + fields: [ + { + name: "status", + type: { + defined: "TransactionBatchStatus", + }, + }, + { + name: "transactions", + type: { + vec: { + defined: "Transaction", + }, + }, + }, + { + name: "timelock", + type: "publicKey", + }, + { + name: "enqueuedSlot", + type: "u64", + }, + { + name: "transactionBatchAuthority", + type: "publicKey", + }, + { + name: "enqueuerType", + type: { + defined: "AuthorityType", + }, + }, + ], + }, + }, + ], + types: [ + { + name: "OptimisticProposer", + type: { + kind: "struct", + fields: [ + { + name: "pubkey", + type: "publicKey", + }, + { + name: "lastSlotEnqueued", + type: "u64", + }, + ], + }, + }, + { + name: "Transaction", + type: { + kind: "struct", + fields: [ + { + name: "programId", + type: "publicKey", + }, + { + name: "accounts", + type: { + vec: { + defined: "TransactionAccount", + }, + }, + }, + { + name: "data", + type: "bytes", + }, + { + name: "didExecute", + type: "bool", + }, + ], + }, + }, + { + name: "TransactionAccount", + type: { + kind: "struct", + fields: [ + { + name: "pubkey", + type: "publicKey", + }, + { + name: "isSigner", + type: "bool", + }, + { + name: "isWritable", + type: "bool", + }, + ], + }, + }, + { + name: "AuthorityType", + type: { + kind: "enum", + variants: [ + { + name: "OptimisticProposer", + }, + { + name: "TimelockAuthority", + }, + ], + }, + }, + { + name: "TransactionBatchStatus", + type: { + kind: "enum", + variants: [ + { + name: "Created", + }, + { + name: "Sealed", + }, + { + name: "Enqueued", + }, + { + name: "Cancelled", + }, + { + name: "Executed", + }, + ], + }, + }, + ], + errors: [ + { + code: 6000, + name: "NotReady", + msg: "This transaction is not yet ready to be executed", + }, + { + code: 6001, + name: "CannotAddTransactions", + msg: "Can only add instructions when transaction batch status is `Created`", + }, + { + code: 6002, + name: "CannotSealTransactionBatch", + msg: "Can only seal the transaction batch when status is `Created`", + }, + { + code: 6003, + name: "CannotEnqueueTransactionBatch", + msg: "Can only enqueue the timelock running once the status is `Sealed`", + }, + { + code: 6004, + name: "CannotCancelTimelock", + msg: "Can only cancel the transactions if the status `Enqueued`", + }, + { + code: 6005, + name: "CanOnlyCancelDuringTimelockPeriod", + msg: "Can only cancel the transactions during the timelock period", + }, + { + code: 6006, + name: "CannotExecuteTransactions", + msg: "Can only execute the transactions if the status is `Enqueued`", + }, + { + code: 6007, + name: "NoAuthority", + msg: "The signer is neither the timelock authority nor an optimistic proposer", + }, + { + code: 6008, + name: "InsufficientPermissions", + msg: "Optimistic proposers can't cancel transaction batches enqueued by the timelock authority", + }, + { + code: 6009, + name: "OptimisticProposerCooldown", + msg: "This optimistic proposer is still in its cooldown period", + }, + ], +}; diff --git a/sdk/src/v0.5/types/shared_liquidity_manager.ts b/sdk/src/v0.5/types/shared_liquidity_manager.ts new file mode 100644 index 000000000..a4a2d4f8d --- /dev/null +++ b/sdk/src/v0.5/types/shared_liquidity_manager.ts @@ -0,0 +1,3529 @@ +export type SharedLiquidityManager = { + version: "0.1.0"; + name: "shared_liquidity_manager"; + docs: ["TODO:", "- add unstake", "- add unit tests"]; + instructions: [ + { + name: "initializeSharedLiquidityPool"; + accounts: [ + { + name: "slPool"; + isMut: true; + isSigner: false; + }, + { + name: "dao"; + isMut: false; + isSigner: false; + }, + { + name: "creator"; + isMut: true; + isSigner: true; + }, + { + name: "creatorSlPoolPosition"; + isMut: true; + isSigner: false; + }, + { + name: "baseMint"; + isMut: false; + isSigner: false; + }, + { + name: "quoteMint"; + isMut: false; + isSigner: false; + }, + { + name: "slPoolSpotLpVault"; + isMut: true; + isSigner: false; + }, + { + name: "creatorQuoteTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "creatorBaseTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "creatorLpAccount"; + isMut: true; + isSigner: false; + docs: ["so Raydium will create it"]; + }, + { + name: "raydiumInitPoolStatic"; + accounts: [ + { + name: "raydiumAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "createPoolFee"; + isMut: true; + isSigner: false; + }, + { + name: "ammConfig"; + isMut: true; + isSigner: false; + }, + { + name: "cpSwapProgram"; + isMut: false; + isSigner: false; + }, + { + name: "rent"; + isMut: false; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + } + ]; + }, + { + name: "spotPool"; + isMut: true; + isSigner: false; + }, + { + name: "spotPoolLpMint"; + isMut: true; + isSigner: false; + }, + { + name: "spotPoolBaseVault"; + isMut: true; + isSigner: false; + }, + { + name: "spotPoolQuoteVault"; + isMut: true; + isSigner: false; + }, + { + name: "spotPoolObservationState"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolSigner"; + isMut: false; + isSigner: false; + }, + { + name: "slPoolBaseVault"; + isMut: false; + isSigner: false; + }, + { + name: "slPoolQuoteVault"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "cpSwapProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "params"; + type: { + defined: "InitializeSharedLiquidityPoolParams"; + }; + } + ]; + }, + { + name: "initializeDraftProposal"; + accounts: [ + { + name: "draftProposal"; + isMut: true; + isSigner: false; + }, + { + name: "sharedLiquidityPool"; + isMut: false; + isSigner: false; + }, + { + name: "baseMint"; + isMut: false; + isSigner: false; + }, + { + name: "stakedTokenVault"; + isMut: true; + isSigner: false; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "params"; + type: { + defined: "InitializeDraftProposalParams"; + }; + } + ]; + }, + { + name: "stakeToDraftProposal"; + accounts: [ + { + name: "draftProposal"; + isMut: true; + isSigner: false; + }, + { + name: "staker"; + isMut: false; + isSigner: true; + }, + { + name: "stakerTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "stakedTokenVault"; + isMut: true; + isSigner: false; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "stakeRecord"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "params"; + type: { + defined: "StakeToDraftProposalParams"; + }; + } + ]; + }, + { + name: "unstakeFromDraftProposal"; + accounts: [ + { + name: "draftProposal"; + isMut: true; + isSigner: false; + }, + { + name: "staker"; + isMut: false; + isSigner: true; + }, + { + name: "stakerTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "stakedTokenVault"; + isMut: true; + isSigner: false; + }, + { + name: "stakeRecord"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "params"; + type: { + defined: "UnstakeFromDraftProposalParams"; + }; + } + ]; + }, + { + name: "depositSharedLiquidity"; + accounts: [ + { + name: "slPool"; + isMut: true; + isSigner: false; + }, + { + name: "activeSpotPool"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolSpotLpVault"; + isMut: true; + isSigner: false; + }, + { + name: "userQuoteTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userBaseTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "spotPoolBaseVault"; + isMut: true; + isSigner: false; + }, + { + name: "spotPoolQuoteVault"; + isMut: true; + isSigner: false; + }, + { + name: "baseMint"; + isMut: false; + isSigner: false; + }, + { + name: "quoteMint"; + isMut: false; + isSigner: false; + }, + { + name: "spotPoolLpMint"; + isMut: true; + isSigner: false; + }, + { + name: "userLpTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userSlPoolPosition"; + isMut: true; + isSigner: false; + }, + { + name: "user"; + isMut: false; + isSigner: true; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "raydiumAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram2022"; + isMut: false; + isSigner: false; + }, + { + name: "cpSwapProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "params"; + type: { + defined: "DepositSharedLiquidityParams"; + }; + } + ]; + }, + { + name: "withdrawSharedLiquidity"; + accounts: [ + { + name: "slPool"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolSigner"; + isMut: false; + isSigner: false; + }, + { + name: "activeSpotPool"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolSpotLpVault"; + isMut: true; + isSigner: false; + }, + { + name: "userQuoteTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userBaseTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "spotPoolBaseVault"; + isMut: true; + isSigner: false; + }, + { + name: "spotPoolQuoteVault"; + isMut: true; + isSigner: false; + }, + { + name: "baseMint"; + isMut: false; + isSigner: false; + }, + { + name: "quoteMint"; + isMut: false; + isSigner: false; + }, + { + name: "spotPoolLpMint"; + isMut: true; + isSigner: false; + }, + { + name: "userLpTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "userSlPoolPosition"; + isMut: true; + isSigner: false; + }, + { + name: "user"; + isMut: true; + isSigner: true; + }, + { + name: "feeReceiver"; + isMut: false; + isSigner: false; + }, + { + name: "raydiumAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram2022"; + isMut: false; + isSigner: false; + }, + { + name: "cpSwapProgram"; + isMut: false; + isSigner: false; + }, + { + name: "memoProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "params"; + type: { + defined: "WithdrawSharedLiquidityParams"; + }; + } + ]; + }, + { + name: "initializeProposalWithLiquidity"; + accounts: [ + { + name: "sharedLiquidityPool"; + isMut: true; + isSigner: false; + }, + { + name: "proposalCreator"; + isMut: false; + isSigner: true; + }, + { + name: "proposal"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolBaseVault"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolQuoteVault"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolSpotLpVault"; + isMut: true; + isSigner: false; + }, + { + name: "baseMint"; + isMut: false; + isSigner: false; + }, + { + name: "quoteMint"; + isMut: false; + isSigner: false; + }, + { + name: "raydium"; + accounts: [ + { + name: "spotPool"; + isMut: true; + isSigner: false; + }, + { + name: "spotPoolBaseVault"; + isMut: true; + isSigner: false; + }, + { + name: "spotPoolQuoteVault"; + isMut: true; + isSigner: false; + }, + { + name: "lpMint"; + isMut: true; + isSigner: false; + }, + { + name: "raydiumAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram2022"; + isMut: false; + isSigner: false; + }, + { + name: "cpSwapProgram"; + isMut: false; + isSigner: false; + }, + { + name: "memoProgram"; + isMut: false; + isSigner: false; + } + ]; + }, + { + name: "conditionalVault"; + accounts: [ + { + name: "question"; + isMut: true; + isSigner: false; + }, + { + name: "baseVault"; + isMut: true; + isSigner: false; + }, + { + name: "quoteVault"; + isMut: true; + isSigner: false; + }, + { + name: "baseVaultUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "quoteVaultUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "conditionalVaultProgram"; + isMut: false; + isSigner: false; + }, + { + name: "passBaseMint"; + isMut: true; + isSigner: false; + }, + { + name: "failBaseMint"; + isMut: true; + isSigner: false; + }, + { + name: "passQuoteMint"; + isMut: true; + isSigner: false; + }, + { + name: "failQuoteMint"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolPassBaseVault"; + isMut: true; + isSigner: true; + }, + { + name: "slPoolFailBaseVault"; + isMut: true; + isSigner: true; + }, + { + name: "slPoolPassQuoteVault"; + isMut: true; + isSigner: true; + }, + { + name: "slPoolFailQuoteVault"; + isMut: true; + isSigner: true; + }, + { + name: "vaultEventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "slPoolSigner"; + isMut: true; + isSigner: false; + } + ]; + }, + { + name: "amm"; + accounts: [ + { + name: "passAmm"; + isMut: true; + isSigner: false; + }, + { + name: "failAmm"; + isMut: true; + isSigner: false; + }, + { + name: "passLpMint"; + isMut: true; + isSigner: false; + }, + { + name: "failLpMint"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolPassLpAccount"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolFailLpAccount"; + isMut: true; + isSigner: false; + }, + { + name: "passAmmVaultAtaBase"; + isMut: true; + isSigner: false; + }, + { + name: "passAmmVaultAtaQuote"; + isMut: true; + isSigner: false; + }, + { + name: "failAmmVaultAtaBase"; + isMut: true; + isSigner: false; + }, + { + name: "failAmmVaultAtaQuote"; + isMut: true; + isSigner: false; + }, + { + name: "proposal"; + isMut: true; + isSigner: false; + }, + { + name: "proposalPassLpVault"; + isMut: true; + isSigner: false; + }, + { + name: "proposalFailLpVault"; + isMut: true; + isSigner: false; + }, + { + name: "ammProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "slPoolSigner"; + isMut: false; + isSigner: false; + } + ]; + }, + { + name: "draftProposal"; + isMut: true; + isSigner: false; + }, + { + name: "dao"; + isMut: true; + isSigner: false; + }, + { + name: "autocratProgram"; + isMut: false; + isSigner: false; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "autocratEventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: "params"; + type: { + defined: "InitializeProposalWithLiquidityParams"; + }; + } + ]; + }, + { + name: "removeProposalLiquidity"; + accounts: [ + { + name: "slPool"; + isMut: true; + isSigner: false; + }, + { + name: "proposal"; + isMut: false; + isSigner: false; + }, + { + name: "slPoolBaseVault"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolQuoteVault"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolSpotLpVault"; + isMut: true; + isSigner: false; + }, + { + name: "baseMint"; + isMut: false; + isSigner: false; + }, + { + name: "quoteMint"; + isMut: false; + isSigner: false; + }, + { + name: "raydiumInitPoolStatic"; + accounts: [ + { + name: "raydiumAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "createPoolFee"; + isMut: true; + isSigner: false; + }, + { + name: "ammConfig"; + isMut: true; + isSigner: false; + }, + { + name: "cpSwapProgram"; + isMut: false; + isSigner: false; + }, + { + name: "rent"; + isMut: false; + isSigner: false; + }, + { + name: "associatedTokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + } + ]; + }, + { + name: "raydium"; + accounts: [ + { + name: "activeSpotPool"; + isMut: true; + isSigner: false; + }, + { + name: "activeSpotPoolLpMint"; + isMut: true; + isSigner: false; + }, + { + name: "activeSpotPoolBaseVault"; + isMut: true; + isSigner: false; + }, + { + name: "activeSpotPoolQuoteVault"; + isMut: true; + isSigner: false; + }, + { + name: "tokenProgram2022"; + isMut: false; + isSigner: false; + }, + { + name: "cpSwapProgram"; + isMut: false; + isSigner: false; + }, + { + name: "memoProgram"; + isMut: false; + isSigner: false; + }, + { + name: "nextSpotPool"; + isMut: true; + isSigner: false; + }, + { + name: "nextSpotPoolLpMint"; + isMut: true; + isSigner: false; + }, + { + name: "nextSpotPoolBaseVault"; + isMut: true; + isSigner: false; + }, + { + name: "nextSpotPoolQuoteVault"; + isMut: true; + isSigner: false; + }, + { + name: "nextSpotPoolObservationState"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolNextSpotLpVault"; + isMut: true; + isSigner: false; + }, + { + name: "slPool"; + isMut: false; + isSigner: false; + }, + { + name: "slPoolSigner"; + isMut: false; + isSigner: false; + }, + { + name: "baseMint"; + isMut: false; + isSigner: false; + }, + { + name: "quoteMint"; + isMut: false; + isSigner: false; + } + ]; + }, + { + name: "conditionalVault"; + accounts: [ + { + name: "question"; + isMut: true; + isSigner: false; + }, + { + name: "baseVault"; + isMut: true; + isSigner: false; + }, + { + name: "quoteVault"; + isMut: true; + isSigner: false; + }, + { + name: "baseVaultUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "quoteVaultUnderlyingTokenAccount"; + isMut: true; + isSigner: false; + }, + { + name: "conditionalVaultProgram"; + isMut: false; + isSigner: false; + }, + { + name: "passBaseMint"; + isMut: true; + isSigner: false; + }, + { + name: "failBaseMint"; + isMut: true; + isSigner: false; + }, + { + name: "passQuoteMint"; + isMut: true; + isSigner: false; + }, + { + name: "failQuoteMint"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolPassBaseVault"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolFailBaseVault"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolPassQuoteVault"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolFailQuoteVault"; + isMut: true; + isSigner: false; + }, + { + name: "vaultEventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "slPoolSigner"; + isMut: true; + isSigner: false; + } + ]; + }, + { + name: "ammm"; + accounts: [ + { + name: "passAmm"; + isMut: true; + isSigner: false; + }, + { + name: "failAmm"; + isMut: true; + isSigner: false; + }, + { + name: "passLpMint"; + isMut: true; + isSigner: false; + }, + { + name: "failLpMint"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolPassLpAccount"; + isMut: true; + isSigner: false; + }, + { + name: "slPoolFailLpAccount"; + isMut: true; + isSigner: false; + }, + { + name: "passAmmVaultAtaBase"; + isMut: true; + isSigner: false; + }, + { + name: "passAmmVaultAtaQuote"; + isMut: true; + isSigner: false; + }, + { + name: "failAmmVaultAtaBase"; + isMut: true; + isSigner: false; + }, + { + name: "failAmmVaultAtaQuote"; + isMut: true; + isSigner: false; + }, + { + name: "ammProgram"; + isMut: false; + isSigner: false; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "slPoolSigner"; + isMut: false; + isSigner: false; + } + ]; + }, + { + name: "systemProgram"; + isMut: false; + isSigner: false; + }, + { + name: "tokenProgram"; + isMut: false; + isSigner: false; + }, + { + name: "payer"; + isMut: true; + isSigner: true; + }, + { + name: "eventAuthority"; + isMut: false; + isSigner: false; + }, + { + name: "program"; + isMut: false; + isSigner: false; + } + ]; + args: []; + } + ]; + accounts: [ + { + name: "draftProposal"; + type: { + kind: "struct"; + fields: [ + { + name: "sharedLiquidityPool"; + type: "publicKey"; + }, + { + name: "baseMint"; + type: "publicKey"; + }, + { + name: "instruction"; + type: { + defined: "ProposalInstruction"; + }; + }, + { + name: "status"; + type: { + defined: "DraftProposalStatus"; + }; + }, + { + name: "stakedTokenAmount"; + docs: [ + "The amount of tokens that have been staked on this draft proposal" + ]; + type: "u64"; + }, + { + name: "stakedTokenVault"; + docs: ["The vault that holds the staked tokens"]; + type: "publicKey"; + }, + { + name: "nonce"; + docs: ["The nonce used to create this draft proposal PDA"]; + type: "u64"; + }, + { + name: "pdaBump"; + type: "u8"; + } + ]; + }; + }, + { + name: "liquidityPosition"; + type: { + kind: "struct"; + fields: [ + { + name: "owner"; + docs: ["The owner of this position"]; + type: "publicKey"; + }, + { + name: "pool"; + docs: ["The shared liquidity pool this position belongs to"]; + type: "publicKey"; + }, + { + name: "underlyingSpotLpShares"; + docs: [ + "The amount of underlying spot LP shares this position represents" + ]; + type: "u64"; + }, + { + name: "bump"; + docs: ["The PDA bump"]; + type: "u8"; + } + ]; + }; + }, + { + name: "sharedLiquidityPool"; + type: { + kind: "struct"; + fields: [ + { + name: "pdaBump"; + docs: ["The PDA bump."]; + type: "u8"; + }, + { + name: "dao"; + docs: ["The DAO."]; + type: "publicKey"; + }, + { + name: "baseMint"; + docs: ["The base mint."]; + type: "publicKey"; + }, + { + name: "quoteMint"; + docs: ["The quote mint."]; + type: "publicKey"; + }, + { + name: "slPoolSigner"; + docs: [ + "The signer of this pool, used because Raydium pools need a SOL payer and this PDA can't hold SOL." + ]; + type: "publicKey"; + }, + { + name: "slPoolSignerBump"; + docs: ["The pda bump of the signer."]; + type: "u8"; + }, + { + name: "slPoolBaseVault"; + docs: [ + "Holds the base tokens for the shared liquidity pool when it's moving liquidity around." + ]; + type: "publicKey"; + }, + { + name: "slPoolQuoteVault"; + docs: [ + "Holds the quote tokens for the shared liquidity pool when it's moving liquidity around." + ]; + type: "publicKey"; + }, + { + name: "slPoolSpotLpVault"; + docs: ["Holds the LP tokens for the shared liquidity pool."]; + type: "publicKey"; + }, + { + name: "activeProposal"; + docs: ["The proposal that's using liquidity from this pool."]; + type: { + option: "publicKey"; + }; + }, + { + name: "proposalStakeRateThresholdBps"; + docs: [ + "The percentage of a token's supply, in basis points, that needs to be", + "staked to a draft proposal before it can be initialized." + ]; + type: "u16"; + }, + { + name: "seqNum"; + docs: [ + "The sequence number of this shared liquidity pool. Useful for sorting events." + ]; + type: "u64"; + }, + { + name: "activeSpotPool"; + docs: [ + "The current Raydium spot pool. Changes when a proposal is removed." + ]; + type: "publicKey"; + }, + { + name: "activeSpotPoolIndex"; + docs: [ + "The index of the current Raydium spot pool. Starts at 0 and increments by 1 for each new spot pool." + ]; + type: "u32"; + }, + { + name: "isBaseToken0"; + docs: [ + "Whether the base token is token0 in the current Raydium spot pool (otherwise it's token1)." + ]; + type: "bool"; + } + ]; + }; + }, + { + name: "stakeRecord"; + type: { + kind: "struct"; + fields: [ + { + name: "staker"; + type: "publicKey"; + }, + { + name: "amount"; + type: "u64"; + } + ]; + }; + } + ]; + types: [ + { + name: "DepositSharedLiquidityParams"; + type: { + kind: "struct"; + fields: [ + { + name: "lpTokenAmount"; + docs: ["The amount of LP tokens to mint"]; + type: "u64"; + }, + { + name: "maxQuoteTokenAmount"; + docs: ["The maximum amount of quote tokens to deposit"]; + type: "u64"; + }, + { + name: "maxBaseTokenAmount"; + docs: ["The maximum amount of base tokens to deposit"]; + type: "u64"; + } + ]; + }; + }, + { + name: "InitializeDraftProposalParams"; + type: { + kind: "struct"; + fields: [ + { + name: "instruction"; + type: { + defined: "ProposalInstruction"; + }; + }, + { + name: "draftProposalNonce"; + docs: [ + "The nonce for the draft proposal, not used for anything aside from the PDA" + ]; + type: "u64"; + } + ]; + }; + }, + { + name: "InitializeProposalWithLiquidityParams"; + type: { + kind: "struct"; + fields: [ + { + name: "nonce"; + type: "u64"; + } + ]; + }; + }, + { + name: "InitializeSharedLiquidityPoolParams"; + type: { + kind: "struct"; + fields: [ + { + name: "baseAmount"; + type: "u64"; + }, + { + name: "quoteAmount"; + type: "u64"; + }, + { + name: "proposalStakeRateThresholdBps"; + type: "u16"; + } + ]; + }; + }, + { + name: "StakeToDraftProposalParams"; + type: { + kind: "struct"; + fields: [ + { + name: "amount"; + type: "u64"; + } + ]; + }; + }, + { + name: "UnstakeFromDraftProposalParams"; + type: { + kind: "struct"; + fields: [ + { + name: "amount"; + type: "u64"; + } + ]; + }; + }, + { + name: "WithdrawSharedLiquidityParams"; + type: { + kind: "struct"; + fields: [ + { + name: "lpTokenAmount"; + docs: ["The amount of LP tokens to withdraw"]; + type: "u64"; + }, + { + name: "minimumToken0Amount"; + docs: ["The minimum amount of token0 to receive"]; + type: "u64"; + }, + { + name: "minimumToken1Amount"; + docs: ["The minimum amount of token1 to receive"]; + type: "u64"; + } + ]; + }; + }, + { + name: "ProposalAccount"; + type: { + kind: "struct"; + fields: [ + { + name: "pubkey"; + type: "publicKey"; + }, + { + name: "isSigner"; + type: "bool"; + }, + { + name: "isWritable"; + type: "bool"; + } + ]; + }; + }, + { + name: "ProposalInstruction"; + type: { + kind: "struct"; + fields: [ + { + name: "programId"; + type: "publicKey"; + }, + { + name: "accounts"; + type: { + vec: { + defined: "ProposalAccount"; + }; + }; + }, + { + name: "data"; + type: "bytes"; + } + ]; + }; + }, + { + name: "DraftProposalStatus"; + type: { + kind: "enum"; + variants: [ + { + name: "Draft"; + }, + { + name: "Initialized"; + } + ]; + }; + } + ]; + errors: [ + { + code: 6000; + name: "InsufficientStake"; + msg: "Insufficient stake amount"; + }, + { + code: 6001; + name: "ProposalNotFinalized"; + msg: "Proposal is not finalized"; + }, + { + code: 6002; + name: "NoLpTokensToRemove"; + msg: "No LP tokens to remove from AMM"; + }, + { + code: 6003; + name: "NoTokensFromAmm"; + msg: "No tokens received from AMM removal"; + }, + { + code: 6004; + name: "InsufficientReservesReturned"; + msg: "Insufficient reserves returned to spot AMM (less than 99.5%)"; + }, + { + code: 6005; + name: "PoolInUse"; + msg: "Pool is currently being used by an active proposal"; + }, + { + code: 6006; + name: "InsufficientLpShares"; + msg: "User does not have enough LP shares to withdraw"; + }, + { + code: 6007; + name: "SlippageExceeded"; + msg: "Slippage exceeded minimum token amounts"; + }, + { + code: 6008; + name: "NoLpTokensInPool"; + msg: "No LP tokens in pool's LP token account"; + }, + { + code: 6009; + name: "NotEnoughLpTokens"; + msg: "Not enough LP tokens to provide liquidity to proposal"; + }, + { + code: 6010; + name: "InsufficientFunds"; + msg: "Insufficient funds"; + }, + { + code: 6011; + name: "NoActiveProposal"; + msg: "No active proposal"; + }, + { + code: 6012; + name: "ProposalNotInDraftStatus"; + msg: "Proposal is not in draft status"; + }, + { + code: 6013; + name: "ProposalAlreadyActive"; + msg: "Proposal already active"; + }, + { + code: 6014; + name: "AmmAlreadyHasLiquidity"; + msg: "AMM already has liquidity"; + }, + { + code: 6015; + name: "QuestionAlreadyResolved"; + msg: "Question already resolved"; + } + ]; +}; + +export const IDL: SharedLiquidityManager = { + version: "0.1.0", + name: "shared_liquidity_manager", + docs: ["TODO:", "- add unstake", "- add unit tests"], + instructions: [ + { + name: "initializeSharedLiquidityPool", + accounts: [ + { + name: "slPool", + isMut: true, + isSigner: false, + }, + { + name: "dao", + isMut: false, + isSigner: false, + }, + { + name: "creator", + isMut: true, + isSigner: true, + }, + { + name: "creatorSlPoolPosition", + isMut: true, + isSigner: false, + }, + { + name: "baseMint", + isMut: false, + isSigner: false, + }, + { + name: "quoteMint", + isMut: false, + isSigner: false, + }, + { + name: "slPoolSpotLpVault", + isMut: true, + isSigner: false, + }, + { + name: "creatorQuoteTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "creatorBaseTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "creatorLpAccount", + isMut: true, + isSigner: false, + docs: ["so Raydium will create it"], + }, + { + name: "raydiumInitPoolStatic", + accounts: [ + { + name: "raydiumAuthority", + isMut: false, + isSigner: false, + }, + { + name: "createPoolFee", + isMut: true, + isSigner: false, + }, + { + name: "ammConfig", + isMut: true, + isSigner: false, + }, + { + name: "cpSwapProgram", + isMut: false, + isSigner: false, + }, + { + name: "rent", + isMut: false, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + ], + }, + { + name: "spotPool", + isMut: true, + isSigner: false, + }, + { + name: "spotPoolLpMint", + isMut: true, + isSigner: false, + }, + { + name: "spotPoolBaseVault", + isMut: true, + isSigner: false, + }, + { + name: "spotPoolQuoteVault", + isMut: true, + isSigner: false, + }, + { + name: "spotPoolObservationState", + isMut: true, + isSigner: false, + }, + { + name: "slPoolSigner", + isMut: false, + isSigner: false, + }, + { + name: "slPoolBaseVault", + isMut: false, + isSigner: false, + }, + { + name: "slPoolQuoteVault", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "cpSwapProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "params", + type: { + defined: "InitializeSharedLiquidityPoolParams", + }, + }, + ], + }, + { + name: "initializeDraftProposal", + accounts: [ + { + name: "draftProposal", + isMut: true, + isSigner: false, + }, + { + name: "sharedLiquidityPool", + isMut: false, + isSigner: false, + }, + { + name: "baseMint", + isMut: false, + isSigner: false, + }, + { + name: "stakedTokenVault", + isMut: true, + isSigner: false, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "params", + type: { + defined: "InitializeDraftProposalParams", + }, + }, + ], + }, + { + name: "stakeToDraftProposal", + accounts: [ + { + name: "draftProposal", + isMut: true, + isSigner: false, + }, + { + name: "staker", + isMut: false, + isSigner: true, + }, + { + name: "stakerTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "stakedTokenVault", + isMut: true, + isSigner: false, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "stakeRecord", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "params", + type: { + defined: "StakeToDraftProposalParams", + }, + }, + ], + }, + { + name: "unstakeFromDraftProposal", + accounts: [ + { + name: "draftProposal", + isMut: true, + isSigner: false, + }, + { + name: "staker", + isMut: false, + isSigner: true, + }, + { + name: "stakerTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "stakedTokenVault", + isMut: true, + isSigner: false, + }, + { + name: "stakeRecord", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "params", + type: { + defined: "UnstakeFromDraftProposalParams", + }, + }, + ], + }, + { + name: "depositSharedLiquidity", + accounts: [ + { + name: "slPool", + isMut: true, + isSigner: false, + }, + { + name: "activeSpotPool", + isMut: true, + isSigner: false, + }, + { + name: "slPoolSpotLpVault", + isMut: true, + isSigner: false, + }, + { + name: "userQuoteTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "userBaseTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "spotPoolBaseVault", + isMut: true, + isSigner: false, + }, + { + name: "spotPoolQuoteVault", + isMut: true, + isSigner: false, + }, + { + name: "baseMint", + isMut: false, + isSigner: false, + }, + { + name: "quoteMint", + isMut: false, + isSigner: false, + }, + { + name: "spotPoolLpMint", + isMut: true, + isSigner: false, + }, + { + name: "userLpTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "userSlPoolPosition", + isMut: true, + isSigner: false, + }, + { + name: "user", + isMut: false, + isSigner: true, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "raydiumAuthority", + isMut: false, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram2022", + isMut: false, + isSigner: false, + }, + { + name: "cpSwapProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "params", + type: { + defined: "DepositSharedLiquidityParams", + }, + }, + ], + }, + { + name: "withdrawSharedLiquidity", + accounts: [ + { + name: "slPool", + isMut: true, + isSigner: false, + }, + { + name: "slPoolSigner", + isMut: false, + isSigner: false, + }, + { + name: "activeSpotPool", + isMut: true, + isSigner: false, + }, + { + name: "slPoolSpotLpVault", + isMut: true, + isSigner: false, + }, + { + name: "userQuoteTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "userBaseTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "spotPoolBaseVault", + isMut: true, + isSigner: false, + }, + { + name: "spotPoolQuoteVault", + isMut: true, + isSigner: false, + }, + { + name: "baseMint", + isMut: false, + isSigner: false, + }, + { + name: "quoteMint", + isMut: false, + isSigner: false, + }, + { + name: "spotPoolLpMint", + isMut: true, + isSigner: false, + }, + { + name: "userLpTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "userSlPoolPosition", + isMut: true, + isSigner: false, + }, + { + name: "user", + isMut: true, + isSigner: true, + }, + { + name: "feeReceiver", + isMut: false, + isSigner: false, + }, + { + name: "raydiumAuthority", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram2022", + isMut: false, + isSigner: false, + }, + { + name: "cpSwapProgram", + isMut: false, + isSigner: false, + }, + { + name: "memoProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "params", + type: { + defined: "WithdrawSharedLiquidityParams", + }, + }, + ], + }, + { + name: "initializeProposalWithLiquidity", + accounts: [ + { + name: "sharedLiquidityPool", + isMut: true, + isSigner: false, + }, + { + name: "proposalCreator", + isMut: false, + isSigner: true, + }, + { + name: "proposal", + isMut: true, + isSigner: false, + }, + { + name: "slPoolBaseVault", + isMut: true, + isSigner: false, + }, + { + name: "slPoolQuoteVault", + isMut: true, + isSigner: false, + }, + { + name: "slPoolSpotLpVault", + isMut: true, + isSigner: false, + }, + { + name: "baseMint", + isMut: false, + isSigner: false, + }, + { + name: "quoteMint", + isMut: false, + isSigner: false, + }, + { + name: "raydium", + accounts: [ + { + name: "spotPool", + isMut: true, + isSigner: false, + }, + { + name: "spotPoolBaseVault", + isMut: true, + isSigner: false, + }, + { + name: "spotPoolQuoteVault", + isMut: true, + isSigner: false, + }, + { + name: "lpMint", + isMut: true, + isSigner: false, + }, + { + name: "raydiumAuthority", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram2022", + isMut: false, + isSigner: false, + }, + { + name: "cpSwapProgram", + isMut: false, + isSigner: false, + }, + { + name: "memoProgram", + isMut: false, + isSigner: false, + }, + ], + }, + { + name: "conditionalVault", + accounts: [ + { + name: "question", + isMut: true, + isSigner: false, + }, + { + name: "baseVault", + isMut: true, + isSigner: false, + }, + { + name: "quoteVault", + isMut: true, + isSigner: false, + }, + { + name: "baseVaultUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "quoteVaultUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "conditionalVaultProgram", + isMut: false, + isSigner: false, + }, + { + name: "passBaseMint", + isMut: true, + isSigner: false, + }, + { + name: "failBaseMint", + isMut: true, + isSigner: false, + }, + { + name: "passQuoteMint", + isMut: true, + isSigner: false, + }, + { + name: "failQuoteMint", + isMut: true, + isSigner: false, + }, + { + name: "slPoolPassBaseVault", + isMut: true, + isSigner: true, + }, + { + name: "slPoolFailBaseVault", + isMut: true, + isSigner: true, + }, + { + name: "slPoolPassQuoteVault", + isMut: true, + isSigner: true, + }, + { + name: "slPoolFailQuoteVault", + isMut: true, + isSigner: true, + }, + { + name: "vaultEventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "slPoolSigner", + isMut: true, + isSigner: false, + }, + ], + }, + { + name: "amm", + accounts: [ + { + name: "passAmm", + isMut: true, + isSigner: false, + }, + { + name: "failAmm", + isMut: true, + isSigner: false, + }, + { + name: "passLpMint", + isMut: true, + isSigner: false, + }, + { + name: "failLpMint", + isMut: true, + isSigner: false, + }, + { + name: "slPoolPassLpAccount", + isMut: true, + isSigner: false, + }, + { + name: "slPoolFailLpAccount", + isMut: true, + isSigner: false, + }, + { + name: "passAmmVaultAtaBase", + isMut: true, + isSigner: false, + }, + { + name: "passAmmVaultAtaQuote", + isMut: true, + isSigner: false, + }, + { + name: "failAmmVaultAtaBase", + isMut: true, + isSigner: false, + }, + { + name: "failAmmVaultAtaQuote", + isMut: true, + isSigner: false, + }, + { + name: "proposal", + isMut: true, + isSigner: false, + }, + { + name: "proposalPassLpVault", + isMut: true, + isSigner: false, + }, + { + name: "proposalFailLpVault", + isMut: true, + isSigner: false, + }, + { + name: "ammProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "slPoolSigner", + isMut: false, + isSigner: false, + }, + ], + }, + { + name: "draftProposal", + isMut: true, + isSigner: false, + }, + { + name: "dao", + isMut: true, + isSigner: false, + }, + { + name: "autocratProgram", + isMut: false, + isSigner: false, + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "autocratEventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: "params", + type: { + defined: "InitializeProposalWithLiquidityParams", + }, + }, + ], + }, + { + name: "removeProposalLiquidity", + accounts: [ + { + name: "slPool", + isMut: true, + isSigner: false, + }, + { + name: "proposal", + isMut: false, + isSigner: false, + }, + { + name: "slPoolBaseVault", + isMut: true, + isSigner: false, + }, + { + name: "slPoolQuoteVault", + isMut: true, + isSigner: false, + }, + { + name: "slPoolSpotLpVault", + isMut: true, + isSigner: false, + }, + { + name: "baseMint", + isMut: false, + isSigner: false, + }, + { + name: "quoteMint", + isMut: false, + isSigner: false, + }, + { + name: "raydiumInitPoolStatic", + accounts: [ + { + name: "raydiumAuthority", + isMut: false, + isSigner: false, + }, + { + name: "createPoolFee", + isMut: true, + isSigner: false, + }, + { + name: "ammConfig", + isMut: true, + isSigner: false, + }, + { + name: "cpSwapProgram", + isMut: false, + isSigner: false, + }, + { + name: "rent", + isMut: false, + isSigner: false, + }, + { + name: "associatedTokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + ], + }, + { + name: "raydium", + accounts: [ + { + name: "activeSpotPool", + isMut: true, + isSigner: false, + }, + { + name: "activeSpotPoolLpMint", + isMut: true, + isSigner: false, + }, + { + name: "activeSpotPoolBaseVault", + isMut: true, + isSigner: false, + }, + { + name: "activeSpotPoolQuoteVault", + isMut: true, + isSigner: false, + }, + { + name: "tokenProgram2022", + isMut: false, + isSigner: false, + }, + { + name: "cpSwapProgram", + isMut: false, + isSigner: false, + }, + { + name: "memoProgram", + isMut: false, + isSigner: false, + }, + { + name: "nextSpotPool", + isMut: true, + isSigner: false, + }, + { + name: "nextSpotPoolLpMint", + isMut: true, + isSigner: false, + }, + { + name: "nextSpotPoolBaseVault", + isMut: true, + isSigner: false, + }, + { + name: "nextSpotPoolQuoteVault", + isMut: true, + isSigner: false, + }, + { + name: "nextSpotPoolObservationState", + isMut: true, + isSigner: false, + }, + { + name: "slPoolNextSpotLpVault", + isMut: true, + isSigner: false, + }, + { + name: "slPool", + isMut: false, + isSigner: false, + }, + { + name: "slPoolSigner", + isMut: false, + isSigner: false, + }, + { + name: "baseMint", + isMut: false, + isSigner: false, + }, + { + name: "quoteMint", + isMut: false, + isSigner: false, + }, + ], + }, + { + name: "conditionalVault", + accounts: [ + { + name: "question", + isMut: true, + isSigner: false, + }, + { + name: "baseVault", + isMut: true, + isSigner: false, + }, + { + name: "quoteVault", + isMut: true, + isSigner: false, + }, + { + name: "baseVaultUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "quoteVaultUnderlyingTokenAccount", + isMut: true, + isSigner: false, + }, + { + name: "conditionalVaultProgram", + isMut: false, + isSigner: false, + }, + { + name: "passBaseMint", + isMut: true, + isSigner: false, + }, + { + name: "failBaseMint", + isMut: true, + isSigner: false, + }, + { + name: "passQuoteMint", + isMut: true, + isSigner: false, + }, + { + name: "failQuoteMint", + isMut: true, + isSigner: false, + }, + { + name: "slPoolPassBaseVault", + isMut: true, + isSigner: false, + }, + { + name: "slPoolFailBaseVault", + isMut: true, + isSigner: false, + }, + { + name: "slPoolPassQuoteVault", + isMut: true, + isSigner: false, + }, + { + name: "slPoolFailQuoteVault", + isMut: true, + isSigner: false, + }, + { + name: "vaultEventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "slPoolSigner", + isMut: true, + isSigner: false, + }, + ], + }, + { + name: "ammm", + accounts: [ + { + name: "passAmm", + isMut: true, + isSigner: false, + }, + { + name: "failAmm", + isMut: true, + isSigner: false, + }, + { + name: "passLpMint", + isMut: true, + isSigner: false, + }, + { + name: "failLpMint", + isMut: true, + isSigner: false, + }, + { + name: "slPoolPassLpAccount", + isMut: true, + isSigner: false, + }, + { + name: "slPoolFailLpAccount", + isMut: true, + isSigner: false, + }, + { + name: "passAmmVaultAtaBase", + isMut: true, + isSigner: false, + }, + { + name: "passAmmVaultAtaQuote", + isMut: true, + isSigner: false, + }, + { + name: "failAmmVaultAtaBase", + isMut: true, + isSigner: false, + }, + { + name: "failAmmVaultAtaQuote", + isMut: true, + isSigner: false, + }, + { + name: "ammProgram", + isMut: false, + isSigner: false, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "slPoolSigner", + isMut: false, + isSigner: false, + }, + ], + }, + { + name: "systemProgram", + isMut: false, + isSigner: false, + }, + { + name: "tokenProgram", + isMut: false, + isSigner: false, + }, + { + name: "payer", + isMut: true, + isSigner: true, + }, + { + name: "eventAuthority", + isMut: false, + isSigner: false, + }, + { + name: "program", + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + ], + accounts: [ + { + name: "draftProposal", + type: { + kind: "struct", + fields: [ + { + name: "sharedLiquidityPool", + type: "publicKey", + }, + { + name: "baseMint", + type: "publicKey", + }, + { + name: "instruction", + type: { + defined: "ProposalInstruction", + }, + }, + { + name: "status", + type: { + defined: "DraftProposalStatus", + }, + }, + { + name: "stakedTokenAmount", + docs: [ + "The amount of tokens that have been staked on this draft proposal", + ], + type: "u64", + }, + { + name: "stakedTokenVault", + docs: ["The vault that holds the staked tokens"], + type: "publicKey", + }, + { + name: "nonce", + docs: ["The nonce used to create this draft proposal PDA"], + type: "u64", + }, + { + name: "pdaBump", + type: "u8", + }, + ], + }, + }, + { + name: "liquidityPosition", + type: { + kind: "struct", + fields: [ + { + name: "owner", + docs: ["The owner of this position"], + type: "publicKey", + }, + { + name: "pool", + docs: ["The shared liquidity pool this position belongs to"], + type: "publicKey", + }, + { + name: "underlyingSpotLpShares", + docs: [ + "The amount of underlying spot LP shares this position represents", + ], + type: "u64", + }, + { + name: "bump", + docs: ["The PDA bump"], + type: "u8", + }, + ], + }, + }, + { + name: "sharedLiquidityPool", + type: { + kind: "struct", + fields: [ + { + name: "pdaBump", + docs: ["The PDA bump."], + type: "u8", + }, + { + name: "dao", + docs: ["The DAO."], + type: "publicKey", + }, + { + name: "baseMint", + docs: ["The base mint."], + type: "publicKey", + }, + { + name: "quoteMint", + docs: ["The quote mint."], + type: "publicKey", + }, + { + name: "slPoolSigner", + docs: [ + "The signer of this pool, used because Raydium pools need a SOL payer and this PDA can't hold SOL.", + ], + type: "publicKey", + }, + { + name: "slPoolSignerBump", + docs: ["The pda bump of the signer."], + type: "u8", + }, + { + name: "slPoolBaseVault", + docs: [ + "Holds the base tokens for the shared liquidity pool when it's moving liquidity around.", + ], + type: "publicKey", + }, + { + name: "slPoolQuoteVault", + docs: [ + "Holds the quote tokens for the shared liquidity pool when it's moving liquidity around.", + ], + type: "publicKey", + }, + { + name: "slPoolSpotLpVault", + docs: ["Holds the LP tokens for the shared liquidity pool."], + type: "publicKey", + }, + { + name: "activeProposal", + docs: ["The proposal that's using liquidity from this pool."], + type: { + option: "publicKey", + }, + }, + { + name: "proposalStakeRateThresholdBps", + docs: [ + "The percentage of a token's supply, in basis points, that needs to be", + "staked to a draft proposal before it can be initialized.", + ], + type: "u16", + }, + { + name: "seqNum", + docs: [ + "The sequence number of this shared liquidity pool. Useful for sorting events.", + ], + type: "u64", + }, + { + name: "activeSpotPool", + docs: [ + "The current Raydium spot pool. Changes when a proposal is removed.", + ], + type: "publicKey", + }, + { + name: "activeSpotPoolIndex", + docs: [ + "The index of the current Raydium spot pool. Starts at 0 and increments by 1 for each new spot pool.", + ], + type: "u32", + }, + { + name: "isBaseToken0", + docs: [ + "Whether the base token is token0 in the current Raydium spot pool (otherwise it's token1).", + ], + type: "bool", + }, + ], + }, + }, + { + name: "stakeRecord", + type: { + kind: "struct", + fields: [ + { + name: "staker", + type: "publicKey", + }, + { + name: "amount", + type: "u64", + }, + ], + }, + }, + ], + types: [ + { + name: "DepositSharedLiquidityParams", + type: { + kind: "struct", + fields: [ + { + name: "lpTokenAmount", + docs: ["The amount of LP tokens to mint"], + type: "u64", + }, + { + name: "maxQuoteTokenAmount", + docs: ["The maximum amount of quote tokens to deposit"], + type: "u64", + }, + { + name: "maxBaseTokenAmount", + docs: ["The maximum amount of base tokens to deposit"], + type: "u64", + }, + ], + }, + }, + { + name: "InitializeDraftProposalParams", + type: { + kind: "struct", + fields: [ + { + name: "instruction", + type: { + defined: "ProposalInstruction", + }, + }, + { + name: "draftProposalNonce", + docs: [ + "The nonce for the draft proposal, not used for anything aside from the PDA", + ], + type: "u64", + }, + ], + }, + }, + { + name: "InitializeProposalWithLiquidityParams", + type: { + kind: "struct", + fields: [ + { + name: "nonce", + type: "u64", + }, + ], + }, + }, + { + name: "InitializeSharedLiquidityPoolParams", + type: { + kind: "struct", + fields: [ + { + name: "baseAmount", + type: "u64", + }, + { + name: "quoteAmount", + type: "u64", + }, + { + name: "proposalStakeRateThresholdBps", + type: "u16", + }, + ], + }, + }, + { + name: "StakeToDraftProposalParams", + type: { + kind: "struct", + fields: [ + { + name: "amount", + type: "u64", + }, + ], + }, + }, + { + name: "UnstakeFromDraftProposalParams", + type: { + kind: "struct", + fields: [ + { + name: "amount", + type: "u64", + }, + ], + }, + }, + { + name: "WithdrawSharedLiquidityParams", + type: { + kind: "struct", + fields: [ + { + name: "lpTokenAmount", + docs: ["The amount of LP tokens to withdraw"], + type: "u64", + }, + { + name: "minimumToken0Amount", + docs: ["The minimum amount of token0 to receive"], + type: "u64", + }, + { + name: "minimumToken1Amount", + docs: ["The minimum amount of token1 to receive"], + type: "u64", + }, + ], + }, + }, + { + name: "ProposalAccount", + type: { + kind: "struct", + fields: [ + { + name: "pubkey", + type: "publicKey", + }, + { + name: "isSigner", + type: "bool", + }, + { + name: "isWritable", + type: "bool", + }, + ], + }, + }, + { + name: "ProposalInstruction", + type: { + kind: "struct", + fields: [ + { + name: "programId", + type: "publicKey", + }, + { + name: "accounts", + type: { + vec: { + defined: "ProposalAccount", + }, + }, + }, + { + name: "data", + type: "bytes", + }, + ], + }, + }, + { + name: "DraftProposalStatus", + type: { + kind: "enum", + variants: [ + { + name: "Draft", + }, + { + name: "Initialized", + }, + ], + }, + }, + ], + errors: [ + { + code: 6000, + name: "InsufficientStake", + msg: "Insufficient stake amount", + }, + { + code: 6001, + name: "ProposalNotFinalized", + msg: "Proposal is not finalized", + }, + { + code: 6002, + name: "NoLpTokensToRemove", + msg: "No LP tokens to remove from AMM", + }, + { + code: 6003, + name: "NoTokensFromAmm", + msg: "No tokens received from AMM removal", + }, + { + code: 6004, + name: "InsufficientReservesReturned", + msg: "Insufficient reserves returned to spot AMM (less than 99.5%)", + }, + { + code: 6005, + name: "PoolInUse", + msg: "Pool is currently being used by an active proposal", + }, + { + code: 6006, + name: "InsufficientLpShares", + msg: "User does not have enough LP shares to withdraw", + }, + { + code: 6007, + name: "SlippageExceeded", + msg: "Slippage exceeded minimum token amounts", + }, + { + code: 6008, + name: "NoLpTokensInPool", + msg: "No LP tokens in pool's LP token account", + }, + { + code: 6009, + name: "NotEnoughLpTokens", + msg: "Not enough LP tokens to provide liquidity to proposal", + }, + { + code: 6010, + name: "InsufficientFunds", + msg: "Insufficient funds", + }, + { + code: 6011, + name: "NoActiveProposal", + msg: "No active proposal", + }, + { + code: 6012, + name: "ProposalNotInDraftStatus", + msg: "Proposal is not in draft status", + }, + { + code: 6013, + name: "ProposalAlreadyActive", + msg: "Proposal already active", + }, + { + code: 6014, + name: "AmmAlreadyHasLiquidity", + msg: "AMM already has liquidity", + }, + { + code: 6015, + name: "QuestionAlreadyResolved", + msg: "Question already resolved", + }, + ], +}; diff --git a/sdk/src/v0.5/types/utils.ts b/sdk/src/v0.5/types/utils.ts new file mode 100644 index 000000000..c878debe7 --- /dev/null +++ b/sdk/src/v0.5/types/utils.ts @@ -0,0 +1,3 @@ +export type LowercaseKeys = { + [K in keyof T as Lowercase]: T[K]; +}; diff --git a/sdk/src/v0.5/utils/cu.ts b/sdk/src/v0.5/utils/cu.ts new file mode 100644 index 000000000..b55cbac95 --- /dev/null +++ b/sdk/src/v0.5/utils/cu.ts @@ -0,0 +1,11 @@ +export const MaxCUs = { + initializeDao: 40_000, + createIdempotent: 25_000, + initializeConditionalVault: 45_000, + mintConditionalTokens: 35_000, + initializeAmm: 120_000, + addLiquidity: 120_000, + initializeProposal: 60_000, +}; + +export const DEFAULT_CU_PRICE = 1; diff --git a/sdk/src/v0.5/utils/filters.ts b/sdk/src/v0.5/utils/filters.ts new file mode 100644 index 000000000..945f77314 --- /dev/null +++ b/sdk/src/v0.5/utils/filters.ts @@ -0,0 +1,21 @@ +import { GetProgramAccountsFilter, PublicKey } from "@solana/web3.js"; + +export const filterPositionsByUser = ( + userAddr: PublicKey +): GetProgramAccountsFilter => ({ + memcmp: { + offset: 8, // discriminator + bytes: userAddr.toBase58(), + }, +}); + +export const filterPositionsByAmm = ( + ammAddr: PublicKey +): GetProgramAccountsFilter => ({ + memcmp: { + offset: + 8 + // discriminator + 32, // user address + bytes: ammAddr.toBase58(), + }, +}); diff --git a/sdk/src/v0.5/utils/index.ts b/sdk/src/v0.5/utils/index.ts new file mode 100644 index 000000000..cb5d012e2 --- /dev/null +++ b/sdk/src/v0.5/utils/index.ts @@ -0,0 +1,40 @@ +export * from "./filters.js"; +export * from "./pda.js"; +export * from "./priceMath.js"; +export * from "./metadata.js"; +export * from "./cu.js"; +export * from "./instruction.js"; + +import { AccountMeta, ComputeBudgetProgram, PublicKey } from "@solana/web3.js"; + +export enum PriorityFeeTier { + NORMAL = 35, + HIGH = 3571, + TURBO = 357142, +} + +export const addComputeUnits = (num_units: number = 1_400_000) => + ComputeBudgetProgram.setComputeUnitLimit({ + units: num_units, + }); + +export const addPriorityFee = (pf: number) => + ComputeBudgetProgram.setComputeUnitPrice({ + microLamports: pf, + }); + +export const pubkeyToAccountInfo = ( + pubkey: PublicKey, + isWritable: boolean, + isSigner = false +): AccountMeta => { + return { + pubkey: pubkey, + isSigner: isSigner, + isWritable: isWritable, + }; +}; + +export async function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/sdk/src/v0.5/utils/instruction.ts b/sdk/src/v0.5/utils/instruction.ts new file mode 100644 index 000000000..f18e48834 --- /dev/null +++ b/sdk/src/v0.5/utils/instruction.ts @@ -0,0 +1,16 @@ +import * as anchor from "@coral-xyz/anchor"; +import { TransactionInstruction } from "@solana/web3.js"; + +export class InstructionUtils { + public static async getInstructions( + ...methodBuilders: any[] + ): Promise { + let instructions: TransactionInstruction[] = []; + + for (const methodBuilder of methodBuilders) { + instructions.push(...(await methodBuilder.transaction()).instructions); + } + + return instructions; + } +} diff --git a/sdk/src/v0.5/utils/metadata.ts b/sdk/src/v0.5/utils/metadata.ts new file mode 100644 index 000000000..922a89f37 --- /dev/null +++ b/sdk/src/v0.5/utils/metadata.ts @@ -0,0 +1,35 @@ +import BN from "bn.js"; +import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; +import { Connection } from "@solana/web3.js"; +import { bundlrUploader } from "@metaplex-foundation/umi-uploader-bundlr"; +import { UmiPlugin } from "@metaplex-foundation/umi"; + +export const assetImageMap: Record = { + fMETA: "https://arweave.net/tGxvOjMZw7B0qHsdCcIMO57oH5g5OaItOZdXo3BXKz8", + fUSDC: "https://arweave.net/DpvxeAyVbaoivhIVCLjdf566k2SwVn0YVBL0sTOezWk", + pMETA: "https://arweave.net/iuqi7PRRESdDxj1oRyk2WzR90_zdFcmZsuWicv3XGfs", + pUSDC: "https://arweave.net/e4IO7F59F_RKCiuB--_ABPot7Qh1yFsGkWzVhcXuKDU", +}; + +// Upload some JSON, returning its URL +export const uploadConditionalTokenMetadataJson = async ( + connection: Connection, + identityPlugin: UmiPlugin, + proposalNumber: number, + symbol: string + // proposal: BN, + // conditionalToken: string, + // image: string +): Promise => { + // use bundlr, targeting arweave + const umi = createUmi(connection); + umi.use(bundlrUploader()); + umi.use(identityPlugin); + + return umi.uploader.uploadJson({ + name: `Proposal ${proposalNumber}: ${symbol}`, + image: assetImageMap[symbol], + symbol, + description: "A conditional token for use in futarchy.", + }); +}; diff --git a/sdk/src/v0.5/utils/pda.ts b/sdk/src/v0.5/utils/pda.ts new file mode 100644 index 000000000..1df1c1dc1 --- /dev/null +++ b/sdk/src/v0.5/utils/pda.ts @@ -0,0 +1,323 @@ +import { AccountMeta, PublicKey } from "@solana/web3.js"; +import { utils } from "@coral-xyz/anchor"; +import { + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, +} from "@solana/spl-token"; +import BN from "bn.js"; +import { + fromWeb3JsPublicKey, + toWeb3JsPublicKey, +} from "@metaplex-foundation/umi-web3js-adapters"; +import { + DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID, + MPL_TOKEN_METADATA_PROGRAM_ID, + RAYDIUM_CP_SWAP_PROGRAM_ID, + SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, +} from "../constants.js"; +import { LAUNCHPAD_PROGRAM_ID } from "../constants.js"; + +export const getEventAuthorityAddr = (programId: PublicKey) => { + return PublicKey.findProgramAddressSync( + [Buffer.from("__event_authority")], + programId + ); +}; + +export const getQuestionAddr = ( + programId: PublicKey, + questionId: Uint8Array, + oracle: PublicKey, + numOutcomes: number +) => { + if (questionId.length != 32) { + throw new Error("questionId must be 32 bytes"); + } + + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("question"), + Buffer.from(questionId), + oracle.toBuffer(), + new BN(numOutcomes).toArrayLike(Buffer, "le", 1), + ], + programId + ); +}; + +export const getVaultAddr = ( + programId: PublicKey, + question: PublicKey, + underlyingTokenMint: PublicKey +) => { + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("conditional_vault"), + question.toBuffer(), + underlyingTokenMint.toBuffer(), + ], + programId + ); +}; + +export const getConditionalTokenMintAddr = ( + programId: PublicKey, + vault: PublicKey, + index: number +) => { + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("conditional_token"), + vault.toBuffer(), + new BN(index).toArrayLike(Buffer, "le", 1), + ], + programId + ); +}; + +export const getDownAndUpMintAddrs = ( + programId: PublicKey, + vault: PublicKey +): { down: PublicKey; up: PublicKey } => { + return { + down: getConditionalTokenMintAddr(programId, vault, 0)[0], + up: getConditionalTokenMintAddr(programId, vault, 1)[0], + }; +}; + +export const getFailAndPassMintAddrs = ( + programId: PublicKey, + vault: PublicKey +): { fail: PublicKey; pass: PublicKey } => { + return { + fail: getConditionalTokenMintAddr(programId, vault, 0)[0], + pass: getConditionalTokenMintAddr(programId, vault, 1)[0], + }; +}; + +export const getMetadataAddr = (mint: PublicKey) => { + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("metadata"), + MPL_TOKEN_METADATA_PROGRAM_ID.toBuffer(), + mint.toBuffer(), + ], + MPL_TOKEN_METADATA_PROGRAM_ID + ); +}; + +export const getDaoTreasuryAddr = ( + programId: PublicKey, + dao: PublicKey +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync([dao.toBuffer()], programId); +}; + +export const getProposalAddr = ( + programId: PublicKey, + proposer: PublicKey, + nonce: BN +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("proposal"), + proposer.toBuffer(), + nonce.toArrayLike(Buffer, "le", 8), + ], + programId + ); +}; + +export const getAmmAddr = ( + programId: PublicKey, + baseMint: PublicKey, + quoteMint: PublicKey +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("amm__"), + baseMint.toBuffer(), + quoteMint.toBuffer(), + ], + programId + ); +}; + +export const getAmmLpMintAddr = ( + programId: PublicKey, + amm: PublicKey +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [utils.bytes.utf8.encode("amm_lp_mint"), amm.toBuffer()], + programId + ); +}; + +export function getLaunchAddr( + programId: PublicKey = LAUNCHPAD_PROGRAM_ID, + tokenMint: PublicKey +): [PublicKey, number] { + return PublicKey.findProgramAddressSync( + [Buffer.from("launch"), tokenMint.toBuffer()], + programId + ); +} + +export const getLaunchSignerAddr = ( + programId: PublicKey = LAUNCHPAD_PROGRAM_ID, + launch: PublicKey +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [Buffer.from("launch_signer"), launch.toBuffer()], + programId + ); +}; + +export const getFundingRecordAddr = ( + programId: PublicKey = LAUNCHPAD_PROGRAM_ID, + launch: PublicKey, + funder: PublicKey +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [Buffer.from("funding_record"), launch.toBuffer(), funder.toBuffer()], + programId + ); +}; + +export const getLaunchDaoAddr = ( + programId: PublicKey = LAUNCHPAD_PROGRAM_ID, + launch: PublicKey +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [Buffer.from("launch_dao"), launch.toBuffer()], + programId + ); +}; + +export const getLiquidityPoolAddr = ( + programId: PublicKey = LAUNCHPAD_PROGRAM_ID, + dao: PublicKey +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [Buffer.from("pool_state"), dao.toBuffer()], + programId + ); +}; + +export const getSharedLiquidityPoolAddr = ( + programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, + dao: PublicKey, + creator: PublicKey, + proposalStakeRateThresholdBps: number +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [ + Buffer.from("sl_pool"), + dao.toBuffer(), + creator.toBuffer(), + new BN(proposalStakeRateThresholdBps).toArrayLike(Buffer, "le", 2), + ], + programId + ); +}; + +export const getSlPoolPositionAddr = ( + programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, + slPool: PublicKey, + user: PublicKey +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [Buffer.from("sl_pool_position"), slPool.toBuffer(), user.toBuffer()], + programId + ); +}; + +export const getRaydiumCpmmLpMintAddr = ( + poolState: PublicKey, + isDevnet: boolean +): [PublicKey, number] => { + const programId = isDevnet + ? DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID + : RAYDIUM_CP_SWAP_PROGRAM_ID; + return PublicKey.findProgramAddressSync( + [Buffer.from("pool_lp_mint"), poolState.toBuffer()], + programId + ); +}; + +export const getRaydiumCpmmPoolVaultAddr = ( + poolState: PublicKey, + token: PublicKey, + isDevnet: boolean +): [PublicKey, number] => { + const programId = isDevnet + ? DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID + : RAYDIUM_CP_SWAP_PROGRAM_ID; + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("pool_vault"), + poolState.toBuffer(), + token.toBuffer(), + ], + programId + ); +}; + +export const getRaydiumCpmmObservationStateAddr = ( + poolState: PublicKey, + isDevnet: boolean +): [PublicKey, number] => { + const programId = isDevnet + ? DEVNET_RAYDIUM_CP_SWAP_PROGRAM_ID + : RAYDIUM_CP_SWAP_PROGRAM_ID; + return PublicKey.findProgramAddressSync( + [utils.bytes.utf8.encode("observation"), poolState.toBuffer()], + programId + ); +}; + +export const getSharedLiquidityPoolSignerAddr = ( + programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, + slPool: PublicKey +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [Buffer.from("sl_pool_signer"), slPool.toBuffer()], + programId + ); +}; + +export const getSpotPoolAddr = ( + programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, + slPool: PublicKey, + index: number +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [ + utils.bytes.utf8.encode("spot_pool"), + slPool.toBuffer(), + new BN(index).toArrayLike(Buffer, "le", 4), + ], + programId + ); +}; + +export const getDraftProposalAddr = ( + programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, + nonce: BN +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [Buffer.from("draft_proposal"), nonce.toArrayLike(Buffer, "le", 8)], + programId + ); +}; + +export const getStakeRecordAddr = ( + programId: PublicKey = SHARED_LIQUIDITY_MANAGER_PROGRAM_ID, + draftProposal: PublicKey, + staker: PublicKey +): [PublicKey, number] => { + return PublicKey.findProgramAddressSync( + [Buffer.from("stake_record"), draftProposal.toBuffer(), staker.toBuffer()], + programId + ); +}; diff --git a/sdk/src/v0.5/utils/priceMath.ts b/sdk/src/v0.5/utils/priceMath.ts new file mode 100644 index 000000000..cebf00c36 --- /dev/null +++ b/sdk/src/v0.5/utils/priceMath.ts @@ -0,0 +1,198 @@ +import BN from "bn.js"; +import { Amm } from "../types/index.js"; +import { SwapType } from "../AmmClient.js"; +import { AmmMath as V3AmmMath } from "../../v0.3/utils/ammMath.js"; + +const BN_TEN = new BN(10); +const PRICE_SCALE = BN_TEN.pow(new BN(12)); +const PRICE_SCALE_NUMBER = 1e12; + +export type AddLiquiditySimulation = { + baseAmount: BN; + quoteAmount: BN; + expectedLpTokens: BN; + minLpTokens?: BN; + maxBaseAmount?: BN; +}; + +export type SwapSimulation = { + expectedOut: BN; + newBaseReserves: BN; + newQuoteReserves: BN; + minExpectedOut?: BN; +}; + +export type RemoveLiquiditySimulation = { + expectedBaseOut: BN; + expectedQuoteOut: BN; + minBaseOut?: BN; + minQuoteOut?: BN; +}; + +export class AmmMath { + // Re-export common methods from v0.3 + public static getHumanPriceFromReserves = V3AmmMath.getHumanPriceFromReserves; + public static getAmmPriceFromReserves = V3AmmMath.getAmmPriceFromReserves; + public static getChainAmount = V3AmmMath.getChainAmount; + public static getHumanAmount = V3AmmMath.getHumanAmount; + public static getAmmPrice = V3AmmMath.getAmmPrice; + public static getAmmPrices = V3AmmMath.getAmmPrices; + public static scale = V3AmmMath.scale; + public static addSlippage = V3AmmMath.addSlippage; + public static subtractSlippage = V3AmmMath.subtractSlippage; + public static simulateAddLiquidity = V3AmmMath.simulateAddLiquidity; + public static simulateRemoveLiquidity = V3AmmMath.simulateRemoveLiquidity; + + public static getHumanPrice( + ammPrice: BN, + baseDecimals: number, + quoteDecimals: number + ): number { + const decimalScalar = BN_TEN.pow( + new BN(quoteDecimals - baseDecimals).abs() + ); + const price1e12 = + quoteDecimals > baseDecimals + ? ammPrice.div(decimalScalar) + : ammPrice.mul(decimalScalar); + + // in case the BN is too large to cast to number, we try + try { + return price1e12.toNumber() / 1e12; + } catch (e) { + // BN tried to cast into number larger than 53 bits so we we do division via BN methods first, then cast to number(so it is smaller before the cast) + return price1e12.div(new BN(1e12)).toNumber(); + } + } + + public static getTwap(amm: Amm): BN { + return amm.oracle.aggregator.div( + amm.oracle.lastUpdatedSlot.sub(amm.createdAtSlot) + ); + } + + public static simulateSwapInner( + inputAmount: BN, + inputReserves: BN, + outputReserves: BN + ): BN { + if (inputReserves.eqn(0) || outputReserves.eqn(0)) { + throw new Error("reserves must be non-zero"); + } + + let inputAmountWithFee: BN = inputAmount.muln(990); + + let numerator: BN = inputAmountWithFee.mul(outputReserves); + let denominator: BN = inputReserves.muln(1000).add(inputAmountWithFee); + + return numerator.div(denominator); + } + + public static simulateSwap( + inputAmount: BN, + swapType: SwapType, + baseReserves: BN, + quoteReserves: BN, + slippageBps?: BN + ): SwapSimulation { + let inputReserves: BN, outputReserves: BN; + if (swapType.buy) { + inputReserves = quoteReserves; + outputReserves = baseReserves; + } else { + inputReserves = baseReserves; + outputReserves = quoteReserves; + } + + let expectedOut = this.simulateSwapInner( + inputAmount, + inputReserves, + outputReserves + ); + + let minExpectedOut; + if (slippageBps) { + minExpectedOut = AmmMath.subtractSlippage(expectedOut, slippageBps); + } + + let newBaseReserves: BN, newQuoteReserves: BN; + if (swapType.buy) { + newBaseReserves = baseReserves.sub(expectedOut); + newQuoteReserves = quoteReserves.add(inputAmount); + } else { + newBaseReserves = baseReserves.add(inputAmount); + newQuoteReserves = quoteReserves.sub(expectedOut); + } + + return { + expectedOut, + newBaseReserves, + newQuoteReserves, + minExpectedOut, + }; + } + + /** + * Calculates the optimal swap amount and mergeable tokens without using square roots. + * @param userBalanceIn BN – Tokens that a user wants to dispose of. + * @param ammReserveIn BN – Amount of tokens in the AMM of the token that the user wants to dispose of. + * @param ammReserveOut BN – Amount of tokens in the AMM of the token that the user wants to receive. + * @returns An object containing the optimal swap amount, expected quote received, and expected mergeable tokens. + */ + + public static calculateOptimalSwapForMerge( + userBalanceIn: BN, + ammReserveIn: BN, + ammReserveOut: BN, + slippageBps: BN + ): { + optimalSwapAmount: BN; + userInAfterSwap: BN; + expectedOut: BN; + minimumExpectedOut: BN; + } { + // essentially, we want to calculate the swap amount so that the remaining user balance = received token amount + + // solve this system of equations for swapAmount, outputAmount (we only care about swap amount tho) + // (baseReserve + swapAmount) * (quoteReserve - outputAmount) = baseReserve * quoteReserve + // baseAmount - swapAmount = outputAmount + + //solve equation + // (baseReserve + .99*swapAmount) * (quoteReserve - (userTokens - swapAmount)) = baseReserve * quoteReserve + // multiplying out the left hand side and subtracting baseReserve * quoteReserve from both sides yields the following: + // baseReserve*quoteReserve - baseReserve*userTokens + baseReserve*swapAmount + .99*swapAmount*quoteReserve - .99*swapAmount*userTokens + .99*swapAmount^2 = baseReserve*quoteReserve + // .99*swapAmount^2 + baseReserve*swapAmount + .99*swapAmount*quoteReserve - baseReserve*userTokens - .99*swapAmount*userTokens = 0 + // in the quadratic equation, a = .99, b = (baseReserve + .99*quoteReserve - .99*userTokens), c = -baseReserve*userTokens + // x = (-b + sqrt(b^2 - 4ac)) / 2a + + let a = 0.99; + let b = + Number(ammReserveIn) + + 0.99 * Number(ammReserveOut) - + 0.99 * Number(userBalanceIn); + let c = -Number(ammReserveIn) * Number(userBalanceIn); + + let x = (-b + Math.sqrt(b ** 2 - 4 * a * c)) / (2 * a); + //this should mathematically return a positive number assuming userBalanceIn, ammReserveIn, and ammReserveOut are all positive (which they should be) + // -b + Math.sqrt(b ** 2 - 4 * a * c) > 0 because -4*a*c > 0 and sqrt(b**2 + positive number) > b + + const swapAmount = x; + + let expectedOut = this.simulateSwapInner( + new BN(swapAmount), + ammReserveIn, + ammReserveOut + ); + let minimumExpectedOut = + Number(expectedOut) - (Number(expectedOut) * Number(slippageBps)) / 10000; + return { + optimalSwapAmount: new BN(swapAmount), + userInAfterSwap: new BN(Number(userBalanceIn) - swapAmount), + expectedOut: expectedOut, + minimumExpectedOut: new BN(minimumExpectedOut), + }; + } +} + +// Add backwards compatibility alias +export { AmmMath as PriceMath }; diff --git a/sdk/tsconfig.json b/sdk/tsconfig.json index bd370bfbb..d2b651ade 100644 --- a/sdk/tsconfig.json +++ b/sdk/tsconfig.json @@ -6,7 +6,8 @@ ], "paths": { "@metadaoproject/futarchy/v0.3": ["./dist/v0.3/types/index.d.ts"], - "@metadaoproject/futarchy/v0.4": ["./dist/v0.4/types/index.d.ts"] + "@metadaoproject/futarchy/v0.4": ["./dist/v0.4/types/index.d.ts"], + "@metadaoproject/futarchy/v0.5": ["./dist/v0.5/types/index.d.ts"] }, "typeRoots": [ "./node_modules/@types" @@ -27,7 +28,8 @@ "include": [ "src/*", "src/v0.3/*", - "src/v0.4/*" + "src/v0.4/*", + "src/v0.5/*" ], "exclude": [ "node_modules", diff --git a/sdk/yarn.lock b/sdk/yarn.lock index 38b070f7f..67ef13297 100644 --- a/sdk/yarn.lock +++ b/sdk/yarn.lock @@ -751,13 +751,6 @@ "@solana/codecs-core" "2.0.0-experimental.8618508" "@solana/codecs-numbers" "2.0.0-experimental.8618508" -"@solana/spl-memo@^0.2.5": - version "0.2.5" - resolved "https://registry.yarnpkg.com/@solana/spl-memo/-/spl-memo-0.2.5.tgz#a7828cdd1e810ff77c7c015ac97dfa166d0651fe" - integrity sha512-0Zx5t3gAdcHlRTt2O3RgGlni1x7vV7Xq7j4z9q8kKOMgU03PyoTbFQ/BSYCcICHzkaqD7ZxAiaJ6dlXolg01oA== - dependencies: - buffer "^6.0.3" - "@solana/spl-token-metadata@^0.1.2": version "0.1.2" resolved "https://registry.yarnpkg.com/@solana/spl-token-metadata/-/spl-token-metadata-0.1.2.tgz#876e13432bd2960bd3cac16b9b0af63e69e37719" diff --git a/tests/amm/integration/ammLifecycle.test.ts b/tests/amm/integration/ammLifecycle.test.ts index 2fa3ca2dd..f6363fc3c 100644 --- a/tests/amm/integration/ammLifecycle.test.ts +++ b/tests/amm/integration/ammLifecycle.test.ts @@ -2,7 +2,7 @@ import { AmmClient, getAmmAddr, getAmmLpMintAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { Keypair, PublicKey } from "@solana/web3.js"; import { assert } from "chai"; import { diff --git a/tests/amm/unit/addLiquidity.test.ts b/tests/amm/unit/addLiquidity.test.ts index e9af8f8d5..ef41e671b 100644 --- a/tests/amm/unit/addLiquidity.test.ts +++ b/tests/amm/unit/addLiquidity.test.ts @@ -2,7 +2,7 @@ import { AmmClient, getAmmAddr, getAmmLpMintAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { Keypair, PublicKey } from "@solana/web3.js"; import { assert } from "chai"; import { diff --git a/tests/amm/unit/crankThatTwap.test.ts b/tests/amm/unit/crankThatTwap.test.ts index 0ee60fdf9..67981de8d 100644 --- a/tests/amm/unit/crankThatTwap.test.ts +++ b/tests/amm/unit/crankThatTwap.test.ts @@ -1,4 +1,4 @@ -import { AmmClient, AmmMath, PriceMath } from "@metadaoproject/futarchy/v0.4"; +import { AmmClient, AmmMath, PriceMath } from "@metadaoproject/futarchy/v0.5"; import { ComputeBudgetProgram, Keypair, PublicKey } from "@solana/web3.js"; import { assert } from "chai"; import { createMint, mintTo } from "spl-token-bankrun"; diff --git a/tests/amm/unit/initializeAmm.test.ts b/tests/amm/unit/initializeAmm.test.ts index 48636b1ec..fb1cc1576 100644 --- a/tests/amm/unit/initializeAmm.test.ts +++ b/tests/amm/unit/initializeAmm.test.ts @@ -3,7 +3,7 @@ import { getAmmAddr, getAmmLpMintAddr, PriceMath, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { Keypair, PublicKey } from "@solana/web3.js"; import { assert } from "chai"; import { createMint } from "spl-token-bankrun"; diff --git a/tests/amm/unit/swap.test.ts b/tests/amm/unit/swap.test.ts index f308d3493..87bccb234 100644 --- a/tests/amm/unit/swap.test.ts +++ b/tests/amm/unit/swap.test.ts @@ -3,7 +3,7 @@ import { AmmMath, getAmmAddr, getAmmLpMintAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { Keypair, PublicKey } from "@solana/web3.js"; import { assert } from "chai"; import { diff --git a/tests/autocrat/autocrat.ts b/tests/autocrat/autocrat.ts index 1c2db8089..087e0934c 100644 --- a/tests/autocrat/autocrat.ts +++ b/tests/autocrat/autocrat.ts @@ -43,12 +43,12 @@ import { getVaultAddr, AmmMath, getEventAuthorityAddr, -} from "@metadaoproject/futarchy/v0.4"; -import { PriceMath } from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; +import { PriceMath } from "@metadaoproject/futarchy/v0.5"; import { AutocratClient, ConditionalVaultClient, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { ComputeBudgetInstruction, ComputeBudgetProgram, diff --git a/tests/conditionalVault/unit/addMetadataToConditionalTokens.test.ts b/tests/conditionalVault/unit/addMetadataToConditionalTokens.test.ts index 023324519..af85ba7e9 100644 --- a/tests/conditionalVault/unit/addMetadataToConditionalTokens.test.ts +++ b/tests/conditionalVault/unit/addMetadataToConditionalTokens.test.ts @@ -3,7 +3,7 @@ import { ConditionalVaultClient, getConditionalTokenMintAddr, getMetadataAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { Keypair, PublicKey } from "@solana/web3.js"; import { assert } from "chai"; import { createMint } from "spl-token-bankrun"; diff --git a/tests/conditionalVault/unit/initializeConditionalVault.test.ts b/tests/conditionalVault/unit/initializeConditionalVault.test.ts index 7c9ac1531..228c80ce7 100644 --- a/tests/conditionalVault/unit/initializeConditionalVault.test.ts +++ b/tests/conditionalVault/unit/initializeConditionalVault.test.ts @@ -2,7 +2,7 @@ import { ConditionalVaultClient, getVaultAddr, getConditionalTokenMintAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { sha256 } from "@metadaoproject/futarchy"; import { Keypair, PublicKey } from "@solana/web3.js"; import { assert } from "chai"; diff --git a/tests/conditionalVault/unit/initializeQuestion.test.ts b/tests/conditionalVault/unit/initializeQuestion.test.ts index acb5e2819..6dca43868 100644 --- a/tests/conditionalVault/unit/initializeQuestion.test.ts +++ b/tests/conditionalVault/unit/initializeQuestion.test.ts @@ -6,7 +6,7 @@ import { expectError } from "../../utils"; import { ConditionalVaultClient, getQuestionAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; // import { getQuestionAddr } from "@metadaoproject/futarchy/dist/v0.4"; export default function suite() { diff --git a/tests/conditionalVault/unit/mergeTokens.test.ts b/tests/conditionalVault/unit/mergeTokens.test.ts index 30f294590..fb844f011 100644 --- a/tests/conditionalVault/unit/mergeTokens.test.ts +++ b/tests/conditionalVault/unit/mergeTokens.test.ts @@ -1,5 +1,5 @@ import { sha256 } from "@metadaoproject/futarchy"; -import { ConditionalVaultClient } from "@metadaoproject/futarchy/v0.4"; +import { ConditionalVaultClient } from "@metadaoproject/futarchy/v0.5"; import { ComputeBudgetProgram, Keypair, PublicKey } from "@solana/web3.js"; import { assert } from "chai"; import { diff --git a/tests/conditionalVault/unit/redeemTokens.test.ts b/tests/conditionalVault/unit/redeemTokens.test.ts index 143554f83..f420ac681 100644 --- a/tests/conditionalVault/unit/redeemTokens.test.ts +++ b/tests/conditionalVault/unit/redeemTokens.test.ts @@ -1,5 +1,5 @@ import { sha256 } from "@metadaoproject/futarchy"; -import { ConditionalVaultClient } from "@metadaoproject/futarchy/v0.4"; +import { ConditionalVaultClient } from "@metadaoproject/futarchy/v0.5"; import { ComputeBudgetProgram, Keypair, PublicKey } from "@solana/web3.js"; import { assert } from "chai"; import { diff --git a/tests/conditionalVault/unit/resolveQuestion.test.ts b/tests/conditionalVault/unit/resolveQuestion.test.ts index c00a01a13..abcd192a6 100644 --- a/tests/conditionalVault/unit/resolveQuestion.test.ts +++ b/tests/conditionalVault/unit/resolveQuestion.test.ts @@ -1,5 +1,5 @@ import { sha256 } from "@metadaoproject/futarchy"; -import { ConditionalVaultClient } from "@metadaoproject/futarchy/v0.4"; +import { ConditionalVaultClient } from "@metadaoproject/futarchy/v0.5"; import { Keypair, PublicKey } from "@solana/web3.js"; import { assert } from "chai"; import { expectError } from "../../utils.js"; diff --git a/tests/conditionalVault/unit/splitTokens.test.ts b/tests/conditionalVault/unit/splitTokens.test.ts index 4951b0063..4c467dd09 100644 --- a/tests/conditionalVault/unit/splitTokens.test.ts +++ b/tests/conditionalVault/unit/splitTokens.test.ts @@ -1,5 +1,5 @@ import { sha256 } from "@metadaoproject/futarchy"; -import { ConditionalVaultClient } from "@metadaoproject/futarchy/v0.4"; +import { ConditionalVaultClient } from "@metadaoproject/futarchy/v0.5"; import { ComputeBudgetProgram, Keypair, PublicKey } from "@solana/web3.js"; import { assert } from "chai"; import { diff --git a/tests/integration/fullLaunch.test.ts b/tests/integration/fullLaunch.test.ts index 942d61636..c7b896ee9 100644 --- a/tests/integration/fullLaunch.test.ts +++ b/tests/integration/fullLaunch.test.ts @@ -13,7 +13,7 @@ import { getLaunchSignerAddr, MAINNET_USDC, PriceMath, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { BN } from "bn.js"; import { getAssociatedTokenAddressSync, diff --git a/tests/integration/mintAndSwap.test.ts b/tests/integration/mintAndSwap.test.ts index 42610f9fb..9510b72e1 100644 --- a/tests/integration/mintAndSwap.test.ts +++ b/tests/integration/mintAndSwap.test.ts @@ -5,7 +5,7 @@ import { getAmmAddr, SwapType, InstructionUtils, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { sha256 } from "@noble/hashes/sha256"; import { Keypair, PublicKey, Transaction } from "@solana/web3.js"; import BN from "bn.js"; diff --git a/tests/integration/scalarMarkets.test.ts b/tests/integration/scalarMarkets.test.ts index 8f13cb87c..9548c3bdf 100644 --- a/tests/integration/scalarMarkets.test.ts +++ b/tests/integration/scalarMarkets.test.ts @@ -4,7 +4,7 @@ import { getAmmAddr, SwapType, InstructionUtils, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { sha256 } from "@noble/hashes/sha256"; import { Keypair, PublicKey, Transaction } from "@solana/web3.js"; import BN from "bn.js"; diff --git a/tests/integration/twap.test.ts b/tests/integration/twap.test.ts index 3bb1b6992..ddea2622d 100644 --- a/tests/integration/twap.test.ts +++ b/tests/integration/twap.test.ts @@ -1,7 +1,7 @@ import { assert } from "chai"; import { Keypair, ComputeBudgetProgram } from "@solana/web3.js"; import { advanceBySlots, DAY_IN_SLOTS, toBN } from "../utils.js"; -import { AmmMath } from "@metadaoproject/futarchy/v0.4"; +import { AmmMath } from "@metadaoproject/futarchy/v0.5"; export default async function test() { // Create META and USDC mints diff --git a/tests/launchpad/unit/claim.test.ts b/tests/launchpad/unit/claim.test.ts index dca149b18..878da28f3 100644 --- a/tests/launchpad/unit/claim.test.ts +++ b/tests/launchpad/unit/claim.test.ts @@ -7,7 +7,7 @@ import { getLaunchSignerAddr, LaunchpadClient, MAINNET_USDC, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { BN } from "bn.js"; import { getAssociatedTokenAddressSync } from "@solana/spl-token"; import { initializeMintWithSeeds } from "../utils.js"; diff --git a/tests/launchpad/unit/completeLaunch.test.ts b/tests/launchpad/unit/completeLaunch.test.ts index c1e755be1..d68e648cf 100644 --- a/tests/launchpad/unit/completeLaunch.test.ts +++ b/tests/launchpad/unit/completeLaunch.test.ts @@ -9,7 +9,7 @@ import { getRaydiumCpmmLpMintAddr, LaunchpadClient, MAINNET_USDC, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { BN } from "bn.js"; import { deserializeMetadata, diff --git a/tests/launchpad/unit/fund.test.ts b/tests/launchpad/unit/fund.test.ts index 20f40cea5..dc8913d0a 100644 --- a/tests/launchpad/unit/fund.test.ts +++ b/tests/launchpad/unit/fund.test.ts @@ -7,7 +7,7 @@ import { getLaunchSignerAddr, LaunchpadClient, MAINNET_USDC, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { createMint, mintTo, getAccount } from "spl-token-bankrun"; import { BN } from "bn.js"; import { diff --git a/tests/launchpad/unit/initializeLaunch.test.ts b/tests/launchpad/unit/initializeLaunch.test.ts index 610499c5f..05d73b8c6 100644 --- a/tests/launchpad/unit/initializeLaunch.test.ts +++ b/tests/launchpad/unit/initializeLaunch.test.ts @@ -11,7 +11,7 @@ import { getLaunchSignerAddr, getMetadataAddr, LaunchpadClient, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { createMint, mintTo } from "spl-token-bankrun"; import { BN } from "bn.js"; import { @@ -23,7 +23,7 @@ import * as token from "@solana/spl-token"; import { MAINNET_USDC, MPL_TOKEN_METADATA_PROGRAM_ID, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { initializeMintWithSeeds } from "../utils.js"; export default function suite() { diff --git a/tests/launchpad/unit/refund.test.ts b/tests/launchpad/unit/refund.test.ts index 16cf47ca8..937b4485b 100644 --- a/tests/launchpad/unit/refund.test.ts +++ b/tests/launchpad/unit/refund.test.ts @@ -6,7 +6,7 @@ import { getLaunchSignerAddr, LaunchpadClient, MAINNET_USDC, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { createMint } from "spl-token-bankrun"; import { BN } from "bn.js"; import { diff --git a/tests/launchpad/unit/startLaunch.test.ts b/tests/launchpad/unit/startLaunch.test.ts index e241ed4fc..046b3e94d 100644 --- a/tests/launchpad/unit/startLaunch.test.ts +++ b/tests/launchpad/unit/startLaunch.test.ts @@ -5,7 +5,7 @@ import { getLaunchAddr, getLaunchSignerAddr, LaunchpadClient, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { createMint } from "spl-token-bankrun"; import { BN } from "bn.js"; import { diff --git a/tests/launchpad/utils.ts b/tests/launchpad/utils.ts index cf4f25a2d..fe5c2ae87 100644 --- a/tests/launchpad/utils.ts +++ b/tests/launchpad/utils.ts @@ -1,11 +1,11 @@ import { PublicKey, Signer, SystemProgram, Transaction } from "@solana/web3.js"; import * as token from "@solana/spl-token"; import { BanksClient } from "solana-bankrun"; -import { LaunchpadClient } from "@metadaoproject/futarchy/v0.4"; +import { LaunchpadClient } from "@metadaoproject/futarchy/v0.5"; import { getLaunchAddr, getLaunchSignerAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; export async function initializeMintWithSeeds( banksClient: BanksClient, diff --git a/tests/main.test.ts b/tests/main.test.ts index 989eeaf99..b8f9a9494 100644 --- a/tests/main.test.ts +++ b/tests/main.test.ts @@ -15,7 +15,7 @@ import { SharedLiquidityManagerClient, MAINNET_USDC, RAYDIUM_CREATE_POOL_FEE_RECEIVE, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; // import { // // AmmClient, // // AutocratClient, @@ -38,7 +38,7 @@ import { assert } from "chai"; import { MPL_TOKEN_METADATA_PROGRAM_ID as UMI_MPL_TOKEN_METADATA_PROGRAM_ID } from "@metaplex-foundation/mpl-token-metadata"; import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters"; import * as fs from "fs"; -import { LOW_FEE_RAYDIUM_CONFIG } from "@metadaoproject/futarchy/v0.4"; +import { LOW_FEE_RAYDIUM_CONFIG } from "@metadaoproject/futarchy/v0.5"; const MPL_TOKEN_METADATA_PROGRAM_ID = toWeb3JsPublicKey( UMI_MPL_TOKEN_METADATA_PROGRAM_ID diff --git a/tests/sharedLiquidityManager/integration/sharedLiquidityManagerLifecycle.test.ts b/tests/sharedLiquidityManager/integration/sharedLiquidityManagerLifecycle.test.ts index 0cafd8fa6..1bd956c41 100644 --- a/tests/sharedLiquidityManager/integration/sharedLiquidityManagerLifecycle.test.ts +++ b/tests/sharedLiquidityManager/integration/sharedLiquidityManagerLifecycle.test.ts @@ -25,7 +25,7 @@ import { getDraftProposalAddr, getStakeRecordAddr, getSpotPoolAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { AddressLookupTableAccount, AddressLookupTableProgram, diff --git a/tests/sharedLiquidityManager/unit/depositSharedLiquidity.test.ts b/tests/sharedLiquidityManager/unit/depositSharedLiquidity.test.ts index ddd7b41f8..8ea9fae42 100644 --- a/tests/sharedLiquidityManager/unit/depositSharedLiquidity.test.ts +++ b/tests/sharedLiquidityManager/unit/depositSharedLiquidity.test.ts @@ -4,7 +4,7 @@ import { getSharedLiquidityPoolAddr, getSpotPoolAddr, getSlPoolPositionAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { PublicKey, ComputeBudgetProgram, Keypair } from "@solana/web3.js"; import { assert } from "chai"; import { createMint, getAccount } from "spl-token-bankrun"; diff --git a/tests/sharedLiquidityManager/unit/initializeDraftProposal.test.ts b/tests/sharedLiquidityManager/unit/initializeDraftProposal.test.ts index a0f09195e..6edcc63b0 100644 --- a/tests/sharedLiquidityManager/unit/initializeDraftProposal.test.ts +++ b/tests/sharedLiquidityManager/unit/initializeDraftProposal.test.ts @@ -3,7 +3,7 @@ import { AutocratClient, getDraftProposalAddr, getSharedLiquidityPoolAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { PublicKey, ComputeBudgetProgram } from "@solana/web3.js"; import { assert } from "chai"; import { createMint } from "spl-token-bankrun"; diff --git a/tests/sharedLiquidityManager/unit/initializeProposalWithLiquidity.test.ts b/tests/sharedLiquidityManager/unit/initializeProposalWithLiquidity.test.ts index 93157c19d..2a263e6e1 100644 --- a/tests/sharedLiquidityManager/unit/initializeProposalWithLiquidity.test.ts +++ b/tests/sharedLiquidityManager/unit/initializeProposalWithLiquidity.test.ts @@ -14,7 +14,7 @@ import { CONDITIONAL_VAULT_PROGRAM_ID, AUTOCRAT_PROGRAM_ID, getSlPoolPositionAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { PublicKey, ComputeBudgetProgram, diff --git a/tests/sharedLiquidityManager/unit/initializeSharedLiquidityPool.test.ts b/tests/sharedLiquidityManager/unit/initializeSharedLiquidityPool.test.ts index 5f03b67e9..f9f4a690f 100644 --- a/tests/sharedLiquidityManager/unit/initializeSharedLiquidityPool.test.ts +++ b/tests/sharedLiquidityManager/unit/initializeSharedLiquidityPool.test.ts @@ -2,7 +2,7 @@ import { SharedLiquidityManagerClient, AutocratClient, getSharedLiquidityPoolAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { PublicKey, ComputeBudgetProgram } from "@solana/web3.js"; import { assert } from "chai"; import { createMint } from "spl-token-bankrun"; diff --git a/tests/sharedLiquidityManager/unit/removeProposalLiquidity.test.ts b/tests/sharedLiquidityManager/unit/removeProposalLiquidity.test.ts index b22f6d31d..95cff188c 100644 --- a/tests/sharedLiquidityManager/unit/removeProposalLiquidity.test.ts +++ b/tests/sharedLiquidityManager/unit/removeProposalLiquidity.test.ts @@ -10,7 +10,7 @@ import { getSharedLiquidityPoolSignerAddr, InstructionUtils, getDaoTreasuryAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { sha256 } from "@metadaoproject/futarchy"; import { PublicKey, diff --git a/tests/sharedLiquidityManager/unit/stakeToDraftProposal.test.ts b/tests/sharedLiquidityManager/unit/stakeToDraftProposal.test.ts index fb38c2e99..f5fdbaeec 100644 --- a/tests/sharedLiquidityManager/unit/stakeToDraftProposal.test.ts +++ b/tests/sharedLiquidityManager/unit/stakeToDraftProposal.test.ts @@ -4,7 +4,7 @@ import { getDraftProposalAddr, getStakeRecordAddr, getSharedLiquidityPoolAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { PublicKey, Keypair, ComputeBudgetProgram } from "@solana/web3.js"; import { assert } from "chai"; import { createMint, getAccount } from "spl-token-bankrun"; diff --git a/tests/sharedLiquidityManager/unit/unstakeFromDraftProposal.test.ts b/tests/sharedLiquidityManager/unit/unstakeFromDraftProposal.test.ts index e798ea767..71444a3ec 100644 --- a/tests/sharedLiquidityManager/unit/unstakeFromDraftProposal.test.ts +++ b/tests/sharedLiquidityManager/unit/unstakeFromDraftProposal.test.ts @@ -4,7 +4,7 @@ import { getDraftProposalAddr, getStakeRecordAddr, getSharedLiquidityPoolAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { PublicKey, Keypair, ComputeBudgetProgram } from "@solana/web3.js"; import { assert } from "chai"; import { createMint, getAccount } from "spl-token-bankrun"; diff --git a/tests/sharedLiquidityManager/unit/withdrawSharedLiquidity.test.ts b/tests/sharedLiquidityManager/unit/withdrawSharedLiquidity.test.ts index d1c66c049..0a036be01 100644 --- a/tests/sharedLiquidityManager/unit/withdrawSharedLiquidity.test.ts +++ b/tests/sharedLiquidityManager/unit/withdrawSharedLiquidity.test.ts @@ -5,7 +5,7 @@ import { getSpotPoolAddr, getSlPoolPositionAddr, getRaydiumCpmmLpMintAddr, -} from "@metadaoproject/futarchy/v0.4"; +} from "@metadaoproject/futarchy/v0.5"; import { PublicKey, ComputeBudgetProgram, Keypair } from "@solana/web3.js"; import { assert } from "chai"; import { createMint, getAccount } from "spl-token-bankrun";