Skip to content

Commit

Permalink
feat(synapse-interface): destination address (#2137)
Browse files Browse the repository at this point in the history
* Init

* Basic Address Input

* Detect if input is valid address

* Click on Input to trigger warning

* DestinationInputWarning to handle accept/reject warning

* Hide placeholder when input is active

* Input display when input address valid

* Input width

* DestinationInputWarning state

* Warning accept/reject callback

* DestinationInputWarning to take up entire output container

* Style Warning

* Focus on Input after accepting warning terms

* showDestinationWarning state in bridge display to track if user already accepted warning for session

* Input border red signalling invalid input when activated

* Improve isEmptyString

* SwitchButton takes priority over OutputContainer in visual layer

* Clear Input button

* Style and format clear button for smooth input clearing

* Style Close Button

* Clean

* filterTransactionsByRecipient

* Calculate days ago a recipient tx was executed

* filterNewestTxByRecipient

* Display list of recipient addresses when input is focused

* Style Receipient dropdown list

* Destination address settable from dropdown list

* Close dropdown after selecting new destination address from list

* Disable Input if wallet unconnected

* Hover text on Input

* Input html states, styling

* Remove previous dest address settings state + component

* Optimize OutputContianer address prop passed into DestinationAddressInput, remove previous component

* Clean Bridge imports

* Style Input

* Replace useSelector with hook

* clearDestinationAddress on Bridge Page load

* Clean up Bridge reducer to not require actions file for better imports

* Rm file

* Maintain inputted destination address after bridge tx executes

* Clear destination address by setting to null, clear input

* Fix errors in BridgeTransactionButton

* User inputted empty string throws error in input

* Clean

* Update text error state

* Clean callbacks to make clear input flow clearer

* Clean

* Fix console errors

* Clean

* Add hover on warning buttnos

* .

* Refactor; clean functions

* Use destination address as key

* Style address dropdown

* Rm log

* Clean

* Keep inputRef local

* Add To

* Dynamically set Input width

* Adjust spacing for filled input

* Dynamic input width including placeholder

* Increase input width when focused

* Remove shift when x button appears

* Max width for input to fit on mobile

* Clean

* Basic Confirm Warning

* Connect ConfirmWarning to store

* Allow Warning text to be clickable

* Style: BridgeTransactionButton Warning

* Add setIsDestinationWarningAccepted to state to track status

* Show Confirm warning button when warning not yet accepted + tracked in state

* Conditions for showing Destination Address in Bridge Receipt

* Remove prior destination warning popup

* BridgeWarnings

* Conditions to show Warning

* Conditions to hide Destination Address Input

* Simplify

* Update button color for Confirm destination address

* Use default text size for dropdown

* Ensure blur from input on handleInputBlur

* Ensure blur from input on handleInputBlur

* ..

* Add paste functionality

* Conditions to show paste button

* Add key press up/down direction for navigating list

* Add pressing enter key functionality to select Address from list

* Reset list idx onClose

* Clean

* Prevent input blur when mouseDown on ListReceipient item

* Blur after selecting address from list

* Update input ref to useRef

* Fix merge imports

* Make input smaller

* Unconnected input padding

* Remove shift when input is valid address

* Add back SettingsSlideOver

* Add back settings toggled page

* Show destination address input when toggled on from Settings

* Clean SettingsSlideOver

* Clean

* Remove Pink highlight on Input

* Increase spacing between address and days ago

* Increase width of input, limit for mobile

* Remove yellow text in Warning

* Only show Destination Address in Receipt if valid

* Clear input if invalid and exists

* Adjust dropdown spacing

* Minor adjustments

* Blur input after clearing

* Enter button can submit input text for validation

* Paste icon sizing

* Show dest address for unconnected user if inputted

* Hide destination address input on page load between page switch

* Hide Bridge Warning if destination address is turned off

* Ensure bridge listener clears destination address if destination input setting turned off

* Remove unused code

* Fix enter bug when wallet disconnected

* Update dispatch value

* Update to proper action to dispatch

* Add back segment given we are using settings

* Lint

* Remove side effect to clear dest address

* Origin token copy

---------

Co-authored-by: abtestingalpha <abtestingalpha@gmail.com>
  • Loading branch information
bigboydiamonds and abtestingalpha authored Mar 27, 2024
1 parent 4cbd5dc commit 44f8af6
Show file tree
Hide file tree
Showing 18 changed files with 671 additions and 295 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ import {
import { resetTransactionsState } from '@/slices/transactions/actions'
import { PortfolioState } from '@/slices/portfolio/reducer'
import { useBridgeState } from '@/slices/bridge/hooks'
import { BridgeState } from '@/slices/bridge/reducer'
import { resetBridgeInputs } from '@/slices/bridge/actions'
import { BridgeState, resetBridgeInputs } from '@/slices/bridge/reducer'
import { ViewSearchAddressBanner } from './components/ViewSearchAddressBanner'
import { Activity } from '../Activity/Activity'
import { useSearchInputState } from './helpers/useSearchInputStatus'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import Image from 'next/image'
import { useMemo } from 'react'
import { useAppSelector } from '@/store/hooks'
import { useBridgeState } from '@/slices/bridge/hooks'
import { useAccount } from 'wagmi'
import { useCoingeckoPrice } from '@hooks/useCoingeckoPrice'
import {
ELIGIBILITY_DEFAULT_TEXT,
useStipEligibility,
} from '@/utils/hooks/useStipEligibility'
import { formatBigIntToString } from '@/utils/bigint/format'
import { formatBigIntToPercentString } from '@/utils/bigint/format'
import { getValidAddress, isValidAddress } from '@/utils/isValidAddress'
import { EMPTY_BRIDGE_QUOTE } from '@/constants/bridge'
import { CHAINS_BY_ID } from '@constants/chains'
import * as CHAINS from '@constants/chains/master'
Expand All @@ -26,11 +28,34 @@ const BridgeExchangeRateInfo = () => {
<Router />
<Rebate />
<Slippage />
<DestinationAddress />
</section>
</div>
)
}

const DestinationAddress = () => {
const { address } = useAccount()
const { destinationAddress } = useBridgeState()

const showAddress =
destinationAddress &&
getValidAddress(address) !== getValidAddress(destinationAddress)

const isInputValidAddress: boolean = destinationAddress
? isValidAddress(destinationAddress)
: false

if (showAddress && isInputValidAddress) {
return (
<div className="flex items-center space-x-1">
<div>To: </div>
<div className="text-primary">{destinationAddress}</div>
</div>
)
}
}

const Slippage = () => {
const {
fromValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,22 @@ import { isAddress } from 'viem'

import { useConnectModal } from '@rainbow-me/rainbowkit'
import { stringToBigInt } from '@/utils/bigint/format'
import { useBridgeState } from '@/slices/bridge/hooks'
import { useBridgeDisplayState, useBridgeState } from '@/slices/bridge/hooks'
import { usePortfolioBalances } from '@/slices/portfolio/hooks'
import { PAUSED_FROM_CHAIN_IDS, PAUSED_TO_CHAIN_IDS } from '@/constants/chains'
import { useAppDispatch } from '@/store/hooks'
import {
setIsDestinationWarningAccepted,
setShowDestinationWarning,
} from '@/slices/bridgeDisplaySlice'

export const BridgeTransactionButton = ({
approveTxn,
executeBridge,
isApproved,
isBridgePaused,
}) => {
const dispatch = useAppDispatch()
const [isConnected, setIsConnected] = useState(false)
const { openConnectModal } = useConnectModal()

Expand All @@ -45,10 +51,8 @@ export const BridgeTransactionButton = ({
isLoading,
bridgeQuote,
} = useBridgeState()

const { showDestinationAddress } = useSelector(
(state: RootState) => state.bridgeDisplay
)
const { showDestinationWarning, isDestinationWarningAccepted } =
useBridgeDisplayState()

const balances = usePortfolioBalances()
const balancesForChain = balances[fromChainId]
Expand All @@ -69,7 +73,6 @@ export const BridgeTransactionButton = ({
bridgeQuote === EMPTY_BRIDGE_QUOTE_ZERO ||
bridgeQuote === EMPTY_BRIDGE_QUOTE ||
(destinationAddress && !isAddress(destinationAddress)) ||
(showDestinationAddress && !destinationAddress) ||
(isConnected && !sufficientBalance) ||
PAUSED_FROM_CHAIN_IDS.includes(fromChainId) ||
PAUSED_TO_CHAIN_IDS.includes(toChainId) ||
Expand Down Expand Up @@ -109,7 +112,7 @@ export const BridgeTransactionButton = ({
}
} else if (!fromToken) {
buttonProperties = {
label: `Unsupported Network`,
label: `Please select an Origin token`,
onClick: null,
}
} else if (
Expand All @@ -131,14 +134,16 @@ export const BridgeTransactionButton = ({
label: 'Insufficient balance',
onClick: null,
}
} else if (showDestinationAddress && !destinationAddress) {
buttonProperties = {
label: 'Please add valid destination address',
}
} else if (destinationAddress && !isAddress(destinationAddress)) {
buttonProperties = {
label: 'Invalid destination address',
}
} else if (showDestinationWarning && !isDestinationWarningAccepted) {
buttonProperties = {
label: 'Confirm destination address',
onClick: () => dispatch(setIsDestinationWarningAccepted(true)),
className: '!from-bgLight !to-bgLight',
}
} else if (chain?.id != fromChainId && fromValueBigInt > 0) {
buttonProperties = {
label: `Switch to ${chains.find((c) => c.id === fromChainId)?.name}`,
Expand All @@ -161,11 +166,13 @@ export const BridgeTransactionButton = ({

return (
buttonProperties && (
<TransactionButton
{...buttonProperties}
disabled={isButtonDisabled}
chainId={fromChainId}
/>
<>
<TransactionButton
{...buttonProperties}
disabled={isButtonDisabled}
chainId={fromChainId}
/>
</>
)
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { useAppDispatch } from '@/store/hooks'
import { useBridgeDisplayState } from '@/slices/bridge/hooks'
import { setIsDestinationWarningAccepted } from '@/slices/bridgeDisplaySlice'

export const ConfirmDestinationAddressWarning = () => {
const dispatch = useAppDispatch()
const {
showDestinationWarning,
isDestinationWarningAccepted,
showDestinationAddress,
} = useBridgeDisplayState()

const handleCheckboxChange = () => {
dispatch(setIsDestinationWarningAccepted(!isDestinationWarningAccepted))
}

if (showDestinationAddress && showDestinationWarning) {
return (
<div
className="flex items-center mb-2 space-x-3 cursor-pointer"
onClick={handleCheckboxChange}
>
<input
type="checkbox"
id="destination-warning"
name="destinationWarning"
value=""
checked={isDestinationWarningAccepted}
onChange={handleCheckboxChange}
className={`
cursor-pointer border rounded-[4px] border-secondary
text-synapsePurple bg-transparent outline-none
focus:!outline-0 focus:ring-0 focus:!border-0
active:!outline-0 active:ring-0 active:!border-0
`}
/>
<div>
<p className="text-sm text-secondary">
<strong>Required:</strong> Verify your destination address to
continue.
<br />
Do <strong>not</strong> send assets to a custodial or exchange
address. It may be impossible to recover your funds.
</p>
</div>
</div>
)
}
}
Loading

0 comments on commit 44f8af6

Please sign in to comment.