From 38dec50c9f1aba262e2a07ae99b300e07b74d051 Mon Sep 17 00:00:00 2001 From: abtestingalpha Date: Thu, 29 Aug 2024 13:04:25 -0400 Subject: [PATCH 01/12] bridge quote history middleware --- .../slices/bridgeQuote/reducer.ts | 8 +++++- .../bridgeQuoteHistoryMiddleware.ts | 25 +++++++++++++++++++ .../destinationAddressMiddleware.ts | 0 packages/synapse-interface/store/store.ts | 9 +++++-- 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 packages/synapse-interface/store/middleware/bridgeQuoteHistoryMiddleware.ts rename packages/synapse-interface/store/{ => middleware}/destinationAddressMiddleware.ts (100%) diff --git a/packages/synapse-interface/slices/bridgeQuote/reducer.ts b/packages/synapse-interface/slices/bridgeQuote/reducer.ts index 8407876035..898769f622 100644 --- a/packages/synapse-interface/slices/bridgeQuote/reducer.ts +++ b/packages/synapse-interface/slices/bridgeQuote/reducer.ts @@ -6,11 +6,13 @@ import { fetchBridgeQuote } from './thunks' export interface BridgeQuoteState { bridgeQuote: BridgeQuote + previousBridgeQuote: BridgeQuote | null isLoading: boolean } export const initialState: BridgeQuoteState = { bridgeQuote: EMPTY_BRIDGE_QUOTE, + previousBridgeQuote: null, isLoading: false, } @@ -24,6 +26,9 @@ export const bridgeQuoteSlice = createSlice({ resetBridgeQuote: (state) => { state.bridgeQuote = initialState.bridgeQuote }, + setPreviousBridgeQuote: (state, action: PayloadAction) => { + state.previousBridgeQuote = action.payload + }, }, extraReducers: (builder) => { builder @@ -44,6 +49,7 @@ export const bridgeQuoteSlice = createSlice({ }, }) -export const { resetBridgeQuote, setIsLoading } = bridgeQuoteSlice.actions +export const { resetBridgeQuote, setIsLoading, setPreviousBridgeQuote } = + bridgeQuoteSlice.actions export default bridgeQuoteSlice.reducer diff --git a/packages/synapse-interface/store/middleware/bridgeQuoteHistoryMiddleware.ts b/packages/synapse-interface/store/middleware/bridgeQuoteHistoryMiddleware.ts new file mode 100644 index 0000000000..f58c09ae03 --- /dev/null +++ b/packages/synapse-interface/store/middleware/bridgeQuoteHistoryMiddleware.ts @@ -0,0 +1,25 @@ +import { + Middleware, + MiddlewareAPI, + Dispatch, + AnyAction, +} from '@reduxjs/toolkit' + +export const bridgeQuoteHistoryMiddleware: Middleware = + (store: MiddlewareAPI) => (next: Dispatch) => (action: AnyAction) => { + const previousState = store.getState() + const result = next(action) + const currentState = store.getState() + + if ( + previousState.bridgeQuote.bridgeQuote !== + currentState.bridgeQuote.bridgeQuote + ) { + store.dispatch({ + type: 'bridgeQuote/setPreviousBridgeQuote', + payload: previousState.bridgeQuote.bridgeQuote, + }) + } + + return result + } diff --git a/packages/synapse-interface/store/destinationAddressMiddleware.ts b/packages/synapse-interface/store/middleware/destinationAddressMiddleware.ts similarity index 100% rename from packages/synapse-interface/store/destinationAddressMiddleware.ts rename to packages/synapse-interface/store/middleware/destinationAddressMiddleware.ts diff --git a/packages/synapse-interface/store/store.ts b/packages/synapse-interface/store/store.ts index 70f5515a6f..d8cdf3e70a 100644 --- a/packages/synapse-interface/store/store.ts +++ b/packages/synapse-interface/store/store.ts @@ -6,7 +6,8 @@ import { api } from '@/slices/api/slice' import { segmentAnalyticsEvent } from '@/contexts/SegmentAnalyticsProvider' import { storageKey, persistConfig, persistedReducer } from './reducer' import { resetReduxCache } from '@/slices/application/actions' -import { destinationAddressMiddleware } from '@/store/destinationAddressMiddleware' +import { destinationAddressMiddleware } from '@/store/middleware/destinationAddressMiddleware' +import { bridgeQuoteHistoryMiddleware } from './middleware/bridgeQuoteHistoryMiddleware' const checkVersionAndResetCache = (): boolean => { if (typeof window !== 'undefined') { @@ -28,7 +29,11 @@ export const store = configureStore({ middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false, - }).concat(api.middleware, destinationAddressMiddleware), + }).concat( + api.middleware, + destinationAddressMiddleware, + bridgeQuoteHistoryMiddleware + ), }) if (checkVersionAndResetCache()) { From f44b62c7f80a4fe01693831f50d22d349653ed20 Mon Sep 17 00:00:00 2001 From: bigboydiamonds <57741810+bigboydiamonds@users.noreply.github.com> Date: Fri, 30 Aug 2024 11:04:06 -0700 Subject: [PATCH 02/12] skip resetting quote at beginning of fetch --- packages/synapse-interface/pages/state-managed-bridge/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/synapse-interface/pages/state-managed-bridge/index.tsx b/packages/synapse-interface/pages/state-managed-bridge/index.tsx index 63b7b71e42..997b02b38a 100644 --- a/packages/synapse-interface/pages/state-managed-bridge/index.tsx +++ b/packages/synapse-interface/pages/state-managed-bridge/index.tsx @@ -134,8 +134,6 @@ const StateManagedBridge = () => { // will have to handle deadlineMinutes here at later time, gets passed as optional last arg in .bridgeQuote() - /* clear stored bridge quote before requesting new bridge quote */ - dispatch(resetBridgeQuote()) const currentTimestamp: number = getTimeMinutesFromNow(0) try { From 3e388696d3277b3e698fe677f6ed8a6efaf3d941 Mon Sep 17 00:00:00 2001 From: bigboydiamonds <57741810+bigboydiamonds@users.noreply.github.com> Date: Fri, 30 Aug 2024 12:15:04 -0700 Subject: [PATCH 03/12] bridge button requests user to confirm new bridge price when detected --- .vscode/settings.json | 2 +- .../BridgeTransactionButton.tsx | 17 ++++- .../hooks/useBridgeValidations.ts | 2 +- .../hooks/useConfirmNewBridgePrice.ts | 62 +++++++++++++++++++ 4 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index ed3d2aeafe..ecf06d181a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -22,4 +22,4 @@ "solidity.compileUsingRemoteVersion": "v0.8.17+commit.8df45f5f", "solidity.formatter": "prettier", "solidity.defaultCompiler": "remote" -} +} \ No newline at end of file diff --git a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx index 48c0aa19ec..6f36ba148c 100644 --- a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx +++ b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx @@ -9,8 +9,12 @@ import { useBridgeQuoteState } from '@/slices/bridgeQuote/hooks' import { setIsDestinationWarningAccepted } from '@/slices/bridgeDisplaySlice' import { useBridgeDisplayState, useBridgeState } from '@/slices/bridge/hooks' import { TransactionButton } from '@/components/buttons/TransactionButton' -import { useBridgeValidations } from './hooks/useBridgeValidations' +import { + useBridgeValidations, + constructStringifiedBridgeSelections, +} from './hooks/useBridgeValidations' import { segmentAnalyticsEvent } from '@/contexts/SegmentAnalyticsProvider' +import { useConfirmNewBridgePrice } from './hooks/useConfirmNewBridgePrice' export const BridgeTransactionButton = ({ approveTxn, @@ -45,6 +49,11 @@ export const BridgeTransactionButton = ({ debouncedFromValue, } = useBridgeState() const { bridgeQuote, isLoading } = useBridgeQuoteState() + const { + hasQuoteOutputChanged, + hasUserConfirmedChange, + setHasUserConfirmedChange, + } = useConfirmNewBridgePrice() const { isWalletPending } = useWalletState() const { showDestinationWarning, isDestinationWarningAccepted } = @@ -161,6 +170,12 @@ export const BridgeTransactionButton = ({ onClick: () => switchChain({ chainId: fromChainId }), pendingLabel: 'Switching chains', } + } else if (hasQuoteOutputChanged && !hasUserConfirmedChange) { + buttonProperties = { + label: 'Confirm new price', + onClick: () => setHasUserConfirmedChange(true), + className: 'border-synapsePurple !from-bgLight !to-bgLight', + } } else if (!isApproved && hasValidInput && hasValidQuote) { buttonProperties = { onClick: approveTxn, diff --git a/packages/synapse-interface/components/StateManagedBridge/hooks/useBridgeValidations.ts b/packages/synapse-interface/components/StateManagedBridge/hooks/useBridgeValidations.ts index e64ac72587..b3f31ab0f6 100644 --- a/packages/synapse-interface/components/StateManagedBridge/hooks/useBridgeValidations.ts +++ b/packages/synapse-interface/components/StateManagedBridge/hooks/useBridgeValidations.ts @@ -111,7 +111,7 @@ export const useBridgeValidations = () => { } } -const constructStringifiedBridgeSelections = ( +export const constructStringifiedBridgeSelections = ( originAmount, originChainId, originToken, diff --git a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts new file mode 100644 index 0000000000..a67e3789fd --- /dev/null +++ b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts @@ -0,0 +1,62 @@ +import { useState, useEffect, useMemo } from 'react' + +import { useBridgeQuoteState } from '@/slices/bridgeQuote/hooks' +import { constructStringifiedBridgeSelections } from './useBridgeValidations' + +export const useConfirmNewBridgePrice = () => { + const [hasQuoteOutputChanged, setHasQuoteOutputChanged] = + useState(false) + const [hasUserConfirmedChange, setHasUserConfirmedChange] = + useState(false) + + const { bridgeQuote, previousBridgeQuote } = useBridgeQuoteState() + + const currentBridgeQuoteSelections = useMemo( + () => + constructStringifiedBridgeSelections( + bridgeQuote?.inputAmountForQuote, + bridgeQuote?.originChainId, + bridgeQuote?.originTokenForQuote, + bridgeQuote?.destChainId, + bridgeQuote?.destTokenForQuote + ), + [bridgeQuote] + ) + + const previousBridgeQuoteSelections = useMemo( + () => + constructStringifiedBridgeSelections( + previousBridgeQuote?.inputAmountForQuote, + previousBridgeQuote?.originChainId, + previousBridgeQuote?.originTokenForQuote, + previousBridgeQuote?.destChainId, + previousBridgeQuote?.destTokenForQuote + ), + [previousBridgeQuote] + ) + + useEffect(() => { + const selectionsMatch = + currentBridgeQuoteSelections === previousBridgeQuoteSelections + + const outputAmountChanged = + bridgeQuote?.outputAmount !== previousBridgeQuote?.outputAmount + + setHasQuoteOutputChanged(selectionsMatch && outputAmountChanged) + + if (!selectionsMatch || !outputAmountChanged) { + setHasUserConfirmedChange(false) + } + }, [ + bridgeQuote, + previousBridgeQuote, + currentBridgeQuoteSelections, + previousBridgeQuoteSelections, + ]) + + return { + hasQuoteOutputChanged, + hasUserConfirmedChange, + setHasUserConfirmedChange, + } +} From bd29349e8b2db8b3a6a6a5c1236310eba31ea47f Mon Sep 17 00:00:00 2001 From: bigboydiamonds <57741810+bigboydiamonds@users.noreply.github.com> Date: Fri, 30 Aug 2024 12:27:21 -0700 Subject: [PATCH 04/12] conditions for displaying confirm price --- .../StateManagedBridge/BridgeTransactionButton.tsx | 2 +- .../StateManagedBridge/hooks/useConfirmNewBridgePrice.ts | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx index 6f36ba148c..2f2d26e9be 100644 --- a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx +++ b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx @@ -174,7 +174,7 @@ export const BridgeTransactionButton = ({ buttonProperties = { label: 'Confirm new price', onClick: () => setHasUserConfirmedChange(true), - className: 'border-synapsePurple !from-bgLight !to-bgLight', + className: '!border !border-synapsePurple !from-bgLight !to-bgLight', } } else if (!isApproved && hasValidInput && hasValidQuote) { buttonProperties = { diff --git a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts index a67e3789fd..3e234663e0 100644 --- a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts +++ b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts @@ -36,15 +36,20 @@ export const useConfirmNewBridgePrice = () => { ) useEffect(() => { + const isValidQuotes = + bridgeQuote?.outputAmount && previousBridgeQuote?.outputAmount + const selectionsMatch = currentBridgeQuoteSelections === previousBridgeQuoteSelections const outputAmountChanged = bridgeQuote?.outputAmount !== previousBridgeQuote?.outputAmount - setHasQuoteOutputChanged(selectionsMatch && outputAmountChanged) + setHasQuoteOutputChanged( + isValidQuotes && selectionsMatch && outputAmountChanged + ) - if (!selectionsMatch || !outputAmountChanged) { + if (outputAmountChanged || !selectionsMatch) { setHasUserConfirmedChange(false) } }, [ From 76663ba15355852e1a04112650fd91cfd13e65d1 Mon Sep 17 00:00:00 2001 From: bigboydiamonds <57741810+bigboydiamonds@users.noreply.github.com> Date: Fri, 30 Aug 2024 13:00:57 -0700 Subject: [PATCH 05/12] confirm prices based on initial triggered ref --- .../BridgeTransactionButton.tsx | 3 ++- .../hooks/useConfirmNewBridgePrice.ts | 23 +++++++++++++------ .../components/buttons/TransactionButton.tsx | 2 +- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx index 2f2d26e9be..f2d5fcf039 100644 --- a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx +++ b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx @@ -174,7 +174,8 @@ export const BridgeTransactionButton = ({ buttonProperties = { label: 'Confirm new price', onClick: () => setHasUserConfirmedChange(true), - className: '!border !border-synapsePurple !from-bgLight !to-bgLight', + className: + '!border !border-synapsePurple !from-bgLight !to-bgLight !animate-pulse !hover:animate-none', } } else if (!isApproved && hasValidInput && hasValidQuote) { buttonProperties = { diff --git a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts index 3e234663e0..b071e87723 100644 --- a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts +++ b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts @@ -1,4 +1,4 @@ -import { useState, useEffect, useMemo } from 'react' +import { useState, useEffect, useMemo, useRef } from 'react' import { useBridgeQuoteState } from '@/slices/bridgeQuote/hooks' import { constructStringifiedBridgeSelections } from './useBridgeValidations' @@ -9,6 +9,8 @@ export const useConfirmNewBridgePrice = () => { const [hasUserConfirmedChange, setHasUserConfirmedChange] = useState(false) + const triggeredQuoteRef = useRef(null) + const { bridgeQuote, previousBridgeQuote } = useBridgeQuoteState() const currentBridgeQuoteSelections = useMemo( @@ -36,7 +38,7 @@ export const useConfirmNewBridgePrice = () => { ) useEffect(() => { - const isValidQuotes = + const validQuotes = bridgeQuote?.outputAmount && previousBridgeQuote?.outputAmount const selectionsMatch = @@ -45,12 +47,19 @@ export const useConfirmNewBridgePrice = () => { const outputAmountChanged = bridgeQuote?.outputAmount !== previousBridgeQuote?.outputAmount - setHasQuoteOutputChanged( - isValidQuotes && selectionsMatch && outputAmountChanged - ) - - if (outputAmountChanged || !selectionsMatch) { + if (validQuotes && selectionsMatch && outputAmountChanged) { + // Ref quote that triggered the change + triggeredQuoteRef.current = bridgeQuote + setHasQuoteOutputChanged(true) setHasUserConfirmedChange(false) + } else if ( + bridgeQuote?.outputAmount === triggeredQuoteRef?.current?.outputAmount && + selectionsMatch + ) { + // Maintain status until User confirms ref changes + setHasQuoteOutputChanged(true) + } else { + setHasQuoteOutputChanged(false) } }, [ bridgeQuote, diff --git a/packages/synapse-interface/components/buttons/TransactionButton.tsx b/packages/synapse-interface/components/buttons/TransactionButton.tsx index 8decf4bb50..6cb70ce902 100644 --- a/packages/synapse-interface/components/buttons/TransactionButton.tsx +++ b/packages/synapse-interface/components/buttons/TransactionButton.tsx @@ -42,8 +42,8 @@ export const TransactionButton = ({ style={style} disabled={disabled} className={` - ${className} ${BASE_PROPERTIES} + ${className} ${ isPending ? 'from-fuchsia-400 dark:from-fuchsia-900 to-purple-400 dark:to-purple-900' From 18c817681e2821ce7e087e74851689b5b81b1cb3 Mon Sep 17 00:00:00 2001 From: bigboydiamonds <57741810+bigboydiamonds@users.noreply.github.com> Date: Fri, 30 Aug 2024 13:05:03 -0700 Subject: [PATCH 06/12] nit --- .../StateManagedBridge/BridgeTransactionButton.tsx | 2 +- .../StateManagedBridge/hooks/useConfirmNewBridgePrice.ts | 8 ++++---- .../components/buttons/TransactionButton.tsx | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx index f2d5fcf039..fc675484fa 100644 --- a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx +++ b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx @@ -175,7 +175,7 @@ export const BridgeTransactionButton = ({ label: 'Confirm new price', onClick: () => setHasUserConfirmedChange(true), className: - '!border !border-synapsePurple !from-bgLight !to-bgLight !animate-pulse !hover:animate-none', + '!border !border-synapsePurple !from-bgLight !to-bgLight !animate-pulse', } } else if (!isApproved && hasValidInput && hasValidQuote) { buttonProperties = { diff --git a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts index b071e87723..ffc3bfc3fb 100644 --- a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts +++ b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts @@ -47,16 +47,16 @@ export const useConfirmNewBridgePrice = () => { const outputAmountChanged = bridgeQuote?.outputAmount !== previousBridgeQuote?.outputAmount - if (validQuotes && selectionsMatch && outputAmountChanged) { + if (selectionsMatch && validQuotes && outputAmountChanged) { // Ref quote that triggered the change triggeredQuoteRef.current = bridgeQuote setHasQuoteOutputChanged(true) setHasUserConfirmedChange(false) } else if ( - bridgeQuote?.outputAmount === triggeredQuoteRef?.current?.outputAmount && - selectionsMatch + selectionsMatch && + bridgeQuote?.outputAmount === triggeredQuoteRef?.current?.outputAmount ) { - // Maintain status until User confirms ref changes + // Maintain status until User confirms ref quote update setHasQuoteOutputChanged(true) } else { setHasQuoteOutputChanged(false) diff --git a/packages/synapse-interface/components/buttons/TransactionButton.tsx b/packages/synapse-interface/components/buttons/TransactionButton.tsx index 6cb70ce902..8decf4bb50 100644 --- a/packages/synapse-interface/components/buttons/TransactionButton.tsx +++ b/packages/synapse-interface/components/buttons/TransactionButton.tsx @@ -42,8 +42,8 @@ export const TransactionButton = ({ style={style} disabled={disabled} className={` - ${BASE_PROPERTIES} ${className} + ${BASE_PROPERTIES} ${ isPending ? 'from-fuchsia-400 dark:from-fuchsia-900 to-purple-400 dark:to-purple-900' From 6d14aca1463532aa7f8cd93d34c2f65062156ef6 Mon Sep 17 00:00:00 2001 From: bigboydiamonds <57741810+bigboydiamonds@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:40:01 -0700 Subject: [PATCH 07/12] request User confirm price if change greater than 1 bps --- .../hooks/useConfirmNewBridgePrice.ts | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts index ffc3bfc3fb..ac20572b27 100644 --- a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts +++ b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts @@ -9,7 +9,7 @@ export const useConfirmNewBridgePrice = () => { const [hasUserConfirmedChange, setHasUserConfirmedChange] = useState(false) - const triggeredQuoteRef = useRef(null) + const quoteRef = useRef(null) const { bridgeQuote, previousBridgeQuote } = useBridgeQuoteState() @@ -47,18 +47,50 @@ export const useConfirmNewBridgePrice = () => { const outputAmountChanged = bridgeQuote?.outputAmount !== previousBridgeQuote?.outputAmount - if (selectionsMatch && validQuotes && outputAmountChanged) { - // Ref quote that triggered the change - triggeredQuoteRef.current = bridgeQuote + const outputAmountDiffMoreThan1bps = + validQuotes && quoteRef?.current?.outputAmountString + ? Math.abs( + parseFloat(bridgeQuote?.outputAmountString) - + parseFloat(quoteRef?.current?.outputAmountString) + ) / + parseFloat(quoteRef?.current?.outputAmountString) > + 0.0001 + : validQuotes + ? Math.abs( + parseFloat(bridgeQuote?.outputAmountString) - + parseFloat(previousBridgeQuote?.outputAmountString) + ) / + parseFloat(previousBridgeQuote?.outputAmountString) > + 0.0001 + : false + + // console.log('outputAmountDiffMoreThan1bps:', outputAmountDiffMoreThan1bps) + // console.log( + // 'bridgeQuote?.outputAmountString: ', + // bridgeQuote?.outputAmountString + // ) + // console.log( + // 'previousBridgeQuote?.outputAmountString: ', + // previousBridgeQuote?.outputAmountString + // ) + + if ( + validQuotes && + selectionsMatch && + outputAmountChanged && + outputAmountDiffMoreThan1bps + ) { + quoteRef.current = bridgeQuote setHasQuoteOutputChanged(true) setHasUserConfirmedChange(false) } else if ( selectionsMatch && - bridgeQuote?.outputAmount === triggeredQuoteRef?.current?.outputAmount + bridgeQuote?.outputAmount === quoteRef?.current?.outputAmount ) { // Maintain status until User confirms ref quote update setHasQuoteOutputChanged(true) } else { + quoteRef.current = null setHasQuoteOutputChanged(false) } }, [ From cd75683ab44c41d1ff1b1ffc47be0124fe903e3b Mon Sep 17 00:00:00 2001 From: bigboydiamonds <57741810+bigboydiamonds@users.noreply.github.com> Date: Tue, 3 Sep 2024 16:15:34 -0700 Subject: [PATCH 08/12] callback functions to handle creating/accepting/reset confirm flow --- .../BridgeTransactionButton.tsx | 4 +- .../hooks/useConfirmNewBridgePrice.ts | 147 ++++++++++-------- 2 files changed, 80 insertions(+), 71 deletions(-) diff --git a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx index c9cdea2d09..c49db357d9 100644 --- a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx +++ b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx @@ -52,7 +52,7 @@ export const BridgeTransactionButton = ({ const { hasQuoteOutputChanged, hasUserConfirmedChange, - setHasUserConfirmedChange, + handleUserAcceptChange, } = useConfirmNewBridgePrice() const { isWalletPending } = useWalletState() @@ -174,7 +174,7 @@ export const BridgeTransactionButton = ({ } else if (hasQuoteOutputChanged && !hasUserConfirmedChange) { buttonProperties = { label: 'Confirm new price', - onClick: () => setHasUserConfirmedChange(true), + onClick: () => handleUserAcceptChange(), className: '!border !border-synapsePurple !from-bgLight !to-bgLight !animate-pulse', } diff --git a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts index ac20572b27..4d6d032167 100644 --- a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts +++ b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts @@ -1,108 +1,117 @@ -import { useState, useEffect, useMemo, useRef } from 'react' +import { useState, useEffect, useMemo, useRef, useCallback } from 'react' import { useBridgeQuoteState } from '@/slices/bridgeQuote/hooks' import { constructStringifiedBridgeSelections } from './useBridgeValidations' export const useConfirmNewBridgePrice = () => { + const quoteRef = useRef(null) + const [hasQuoteOutputChanged, setHasQuoteOutputChanged] = useState(false) const [hasUserConfirmedChange, setHasUserConfirmedChange] = useState(false) - const quoteRef = useRef(null) - const { bridgeQuote, previousBridgeQuote } = useBridgeQuoteState() - const currentBridgeQuoteSelections = useMemo( - () => + const createBridgeSelections = useCallback( + (quote) => constructStringifiedBridgeSelections( - bridgeQuote?.inputAmountForQuote, - bridgeQuote?.originChainId, - bridgeQuote?.originTokenForQuote, - bridgeQuote?.destChainId, - bridgeQuote?.destTokenForQuote + quote?.inputAmountForQuote, + quote?.originChainId, + quote?.originTokenForQuote, + quote?.destChainId, + quote?.destTokenForQuote ), - [bridgeQuote] + [] + ) + + const currentBridgeQuoteSelections = useMemo( + () => createBridgeSelections(bridgeQuote), + [bridgeQuote, createBridgeSelections] ) const previousBridgeQuoteSelections = useMemo( - () => - constructStringifiedBridgeSelections( - previousBridgeQuote?.inputAmountForQuote, - previousBridgeQuote?.originChainId, - previousBridgeQuote?.originTokenForQuote, - previousBridgeQuote?.destChainId, - previousBridgeQuote?.destTokenForQuote - ), - [previousBridgeQuote] + () => createBridgeSelections(previousBridgeQuote), + [previousBridgeQuote, createBridgeSelections] ) + const calculateOutputRelativeDifference = useCallback((quoteA, quoteB) => { + if (!quoteA?.outputAmountString || !quoteB?.outputAmountString) return null + + const outputA = parseFloat(quoteA.outputAmountString) + const outputB = parseFloat(quoteB.outputAmountString) + + return Math.abs(outputA - outputB) / outputB + }, []) + + const handleRequestUserConfirmChange = (previousQuote) => { + if (!hasQuoteOutputChanged && !hasUserConfirmedChange) { + quoteRef.current = previousQuote + setHasQuoteOutputChanged(true) + setHasUserConfirmedChange(false) + } + } + + const handleUserAcceptChange = () => { + quoteRef.current = null + setHasUserConfirmedChange(true) + } + + const handleReset = () => { + if (hasUserConfirmedChange) { + quoteRef.current = null + setHasQuoteOutputChanged(false) + setHasUserConfirmedChange(false) + } + } + useEffect(() => { const validQuotes = bridgeQuote?.outputAmount && previousBridgeQuote?.outputAmount - const selectionsMatch = currentBridgeQuoteSelections === previousBridgeQuoteSelections - const outputAmountChanged = - bridgeQuote?.outputAmount !== previousBridgeQuote?.outputAmount - - const outputAmountDiffMoreThan1bps = - validQuotes && quoteRef?.current?.outputAmountString - ? Math.abs( - parseFloat(bridgeQuote?.outputAmountString) - - parseFloat(quoteRef?.current?.outputAmountString) - ) / - parseFloat(quoteRef?.current?.outputAmountString) > - 0.0001 - : validQuotes - ? Math.abs( - parseFloat(bridgeQuote?.outputAmountString) - - parseFloat(previousBridgeQuote?.outputAmountString) - ) / - parseFloat(previousBridgeQuote?.outputAmountString) > - 0.0001 - : false - - // console.log('outputAmountDiffMoreThan1bps:', outputAmountDiffMoreThan1bps) - // console.log( - // 'bridgeQuote?.outputAmountString: ', - // bridgeQuote?.outputAmountString - // ) - // console.log( - // 'previousBridgeQuote?.outputAmountString: ', - // previousBridgeQuote?.outputAmountString - // ) - - if ( - validQuotes && - selectionsMatch && - outputAmountChanged && - outputAmountDiffMoreThan1bps - ) { - quoteRef.current = bridgeQuote - setHasQuoteOutputChanged(true) - setHasUserConfirmedChange(false) - } else if ( - selectionsMatch && - bridgeQuote?.outputAmount === quoteRef?.current?.outputAmount - ) { - // Maintain status until User confirms ref quote update - setHasQuoteOutputChanged(true) + const outputAmountDiffMoreThan1bps = validQuotes + ? calculateOutputRelativeDifference( + bridgeQuote, + quoteRef.current ?? previousBridgeQuote + ) > 0.0001 + : false + + console.log('quoteRef.current:', quoteRef.current?.outputAmountString) + console.log( + 'bridgeQuote?.outputAmountString: ', + bridgeQuote?.outputAmountString + ) + console.log( + 'previousBridgeQuote?.outputAmountString:', + previousBridgeQuote?.outputAmountString + ) + console.log( + 'relative difference: ', + calculateOutputRelativeDifference( + bridgeQuote, + quoteRef.current ?? previousBridgeQuote + ) + ) + console.log('outputAmountDiffMoreThan1bps: ', outputAmountDiffMoreThan1bps) + + if (validQuotes && selectionsMatch && outputAmountDiffMoreThan1bps) { + handleRequestUserConfirmChange(previousBridgeQuote) } else { - quoteRef.current = null - setHasQuoteOutputChanged(false) + handleReset() } }, [ bridgeQuote, previousBridgeQuote, currentBridgeQuoteSelections, previousBridgeQuoteSelections, + calculateOutputRelativeDifference, ]) return { hasQuoteOutputChanged, hasUserConfirmedChange, - setHasUserConfirmedChange, + handleUserAcceptChange, } } From febd306eddaeebb148ec839f908a33b337b7ec67 Mon Sep 17 00:00:00 2001 From: bigboydiamonds <57741810+bigboydiamonds@users.noreply.github.com> Date: Wed, 4 Sep 2024 16:07:55 -0700 Subject: [PATCH 09/12] request user confirm after first accepted --- .../StateManagedBridge/hooks/useConfirmNewBridgePrice.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts index 4d6d032167..c6ab7cfed3 100644 --- a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts +++ b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts @@ -48,8 +48,8 @@ export const useConfirmNewBridgePrice = () => { if (!hasQuoteOutputChanged && !hasUserConfirmedChange) { quoteRef.current = previousQuote setHasQuoteOutputChanged(true) - setHasUserConfirmedChange(false) } + setHasUserConfirmedChange(false) } const handleUserAcceptChange = () => { From e7df2386edbc3595a862dd69186bc86c3a11e552 Mon Sep 17 00:00:00 2001 From: bigboydiamonds <57741810+bigboydiamonds@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:33:57 -0700 Subject: [PATCH 10/12] fe/updating-quote (#3104) * request user confirm after first accepted * Update button message to reflect when quote updating * change button text ordering for insufficient balance * rm log --- .../BridgeTransactionButton.tsx | 16 +++++++++++----- .../hooks/useConfirmNewBridgePrice.ts | 8 +++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx index c49db357d9..c2a87dac84 100644 --- a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx +++ b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx @@ -50,6 +50,7 @@ export const BridgeTransactionButton = ({ } = useBridgeState() const { bridgeQuote, isLoading } = useBridgeQuoteState() const { + hasSameSelectionsAsPreviousQuote, hasQuoteOutputChanged, hasUserConfirmedChange, handleUserAcceptChange, @@ -103,6 +104,16 @@ export const BridgeTransactionButton = ({ label: `Please select an Origin token`, onClick: null, } + } else if (isConnected && !hasSufficientBalance) { + buttonProperties = { + label: 'Insufficient balance', + onClick: null, + } + } else if (isLoading && hasSameSelectionsAsPreviousQuote) { + buttonProperties = { + label: 'Updating quote', + onClick: null, + } } else if (isLoading) { buttonProperties = { label: `Bridge ${fromToken?.symbol}`, @@ -150,11 +161,6 @@ export const BridgeTransactionButton = ({ label: 'Invalid bridge quote', onClick: null, } - } else if (!isLoading && isConnected && !hasSufficientBalance) { - buttonProperties = { - label: 'Insufficient balance', - onClick: null, - } } else if (destinationAddress && !isAddress(destinationAddress)) { buttonProperties = { label: 'Invalid Destination address', diff --git a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts index 4d6d032167..568c94acb7 100644 --- a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts +++ b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts @@ -35,6 +35,11 @@ export const useConfirmNewBridgePrice = () => { [previousBridgeQuote, createBridgeSelections] ) + const hasSameSelectionsAsPreviousQuote = useMemo( + () => currentBridgeQuoteSelections === previousBridgeQuoteSelections, + [currentBridgeQuoteSelections, previousBridgeQuoteSelections] + ) + const calculateOutputRelativeDifference = useCallback((quoteA, quoteB) => { if (!quoteA?.outputAmountString || !quoteB?.outputAmountString) return null @@ -48,8 +53,8 @@ export const useConfirmNewBridgePrice = () => { if (!hasQuoteOutputChanged && !hasUserConfirmedChange) { quoteRef.current = previousQuote setHasQuoteOutputChanged(true) - setHasUserConfirmedChange(false) } + setHasUserConfirmedChange(false) } const handleUserAcceptChange = () => { @@ -110,6 +115,7 @@ export const useConfirmNewBridgePrice = () => { ]) return { + hasSameSelectionsAsPreviousQuote, hasQuoteOutputChanged, hasUserConfirmedChange, handleUserAcceptChange, From 571b39101cf567e21a587f1ab551e1354e36d292 Mon Sep 17 00:00:00 2001 From: bigboydiamonds <57741810+bigboydiamonds@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:53:02 -0700 Subject: [PATCH 11/12] clean logic --- .../BridgeTransactionButton.tsx | 4 +- .../hooks/useConfirmNewBridgePrice.ts | 133 ++++++++---------- 2 files changed, 62 insertions(+), 75 deletions(-) diff --git a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx index c2a87dac84..975d139e27 100644 --- a/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx +++ b/packages/synapse-interface/components/StateManagedBridge/BridgeTransactionButton.tsx @@ -53,7 +53,7 @@ export const BridgeTransactionButton = ({ hasSameSelectionsAsPreviousQuote, hasQuoteOutputChanged, hasUserConfirmedChange, - handleUserAcceptChange, + onUserAcceptChange, } = useConfirmNewBridgePrice() const { isWalletPending } = useWalletState() @@ -180,7 +180,7 @@ export const BridgeTransactionButton = ({ } else if (hasQuoteOutputChanged && !hasUserConfirmedChange) { buttonProperties = { label: 'Confirm new price', - onClick: () => handleUserAcceptChange(), + onClick: () => onUserAcceptChange(), className: '!border !border-synapsePurple !from-bgLight !to-bgLight !animate-pulse', } diff --git a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts index 568c94acb7..2f4a43ab74 100644 --- a/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts +++ b/packages/synapse-interface/components/StateManagedBridge/hooks/useConfirmNewBridgePrice.ts @@ -1,7 +1,9 @@ -import { useState, useEffect, useMemo, useRef, useCallback } from 'react' +import { useState, useEffect, useMemo, useRef } from 'react' +import { useBridgeState } from '@/slices/bridge/hooks' import { useBridgeQuoteState } from '@/slices/bridgeQuote/hooks' import { constructStringifiedBridgeSelections } from './useBridgeValidations' +import { BridgeQuote } from '@/utils/types' export const useConfirmNewBridgePrice = () => { const quoteRef = useRef(null) @@ -12,27 +14,31 @@ export const useConfirmNewBridgePrice = () => { useState(false) const { bridgeQuote, previousBridgeQuote } = useBridgeQuoteState() + const { debouncedFromValue, fromToken, toToken, fromChainId, toChainId } = + useBridgeState() - const createBridgeSelections = useCallback( - (quote) => + const currentBridgeQuoteSelections = useMemo( + () => constructStringifiedBridgeSelections( - quote?.inputAmountForQuote, - quote?.originChainId, - quote?.originTokenForQuote, - quote?.destChainId, - quote?.destTokenForQuote + debouncedFromValue, + fromChainId, + fromToken, + toChainId, + toToken ), - [] - ) - - const currentBridgeQuoteSelections = useMemo( - () => createBridgeSelections(bridgeQuote), - [bridgeQuote, createBridgeSelections] + [debouncedFromValue, fromChainId, fromToken, toChainId, toToken] ) const previousBridgeQuoteSelections = useMemo( - () => createBridgeSelections(previousBridgeQuote), - [previousBridgeQuote, createBridgeSelections] + () => + constructStringifiedBridgeSelections( + previousBridgeQuote?.inputAmountForQuote, + previousBridgeQuote?.originChainId, + previousBridgeQuote?.originTokenForQuote, + previousBridgeQuote?.destChainId, + previousBridgeQuote?.destTokenForQuote + ), + [previousBridgeQuote] ) const hasSameSelectionsAsPreviousQuote = useMemo( @@ -40,16 +46,29 @@ export const useConfirmNewBridgePrice = () => { [currentBridgeQuoteSelections, previousBridgeQuoteSelections] ) - const calculateOutputRelativeDifference = useCallback((quoteA, quoteB) => { - if (!quoteA?.outputAmountString || !quoteB?.outputAmountString) return null + useEffect(() => { + const validQuotes = + bridgeQuote?.outputAmount && previousBridgeQuote?.outputAmount - const outputA = parseFloat(quoteA.outputAmountString) - const outputB = parseFloat(quoteB.outputAmountString) + const outputAmountDiffMoreThan1bps = validQuotes + ? calculateOutputRelativeDifference( + bridgeQuote, + quoteRef.current ?? previousBridgeQuote + ) > 0.0001 + : false - return Math.abs(outputA - outputB) / outputB - }, []) + if ( + validQuotes && + outputAmountDiffMoreThan1bps && + hasSameSelectionsAsPreviousQuote + ) { + requestUserConfirmChange(previousBridgeQuote) + } else { + resetConfirm() + } + }, [bridgeQuote, previousBridgeQuote, hasSameSelectionsAsPreviousQuote]) - const handleRequestUserConfirmChange = (previousQuote) => { + const requestUserConfirmChange = (previousQuote: BridgeQuote) => { if (!hasQuoteOutputChanged && !hasUserConfirmedChange) { quoteRef.current = previousQuote setHasQuoteOutputChanged(true) @@ -57,12 +76,7 @@ export const useConfirmNewBridgePrice = () => { setHasUserConfirmedChange(false) } - const handleUserAcceptChange = () => { - quoteRef.current = null - setHasUserConfirmedChange(true) - } - - const handleReset = () => { + const resetConfirm = () => { if (hasUserConfirmedChange) { quoteRef.current = null setHasQuoteOutputChanged(false) @@ -70,54 +84,27 @@ export const useConfirmNewBridgePrice = () => { } } - useEffect(() => { - const validQuotes = - bridgeQuote?.outputAmount && previousBridgeQuote?.outputAmount - const selectionsMatch = - currentBridgeQuoteSelections === previousBridgeQuoteSelections - - const outputAmountDiffMoreThan1bps = validQuotes - ? calculateOutputRelativeDifference( - bridgeQuote, - quoteRef.current ?? previousBridgeQuote - ) > 0.0001 - : false - - console.log('quoteRef.current:', quoteRef.current?.outputAmountString) - console.log( - 'bridgeQuote?.outputAmountString: ', - bridgeQuote?.outputAmountString - ) - console.log( - 'previousBridgeQuote?.outputAmountString:', - previousBridgeQuote?.outputAmountString - ) - console.log( - 'relative difference: ', - calculateOutputRelativeDifference( - bridgeQuote, - quoteRef.current ?? previousBridgeQuote - ) - ) - console.log('outputAmountDiffMoreThan1bps: ', outputAmountDiffMoreThan1bps) - - if (validQuotes && selectionsMatch && outputAmountDiffMoreThan1bps) { - handleRequestUserConfirmChange(previousBridgeQuote) - } else { - handleReset() - } - }, [ - bridgeQuote, - previousBridgeQuote, - currentBridgeQuoteSelections, - previousBridgeQuoteSelections, - calculateOutputRelativeDifference, - ]) + const onUserAcceptChange = () => { + quoteRef.current = null + setHasUserConfirmedChange(true) + } return { hasSameSelectionsAsPreviousQuote, hasQuoteOutputChanged, hasUserConfirmedChange, - handleUserAcceptChange, + onUserAcceptChange, } } + +const calculateOutputRelativeDifference = ( + quoteA?: BridgeQuote, + quoteB?: BridgeQuote +) => { + if (!quoteA?.outputAmountString || !quoteB?.outputAmountString) return null + + const outputA = parseFloat(quoteA.outputAmountString) + const outputB = parseFloat(quoteB.outputAmountString) + + return Math.abs(outputA - outputB) / outputB +} From c7b29815629ed43cf8ffef847390cf4ce2561c4a Mon Sep 17 00:00:00 2001 From: bigboydiamonds <57741810+bigboydiamonds@users.noreply.github.com> Date: Fri, 6 Sep 2024 17:20:29 -0700 Subject: [PATCH 12/12] [WIP] stale quote animation (#3105) * animate-quote-refresh * pair stale quote refresh with each quote * update progress circle animation --- .../StateManagedBridge/OutputContainer.tsx | 49 ++++++++++++++++++- .../pages/state-managed-bridge/index.tsx | 1 - .../utils/hooks/useStaleQuoteUpdater.ts | 25 +++++----- 3 files changed, 59 insertions(+), 16 deletions(-) diff --git a/packages/synapse-interface/components/StateManagedBridge/OutputContainer.tsx b/packages/synapse-interface/components/StateManagedBridge/OutputContainer.tsx index 9f06ed4bd2..03b73bb8f0 100644 --- a/packages/synapse-interface/components/StateManagedBridge/OutputContainer.tsx +++ b/packages/synapse-interface/components/StateManagedBridge/OutputContainer.tsx @@ -1,5 +1,5 @@ import { useAccount } from 'wagmi' -import { useMemo } from 'react' +import { useMemo, useEffect, useState } from 'react' import { ChainSelector } from '@/components/ui/ChainSelector' import { TokenSelector } from '@/components/ui/TokenSelector' @@ -14,11 +14,13 @@ import { setToChainId, setToToken } from '@/slices/bridge/reducer' import { useBridgeDisplayState, useBridgeState } from '@/slices/bridge/hooks' import { useWalletState } from '@/slices/wallet/hooks' import { useBridgeQuoteState } from '@/slices/bridgeQuote/hooks' +import { BridgeQuote } from '@/utils/types' import { useBridgeValidations } from './hooks/useBridgeValidations' +import { useConfirmNewBridgePrice } from './hooks/useConfirmNewBridgePrice' export const OutputContainer = () => { const { address } = useAccount() - const { bridgeQuote, isLoading } = useBridgeQuoteState() + const { bridgeQuote, previousBridgeQuote, isLoading } = useBridgeQuoteState() const { showDestinationAddress } = useBridgeDisplayState() const { hasValidInput, hasValidQuote } = useBridgeValidations() @@ -48,6 +50,9 @@ export const OutputContainer = () => { showValue={showValue} isLoading={isLoading} /> + {hasValidQuote && !isLoading && ( + + )} ) @@ -88,3 +93,43 @@ const ToTokenSelector = () => { /> ) } + +const AnimatedProgressCircle = ({ bridgeQuoteId }) => { + const [animationKey, setAnimationKey] = useState(0) + + useEffect(() => { + setAnimationKey((prevKey) => prevKey + 1) + }, [bridgeQuoteId]) + + return ( + + + + + + + + + ) +} diff --git a/packages/synapse-interface/pages/state-managed-bridge/index.tsx b/packages/synapse-interface/pages/state-managed-bridge/index.tsx index 58e61370c2..43b5e65aa2 100644 --- a/packages/synapse-interface/pages/state-managed-bridge/index.tsx +++ b/packages/synapse-interface/pages/state-managed-bridge/index.tsx @@ -200,7 +200,6 @@ const StateManagedBridge = () => { bridgeQuote, getAndSetBridgeQuote, isLoading, - isWalletPending, quoteTimeout ) diff --git a/packages/synapse-interface/utils/hooks/useStaleQuoteUpdater.ts b/packages/synapse-interface/utils/hooks/useStaleQuoteUpdater.ts index 05ccd37dc3..f998c777c2 100644 --- a/packages/synapse-interface/utils/hooks/useStaleQuoteUpdater.ts +++ b/packages/synapse-interface/utils/hooks/useStaleQuoteUpdater.ts @@ -2,7 +2,6 @@ import { isNull, isNumber } from 'lodash' import { useEffect, useRef } from 'react' import { BridgeQuote } from '@/utils/types' -import { calculateTimeBetween } from '@/utils/time' import { useIntervalTimer } from '@/utils/hooks/useIntervalTimer' import { convertUuidToUnix } from '@/utils/convertUuidToUnix' @@ -14,25 +13,19 @@ export const useStaleQuoteUpdater = ( quote: BridgeQuote, refreshQuoteCallback: () => Promise, isQuoteLoading: boolean, - isWalletPending: boolean, staleTimeout: number = 15000 // Default 15_000ms or 15s ) => { const eventListenerRef = useRef void)>(null) - + const timeoutRef = useRef(null) const quoteTime = quote?.id ? convertUuidToUnix(quote?.id) : null const isValidQuote = isNumber(quoteTime) && !isNull(quoteTime) - const currentTime = useIntervalTimer(staleTimeout, !isValidQuote) + useIntervalTimer(staleTimeout, !isValidQuote) useEffect(() => { - if (isValidQuote && !isQuoteLoading && !isWalletPending) { - const timeDifference = calculateTimeBetween(currentTime, quoteTime) - const isStaleQuote = timeDifference >= staleTimeout - - if (isStaleQuote) { - if (eventListenerRef.current) { - document.removeEventListener('mousemove', eventListenerRef.current) - } + if (isValidQuote && !isQuoteLoading) { + timeoutRef.current = setTimeout(() => { + eventListenerRef.current = null const newEventListener = () => { refreshQuoteCallback() @@ -44,7 +37,13 @@ export const useStaleQuoteUpdater = ( }) eventListenerRef.current = newEventListener + }, staleTimeout) + } + + return () => { + if (timeoutRef.current) { + clearTimeout(timeoutRef.current) } } - }, [currentTime, staleTimeout]) + }, [quote, isQuoteLoading]) }