diff --git a/lib/client/client.ts b/lib/client/client.ts index d81e198..65ac670 100644 --- a/lib/client/client.ts +++ b/lib/client/client.ts @@ -216,6 +216,16 @@ export interface FutarchyAmmMarketsClient { outputAmountMin: number, slippage: number ): Promise | undefined>; + mintAndSwap( + mintAmount: number, + vaultAccountAddress: PublicKey, + vaultAccount: VaultAccountWithProtocol, + ammMarket: AmmMarket, + swapType: SwapType, + inputAmount: number, + outputAmountMin: number, + slippage: number + ): Promise | undefined>; removeLiquidity( ammMarket: AmmMarket, lpTokensToBurn: number, diff --git a/lib/client/indexer/indexerClient.ts b/lib/client/indexer/indexerClient.ts index f1a93a5..80a5950 100644 --- a/lib/client/indexer/indexerClient.ts +++ b/lib/client/indexer/indexerClient.ts @@ -123,8 +123,6 @@ export class FutarchyIndexerClient implements FutarchyClient { { query, variables }, { next: (data) => { - console.log(data); - subscriber.next(data.data?.prices[0].updated_slot); }, error: (error) => subscriber.error(error), diff --git a/lib/client/indexer/market-clients/ammMarkets.ts b/lib/client/indexer/market-clients/ammMarkets.ts index c68bede..10cb019 100644 --- a/lib/client/indexer/market-clients/ammMarkets.ts +++ b/lib/client/indexer/market-clients/ammMarkets.ts @@ -9,11 +9,13 @@ import { SwapPreview, TokenMetadataSource, TokenProps, - TokenWithBalance + TokenWithBalance, + VaultAccountWithProtocol } from "@/types"; import { PublicKey } from "@solana/web3.js"; import { SwapType } from "@metadaoproject/futarchy"; -import { SendTransactionResponse } from "@/types/transactions"; +import { TransactionProcessingUpdate } from "@/types/transactions"; +import { Observable } from "rxjs"; export class FutarchyIndexerAmmMarketsClient implements FutarchyAmmMarketsClient @@ -111,6 +113,28 @@ export class FutarchyIndexerAmmMarketsClient ); } + async mintAndSwap( + mintAmount: number, + vaultAccountAddress: PublicKey, + vaultAccount: VaultAccountWithProtocol, + ammMarket: AmmMarket, + swapType: SwapType, + inputAmount: number, + outputAmountMin: number, + slippage: number + ): Promise | undefined> { + return this.rpcMarketsClient.mintAndSwap( + mintAmount, + vaultAccountAddress, + vaultAccount, + ammMarket, + swapType, + inputAmount, + outputAmountMin, + slippage + ); + } + /** * * @param ammMarket diff --git a/lib/client/rpc/market-clients/ammMarkets.ts b/lib/client/rpc/market-clients/ammMarkets.ts index 20b5271..81c55f4 100644 --- a/lib/client/rpc/market-clients/ammMarkets.ts +++ b/lib/client/rpc/market-clients/ammMarkets.ts @@ -2,7 +2,7 @@ import { FutarchyAmmMarketsClient } from "@/client"; import { enrichTokenMetadata } from "@/tokens"; import { calculateMaxWithSlippage, calculateMinWithSlippage } from "@/trading"; import { TransactionSender } from "@/transactions/sender"; -import { TokenWithBalance } from "@/types"; +import { TokenWithBalance, VaultAccountWithProtocol } from "@/types"; import { AddLiquiditySimulationResponse, AmmMarket, @@ -13,10 +13,13 @@ import { import { TransactionProcessingUpdate } from "@/types/transactions"; import anchor from "@coral-xyz/anchor"; import BN from "bn.js"; +import numeral from "numeral"; import { AMM_PROGRAM_ID, AmmAccount, AmmClient, + AutocratClient, + InstructionUtils, PriceMath, SwapType, getAmmAddr, @@ -24,24 +27,27 @@ import { } from "@metadaoproject/futarchy"; import { Amm as AmmIDLType } from "@/idl/amm_v0.3"; import { getAssociatedTokenAddressSync } from "@solana/spl-token"; -import { AccountInfo, PublicKey } from "@solana/web3.js"; +import { AccountInfo, PublicKey, Transaction } from "@solana/web3.js"; import { Observable } from "rxjs"; export class FutarchyAmmMarketsRPCClient implements FutarchyAmmMarketsClient { private rpcProvider: anchor.Provider; private amm: anchor.Program; private ammClient: AmmClient; + private autocratClient: AutocratClient; private transactionSender: TransactionSender | undefined; constructor( rpcProvider: anchor.Provider, amm: anchor.Program, ammClient: AmmClient, + autocratClient: AutocratClient, transactionSender: TransactionSender | undefined ) { this.rpcProvider = rpcProvider; this.amm = amm; this.ammClient = ammClient; + this.autocratClient = autocratClient; this.transactionSender = transactionSender; } @@ -390,6 +396,77 @@ export class FutarchyAmmMarketsRPCClient implements FutarchyAmmMarketsClient { ); } + async mintAndSwap( + mintAmount: number, + vaultAccountAddress: PublicKey, + vaultAccount: VaultAccountWithProtocol, + ammMarket: AmmMarket, + swapType: SwapType, + inputAmount: number, + outputAmountMin: number, + slippage: number + ) { + if (!this.transactionSender) { + console.error("Transaction sender is undefined"); + return; + } + let [inputToken, outputToken] = swapType.buy + ? [ammMarket.quoteToken, ammMarket.baseToken] + : [ammMarket.baseToken, ammMarket.quoteToken]; + + const inputAmountScaled: BN = PriceMath.getChainAmount( + inputAmount, + inputToken.decimals + ); + const outputAmountMinScaled: BN = PriceMath.getChainAmount( + outputAmountMin, + outputToken.decimals + ); + // TODO don't need to do this if we use new futarchy SDK with slippage on preview calculation + const outputAmountWithSlippage = new BN( + calculateMinWithSlippage(outputAmountMinScaled.toNumber(), slippage) + ); + + const { decimals } = await enrichTokenMetadata( + vaultAccount.conditionalOnFinalizeTokenMint, + this.rpcProvider + ); + + const mintIx = + await this.autocratClient.vaultClient.mintConditionalTokensIx( + vaultAccountAddress, + vaultAccount.underlyingTokenMint, + new BN( + numeral(mintAmount) + .multiply(10 ** (decimals || 0)) + .format("0") + ) + ); + + const swapIx = await this.ammClient.swapIx( + ammMarket.publicKey, + ammMarket.baseMint, + ammMarket.quoteMint, + swapType, + inputAmountScaled, + outputAmountWithSlippage + ); + + const ixs = await InstructionUtils.getInstructions(mintIx, swapIx); + + const tx = new Transaction().add(...ixs); + + return this.transactionSender?.send( + [tx], + this.rpcProvider.connection, + { + customErrors: [this.ammClient.program.idl.errors], + CUs: 150_000 + }, + { title: "Swapping" } + ); + } + async getSwapPreview( ammMarket: AmmMarket, inputAmount: number, diff --git a/lib/client/rpc/markets.ts b/lib/client/rpc/markets.ts index 8336951..7dfcd88 100644 --- a/lib/client/rpc/markets.ts +++ b/lib/client/rpc/markets.ts @@ -11,7 +11,7 @@ import { } from "@/types"; import { FutarchyMarketsClient } from "@/client"; import { TransactionSender } from "@/transactions/sender"; -import { AmmClient, PriceMath } from "@metadaoproject/futarchy"; +import { AmmClient, AutocratClient, PriceMath } from "@metadaoproject/futarchy"; import { FutarchyOpenbookMarketsRPCClient } from "./market-clients/openbookMarkets"; import { FutarchyAmmMarketsRPCClient } from "./market-clients/ammMarkets"; import { Amm as AmmIDLType } from "@/idl/amm_v0.3"; @@ -36,6 +36,7 @@ export class FutarchyMarketsRPCClient implements FutarchyMarketsClient { openbookClient: OpenBookV2Client, amm: Program, ammClient: AmmClient, + autocratClient: AutocratClient, transactionSender: TransactionSender | undefined ) { this.openbook = new FutarchyOpenbookMarketsRPCClient( @@ -48,6 +49,7 @@ export class FutarchyMarketsRPCClient implements FutarchyMarketsClient { rpcProvider, amm, ammClient, + autocratClient, transactionSender ); } diff --git a/lib/client/rpc/rpcClient.ts b/lib/client/rpc/rpcClient.ts index fe413d7..35f14c0 100644 --- a/lib/client/rpc/rpcClient.ts +++ b/lib/client/rpc/rpcClient.ts @@ -16,7 +16,10 @@ import { AMM_PROGRAM_ID, Amm as AmmIDLType, AmmClient, - AmmIDL as AMM_IDL + AmmIDL as AMM_IDL, + AutocratClient, + AUTOCRAT_PROGRAM_ID, + CONDITIONAL_VAULT_PROGRAM_ID } from "@metadaoproject/futarchy"; import { FutarchyMarketsRPCClient } from "./markets"; import { FutarchyRPCSocialsClient } from "./socials"; @@ -53,6 +56,7 @@ export class FutarchyRPCClient implements FutarchyClient { new OpenBookV2Client(rpcProvider, OPENBOOK_PROGRAM_ID), new Program(AMM_IDL, AMM_PROGRAM_ID, rpcProvider), new AmmClient(rpcProvider, AMM_PROGRAM_ID, []), + new AutocratClient(rpcProvider, AUTOCRAT_PROGRAM_ID, CONDITIONAL_VAULT_PROGRAM_ID, AMM_PROGRAM_ID, []), transactionSender ); } diff --git a/package.json b/package.json index 14a825f..df526d8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@metadaoproject/futarchy-sdk", - "version": "4.0.0-alpha.52", + "version": "4.0.0-alpha.53", "type": "module", "main": "dist", "scripts": {