From 1b77c3bb5c4b040b2edbe2818772e7dea09323e6 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 15 Jul 2024 12:25:25 +0200 Subject: [PATCH 01/75] add wallet reconnected snackbar --- .../HeaderWrapper/HeaderWrapper.tsx | 10 ++++---- src/store/reducers/wallet.ts | 4 +++- src/store/sagas/wallet.ts | 24 ++++++++++++++++--- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/containers/HeaderWrapper/HeaderWrapper.tsx b/src/containers/HeaderWrapper/HeaderWrapper.tsx index a67175d3..5c473264 100644 --- a/src/containers/HeaderWrapper/HeaderWrapper.tsx +++ b/src/containers/HeaderWrapper/HeaderWrapper.tsx @@ -22,14 +22,11 @@ export const HeaderWrapper: React.FC = () => { useEffect(() => { const fetchWallet = async () => { const wallet = await getAlephZeroWallet() - wallet.addListener('connect', () => { - dispatch(walletActions.connect()) - }) await wallet.canEagerConnect().then( async canEagerConnect => { if (canEagerConnect) { - dispatch(walletActions.connect()) + dispatch(walletActions.connect(true)) } }, error => { @@ -59,7 +56,10 @@ export const HeaderWrapper: React.FC = () => { dispatch(actions.setNetwork({ networkType: network, rpcAddress, rpcName })) } }} - onConnectWallet={openWalletSelectorModal} + onConnectWallet={async () => { + await openWalletSelectorModal() + dispatch(walletActions.connect(false)) + }} landing={location.pathname.substring(1)} walletConnected={walletStatus === Status.Initialized} onDisconnectWallet={() => { diff --git a/src/store/reducers/wallet.ts b/src/store/reducers/wallet.ts index 7bc2cf7a..f1c96cf1 100644 --- a/src/store/reducers/wallet.ts +++ b/src/store/reducers/wallet.ts @@ -76,7 +76,9 @@ const walletSlice = createSlice({ return state }, airdrop() {}, - connect() {}, + connect(state, _action: PayloadAction) { + return state + }, disconnect() {} } }) diff --git a/src/store/sagas/wallet.ts b/src/store/sagas/wallet.ts index 68c12994..a8f92d48 100644 --- a/src/store/sagas/wallet.ts +++ b/src/store/sagas/wallet.ts @@ -139,7 +139,7 @@ export function* handleAirdrop(): Generator { } } -export function* init(): Generator { +export function* init(isEagerConnect: boolean): Generator { try { yield* put(actions.setStatus(Status.Init)) @@ -147,6 +147,24 @@ export function* init(): Generator { yield* call([walletAdapter, walletAdapter.connect]) const accounts = yield* call([walletAdapter.accounts, walletAdapter.accounts.get]) + if (isEagerConnect) { + yield* put( + snackbarsActions.add({ + message: 'Wallet reconnected.', + variant: 'info', + persist: false + }) + ) + } else { + yield* put( + snackbarsActions.add({ + message: 'Wallet connected.', + variant: 'info', + persist: false + }) + ) + } + yield* put(actions.setAddress(accounts[0].address)) const allTokens = yield* select(tokens) @@ -162,7 +180,7 @@ export const sleep = (ms: number) => { return new Promise(resolve => setTimeout(resolve, ms)) } -export function* handleConnect(): Generator { +export function* handleConnect(action: PayloadAction): Generator { const walletStatus = yield* select(status) if (walletStatus === Status.Initialized) { yield* put( @@ -174,7 +192,7 @@ export function* handleConnect(): Generator { ) return } - yield* call(init) + yield* call(init, action.payload) } export function* handleDisconnect(): Generator { From eed71db7b8e26d32953ca8283924b10e77072748 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 15 Jul 2024 12:44:48 +0200 Subject: [PATCH 02/75] fix tests --- src/store/reducers/wallet.ts | 3 --- src/store/sagas/wallet.ts | 8 +------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/store/reducers/wallet.ts b/src/store/reducers/wallet.ts index f1c96cf1..016572e2 100644 --- a/src/store/reducers/wallet.ts +++ b/src/store/reducers/wallet.ts @@ -36,9 +36,6 @@ const walletSlice = createSlice({ resetState() { return defaultState }, - initWallet(state) { - return state - }, setAddress(state, action: PayloadAction) { state.address = action.payload return state diff --git a/src/store/sagas/wallet.ts b/src/store/sagas/wallet.ts index a8f92d48..827111ba 100644 --- a/src/store/sagas/wallet.ts +++ b/src/store/sagas/wallet.ts @@ -262,16 +262,10 @@ export function* airdropSaga(): Generator { yield takeLeading(actions.airdrop, handleAirdrop) } -export function* initSaga(): Generator { - yield takeLeading(actions.initWallet, init) -} - export function* getBalancesHandler(): Generator { yield takeLeading(actions.getBalances, handleGetBalances) } export function* walletSaga(): Generator { - yield all( - [initSaga, airdropSaga, connectHandler, disconnectHandler, getBalancesHandler].map(spawn) - ) + yield all([airdropSaga, connectHandler, disconnectHandler, getBalancesHandler].map(spawn)) } From 8b9e583c477f89b94dbc6e9e5083d77931478159 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 15 Jul 2024 13:54:55 +0200 Subject: [PATCH 03/75] merge init position sagas --- src/store/sagas/positions.ts | 210 ++++++----------------------------- 1 file changed, 32 insertions(+), 178 deletions(-) diff --git a/src/store/sagas/positions.ts b/src/store/sagas/positions.ts index a6c4a592..81d61dd2 100644 --- a/src/store/sagas/positions.ts +++ b/src/store/sagas/positions.ts @@ -34,7 +34,7 @@ import { } from '@store/reducers/positions' import { actions as snackbarsActions } from '@store/reducers/snackbars' import { actions as walletActions } from '@store/reducers/wallet' -import { invariantAddress } from '@store/selectors/connection' +import { invariantAddress, wrappedAZEROAddress } from '@store/selectors/connection' import { poolsArraySortedByFees, tickMaps, tokens } from '@store/selectors/pools' import { address, balance } from '@store/selectors/wallet' import { getAlephZeroWallet } from '@utils/web3/wallet' @@ -59,16 +59,8 @@ function* handleInitPosition(action: PayloadAction): Generator initPool, slippageTolerance } = action.payload - const { tokenX, tokenY, feeTier } = poolKeyData - if ( - (tokenX === TESTNET_WAZERO_ADDRESS && tokenXAmount !== 0n) || - (tokenY === TESTNET_WAZERO_ADDRESS && tokenYAmount !== 0n) - ) { - return yield* call(handleInitPositionWithAZERO, action) - } - const loaderCreatePosition = createLoaderKey() const loaderSigningTx = createLoaderKey() @@ -82,167 +74,18 @@ function* handleInitPosition(action: PayloadAction): Generator }) ) - const api = yield* getApi() const walletAddress = yield* select(address) const adapter = yield* call(getAlephZeroWallet) + const azeroBalance = yield* select(balance) const invAddress = yield* select(invariantAddress) - - const txs = [] - - const psp22 = yield* getPSP22() - - const [xAmountWithSlippage, yAmountWithSlippage] = calculateTokenAmountsWithSlippage( - feeTier.tickSpacing, - spotSqrtPrice, - liquidityDelta, - lowerTick, - upperTick, - slippageTolerance, - true - ) - - const XTokenTx = psp22.approveTx(invAddress, xAmountWithSlippage, tokenX, PSP22_APPROVE_OPTIONS) - txs.push(XTokenTx) - - const YTokenTx = psp22.approveTx(invAddress, yAmountWithSlippage, tokenY, PSP22_APPROVE_OPTIONS) - txs.push(YTokenTx) - - const invariant = yield* getInvariant() - - if (initPool) { - const createPoolTx = invariant.createPoolTx( - poolKeyData, - spotSqrtPrice, - INVARIANT_CREATE_POOL_OPTIONS - ) - txs.push(createPoolTx) - } - - const tx = invariant.createPositionTx( - poolKeyData, - lowerTick, - upperTick, - liquidityDelta, - spotSqrtPrice, - slippageTolerance, - INVARIANT_CREATE_POSITION_OPTIONS - ) - txs.push(tx) - - const batchedTx = api.tx.utility.batchAll(txs) - - yield put( - snackbarsActions.add({ - message: 'Signing transaction...', - variant: 'pending', - persist: true, - key: loaderSigningTx - }) - ) - - let signedBatchedTx: SubmittableExtrinsic - try { - signedBatchedTx = yield* call([batchedTx, batchedTx.signAsync], walletAddress, { - signer: adapter.signer as Signer - }) - } catch (e) { - throw new Error(ErrorMessage.TRANSACTION_SIGNING_ERROR) - } - - closeSnackbar(loaderSigningTx) - yield put(snackbarsActions.remove(loaderSigningTx)) - - const txResult = yield* call(sendTx, signedBatchedTx) - - yield* put(actions.setInitPositionSuccess(true)) - - closeSnackbar(loaderCreatePosition) - yield put(snackbarsActions.remove(loaderCreatePosition)) - - yield put( - snackbarsActions.add({ - message: 'Position successfully created', - variant: 'success', - persist: false, - txid: txResult.hash - }) - ) - - const { length } = yield* select(positionsList) - const position = yield* call([invariant, invariant.getPosition], walletAddress, length) - yield* put(actions.addPosition(position)) - - yield* call(fetchBalances, [tokenX, tokenY]) - - yield* put(poolsActions.getPoolKeys()) - } catch (e: unknown) { - const error = ensureError(e) - console.log(error) - - yield* put(actions.setInitPositionSuccess(false)) - - closeSnackbar(loaderCreatePosition) - yield put(snackbarsActions.remove(loaderCreatePosition)) - closeSnackbar(loaderSigningTx) - yield put(snackbarsActions.remove(loaderSigningTx)) - - if (isErrorMessage(error.message)) { - yield put( - snackbarsActions.add({ - message: error.message, - variant: 'error', - persist: false - }) - ) - } else { - yield put( - snackbarsActions.add({ - message: 'Failed to send. Please try again.', - variant: 'error', - persist: false - }) - ) - } - } -} - -function* handleInitPositionWithAZERO(action: PayloadAction): Generator { - const loaderCreatePosition = createLoaderKey() - const loaderSigningTx = createLoaderKey() - - const { - poolKeyData, - lowerTick, - upperTick, - spotSqrtPrice, - liquidityDelta, - initPool, - slippageTolerance - } = action.payload - - const { tokenX, tokenY, feeTier } = poolKeyData - - try { - yield put( - snackbarsActions.add({ - message: 'Creating position...', - variant: 'pending', - persist: true, - key: loaderCreatePosition - }) - ) + const wazeroAddress = yield* select(wrappedAZEROAddress) const api = yield* getApi() - const walletAddress = yield* select(address) - const adapter = yield* call(getAlephZeroWallet) - const invAddress = yield* select(invariantAddress) - const azeroBalance = yield* select(balance) - - const txs = [] - + const invariant = yield* getInvariant() + const psp22 = yield* getPSP22() const wazero = yield* getWrappedAZERO() - const psp22 = yield* getPSP22() + const txs = [] const [xAmountWithSlippage, yAmountWithSlippage] = calculateTokenAmountsWithSlippage( feeTier.tickSpacing, @@ -254,14 +97,20 @@ function* handleInitPositionWithAZERO(action: PayloadAction): true ) - let azeroAmount = 0n - if (tokenX === TESTNET_WAZERO_ADDRESS) { - azeroAmount = azeroBalance > xAmountWithSlippage ? xAmountWithSlippage : azeroBalance - } else { - azeroAmount = azeroBalance > yAmountWithSlippage ? yAmountWithSlippage : azeroBalance + if ( + (tokenX === wazeroAddress && tokenXAmount !== 0n) || + (tokenY === wazeroAddress && tokenYAmount !== 0n) + ) { + let azeroAmount = 0n + if (tokenX === wazeroAddress) { + azeroAmount = azeroBalance > xAmountWithSlippage ? xAmountWithSlippage : azeroBalance + } else { + azeroAmount = azeroBalance > yAmountWithSlippage ? yAmountWithSlippage : azeroBalance + } + + const depositTx = wazero.depositTx(azeroAmount, WAZERO_DEPOSIT_OPTIONS) + txs.push(depositTx) } - const depositTx = wazero.depositTx(azeroAmount, WAZERO_DEPOSIT_OPTIONS) - txs.push(depositTx) const XTokenTx = psp22.approveTx(invAddress, xAmountWithSlippage, tokenX, PSP22_APPROVE_OPTIONS) txs.push(XTokenTx) @@ -269,8 +118,6 @@ function* handleInitPositionWithAZERO(action: PayloadAction): const YTokenTx = psp22.approveTx(invAddress, yAmountWithSlippage, tokenY, PSP22_APPROVE_OPTIONS) txs.push(YTokenTx) - const invariant = yield* getInvariant() - if (initPool) { const createPoolTx = invariant.createPoolTx( poolKeyData, @@ -290,7 +137,6 @@ function* handleInitPositionWithAZERO(action: PayloadAction): INVARIANT_CREATE_POSITION_OPTIONS ) txs.push(tx) - const approveTx = psp22.approveTx( invAddress, U128MAX, @@ -312,6 +158,19 @@ function* handleInitPositionWithAZERO(action: PayloadAction): PSP22_APPROVE_OPTIONS ) txs.push(resetApproveTx) + if ( + (tokenX === wazeroAddress && tokenXAmount !== 0n) || + (tokenY === wazeroAddress && tokenYAmount !== 0n) + ) { + const approveTx = psp22.approveTx(invAddress, U128MAX, wazeroAddress, PSP22_APPROVE_OPTIONS) + txs.push(approveTx) + + const unwrapTx = invariant.withdrawAllWAZEROTx(wazeroAddress, INVARIANT_WITHDRAW_ALL_WAZERO) + txs.push(unwrapTx) + + const resetApproveTx = psp22.approveTx(invAddress, 0n, wazeroAddress, PSP22_APPROVE_OPTIONS) + txs.push(resetApproveTx) + } const batchedTx = api.tx.utility.batchAll(txs) @@ -492,11 +351,6 @@ export function* handleGetCurrentPlotTicks(action: PayloadAction) { const { index, addressTokenX, addressTokenY } = action.payload - if (addressTokenX === TESTNET_WAZERO_ADDRESS || addressTokenY === TESTNET_WAZERO_ADDRESS) { - yield* call(handleClaimFeeWithAZERO, action) - return - } - const loaderKey = createLoaderKey() const loaderSigningTx = createLoaderKey() try { From 8355fb2e4c32343f2812c37537715684844124c4 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 15 Jul 2024 14:07:32 +0200 Subject: [PATCH 04/75] merge claim fee sagas --- src/store/sagas/positions.ts | 44 ++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/store/sagas/positions.ts b/src/store/sagas/positions.ts index 81d61dd2..52261f25 100644 --- a/src/store/sagas/positions.ts +++ b/src/store/sagas/positions.ts @@ -353,6 +353,7 @@ export function* handleClaimFee(action: PayloadAction) { const loaderKey = createLoaderKey() const loaderSigningTx = createLoaderKey() + try { yield put( snackbarsActions.add({ @@ -362,13 +363,46 @@ export function* handleClaimFee(action: PayloadAction) { key: loaderKey }) ) + const walletAddress = yield* select(address) + const adapter = yield* call(getAlephZeroWallet) + const invAddress = yield* select(invariantAddress) + const wazeroAddress = yield* select(wrappedAZEROAddress) + const api = yield* getApi() const invariant = yield* getInvariant() + const psp22 = yield* getPSP22() - const adapter = yield* call(getAlephZeroWallet) + const txs = [] - const tx = invariant.claimFeeTx(index, INVARIANT_CLAIM_FEE_OPTIONS) + const claimTx = invariant.claimFeeTx(index, INVARIANT_CLAIM_FEE_OPTIONS) + txs.push(claimTx) + + if (addressTokenX === wazeroAddress || addressTokenY === wazeroAddress) { + const approveTx = psp22.approveTx( + invAddress, + U128MAX, + TESTNET_WAZERO_ADDRESS, + PSP22_APPROVE_OPTIONS + ) + txs.push(approveTx) + + const unwrapTx = invariant.withdrawAllWAZEROTx( + TESTNET_WAZERO_ADDRESS, + INVARIANT_WITHDRAW_ALL_WAZERO + ) + txs.push(unwrapTx) + + const resetApproveTx = psp22.approveTx( + invAddress, + 0n, + TESTNET_WAZERO_ADDRESS, + PSP22_APPROVE_OPTIONS + ) + txs.push(resetApproveTx) + } + + const batchedTx = api.tx.utility.batchAll(txs) yield put( snackbarsActions.add({ @@ -379,9 +413,9 @@ export function* handleClaimFee(action: PayloadAction) { }) ) - let signedTx: SubmittableExtrinsic + let signedBatchedTx: SubmittableExtrinsic try { - signedTx = yield* call([tx, tx.signAsync], walletAddress, { + signedBatchedTx = yield* call([batchedTx, batchedTx.signAsync], walletAddress, { signer: adapter.signer as Signer }) } catch (e) { @@ -391,7 +425,7 @@ export function* handleClaimFee(action: PayloadAction) { closeSnackbar(loaderSigningTx) yield put(snackbarsActions.remove(loaderSigningTx)) - const txResult = yield* call(sendTx, signedTx) + const txResult = yield* call(sendTx, signedBatchedTx) closeSnackbar(loaderKey) yield put(snackbarsActions.remove(loaderKey)) From 9bbd45947accb7451750aa58b2f433a624815e25 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 15 Jul 2024 14:15:37 +0200 Subject: [PATCH 05/75] merge close position sagas --- src/store/sagas/positions.ts | 243 ++--------------------------------- 1 file changed, 14 insertions(+), 229 deletions(-) diff --git a/src/store/sagas/positions.ts b/src/store/sagas/positions.ts index 52261f25..47bf677f 100644 --- a/src/store/sagas/positions.ts +++ b/src/store/sagas/positions.ts @@ -472,123 +472,6 @@ export function* handleClaimFee(action: PayloadAction) { } } -export function* handleClaimFeeWithAZERO(action: PayloadAction) { - const loaderKey = createLoaderKey() - const loaderSigningTx = createLoaderKey() - - try { - yield put( - snackbarsActions.add({ - message: 'Claiming fee...', - variant: 'pending', - persist: true, - key: loaderKey - }) - ) - - const walletAddress = yield* select(address) - const api = yield* getApi() - const invAddress = yield* select(invariantAddress) - const { index, addressTokenX, addressTokenY } = action.payload - - const invariant = yield* getInvariant() - const psp22 = yield* getPSP22() - const adapter = yield* call(getAlephZeroWallet) - - const txs = [] - const claimTx = invariant.claimFeeTx(index, INVARIANT_CLAIM_FEE_OPTIONS) - txs.push(claimTx) - - const approveTx = psp22.approveTx( - invAddress, - U128MAX, - TESTNET_WAZERO_ADDRESS, - PSP22_APPROVE_OPTIONS - ) - txs.push(approveTx) - - const unwrapTx = invariant.withdrawAllWAZEROTx( - TESTNET_WAZERO_ADDRESS, - INVARIANT_WITHDRAW_ALL_WAZERO - ) - txs.push(unwrapTx) - - const resetApproveTx = psp22.approveTx( - invAddress, - 0n, - TESTNET_WAZERO_ADDRESS, - PSP22_APPROVE_OPTIONS - ) - txs.push(resetApproveTx) - - const batchedTx = api.tx.utility.batchAll(txs) - - yield put( - snackbarsActions.add({ - message: 'Signing transaction...', - variant: 'pending', - persist: true, - key: loaderSigningTx - }) - ) - - let signedBatchedTx: SubmittableExtrinsic - try { - signedBatchedTx = yield* call([batchedTx, batchedTx.signAsync], walletAddress, { - signer: adapter.signer as Signer - }) - } catch (e) { - throw new Error(ErrorMessage.TRANSACTION_SIGNING_ERROR) - } - - closeSnackbar(loaderSigningTx) - yield put(snackbarsActions.remove(loaderSigningTx)) - - const txResult = yield* call(sendTx, signedBatchedTx) - - closeSnackbar(loaderKey) - yield put(snackbarsActions.remove(loaderKey)) - yield put( - snackbarsActions.add({ - message: 'Fee successfully created', - variant: 'success', - persist: false, - txid: txResult.hash - }) - ) - - yield put(actions.getSinglePosition(index)) - - yield* call(fetchBalances, [addressTokenX, addressTokenY]) - } catch (e: unknown) { - const error = ensureError(e) - console.log(error) - - closeSnackbar(loaderSigningTx) - yield put(snackbarsActions.remove(loaderSigningTx)) - closeSnackbar(loaderKey) - yield put(snackbarsActions.remove(loaderKey)) - - if (isErrorMessage(error.message)) { - yield put( - snackbarsActions.add({ - message: error.message, - variant: 'error', - persist: false - }) - ) - } else { - yield put( - snackbarsActions.add({ - message: 'Failed to close position. Please try again.', - variant: 'error', - persist: false - }) - ) - } - } -} - export function* handleGetSinglePosition(action: PayloadAction) { try { const walletAddress = yield* select(address) @@ -621,11 +504,6 @@ export function* handleGetSinglePosition(action: PayloadAction) { export function* handleClosePosition(action: PayloadAction) { const { addressTokenX, addressTokenY, onSuccess, positionIndex } = action.payload - if (addressTokenX === TESTNET_WAZERO_ADDRESS || addressTokenY === TESTNET_WAZERO_ADDRESS) { - yield* call(handleClosePositionWithAZERO, action) - return - } - const loaderKey = createLoaderKey() const loaderSigningTx = createLoaderKey() @@ -640,113 +518,15 @@ export function* handleClosePosition(action: PayloadAction) { ) const walletAddress = yield* select(address) - - const invariant = yield* getInvariant() const adapter = yield* call(getAlephZeroWallet) - const allPositions = yield* select(positionsList) - const getPositionsListPagePayload: PayloadAction<{ index: number; refresh: boolean }> = { - type: actions.getPositionsListPage.type, - payload: { - index: Math.floor(Number(allPositions.length) / POSITIONS_PER_QUERY), - refresh: false - } - } - const fetchTask = yield* fork(handleGetPositionsListPage, getPositionsListPagePayload) - yield* join(fetchTask) - - const tx = invariant.removePositionTx(positionIndex, INVARIANT_REMOVE_POSITION_OPTIONS) - - yield put( - snackbarsActions.add({ - message: 'Signing transaction...', - variant: 'pending', - persist: true, - key: loaderSigningTx - }) - ) - - let signedTx: SubmittableExtrinsic - try { - signedTx = yield* call([tx, tx.signAsync], walletAddress, { - signer: adapter.signer as Signer - }) - } catch (e) { - throw new Error(ErrorMessage.TRANSACTION_SIGNING_ERROR) - } - - closeSnackbar(loaderSigningTx) - yield put(snackbarsActions.remove(loaderSigningTx)) - - const txResult = yield* call(sendTx, signedTx) - - closeSnackbar(loaderKey) - yield put(snackbarsActions.remove(loaderKey)) - yield put( - snackbarsActions.add({ - message: 'Position successfully removed', - variant: 'success', - persist: false, - txid: txResult.hash - }) - ) - - yield* put(actions.removePosition(positionIndex)) - onSuccess() - - yield* call(fetchBalances, [addressTokenX, addressTokenY]) - } catch (e: unknown) { - const error = ensureError(e) - console.log(error) - - closeSnackbar(loaderSigningTx) - yield put(snackbarsActions.remove(loaderSigningTx)) - closeSnackbar(loaderKey) - yield put(snackbarsActions.remove(loaderKey)) - - if (isErrorMessage(error.message)) { - yield put( - snackbarsActions.add({ - message: error.message, - variant: 'error', - persist: false - }) - ) - } else { - yield put( - snackbarsActions.add({ - message: 'Failed to close position. Please try again.', - variant: 'error', - persist: false - }) - ) - } - } -} - -export function* handleClosePositionWithAZERO(action: PayloadAction) { - const loaderSigningTx = createLoaderKey() - const loaderKey = createLoaderKey() - - try { - yield put( - snackbarsActions.add({ - message: 'Removing position...', - variant: 'pending', - persist: true, - key: loaderKey - }) - ) + const invAddress = yield* select(invariantAddress) + const wazeroAddress = yield* select(wrappedAZEROAddress) - const { addressTokenX, addressTokenY, positionIndex, onSuccess } = action.payload - const walletAddress = yield* select(address) const api = yield* getApi() - const invAddress = yield* select(invariantAddress) const invariant = yield* getInvariant() const psp22 = yield* getPSP22() - const adapter = yield* call(getAlephZeroWallet) - const allPositions = yield* select(positionsList) const getPositionsListPagePayload: PayloadAction<{ index: number; refresh: boolean }> = { type: actions.getPositionsListPage.type, payload: { @@ -759,17 +539,22 @@ export function* handleClosePositionWithAZERO(action: PayloadAction Date: Mon, 15 Jul 2024 14:28:45 +0200 Subject: [PATCH 06/75] merge swap sagas --- src/store/sagas/swap.ts | 188 ++-------------------------------------- 1 file changed, 9 insertions(+), 179 deletions(-) diff --git a/src/store/sagas/swap.ts b/src/store/sagas/swap.ts index e861985a..ddf2132b 100644 --- a/src/store/sagas/swap.ts +++ b/src/store/sagas/swap.ts @@ -34,9 +34,8 @@ import { import { actions as poolActions } from '@store/reducers/pools' import { actions as snackbarsActions } from '@store/reducers/snackbars' import { Simulate, Swap, actions } from '@store/reducers/swap' -import { invariantAddress } from '@store/selectors/connection' +import { invariantAddress, wrappedAZEROAddress } from '@store/selectors/connection' import { poolTicks, pools, tickMaps, tokens } from '@store/selectors/pools' -import { simulateResult } from '@store/selectors/swap' import { address, balance } from '@store/selectors/wallet' import { getAlephZeroWallet } from '@utils/web3/wallet' import { closeSnackbar } from 'notistack' @@ -61,16 +60,10 @@ export function* handleSwap(action: PayloadAction>): Generato return } - if (poolKey.tokenX === TESTNET_WAZERO_ADDRESS || poolKey.tokenY === TESTNET_WAZERO_ADDRESS) { - return yield* call(handleSwapWithAZERO, action) - } - const loaderSwappingTokens = createLoaderKey() const loaderSigningTx = createLoaderKey() try { - const allTokens = yield* select(tokens) - yield put( snackbarsActions.add({ message: 'Swapping tokens...', @@ -80,174 +73,16 @@ export function* handleSwap(action: PayloadAction>): Generato }) ) - const api = yield* getApi() const walletAddress = yield* select(address) const adapter = yield* call(getAlephZeroWallet) - const invAddress = yield* select(invariantAddress) - - const tokenX = allTokens[poolKey.tokenX] - const tokenY = allTokens[poolKey.tokenY] - const xToY = tokenFrom.toString() === poolKey.tokenX - - const txs = [] - - const psp22 = yield* getPSP22() - const invariant = yield* getInvariant() - const sqrtPriceLimit = calculateSqrtPriceAfterSlippage(estimatedPriceAfterSwap, slippage, !xToY) - const calculatedAmountIn = slippage - ? calculateAmountInWithSlippage(amountOut, sqrtPriceLimit, xToY, poolKey.feeTier.fee) - : amountIn - - if (xToY) { - const approveTx = psp22.approveTx( - invAddress, - calculatedAmountIn, - tokenX.address.toString(), - PSP22_APPROVE_OPTIONS - ) - txs.push(approveTx) - } else { - const approveTx = psp22.approveTx( - invAddress, - calculatedAmountIn, - tokenY.address.toString(), - PSP22_APPROVE_OPTIONS - ) - txs.push(approveTx) - } - - const swapTx = invariant.swapWithSlippageTx( - poolKey, - xToY, - byAmountIn ? amountIn : amountOut, - byAmountIn, - estimatedPriceAfterSwap, - slippage, - INVARIANT_SWAP_OPTIONS - ) - txs.push(swapTx) - - const batchedTx = api.tx.utility.batchAll(txs) - - yield put( - snackbarsActions.add({ - message: 'Signing transaction...', - variant: 'pending', - persist: true, - key: loaderSigningTx - }) - ) - - let signedBatchedTx: SubmittableExtrinsic - try { - signedBatchedTx = yield* call([batchedTx, batchedTx.signAsync], walletAddress, { - signer: adapter.signer as Signer - }) - } catch (e) { - throw new Error(ErrorMessage.TRANSACTION_SIGNING_ERROR) - } - - closeSnackbar(loaderSigningTx) - yield put(snackbarsActions.remove(loaderSigningTx)) - - const txResult = yield* call(sendTx, signedBatchedTx) - - closeSnackbar(loaderSwappingTokens) - yield put(snackbarsActions.remove(loaderSwappingTokens)) - - yield put( - snackbarsActions.add({ - message: 'Tokens swapped successfully.', - variant: 'success', - persist: false, - txid: txResult.hash - }) - ) - - yield* call(fetchBalances, [poolKey.tokenX, poolKey.tokenY]) - - yield put(actions.setSwapSuccess(true)) - - yield put( - poolActions.getAllPoolsForPairData({ - first: tokenFrom, - second: tokenTo - }) - ) - } catch (e: unknown) { - const error = ensureError(e) - console.log(error) - - yield put(actions.setSwapSuccess(false)) - - closeSnackbar(loaderSwappingTokens) - yield put(snackbarsActions.remove(loaderSwappingTokens)) - closeSnackbar(loaderSigningTx) - yield put(snackbarsActions.remove(loaderSigningTx)) - - if (isErrorMessage(error.message)) { - yield put( - snackbarsActions.add({ - message: error.message, - variant: 'error', - persist: false - }) - ) - } else { - yield put( - snackbarsActions.add({ - message: 'Tokens swapping failed. Please try again.', - variant: 'error', - persist: false - }) - ) - } - - yield put( - poolActions.getAllPoolsForPairData({ - first: tokenFrom, - second: tokenTo - }) - ) - } -} - -export function* handleSwapWithAZERO(action: PayloadAction>): Generator { - const { - poolKey, - tokenFrom, - slippage, - amountIn, - amountOut, - byAmountIn, - estimatedPriceAfterSwap, - tokenTo - } = action.payload - - if (!poolKey) { - return - } - - const loaderSwappingTokens = createLoaderKey() - const loaderSigningTx = createLoaderKey() - - try { const allTokens = yield* select(tokens) - - yield put( - snackbarsActions.add({ - message: 'Swapping tokens...', - variant: 'pending', - persist: true, - key: loaderSwappingTokens - }) - ) + const invAddress = yield* select(invariantAddress) + const wazeroAddress = yield* select(wrappedAZEROAddress) const api = yield* getApi() - const walletAddress = yield* select(address) - const adapter = yield* call(getAlephZeroWallet) - const swapSimulateResult = yield* select(simulateResult) - const invAddress = yield* select(invariantAddress) + const invariant = yield* getInvariant() + const psp22 = yield* getPSP22() + const wazero = yield* getWrappedAZERO() const tokenX = allTokens[poolKey.tokenX] const tokenY = allTokens[poolKey.tokenY] @@ -255,9 +90,6 @@ export function* handleSwapWithAZERO(action: PayloadAction>): const txs = [] - const wazero = yield* getWrappedAZERO() - const psp22 = yield* getPSP22() - const invariant = yield* getInvariant() const sqrtPriceLimit = calculateSqrtPriceAfterSlippage(estimatedPriceAfterSwap, slippage, !xToY) const calculatedAmountIn = slippage ? calculateAmountInWithSlippage(amountOut, sqrtPriceLimit, xToY, poolKey.feeTier.fee) @@ -304,10 +136,10 @@ export function* handleSwapWithAZERO(action: PayloadAction>): txs.push(swapTx) if ( - (!xToY && poolKey.tokenX === TESTNET_WAZERO_ADDRESS) || + (!xToY && poolKey.tokenX === wazeroAddress) || (xToY && poolKey.tokenY === TESTNET_WAZERO_ADDRESS) ) { - const withdrawTx = wazero.withdrawTx(swapSimulateResult.amountOut, WAZERO_WITHDRAW_OPTIONS) + const withdrawTx = wazero.withdrawTx(amountOut, WAZERO_WITHDRAW_OPTIONS) txs.push(withdrawTx) } @@ -362,9 +194,7 @@ export function* handleSwapWithAZERO(action: PayloadAction>): }) ) - yield* call(fetchBalances, [ - poolKey.tokenX === TESTNET_WAZERO_ADDRESS ? poolKey.tokenY : poolKey.tokenX - ]) + yield* call(fetchBalances, [poolKey.tokenX, poolKey.tokenY]) yield put(actions.setSwapSuccess(true)) From 2c49227c734a5e9988100564c717547cb652e0f1 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 15 Jul 2024 14:37:23 +0200 Subject: [PATCH 07/75] change variant of wallet connected and reconnected snackbars from info to success --- src/store/sagas/wallet.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/store/sagas/wallet.ts b/src/store/sagas/wallet.ts index 827111ba..e74c17fe 100644 --- a/src/store/sagas/wallet.ts +++ b/src/store/sagas/wallet.ts @@ -151,7 +151,7 @@ export function* init(isEagerConnect: boolean): Generator { yield* put( snackbarsActions.add({ message: 'Wallet reconnected.', - variant: 'info', + variant: 'success', persist: false }) ) @@ -159,7 +159,7 @@ export function* init(isEagerConnect: boolean): Generator { yield* put( snackbarsActions.add({ message: 'Wallet connected.', - variant: 'info', + variant: 'success', persist: false }) ) From 268cefd24a01470541a0919b6e42f562e5261500 Mon Sep 17 00:00:00 2001 From: zielvna Date: Tue, 16 Jul 2024 13:06:48 +0200 Subject: [PATCH 08/75] add wallet disconnected snackbar --- src/store/sagas/wallet.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/store/sagas/wallet.ts b/src/store/sagas/wallet.ts index e74c17fe..c9135f06 100644 --- a/src/store/sagas/wallet.ts +++ b/src/store/sagas/wallet.ts @@ -202,6 +202,14 @@ export function* handleDisconnect(): Generator { yield* call(disconnectWallet) yield* put(actions.resetState()) + yield* put( + snackbarsActions.add({ + message: 'Wallet disconnected.', + variant: 'success', + persist: false + }) + ) + yield* put(positionsActions.setPositionsList([])) yield* put(positionsActions.setPositionsListLength(0n)) yield* put( From 2d4c3cef570c7b06f48d5b8a17877262d66dfdc3 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Tue, 16 Jul 2024 16:23:50 +0200 Subject: [PATCH 09/75] add addresses of tokens in modal --- .../SelectTokenModal/SelectTokenModal.tsx | 24 +++++++++++-- src/components/Modals/SelectModals/style.ts | 36 +++++++++++++------ src/static/icons.ts | 4 ++- src/static/svg/newTab.svg | 6 ++++ 4 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 src/static/svg/newTab.svg diff --git a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx index 3c2452be..bd620fdd 100644 --- a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx +++ b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx @@ -21,6 +21,7 @@ import { import { formatNumber, printBigint } from '@utils/utils' import { SwapToken } from '@store/selectors/wallet' import Scrollbars from 'rc-scrollbars' +import icons from '@static/icons' export interface ISelectTokenModal { tokens: SwapToken[] @@ -240,9 +241,28 @@ export const SelectTokenModal: React.FC = ({ src={token.logoURI} loading='lazy' alt={token.name + 'logo'} - />{' '} + /> - {token.symbol} + + {token.symbol} + + { + event.stopPropagation() + }}> + + {token.assetAddress.slice(0, 4) + + '...' + + token.assetAddress.slice(-5, -1)} + + {'Token + + + + {token.name ? token.name.slice(0, isXs ? 20 : 30) : 'Unknown token'} {token.name.length > (isXs ? 20 : 30) ? '...' : ''} diff --git a/src/components/Modals/SelectModals/style.ts b/src/components/Modals/SelectModals/style.ts index 6725970d..6641ffab 100644 --- a/src/components/Modals/SelectModals/style.ts +++ b/src/components/Modals/SelectModals/style.ts @@ -60,8 +60,7 @@ const useStyles = makeStyles()((theme: Theme) => { selectTokenInput: { backgroundColor: colors.invariant.newDark, width: '100%', - fontSize: 16, - fontWeight: 600, + ...typography.body3, position: 'relative', color: 'white', border: `1px solid ${colors.invariant.newDark}`, @@ -75,7 +74,7 @@ const useStyles = makeStyles()((theme: Theme) => { '&::placeholder': { color: colors.invariant.light, - ...typography.body1 + ...typography.body3 }, '&:focus': { outline: 'none' @@ -86,7 +85,7 @@ const useStyles = makeStyles()((theme: Theme) => { width: 24, height: 26, right: '12px', - top: '14px' + top: '18px' }, commonTokensHeader: { ...typography.body2 @@ -102,13 +101,13 @@ const useStyles = makeStyles()((theme: Theme) => { cursor: 'pointer', justifyContent: 'center', alignItems: 'center', - background: colors.invariant.dark, + background: colors.invariant.newDark, borderRadius: 12, padding: '6px 11px', marginRight: 6, marginBottom: 8, '& p': { - ...typography.heading4, + ...typography.body3, fontWeight: 400 }, @@ -153,12 +152,29 @@ const useStyles = makeStyles()((theme: Theme) => { }, tokenName: { color: colors.white.main, - ...typography.heading4, - lineHeight: '20px' + ...typography.heading3 + }, + tokenAddress: { + backgroundColor: colors.invariant.newDark, + borderRadius: 4, + padding: '2px 4px', + width: 'min-content', + height: 'min-content', + '& a': { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + gap: '12px', + textDecoration: 'none', + '& p': { + color: colors.invariant.lightGrey, + ...typography.caption4 + } + } }, tokenDescrpiption: { - color: colors.invariant.lightGrey, - ...typography.caption4, + color: colors.invariant.textGrey, + ...typography.caption2, lineHeight: '16px', whiteSpace: 'nowrap' }, diff --git a/src/static/icons.ts b/src/static/icons.ts index 52c1ee67..3d4a1ef6 100644 --- a/src/static/icons.ts +++ b/src/static/icons.ts @@ -22,6 +22,7 @@ import closeSmallIcon from './svg/closeSmall.svg' import successIcon from './svg/successIcon.svg' import xIcon from './svg/xCircle.svg' import unknownToken from './svg/unknownToken.svg' +import newTab from './svg/newTab.svg' const icons: { [key: string]: string } = { clear: clearIcon, @@ -47,7 +48,8 @@ const icons: { [key: string]: string } = { docsIcon: docsIcon, successIcon: successIcon, XIcon: xIcon, - unknownToken: unknownToken + unknownToken: unknownToken, + newTab: newTab } export default icons diff --git a/src/static/svg/newTab.svg b/src/static/svg/newTab.svg new file mode 100644 index 00000000..85d2e021 --- /dev/null +++ b/src/static/svg/newTab.svg @@ -0,0 +1,6 @@ + + + + + + From 57e8972352379aa8bb701c03856c0556297560db Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Tue, 16 Jul 2024 17:20:39 +0200 Subject: [PATCH 10/75] updated styles of select token modal --- .../SelectTokenModal/SelectTokenModal.tsx | 2 +- src/components/Modals/SelectModals/style.ts | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx index bd620fdd..8d5a45a4 100644 --- a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx +++ b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx @@ -212,7 +212,7 @@ export const SelectTokenModal: React.FC = ({ diff --git a/src/components/Modals/SelectModals/style.ts b/src/components/Modals/SelectModals/style.ts index 6641ffab..e982c874 100644 --- a/src/components/Modals/SelectModals/style.ts +++ b/src/components/Modals/SelectModals/style.ts @@ -103,7 +103,7 @@ const useStyles = makeStyles()((theme: Theme) => { alignItems: 'center', background: colors.invariant.newDark, borderRadius: 12, - padding: '6px 11px', + padding: '8px 12px', marginRight: 6, marginBottom: 8, '& p': { @@ -126,7 +126,7 @@ const useStyles = makeStyles()((theme: Theme) => { borderTop: `1px solid ${colors.invariant.light}`, width: 451, height: 352, - paddingTop: 20 + paddingTop: 8 }, tokenContainer: { @@ -137,10 +137,10 @@ const useStyles = makeStyles()((theme: Theme) => { tokenItem: { display: 'flex', justifyContent: 'space-between', - margin: '0 0 2px 0', - borderRadius: 10, + marginBottom: 4, + borderRadius: 24, cursor: 'pointer', - padding: 12, + padding: '35px 16px ', '& > p': { whiteSpace: 'nowrap' }, @@ -180,8 +180,8 @@ const useStyles = makeStyles()((theme: Theme) => { }, tokenBalanceStatus: { filter: 'brightness(0.8)', - color: colors.invariant.lightGrey, - ...typography.caption2, + color: colors.invariant.textGrey, + ...typography.body2, minWidth: 'auto' }, From 958f412ff6d8807389f2c777d45877ace19d0ed8 Mon Sep 17 00:00:00 2001 From: zielvna Date: Wed, 17 Jul 2024 11:17:46 +0200 Subject: [PATCH 11/75] update all connect wallet buttons --- src/containers/NewPositionWrapper/NewPositionWrapper.tsx | 5 ++++- .../WrappedPositionsList/WrappedPositionsList.tsx | 6 +++++- src/containers/WrappedSwap/WrappedSwap.tsx | 5 ++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/containers/NewPositionWrapper/NewPositionWrapper.tsx b/src/containers/NewPositionWrapper/NewPositionWrapper.tsx index bbced9f1..f8557b96 100644 --- a/src/containers/NewPositionWrapper/NewPositionWrapper.tsx +++ b/src/containers/NewPositionWrapper/NewPositionWrapper.tsx @@ -700,7 +700,10 @@ export const NewPositionWrapper: React.FC = ({ }} showNoConnected={walletStatus !== Status.Initialized} noConnectedBlockerProps={{ - onConnect: openWalletSelectorModal, + onConnect: async () => { + await openWalletSelectorModal() + dispatch(walletActions.connect(false)) + }, descCustomText: 'Cannot add any liquidity.' }} poolKey={poolKey} diff --git a/src/containers/WrappedPositionsList/WrappedPositionsList.tsx b/src/containers/WrappedPositionsList/WrappedPositionsList.tsx index 8e003f06..bd4f2609 100644 --- a/src/containers/WrappedPositionsList/WrappedPositionsList.tsx +++ b/src/containers/WrappedPositionsList/WrappedPositionsList.tsx @@ -9,6 +9,7 @@ import { calcPriceBySqrtPrice } from '@utils/utils' import { actions } from '@store/reducers/positions' +import { actions as walletActions } from '@store/reducers/wallet' import { Status } from '@store/reducers/wallet' import { isLoadingPositionsList, @@ -158,7 +159,10 @@ export const WrappedPositionsList: React.FC = () => { showNoConnected={walletStatus !== Status.Initialized} itemsPerPage={POSITIONS_PER_PAGE} noConnectedBlockerProps={{ - onConnect: openWalletSelectorModal, + onConnect: async () => { + await openWalletSelectorModal() + dispatch(walletActions.connect(false)) + }, descCustomText: 'You have no positions.' }} pageChanged={page => { diff --git a/src/containers/WrappedSwap/WrappedSwap.tsx b/src/containers/WrappedSwap/WrappedSwap.tsx index 1f3b0b47..1ee2e111 100644 --- a/src/containers/WrappedSwap/WrappedSwap.tsx +++ b/src/containers/WrappedSwap/WrappedSwap.tsx @@ -303,7 +303,10 @@ export const WrappedSwap = () => { ) } }} - onConnectWallet={openWalletSelectorModal} + onConnectWallet={async () => { + await openWalletSelectorModal() + dispatch(walletActions.connect(false)) + }} onDisconnectWallet={() => { dispatch(walletActions.disconnect()) }} From 3b7af53c99245622ef98e17da321feee8abd84a4 Mon Sep 17 00:00:00 2001 From: zielvna Date: Wed, 17 Jul 2024 11:40:11 +0200 Subject: [PATCH 12/75] refactor init position --- src/store/sagas/positions.ts | 62 +++++++----------------------------- 1 file changed, 12 insertions(+), 50 deletions(-) diff --git a/src/store/sagas/positions.ts b/src/store/sagas/positions.ts index 47bf677f..ecb47586 100644 --- a/src/store/sagas/positions.ts +++ b/src/store/sagas/positions.ts @@ -1,4 +1,4 @@ -import { Pool, Position, TESTNET_WAZERO_ADDRESS, sendTx } from '@invariant-labs/a0-sdk' +import { Pool, Position, sendTx } from '@invariant-labs/a0-sdk' import { Signer } from '@polkadot/api/types' import { PayloadAction } from '@reduxjs/toolkit' import { @@ -101,12 +101,9 @@ function* handleInitPosition(action: PayloadAction): Generator (tokenX === wazeroAddress && tokenXAmount !== 0n) || (tokenY === wazeroAddress && tokenYAmount !== 0n) ) { - let azeroAmount = 0n - if (tokenX === wazeroAddress) { - azeroAmount = azeroBalance > xAmountWithSlippage ? xAmountWithSlippage : azeroBalance - } else { - azeroAmount = azeroBalance > yAmountWithSlippage ? yAmountWithSlippage : azeroBalance - } + const isTokenX = tokenX === wazeroAddress + const slippageAmount = isTokenX ? xAmountWithSlippage : yAmountWithSlippage + const azeroAmount = azeroBalance > slippageAmount ? slippageAmount : azeroBalance const depositTx = wazero.depositTx(azeroAmount, WAZERO_DEPOSIT_OPTIONS) txs.push(depositTx) @@ -137,27 +134,7 @@ function* handleInitPosition(action: PayloadAction): Generator INVARIANT_CREATE_POSITION_OPTIONS ) txs.push(tx) - const approveTx = psp22.approveTx( - invAddress, - U128MAX, - TESTNET_WAZERO_ADDRESS, - PSP22_APPROVE_OPTIONS - ) - txs.push(approveTx) - - const unwrapTx = invariant.withdrawAllWAZEROTx( - TESTNET_WAZERO_ADDRESS, - INVARIANT_WITHDRAW_ALL_WAZERO - ) - txs.push(unwrapTx) - const resetApproveTx = psp22.approveTx( - invAddress, - 0n, - TESTNET_WAZERO_ADDRESS, - PSP22_APPROVE_OPTIONS - ) - txs.push(resetApproveTx) if ( (tokenX === wazeroAddress && tokenXAmount !== 0n) || (tokenY === wazeroAddress && tokenYAmount !== 0n) @@ -218,7 +195,7 @@ function* handleInitPosition(action: PayloadAction): Generator const position = yield* call([invariant, invariant.getPosition], walletAddress, length) yield* put(actions.addPosition(position)) - yield* call(fetchBalances, [tokenX === TESTNET_WAZERO_ADDRESS ? tokenY : tokenX]) + yield* call(fetchBalances, [tokenX === wazeroAddress ? tokenY : tokenX]) yield* put(poolsActions.getPoolKeys()) } catch (e: unknown) { @@ -379,26 +356,13 @@ export function* handleClaimFee(action: PayloadAction) { txs.push(claimTx) if (addressTokenX === wazeroAddress || addressTokenY === wazeroAddress) { - const approveTx = psp22.approveTx( - invAddress, - U128MAX, - TESTNET_WAZERO_ADDRESS, - PSP22_APPROVE_OPTIONS - ) + const approveTx = psp22.approveTx(invAddress, U128MAX, wazeroAddress, PSP22_APPROVE_OPTIONS) txs.push(approveTx) - const unwrapTx = invariant.withdrawAllWAZEROTx( - TESTNET_WAZERO_ADDRESS, - INVARIANT_WITHDRAW_ALL_WAZERO - ) + const unwrapTx = invariant.withdrawAllWAZEROTx(wazeroAddress, INVARIANT_WITHDRAW_ALL_WAZERO) txs.push(unwrapTx) - const resetApproveTx = psp22.approveTx( - invAddress, - 0n, - TESTNET_WAZERO_ADDRESS, - PSP22_APPROVE_OPTIONS - ) + const resetApproveTx = psp22.approveTx(invAddress, 0n, wazeroAddress, PSP22_APPROVE_OPTIONS) txs.push(resetApproveTx) } @@ -440,9 +404,7 @@ export function* handleClaimFee(action: PayloadAction) { yield put(actions.getSinglePosition(index)) - yield* call(fetchBalances, [ - addressTokenX === TESTNET_WAZERO_ADDRESS ? addressTokenY : addressTokenX - ]) + yield* call(fetchBalances, [addressTokenX === wazeroAddress ? addressTokenY : addressTokenX]) } catch (e: unknown) { const error = ensureError(e) console.log(error) @@ -546,13 +508,13 @@ export function* handleClosePosition(action: PayloadAction) { txs.push(removePositionTx) if (addressTokenX === wazeroAddress || addressTokenY === wazeroAddress) { - const approveTx = psp22.approveTx(invAddress, U128MAX, TESTNET_WAZERO_ADDRESS) + const approveTx = psp22.approveTx(invAddress, U128MAX, wazeroAddress) txs.push(approveTx) - const unwrapTx = invariant.withdrawAllWAZEROTx(TESTNET_WAZERO_ADDRESS) + const unwrapTx = invariant.withdrawAllWAZEROTx(wazeroAddress) txs.push(unwrapTx) - const resetApproveTx = psp22.approveTx(invAddress, 0n, TESTNET_WAZERO_ADDRESS) + const resetApproveTx = psp22.approveTx(invAddress, 0n, wazeroAddress) txs.push(resetApproveTx) } From a0453c9edc98167eb1928ed49a2363a29a078068 Mon Sep 17 00:00:00 2001 From: zielvna Date: Wed, 17 Jul 2024 18:34:39 +0200 Subject: [PATCH 13/75] allow users to show only their positions on plot --- .../NewPosition/NewPosition.stories.tsx | 6 +- src/components/NewPosition/NewPosition.tsx | 8 +- .../RangeSelector/RangeSelector.stories.tsx | 4 +- .../RangeSelector/RangeSelector.tsx | 24 +++++- .../NewPosition/RangeSelector/style.ts | 5 ++ .../NewPositionWrapper/NewPositionWrapper.tsx | 32 +++++-- src/store/reducers/positions.ts | 1 + src/store/sagas/positions.ts | 84 +++++++++++++++++-- 8 files changed, 146 insertions(+), 18 deletions(-) diff --git a/src/components/NewPosition/NewPosition.stories.tsx b/src/components/NewPosition/NewPosition.stories.tsx index c5c7e618..45a40b92 100644 --- a/src/components/NewPosition/NewPosition.stories.tsx +++ b/src/components/NewPosition/NewPosition.stories.tsx @@ -73,7 +73,9 @@ export const Primary: Story = { isBalanceLoading: false, shouldNotUpdatePriceRange: false, unblockUpdatePriceRange: fn(), - isGetLiquidityError: false + isGetLiquidityError: false, + onlyUserPositions: false, + setOnlyUserPositions: fn() }, render: () => { return ( @@ -132,6 +134,8 @@ export const Primary: Story = { shouldNotUpdatePriceRange={false} unblockUpdatePriceRange={fn()} isGetLiquidityError={false} + onlyUserPositions={false} + setOnlyUserPositions={fn()} /> ) } diff --git a/src/components/NewPosition/NewPosition.tsx b/src/components/NewPosition/NewPosition.tsx index 205c57d7..51fab233 100644 --- a/src/components/NewPosition/NewPosition.tsx +++ b/src/components/NewPosition/NewPosition.tsx @@ -101,6 +101,8 @@ export interface INewPosition { shouldNotUpdatePriceRange: boolean unblockUpdatePriceRange: () => void isGetLiquidityError: boolean + onlyUserPositions: boolean + setOnlyUserPositions: (val: boolean) => void } export const NewPosition: React.FC = ({ @@ -152,7 +154,9 @@ export const NewPosition: React.FC = ({ isBalanceLoading, shouldNotUpdatePriceRange, unblockUpdatePriceRange, - isGetLiquidityError + isGetLiquidityError, + onlyUserPositions, + setOnlyUserPositions }) => { const { classes } = useStyles() const navigate = useNavigate() @@ -733,6 +737,8 @@ export const NewPosition: React.FC = ({ setShouldReversePlot={setShouldReversePlot} shouldNotUpdatePriceRange={shouldNotUpdatePriceRange} unblockUpdatePriceRange={unblockUpdatePriceRange} + onlyUserPositions={onlyUserPositions} + setOnlyUserPositions={setOnlyUserPositions} /> ) : ( { const [concentrationIndex, setConcentrationIndex] = useState(2) diff --git a/src/components/NewPosition/RangeSelector/RangeSelector.tsx b/src/components/NewPosition/RangeSelector/RangeSelector.tsx index a7a19eb9..d9758899 100644 --- a/src/components/NewPosition/RangeSelector/RangeSelector.tsx +++ b/src/components/NewPosition/RangeSelector/RangeSelector.tsx @@ -2,7 +2,7 @@ import RangeInput from '@components/Inputs/RangeInput/RangeInput' import PlotTypeSwitch from '@components/PlotTypeSwitch/PlotTypeSwitch' import PriceRangePlot from '@components/PriceRangePlot/PriceRangePlot' import { getMaxTick, getMinTick } from '@invariant-labs/a0-sdk' -import { Button, Grid, Tooltip, Typography } from '@mui/material' +import { Button, Checkbox, FormControlLabel, Grid, Tooltip, Typography } from '@mui/material' import loader from '@static/gif/loader.gif' import activeLiquidity from '@static/svg/activeLiquidity.svg' import { @@ -54,6 +54,8 @@ export interface IRangeSelector { setShouldReversePlot: (val: boolean) => void shouldNotUpdatePriceRange: boolean unblockUpdatePriceRange: () => void + onlyUserPositions: boolean + setOnlyUserPositions: (onlyUserPositions: boolean) => void } export const RangeSelector: React.FC = ({ @@ -84,7 +86,9 @@ export const RangeSelector: React.FC = ({ shouldReversePlot, setShouldReversePlot, shouldNotUpdatePriceRange, - unblockUpdatePriceRange + unblockUpdatePriceRange, + onlyUserPositions, + setOnlyUserPositions }) => { const { classes } = useStyles() @@ -427,7 +431,7 @@ export const RangeSelector: React.FC = ({ - + = ({ hasError={hasTicksError} reloadHandler={reloadHandler} /> + { + setOnlyUserPositions(!onlyUserPositions) + }} + name='onlyUserPositions' + color='secondary' + /> + } + label='Only your positions' + classes={{ label: classes.checkboxLabel }} + /> Set price range { color: colors.invariant.yellow, ...typography.caption2, textAlign: 'right' + }, + checkboxLabel: { + color: colors.invariant.textGrey, + fontSize: 14, + fontWeight: 'normal' } } }) diff --git a/src/containers/NewPositionWrapper/NewPositionWrapper.tsx b/src/containers/NewPositionWrapper/NewPositionWrapper.tsx index bbced9f1..73b99fe1 100644 --- a/src/containers/NewPositionWrapper/NewPositionWrapper.tsx +++ b/src/containers/NewPositionWrapper/NewPositionWrapper.tsx @@ -144,7 +144,8 @@ export const NewPositionWrapper: React.FC = ({ isXtoY: allPools[poolIndex].poolKey.tokenX === tokens[currentPairReversed === true ? tokenBIndex : tokenAIndex].assetAddress, - disableLoading: true + disableLoading: true, + onlyUserPositions }) ) } @@ -245,7 +246,8 @@ export const NewPositionWrapper: React.FC = ({ positionsActions.getCurrentPlotTicks({ poolKey: allPoolKeys[poolKey], isXtoY, - fetchTicksAndTickmap: true + fetchTicksAndTickmap: true, + onlyUserPositions }) ) } @@ -529,13 +531,29 @@ export const NewPositionWrapper: React.FC = ({ isXtoY: allPools[poolIndex].poolKey.tokenX === tokens[currentPairReversed === true ? tokenBIndex : tokenAIndex].assetAddress, - fetchTicksAndTickmap: true + fetchTicksAndTickmap: true, + onlyUserPositions }) ) } } } + const [onlyUserPositions, setOnlyUserPositions] = useState(true) + + useEffect(() => { + if (poolKey !== '') { + dispatch( + positionsActions.getCurrentPlotTicks({ + poolKey: allPoolKeys[poolKey], + isXtoY, + fetchTicksAndTickmap: true, + onlyUserPositions + }) + ) + } + }, [onlyUserPositions]) + return ( = ({ dispatch( positionsActions.getCurrentPlotTicks({ poolKey: allPoolKeys[poolKey], - isXtoY: allPoolKeys[poolKey].tokenX === tokens[tokenAIndex].assetAddress.toString() + isXtoY: allPoolKeys[poolKey].tokenX === tokens[tokenAIndex].assetAddress.toString(), + onlyUserPositions }) ) } else if ( @@ -657,7 +676,8 @@ export const NewPositionWrapper: React.FC = ({ poolKey: allPoolKeys[poolKey], isXtoY: allPools[poolIndex].poolKey.tokenX === - tokens[currentPairReversed === true ? tokenBIndex : tokenAIndex].assetAddress + tokens[currentPairReversed === true ? tokenBIndex : tokenAIndex].assetAddress, + onlyUserPositions }) ) } @@ -709,6 +729,8 @@ export const NewPositionWrapper: React.FC = ({ shouldNotUpdatePriceRange={shouldNotUpdatePriceRange} unblockUpdatePriceRange={unblockUpdatePriceRange} isGetLiquidityError={isGetLiquidityError} + onlyUserPositions={onlyUserPositions} + setOnlyUserPositions={setOnlyUserPositions} /> ) } diff --git a/src/store/reducers/positions.ts b/src/store/reducers/positions.ts index 294fbfac..27e4e0d4 100644 --- a/src/store/reducers/positions.ts +++ b/src/store/reducers/positions.ts @@ -58,6 +58,7 @@ export interface GetCurrentTicksData { isXtoY: boolean fetchTicksAndTickmap?: boolean disableLoading?: boolean + onlyUserPositions?: boolean } export interface ClosePositionData { diff --git a/src/store/sagas/positions.ts b/src/store/sagas/positions.ts index a6c4a592..a9735a2f 100644 --- a/src/store/sagas/positions.ts +++ b/src/store/sagas/positions.ts @@ -1,4 +1,10 @@ -import { Pool, Position, TESTNET_WAZERO_ADDRESS, sendTx } from '@invariant-labs/a0-sdk' +import { + LiquidityTick, + Pool, + Position, + TESTNET_WAZERO_ADDRESS, + sendTx +} from '@invariant-labs/a0-sdk' import { Signer } from '@polkadot/api/types' import { PayloadAction } from '@reduxjs/toolkit' import { @@ -412,7 +418,7 @@ export function* handleGetCurrentPositionTicks(action: PayloadAction): Generator { - const { poolKey, isXtoY, fetchTicksAndTickmap } = action.payload + const { poolKey, isXtoY, fetchTicksAndTickmap, onlyUserPositions } = action.payload let allTickmaps = yield* select(tickMaps) const allTokens = yield* select(tokens) const allPools = yield* select(poolsArraySortedByFees) @@ -451,11 +457,75 @@ export function* handleGetCurrentPlotTicks(action: PayloadAction { + if (poolKeyToString(position.poolKey) !== poolKeyToString(poolKey)) { + return + } + + if (!ticks[Number(position.lowerTickIndex)]) { + ticks[Number(position.lowerTickIndex)] = { + liquidityChange: position.liquidity, + sign: true + } + } + + if (!ticks[Number(position.upperTickIndex)]) { + ticks[Number(position.upperTickIndex)] = { + liquidityChange: position.liquidity, + sign: false + } + } + + if (ticks[Number(position.lowerTickIndex)].sign) { + ticks[Number(position.lowerTickIndex)].liquidityChange += position.liquidity + } else { + if (ticks[Number(position.lowerTickIndex)].liquidityChange - position.liquidity < 0) { + ticks[Number(position.lowerTickIndex)] = { + liquidityChange: + ticks[Number(position.lowerTickIndex)].liquidityChange - position.liquidity, + sign: true + } + } else { + ticks[Number(position.lowerTickIndex)].liquidityChange - position.liquidity + } + } + + if (!ticks[Number(position.upperTickIndex)].sign) { + ticks[Number(position.upperTickIndex)].liquidityChange += position.liquidity + } else { + if (ticks[Number(position.upperTickIndex)].liquidityChange - position.liquidity < 0) { + ticks[Number(position.upperTickIndex)] = { + liquidityChange: + ticks[Number(position.upperTickIndex)].liquidityChange - position.liquidity, + sign: false + } + } else { + ticks[Number(position.upperTickIndex)].liquidityChange - position.liquidity + } + } + }) + + rawTicks = Object.entries(ticks).map(([index, { liquidityChange, sign }]) => ({ + index: BigInt(index), + liquidityChange, + sign + })) + } else { + rawTicks = yield* call( + [invariant, invariant.getAllLiquidityTicks], + poolKey, + deserializeTickmap(allTickmaps[poolKeyToString(poolKey)]) + ) + } + if (rawTicks.length === 0) { const data = createPlaceholderLiquidityPlot( action.payload.isXtoY, From c8dd44128fbc74851bd7bce87b644380e6919092 Mon Sep 17 00:00:00 2001 From: zielvna Date: Thu, 18 Jul 2024 10:37:22 +0200 Subject: [PATCH 14/75] make only your positions checkbox unchecked by default --- src/containers/NewPositionWrapper/NewPositionWrapper.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/NewPositionWrapper/NewPositionWrapper.tsx b/src/containers/NewPositionWrapper/NewPositionWrapper.tsx index 73b99fe1..2ba7179f 100644 --- a/src/containers/NewPositionWrapper/NewPositionWrapper.tsx +++ b/src/containers/NewPositionWrapper/NewPositionWrapper.tsx @@ -539,7 +539,7 @@ export const NewPositionWrapper: React.FC = ({ } } - const [onlyUserPositions, setOnlyUserPositions] = useState(true) + const [onlyUserPositions, setOnlyUserPositions] = useState(false) useEffect(() => { if (poolKey !== '') { From d577fead104566fe4fd94660392a46fd2b9aac7e Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 18 Jul 2024 11:03:35 +0200 Subject: [PATCH 15/75] add horizontal grid to stats charts --- src/components/Stats/Liquidity/Liquidity.tsx | 20 ++++++-- src/components/Stats/Liquidity/style.ts | 1 + src/components/Stats/Volume/Volume.tsx | 18 +++++-- src/pages/StatsPage/index.tsx | 5 +- src/utils/utils.ts | 50 ++++++++++---------- 5 files changed, 59 insertions(+), 35 deletions(-) diff --git a/src/components/Stats/Liquidity/Liquidity.tsx b/src/components/Stats/Liquidity/Liquidity.tsx index 3fe47e5f..869e1728 100644 --- a/src/components/Stats/Liquidity/Liquidity.tsx +++ b/src/components/Stats/Liquidity/Liquidity.tsx @@ -6,7 +6,7 @@ import { colors } from '@static/theme' import { useStyles } from './style' import { TimeData } from '@store/reducers/stats' import { Grid, Typography } from '@mui/material' -import { formatNumbers, showPrefix } from '@utils/utils' +import { formatNumber, formatNumbers, showPrefix } from '@utils/utils' interface LiquidityInterface { liquidityPercent: number @@ -66,7 +66,7 @@ const Liquidity: React.FC = ({ })) } ]} - margin={{ top: 24, bottom: 24, left: 24, right: 24 }} + margin={{ top: 24, bottom: 24, left: 30, right: 24 }} xScale={{ type: 'time', format: '%d/%m/%Y', @@ -81,14 +81,23 @@ const Liquidity: React.FC = ({ data.length >= 24 ? 'every 4 days' : data.length >= 8 ? 'every 2 days' : 'every day', format: '%d/%m' }} + axisLeft={{ + tickSize: 0, + tickPadding: 2, + tickRotation: 0, + format: volume => { + return formatNumber(volume, true) + }, + tickValues: 5 + }} + gridYValues={5} legends={[]} axisTop={null} axisRight={null} - axisLeft={null} curve={'monotoneX'} role='aplication' enableGridX={false} - enableGridY={false} + enableGridY={true} enablePoints={false} enableArea={true} isInteractive @@ -108,7 +117,8 @@ const Liquidity: React.FC = ({ strokeWidth: 1, strokeDasharray: 'solid' } - } + }, + grid: { line: { stroke: colors.invariant.light } } }} lineWidth={1} defs={[ diff --git a/src/components/Stats/Liquidity/style.ts b/src/components/Stats/Liquidity/style.ts index 0943aec5..0d1bd513 100644 --- a/src/components/Stats/Liquidity/style.ts +++ b/src/components/Stats/Liquidity/style.ts @@ -7,6 +7,7 @@ export const useStyles = makeStyles()(() => ({ color: 'white', borderRadius: 24, paddingBlock: 24, + paddingLeft: 24, boxSizing: 'border-box' }, liquidityContainer: { diff --git a/src/components/Stats/Volume/Volume.tsx b/src/components/Stats/Volume/Volume.tsx index 0f1fb915..402f7ef2 100644 --- a/src/components/Stats/Volume/Volume.tsx +++ b/src/components/Stats/Volume/Volume.tsx @@ -7,7 +7,7 @@ import { useStyles } from './style' import { TimeData } from '@store/reducers/stats' import { Grid, Typography, useMediaQuery } from '@mui/material' import { Box } from '@mui/system' -import { formatNumbers, showPrefix } from '@utils/utils' +import { formatNumber, formatNumbers, showPrefix } from '@utils/utils' interface StatsInterface { percentVolume: number @@ -28,7 +28,7 @@ const Volume: React.FC = ({ percentVolume, volume, data, classNa ticks: { line: { stroke: colors.invariant.component }, text: { fill: '#A9B6BF' } }, legend: { text: { stroke: 'transparent' } } }, - grid: { line: { stroke: 'transparent' } } + grid: { line: { stroke: colors.invariant.light } } } const isLower = percentVolume < 0 @@ -62,7 +62,7 @@ const Volume: React.FC = ({ percentVolume, volume, data, classNa
} keys={['value']} indexBy='timestamp' @@ -84,10 +84,20 @@ const Volume: React.FC = ({ percentVolume, volume, data, classNa : '' } }} + axisLeft={{ + tickSize: 0, + tickPadding: 2, + tickRotation: 0, + format: volume => { + return formatNumber(volume, true) + }, + tickValues: 5 + }} + gridYValues={5} theme={Theme} groupMode='grouped' enableLabel={false} - enableGridY={false} + enableGridY={true} innerPadding={isXsDown ? 1 : 2} isInteractive padding={0.03} diff --git a/src/pages/StatsPage/index.tsx b/src/pages/StatsPage/index.tsx index b650c2a9..329f0a60 100644 --- a/src/pages/StatsPage/index.tsx +++ b/src/pages/StatsPage/index.tsx @@ -1,6 +1,7 @@ import { Grid } from '@mui/material' import { useStyles } from './styles' import workInProgress from '../../static/png/work-in-progress.png' +import WrappedStats from '@containers/WrappedStats/WrappedStats' // import WrappedStats from '@containers/WrappedStats/WrappedStats' export const StatsPage: React.FC = () => { @@ -8,8 +9,8 @@ export const StatsPage: React.FC = () => { return ( - Work in progress icon - {/* */} + {/* Work in progress icon */} + ) } diff --git a/src/utils/utils.ts b/src/utils/utils.ts index bb7ac821..6512d7f0 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -857,7 +857,7 @@ export const createLiquidityPlot = ( return isXtoY ? ticksData : ticksData.reverse() } -export const formatNumber = (number: number | bigint | string): string => { +export const formatNumber = (number: number | bigint | string, noDecimals?: boolean): string => { const numberAsNumber = Number(number) const isNegative = numberAsNumber < 0 const absNumberAsString = numberToString(Math.abs(numberAsNumber)) @@ -871,32 +871,34 @@ export const formatNumber = (number: number | bigint | string): string => { let formattedNumber if (Math.abs(numberAsNumber) > FormatConfig.B) { + const formattedDecimals = noDecimals + ? '' + : (FormatConfig.DecimalsAfterDot ? '.' : '') + + (beforeDot.slice(-FormatConfig.BDecimals) + (afterDot ? afterDot : '')).slice( + 0, + FormatConfig.DecimalsAfterDot + ) formattedNumber = - beforeDot.slice(0, -FormatConfig.BDecimals) + - (FormatConfig.DecimalsAfterDot ? '.' : '') + - (beforeDot.slice(-FormatConfig.BDecimals) + (afterDot ? afterDot : '')).slice( - 0, - FormatConfig.DecimalsAfterDot - ) + - 'B' + beforeDot.slice(0, -FormatConfig.BDecimals) + !noDecimals ? formattedDecimals : '' + 'B' } else if (Math.abs(numberAsNumber) > FormatConfig.M) { - formattedNumber = - beforeDot.slice(0, -FormatConfig.MDecimals) + - (FormatConfig.DecimalsAfterDot ? '.' : '') + - (beforeDot.slice(-FormatConfig.MDecimals) + (afterDot ? afterDot : '')).slice( - 0, - FormatConfig.DecimalsAfterDot - ) + - 'M' + const formattedDecimals = noDecimals + ? '' + : (FormatConfig.DecimalsAfterDot ? '.' : '') + + (beforeDot.slice(-FormatConfig.MDecimals) + (afterDot ? afterDot : '')).slice( + 0, + FormatConfig.DecimalsAfterDot + ) + + formattedNumber = beforeDot.slice(0, -FormatConfig.MDecimals) + formattedDecimals + 'M' } else if (Math.abs(numberAsNumber) > FormatConfig.K) { - formattedNumber = - beforeDot.slice(0, -FormatConfig.KDecimals) + - (FormatConfig.DecimalsAfterDot ? '.' : '') + - (beforeDot.slice(-FormatConfig.KDecimals) + (afterDot ? afterDot : '')).slice( - 0, - FormatConfig.DecimalsAfterDot - ) + - 'K' + const formattedDecimals = noDecimals + ? '' + : (FormatConfig.DecimalsAfterDot ? '.' : '') + + (beforeDot.slice(-FormatConfig.KDecimals) + (afterDot ? afterDot : '')).slice( + 0, + FormatConfig.DecimalsAfterDot + ) + formattedNumber = beforeDot.slice(0, -FormatConfig.KDecimals) + formattedDecimals + 'K' } else if (afterDot && countLeadingZeros(afterDot) <= 3) { const roundedNumber = numberAsNumber.toFixed(countLeadingZeros(afterDot) + 4).slice(0, -1) formattedNumber = trimZeros(roundedNumber) From 9915b845271f2d89e636592abd120bef7192f8af Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 18 Jul 2024 11:33:22 +0200 Subject: [PATCH 16/75] add open position button to top pools --- .../Stats/PoolListItem/PoolListItem.tsx | 13 +++++++++++-- src/components/Stats/PoolListItem/style.ts | 16 +++++++++++++++- src/containers/WrappedStats/mockStats.ts | 4 ++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/components/Stats/PoolListItem/PoolListItem.tsx b/src/components/Stats/PoolListItem/PoolListItem.tsx index a3d25e02..46067560 100644 --- a/src/components/Stats/PoolListItem/PoolListItem.tsx +++ b/src/components/Stats/PoolListItem/PoolListItem.tsx @@ -1,10 +1,11 @@ import React from 'react' import { theme } from '@static/theme' import { useStyles } from './style' -import { Box, Grid, Typography, useMediaQuery } from '@mui/material' -import { formatNumbers, showPrefix } from '@utils/utils' +import { Box, Button, Grid, Typography, useMediaQuery } from '@mui/material' +import { formatNumber, formatNumbers, showPrefix } from '@utils/utils' import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown' import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp' +import { useNavigate } from 'react-router-dom' export enum SortType { NAME_ASC, @@ -62,8 +63,12 @@ const PoolListItem: React.FC = ({ }) => { const { classes } = useStyles() + const navigate = useNavigate() const isXs = useMediaQuery(theme.breakpoints.down('xs')) + const handleOpenPosition = () => { + navigate(`/newPosition/${symbolFrom}/${symbolTo}/0_01`) + } return ( {displayType === 'token' ? ( @@ -126,6 +131,9 @@ const PoolListItem: React.FC = ({ {fee}% {`$${formatNumbers()(volume.toString())}${showPrefix(volume)}`} {`$${formatNumbers()(TVL.toString())}${showPrefix(TVL)}`} + ) : ( @@ -216,6 +224,7 @@ const PoolListItem: React.FC = ({ ) : null} + Action )} diff --git a/src/components/Stats/PoolListItem/style.ts b/src/components/Stats/PoolListItem/style.ts index 34641004..30833926 100644 --- a/src/components/Stats/PoolListItem/style.ts +++ b/src/components/Stats/PoolListItem/style.ts @@ -5,7 +5,7 @@ export const useStyles = makeStyles()(() => ({ container: { color: colors.white.main, display: 'grid', - gridTemplateColumns: '5% 45% 15% 20% auto', + gridTemplateColumns: '5% auto 15% 15% 15% 140px', padding: '18px 0', backgroundColor: colors.invariant.component, @@ -108,5 +108,19 @@ export const useStyles = makeStyles()(() => ({ liquidityDesc: { color: colors.invariant.text, ...typography.caption1 + }, + openPosition: { + width: 140, + height: 32, + background: colors.invariant.greenLinearGradient, + ...typography.body1, + color: colors.invariant.black, + textTransform: 'none', + borderRadius: 10, + transition: 'filter 0.3s linear', + + '&:hover': { + filter: 'brightness(1.15)' + } } })) diff --git a/src/containers/WrappedStats/mockStats.ts b/src/containers/WrappedStats/mockStats.ts index d80f339e..f7ad6be0 100644 --- a/src/containers/WrappedStats/mockStats.ts +++ b/src/containers/WrappedStats/mockStats.ts @@ -31,8 +31,8 @@ export const poolsList = Array(40) address: '5Dvb5E8zKU4E9c7YxfNL5VC8YQj4VAFUTCGYY9ayFLnnY3UA', chainId: 101, decimals: 6, - name: 'UST (Portal)', - symbol: 'UST', + name: 'BTC (Portal)', + symbol: 'BTC', logoURI: 'https://raw.githubusercontent.com/wormhole-foundation/wormhole-token-list/main/assets/UST_wh.png', tags: ['wormhole', 'old-registry'], From 7b2a6387ded28aafdd3373e9e65e560540aa8452 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 18 Jul 2024 11:37:29 +0200 Subject: [PATCH 17/75] fix build --- src/components/Stats/PoolListItem/PoolListItem.tsx | 2 +- src/pages/StatsPage/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Stats/PoolListItem/PoolListItem.tsx b/src/components/Stats/PoolListItem/PoolListItem.tsx index 46067560..3c40b565 100644 --- a/src/components/Stats/PoolListItem/PoolListItem.tsx +++ b/src/components/Stats/PoolListItem/PoolListItem.tsx @@ -2,7 +2,7 @@ import React from 'react' import { theme } from '@static/theme' import { useStyles } from './style' import { Box, Button, Grid, Typography, useMediaQuery } from '@mui/material' -import { formatNumber, formatNumbers, showPrefix } from '@utils/utils' +import { formatNumbers, showPrefix } from '@utils/utils' import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown' import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp' import { useNavigate } from 'react-router-dom' diff --git a/src/pages/StatsPage/index.tsx b/src/pages/StatsPage/index.tsx index 329f0a60..b4b293e1 100644 --- a/src/pages/StatsPage/index.tsx +++ b/src/pages/StatsPage/index.tsx @@ -1,6 +1,6 @@ import { Grid } from '@mui/material' import { useStyles } from './styles' -import workInProgress from '../../static/png/work-in-progress.png' +// import workInProgress from '../../static/png/work-in-progress.png' import WrappedStats from '@containers/WrappedStats/WrappedStats' // import WrappedStats from '@containers/WrappedStats/WrappedStats' From 5ead51e015fcbf6c121c8b82c0d1dd78b73658d5 Mon Sep 17 00:00:00 2001 From: zielvna Date: Thu, 18 Jul 2024 11:44:58 +0200 Subject: [PATCH 18/75] fix change wallet functionality --- src/store/sagas/wallet.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/store/sagas/wallet.ts b/src/store/sagas/wallet.ts index 91894c19..9ed43c11 100644 --- a/src/store/sagas/wallet.ts +++ b/src/store/sagas/wallet.ts @@ -258,6 +258,7 @@ export function* fetchBalances(tokens: string[]): Generator { export function* handleReconnect(): Generator { yield* call(handleDisconnect) yield* call(openWalletSelectorModal) + yield* call(handleConnect, { type: actions.connect.type, payload: false }) } export function* handleGetBalances(action: PayloadAction): Generator { From 7656a5241e79d29aefbd36eb0f3b9fb138f7bc63 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 18 Jul 2024 12:54:49 +0200 Subject: [PATCH 19/75] fix axis labels --- src/components/Stats/Liquidity/Liquidity.tsx | 18 +++++++++++++----- src/components/Stats/Liquidity/style.ts | 3 +-- src/components/Stats/Volume/Volume.tsx | 18 +++++++++++++----- src/components/Stats/Volume/style.ts | 3 +-- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/components/Stats/Liquidity/Liquidity.tsx b/src/components/Stats/Liquidity/Liquidity.tsx index 869e1728..911d1c57 100644 --- a/src/components/Stats/Liquidity/Liquidity.tsx +++ b/src/components/Stats/Liquidity/Liquidity.tsx @@ -2,7 +2,7 @@ import React from 'react' import { ResponsiveLine } from '@nivo/line' import { linearGradientDef } from '@nivo/core' import classNames from 'classnames' -import { colors } from '@static/theme' +import { colors, typography } from '@static/theme' import { useStyles } from './style' import { TimeData } from '@store/reducers/stats' import { Grid, Typography } from '@mui/material' @@ -85,10 +85,18 @@ const Liquidity: React.FC = ({ tickSize: 0, tickPadding: 2, tickRotation: 0, - format: volume => { - return formatNumber(volume, true) - }, - tickValues: 5 + tickValues: 5, + renderTick: ({ x, y, value }) => ( + + {' '} + + {formatNumber(value, true)} + + + ) }} gridYValues={5} legends={[]} diff --git a/src/components/Stats/Liquidity/style.ts b/src/components/Stats/Liquidity/style.ts index 0d1bd513..80ecb715 100644 --- a/src/components/Stats/Liquidity/style.ts +++ b/src/components/Stats/Liquidity/style.ts @@ -46,14 +46,13 @@ export const useStyles = makeStyles()(() => ({ minWidth: 'auto' }, volumeStatusColor: { - height: 20, minWidth: 'auto', padding: '5px 15px 5px 15px', borderRadius: 6 }, volumeStatusHeader: { - ...typography.body1, + ...typography.caption3, filter: 'brightness(1.2)' }, diff --git a/src/components/Stats/Volume/Volume.tsx b/src/components/Stats/Volume/Volume.tsx index 402f7ef2..f99dd30b 100644 --- a/src/components/Stats/Volume/Volume.tsx +++ b/src/components/Stats/Volume/Volume.tsx @@ -1,7 +1,7 @@ import React from 'react' import { ResponsiveBar } from '@nivo/bar' import classNames from 'classnames' -import { colors, theme } from '@static/theme' +import { colors, theme, typography } from '@static/theme' import { linearGradientDef } from '@nivo/core' import { useStyles } from './style' import { TimeData } from '@store/reducers/stats' @@ -88,10 +88,18 @@ const Volume: React.FC = ({ percentVolume, volume, data, classNa tickSize: 0, tickPadding: 2, tickRotation: 0, - format: volume => { - return formatNumber(volume, true) - }, - tickValues: 5 + tickValues: 5, + renderTick: ({ x, y, value }) => ( + + {' '} + + {formatNumber(value, true)} + + + ) }} gridYValues={5} theme={Theme} diff --git a/src/components/Stats/Volume/style.ts b/src/components/Stats/Volume/style.ts index 30057b41..f8f3adad 100644 --- a/src/components/Stats/Volume/style.ts +++ b/src/components/Stats/Volume/style.ts @@ -36,14 +36,13 @@ export const useStyles = makeStyles()(() => ({ minWidth: 'auto' }, volumeStatusColor: { - height: 20, minWidth: 'auto', padding: '5px 15px 5px 15px', borderRadius: 6 }, volumeStatusHeader: { - ...typography.body1, + ...typography.caption3, filter: 'brightness(1.2)' }, barContainer: { From a450dc3d1e1dd486edee2383d1898607b8cf8b69 Mon Sep 17 00:00:00 2001 From: zielvna Date: Thu, 18 Jul 2024 16:26:31 +0200 Subject: [PATCH 20/75] refactor positions and swap sagas --- src/store/sagas/positions.ts | 49 ++++++++++++++++---------------- src/store/sagas/swap.ts | 54 ++++++++++-------------------------- 2 files changed, 38 insertions(+), 65 deletions(-) diff --git a/src/store/sagas/positions.ts b/src/store/sagas/positions.ts index ecb47586..dc962055 100644 --- a/src/store/sagas/positions.ts +++ b/src/store/sagas/positions.ts @@ -1,4 +1,4 @@ -import { Pool, Position, sendTx } from '@invariant-labs/a0-sdk' +import { Invariant, Pool, Position, PSP22, sendTx } from '@invariant-labs/a0-sdk' import { Signer } from '@polkadot/api/types' import { PayloadAction } from '@reduxjs/toolkit' import { @@ -47,6 +47,26 @@ import { calculateTokenAmountsWithSlippage } from '@invariant-labs/a0-sdk/target import { positionsList } from '@store/selectors/positions' import { getApi, getInvariant, getPSP22, getWrappedAZERO } from './connection' +export function getWithdrawAllWAZEROTxs( + invariant: Invariant, + psp22: PSP22, + invariantAddress: string, + wazeroAddress: string +): SubmittableExtrinsic[] { + const txs: SubmittableExtrinsic[] = [] + + const approveTx = psp22.approveTx(invariantAddress, U128MAX, wazeroAddress, PSP22_APPROVE_OPTIONS) + txs.push(approveTx) + + const unwrapTx = invariant.withdrawAllWAZEROTx(wazeroAddress, INVARIANT_WITHDRAW_ALL_WAZERO) + txs.push(unwrapTx) + + const resetApproveTx = psp22.approveTx(invariantAddress, 0n, wazeroAddress, PSP22_APPROVE_OPTIONS) + txs.push(resetApproveTx) + + return txs +} + function* handleInitPosition(action: PayloadAction): Generator { const { poolKeyData, @@ -139,14 +159,7 @@ function* handleInitPosition(action: PayloadAction): Generator (tokenX === wazeroAddress && tokenXAmount !== 0n) || (tokenY === wazeroAddress && tokenYAmount !== 0n) ) { - const approveTx = psp22.approveTx(invAddress, U128MAX, wazeroAddress, PSP22_APPROVE_OPTIONS) - txs.push(approveTx) - - const unwrapTx = invariant.withdrawAllWAZEROTx(wazeroAddress, INVARIANT_WITHDRAW_ALL_WAZERO) - txs.push(unwrapTx) - - const resetApproveTx = psp22.approveTx(invAddress, 0n, wazeroAddress, PSP22_APPROVE_OPTIONS) - txs.push(resetApproveTx) + txs.push(getWithdrawAllWAZEROTxs(invariant, psp22, invAddress, wazeroAddress)) } const batchedTx = api.tx.utility.batchAll(txs) @@ -356,14 +369,7 @@ export function* handleClaimFee(action: PayloadAction) { txs.push(claimTx) if (addressTokenX === wazeroAddress || addressTokenY === wazeroAddress) { - const approveTx = psp22.approveTx(invAddress, U128MAX, wazeroAddress, PSP22_APPROVE_OPTIONS) - txs.push(approveTx) - - const unwrapTx = invariant.withdrawAllWAZEROTx(wazeroAddress, INVARIANT_WITHDRAW_ALL_WAZERO) - txs.push(unwrapTx) - - const resetApproveTx = psp22.approveTx(invAddress, 0n, wazeroAddress, PSP22_APPROVE_OPTIONS) - txs.push(resetApproveTx) + txs.push(getWithdrawAllWAZEROTxs(invariant, psp22, invAddress, wazeroAddress)) } const batchedTx = api.tx.utility.batchAll(txs) @@ -508,14 +514,7 @@ export function* handleClosePosition(action: PayloadAction) { txs.push(removePositionTx) if (addressTokenX === wazeroAddress || addressTokenY === wazeroAddress) { - const approveTx = psp22.approveTx(invAddress, U128MAX, wazeroAddress) - txs.push(approveTx) - - const unwrapTx = invariant.withdrawAllWAZEROTx(wazeroAddress) - txs.push(unwrapTx) - - const resetApproveTx = psp22.approveTx(invAddress, 0n, wazeroAddress) - txs.push(resetApproveTx) + txs.push(getWithdrawAllWAZEROTxs(invariant, psp22, invAddress, wazeroAddress)) } const batchedTx = api.tx.utility.batchAll(txs) diff --git a/src/store/sagas/swap.ts b/src/store/sagas/swap.ts index ddf2132b..46a091a8 100644 --- a/src/store/sagas/swap.ts +++ b/src/store/sagas/swap.ts @@ -1,5 +1,4 @@ import { - TESTNET_WAZERO_ADDRESS, calculatePriceImpact, calculateSqrtPriceAfterSlippage, sendTx, @@ -15,7 +14,6 @@ import { PayloadAction } from '@reduxjs/toolkit' import { ErrorMessage, INVARIANT_SWAP_OPTIONS, - INVARIANT_WITHDRAW_ALL_WAZERO, PSP22_APPROVE_OPTIONS, U128MAX, WAZERO_DEPOSIT_OPTIONS, @@ -43,6 +41,7 @@ import { all, call, put, select, spawn, takeEvery } from 'typed-redux-saga' import { fetchBalances } from './wallet' import { SubmittableExtrinsic } from '@polkadot/api/promise/types' import { getApi, getInvariant, getPSP22, getWrappedAZERO } from './connection' +import { getWithdrawAllWAZEROTxs } from './positions' export function* handleSwap(action: PayloadAction>): Generator { const { @@ -95,10 +94,7 @@ export function* handleSwap(action: PayloadAction>): Generato ? calculateAmountInWithSlippage(amountOut, sqrtPriceLimit, xToY, poolKey.feeTier.fee) : amountIn - if ( - (xToY && poolKey.tokenX === TESTNET_WAZERO_ADDRESS) || - (!xToY && poolKey.tokenY === TESTNET_WAZERO_ADDRESS) - ) { + if ((xToY && poolKey.tokenX === wazeroAddress) || (!xToY && poolKey.tokenY === wazeroAddress)) { const azeroBalance = yield* select(balance) const azeroAmountInWithSlippage = azeroBalance > calculatedAmountIn ? calculatedAmountIn : azeroBalance @@ -106,23 +102,14 @@ export function* handleSwap(action: PayloadAction>): Generato txs.push(depositTx) } - if (xToY) { - const approveTx = psp22.approveTx( - invAddress, - calculatedAmountIn, - tokenX.address.toString(), - PSP22_APPROVE_OPTIONS - ) - txs.push(approveTx) - } else { - const approveTx = psp22.approveTx( - invAddress, - calculatedAmountIn, - tokenY.address.toString(), - PSP22_APPROVE_OPTIONS - ) - txs.push(approveTx) - } + const tokenAddress = xToY ? tokenX.address.toString() : tokenY.address.toString() + const approveTx = psp22.approveTx( + invAddress, + calculatedAmountIn, + tokenAddress, + PSP22_APPROVE_OPTIONS + ) + txs.push(approveTx) const swapTx = invariant.swapWithSlippageTx( poolKey, @@ -135,27 +122,14 @@ export function* handleSwap(action: PayloadAction>): Generato ) txs.push(swapTx) - if ( - (!xToY && poolKey.tokenX === wazeroAddress) || - (xToY && poolKey.tokenY === TESTNET_WAZERO_ADDRESS) - ) { + if ((!xToY && poolKey.tokenX === wazeroAddress) || (xToY && poolKey.tokenY === wazeroAddress)) { const withdrawTx = wazero.withdrawTx(amountOut, WAZERO_WITHDRAW_OPTIONS) txs.push(withdrawTx) } - const approveTx = psp22.approveTx( - invAddress, - U128MAX, - TESTNET_WAZERO_ADDRESS, - PSP22_APPROVE_OPTIONS - ) - txs.push(approveTx) - - const unwrapTx = invariant.withdrawAllWAZEROTx( - TESTNET_WAZERO_ADDRESS, - INVARIANT_WITHDRAW_ALL_WAZERO - ) - txs.push(unwrapTx) + if (poolKey.tokenX === wazeroAddress || poolKey.tokenX === wazeroAddress) { + txs.push(getWithdrawAllWAZEROTxs(invariant, psp22, invAddress, wazeroAddress)) + } const batchedTx = api.tx.utility.batchAll(txs) From 3ba45c8683e35e297e98cd82337649224d51a745 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Fri, 19 Jul 2024 16:39:50 +0200 Subject: [PATCH 21/75] highlight token balance --- .../SelectModals/SelectTokenModal/SelectTokenModal.tsx | 2 +- src/components/Modals/SelectModals/style.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx index 8d5a45a4..c92c1908 100644 --- a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx +++ b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx @@ -270,7 +270,7 @@ export const SelectTokenModal: React.FC = ({ {!hideBalances && Number(tokenBalance) > 0 ? ( - Balance: {formatNumber(tokenBalance)} + Balance: {formatNumber(tokenBalance)} ) : null} diff --git a/src/components/Modals/SelectModals/style.ts b/src/components/Modals/SelectModals/style.ts index e982c874..619ac76a 100644 --- a/src/components/Modals/SelectModals/style.ts +++ b/src/components/Modals/SelectModals/style.ts @@ -182,7 +182,11 @@ const useStyles = makeStyles()((theme: Theme) => { filter: 'brightness(0.8)', color: colors.invariant.textGrey, ...typography.body2, - minWidth: 'auto' + minWidth: 'auto', + + '& span': { + color: colors.invariant.text + } }, tokenIcon: { From fc6664d37d862a68964012e95954d7346efcfc34 Mon Sep 17 00:00:00 2001 From: zielvna Date: Fri, 19 Jul 2024 18:36:46 +0200 Subject: [PATCH 22/75] fix positions and swap sagas --- src/store/sagas/positions.ts | 12 ++++++------ src/store/sagas/swap.ts | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/store/sagas/positions.ts b/src/store/sagas/positions.ts index dc962055..e9de3a52 100644 --- a/src/store/sagas/positions.ts +++ b/src/store/sagas/positions.ts @@ -105,7 +105,7 @@ function* handleInitPosition(action: PayloadAction): Generator const psp22 = yield* getPSP22() const wazero = yield* getWrappedAZERO() - const txs = [] + let txs = [] const [xAmountWithSlippage, yAmountWithSlippage] = calculateTokenAmountsWithSlippage( feeTier.tickSpacing, @@ -159,7 +159,7 @@ function* handleInitPosition(action: PayloadAction): Generator (tokenX === wazeroAddress && tokenXAmount !== 0n) || (tokenY === wazeroAddress && tokenYAmount !== 0n) ) { - txs.push(getWithdrawAllWAZEROTxs(invariant, psp22, invAddress, wazeroAddress)) + txs = [...txs, ...getWithdrawAllWAZEROTxs(invariant, psp22, invAddress, wazeroAddress)] } const batchedTx = api.tx.utility.batchAll(txs) @@ -363,13 +363,13 @@ export function* handleClaimFee(action: PayloadAction) { const invariant = yield* getInvariant() const psp22 = yield* getPSP22() - const txs = [] + let txs = [] const claimTx = invariant.claimFeeTx(index, INVARIANT_CLAIM_FEE_OPTIONS) txs.push(claimTx) if (addressTokenX === wazeroAddress || addressTokenY === wazeroAddress) { - txs.push(getWithdrawAllWAZEROTxs(invariant, psp22, invAddress, wazeroAddress)) + txs = [...txs, ...getWithdrawAllWAZEROTxs(invariant, psp22, invAddress, wazeroAddress)] } const batchedTx = api.tx.utility.batchAll(txs) @@ -505,7 +505,7 @@ export function* handleClosePosition(action: PayloadAction) { const fetchTask = yield* fork(handleGetPositionsListPage, getPositionsListPagePayload) yield* join(fetchTask) - const txs = [] + let txs = [] const removePositionTx = invariant.removePositionTx( positionIndex, @@ -514,7 +514,7 @@ export function* handleClosePosition(action: PayloadAction) { txs.push(removePositionTx) if (addressTokenX === wazeroAddress || addressTokenY === wazeroAddress) { - txs.push(getWithdrawAllWAZEROTxs(invariant, psp22, invAddress, wazeroAddress)) + txs = [...txs, ...getWithdrawAllWAZEROTxs(invariant, psp22, invAddress, wazeroAddress)] } const batchedTx = api.tx.utility.batchAll(txs) diff --git a/src/store/sagas/swap.ts b/src/store/sagas/swap.ts index 46a091a8..9c5df07a 100644 --- a/src/store/sagas/swap.ts +++ b/src/store/sagas/swap.ts @@ -87,7 +87,7 @@ export function* handleSwap(action: PayloadAction>): Generato const tokenY = allTokens[poolKey.tokenY] const xToY = tokenFrom.toString() === poolKey.tokenX - const txs = [] + let txs = [] const sqrtPriceLimit = calculateSqrtPriceAfterSlippage(estimatedPriceAfterSwap, slippage, !xToY) const calculatedAmountIn = slippage @@ -128,7 +128,7 @@ export function* handleSwap(action: PayloadAction>): Generato } if (poolKey.tokenX === wazeroAddress || poolKey.tokenX === wazeroAddress) { - txs.push(getWithdrawAllWAZEROTxs(invariant, psp22, invAddress, wazeroAddress)) + txs = [...txs, ...getWithdrawAllWAZEROTxs(invariant, psp22, invAddress, wazeroAddress)] } const batchedTx = api.tx.utility.batchAll(txs) From 32533200a7b4867e0064843fd5ab282032f46408 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 22 Jul 2024 11:40:34 +0200 Subject: [PATCH 23/75] fix new position layouts --- src/components/NewPosition/RangeSelector/RangeSelector.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/NewPosition/RangeSelector/RangeSelector.tsx b/src/components/NewPosition/RangeSelector/RangeSelector.tsx index fe7a45bb..c2f2813a 100644 --- a/src/components/NewPosition/RangeSelector/RangeSelector.tsx +++ b/src/components/NewPosition/RangeSelector/RangeSelector.tsx @@ -416,8 +416,6 @@ export const RangeSelector: React.FC = ({ - - Date: Mon, 22 Jul 2024 11:52:57 +0200 Subject: [PATCH 24/75] fix single position layout --- .../PositionDetails/PositionDetails.tsx | 56 ++++++++++--------- src/components/PositionDetails/style.ts | 8 +++ 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/components/PositionDetails/PositionDetails.tsx b/src/components/PositionDetails/PositionDetails.tsx index af3b4ec7..cb431896 100644 --- a/src/components/PositionDetails/PositionDetails.tsx +++ b/src/components/PositionDetails/PositionDetails.tsx @@ -168,33 +168,35 @@ const PositionDetails: React.FC = ({ /> - ({ ...tick, x: 1 / tick.x })).reverse() - : Array(100) - .fill(1) - .map((_e, index) => ({ x: index, y: index, index: BigInt(index) })) - } - leftRange={xToY ? leftRange : { ...rightRange, x: 1 / rightRange.x }} - rightRange={xToY ? rightRange : { ...leftRange, x: 1 / leftRange.x }} - midPrice={{ - ...midPrice, - x: midPrice.x ** (xToY ? 1 : -1) - }} - currentPrice={currentPrice ** (xToY ? 1 : -1)} - tokenY={tokenY} - tokenX={tokenX} - ticksLoading={ticksLoading} - tickSpacing={tickSpacing} - min={xToY ? min : 1 / max} - max={xToY ? max : 1 / min} - xToY={xToY} - hasTicksError={hasTicksError} - reloadHandler={reloadHandler} - /> + + ({ ...tick, x: 1 / tick.x })).reverse() + : Array(100) + .fill(1) + .map((_e, index) => ({ x: index, y: index, index: BigInt(index) })) + } + leftRange={xToY ? leftRange : { ...rightRange, x: 1 / rightRange.x }} + rightRange={xToY ? rightRange : { ...leftRange, x: 1 / leftRange.x }} + midPrice={{ + ...midPrice, + x: midPrice.x ** (xToY ? 1 : -1) + }} + currentPrice={currentPrice ** (xToY ? 1 : -1)} + tokenY={tokenY} + tokenX={tokenX} + ticksLoading={ticksLoading} + tickSpacing={tickSpacing} + min={xToY ? min : 1 / max} + max={xToY ? max : 1 / min} + xToY={xToY} + hasTicksError={hasTicksError} + reloadHandler={reloadHandler} + /> + ) diff --git a/src/components/PositionDetails/style.ts b/src/components/PositionDetails/style.ts index 6f832e17..b101e376 100644 --- a/src/components/PositionDetails/style.ts +++ b/src/components/PositionDetails/style.ts @@ -79,5 +79,13 @@ export const useStyles = makeStyles()((theme: Theme) => ({ display: 'flex', justifyContent: 'space-between', alignItems: 'center' + }, + positionPlotWrapper: { + width: '100%', + marginTop: 56, + + [theme.breakpoints.down('md')]: { + marginTop: 0 + } } })) From 0c88d0b6a9a1fcaf5e8bf2252bc60e1288d6add1 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Mon, 22 Jul 2024 12:32:30 +0200 Subject: [PATCH 25/75] styling improvements --- .../Modals/SelectModals/CustomScrollbar.tsx | 3 ++- .../SelectTokenModal/SelectTokenModal.tsx | 7 +++---- src/components/Modals/SelectModals/style.ts | 19 +++++++++++++------ 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/components/Modals/SelectModals/CustomScrollbar.tsx b/src/components/Modals/SelectModals/CustomScrollbar.tsx index a81345de..1d2c6847 100644 --- a/src/components/Modals/SelectModals/CustomScrollbar.tsx +++ b/src/components/Modals/SelectModals/CustomScrollbar.tsx @@ -18,7 +18,8 @@ export const CustomScrollbar = forwardRef, IProps>(( autoHideTimeout={200} classes={{ thumbVertical: classes.scrollbarThumb, - trackVertical: classes.scrollbarTrack + trackVertical: classes.scrollbarTrack, + view: classes.scrollbarView }} className={classes.hideScroll} {...props} diff --git a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx index 96e0f7e7..d7c772bc 100644 --- a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx +++ b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx @@ -71,11 +71,11 @@ export const SelectTokenModal: React.FC = ({ const isXs = useMediaQuery(theme.breakpoints.down('sm')) const [value, setValue] = useState('') - const [isAddOpen, setIsAddOpen] = useState(false) const [hideUnknown, setHideUnknown] = useState(initialHideUnknownTokensValue) const outerRef = useRef(null) + const listRef = useRef(null) const tokensWithIndexes = useMemo( () => @@ -208,7 +208,7 @@ export const SelectTokenModal: React.FC = ({ label='Hide unknown tokens' /> - + = ({ container style={{ ...style, - width: '90%', - height: 40 + width: listRef.current ? listRef.current.clientWidth : 'calc(100% - 48px)' }} alignItems='center' wrap='nowrap' diff --git a/src/components/Modals/SelectModals/style.ts b/src/components/Modals/SelectModals/style.ts index 2d6aed54..a7a3b9c9 100644 --- a/src/components/Modals/SelectModals/style.ts +++ b/src/components/Modals/SelectModals/style.ts @@ -152,7 +152,8 @@ const useStyles = makeStyles()((theme: Theme) => { }, tokenName: { color: colors.white.main, - ...typography.heading3 + ...typography.heading3, + fontWeight: 500 }, tokenAddress: { backgroundColor: colors.invariant.newDark, @@ -168,7 +169,8 @@ const useStyles = makeStyles()((theme: Theme) => { textDecoration: 'none', '& p': { color: colors.invariant.lightGrey, - ...typography.caption4 + ...typography.caption4, + letterSpacing: '0.03em' } } }, @@ -208,8 +210,9 @@ const useStyles = makeStyles()((theme: Theme) => { hideScroll: { '& > *:first-of-type': { - paddingRight: '30px' - } + overflow: 'auto !important' + }, + overflow: 'visible !important' }, scrollbarThumb: { @@ -222,8 +225,12 @@ const useStyles = makeStyles()((theme: Theme) => { borderRadius: 10, height: '98%', margin: 5, - float: 'right', - width: 5 + width: 5, + transform: 'translateX(20px)' + }, + scrollbarView: { + padding: 0 + '!important', + width: 'calc(100% + 50px)' }, paper: { background: 'transparent', From dd82a5653a216585071fc55e8bd21f73e68c3e3f Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 22 Jul 2024 13:03:02 +0200 Subject: [PATCH 26/75] refactor empty placeholder --- .../EmptyPlaceholder/EmptyPlaceholder.tsx | 40 ++++++++---- src/components/EmptyPlaceholder/style.tsx | 61 ++++++++++++++----- src/static/icons.ts | 4 +- src/static/svg/empty.svg | 16 ++--- 4 files changed, 80 insertions(+), 41 deletions(-) diff --git a/src/components/EmptyPlaceholder/EmptyPlaceholder.tsx b/src/components/EmptyPlaceholder/EmptyPlaceholder.tsx index 2b0757f1..6266938e 100644 --- a/src/components/EmptyPlaceholder/EmptyPlaceholder.tsx +++ b/src/components/EmptyPlaceholder/EmptyPlaceholder.tsx @@ -1,28 +1,42 @@ -import { Grid, Typography } from '@mui/material' -import empty from '@static/svg/empty.svg' +import { Button, Grid, Typography } from '@mui/material' import classNames from 'classnames' import React from 'react' import { useStyles } from './style' +import icons from '@static/icons' export interface IEmptyPlaceholder { desc: string + onAction?: () => void className?: string style?: React.CSSProperties } -export const EmptyPlaceholder: React.FC = ({ desc, className, style }) => { +export const EmptyPlaceholder: React.FC = ({ desc, onAction }) => { const { classes } = useStyles() return ( - - empty - It's empty here... - {desc} - + <> + + + + Not connected + It's empty here... + {desc?.length && {desc}} + + + + + // + // empty + // It's empty here... + // {desc} + // ) } diff --git a/src/components/EmptyPlaceholder/style.tsx b/src/components/EmptyPlaceholder/style.tsx index 787ca4e1..02162c1e 100644 --- a/src/components/EmptyPlaceholder/style.tsx +++ b/src/components/EmptyPlaceholder/style.tsx @@ -2,24 +2,55 @@ import { colors, typography } from '@static/theme' import { makeStyles } from 'tss-react/mui' export const useStyles = makeStyles()(() => ({ - wrapper: { - width: 300 + container: { + width: '100%', + height: '370px', + position: 'absolute', + zIndex: 14 }, - image: { - width: 160, - height: 180 + root: { + zIndex: 10, + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + paddingBottom: 25, + width: '100%', + height: '100%', + p: { + textAlign: 'center' + } }, - title: { - ...typography.heading2, - marginBlock: 24, - color: colors.invariant.textGrey, - opacity: 0.7 + img: { + paddingBottom: 25 + }, + blur: { + width: '100%', + height: '370px', + backgroundColor: 'rgba(12, 11, 13, 0.8)', + position: 'absolute', + zIndex: 13, + borderRadius: 10 }, desc: { - color: colors.invariant.textGrey, - opacity: 0.7, - ...typography.heading4, - fontWeight: 400, - textAlign: 'center' + ...typography.body2, + fontWeight: 500, + lineHeight: '20px', + color: colors.invariant.lightHover + }, + button: { + height: 40, + width: 200, + marginTop: 20, + color: colors.invariant.componentBcg, + ...typography.body1, + textTransform: 'none', + borderRadius: 14, + background: colors.invariant.pinkLinearGradientOpacity, + + '&:hover': { + background: colors.invariant.pinkLinearGradient, + boxShadow: '0px 0px 16px rgba(239, 132, 245, 0.35)' + } } })) diff --git a/src/static/icons.ts b/src/static/icons.ts index d9195b2b..a8afc0e6 100644 --- a/src/static/icons.ts +++ b/src/static/icons.ts @@ -25,6 +25,7 @@ import unknownToken from './svg/unknownToken.svg' import newTab from './svg/newTab.svg' import selectToken from './svg/selectToken.svg' import copyAddress from './svg/copy-address.svg' +import emptyIcon from './svg/empty.svg' const icons: { [key: string]: string } = { clear: clearIcon, @@ -53,7 +54,8 @@ const icons: { [key: string]: string } = { unknownToken: unknownToken, newTab: newTab, selectToken: selectToken, - copyAddress: copyAddress + copyAddress: copyAddress, + empty: emptyIcon } export default icons diff --git a/src/static/svg/empty.svg b/src/static/svg/empty.svg index c2f638de..bb365618 100644 --- a/src/static/svg/empty.svg +++ b/src/static/svg/empty.svg @@ -1,13 +1,5 @@ - - - - - - - - - - - - + + + + From 53fe9e9d8b2623ee4880095f3fa348be2d6b6d0c Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 22 Jul 2024 13:09:42 +0200 Subject: [PATCH 27/75] add functionality to empty positions list button --- src/components/PositionsList/PositionsList.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/PositionsList/PositionsList.tsx b/src/components/PositionsList/PositionsList.tsx index a5610875..43f5431b 100644 --- a/src/components/PositionsList/PositionsList.tsx +++ b/src/components/PositionsList/PositionsList.tsx @@ -159,6 +159,7 @@ export const PositionsList: React.FC = ({ )} From a277b378f14f3925f0009fc5e69a502fe7300755 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 22 Jul 2024 13:45:53 +0200 Subject: [PATCH 28/75] remove commented code and change names of the css classes --- .../EmptyPlaceholder/EmptyPlaceholder.tsx | 16 +++------------- src/components/NewPosition/style.ts | 4 ++-- src/components/NoConnected/NoConnected.tsx | 6 +++--- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/components/EmptyPlaceholder/EmptyPlaceholder.tsx b/src/components/EmptyPlaceholder/EmptyPlaceholder.tsx index 6266938e..03346315 100644 --- a/src/components/EmptyPlaceholder/EmptyPlaceholder.tsx +++ b/src/components/EmptyPlaceholder/EmptyPlaceholder.tsx @@ -16,9 +16,9 @@ export const EmptyPlaceholder: React.FC = ({ desc, onAction } return ( <> - - - + + + Not connected It's empty here... {desc?.length && {desc}} @@ -28,15 +28,5 @@ export const EmptyPlaceholder: React.FC = ({ desc, onAction } - // - // empty - // It's empty here... - // {desc} - // ) } diff --git a/src/components/NewPosition/style.ts b/src/components/NewPosition/style.ts index a541c4f2..40dd8f58 100644 --- a/src/components/NewPosition/style.ts +++ b/src/components/NewPosition/style.ts @@ -44,7 +44,7 @@ const useStyles = makeStyles()(theme => { position: 'relative', flexDirection: 'row', - '& .noConnectedLayer': { + '& .blurLayer': { height: '100%' }, @@ -52,7 +52,7 @@ const useStyles = makeStyles()(theme => { flexDirection: 'column', minWidth: 0, - '& .noConnectedInfo': { + '& .blurInfo': { justifyContent: 'flex-start', paddingTop: 60 } diff --git a/src/components/NoConnected/NoConnected.tsx b/src/components/NoConnected/NoConnected.tsx index b9718802..0403ad6c 100644 --- a/src/components/NoConnected/NoConnected.tsx +++ b/src/components/NoConnected/NoConnected.tsx @@ -13,9 +13,9 @@ export const NoConnected: React.FC = ({ onConnect, descCustomText return ( <> - - - + + + Not connected Wallet is not connected. {descCustomText?.length && ( From 0b2d4ae1974d5732ea36714716b2303c4d4fa101 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 22 Jul 2024 14:10:57 +0200 Subject: [PATCH 29/75] align position details and new position layouts --- src/components/NewPosition/PoolInit/style.ts | 6 +++++- src/components/NewPosition/RangeSelector/style.ts | 7 ++++++- src/components/PositionDetails/SinglePositionPlot/style.ts | 3 +-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/components/NewPosition/PoolInit/style.ts b/src/components/NewPosition/PoolInit/style.ts index ef724cf0..fd999c4e 100644 --- a/src/components/NewPosition/PoolInit/style.ts +++ b/src/components/NewPosition/PoolInit/style.ts @@ -110,7 +110,11 @@ const useStyles = makeStyles()(theme => { sliderWrapper: { paddingTop: 24, paddingInline: 8, - position: 'relative' + position: 'relative', + + [theme.breakpoints.down('sm')]: { + paddingBottom: 24 + } } } }) diff --git a/src/components/NewPosition/RangeSelector/style.ts b/src/components/NewPosition/RangeSelector/style.ts index ac28d28c..b7321c92 100644 --- a/src/components/NewPosition/RangeSelector/style.ts +++ b/src/components/NewPosition/RangeSelector/style.ts @@ -29,6 +29,7 @@ const useStyles = makeStyles()(theme => { gap: 16 }, topInnerWrapper: { + width: '100%', minHeight: 300 }, plot: { @@ -110,7 +111,11 @@ const useStyles = makeStyles()(theme => { sliderWrapper: { paddingTop: 24, paddingInline: 8, - position: 'relative' + position: 'relative', + + [theme.breakpoints.down('sm')]: { + paddingBottom: 24 + } }, warningWrapper: { position: 'absolute', diff --git a/src/components/PositionDetails/SinglePositionPlot/style.ts b/src/components/PositionDetails/SinglePositionPlot/style.ts index 38857c37..ad0e5719 100644 --- a/src/components/PositionDetails/SinglePositionPlot/style.ts +++ b/src/components/PositionDetails/SinglePositionPlot/style.ts @@ -10,8 +10,7 @@ export const useStyles = makeStyles()((theme: Theme) => ({ paddingTop: 18, borderRadius: 24, [theme.breakpoints.down('sm')]: { - padding: 8, - paddingTop: 16 + padding: '24px 8px' } }, headerContainer: { From 79deeaee63c481e5cb65b64261739fefea70da03 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Mon, 22 Jul 2024 14:14:29 +0200 Subject: [PATCH 30/75] sort tokens by balance --- .../SelectTokenModal/SelectTokenModal.tsx | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx index 3e2e8043..fdf2f4b3 100644 --- a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx +++ b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx @@ -105,24 +105,14 @@ export const SelectTokenModal: React.FC = ({ const sorted = list.sort((a, b) => { const aBalance = +printBigint(a.balance, a.decimals) const bBalance = +printBigint(b.balance, b.decimals) - if ((aBalance === 0 && bBalance === 0) || (aBalance > 0 && bBalance > 0)) { - if (value.length) { - if ( - a.symbol.toLowerCase().startsWith(value.toLowerCase()) && - !b.symbol.toLowerCase().startsWith(value.toLowerCase()) - ) { - return -1 - } - if ( - b.symbol.toLowerCase().startsWith(value.toLowerCase()) && - !a.symbol.toLowerCase().startsWith(value.toLowerCase()) - ) { - return 1 - } - } - return a.symbol.toLowerCase().localeCompare(b.symbol.toLowerCase()) + + if (aBalance > bBalance) { + return -1 + } else if (aBalance < bBalance) { + return 1 + } else { + return 0 } - return aBalance === 0 ? 1 : -1 }) return hideUnknown ? sorted.filter(token => !token.isUnknown) : sorted From f2f511d41d2f33bb925d1c83ae1757ec4b5b2116 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 22 Jul 2024 15:00:07 +0200 Subject: [PATCH 31/75] add functionality to handle path in swap page --- src/components/Swap/Swap.tsx | 11 +++++++++++ src/containers/WrappedSwap/WrappedSwap.tsx | 13 ++++++++++--- src/pages/RouterPages.tsx | 2 +- src/pages/SwapPage/index.tsx | 7 ++++++- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/components/Swap/Swap.tsx b/src/components/Swap/Swap.tsx index 42522156..8e4f5b23 100644 --- a/src/components/Swap/Swap.tsx +++ b/src/components/Swap/Swap.tsx @@ -31,6 +31,7 @@ import useStyles from './style' import { SimulateResult, TokenPriceData } from '@store/consts/types' import TokensInfo from './TokensInfo/TokensInfo' import { VariantType } from 'notistack' +import { useNavigate } from 'react-router-dom' export interface Pools { tokenX: string @@ -148,6 +149,16 @@ export const Swap: React.FC = ({ const timeoutRef = useRef(0) + const navigate = useNavigate() + + useEffect(() => { + const tokenFromAddress = tokens[tokenFromIndex ?? -1]?.assetAddress + const tokenToAddress = tokens[tokenToIndex ?? -1]?.assetAddress + navigate(`/swap/${tokenFromAddress || '-'}/${tokenToAddress || '-'}`, { + replace: true + }) + }, [tokenToIndex, tokenFromIndex]) + useEffect(() => { if (!!tokens.length && tokenFromIndex === null && tokenToIndex === null) { const firstCommonIndex = commonTokens.length diff --git a/src/containers/WrappedSwap/WrappedSwap.tsx b/src/containers/WrappedSwap/WrappedSwap.tsx index a084f9cb..a9e30b96 100644 --- a/src/containers/WrappedSwap/WrappedSwap.tsx +++ b/src/containers/WrappedSwap/WrappedSwap.tsx @@ -33,7 +33,12 @@ import { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import { VariantType } from 'notistack' -export const WrappedSwap = () => { +type Props = { + initialTokenFrom: string + initialTokenTo: string +} + +export const WrappedSwap = ({ initialTokenFrom, initialTokenTo }: Props) => { const dispatch = useDispatch() const walletAddress = useSelector(address) @@ -86,8 +91,10 @@ export const WrappedSwap = () => { ) } }, [isFetchingNewPool]) - const lastTokenFrom = localStorage.getItem(`INVARIANT_LAST_TOKEN_FROM_${network}`) - const lastTokenTo = localStorage.getItem(`INVARIANT_LAST_TOKEN_TO_${network}`) + + const lastTokenFrom = + initialTokenFrom || localStorage.getItem(`INVARIANT_LAST_TOKEN_FROM_${network}`) + const lastTokenTo = initialTokenTo || localStorage.getItem(`INVARIANT_LAST_TOKEN_TO_${network}`) const initialTokenFromIndex = lastTokenFrom === null diff --git a/src/pages/RouterPages.tsx b/src/pages/RouterPages.tsx index f6d94194..cf85a37b 100644 --- a/src/pages/RouterPages.tsx +++ b/src/pages/RouterPages.tsx @@ -9,7 +9,7 @@ import SwapPage from './SwapPage' export const router = createBrowserRouter( createRoutesFromElements( }> - } /> + } /> } /> } /> } /> diff --git a/src/pages/SwapPage/index.tsx b/src/pages/SwapPage/index.tsx index d35abf8e..83884533 100644 --- a/src/pages/SwapPage/index.tsx +++ b/src/pages/SwapPage/index.tsx @@ -1,13 +1,18 @@ import WrappedSwap from '@containers/WrappedSwap/WrappedSwap' import useStyles from './styles' import { Grid } from '@mui/material' +import { useParams } from 'react-router-dom' export const SwapPage: React.FC = () => { const { classes } = useStyles() + const { item1, item2 } = useParams() + + const initialTokenFrom = item1 || '' + const initialTokenTo = item2 || '' return ( - + ) } From b74c14e7dbde6f25d93e3ace9f85d65a5975fb3d Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Mon, 22 Jul 2024 15:42:17 +0200 Subject: [PATCH 32/75] update styles of -token list --- .../SelectModals/SelectTokenModal/SelectTokenModal.tsx | 6 +++--- src/components/Modals/SelectModals/style.ts | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx index d7c772bc..ac7c9f2d 100644 --- a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx +++ b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx @@ -75,7 +75,7 @@ export const SelectTokenModal: React.FC = ({ const [hideUnknown, setHideUnknown] = useState(initialHideUnknownTokensValue) const outerRef = useRef(null) - const listRef = useRef(null) + const listRef = useRef(null) const tokensWithIndexes = useMemo( () => @@ -210,9 +210,9 @@ export const SelectTokenModal: React.FC = ({ diff --git a/src/components/Modals/SelectModals/style.ts b/src/components/Modals/SelectModals/style.ts index a7a3b9c9..3a792a2b 100644 --- a/src/components/Modals/SelectModals/style.ts +++ b/src/components/Modals/SelectModals/style.ts @@ -20,7 +20,7 @@ const useStyles = makeStyles()((theme: Theme) => { borderRadius: 20, width: 500, [theme.breakpoints.down('sm')]: { - width: '100vw' + maxWidth: '100vw' }, '& .MuiCheckbox-root.Mui-checked': { color: colors.green.button @@ -125,7 +125,7 @@ const useStyles = makeStyles()((theme: Theme) => { background: colors.invariant.component, borderTop: `1px solid ${colors.invariant.light}`, width: 451, - height: 352, + height: 400, paddingTop: 8 }, @@ -140,7 +140,7 @@ const useStyles = makeStyles()((theme: Theme) => { marginBottom: 4, borderRadius: 24, cursor: 'pointer', - padding: '35px 16px ', + padding: '32px 16px ', '& > p': { whiteSpace: 'nowrap' }, @@ -152,8 +152,7 @@ const useStyles = makeStyles()((theme: Theme) => { }, tokenName: { color: colors.white.main, - ...typography.heading3, - fontWeight: 500 + ...typography.heading4 }, tokenAddress: { backgroundColor: colors.invariant.newDark, From fb0605d16f067ed4c81a2e38286ce682184825de Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 22 Jul 2024 16:13:41 +0200 Subject: [PATCH 33/75] refactor messages --- .../DepositSelector/DepositSelector.tsx | 4 ++-- src/components/Swap/Swap.tsx | 8 +++---- .../HeaderWrapper/HeaderWrapper.tsx | 2 +- .../NewPositionWrapper/NewPositionWrapper.tsx | 6 ++--- src/containers/WrappedSwap/WrappedSwap.tsx | 6 ++--- src/store/sagas/connection.ts | 6 ++--- src/store/sagas/positions.ts | 22 +++++++++---------- src/store/sagas/swap.ts | 8 +++---- src/store/sagas/wallet.ts | 2 +- 9 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/components/NewPosition/DepositSelector/DepositSelector.tsx b/src/components/NewPosition/DepositSelector/DepositSelector.tsx index 98e0778d..5c758e44 100644 --- a/src/components/NewPosition/DepositSelector/DepositSelector.tsx +++ b/src/components/NewPosition/DepositSelector/DepositSelector.tsx @@ -157,7 +157,7 @@ export const DepositSelector: React.FC = ({ convertBalanceToBigint(tokenAInputState.value, tokens[tokenAIndex].decimals) > tokens[tokenAIndex].balance ) { - return "You don't have enough token A" + return 'Not enough token A' } if ( @@ -165,7 +165,7 @@ export const DepositSelector: React.FC = ({ convertBalanceToBigint(tokenBInputState.value, tokens[tokenBIndex].decimals) > tokens[tokenBIndex].balance ) { - return "You don't have enough token B" + return 'Not enough token B' } if ( diff --git a/src/components/Swap/Swap.tsx b/src/components/Swap/Swap.tsx index 42522156..707299a7 100644 --- a/src/components/Swap/Swap.tsx +++ b/src/components/Swap/Swap.tsx @@ -343,12 +343,12 @@ export const Swap: React.FC = ({ return 'Insufficient volume' } - return 'Swap tokens' + return 'Swap' } const hasShowRateMessage = () => { return ( getStateMessage() === 'Insufficient balance' || - getStateMessage() === 'Swap tokens' || + getStateMessage() === 'Swap' || getStateMessage() === 'Loading' || getStateMessage() === 'Connect a wallet' || getStateMessage() === 'Insufficient liquidity' @@ -695,11 +695,11 @@ export const Swap: React.FC = ({ className={ getStateMessage() === 'Connect a wallet' ? `${classes.swapButton}` - : getStateMessage() === 'Swap tokens' && progress === 'none' + : getStateMessage() === 'Swap' && progress === 'none' ? `${classes.swapButton} ${classes.ButtonSwapActive}` : classes.swapButton } - disabled={getStateMessage() !== 'Swap tokens' || progress !== 'none'} + disabled={getStateMessage() !== 'Swap' || progress !== 'none'} onClick={() => { if ( simulateResult.poolKey === null || diff --git a/src/containers/HeaderWrapper/HeaderWrapper.tsx b/src/containers/HeaderWrapper/HeaderWrapper.tsx index 208627e5..3abcbe53 100644 --- a/src/containers/HeaderWrapper/HeaderWrapper.tsx +++ b/src/containers/HeaderWrapper/HeaderWrapper.tsx @@ -75,7 +75,7 @@ export const HeaderWrapper: React.FC = () => { dispatch( snackbarsActions.add({ - message: 'Successfully copied wallet address.', + message: 'Wallet address copied.', variant: 'success', persist: false }) diff --git a/src/containers/NewPositionWrapper/NewPositionWrapper.tsx b/src/containers/NewPositionWrapper/NewPositionWrapper.tsx index 1868f84d..aa1b8eb1 100644 --- a/src/containers/NewPositionWrapper/NewPositionWrapper.tsx +++ b/src/containers/NewPositionWrapper/NewPositionWrapper.tsx @@ -334,7 +334,7 @@ export const NewPositionWrapper: React.FC = ({ addNewTokenToLocalStorage(address, currentNetwork) dispatch( snackbarsActions.add({ - message: 'Token added to your list', + message: 'Token added.', variant: 'success', persist: false }) @@ -343,7 +343,7 @@ export const NewPositionWrapper: React.FC = ({ .catch(() => { dispatch( snackbarsActions.add({ - message: 'Token adding failed', + message: 'Token add failed.', variant: 'error', persist: false }) @@ -352,7 +352,7 @@ export const NewPositionWrapper: React.FC = ({ } else { dispatch( snackbarsActions.add({ - message: 'Token already exists on your list', + message: 'Token already in list.', variant: 'info', persist: false }) diff --git a/src/containers/WrappedSwap/WrappedSwap.tsx b/src/containers/WrappedSwap/WrappedSwap.tsx index a084f9cb..59dedf97 100644 --- a/src/containers/WrappedSwap/WrappedSwap.tsx +++ b/src/containers/WrappedSwap/WrappedSwap.tsx @@ -111,7 +111,7 @@ export const WrappedSwap = () => { addNewTokenToLocalStorage(address, network) dispatch( snackbarsActions.add({ - message: 'Token added to your list', + message: 'Token added.', variant: 'success', persist: false }) @@ -120,7 +120,7 @@ export const WrappedSwap = () => { .catch(() => { dispatch( snackbarsActions.add({ - message: 'Token adding failed, check if address is valid and try again', + message: 'Token add failed.', variant: 'error', persist: false }) @@ -129,7 +129,7 @@ export const WrappedSwap = () => { } else { dispatch( snackbarsActions.add({ - message: 'Token already exists on your list', + message: 'Token already in list.', variant: 'info', persist: false }) diff --git a/src/store/sagas/connection.ts b/src/store/sagas/connection.ts index 6e1a8baa..ccdcd499 100644 --- a/src/store/sagas/connection.ts +++ b/src/store/sagas/connection.ts @@ -81,20 +81,20 @@ export function* initConnection(): Generator { yield* put( snackbarsActions.add({ - message: 'Aleph-Zero network connected.', + message: 'Aleph Zero network connected.', variant: 'success', persist: false }) ) - console.log('Aleph-Zero network connected.') + console.log('Aleph Zero network connected.') yield* put(actions.setStatus(Status.Initialized)) } catch (error) { console.log(error) yield* put(actions.setStatus(Status.Error)) yield put( snackbarsActions.add({ - message: 'Failed to connect to Aleph-Zero network', + message: 'Failed to connect to Aleph Zero network.', variant: 'error', persist: false }) diff --git a/src/store/sagas/positions.ts b/src/store/sagas/positions.ts index a6c4a592..46d2d70b 100644 --- a/src/store/sagas/positions.ts +++ b/src/store/sagas/positions.ts @@ -161,7 +161,7 @@ function* handleInitPosition(action: PayloadAction): Generator yield put( snackbarsActions.add({ - message: 'Position successfully created', + message: 'Position created.', variant: 'success', persist: false, txid: txResult.hash @@ -197,7 +197,7 @@ function* handleInitPosition(action: PayloadAction): Generator } else { yield put( snackbarsActions.add({ - message: 'Failed to send. Please try again.', + message: 'Failed to create position. Please try again.', variant: 'error', persist: false }) @@ -346,7 +346,7 @@ function* handleInitPositionWithAZERO(action: PayloadAction): yield put( snackbarsActions.add({ - message: 'Position successfully created', + message: 'Position created.', variant: 'success', persist: false, txid: txResult.hash @@ -384,7 +384,7 @@ function* handleInitPositionWithAZERO(action: PayloadAction): } else { yield put( snackbarsActions.add({ - message: 'Failed to send. Please try again.', + message: 'Failed to create position. Please try again.', variant: 'error', persist: false }) @@ -543,7 +543,7 @@ export function* handleClaimFee(action: PayloadAction) { yield put(snackbarsActions.remove(loaderKey)) yield put( snackbarsActions.add({ - message: 'Fee successfully claimed', + message: 'Fee claimed.', variant: 'success', persist: false, txid: txResult.hash @@ -662,7 +662,7 @@ export function* handleClaimFeeWithAZERO(action: PayloadAction) yield put(snackbarsActions.remove(loaderKey)) yield put( snackbarsActions.add({ - message: 'Fee successfully created', + message: 'Fee claimed.', variant: 'success', persist: false, txid: txResult.hash @@ -692,7 +692,7 @@ export function* handleClaimFeeWithAZERO(action: PayloadAction) } else { yield put( snackbarsActions.add({ - message: 'Failed to close position. Please try again.', + message: 'Failed to claim fee. Please try again.', variant: 'error', persist: false }) @@ -744,7 +744,7 @@ export function* handleClosePosition(action: PayloadAction) { try { yield put( snackbarsActions.add({ - message: 'Removing position...', + message: 'Closing position...', variant: 'pending', persist: true, key: loaderKey @@ -796,7 +796,7 @@ export function* handleClosePosition(action: PayloadAction) { yield put(snackbarsActions.remove(loaderKey)) yield put( snackbarsActions.add({ - message: 'Position successfully removed', + message: 'Position removed.', variant: 'success', persist: false, txid: txResult.hash @@ -843,7 +843,7 @@ export function* handleClosePositionWithAZERO(action: PayloadAction>): Generato yield put( snackbarsActions.add({ - message: 'Tokens swapped successfully.', + message: 'Tokens swapped.', variant: 'success', persist: false, txid: txResult.hash @@ -196,7 +196,7 @@ export function* handleSwap(action: PayloadAction>): Generato } else { yield put( snackbarsActions.add({ - message: 'Tokens swapping failed. Please try again.', + message: 'Tokens swap failed. Please try again.', variant: 'error', persist: false }) @@ -355,7 +355,7 @@ export function* handleSwapWithAZERO(action: PayloadAction>): yield put( snackbarsActions.add({ - message: 'Tokens swapped successfully.', + message: 'Tokens swapped.', variant: 'success', persist: false, txid: txResult.hash @@ -396,7 +396,7 @@ export function* handleSwapWithAZERO(action: PayloadAction>): } else { yield put( snackbarsActions.add({ - message: 'Tokens swapping failed. Please try again.', + message: 'Tokens swap failed. Please try again.', variant: 'error', persist: false }) diff --git a/src/store/sagas/wallet.ts b/src/store/sagas/wallet.ts index e854926f..d610b41c 100644 --- a/src/store/sagas/wallet.ts +++ b/src/store/sagas/wallet.ts @@ -60,7 +60,7 @@ export function* handleAirdrop(): Generator { if (!walletAddress) { return yield* put( snackbarsActions.add({ - message: 'You have to connect your wallet before claiming the faucet', + message: 'Connect your wallet to claim the faucet.', variant: 'error', persist: false }) From da133e432282b8f697de06475601f7b4acd84514 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Mon, 22 Jul 2024 16:48:26 +0200 Subject: [PATCH 34/75] fix concentration level when changing fee tiers --- .../RangeSelector/RangeSelector.tsx | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/components/NewPosition/RangeSelector/RangeSelector.tsx b/src/components/NewPosition/RangeSelector/RangeSelector.tsx index 6adcb804..d386cc1d 100644 --- a/src/components/NewPosition/RangeSelector/RangeSelector.tsx +++ b/src/components/NewPosition/RangeSelector/RangeSelector.tsx @@ -187,15 +187,18 @@ export const RangeSelector: React.FC = ({ setPlotMin(midPrice.x - initSideDist) setPlotMax(midPrice.x + initSideDist) } else { - setConcentrationIndex(0) + const newConcentrationIndex = concentrationArray[concentrationIndex] + ? Math.floor(concentrationIndex) + : concentrationArray.length - 1 + + setConcentrationIndex(newConcentrationIndex) const { leftRange, rightRange } = calculateConcentrationRange( tickSpacing, - concentrationArray[0], + concentrationArray[newConcentrationIndex], 2, midPrice.index, isXtoY ) - changeRangeHandler(leftRange, rightRange) autoZoomHandler(leftRange, rightRange, true) } @@ -353,6 +356,7 @@ export const RangeSelector: React.FC = ({ ? concentrationArray.length - 1 : concentrationIndex setConcentrationIndex(index) + console.log('test') const { leftRange, rightRange } = calculateConcentrationRange( tickSpacing, concentrationArray[index], @@ -366,6 +370,24 @@ export const RangeSelector: React.FC = ({ } }, [midPrice.index, concentrationArray]) + useEffect(() => { + if (shouldReversePlot) { + return + } + + setConcentrationIndex(0) + const { leftRange, rightRange } = calculateConcentrationRange( + tickSpacing, + concentrationArray[0], + 2, + midPrice.index, + isXtoY + ) + + changeRangeHandler(leftRange, rightRange) + autoZoomHandler(leftRange, rightRange, true) + }, [tokenASymbol, tokenBSymbol]) + return ( From 0e2d10e8a72c573c104bce04585ae5826d5bcec7 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 22 Jul 2024 16:49:32 +0200 Subject: [PATCH 35/75] use asset ticker map in path handling in swap page --- src/components/Swap/Swap.tsx | 21 +++++++++++++++------ src/containers/WrappedSwap/WrappedSwap.tsx | 9 ++++++--- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/components/Swap/Swap.tsx b/src/components/Swap/Swap.tsx index 8e4f5b23..f63c5b7c 100644 --- a/src/components/Swap/Swap.tsx +++ b/src/components/Swap/Swap.tsx @@ -15,7 +15,13 @@ import { DEFAULT_TOKEN_DECIMAL, REFRESHER_INTERVAL } from '@store/consts/static' -import { convertBalanceToBigint, printBigint, stringToFixed, trimLeadingZeros } from '@utils/utils' +import { + addressToTicker, + convertBalanceToBigint, + printBigint, + stringToFixed, + trimLeadingZeros +} from '@utils/utils' import { PoolWithPoolKey } from '@store/reducers/pools' import { Swap as SwapData } from '@store/reducers/swap' import { Status } from '@store/reducers/wallet' @@ -152,11 +158,14 @@ export const Swap: React.FC = ({ const navigate = useNavigate() useEffect(() => { - const tokenFromAddress = tokens[tokenFromIndex ?? -1]?.assetAddress - const tokenToAddress = tokens[tokenToIndex ?? -1]?.assetAddress - navigate(`/swap/${tokenFromAddress || '-'}/${tokenToAddress || '-'}`, { - replace: true - }) + const tokenFromAddress = addressToTicker(tokens[tokenFromIndex ?? -1]?.assetAddress) + const tokenToAddress = addressToTicker(tokens[tokenToIndex ?? -1]?.assetAddress) + + if (tokenFromAddress || tokenToAddress) { + navigate(`/swap/${tokenFromAddress || '-'}/${tokenToAddress || '-'}`, { + replace: true + }) + } }, [tokenToIndex, tokenFromIndex]) useEffect(() => { diff --git a/src/containers/WrappedSwap/WrappedSwap.tsx b/src/containers/WrappedSwap/WrappedSwap.tsx index a9e30b96..a173c2aa 100644 --- a/src/containers/WrappedSwap/WrappedSwap.tsx +++ b/src/containers/WrappedSwap/WrappedSwap.tsx @@ -6,7 +6,8 @@ import { addNewTokenToLocalStorage, getCoinGeckoTokenPrice, getMockedTokenPrice, - getNewTokenOrThrow + getNewTokenOrThrow, + tickerToAddress } from '@utils/utils' import { actions as poolsActions } from '@store/reducers/pools' import { actions as snackbarsActions } from '@store/reducers/snackbars' @@ -93,8 +94,10 @@ export const WrappedSwap = ({ initialTokenFrom, initialTokenTo }: Props) => { }, [isFetchingNewPool]) const lastTokenFrom = - initialTokenFrom || localStorage.getItem(`INVARIANT_LAST_TOKEN_FROM_${network}`) - const lastTokenTo = initialTokenTo || localStorage.getItem(`INVARIANT_LAST_TOKEN_TO_${network}`) + tickerToAddress(initialTokenFrom) || + localStorage.getItem(`INVARIANT_LAST_TOKEN_FROM_${network}`) + const lastTokenTo = + tickerToAddress(initialTokenTo) || localStorage.getItem(`INVARIANT_LAST_TOKEN_TO_${network}`) const initialTokenFromIndex = lastTokenFrom === null From 032673b4f174f69c7966e570ab076b6301447d13 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 22 Jul 2024 17:25:59 +0200 Subject: [PATCH 36/75] fix path resetting when clicking on swap menu button second time --- src/components/Header/Header.tsx | 21 +++++++++++++++++---- src/components/Swap/Swap.tsx | 2 +- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 524889d6..aaebb0b0 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -55,7 +55,8 @@ export const Header: React.FC = ({ const routes = ['swap', 'pool', 'stats'] const otherRoutesToHighlight: Record = { - pool: [/^newPosition\/*/, /^position\/*/] + pool: [/^newPosition\/*/, /^position\/*/], + swap: [/^swap\/*/] } const [activePath, setActive] = useState('swap') @@ -89,7 +90,11 @@ export const Header: React.FC = ({ navigate('/swap')} + onClick={() => { + if (!activePath.startsWith('swap')) { + navigate('/swap') + } + }} /> @@ -104,7 +109,11 @@ export const Header: React.FC = ({ navigate('/swap')} + onClick={() => { + if (!activePath.startsWith('swap')) { + navigate('/swap') + } + }} /> @@ -119,7 +128,11 @@ export const Header: React.FC = ({ { + onClick={e => { + if (path === 'swap' && activePath.startsWith('swap')) { + e.preventDefault() + } + setActive(path) }} active={ diff --git a/src/components/Swap/Swap.tsx b/src/components/Swap/Swap.tsx index f63c5b7c..f561ebd1 100644 --- a/src/components/Swap/Swap.tsx +++ b/src/components/Swap/Swap.tsx @@ -37,7 +37,7 @@ import useStyles from './style' import { SimulateResult, TokenPriceData } from '@store/consts/types' import TokensInfo from './TokensInfo/TokensInfo' import { VariantType } from 'notistack' -import { useNavigate } from 'react-router-dom' +import { useLocation, useNavigate } from 'react-router-dom' export interface Pools { tokenX: string From 40e7fbeb0f4fe06ab18c25bdefaf14d44f5d43db Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 22 Jul 2024 17:28:05 +0200 Subject: [PATCH 37/75] remove unnecessary import --- src/components/Swap/Swap.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Swap/Swap.tsx b/src/components/Swap/Swap.tsx index f561ebd1..f63c5b7c 100644 --- a/src/components/Swap/Swap.tsx +++ b/src/components/Swap/Swap.tsx @@ -37,7 +37,7 @@ import useStyles from './style' import { SimulateResult, TokenPriceData } from '@store/consts/types' import TokensInfo from './TokensInfo/TokensInfo' import { VariantType } from 'notistack' -import { useLocation, useNavigate } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' export interface Pools { tokenX: string From 9b650a1e0510535913e713b523bfedfc2c87f3b4 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Tue, 23 Jul 2024 11:54:07 +0200 Subject: [PATCH 38/75] focus input after open modal --- .../SelectTokenModal/SelectTokenModal.tsx | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx index c551320e..5e4e88b3 100644 --- a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx +++ b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx @@ -1,7 +1,7 @@ import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline' import searchIcon from '@static/svg/lupa.svg' import { theme } from '@static/theme' -import React, { forwardRef, useMemo, useRef, useState } from 'react' +import React, { forwardRef, useEffect, useMemo, useRef, useState } from 'react' import { FixedSizeList as List } from 'react-window' import CustomScrollbar from '../CustomScrollbar' import useStyles from '../style' @@ -76,6 +76,7 @@ export const SelectTokenModal: React.FC = ({ const outerRef = useRef(null) const listRef = useRef(null) + const inputRef = useRef(null) const tokensWithIndexes = useMemo( () => @@ -123,6 +124,22 @@ export const SelectTokenModal: React.FC = ({ setValue(e.target.value) } + useEffect(() => { + let timeoutId: NodeJS.Timeout | null = null + if (open) { + timeoutId = setTimeout(() => { + if (inputRef.current) { + inputRef.current.focus() + } + }, 100) + } + return () => { + if (timeoutId) { + clearTimeout(timeoutId) + } + } + }, [open]) + return ( <> = ({ alignItems='center'> Date: Tue, 23 Jul 2024 12:37:11 +0200 Subject: [PATCH 39/75] highlight address --- src/components/Modals/SelectModals/style.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/Modals/SelectModals/style.ts b/src/components/Modals/SelectModals/style.ts index 3a792a2b..e652ce9f 100644 --- a/src/components/Modals/SelectModals/style.ts +++ b/src/components/Modals/SelectModals/style.ts @@ -166,6 +166,10 @@ const useStyles = makeStyles()((theme: Theme) => { justifyContent: 'center', gap: '12px', textDecoration: 'none', + + '&:hover': { + filter: 'brightness(1.2)' + }, '& p': { color: colors.invariant.lightGrey, ...typography.caption4, From 0c284eb94907e05b8535ad8f58c0bb1c4d5ebd6b Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Tue, 23 Jul 2024 12:42:59 +0200 Subject: [PATCH 40/75] highlight address of token --- .../Swap/TokensInfo/SingleToken/SingleToken.tsx | 3 +-- src/components/Swap/TokensInfo/styles.ts | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/components/Swap/TokensInfo/SingleToken/SingleToken.tsx b/src/components/Swap/TokensInfo/SingleToken/SingleToken.tsx index 5830204b..ddfc44a8 100644 --- a/src/components/Swap/TokensInfo/SingleToken/SingleToken.tsx +++ b/src/components/Swap/TokensInfo/SingleToken/SingleToken.tsx @@ -69,7 +69,7 @@ const SingleToken: React.FC = ({ token, tokenPrice, copyTokenAddressHand {token ? (tokenPrice ? '$' + formatNumber(tokenPrice) : 'No data') : '--'} - + {token ? token.assetAddress.slice(0, 4) + '...' + token.assetAddress.slice(-5, -1) @@ -81,7 +81,6 @@ const SingleToken: React.FC = ({ token, tokenPrice, copyTokenAddressHand src={icons.copyAddress} alt={'Copy address'} className={classes.clipboardIcon} - onClick={copyToClipboard} /> diff --git a/src/components/Swap/TokensInfo/styles.ts b/src/components/Swap/TokensInfo/styles.ts index ace483dc..d0e19e54 100644 --- a/src/components/Swap/TokensInfo/styles.ts +++ b/src/components/Swap/TokensInfo/styles.ts @@ -55,6 +55,10 @@ export const useStyles = makeStyles<{ isToken: boolean }>()((_theme, { isToken } flexWrap: 'nowrap', alignItems: 'center', columnGap: 4, + cursor: isToken ? 'pointer' : 'default', + '&:hover': { + filter: isToken ? 'brightness(1.2)' : 'none' + }, '& p': { color: colors.invariant.textGrey, @@ -85,11 +89,7 @@ export const useStyles = makeStyles<{ isToken: boolean }>()((_theme, { isToken } clipboardIcon: { display: 'inline-block', height: 10, - color: colors.invariant.textGrey, - cursor: isToken ? 'pointer' : 'default', - '&:hover': { - filter: isToken ? 'brightness(1.2)' : 'none' - } + color: colors.invariant.textGrey }, link: { maxHeight: 8, From d99e7097e15ce44dcecd03691dd4d85988e795a7 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Tue, 23 Jul 2024 14:33:07 +0200 Subject: [PATCH 41/75] add shadow for snackbars --- src/components/Snackbar/CustomSnackbar/style.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Snackbar/CustomSnackbar/style.ts b/src/components/Snackbar/CustomSnackbar/style.ts index b2692009..45f0d418 100644 --- a/src/components/Snackbar/CustomSnackbar/style.ts +++ b/src/components/Snackbar/CustomSnackbar/style.ts @@ -15,7 +15,8 @@ export const StyledSnackbarContent = styled(SnackbarContent)(({ theme }) => ({ borderRadius: 15, ...typography.body2, marginBottom: 5, - + boxShadow: + 'rgba(0, 0, 0, 0.2) 0px 3px 5px -1px, rgba(0, 0, 0, 0.2) 0px 6px 10px 0px, rgba(0, 0, 0, 0.2) 0px 1px 18px 0px', '& .MuiCircularProgress-colorPrimary': { color: colors.invariant.textGrey }, From cd5e59eea6663d4b4840ba42c9391866f928a924 Mon Sep 17 00:00:00 2001 From: zielvna Date: Tue, 23 Jul 2024 17:40:26 +0200 Subject: [PATCH 42/75] fix get coingecko token price function --- src/utils/utils.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/utils/utils.ts b/src/utils/utils.ts index bb7ac821..19474400 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -253,9 +253,6 @@ export const getCoinGeckoTokenPrice = async (id: string): Promise Date: Tue, 23 Jul 2024 18:41:23 +0200 Subject: [PATCH 43/75] fix ui issues --- src/components/Header/HeaderButton/style.ts | 3 + src/components/Modals/AddTokenModal/style.ts | 3 +- .../SelectTokenModal/SelectTokenModal.tsx | 2 +- src/components/Snackbar/index.tsx | 2 +- src/components/Swap/ExchangeRate/style.ts | 9 +- src/components/Swap/Swap.tsx | 91 ++++++++++--------- src/components/Swap/style.ts | 56 ++++++++---- 7 files changed, 98 insertions(+), 68 deletions(-) diff --git a/src/components/Header/HeaderButton/style.ts b/src/components/Header/HeaderButton/style.ts index 1f5b1cdc..452a6b6d 100644 --- a/src/components/Header/HeaderButton/style.ts +++ b/src/components/Header/HeaderButton/style.ts @@ -21,6 +21,9 @@ const useStyles = makeStyles()((theme: Theme) => { '& #downIcon': { transform: 'rotateX(180deg)' } + }, + [theme.breakpoints.down('sm')]: { + paddingInline: 6 } }, label: { diff --git a/src/components/Modals/AddTokenModal/style.ts b/src/components/Modals/AddTokenModal/style.ts index 8f651fdd..4737d6ec 100644 --- a/src/components/Modals/AddTokenModal/style.ts +++ b/src/components/Modals/AddTokenModal/style.ts @@ -9,7 +9,8 @@ const useStyles = makeStyles()((theme: Theme) => { width: 480, height: 140, borderRadius: 24, - padding: '20px 24px' + padding: '20px 24px', + maxWidth: '100%' }, popover: { marginTop: 'calc(50vh - 350px)', diff --git a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx index 5e4e88b3..ca458a7c 100644 --- a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx +++ b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx @@ -234,7 +234,7 @@ export const SelectTokenModal: React.FC = ({ container style={{ ...style, - width: listRef.current ? listRef.current.clientWidth : 'calc(100% - 48px)' + width: listRef.current ? listRef.current.clientWidth : 'calc(100% - 35px)' }} alignItems='center' wrap='nowrap' diff --git a/src/components/Snackbar/index.tsx b/src/components/Snackbar/index.tsx index d0b1a478..f7c8d90e 100644 --- a/src/components/Snackbar/index.tsx +++ b/src/components/Snackbar/index.tsx @@ -28,7 +28,7 @@ interface ISnackbarProps { } const Snackbar: React.FC = ({ maxSnack = 3, children }) => { - const isExSmall = useMediaQuery(theme.breakpoints.down('xs')) + const isExSmall = useMediaQuery(theme.breakpoints.down('sm')) return ( ({ justifyContent: 'center', whiteSpace: 'nowrap', textOverflow: 'ellipsis', - overflow: 'hidden', - - [theme.breakpoints.down('sm')]: { - ...typography.tiny2 - } + overflow: 'hidden' }, loadingContainer: { width: 20, @@ -36,6 +32,9 @@ export const useStyles = makeStyles()(() => ({ display: 'flex', '&:hover': { borderColor: colors.invariant.lightHover + }, + '@media (max-width: 400px)': { + width: '100%' } } })) diff --git a/src/components/Swap/Swap.tsx b/src/components/Swap/Swap.tsx index 707299a7..91e03063 100644 --- a/src/components/Swap/Swap.tsx +++ b/src/components/Swap/Swap.tsx @@ -604,55 +604,58 @@ export const Swap: React.FC = ({ /> - - + + + + {tokenFromIndex !== null && tokenToIndex !== null && tokenFromIndex !== tokenToIndex && ( - - )} - - {canShowDetails ? ( - setRateReversed(!rateReversed)} - tokenFromSymbol={tokens[rateReversed ? tokenToIndex : tokenFromIndex].symbol} - tokenToSymbol={tokens[rateReversed ? tokenFromIndex : tokenToIndex].symbol} - amount={rateReversed ? 1 / swapRate : swapRate} - tokenToDecimals={Number( - tokens[rateReversed ? tokenFromIndex : tokenToIndex].decimals + + + )} - loading={getStateMessage() === 'Loading'} - /> - ) : null} + + {canShowDetails ? ( + setRateReversed(!rateReversed)} + tokenFromSymbol={tokens[rateReversed ? tokenToIndex : tokenFromIndex].symbol} + tokenToSymbol={tokens[rateReversed ? tokenFromIndex : tokenToIndex].symbol} + amount={rateReversed ? 1 / swapRate : swapRate} + tokenToDecimals={Number( + tokens[rateReversed ? tokenFromIndex : tokenToIndex].decimals + )} + loading={getStateMessage() === 'Loading'} + /> + ) : null} + ({ border: 'none', minWidth: 'auto', color: colors.invariant.lightHover, - padding: 'none', + padding: 0, '&:hover': { filter: 'brightness(1.15)', cursor: 'pointer' + }, + '@media (max-width: 400px)': { + width: '100%' } }, @@ -58,7 +61,11 @@ export const useStyles = makeStyles()((theme: Theme) => ({ background: 'none !important', border: 'none', minWidth: 'auto', - color: colors.invariant.lightHover + padding: 0, + color: colors.invariant.lightHover, + '@media (max-width: 400px)': { + width: '100%' + } }, swapControls: { @@ -177,13 +184,19 @@ export const useStyles = makeStyles()((theme: Theme) => ({ transactionDetails: { display: 'flex', alignItems: 'center', - justifyContent: 'space-between', - flexFlow: 'row nowrap', + justifyContent: 'flex-start', + flexFlow: 'row', + flexWrap: 'wrap', marginTop: 24, marginBottom: 12, position: 'relative', cursor: 'default', - filter: 'brightness(0.9)' + filter: 'brightness(0.9)', + width: '100%', + '@media (max-width: 400px)': { + flexDirection: 'column-reverse', + gap: 4 + } }, transactionDetailsWrapper: { display: 'flex', @@ -200,11 +213,25 @@ export const useStyles = makeStyles()((theme: Theme) => ({ whiteSpace: 'nowrap', pointerEvents: 'none', color: colors.invariant.lightGrey, - [theme.breakpoints.down('sm')]: { - ...typography.tiny2 + + '@media (max-width: 400px)': { + flex: 1 + } + }, + revertWrapper: { + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + marginLeft: 8, + flex: 1, + '@media (max-width: 400px)': { + width: '100%', + flex: 'auto', + flexDirection: 'row-reverse', + columnGap: 8, + marginLeft: 0 } }, - swapButton: { width: '100%', height: 48 @@ -223,12 +250,7 @@ export const useStyles = makeStyles()((theme: Theme) => ({ padding: '5px 15px 5px 15px' }, - transactionBottom: { - // marginTop: 10, - // [theme.breakpoints.down('sm')]: { - // marginTop: 36 - // } - }, + transactionBottom: {}, transtactionData: { border: `1px solid ${colors.invariant.light}`, @@ -247,10 +269,11 @@ export const useStyles = makeStyles()((theme: Theme) => ({ } }, infoIcon: { + display: 'inline-block', width: 10, height: 10, marginLeft: 4, - marginBottom: 2, + filter: 'brightness(0.8)', pointerEvents: 'none' }, @@ -258,7 +281,8 @@ export const useStyles = makeStyles()((theme: Theme) => ({ display: 'flex', justifyContent: 'space-between', alignItems: 'center', - gap: 8 + gap: 8, + flexWrap: 'wrap' }, slippageButton: { height: 27, From f2a561222975a45c2cc67cb5b153f613e3cec1b2 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Wed, 24 Jul 2024 08:51:25 +0200 Subject: [PATCH 44/75] fix build --- src/components/PositionsList/PositionsList.tsx | 12 +++++++++++- src/components/PositionsList/style.ts | 6 ++++++ src/components/Swap/ExchangeRate/style.ts | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/components/PositionsList/PositionsList.tsx b/src/components/PositionsList/PositionsList.tsx index a5610875..ea308bf3 100644 --- a/src/components/PositionsList/PositionsList.tsx +++ b/src/components/PositionsList/PositionsList.tsx @@ -1,7 +1,7 @@ import { EmptyPlaceholder } from '@components/EmptyPlaceholder/EmptyPlaceholder' import { INoConnected, NoConnected } from '@components/NoConnected/NoConnected' import { PaginationList } from '@components/PaginationList/PaginationList' -import { Button, Grid, InputAdornment, InputBase, Typography } from '@mui/material' +import { Box, Button, Grid, Hidden, InputAdornment, InputBase, Typography } from '@mui/material' import loader from '@static/gif/loader.gif' import SearchIcon from '@static/svg/lupaDark.svg' import refreshIcon from '@static/svg/refresh.svg' @@ -103,10 +103,12 @@ export const PositionsList: React.FC = ({ justifyContent='space-between' alignItems='center'> + {/* */} Your Liquidity Positions {String(length)} + {/* */} = ({ onChange={handleChangeInput} value={searchValue} /> + {/* */} + {/* + + Your Liquidity Positions + {String(length)} + + */} + {/* */} diff --git a/src/components/PositionsList/style.ts b/src/components/PositionsList/style.ts index 2285c666..150e4b2e 100644 --- a/src/components/PositionsList/style.ts +++ b/src/components/PositionsList/style.ts @@ -154,5 +154,11 @@ export const useStyles = makeStyles()((theme: Theme) => ({ '&:hover': { filter: 'brightness(1.5)' } + }, + titleMobileContainer: { + display: 'flex', + flexDirection: 'row', + + alignItems: 'center' } })) diff --git a/src/components/Swap/ExchangeRate/style.ts b/src/components/Swap/ExchangeRate/style.ts index 53917c38..26927ce1 100644 --- a/src/components/Swap/ExchangeRate/style.ts +++ b/src/components/Swap/ExchangeRate/style.ts @@ -1,4 +1,4 @@ -import { colors, theme, typography } from '@static/theme' +import { colors, typography } from '@static/theme' import { makeStyles } from 'tss-react/mui' export const useStyles = makeStyles()(() => ({ From e985957698496d5431f42ebe9484a58ed07c2133 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Wed, 24 Jul 2024 09:01:48 +0200 Subject: [PATCH 45/75] fix build --- src/components/PositionsList/PositionsList.tsx | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/components/PositionsList/PositionsList.tsx b/src/components/PositionsList/PositionsList.tsx index ea308bf3..a5610875 100644 --- a/src/components/PositionsList/PositionsList.tsx +++ b/src/components/PositionsList/PositionsList.tsx @@ -1,7 +1,7 @@ import { EmptyPlaceholder } from '@components/EmptyPlaceholder/EmptyPlaceholder' import { INoConnected, NoConnected } from '@components/NoConnected/NoConnected' import { PaginationList } from '@components/PaginationList/PaginationList' -import { Box, Button, Grid, Hidden, InputAdornment, InputBase, Typography } from '@mui/material' +import { Button, Grid, InputAdornment, InputBase, Typography } from '@mui/material' import loader from '@static/gif/loader.gif' import SearchIcon from '@static/svg/lupaDark.svg' import refreshIcon from '@static/svg/refresh.svg' @@ -103,12 +103,10 @@ export const PositionsList: React.FC = ({ justifyContent='space-between' alignItems='center'> - {/* */} Your Liquidity Positions {String(length)} - {/* */} = ({ onChange={handleChangeInput} value={searchValue} /> - {/* */} - {/* - - Your Liquidity Positions - {String(length)} - - */} - {/* */} From 27722efea6bb30df29a40f534aaf7462c1a849f0 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Wed, 24 Jul 2024 10:25:58 +0200 Subject: [PATCH 46/75] fix width of tokens in select modal --- .../Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx index ca458a7c..8c8e2d96 100644 --- a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx +++ b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx @@ -234,7 +234,7 @@ export const SelectTokenModal: React.FC = ({ container style={{ ...style, - width: listRef.current ? listRef.current.clientWidth : 'calc(100% - 35px)' + width: listRef.current ? listRef.current.clientWidth : 'calc(100% - 50px)' }} alignItems='center' wrap='nowrap' From 4bf5156aa59cce6f8b0856c9d45bdf9afee75a15 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Wed, 24 Jul 2024 10:31:24 +0200 Subject: [PATCH 47/75] fix margin top of add token modal --- src/components/Modals/AddTokenModal/style.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Modals/AddTokenModal/style.ts b/src/components/Modals/AddTokenModal/style.ts index 4737d6ec..a737168c 100644 --- a/src/components/Modals/AddTokenModal/style.ts +++ b/src/components/Modals/AddTokenModal/style.ts @@ -13,7 +13,7 @@ const useStyles = makeStyles()((theme: Theme) => { maxWidth: '100%' }, popover: { - marginTop: 'calc(50vh - 350px)', + marginTop: 'max(calc(50vh - 350px), 20px)', marginLeft: 'calc(50vw - 241px)', [theme.breakpoints.down('sm')]: { display: 'flex', From c8e196d16108636c3e3c9a560ec324198e66dee1 Mon Sep 17 00:00:00 2001 From: zielvna Date: Wed, 24 Jul 2024 11:25:48 +0200 Subject: [PATCH 48/75] refactor logic behind showing only user positions in new position page --- src/store/sagas/positions.ts | 57 ++---------------------------------- src/utils/utils.ts | 49 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 55 deletions(-) diff --git a/src/store/sagas/positions.ts b/src/store/sagas/positions.ts index 2af3f8db..67bb1e4c 100644 --- a/src/store/sagas/positions.ts +++ b/src/store/sagas/positions.ts @@ -20,6 +20,7 @@ import { createPlaceholderLiquidityPlot, deserializeTickmap, ensureError, + getLiquidityTicksByPositionsList, isErrorMessage, poolKeyToString } from '@utils/utils' @@ -306,61 +307,7 @@ export function* handleGetCurrentPlotTicks(action: PayloadAction { - if (poolKeyToString(position.poolKey) !== poolKeyToString(poolKey)) { - return - } - - if (!ticks[Number(position.lowerTickIndex)]) { - ticks[Number(position.lowerTickIndex)] = { - liquidityChange: position.liquidity, - sign: true - } - } - - if (!ticks[Number(position.upperTickIndex)]) { - ticks[Number(position.upperTickIndex)] = { - liquidityChange: position.liquidity, - sign: false - } - } - - if (ticks[Number(position.lowerTickIndex)].sign) { - ticks[Number(position.lowerTickIndex)].liquidityChange += position.liquidity - } else { - if (ticks[Number(position.lowerTickIndex)].liquidityChange - position.liquidity < 0) { - ticks[Number(position.lowerTickIndex)] = { - liquidityChange: - ticks[Number(position.lowerTickIndex)].liquidityChange - position.liquidity, - sign: true - } - } else { - ticks[Number(position.lowerTickIndex)].liquidityChange - position.liquidity - } - } - - if (!ticks[Number(position.upperTickIndex)].sign) { - ticks[Number(position.upperTickIndex)].liquidityChange += position.liquidity - } else { - if (ticks[Number(position.upperTickIndex)].liquidityChange - position.liquidity < 0) { - ticks[Number(position.upperTickIndex)] = { - liquidityChange: - ticks[Number(position.upperTickIndex)].liquidityChange - position.liquidity, - sign: false - } - } else { - ticks[Number(position.upperTickIndex)].liquidityChange - position.liquidity - } - } - }) - - rawTicks = Object.entries(ticks).map(([index, { liquidityChange, sign }]) => ({ - index: BigInt(index), - liquidityChange, - sign - })) + rawTicks = getLiquidityTicksByPositionsList(poolKey, list) } else { rawTicks = yield* call( [invariant, invariant.getAllLiquidityTicks], diff --git a/src/utils/utils.ts b/src/utils/utils.ts index bb7ac821..e20b20de 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -4,6 +4,7 @@ import { Network, PSP22, PoolKey, + Position, Tick, Tickmap, calculateSqrtPrice, @@ -1117,3 +1118,51 @@ export const validConcentrationMidPriceTick = ( return midPriceTick } + +type LiquidityTickWithoutIndex = Omit + +export const getLiquidityTicksByPositionsList = ( + poolKey: PoolKey, + positions: Position[] +): LiquidityTick[] => { + const ticks: Record = {} + + positions.forEach(position => { + if (poolKeyToString(position.poolKey) === poolKeyToString(poolKey)) { + updateTick(ticks, Number(position.lowerTickIndex), position.liquidity, true) + updateTick(ticks, Number(position.upperTickIndex), position.liquidity, false) + } + }) + + return Object.entries(ticks).map(([index, { liquidityChange, sign }]) => ({ + index: BigInt(index), + liquidityChange, + sign + })) +} + +export const updateTick = ( + ticks: Record, + tickIndex: number, + positionLiquidity: bigint, + isLowerTick: boolean +) => { + if (!ticks[tickIndex]) { + ticks[tickIndex] = { + liquidityChange: positionLiquidity, + sign: isLowerTick + } + } + + const tick = ticks[tickIndex] + + if (tick.sign === isLowerTick) { + tick.liquidityChange += positionLiquidity + } else { + tick.liquidityChange -= positionLiquidity + if (tick.liquidityChange < 0) { + tick.liquidityChange = -tick.liquidityChange + tick.sign = isLowerTick + } + } +} From 6a2c41c096447bb8d3972357acfc17fff5e5ad02 Mon Sep 17 00:00:00 2001 From: zielvna Date: Wed, 24 Jul 2024 12:09:32 +0200 Subject: [PATCH 49/75] fix reconnect issue with nightly connect adapter --- src/utils/web3/selector.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/web3/selector.ts b/src/utils/web3/selector.ts index 06d94001..4830cd33 100644 --- a/src/utils/web3/selector.ts +++ b/src/utils/web3/selector.ts @@ -12,7 +12,7 @@ export const nightlyConnectAdapter = async ( connectionOptions: ConnectionOptions = {} ) => { if (_adapter) return _adapter - _adapter = await NightlyConnectAdapter.buildLazy( + _adapter = await NightlyConnectAdapter.build( { appMetadata: { name: 'Invariant', From 08d0290fc1cc76c91501130229f61562ec8ccd8e Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Wed, 24 Jul 2024 15:02:32 +0200 Subject: [PATCH 50/75] fix concentration level when changing fee tier --- .../RangeSelector/RangeSelector.tsx | 21 +++++++++++++++---- src/utils/utils.ts | 19 +++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/components/NewPosition/RangeSelector/RangeSelector.tsx b/src/components/NewPosition/RangeSelector/RangeSelector.tsx index d386cc1d..16d10915 100644 --- a/src/components/NewPosition/RangeSelector/RangeSelector.tsx +++ b/src/components/NewPosition/RangeSelector/RangeSelector.tsx @@ -8,6 +8,7 @@ import { calcPriceByTickIndex, calcTicksAmountInRange, calculateConcentrationRange, + findClosestIndexByValue, nearestTickIndex, toMaxNumericPlaces } from '@utils/utils' @@ -98,6 +99,8 @@ export const RangeSelector: React.FC = ({ const [currentMidPrice, setCurrentMidPrice] = useState(midPrice) const [triggerReset, setTriggerReset] = useState(false) + const [previousConcentration, setPreviousConcentration] = useState(0) + const isMountedRef = useRef(false) useEffect(() => { @@ -187,11 +190,13 @@ export const RangeSelector: React.FC = ({ setPlotMin(midPrice.x - initSideDist) setPlotMax(midPrice.x + initSideDist) } else { - const newConcentrationIndex = concentrationArray[concentrationIndex] - ? Math.floor(concentrationIndex) - : concentrationArray.length - 1 + const newConcentrationIndex = findClosestIndexByValue( + concentrationArray, + previousConcentration + ) setConcentrationIndex(newConcentrationIndex) + setPreviousConcentration(concentrationArray[newConcentrationIndex]) const { leftRange, rightRange } = calculateConcentrationRange( tickSpacing, concentrationArray[newConcentrationIndex], @@ -274,6 +279,13 @@ export const RangeSelector: React.FC = ({ } }, [ticksLoading, isMountedRef, midPrice.index, poolKey]) + useEffect(() => { + const newConcentrationIndex = findClosestIndexByValue(concentrationArray, previousConcentration) + + setConcentrationIndex(newConcentrationIndex) + setPreviousConcentration(concentrationArray[newConcentrationIndex]) + }, [concentrationArray]) + const autoZoomHandler = (left: bigint, right: bigint, canZoomCloser: boolean = false) => { const { leftInRange, rightInRange } = getTicksInsideRange(left, right, isXtoY) @@ -368,7 +380,7 @@ export const RangeSelector: React.FC = ({ changeRangeHandler(leftRange, rightRange) autoZoomHandler(leftRange, rightRange, true) } - }, [midPrice.index, concentrationArray]) + }, [midPrice.index]) useEffect(() => { if (shouldReversePlot) { @@ -549,6 +561,7 @@ export const RangeSelector: React.FC = ({ valueIndex={concentrationIndex} values={concentrationArray} valueChangeHandler={value => { + setPreviousConcentration(concentrationArray[value]) setConcentrationIndex(value) const { leftRange, rightRange } = calculateConcentrationRange( tickSpacing, diff --git a/src/utils/utils.ts b/src/utils/utils.ts index bb7ac821..4115f19d 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1117,3 +1117,22 @@ export const validConcentrationMidPriceTick = ( return midPriceTick } + +export const findClosestIndexByValue = (arr: number[], value: number): number => { + const high = arr.length - 1 + + if (value < arr[0]) { + return 0 + } + + if (value > arr[high]) { + return high + } + + for (let i = arr.length - 1; i >= 0; i--) { + if (Number(arr[i].toFixed(0)) <= Number(value.toFixed(0))) { + return i + } + } + return high +} From 118b56d5c22587051344ad30156ee922f69a116f Mon Sep 17 00:00:00 2001 From: zielvna Date: Wed, 24 Jul 2024 16:29:09 +0200 Subject: [PATCH 51/75] change only your positions label to show only your positions --- src/components/NewPosition/RangeSelector/RangeSelector.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/NewPosition/RangeSelector/RangeSelector.tsx b/src/components/NewPosition/RangeSelector/RangeSelector.tsx index 459ba8b0..e1232976 100644 --- a/src/components/NewPosition/RangeSelector/RangeSelector.tsx +++ b/src/components/NewPosition/RangeSelector/RangeSelector.tsx @@ -475,7 +475,7 @@ export const RangeSelector: React.FC = ({ color='secondary' /> } - label='Only your positions' + label='Show only your positions' classes={{ label: classes.checkboxLabel }} /> From b406af26020796cd736371cbadea399636dd05fa Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Wed, 24 Jul 2024 17:06:25 +0200 Subject: [PATCH 52/75] add icons to stats for swap and add position --- .../Stats/PoolListItem/PoolListItem.tsx | 22 ++++++++---- src/components/Stats/PoolListItem/style.ts | 34 +++++++++++++------ src/index.css | 1 - src/static/icons.ts | 6 +++- src/static/svg/horizontalSwapArrows.svg | 5 +++ src/static/svg/plus.svg | 4 +++ 6 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 src/static/svg/horizontalSwapArrows.svg create mode 100644 src/static/svg/plus.svg diff --git a/src/components/Stats/PoolListItem/PoolListItem.tsx b/src/components/Stats/PoolListItem/PoolListItem.tsx index 3c40b565..886beb2b 100644 --- a/src/components/Stats/PoolListItem/PoolListItem.tsx +++ b/src/components/Stats/PoolListItem/PoolListItem.tsx @@ -1,11 +1,12 @@ import React from 'react' import { theme } from '@static/theme' import { useStyles } from './style' -import { Box, Button, Grid, Typography, useMediaQuery } from '@mui/material' +import { Box, Grid, Typography, useMediaQuery } from '@mui/material' import { formatNumbers, showPrefix } from '@utils/utils' import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown' import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp' import { useNavigate } from 'react-router-dom' +import icons from '@static/icons' export enum SortType { NAME_ASC, @@ -69,8 +70,12 @@ const PoolListItem: React.FC = ({ const handleOpenPosition = () => { navigate(`/newPosition/${symbolFrom}/${symbolTo}/0_01`) } + + const handleOpenSwap = () => { + navigate(`/swap/${symbolFrom}/${symbolTo}`) + } return ( - + {displayType === 'token' ? ( = ({ {fee}% {`$${formatNumbers()(volume.toString())}${showPrefix(volume)}`} {`$${formatNumbers()(TVL.toString())}${showPrefix(TVL)}`} - + + + + ) : ( @@ -224,7 +234,7 @@ const PoolListItem: React.FC = ({ ) : null} - Action + Action )} diff --git a/src/components/Stats/PoolListItem/style.ts b/src/components/Stats/PoolListItem/style.ts index 30833926..4ec46fed 100644 --- a/src/components/Stats/PoolListItem/style.ts +++ b/src/components/Stats/PoolListItem/style.ts @@ -5,18 +5,22 @@ export const useStyles = makeStyles()(() => ({ container: { color: colors.white.main, display: 'grid', - gridTemplateColumns: '5% auto 15% 15% 15% 140px', + gridTemplateColumns: '5% auto 15% 15% 15% 80px', padding: '18px 0', - backgroundColor: colors.invariant.component, borderBottom: `1px solid ${colors.invariant.light}`, whiteSpace: 'nowrap', + maxWidth: '100%', + '& p': { ...typography.heading4, display: 'flex', - justifyContent: 'start', + justifyContent: 'flex-start', alignItems: 'center' }, + '& p:last-child': { + justifyContent: 'flex-end' + }, [theme.breakpoints.down('sm')]: { '& p': { @@ -109,18 +113,28 @@ export const useStyles = makeStyles()(() => ({ color: colors.invariant.text, ...typography.caption1 }, - openPosition: { - width: 140, + action: { + display: 'flex', + justifyContent: 'flex-end', + alignItems: 'center', + gap: 8 + }, + actionButton: { height: 32, - background: colors.invariant.greenLinearGradient, - ...typography.body1, + background: 'none', + width: 32, + padding: 0, + margin: 0, + border: 'none', + color: colors.invariant.black, textTransform: 'none', - borderRadius: 10, - transition: 'filter 0.3s linear', + + transition: 'filter 0.2s linear', '&:hover': { - filter: 'brightness(1.15)' + filter: 'brightness(1.2)', + cursor: 'pointer' } } })) diff --git a/src/index.css b/src/index.css index 0244ae48..e036f1e3 100644 --- a/src/index.css +++ b/src/index.css @@ -1,7 +1,6 @@ * { min-width: 0; min-height: 0; - max-width: 100%; } body { margin: 0; diff --git a/src/static/icons.ts b/src/static/icons.ts index 52c1ee67..f4bfda32 100644 --- a/src/static/icons.ts +++ b/src/static/icons.ts @@ -22,6 +22,8 @@ import closeSmallIcon from './svg/closeSmall.svg' import successIcon from './svg/successIcon.svg' import xIcon from './svg/xCircle.svg' import unknownToken from './svg/unknownToken.svg' +import plusIcon from './svg/plus.svg' +import horizontalSwapIcon from './svg/horizontalSwapArrows.svg' const icons: { [key: string]: string } = { clear: clearIcon, @@ -47,7 +49,9 @@ const icons: { [key: string]: string } = { docsIcon: docsIcon, successIcon: successIcon, XIcon: xIcon, - unknownToken: unknownToken + unknownToken: unknownToken, + plusIcon: plusIcon, + horizontalSwapIcon: horizontalSwapIcon } export default icons diff --git a/src/static/svg/horizontalSwapArrows.svg b/src/static/svg/horizontalSwapArrows.svg new file mode 100644 index 00000000..0c9092b3 --- /dev/null +++ b/src/static/svg/horizontalSwapArrows.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/static/svg/plus.svg b/src/static/svg/plus.svg new file mode 100644 index 00000000..734c1abb --- /dev/null +++ b/src/static/svg/plus.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From b62a601942e91349e1fa7f900944e3a6c13698c8 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Wed, 24 Jul 2024 17:09:16 +0200 Subject: [PATCH 53/75] revert functions --- src/components/Stats/PoolListItem/PoolListItem.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Stats/PoolListItem/PoolListItem.tsx b/src/components/Stats/PoolListItem/PoolListItem.tsx index 886beb2b..f6551874 100644 --- a/src/components/Stats/PoolListItem/PoolListItem.tsx +++ b/src/components/Stats/PoolListItem/PoolListItem.tsx @@ -137,10 +137,10 @@ const PoolListItem: React.FC = ({ {`$${formatNumbers()(volume.toString())}${showPrefix(volume)}`} {`$${formatNumbers()(TVL.toString())}${showPrefix(TVL)}`} - - From 43372c4b76110ed338e35f41a7f7cb6a3ae3354e Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 25 Jul 2024 08:26:05 +0200 Subject: [PATCH 54/75] show snackbars only from bottom --- src/components/Snackbar/index.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/Snackbar/index.tsx b/src/components/Snackbar/index.tsx index f7c8d90e..b29978e7 100644 --- a/src/components/Snackbar/index.tsx +++ b/src/components/Snackbar/index.tsx @@ -34,11 +34,7 @@ const Snackbar: React.FC = ({ maxSnack = 3, children }) => { Date: Thu, 25 Jul 2024 08:28:10 +0200 Subject: [PATCH 55/75] hide stats --- src/pages/StatsPage/index.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pages/StatsPage/index.tsx b/src/pages/StatsPage/index.tsx index b4b293e1..b650c2a9 100644 --- a/src/pages/StatsPage/index.tsx +++ b/src/pages/StatsPage/index.tsx @@ -1,7 +1,6 @@ import { Grid } from '@mui/material' import { useStyles } from './styles' -// import workInProgress from '../../static/png/work-in-progress.png' -import WrappedStats from '@containers/WrappedStats/WrappedStats' +import workInProgress from '../../static/png/work-in-progress.png' // import WrappedStats from '@containers/WrappedStats/WrappedStats' export const StatsPage: React.FC = () => { @@ -9,8 +8,8 @@ export const StatsPage: React.FC = () => { return ( - {/* Work in progress icon */} - + Work in progress icon + {/* */} ) } From 710e2799df709e52a19119b2d5d01876a185dbd9 Mon Sep 17 00:00:00 2001 From: zielvna Date: Thu, 25 Jul 2024 09:47:17 +0200 Subject: [PATCH 56/75] make concentration slider jumps when changing fee tier more smooth --- .../RangeSelector/RangeSelector.tsx | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/components/NewPosition/RangeSelector/RangeSelector.tsx b/src/components/NewPosition/RangeSelector/RangeSelector.tsx index 16d10915..8dd5b23c 100644 --- a/src/components/NewPosition/RangeSelector/RangeSelector.tsx +++ b/src/components/NewPosition/RangeSelector/RangeSelector.tsx @@ -101,6 +101,8 @@ export const RangeSelector: React.FC = ({ const [previousConcentration, setPreviousConcentration] = useState(0) + const [cachedConcentrationArray, setCachedConcentrationArray] = useState(concentrationArray) + const isMountedRef = useRef(false) useEffect(() => { @@ -191,15 +193,15 @@ export const RangeSelector: React.FC = ({ setPlotMax(midPrice.x + initSideDist) } else { const newConcentrationIndex = findClosestIndexByValue( - concentrationArray, + cachedConcentrationArray, previousConcentration ) setConcentrationIndex(newConcentrationIndex) - setPreviousConcentration(concentrationArray[newConcentrationIndex]) + setPreviousConcentration(cachedConcentrationArray[newConcentrationIndex]) const { leftRange, rightRange } = calculateConcentrationRange( tickSpacing, - concentrationArray[newConcentrationIndex], + cachedConcentrationArray[newConcentrationIndex], 2, midPrice.index, isXtoY @@ -280,6 +282,8 @@ export const RangeSelector: React.FC = ({ }, [ticksLoading, isMountedRef, midPrice.index, poolKey]) useEffect(() => { + setCachedConcentrationArray(concentrationArray) + const newConcentrationIndex = findClosestIndexByValue(concentrationArray, previousConcentration) setConcentrationIndex(newConcentrationIndex) @@ -348,7 +352,7 @@ export const RangeSelector: React.FC = ({ setConcentrationIndex(0) const { leftRange, rightRange } = calculateConcentrationRange( tickSpacing, - concentrationArray[0], + cachedConcentrationArray[0], 2, midPrice.index, isXtoY @@ -364,14 +368,14 @@ export const RangeSelector: React.FC = ({ useEffect(() => { if (positionOpeningMethod === 'concentration' && !ticksLoading && isMountedRef.current) { const index = - concentrationIndex > concentrationArray.length - 1 - ? concentrationArray.length - 1 + concentrationIndex > cachedConcentrationArray.length - 1 + ? cachedConcentrationArray.length - 1 : concentrationIndex setConcentrationIndex(index) console.log('test') const { leftRange, rightRange } = calculateConcentrationRange( tickSpacing, - concentrationArray[index], + cachedConcentrationArray[index], 2, midPrice.index, isXtoY @@ -390,7 +394,7 @@ export const RangeSelector: React.FC = ({ setConcentrationIndex(0) const { leftRange, rightRange } = calculateConcentrationRange( tickSpacing, - concentrationArray[0], + cachedConcentrationArray[0], 2, midPrice.index, isXtoY @@ -559,13 +563,13 @@ export const RangeSelector: React.FC = ({ { - setPreviousConcentration(concentrationArray[value]) + setPreviousConcentration(cachedConcentrationArray[value]) setConcentrationIndex(value) const { leftRange, rightRange } = calculateConcentrationRange( tickSpacing, - concentrationArray[value], + cachedConcentrationArray[value], 2, midPrice.index, isXtoY From a8af7546d320487b12025d1ede23f7df7cdccbc7 Mon Sep 17 00:00:00 2001 From: zielvna Date: Thu, 25 Jul 2024 12:03:55 +0200 Subject: [PATCH 57/75] fix get liquidity ticks by positions list function --- src/utils/utils.ts | 51 ++++++++++++++++------------------------------ 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 24fbd788..d123f9f3 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1119,50 +1119,35 @@ export const validConcentrationMidPriceTick = ( return midPriceTick } -type LiquidityTickWithoutIndex = Omit - export const getLiquidityTicksByPositionsList = ( poolKey: PoolKey, positions: Position[] ): LiquidityTick[] => { - const ticks: Record = {} + const liquidityChanges: Record = {} positions.forEach(position => { if (poolKeyToString(position.poolKey) === poolKeyToString(poolKey)) { - updateTick(ticks, Number(position.lowerTickIndex), position.liquidity, true) - updateTick(ticks, Number(position.upperTickIndex), position.liquidity, false) + const lowerTickIndex = Number(position.lowerTickIndex) + const upperTickIndex = Number(position.upperTickIndex) + + liquidityChanges[lowerTickIndex] = + (liquidityChanges[lowerTickIndex] ?? 0n) + position.liquidity + liquidityChanges[upperTickIndex] = + (liquidityChanges[upperTickIndex] ?? 0n) - position.liquidity } }) - return Object.entries(ticks).map(([index, { liquidityChange, sign }]) => ({ - index: BigInt(index), - liquidityChange, - sign - })) -} + const ticks: LiquidityTick[] = [] -export const updateTick = ( - ticks: Record, - tickIndex: number, - positionLiquidity: bigint, - isLowerTick: boolean -) => { - if (!ticks[tickIndex]) { - ticks[tickIndex] = { - liquidityChange: positionLiquidity, - sign: isLowerTick - } - } + Object.entries(liquidityChanges).forEach(([tickIndex, liquidityChangeTotal]) => { + const index = BigInt(tickIndex) + const [liquidityChange, sign] = + liquidityChangeTotal > 0n ? [liquidityChangeTotal, true] : [-liquidityChangeTotal, false] - const tick = ticks[tickIndex] - - if (tick.sign === isLowerTick) { - tick.liquidityChange += positionLiquidity - } else { - tick.liquidityChange -= positionLiquidity - if (tick.liquidityChange < 0) { - tick.liquidityChange = -tick.liquidityChange - tick.sign = isLowerTick + if (liquidityChange !== 0n) { + ticks.push({ index, liquidityChange, sign }) } - } + }) + + return ticks } From 7d89165cb03020d1887a53aae97dfe2971c57679 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 25 Jul 2024 12:24:21 +0200 Subject: [PATCH 58/75] prevent shifting token description in select token modal --- .../SelectTokenModal/SelectTokenModal.tsx | 29 +++++++++++++------ src/components/Modals/SelectModals/style.ts | 24 ++++++++++----- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx index 8c8e2d96..d2a2cb4d 100644 --- a/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx +++ b/src/components/Modals/SelectModals/SelectTokenModal/SelectTokenModal.tsx @@ -75,7 +75,6 @@ export const SelectTokenModal: React.FC = ({ const [hideUnknown, setHideUnknown] = useState(initialHideUnknownTokensValue) const outerRef = useRef(null) - const listRef = useRef(null) const inputRef = useRef(null) const tokensWithIndexes = useMemo( @@ -216,7 +215,7 @@ export const SelectTokenModal: React.FC = ({ label='Hide unknown tokens' /> - + = ({ container style={{ ...style, - width: listRef.current ? listRef.current.clientWidth : 'calc(100% - 50px)' + width: 'calc(100% - 50px)' }} alignItems='center' wrap='nowrap' @@ -250,7 +249,12 @@ export const SelectTokenModal: React.FC = ({ alt={token.name + 'logo'} /> - + {token.symbol ? token.symbol : 'Unknown'}{' '} @@ -277,11 +281,18 @@ export const SelectTokenModal: React.FC = ({ {token.name.length > (isXs ? 20 : 30) ? '...' : ''} - {!hideBalances && Number(tokenBalance) > 0 ? ( - - Balance: {formatNumber(tokenBalance)} - - ) : null} + + {!hideBalances && Number(tokenBalance) > 0 ? ( + <> + Balance: +   {formatNumber(tokenBalance)} + + ) : null} + ) }} diff --git a/src/components/Modals/SelectModals/style.ts b/src/components/Modals/SelectModals/style.ts index e652ce9f..0c66607a 100644 --- a/src/components/Modals/SelectModals/style.ts +++ b/src/components/Modals/SelectModals/style.ts @@ -20,7 +20,8 @@ const useStyles = makeStyles()((theme: Theme) => { borderRadius: 20, width: 500, [theme.breakpoints.down('sm')]: { - maxWidth: '100vw' + maxWidth: '100vw', + padding: '16px 8px ' }, '& .MuiCheckbox-root.Mui-checked': { color: colors.green.button @@ -126,12 +127,17 @@ const useStyles = makeStyles()((theme: Theme) => { borderTop: `1px solid ${colors.invariant.light}`, width: 451, height: 400, - paddingTop: 8 + paddingTop: 8, + [theme.breakpoints.down('sm')]: { + flexDirection: 'column', + width: 501 + } }, tokenContainer: { display: 'flex', - flexDirection: 'column' + flexDirection: 'column', + minWidth: 'min-content' }, tokenItem: { @@ -140,7 +146,8 @@ const useStyles = makeStyles()((theme: Theme) => { marginBottom: 4, borderRadius: 24, cursor: 'pointer', - padding: '32px 16px ', + padding: '0 16px ', + '& > p': { whiteSpace: 'nowrap' }, @@ -184,12 +191,13 @@ const useStyles = makeStyles()((theme: Theme) => { whiteSpace: 'nowrap' }, tokenBalanceStatus: { - filter: 'brightness(0.8)', color: colors.invariant.textGrey, - ...typography.body2, - minWidth: 'auto', + maxHeight: 40, + '& p': { + ...typography.body2 + }, - '& span': { + '& p:last-child': { color: colors.invariant.text } }, From d78891e5b429456b775eec6fb52a32be3aaadfb6 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 25 Jul 2024 13:09:19 +0200 Subject: [PATCH 59/75] improve ui of select and add token modals --- .../Modals/AddTokenModal/AddTokenModal.tsx | 9 ++------ src/components/Modals/AddTokenModal/style.ts | 23 +++++++++++-------- src/components/Modals/SelectModals/style.ts | 9 ++++---- src/components/NewPosition/PoolInit/style.ts | 3 ++- .../NewPosition/RangeSelector/style.ts | 3 ++- src/components/PriceRangePlot/style.ts | 1 + 6 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/components/Modals/AddTokenModal/AddTokenModal.tsx b/src/components/Modals/AddTokenModal/AddTokenModal.tsx index a9f30d9f..9fa2915a 100644 --- a/src/components/Modals/AddTokenModal/AddTokenModal.tsx +++ b/src/components/Modals/AddTokenModal/AddTokenModal.tsx @@ -34,14 +34,9 @@ export const AddTokenModal: React.FC = ({ open, handleClose, addToken }) {'\u2715'} - + setAddress(e.target.value)} value={address} diff --git a/src/components/Modals/AddTokenModal/style.ts b/src/components/Modals/AddTokenModal/style.ts index a737168c..9cf3d706 100644 --- a/src/components/Modals/AddTokenModal/style.ts +++ b/src/components/Modals/AddTokenModal/style.ts @@ -7,10 +7,13 @@ const useStyles = makeStyles()((theme: Theme) => { root: { background: colors.invariant.component, width: 480, - height: 140, borderRadius: 24, padding: '20px 24px', - maxWidth: '100%' + maxWidth: '100%', + + [theme.breakpoints.down('sm')]: { + padding: '20px 16px ' + } }, popover: { marginTop: 'max(calc(50vh - 350px), 20px)', @@ -26,10 +29,12 @@ const useStyles = makeStyles()((theme: Theme) => { boxShadow: 'none' }, upperRow: { - height: 20 - }, - lowerRow: { - height: 60 + flexWrap: 'nowrap', + marginBottom: 20, + '& p': { + ...typography.heading4, + color: colors.white.main + } }, title: { ...typography.heading4, @@ -49,10 +54,9 @@ const useStyles = makeStyles()((theme: Theme) => { input: { backgroundColor: colors.invariant.newDark, width: '100%', - height: 60, color: colors.white.main, borderRadius: 20, - padding: '7px 10px 6px', + padding: '12px 10px', ...typography.heading4, fontWeight: 400, marginRight: 16, @@ -67,9 +71,8 @@ const useStyles = makeStyles()((theme: Theme) => { }, add: { minWidth: 82, - height: 60, background: colors.invariant.greenLinearGradient, - ...typography.heading3, + ...typography.heading4, color: colors.invariant.black, textTransform: 'none', borderRadius: 18, diff --git a/src/components/Modals/SelectModals/style.ts b/src/components/Modals/SelectModals/style.ts index 0c66607a..9dcd7b2b 100644 --- a/src/components/Modals/SelectModals/style.ts +++ b/src/components/Modals/SelectModals/style.ts @@ -21,7 +21,7 @@ const useStyles = makeStyles()((theme: Theme) => { width: 500, [theme.breakpoints.down('sm')]: { maxWidth: '100vw', - padding: '16px 8px ' + padding: '20px 16px' }, '& .MuiCheckbox-root.Mui-checked': { color: colors.green.button @@ -67,7 +67,7 @@ const useStyles = makeStyles()((theme: Theme) => { border: `1px solid ${colors.invariant.newDark}`, borderColor: colors.invariant.newDark, borderRadius: 15, - padding: '18px 10px 17px 10px', + padding: '13px 44px 13px 10px', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', @@ -86,7 +86,7 @@ const useStyles = makeStyles()((theme: Theme) => { width: 24, height: 26, right: '12px', - top: '18px' + top: '14px' }, commonTokensHeader: { ...typography.body2 @@ -355,7 +355,8 @@ const useStyles = makeStyles()((theme: Theme) => { }, addIcon: { marginLeft: 10, - cursor: 'pointer' + cursor: 'pointer', + fontSize: 28 } } }) diff --git a/src/components/NewPosition/PoolInit/style.ts b/src/components/NewPosition/PoolInit/style.ts index ef724cf0..fa81de74 100644 --- a/src/components/NewPosition/PoolInit/style.ts +++ b/src/components/NewPosition/PoolInit/style.ts @@ -26,7 +26,8 @@ const useStyles = makeStyles()(theme => { gap: 4 }, topInnerWrapper: { - minHeight: 300 + minHeight: 300, + maxWidth: '100%' }, bottomInnerWrapper: { display: 'flex', diff --git a/src/components/NewPosition/RangeSelector/style.ts b/src/components/NewPosition/RangeSelector/style.ts index e5842d9e..65b32e37 100644 --- a/src/components/NewPosition/RangeSelector/style.ts +++ b/src/components/NewPosition/RangeSelector/style.ts @@ -29,7 +29,8 @@ const useStyles = makeStyles()(theme => { gap: 16 }, topInnerWrapper: { - minHeight: 300 + minHeight: 300, + maxWidth: '100%' }, plot: { width: '100%', diff --git a/src/components/PriceRangePlot/style.ts b/src/components/PriceRangePlot/style.ts index 580e5313..845e0c7b 100644 --- a/src/components/PriceRangePlot/style.ts +++ b/src/components/PriceRangePlot/style.ts @@ -5,6 +5,7 @@ import { makeStyles } from 'tss-react/mui' export const useStyles = makeStyles()((theme: Theme) => ({ container: { height: '100%', + maxWidth: '100%', position: 'relative', '& g > text': { stroke: 'none', From 704093ef10735c6d60293e4764c7be2c46c2cbf1 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 25 Jul 2024 13:14:13 +0200 Subject: [PATCH 60/75] fix padding in input --- src/components/Modals/SelectModals/style.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Modals/SelectModals/style.ts b/src/components/Modals/SelectModals/style.ts index 9dcd7b2b..3be77a7b 100644 --- a/src/components/Modals/SelectModals/style.ts +++ b/src/components/Modals/SelectModals/style.ts @@ -67,7 +67,7 @@ const useStyles = makeStyles()((theme: Theme) => { border: `1px solid ${colors.invariant.newDark}`, borderColor: colors.invariant.newDark, borderRadius: 15, - padding: '13px 44px 13px 10px', + padding: '13px 44px 13px 10px !important', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', From e2dcc368b1929afdf1e4b492c8943b8e727e5f76 Mon Sep 17 00:00:00 2001 From: zielvna Date: Thu, 25 Jul 2024 13:38:36 +0200 Subject: [PATCH 61/75] prevent reloading when clicking show only your positions checkbox --- .../NewPositionWrapper/NewPositionWrapper.tsx | 41 ++++------- src/store/reducers/positions.ts | 19 +++-- src/store/sagas/positions.ts | 72 +++++++++---------- 3 files changed, 63 insertions(+), 69 deletions(-) diff --git a/src/containers/NewPositionWrapper/NewPositionWrapper.tsx b/src/containers/NewPositionWrapper/NewPositionWrapper.tsx index 193aca62..b396dfbb 100644 --- a/src/containers/NewPositionWrapper/NewPositionWrapper.tsx +++ b/src/containers/NewPositionWrapper/NewPositionWrapper.tsx @@ -69,7 +69,16 @@ export const NewPositionWrapper: React.FC = ({ const shouldNotUpdatePriceRange = useSelector(shouldNotUpdateRange) const { success, inProgress } = useSelector(initPosition) - const { data: ticksData, loading: ticksLoading, hasError: hasTicksError } = useSelector(plotTicks) + + const [onlyUserPositions, setOnlyUserPositions] = useState(false) + const { + allData, + userData, + loading: ticksLoading, + hasError: hasTicksError + } = useSelector(plotTicks) + const ticksData = onlyUserPositions ? userData : allData + const isFetchingNewPool = useSelector(isLoadingLatestPoolsForTransaction) const currentNetwork = useSelector(networkType) @@ -145,8 +154,7 @@ export const NewPositionWrapper: React.FC = ({ isXtoY: allPools[poolIndex].poolKey.tokenX === tokens[currentPairReversed === true ? tokenBIndex : tokenAIndex].assetAddress, - disableLoading: true, - onlyUserPositions + disableLoading: true }) ) } @@ -247,8 +255,7 @@ export const NewPositionWrapper: React.FC = ({ positionsActions.getCurrentPlotTicks({ poolKey: allPoolKeys[poolKey], isXtoY, - fetchTicksAndTickmap: true, - onlyUserPositions + fetchTicksAndTickmap: true }) ) } @@ -525,29 +532,13 @@ export const NewPositionWrapper: React.FC = ({ isXtoY: allPools[poolIndex].poolKey.tokenX === tokens[currentPairReversed === true ? tokenBIndex : tokenAIndex].assetAddress, - fetchTicksAndTickmap: true, - onlyUserPositions + fetchTicksAndTickmap: true }) ) } } } - const [onlyUserPositions, setOnlyUserPositions] = useState(false) - - useEffect(() => { - if (poolKey !== '') { - dispatch( - positionsActions.getCurrentPlotTicks({ - poolKey: allPoolKeys[poolKey], - isXtoY, - fetchTicksAndTickmap: true, - onlyUserPositions - }) - ) - } - }, [onlyUserPositions]) - return ( = ({ dispatch( positionsActions.getCurrentPlotTicks({ poolKey: allPoolKeys[poolKey], - isXtoY: allPoolKeys[poolKey].tokenX === tokens[tokenAIndex].assetAddress.toString(), - onlyUserPositions + isXtoY: allPoolKeys[poolKey].tokenX === tokens[tokenAIndex].assetAddress.toString() }) ) } else if ( @@ -668,8 +658,7 @@ export const NewPositionWrapper: React.FC = ({ poolKey: allPoolKeys[poolKey], isXtoY: allPools[poolIndex].poolKey.tokenX === - tokens[currentPairReversed === true ? tokenBIndex : tokenAIndex].assetAddress, - onlyUserPositions + tokens[currentPairReversed === true ? tokenBIndex : tokenAIndex].assetAddress }) ) } diff --git a/src/store/reducers/positions.ts b/src/store/reducers/positions.ts index 27e4e0d4..b9a0d581 100644 --- a/src/store/reducers/positions.ts +++ b/src/store/reducers/positions.ts @@ -19,7 +19,8 @@ export type TickPlotPositionData = Omit export type InitMidPrice = TickPlotPositionData & { sqrtPrice: bigint } export interface PlotTicks { - data: PlotTickData[] + allData: PlotTickData[] + userData: PlotTickData[] loading: boolean hasError?: boolean } @@ -58,7 +59,7 @@ export interface GetCurrentTicksData { isXtoY: boolean fetchTicksAndTickmap?: boolean disableLoading?: boolean - onlyUserPositions?: boolean + onlyUserPositionsEnabled?: boolean } export interface ClosePositionData { @@ -89,7 +90,8 @@ export interface HandleClaimFee { export const defaultState: IPositionsStore = { lastPage: 1, plotTicks: { - data: [], + allData: [], + userData: [], loading: false }, positionsList: { @@ -128,14 +130,19 @@ const positionsSlice = createSlice({ state.initPosition.success = action.payload return state }, - setPlotTicks(state, action: PayloadAction) { - state.plotTicks.data = action.payload + setPlotTicks( + state, + action: PayloadAction<{ allPlotTicks: PlotTickData[]; userPlotTicks: PlotTickData[] }> + ) { + state.plotTicks.allData = action.payload.allPlotTicks + state.plotTicks.userData = action.payload.userPlotTicks state.plotTicks.loading = false state.plotTicks.hasError = false return state }, setErrorPlotTicks(state, action: PayloadAction) { - state.plotTicks.data = action.payload + state.plotTicks.allData = action.payload + state.plotTicks.userData = action.payload state.plotTicks.loading = false state.plotTicks.hasError = true return state diff --git a/src/store/sagas/positions.ts b/src/store/sagas/positions.ts index 67bb1e4c..2628179a 100644 --- a/src/store/sagas/positions.ts +++ b/src/store/sagas/positions.ts @@ -1,4 +1,4 @@ -import { LiquidityTick, Pool, Position, sendTx, Invariant, PSP22 } from '@invariant-labs/a0-sdk' +import { Pool, Position, sendTx, Invariant, PSP22 } from '@invariant-labs/a0-sdk' import { Signer } from '@polkadot/api/types' import { PayloadAction } from '@reduxjs/toolkit' import { @@ -262,7 +262,7 @@ export function* handleGetCurrentPositionTicks(action: PayloadAction): Generator { - const { poolKey, isXtoY, fetchTicksAndTickmap, onlyUserPositions } = action.payload + const { poolKey, isXtoY, fetchTicksAndTickmap } = action.payload let allTickmaps = yield* select(tickMaps) const allTokens = yield* select(tokens) const allPools = yield* select(poolsArraySortedByFees) @@ -297,45 +297,43 @@ export function* handleGetCurrentPlotTicks(action: PayloadAction Date: Thu, 25 Jul 2024 13:45:19 +0200 Subject: [PATCH 62/75] fix single position page --- .../SinglePositionWrapper/SinglePositionWrapper.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/containers/SinglePositionWrapper/SinglePositionWrapper.tsx b/src/containers/SinglePositionWrapper/SinglePositionWrapper.tsx index 292b1b55..0c1d44eb 100644 --- a/src/containers/SinglePositionWrapper/SinglePositionWrapper.tsx +++ b/src/containers/SinglePositionWrapper/SinglePositionWrapper.tsx @@ -48,7 +48,11 @@ export const SinglePositionWrapper: React.FC = ({ id }) => { const currentNetwork = useSelector(networkType) const position = useSelector(singlePositionData(id)) const isLoadingList = useSelector(isLoadingPositionsList) - const { data: ticksData, loading: ticksLoading, hasError: hasTicksError } = useSelector(plotTicks) + const { + allData: ticksData, + loading: ticksLoading, + hasError: hasTicksError + } = useSelector(plotTicks) const allTickMaps = useSelector(tickMaps) const { lowerTick, From 456b3dade32651aff7b830c8badac4294d48c686 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 25 Jul 2024 13:57:56 +0200 Subject: [PATCH 63/75] improve swap layout --- src/components/Swap/Swap.tsx | 11 ++++++++--- src/components/Swap/style.ts | 10 +++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/components/Swap/Swap.tsx b/src/components/Swap/Swap.tsx index c1bba0bd..1c18ef52 100644 --- a/src/components/Swap/Swap.tsx +++ b/src/components/Swap/Swap.tsx @@ -646,7 +646,6 @@ export const Swap: React.FC = ({ {detailsOpen && canShowDetails ? 'Hide' : 'Show'} transaction details - @@ -654,13 +653,19 @@ export const Swap: React.FC = ({ {tokenFromIndex !== null && tokenToIndex !== null && tokenFromIndex !== tokenToIndex && ( - + - + )} {canShowDetails ? ( diff --git a/src/components/Swap/style.ts b/src/components/Swap/style.ts index 46aac706..acbc8c13 100644 --- a/src/components/Swap/style.ts +++ b/src/components/Swap/style.ts @@ -19,6 +19,8 @@ export const useStyles = makeStyles()((theme: Theme) => ({ width: 500, position: 'relative', paddingBottom: 9, + rowGap: 8, + '& h1': { ...typography.heading4, color: colors.white.main @@ -205,7 +207,7 @@ export const useStyles = makeStyles()((theme: Theme) => ({ paddingInline: 15, borderRadius: '10px', alignItems: 'center', - height: 32 + height: 34 }, transactionDetailsHeader: { @@ -230,6 +232,12 @@ export const useStyles = makeStyles()((theme: Theme) => ({ flexDirection: 'row-reverse', columnGap: 8, marginLeft: 0 + }, + + '& svg ': { + height: 32 + '!important', + width: 20, + minWidth: '100%' } }, swapButton: { From a0e6f71fc41fb34ae4c156bc58d7c4f587c5f74e Mon Sep 17 00:00:00 2001 From: zielvna Date: Thu, 25 Jul 2024 14:13:33 +0200 Subject: [PATCH 64/75] change details button size --- src/components/Snackbar/CustomSnackbar/style.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Snackbar/CustomSnackbar/style.ts b/src/components/Snackbar/CustomSnackbar/style.ts index 45f0d418..5d71b594 100644 --- a/src/components/Snackbar/CustomSnackbar/style.ts +++ b/src/components/Snackbar/CustomSnackbar/style.ts @@ -137,7 +137,6 @@ export const StyledDetails = styled('button')({ [theme.breakpoints.down('sm')]: { width: 36, height: 16, - fontSize: 9, lineHeight: '14px', marginTop: 2, marginRight: 8, From 85de5d515e13809e8fbd1195fdb35fb164fbd9a9 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 25 Jul 2024 14:24:41 +0200 Subject: [PATCH 65/75] fix build --- src/components/Swap/Swap.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/Swap/Swap.tsx b/src/components/Swap/Swap.tsx index 1c18ef52..e6d97f04 100644 --- a/src/components/Swap/Swap.tsx +++ b/src/components/Swap/Swap.tsx @@ -5,8 +5,7 @@ import Slippage from '@components/Modals/Slippage/Slippage' import Refresher from '@components/Refresher/Refresher' import { PoolKey, Price } from '@invariant-labs/a0-sdk' import { PERCENTAGE_DENOMINATOR } from '@invariant-labs/a0-sdk/target/consts' -import { Box, Button, CardMedia, Grid, Typography } from '@mui/material' -import infoIcon from '@static/svg/info.svg' +import { Box, Button, Grid, Typography } from '@mui/material' import refreshIcon from '@static/svg/refresh.svg' import settingIcon from '@static/svg/settings.svg' import SwapArrows from '@static/svg/swap-arrows.svg' From 6a83d3a55512a08bfc143aff9ccd6476bc30493b Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Thu, 25 Jul 2024 14:59:56 +0200 Subject: [PATCH 66/75] change color of checkbox --- src/components/Modals/SelectModals/style.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/Modals/SelectModals/style.ts b/src/components/Modals/SelectModals/style.ts index e652ce9f..13557167 100644 --- a/src/components/Modals/SelectModals/style.ts +++ b/src/components/Modals/SelectModals/style.ts @@ -22,6 +22,12 @@ const useStyles = makeStyles()((theme: Theme) => { [theme.breakpoints.down('sm')]: { maxWidth: '100vw' }, + '.MuiFormControlLabel-label': { + color: colors.invariant.lightGrey + }, + '& .MuiCheckbox-root': { + color: colors.invariant.lightGrey + }, '& .MuiCheckbox-root.Mui-checked': { color: colors.green.button } From 007c2a78b53b3c0f6e4c69d7147bde50ad2c95da Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Fri, 26 Jul 2024 11:58:09 +0200 Subject: [PATCH 67/75] fix transparent background of buttons on mobile --- .../NewPosition/RangeSelector/RangeSelector.tsx | 2 +- src/components/NewPosition/RangeSelector/style.ts | 9 +++++++-- src/index.css | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/NewPosition/RangeSelector/RangeSelector.tsx b/src/components/NewPosition/RangeSelector/RangeSelector.tsx index 4f70c9c0..4408eeff 100644 --- a/src/components/NewPosition/RangeSelector/RangeSelector.tsx +++ b/src/components/NewPosition/RangeSelector/RangeSelector.tsx @@ -603,7 +603,7 @@ export const RangeSelector: React.FC = ({ /> ) : ( - + diff --git a/src/components/NewPosition/RangeSelector/style.ts b/src/components/NewPosition/RangeSelector/style.ts index a88f5cd8..fede9c03 100644 --- a/src/components/NewPosition/RangeSelector/style.ts +++ b/src/components/NewPosition/RangeSelector/style.ts @@ -66,10 +66,15 @@ const useStyles = makeStyles()(theme => { backgroundColor: colors.invariant.light, borderRadius: 11, + '&:hover': { + '@media (hover: none)': { + backgroundColor: colors.invariant.light + } + }, + [theme.breakpoints.down('md')]: { '&:first-of-type': { - marginRight: 0, - marginBottom: 8 + marginRight: 0 } } }, diff --git a/src/index.css b/src/index.css index e036f1e3..33de614e 100644 --- a/src/index.css +++ b/src/index.css @@ -1,6 +1,7 @@ * { min-width: 0; min-height: 0; + -webkit-tap-highlight-color: transparent; } body { margin: 0; From 696b9a5a41b1b8931c1b277eb6d5b4dcfd4a5742 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Fri, 26 Jul 2024 12:22:44 +0200 Subject: [PATCH 68/75] fix blured background after back button when modal is opened --- src/components/Inputs/Select/Select.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/Inputs/Select/Select.tsx b/src/components/Inputs/Select/Select.tsx index 21cbf1e1..46295133 100644 --- a/src/components/Inputs/Select/Select.tsx +++ b/src/components/Inputs/Select/Select.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect } from 'react' import icons from '@static/icons' import classNames from 'classnames' import useStyles from './style' @@ -7,6 +7,7 @@ import { Button } from '@mui/material' import ExpandMoreIcon from '@mui/icons-material/ExpandMore' import SelectTokenModal from '@components/Modals/SelectModals/SelectTokenModal/SelectTokenModal' import { SwapToken } from '@store/selectors/wallet' +import { useLocation, useNavigate } from 'react-router-dom' export interface ISelectModal { name?: string @@ -52,6 +53,12 @@ export const Select: React.FC = ({ setOpen(false) } + useEffect(() => { + return () => { + unblurContent() + } + }, []) + const displayName = !current ? name : current.symbol return ( @@ -97,4 +104,5 @@ export const Select: React.FC = ({ ) } + export default Select From da7531a7944dde0492864b9b00ac10d8f799d046 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Fri, 26 Jul 2024 12:26:32 +0200 Subject: [PATCH 69/75] fix buttons on init pool --- src/components/NewPosition/PoolInit/style.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/NewPosition/PoolInit/style.ts b/src/components/NewPosition/PoolInit/style.ts index 23daefbd..514ba843 100644 --- a/src/components/NewPosition/PoolInit/style.ts +++ b/src/components/NewPosition/PoolInit/style.ts @@ -64,10 +64,15 @@ const useStyles = makeStyles()(theme => { backgroundColor: colors.invariant.light, borderRadius: 11, + '&:hover': { + '@media (hover: none)': { + backgroundColor: colors.invariant.light + } + }, + [theme.breakpoints.down('md')]: { '&:first-of-type': { - marginRight: 0, - marginBottom: 8 + marginRight: 0 } } }, From d774fc054b35dbd0f316abb3a68c1b634e882f35 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Fri, 26 Jul 2024 12:28:29 +0200 Subject: [PATCH 70/75] fix build --- src/components/Inputs/Select/Select.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Inputs/Select/Select.tsx b/src/components/Inputs/Select/Select.tsx index 46295133..9bcb00a7 100644 --- a/src/components/Inputs/Select/Select.tsx +++ b/src/components/Inputs/Select/Select.tsx @@ -7,7 +7,6 @@ import { Button } from '@mui/material' import ExpandMoreIcon from '@mui/icons-material/ExpandMore' import SelectTokenModal from '@components/Modals/SelectModals/SelectTokenModal/SelectTokenModal' import { SwapToken } from '@store/selectors/wallet' -import { useLocation, useNavigate } from 'react-router-dom' export interface ISelectModal { name?: string From 393fcd85fea3f0afecd8e905b085db7c9f99a748 Mon Sep 17 00:00:00 2001 From: zielvna Date: Fri, 26 Jul 2024 12:58:43 +0200 Subject: [PATCH 71/75] refactor header --- src/components/Header/Header.tsx | 70 ++++++++++++----- .../Header/HeaderButton/SelectChainButton.tsx | 61 +++++++++++++++ src/components/Header/style.ts | 16 +++- src/components/Modals/RoutesModal/index.tsx | 9 ++- .../Modals/SelectChain/SelectChain.tsx | 64 +++++++++++++++ src/components/Modals/SelectChain/style.ts | 78 +++++++++++++++++++ .../HeaderWrapper/HeaderWrapper.tsx | 11 ++- src/store/consts/static.ts | 14 +++- src/store/consts/types.ts | 10 +++ 9 files changed, 306 insertions(+), 27 deletions(-) create mode 100644 src/components/Header/HeaderButton/SelectChainButton.tsx create mode 100644 src/components/Modals/SelectChain/SelectChain.tsx create mode 100644 src/components/Modals/SelectChain/style.ts diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index aaebb0b0..29038827 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -6,7 +6,7 @@ import { Box, Button, CardMedia, Grid, IconButton, useMediaQuery } from '@mui/ma import icons from '@static/icons' import Hamburger from '@static/svg/Hamburger.svg' import { theme } from '@static/theme' -import { AlephZeroNetworks } from '@store/consts/static' +import { AlephZeroNetworks, CHAINS } from '@store/consts/static' import { blurContent, unblurContent } from '@utils/uiUtils' import { useEffect, useState } from 'react' import { Link, useNavigate } from 'react-router-dom' @@ -16,6 +16,9 @@ import SelectRPCButton from './HeaderButton/SelectRPCButton' import useButtonStyles from './HeaderButton/style' import useStyles from './style' import { Network } from '@invariant-labs/a0-sdk' +import SelectChainButton from './HeaderButton/SelectChainButton' +import { ISelectChain } from '@store/consts/types' +import SelectChain from '@components/Modals/SelectChain/SelectChain' export interface IHeader { address: string @@ -30,6 +33,8 @@ export interface IHeader { defaultTestnetRPC: string onCopyAddress: () => void onChangeWallet: () => void + activeChain: ISelectChain + onChainSelect: (chain: ISelectChain) => void } export const Header: React.FC = ({ @@ -44,13 +49,15 @@ export const Header: React.FC = ({ onDisconnectWallet, defaultTestnetRPC, onCopyAddress, - onChangeWallet + onChangeWallet, + activeChain, + onChainSelect }) => { const { classes } = useStyles() const buttonStyles = useButtonStyles() const navigate = useNavigate() - const isXsDown = useMediaQuery(theme.breakpoints.down('sm')) + const isMdDown = useMediaQuery(theme.breakpoints.down('md')) const routes = ['swap', 'pool', 'stats'] @@ -63,6 +70,7 @@ export const Header: React.FC = ({ const [routesModalOpen, setRoutesModalOpen] = useState(false) const [testnetRpcsOpen, setTestnetRpcsOpen] = useState(false) + const [chainSelectOpen, setChainSelectOpen] = useState(false) const [routesModalAnchor, setRoutesModalAnchor] = useState(null) useEffect(() => { @@ -86,17 +94,15 @@ export const Header: React.FC = ({ className={classes.leftSide} justifyContent='flex-start' sx={{ display: { xs: 'none', md: 'block' } }}> - - { - if (!activePath.startsWith('swap')) { - navigate('/swap') - } - }} - /> - + { + if (!activePath.startsWith('swap')) { + navigate('/swap') + } + }} + /> = ({ item className={classes.routers} wrap='nowrap' - sx={{ display: { xs: 'none', md: 'block' } }}> + sx={{ display: { xs: 'none', lg: 'block' } }}> {routes.map(path => ( = ({ {typeOfNetwork === Network.Testnet ? ( - + + { + onSelect(chain) + handleClose() + }} + handleClose={handleClose} + activeChain={activeChain} + /> + + ) +} +export default SelectChainButton diff --git a/src/components/Header/style.ts b/src/components/Header/style.ts index ca5564ae..fce70d95 100644 --- a/src/components/Header/style.ts +++ b/src/components/Header/style.ts @@ -9,6 +9,8 @@ const useStyles = makeStyles()((theme: Theme) => { maxWidth: 1920, paddingInline: 150, height: 70, + display: 'flex', + justifyContent: 'space-between', [theme.breakpoints.down('xl')]: { paddingInline: 32 @@ -23,7 +25,7 @@ const useStyles = makeStyles()((theme: Theme) => { } }, logo: { - minWidth: 150, + width: 150, height: 40, '&:hover': { @@ -56,8 +58,8 @@ const useStyles = makeStyles()((theme: Theme) => { } }, buttons: { + width: 'auto', justifyContent: 'flex-end', - flex: '1 1 0%', gap: 12, [theme.breakpoints.up('lg')]: { @@ -75,6 +77,10 @@ const useStyles = makeStyles()((theme: Theme) => { [theme.breakpoints.down('sm')]: { gap: 4 + }, + + [theme.breakpoints.up('xl')]: { + flex: '1 1 0%' } }, buttonsLgConnected: { @@ -106,7 +112,11 @@ const useStyles = makeStyles()((theme: Theme) => { } }, leftSide: { - flex: '1 1 0%' + width: 'auto', + + [theme.breakpoints.up('xl')]: { + flex: '1 1 0%' + } } } }) diff --git a/src/components/Modals/RoutesModal/index.tsx b/src/components/Modals/RoutesModal/index.tsx index d60797d2..6aaf196a 100644 --- a/src/components/Modals/RoutesModal/index.tsx +++ b/src/components/Modals/RoutesModal/index.tsx @@ -12,6 +12,7 @@ export interface IRoutesModal { current?: string onFaucet?: () => void onRPC?: () => void + onChainSelect?: () => void } export const RoutesModal: React.FC = ({ routes, @@ -21,7 +22,8 @@ export const RoutesModal: React.FC = ({ onSelect, current, onFaucet, - onRPC + onRPC, + onChainSelect }) => { const { classes } = useStyles() @@ -84,6 +86,11 @@ export const RoutesModal: React.FC = ({ Set RPC ) : null} + {typeof onChainSelect !== 'undefined' ? ( + + Change chain + + ) : null} ) diff --git a/src/components/Modals/SelectChain/SelectChain.tsx b/src/components/Modals/SelectChain/SelectChain.tsx new file mode 100644 index 00000000..af07b6bb --- /dev/null +++ b/src/components/Modals/SelectChain/SelectChain.tsx @@ -0,0 +1,64 @@ +import React from 'react' +import icons from '@static/icons' +import classNames from 'classnames' +import useStyles from './style' +import { Grid, Popover, Typography } from '@mui/material' +import DotIcon from '@mui/icons-material/FiberManualRecordRounded' +import { ISelectChain } from '@store/consts/types' + +export interface ISelectChainModal { + chains: ISelectChain[] + open: boolean + anchorEl: HTMLButtonElement | null + onSelect: (chain: ISelectChain) => void + handleClose: () => void + activeChain: ISelectChain +} +export const SelectChain: React.FC = ({ + chains, + anchorEl, + open, + onSelect, + handleClose, + activeChain +}) => { + const { classes } = useStyles() + return ( + + + Select a chain + + {chains.map(chain => ( + { + onSelect(chain) + }}> + {`${chain} + {chain.name} + + + ))} + + + + ) +} +export default SelectChain diff --git a/src/components/Modals/SelectChain/style.ts b/src/components/Modals/SelectChain/style.ts new file mode 100644 index 00000000..50fa31a4 --- /dev/null +++ b/src/components/Modals/SelectChain/style.ts @@ -0,0 +1,78 @@ +import { colors, typography } from '@static/theme' +import { makeStyles } from 'tss-react/mui' + +const useStyles = makeStyles()(() => { + return { + root: { + background: colors.invariant.component, + width: 170, + borderRadius: 20, + marginTop: 8, + padding: 8 + }, + list: { + borderRadius: 5, + marginTop: 7 + }, + listItem: { + color: colors.invariant.textGrey, + background: colors.invariant.component, + borderRadius: 11, + padding: '6px 7px', + width: '100%', + cursor: 'pointer', + display: 'flex', + alignItems: 'center', + '&:hover': { + background: colors.invariant.light, + color: colors.white.main + }, + '&:first-of-type': { + marginBottom: '4px' + }, + '&:not(:first-of-type)': { + margin: '4px 0' + }, + '&:last-child': { + marginTop: '4px' + } + }, + title: { + ...typography.body1, + margin: 10 + }, + dotIcon: { + width: 12, + marginLeft: 'auto', + color: colors.invariant.green, + display: 'none' + }, + name: { + textTransform: 'capitalize', + ...typography.body2, + paddingTop: '1px' + }, + paper: { + background: 'transparent', + boxShadow: 'none' + }, + icon: { + float: 'left', + marginRight: 8, + opacity: 1 + }, + active: { + background: colors.invariant.light, + color: colors.white.main, + '& $icon': { + opacity: 1 + }, + + '& $dotIcon': { + display: 'block' + } + } + } +}) + +export default useStyles diff --git a/src/containers/HeaderWrapper/HeaderWrapper.tsx b/src/containers/HeaderWrapper/HeaderWrapper.tsx index 7b1648e7..fa1f08d5 100644 --- a/src/containers/HeaderWrapper/HeaderWrapper.tsx +++ b/src/containers/HeaderWrapper/HeaderWrapper.tsx @@ -1,6 +1,6 @@ import Header from '@components/Header/Header' import { Network } from '@invariant-labs/a0-sdk' -import { AlephZeroNetworks } from '@store/consts/static' +import { AlephZeroNetworks, CHAINS } from '@store/consts/static' import { actions } from '@store/reducers/connection' import { Status, actions as walletActions } from '@store/reducers/wallet' import { networkType, rpcAddress } from '@store/selectors/connection' @@ -11,6 +11,7 @@ import React, { useEffect, useMemo } from 'react' import { useDispatch, useSelector } from 'react-redux' import { useLocation } from 'react-router-dom' import { actions as snackbarsActions } from '@store/reducers/snackbars' +import { Chain } from '@store/consts/types' export const HeaderWrapper: React.FC = () => { const dispatch = useDispatch() @@ -45,6 +46,8 @@ export const HeaderWrapper: React.FC = () => { return lastRPC === null ? AlephZeroNetworks.TEST : lastRPC }, []) + const activeChain = CHAINS.find(chain => chain.name === Chain.AlephZero) ?? CHAINS[0] + return (
{ onChangeWallet={() => { dispatch(walletActions.reconnect()) }} + activeChain={activeChain} + onChainSelect={chain => { + if (chain.name !== activeChain.name) { + window.location.replace(chain.address) + } + }} /> ) } diff --git a/src/store/consts/static.ts b/src/store/consts/static.ts index 3a0166f4..190c318a 100644 --- a/src/store/consts/static.ts +++ b/src/store/consts/static.ts @@ -8,7 +8,14 @@ import { TESTNET_WAZERO_ADDRESS } from '@invariant-labs/a0-sdk' import { Keyring } from '@polkadot/api' -import { BestTier, FormatNumberThreshold, PrefixConfig, Token, TokenPriceData } from './types' +import { + BestTier, + Chain, + FormatNumberThreshold, + PrefixConfig, + Token, + TokenPriceData +} from './types' import { testnetBestTiersCreator } from '@utils/utils' import { POSITIONS_ENTRIES_LIMIT } from '@invariant-labs/a0-sdk/target/consts' @@ -281,3 +288,8 @@ export const MINIMAL_POOL_INIT_PRICE = 0.00000001 export const DEFAULT_SWAP_SLIPPAGE = '0.50' export const DEFAULT_NEW_POSITION_SLIPPAGE = '0.50' + +export const CHAINS = [ + { name: Chain.Solana, address: 'https://invariant.app/swap' }, + { name: Chain.AlephZero, address: 'https://azero.invariant.app/swap' } +] diff --git a/src/store/consts/types.ts b/src/store/consts/types.ts index ef1f56bc..f7f5733c 100644 --- a/src/store/consts/types.ts +++ b/src/store/consts/types.ts @@ -67,3 +67,13 @@ export interface BestTier { tokenY: string bestTierIndex: number } + +export interface ISelectChain { + name: Chain + address: string +} + +export enum Chain { + Solana = 'Solana', + AlephZero = 'Aleph Zero' +} From c6c7b1e772966ec44136e70ffa03637a053a6e10 Mon Sep 17 00:00:00 2001 From: zielvna Date: Fri, 26 Jul 2024 13:03:26 +0200 Subject: [PATCH 72/75] fix header story --- src/components/Header/Header.stories.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/Header/Header.stories.tsx b/src/components/Header/Header.stories.tsx index 6447350a..110788b6 100644 --- a/src/components/Header/Header.stories.tsx +++ b/src/components/Header/Header.stories.tsx @@ -3,6 +3,7 @@ import { fn } from '@storybook/test' import Header from './Header' import { MemoryRouter } from 'react-router-dom' import { Network } from '@invariant-labs/a0-sdk' +import { Chain } from '@store/consts/types' const meta = { title: 'Layout/Header', @@ -33,6 +34,11 @@ export const Primary: Story = { walletConnected: true, onFaucet: fn(), onCopyAddress: fn(), - onChangeWallet: fn() + onChangeWallet: fn(), + activeChain: { + name: Chain.AlephZero, + address: 'https://azero.invariant.app/swap' + }, + onChainSelect: fn() } } From ad95c20b23a487d689148ecfa07ddb12169b18b2 Mon Sep 17 00:00:00 2001 From: zielvna Date: Fri, 26 Jul 2024 15:53:09 +0200 Subject: [PATCH 73/75] fix header layout --- src/components/Header/Header.tsx | 9 ++------- src/components/Header/style.ts | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 29038827..5338711e 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -104,13 +104,8 @@ export const Header: React.FC = ({ }} /> - - + + { gap: 4 }, - [theme.breakpoints.up('xl')]: { - flex: '1 1 0%' + [theme.breakpoints.up(1600)]: { + width: 600 } }, buttonsLgConnected: { @@ -98,6 +98,9 @@ const useStyles = makeStyles()((theme: Theme) => { transition: 'filter 300ms' }, menuButton: { + width: 142, + display: 'flex', + justifyContent: 'flex-end', borderRadius: 10, paddingInline: 6, paddingBlock: 1, @@ -109,13 +112,21 @@ const useStyles = makeStyles()((theme: Theme) => { }, '&:hover $menu': { filter: 'brightness(2)' + }, + + [theme.breakpoints.down('md')]: { + width: 40 } }, leftSide: { width: 'auto', - [theme.breakpoints.up('xl')]: { + [theme.breakpoints.up(1600)]: { flex: '1 1 0%' + }, + + [theme.breakpoints.up(1600)]: { + width: 600 } } } From b294063dd8e872811efa4cabf06b6677b9feca56 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Fri, 26 Jul 2024 15:58:49 +0200 Subject: [PATCH 74/75] refactor refresher position --- src/components/Swap/ExchangeRate/style.ts | 7 +-- src/components/Swap/Swap.tsx | 65 ++++++++++++----------- src/components/Swap/style.ts | 38 +++++++------ 3 files changed, 59 insertions(+), 51 deletions(-) diff --git a/src/components/Swap/ExchangeRate/style.ts b/src/components/Swap/ExchangeRate/style.ts index 26927ce1..d7a0d638 100644 --- a/src/components/Swap/ExchangeRate/style.ts +++ b/src/components/Swap/ExchangeRate/style.ts @@ -1,4 +1,4 @@ -import { colors, typography } from '@static/theme' +import { colors, theme, typography } from '@static/theme' import { makeStyles } from 'tss-react/mui' export const useStyles = makeStyles()(() => ({ @@ -33,8 +33,9 @@ export const useStyles = makeStyles()(() => ({ '&:hover': { borderColor: colors.invariant.lightHover }, - '@media (max-width: 400px)': { - width: '100%' + [theme.breakpoints.down('sm')]: { + width: '100%', + flex: 1 } } })) diff --git a/src/components/Swap/Swap.tsx b/src/components/Swap/Swap.tsx index e6d97f04..609ffc1e 100644 --- a/src/components/Swap/Swap.tsx +++ b/src/components/Swap/Swap.tsx @@ -623,32 +623,33 @@ export const Swap: React.FC = ({ /> - - + + {tokenFromIndex !== null && tokenToIndex !== null && tokenFromIndex !== tokenToIndex && ( @@ -658,7 +659,8 @@ export const Swap: React.FC = ({ justifyContent='center' width={20} height={34} - minWidth='fit-content'> + minWidth='fit-content' + ml={1}> = ({ /> )} - - {canShowDetails ? ( + + {canShowDetails ? ( + setRateReversed(!rateReversed)} tokenFromSymbol={tokens[rateReversed ? tokenToIndex : tokenFromIndex].symbol} @@ -678,8 +681,8 @@ export const Swap: React.FC = ({ )} loading={getStateMessage() === 'Loading'} /> - ) : null} - + + ) : null} ({ transactionDetails: { display: 'flex', alignItems: 'center', - justifyContent: 'flex-start', + justifyContent: 'space-between', flexFlow: 'row', flexWrap: 'wrap', marginTop: 24, marginBottom: 12, - position: 'relative', cursor: 'default', filter: 'brightness(0.9)', width: '100%', - '@media (max-width: 400px)': { + [theme.breakpoints.down('sm')]: { flexDirection: 'column-reverse', gap: 4 } }, + transactionDetailsInner: { + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-start', + [theme.breakpoints.down('sm')]: { + width: '100%' + } + }, + transactionDetailsButton: { + [theme.breakpoints.down('sm')]: { + flexGrow: 1 + } + }, transactionDetailsWrapper: { display: 'flex', flexDirection: 'row', + justifyContent: 'center', backgroundColor: colors.invariant.light, paddingInline: 15, borderRadius: '10px', @@ -214,24 +227,15 @@ export const useStyles = makeStyles()((theme: Theme) => ({ ...typography.caption2, whiteSpace: 'nowrap', pointerEvents: 'none', - color: colors.invariant.lightGrey, - - '@media (max-width: 400px)': { - flex: 1 - } + color: colors.invariant.lightGrey }, - revertWrapper: { + + exchangeRateWrapper: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', - marginLeft: 8, - flex: 1, - '@media (max-width: 400px)': { - width: '100%', - flex: 'auto', - flexDirection: 'row-reverse', - columnGap: 8, - marginLeft: 0 + [theme.breakpoints.down('sm')]: { + width: '100%' }, '& svg ': { From 0809b669aed895a77279b4eefb93b6df8dd95a94 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Fri, 26 Jul 2024 16:05:43 +0200 Subject: [PATCH 75/75] change position of label --- src/components/Modals/SelectModals/style.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Modals/SelectModals/style.ts b/src/components/Modals/SelectModals/style.ts index 13557167..9b636146 100644 --- a/src/components/Modals/SelectModals/style.ts +++ b/src/components/Modals/SelectModals/style.ts @@ -23,7 +23,8 @@ const useStyles = makeStyles()((theme: Theme) => { maxWidth: '100vw' }, '.MuiFormControlLabel-label': { - color: colors.invariant.lightGrey + color: colors.invariant.lightGrey, + transform: 'translateY(1.5px)' }, '& .MuiCheckbox-root': { color: colors.invariant.lightGrey