From 7d6563a3e637eec9ca7c91965377937c5d2d1c97 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 22 Aug 2024 03:02:42 +0200 Subject: [PATCH 1/4] add burn liquidity handler --- frontend/package-lock.json | 9 +- frontend/package.json | 2 +- .../src/components/Liquidity/Liquidity.tsx | 10 +- .../LiquidityWrapper/LiquidityWrapper.tsx | 16 ++- frontend/src/store/consts/static.ts | 7 + frontend/src/store/reducers/pools.ts | 3 + frontend/src/store/sagas/pools.ts | 133 +++++++++++++++++- frontend/src/utils/web3/adapters/types.ts | 6 +- 8 files changed, 167 insertions(+), 19 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e5063c6..ced9b68 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@emotion/react": "^11.13.0", "@emotion/styled": "^11.13.0", - "@invariant-labs/eclipse-link-sdk": "^0.1.3", + "@invariant-labs/eclipse-link-sdk": "^0.1.4", "@invariant-labs/sdk-eclipse": "^0.0.17", "@mui/icons-material": "^5.16.7", "@mui/material": "^5.16.7", @@ -1107,9 +1107,10 @@ "dev": true }, "node_modules/@invariant-labs/eclipse-link-sdk": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@invariant-labs/eclipse-link-sdk/-/eclipse-link-sdk-0.1.3.tgz", - "integrity": "sha512-hZireEYxWU0m0LhKpnWWusH0utcqyWxonbYA4/Emgb0U0jjP2LImUO6ODm2+MGPIJuyjWFoPKf50z327zmyBjw==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@invariant-labs/eclipse-link-sdk/-/eclipse-link-sdk-0.1.4.tgz", + "integrity": "sha512-MslpgJGLq+y+TYYgVC20N8XpZuhi685gOMLB92X1Q+0ijdxWRB7MjTKzHTQEnga8fBIxJIqQVDmw3C+snRfUDQ==", + "license": "ISC", "dependencies": { "@coral-xyz/anchor": "^0.29.0", "@solana/web3.js": "^1.95.2" diff --git a/frontend/package.json b/frontend/package.json index b387748..3ace469 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,7 +14,7 @@ "dependencies": { "@emotion/react": "^11.13.0", "@emotion/styled": "^11.13.0", - "@invariant-labs/eclipse-link-sdk": "^0.1.3", + "@invariant-labs/eclipse-link-sdk": "^0.1.4", "@invariant-labs/sdk-eclipse": "^0.0.17", "@mui/icons-material": "^5.16.7", "@mui/material": "^5.16.7", diff --git a/frontend/src/components/Liquidity/Liquidity.tsx b/frontend/src/components/Liquidity/Liquidity.tsx index bd307c8..cae88e1 100644 --- a/frontend/src/components/Liquidity/Liquidity.tsx +++ b/frontend/src/components/Liquidity/Liquidity.tsx @@ -3,7 +3,7 @@ import { SwapToken } from '@store/selectors/wallet' import React, { useEffect, useMemo, useState } from 'react' import { useNavigate } from 'react-router-dom' import useStyles from './style' -import { FormatNumberThreshold, TokenPriceData } from '@store/consts/types' +import { TokenPriceData } from '@store/consts/types' import { TooltipHover } from '@components/TooltipHover/TooltipHover' import { INoConnected, NoConnected } from '@components/NoConnected/NoConnected' import { ProgressState } from '@components/AnimatedButton/AnimatedButton' @@ -37,7 +37,7 @@ export interface ILiquidity { midPrice: any setMidPrice: (mid: any) => void addLiquidityHandler: (xAmount: number, yAmount: number) => void - removeLiquidityHandler: (xAmount: number, yAmount: FormatNumberThreshold) => void + removeLiquidityHandler: () => void onChangePositionTokens: ( tokenAIndex: number | null, tokenBindex: number | null, @@ -81,7 +81,7 @@ export const Liquidity: React.FC = ({ tokens, // setMidPrice, // addLiquidityHandler, - // removeLiquidityHandler, + removeLiquidityHandler, onChangePositionTokens, calcAmount, feeTiers, @@ -460,9 +460,7 @@ export const Liquidity: React.FC = ({ ) : ( { - //TODO - }} + onRemoveLiquidity={removeLiquidityHandler} LPTokenInputState={{ value: LPTokenDeposit, setValue: value => { diff --git a/frontend/src/containers/LiquidityWrapper/LiquidityWrapper.tsx b/frontend/src/containers/LiquidityWrapper/LiquidityWrapper.tsx index dcfa28e..2ca394b 100644 --- a/frontend/src/containers/LiquidityWrapper/LiquidityWrapper.tsx +++ b/frontend/src/containers/LiquidityWrapper/LiquidityWrapper.tsx @@ -218,8 +218,6 @@ export const LiquidityWrapper: React.FC = ({ } }, [allLpPools]) - console.log(lpPoolIndex) - useEffect(() => { isMountedRef.current = true return () => { @@ -237,7 +235,19 @@ export const LiquidityWrapper: React.FC = ({ midPrice={10} setMidPrice={() => {}} addLiquidityHandler={() => {}} - removeLiquidityHandler={() => {}} + removeLiquidityHandler={() => { + if (tokenAIndex !== null && tokenBIndex !== null) { + dispatch( + poolsActions.burn( + new Pair( + tokens[tokenAIndex].address, + tokens[tokenBIndex].address, + FEE_TIERS[feeIndex] + ) + ) + ) + } + }} onChangePositionTokens={(tokenA, tokenB, feeTierIndex) => { setTokenAIndex(tokenA) setTokenBIndex(tokenB) diff --git a/frontend/src/store/consts/static.ts b/frontend/src/store/consts/static.ts index 1348545..1f6d023 100644 --- a/frontend/src/store/consts/static.ts +++ b/frontend/src/store/consts/static.ts @@ -2,6 +2,7 @@ import { BN } from '@project-serum/anchor' import { PublicKey } from '@solana/web3.js' import { FormatNumberThreshold, PrefixConfig } from './types' import { FEE_TIERS } from '@invariant-labs/sdk-eclipse/lib/utils' +import { ISnackbar } from '@store/reducers/snackbars' export interface FeeTier { fee: BN tickSpacing?: number @@ -277,3 +278,9 @@ export const addressTickerMap: { [key: string]: string } = { USDC: '5gFSyxjNsuQsZKn9g5L9Ky3cSUvJ6YXqWVuPzmSi8Trx', ETH: 'So11111111111111111111111111111111111111112' } + +export const SIGNING_SNACKBAR_CONFIG: Omit = { + message: 'Signing transactions', + variant: 'pending', + persist: true +} diff --git a/frontend/src/store/reducers/pools.ts b/frontend/src/store/reducers/pools.ts index f92f047..855ae79 100644 --- a/frontend/src/store/reducers/pools.ts +++ b/frontend/src/store/reducers/pools.ts @@ -140,6 +140,9 @@ const poolsSlice = createSlice({ state.lpPools = R.merge(state.lpPools, newData) state.isLoadingLatestPoolsForTransaction = false return state + }, + burn(state, _action: PayloadAction) { + return state } } }) diff --git a/frontend/src/store/sagas/pools.ts b/frontend/src/store/sagas/pools.ts index 58fc1c3..b78ab34 100644 --- a/frontend/src/store/sagas/pools.ts +++ b/frontend/src/store/sagas/pools.ts @@ -5,8 +5,17 @@ import { PayloadAction } from '@reduxjs/toolkit' import { getMarketProgram } from '@web3/programs/amm' import { getPools } from '@store/consts/utils' import { Pair } from '@invariant-labs/sdk-eclipse' -import { FEE_TIERS } from '@invariant-labs/sdk-eclipse/lib/utils' +import { FEE_TIERS, getMaxTick, getMinTick } from '@invariant-labs/sdk-eclipse/lib/utils' import { getProtocolProgram } from '@web3/programs/protocol' +import { AnchorProvider, BN } from '@project-serum/anchor' +import { BlockheightBasedTransactionConfirmationStrategy, Transaction } from '@solana/web3.js' +import { getAssociatedTokenAddress } from '@solana/spl-token' +import { getConnection } from './connection' +import { getWallet } from './wallet' +import { createLoaderKey } from '@utils/utils' +import { actions as snackbarsActions } from '@store/reducers/snackbars' +import { SIGNING_SNACKBAR_CONFIG } from '@store/consts/static' +import { closeSnackbar } from 'notistack' export interface iTick { index: iTick[] @@ -70,6 +79,118 @@ export function* fetchLpPoolData(action: PayloadAction) { } } +export function* handleBurn(action: PayloadAction) { + const loaderHandleBurn = createLoaderKey() + const loaderSigningTx = createLoaderKey() + + try { + yield put( + snackbarsActions.add({ + message: 'Removing liquidity...', + variant: 'pending', + persist: true, + key: loaderHandleBurn + }) + ) + + const pair = action.payload + + const networkType = yield* select(network) + const rpc = yield* select(rpcAddress) + const wallet = yield* call(getWallet) + const connection = yield* call(getConnection) + + const protocolProgram = yield* call(getProtocolProgram, networkType, rpc) + const marketProgram = yield* call(getMarketProgram, networkType, rpc) + + const tx = new Transaction() + + const { address: stateAddress } = yield* call([marketProgram, marketProgram.getStateAddress]) + const { positionListAddress } = yield* call( + [marketProgram, marketProgram.getPositionListAddress], + protocolProgram.programAuthority + ) + const { positionAddress } = yield* call( + [marketProgram, marketProgram.getPositionAddress], + protocolProgram.programAuthority, + 0 + ) + const { positionAddress: lastPositionAddress } = yield* call( + [marketProgram, marketProgram.getPositionAddress], + protocolProgram.programAuthority, + 0 + ) + const { tickAddress: lowerTickAddress } = yield* call( + [marketProgram, marketProgram.getTickAddress], + pair, + getMinTick(pair.feeTier.tickSpacing ?? 0) + ) + const { tickAddress: upperTickAddress } = yield* call( + [marketProgram, marketProgram.getTickAddress], + pair, + getMaxTick(pair.feeTier.tickSpacing ?? 0) + ) + const pool = yield* call([marketProgram, marketProgram.getPool], pair) + const accountXAddress = yield* call(getAssociatedTokenAddress, pool.tokenX, wallet.publicKey) + const accountYAddress = yield* call(getAssociatedTokenAddress, pool.tokenY, wallet.publicKey) + const { programAuthority } = yield* call([marketProgram, marketProgram.getProgramAuthority]) + + const burnIx = yield* call([protocolProgram, protocolProgram.burnLpTokenIx], { + pair, + index: 0, + liquidityDelta: new BN(10000), + invProgram: marketProgram.program.programId, + invState: stateAddress, + position: positionAddress, + lastPosition: lastPositionAddress, + positionList: positionListAddress, + lowerTick: lowerTickAddress, + upperTick: upperTickAddress, + tickmap: pool.tickmap, + accountX: accountXAddress, + accountY: accountYAddress, + invReserveX: pool.tokenXReserve, + invReserveY: pool.tokenYReserve, + invProgramAuthority: programAuthority + }) + tx.add(burnIx) + + const blockhash = yield* call([connection, connection.getLatestBlockhash]) + tx.recentBlockhash = blockhash.blockhash + tx.feePayer = wallet.publicKey + + yield put(snackbarsActions.add({ ...SIGNING_SNACKBAR_CONFIG, key: loaderSigningTx })) + + const signedTx = yield* call([wallet, wallet.signTransaction], tx) + + closeSnackbar(loaderSigningTx) + yield put(snackbarsActions.remove(loaderSigningTx)) + + const signature = yield* call( + [connection, connection.sendRawTransaction], + signedTx.serialize(), + AnchorProvider.defaultOptions() + ) + + const confirmStrategy: BlockheightBasedTransactionConfirmationStrategy = { + blockhash: blockhash.blockhash, + lastValidBlockHeight: blockhash.lastValidBlockHeight, + signature + } + yield* call([connection, connection.confirmTransaction], confirmStrategy) + + closeSnackbar(loaderHandleBurn) + yield put(snackbarsActions.remove(loaderHandleBurn)) + } catch (error) { + closeSnackbar(loaderSigningTx) + yield put(snackbarsActions.remove(loaderSigningTx)) + closeSnackbar(loaderHandleBurn) + yield put(snackbarsActions.remove(loaderHandleBurn)) + + console.error('Error burning LP tokens:', error) + } +} + export function* getPoolDataHandler(): Generator { yield* takeLatest(actions.getPoolData, fetchPoolData) } @@ -82,6 +203,14 @@ export function* getLpPoolDataHandler(): Generator { yield* takeLatest(actions.getLpPoolData, fetchLpPoolData) } +export function* burnHandler(): Generator { + yield* takeLatest(actions.burn, handleBurn) +} + export function* poolsSaga(): Generator { - yield all([getPoolDataHandler, getAllPoolsForPairDataHandler, getLpPoolDataHandler].map(spawn)) + yield all( + [getPoolDataHandler, getAllPoolsForPairDataHandler, getLpPoolDataHandler, burnHandler].map( + spawn + ) + ) } diff --git a/frontend/src/utils/web3/adapters/types.ts b/frontend/src/utils/web3/adapters/types.ts index b41808d..e746f93 100644 --- a/frontend/src/utils/web3/adapters/types.ts +++ b/frontend/src/utils/web3/adapters/types.ts @@ -1,10 +1,10 @@ -import { PublicKey, Transaction } from '@solana/web3.js' +import { PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js' export interface WalletAdapter { publicKey: PublicKey connected: boolean - signTransaction: (transaction: Transaction) => Promise - signAllTransactions: (transaction: Transaction[]) => Promise + signTransaction(tx: T): Promise + signAllTransactions(txs: T[]): Promise connect: () => any disconnect: () => any } From f6ffb69acbc8ef3b27a8b98f7f43b2305108d0d6 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 22 Aug 2024 03:30:06 +0200 Subject: [PATCH 2/4] pass liquidity detla to burn handler --- .../src/containers/LiquidityWrapper/LiquidityWrapper.tsx | 9 +++++---- frontend/src/store/reducers/pools.ts | 7 ++++++- frontend/src/store/sagas/pools.ts | 8 ++++---- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/frontend/src/containers/LiquidityWrapper/LiquidityWrapper.tsx b/frontend/src/containers/LiquidityWrapper/LiquidityWrapper.tsx index 29416e0..4c6a1a7 100644 --- a/frontend/src/containers/LiquidityWrapper/LiquidityWrapper.tsx +++ b/frontend/src/containers/LiquidityWrapper/LiquidityWrapper.tsx @@ -253,13 +253,14 @@ export const LiquidityWrapper: React.FC = ({ removeLiquidityHandler={() => { if (tokenAIndex !== null && tokenBIndex !== null) { dispatch( - poolsActions.burn( - new Pair( + poolsActions.burn({ + pair: new Pair( tokens[tokenAIndex].address, tokens[tokenBIndex].address, FEE_TIERS[feeIndex] - ) - ) + ), + liquidityDelta: new BN(10000) + }) ) } }} diff --git a/frontend/src/store/reducers/pools.ts b/frontend/src/store/reducers/pools.ts index 211b832..3689a4a 100644 --- a/frontend/src/store/reducers/pools.ts +++ b/frontend/src/store/reducers/pools.ts @@ -98,6 +98,11 @@ export interface MintData { lpPoolExists: boolean } +export interface BurnData { + pair: Pair + liquidityDelta: BN +} + export const poolsSliceName = 'pools' const poolsSlice = createSlice({ name: poolsSliceName, @@ -152,7 +157,7 @@ const poolsSlice = createSlice({ mint(state, _action: PayloadAction) { return state }, - burn(state, _action: PayloadAction) { + burn(state, _action: PayloadAction) { return state } } diff --git a/frontend/src/store/sagas/pools.ts b/frontend/src/store/sagas/pools.ts index df98403..7d0fcde 100644 --- a/frontend/src/store/sagas/pools.ts +++ b/frontend/src/store/sagas/pools.ts @@ -1,4 +1,4 @@ -import { actions, MintData, PairTokens, PoolWithAddress } from '@store/reducers/pools' +import { actions, BurnData, MintData, PairTokens, PoolWithAddress } from '@store/reducers/pools' import { network, rpcAddress } from '@store/selectors/connection' import { all, call, put, select, spawn, takeLatest } from 'typed-redux-saga' import { PayloadAction } from '@reduxjs/toolkit' @@ -189,7 +189,7 @@ export function* handleMint(action: PayloadAction) { yield* call([connection, connection.confirmTransaction], confirmStrategy) } -export function* handleBurn(action: PayloadAction) { +export function* handleBurn(action: PayloadAction) { const loaderHandleBurn = createLoaderKey() const loaderSigningTx = createLoaderKey() @@ -203,7 +203,7 @@ export function* handleBurn(action: PayloadAction) { }) ) - const pair = action.payload + const { liquidityDelta, pair } = action.payload const networkType = yield* select(network) const rpc = yield* select(rpcAddress) @@ -248,7 +248,7 @@ export function* handleBurn(action: PayloadAction) { const burnIx = yield* call([protocolProgram, protocolProgram.burnLpTokenIx], { pair, index: 0, - liquidityDelta: new BN(10000), + liquidityDelta, invProgram: marketProgram.program.programId, invState: stateAddress, position: positionAddress, From c8b1b30e1b2485dc88d781872e485d26b4cd8e88 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 22 Aug 2024 03:35:35 +0200 Subject: [PATCH 3/4] add snackbars for mint LP token --- frontend/src/store/sagas/pools.ts | 227 +++++++++++++++++------------- 1 file changed, 131 insertions(+), 96 deletions(-) diff --git a/frontend/src/store/sagas/pools.ts b/frontend/src/store/sagas/pools.ts index 7d0fcde..92a4f4f 100644 --- a/frontend/src/store/sagas/pools.ts +++ b/frontend/src/store/sagas/pools.ts @@ -80,113 +80,148 @@ export function* fetchLpPoolData(action: PayloadAction) { } export function* handleMint(action: PayloadAction) { - const { pair, lpPoolExists } = action.payload + const loaderHandleMint = createLoaderKey() + const loaderSigningTx = createLoaderKey() + try { + yield put( + snackbarsActions.add({ + message: 'Adding liquidity...', + variant: 'pending', + persist: true, + key: loaderHandleMint + }) + ) + const { pair, lpPoolExists } = action.payload - const networkType = yield* select(network) - const rpc = yield* select(rpcAddress) - const wallet = yield* call(getWallet) - const connection = yield* call(getConnection) + const networkType = yield* select(network) + const rpc = yield* select(rpcAddress) + const wallet = yield* call(getWallet) + const connection = yield* call(getConnection) - const protocolProgram = yield* call(getProtocolProgram, networkType, rpc) - const marketProgram = yield* call(getMarketProgram, networkType, rpc) + const protocolProgram = yield* call(getProtocolProgram, networkType, rpc) + const marketProgram = yield* call(getMarketProgram, networkType, rpc) - const tx = new Transaction() + const tx = new Transaction() - if (lpPoolExists) { - const initLpPoolIx = yield* call([protocolProgram, protocolProgram.initLpPoolIx], { - pair - }) - tx.add(initLpPoolIx) - - const lowerTickIndex = getMinTick(pair.feeTier.tickSpacing ?? 0) - try { - yield* call([marketProgram, marketProgram.getTick], pair, lowerTickIndex) - } catch (e) { - const createLowerTickIx = yield* call([marketProgram, marketProgram.createTickInstruction], { - pair, - index: getMinTick(pair.feeTier.tickSpacing ?? 0) + if (lpPoolExists) { + const initLpPoolIx = yield* call([protocolProgram, protocolProgram.initLpPoolIx], { + pair }) - tx.add(createLowerTickIx) + tx.add(initLpPoolIx) + + const lowerTickIndex = getMinTick(pair.feeTier.tickSpacing ?? 0) + try { + yield* call([marketProgram, marketProgram.getTick], pair, lowerTickIndex) + } catch (e) { + const createLowerTickIx = yield* call( + [marketProgram, marketProgram.createTickInstruction], + { + pair, + index: getMinTick(pair.feeTier.tickSpacing ?? 0) + } + ) + tx.add(createLowerTickIx) + } + + const upperTickIndex = getMaxTick(pair.feeTier.tickSpacing ?? 0) + try { + yield* call([marketProgram, marketProgram.getTick], pair, upperTickIndex) + } catch (e) { + const createLowerTickIx = yield* call( + [marketProgram, marketProgram.createTickInstruction], + { + pair, + index: getMinTick(pair.feeTier.tickSpacing ?? 0) + } + ) + tx.add(createLowerTickIx) + } } - const upperTickIndex = getMaxTick(pair.feeTier.tickSpacing ?? 0) - try { - yield* call([marketProgram, marketProgram.getTick], pair, upperTickIndex) - } catch (e) { - const createLowerTickIx = yield* call([marketProgram, marketProgram.createTickInstruction], { - pair, - index: getMinTick(pair.feeTier.tickSpacing ?? 0) - }) - tx.add(createLowerTickIx) + const { address: stateAddress } = yield* call([marketProgram, marketProgram.getStateAddress]) + const { positionListAddress } = yield* call( + [marketProgram, marketProgram.getPositionListAddress], + protocolProgram.programAuthority + ) + const { positionAddress } = yield* call( + [marketProgram, marketProgram.getPositionAddress], + protocolProgram.programAuthority, + 0 + ) + const { positionAddress: lastPositionAddress } = yield* call( + [marketProgram, marketProgram.getPositionAddress], + protocolProgram.programAuthority, + 0 + ) + const { tickAddress: lowerTickAddress } = yield* call( + [marketProgram, marketProgram.getTickAddress], + pair, + getMinTick(pair.feeTier.tickSpacing ?? 0) + ) + const { tickAddress: upperTickAddress } = yield* call( + [marketProgram, marketProgram.getTickAddress], + pair, + getMaxTick(pair.feeTier.tickSpacing ?? 0) + ) + const pool = yield* call([marketProgram, marketProgram.getPool], pair) + const accountXAddress = yield* call(getAssociatedTokenAddress, pool.tokenX, wallet.publicKey) + const accountYAddress = yield* call(getAssociatedTokenAddress, pool.tokenY, wallet.publicKey) + const { programAuthority } = yield* call([marketProgram, marketProgram.getProgramAuthority]) + + const mintIx = yield* call([protocolProgram, protocolProgram.mintLpTokenIx], { + pair, + index: 0, + liquidityDelta: new BN(10000), + invProgram: marketProgram.program.programId, + invState: stateAddress, + position: positionAddress, + lastPosition: lastPositionAddress, + positionList: positionListAddress, + lowerTick: lowerTickAddress, + upperTick: upperTickAddress, + tickmap: pool.tickmap, + accountX: accountXAddress, + accountY: accountYAddress, + invReserveX: pool.tokenXReserve, + invReserveY: pool.tokenYReserve, + invProgramAuthority: programAuthority + }) + tx.add(mintIx) + + const blockhash = yield* call([connection, connection.getLatestBlockhash]) + tx.recentBlockhash = blockhash.blockhash + tx.feePayer = wallet.publicKey + + yield put(snackbarsActions.add({ ...SIGNING_SNACKBAR_CONFIG, key: loaderSigningTx })) + + const signedTx = yield* call([wallet, wallet.signTransaction], tx) + + closeSnackbar(loaderSigningTx) + yield put(snackbarsActions.remove(loaderSigningTx)) + + const signature = yield* call( + [connection, connection.sendRawTransaction], + signedTx.serialize(), + AnchorProvider.defaultOptions() + ) + + const confirmStrategy: BlockheightBasedTransactionConfirmationStrategy = { + blockhash: blockhash.blockhash, + lastValidBlockHeight: blockhash.lastValidBlockHeight, + signature } - } + yield* call([connection, connection.confirmTransaction], confirmStrategy) - const { address: stateAddress } = yield* call([marketProgram, marketProgram.getStateAddress]) - const { positionListAddress } = yield* call( - [marketProgram, marketProgram.getPositionListAddress], - protocolProgram.programAuthority - ) - const { positionAddress } = yield* call( - [marketProgram, marketProgram.getPositionAddress], - protocolProgram.programAuthority, - 0 - ) - const { positionAddress: lastPositionAddress } = yield* call( - [marketProgram, marketProgram.getPositionAddress], - protocolProgram.programAuthority, - 0 - ) - const { tickAddress: lowerTickAddress } = yield* call( - [marketProgram, marketProgram.getTickAddress], - pair, - getMinTick(pair.feeTier.tickSpacing ?? 0) - ) - const { tickAddress: upperTickAddress } = yield* call( - [marketProgram, marketProgram.getTickAddress], - pair, - getMaxTick(pair.feeTier.tickSpacing ?? 0) - ) - const pool = yield* call([marketProgram, marketProgram.getPool], pair) - const accountXAddress = yield* call(getAssociatedTokenAddress, pool.tokenX, wallet.publicKey) - const accountYAddress = yield* call(getAssociatedTokenAddress, pool.tokenY, wallet.publicKey) - const { programAuthority } = yield* call([marketProgram, marketProgram.getProgramAuthority]) - - const mintIx = yield* call([protocolProgram, protocolProgram.mintLpTokenIx], { - pair, - index: 0, - liquidityDelta: new BN(10000), - invProgram: marketProgram.program.programId, - invState: stateAddress, - position: positionAddress, - lastPosition: lastPositionAddress, - positionList: positionListAddress, - lowerTick: lowerTickAddress, - upperTick: upperTickAddress, - tickmap: pool.tickmap, - accountX: accountXAddress, - accountY: accountYAddress, - invReserveX: pool.tokenXReserve, - invReserveY: pool.tokenYReserve, - invProgramAuthority: programAuthority - }) - tx.add(mintIx) - - const blockhash = yield* call([connection, connection.getLatestBlockhash]) - tx.recentBlockhash = blockhash.blockhash - tx.feePayer = wallet.publicKey - const signedTx = yield* call([wallet, wallet.signTransaction], tx) - const signature = yield* call( - [connection, connection.sendRawTransaction], - signedTx.serialize(), - AnchorProvider.defaultOptions() - ) + closeSnackbar(loaderHandleMint) + yield put(snackbarsActions.remove(loaderHandleMint)) + } catch (error) { + closeSnackbar(loaderSigningTx) + yield put(snackbarsActions.remove(loaderSigningTx)) + closeSnackbar(loaderHandleMint) + yield put(snackbarsActions.remove(loaderHandleMint)) - const confirmStrategy: BlockheightBasedTransactionConfirmationStrategy = { - blockhash: blockhash.blockhash, - lastValidBlockHeight: blockhash.lastValidBlockHeight, - signature + console.error('Error minting LP tokens:', error) } - yield* call([connection, connection.confirmTransaction], confirmStrategy) } export function* handleBurn(action: PayloadAction) { From 1de172225191b15208270ec9278d5fd70c656398 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 22 Aug 2024 04:32:52 +0200 Subject: [PATCH 4/4] unblock fee tiers --- .../Liquidity/FeeSwitch/FeeSwitch.tsx | 4 +-- .../components/Liquidity/FeeSwitch/style.ts | 4 --- .../src/components/Liquidity/Liquidity.tsx | 30 +++++++------------ 3 files changed, 12 insertions(+), 26 deletions(-) diff --git a/frontend/src/components/Liquidity/FeeSwitch/FeeSwitch.tsx b/frontend/src/components/Liquidity/FeeSwitch/FeeSwitch.tsx index 6abe18c..b02dbd4 100644 --- a/frontend/src/components/Liquidity/FeeSwitch/FeeSwitch.tsx +++ b/frontend/src/components/Liquidity/FeeSwitch/FeeSwitch.tsx @@ -55,10 +55,8 @@ export const FeeSwitch: React.FC = ({ singleTabClasses.root, index === bestTierIndex ? singleTabClasses.best : undefined ), - selected: singleTabClasses.selected, - disabled: singleTabClasses.disabled + selected: singleTabClasses.selected }} - disabled={index !== bestTierIndex} /> ))} diff --git a/frontend/src/components/Liquidity/FeeSwitch/style.ts b/frontend/src/components/Liquidity/FeeSwitch/style.ts index 8cc99b5..49d4998 100644 --- a/frontend/src/components/Liquidity/FeeSwitch/style.ts +++ b/frontend/src/components/Liquidity/FeeSwitch/style.ts @@ -95,10 +95,6 @@ export const useSingleTabStyles = makeStyles()(() => { '&:hover': { color: colors.white.main } - }, - disabled: { - ...typography.heading4, - color: '#3a466b' + ' !important' } } }) diff --git a/frontend/src/components/Liquidity/Liquidity.tsx b/frontend/src/components/Liquidity/Liquidity.tsx index 79ed844..b9d20c0 100644 --- a/frontend/src/components/Liquidity/Liquidity.tsx +++ b/frontend/src/components/Liquidity/Liquidity.tsx @@ -93,7 +93,7 @@ export const Liquidity: React.FC = ({ tickSpacing, // isWaitingForNewPool, poolIndex, - // bestTiers, + bestTiers, // canCreateNewPool, handleAddToken, commonTokens, @@ -182,19 +182,16 @@ export const Liquidity: React.FC = ({ return trimLeadingZeros(printBN(result, tokens[printIndex].decimals)) } - // const bestTierIndex = - // tokenAIndex === null || tokenBIndex === null - // ? undefined - // : (bestTiers.find( - // tier => - // (tier.tokenX.equals(tokens[tokenAIndex].assetAddress) && - // tier.tokenY.equals(tokens[tokenBIndex].assetAddress)) || - // (tier.tokenX.equals(tokens[tokenBIndex].assetAddress) && - // tier.tokenY.equals(tokens[tokenAIndex].assetAddress)) - // )?.bestTierIndex ?? undefined) - - // Temporary set best tier index as only available - const bestTierIndex = 2 + const bestTierIndex = + tokenAIndex === null || tokenBIndex === null + ? undefined + : (bestTiers.find( + tier => + (tier.tokenX.equals(tokens[tokenAIndex].assetAddress) && + tier.tokenY.equals(tokens[tokenBIndex].assetAddress)) || + (tier.tokenX.equals(tokens[tokenBIndex].assetAddress) && + tier.tokenY.equals(tokens[tokenAIndex].assetAddress)) + )?.bestTierIndex ?? undefined) const updatePath = ( index1: number | null, @@ -285,11 +282,6 @@ export const Liquidity: React.FC = ({ return '0' }, [tokenADeposit, tokenBDeposit, poolIndex]) - useEffect(() => { - if (bestTierIndex) { - setPositionTokens(tokenAIndex, tokenBIndex, bestTierIndex, true) - } - }, [bestTierIndex]) return ( {showNoConnected && }