Skip to content

Commit

Permalink
Widget/pending tx (#1988)
Browse files Browse the repository at this point in the history
* Store bridged originAmount in Redux to display in Transaction

* Store origin token symbol in Redux

* TransactionDetail

* Update time remaining displayed format

* TimeRemaining display when delayed past 1 min

* Move remaining time display into dropdown

* Pass down delayedTime into TimeRemaining in sec

* Clean

* Update executeBridgeTxn.rejected reducer case

* Complete tx

---------

Co-authored-by: abtestingalpha <[email protected]>
  • Loading branch information
bigboydiamonds and abtestingalpha authored Feb 6, 2024
1 parent 4817024 commit f155ea4
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 34 deletions.
17 changes: 13 additions & 4 deletions packages/widget/src/components/TimeRemaining.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,33 @@ export const TimeRemaining = ({
isComplete,
remainingTime,
isDelayed,
delayedTime,
}: {
isComplete: boolean
remainingTime: number
isDelayed: boolean
delayedTime: number | null
}) => {
if (isComplete) {
return
return <div>Complete!</div>
}

if (isDelayed) {
return <div>Waiting...</div>
const delayedTimeInMin = Math.floor(delayedTime / 60)
const absoluteDelayedTime = Math.abs(delayedTimeInMin)
const showDelayedTime = delayedTimeInMin < -1
return (
<div>
Waiting... {showDelayedTime ? `(${absoluteDelayedTime}m)` : null}
</div>
)
}

const estTime = useMemo(() => {
if (remainingTime > 60) {
return Math.ceil(remainingTime / 60) + ' minutes'
return Math.ceil(remainingTime / 60) + 'm remaining'
} else {
return remainingTime + ' seconds'
return remainingTime + 's remaining'
}
}, [remainingTime])

Expand Down
67 changes: 43 additions & 24 deletions packages/widget/src/components/Transaction.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useEffect, useMemo, useCallback } from 'react'
import { Chain } from 'types'

import { useAppDispatch } from '@/state/hooks'
import { getTxBlockExplorerLink } from '@/utils/getTxBlockExplorerLink'
Expand All @@ -16,9 +17,12 @@ import { useSynapseContext } from '@/providers/SynapseProvider'
import { TimeRemaining } from '@/components/TimeRemaining'
import { DropdownMenu } from '@/components/ui/DropdownMenu'
import { MenuItem } from '@/components/ui/MenuItem'
import { CHAINS_BY_ID } from '@/constants/chains'

export const Transaction = ({
connectedAddress,
originAmount,
originTokenSymbol,
originChainId,
destinationChainId,
originTxHash,
Expand All @@ -30,6 +34,8 @@ export const Transaction = ({
isStoredComplete,
}: {
connectedAddress: string
originAmount: string
originTokenSymbol: string
originChainId: number
destinationChainId: number
originTxHash: string
Expand All @@ -53,12 +59,6 @@ export const Transaction = ({
destinationChainId,
connectedAddress
)
const synapseExplorerLink = getTxSynapseExplorerLink({
originChainId,
destinationChainId,
txHash: originTxHash,
kappa,
})

const elapsedTime: number = currentTime - timestamp // in seconds
const remainingTime: number = estimatedTime - elapsedTime
Expand All @@ -70,6 +70,9 @@ export const Transaction = ({
return currentTime - timestamp > estimatedTime
}, [estimatedTime, currentTime, timestamp])

const delayedTime = isEstimatedTimeReached ? remainingTime : null
const delayedTimeInMin = remainingTime ? Math.floor(remainingTime / 60) : null

const [isTxComplete, _kappa] = useBridgeTxStatus({
synapseSDK,
originChainId,
Expand Down Expand Up @@ -98,14 +101,10 @@ export const Transaction = ({
useEffect(() => {
const txKappa = kappa ?? _kappa

if (isTxComplete && originTxHash && txKappa) {
if (transactions[originTxHash]?.isComplete === false) {
dispatch(
completeTransaction({ originTxHash, kappa: txKappa as string })
)
}
if (!isStoredComplete && isTxComplete && originTxHash && txKappa) {
dispatch(completeTransaction({ originTxHash, kappa: txKappa as string }))
}
}, [isTxComplete, dispatch, transactions])
}, [isStoredComplete, isTxComplete, dispatch, transactions])

const handleClearTransaction = useCallback(() => {
dispatch(removeTransaction({ originTxHash }))
Expand All @@ -120,24 +119,28 @@ export const Transaction = ({
`}
style={{ background: 'var(--synapse-surface' }}
>
{isTxFinalized ? 'Complete' : 'Pending'}
<TransactionBridgeDetail
tokenAmount={originAmount}
originTokenSymbol={originTokenSymbol}
destinationChain={CHAINS_BY_ID[destinationChainId]}
/>
<div className="flex items-center justify-end gap-2 grow">
<TimeRemaining
isComplete={isTxFinalized as boolean}
remainingTime={remainingTime}
isDelayed={isEstimatedTimeReached}
/>

<DropdownMenu>
<DropdownMenu
menuTitleElement={
<TimeRemaining
isComplete={isTxFinalized as boolean}
remainingTime={remainingTime}
isDelayed={isEstimatedTimeReached}
delayedTime={delayedTime}
/>
}
>
{!isNull(originTxExplorerLink) && (
<MenuItem text={originExplorerName} link={originTxExplorerLink} />
)}
{!isNull(destExplorerAddressLink) && (
<MenuItem text={destExplorerName} link={destExplorerAddressLink} />
)}
{/* {!isNull(synapseExplorerLink) && (
<MenuItem text="Synapse Explorer" link={synapseExplorerLink} />
)} */}
<MenuItem
text="Contact Support"
link="https://discord.gg/synapseprotocol"
Expand All @@ -154,3 +157,19 @@ export const Transaction = ({
</div>
)
}

const TransactionBridgeDetail = ({
tokenAmount,
originTokenSymbol,
destinationChain,
}: {
tokenAmount: string
originTokenSymbol: string
destinationChain: Chain
}) => {
return (
<div className="flex">
{tokenAmount} {originTokenSymbol} to {destinationChain.name}
</div>
)
}
2 changes: 2 additions & 0 deletions packages/widget/src/components/Transactions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export const Transactions = ({
return transactions.map((transaction: TransactionDetails) => (
<Transaction
connectedAddress={connectedAddress}
originAmount={transaction.originAmount}
originTokenSymbol={transaction.originTokenSymbol}
originChainId={transaction.originChainId}
destinationChainId={transaction.destinationChainId}
originTxHash={transaction.originTxHash}
Expand Down
2 changes: 2 additions & 0 deletions packages/widget/src/components/Widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ export const Widget = ({
debouncedInputAmount,
originToken?.decimals[originChainId]
),
parsedOriginAmount: debouncedInputAmount,
originTokenSymbol: originToken?.symbol,
originQuery: bridgeQuote?.quotes.originQuery,
destinationQuery: bridgeQuote?.quotes.destQuery,
bridgeModuleName: bridgeQuote?.bridgeModuleName,
Expand Down
11 changes: 5 additions & 6 deletions packages/widget/src/components/ui/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useState } from 'react'

import { DownArrow } from '@/components/icons/DownArrow'

export const DropdownMenu = ({ children }) => {
export const DropdownMenu = ({ menuTitleElement, children }) => {
const [open, setOpen] = useState<boolean>(false)

const handleClick = () => {
Expand All @@ -14,13 +14,12 @@ export const DropdownMenu = ({ children }) => {
<div
onClick={handleClick}
className={`
rounded w-5 h-[21px] flex place-items-center justify-center
border border-solid border-[--synapse-border]
hover:border-[--synapse-focus]
cursor-pointer
flex place-items-center justify-center
px-2 py-1 rounded space-x-2 cursor-pointer
hover:border-[--synapse-focus] hover:bg-[--synapse-select-bg]
`}
style={{ background: 'var(--synapse-select-bg' }}
>
{menuTitleElement}
<DownArrow />
</div>

Expand Down
4 changes: 4 additions & 0 deletions packages/widget/src/hooks/useTransactionListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export const useTransactionListener = () => {
const dispatch = useAppDispatch()
const {
txHash,
originAmount,
originTokenSymbol,
originChainId,
destinationChainId,
bridgeModuleName,
Expand All @@ -25,6 +27,8 @@ export const useTransactionListener = () => {
if (!transactions[txHash]) {
dispatch(
addTransaction({
originAmount,
originTokenSymbol,
originTxHash: txHash,
originChainId,
destinationChainId,
Expand Down
6 changes: 6 additions & 0 deletions packages/widget/src/state/slices/bridgeTransaction/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export const executeBridgeTxn = createAsyncThunk(
destinationChainId,
tokenAddress,
amount,
parsedOriginAmount,
originTokenSymbol,
originQuery,
destinationQuery,
bridgeModuleName,
Expand All @@ -31,6 +33,8 @@ export const executeBridgeTxn = createAsyncThunk(
destinationChainId: number
tokenAddress: string
amount: bigint
parsedOriginAmount: string
originTokenSymbol: string
originQuery: {}
destinationQuery: {}
estimatedTime: number
Expand Down Expand Up @@ -72,6 +76,8 @@ export const executeBridgeTxn = createAsyncThunk(
return {
txHash,
bridgeModuleName,
parsedOriginAmount,
originTokenSymbol,
originChainId,
destinationChainId,
estimatedTime,
Expand Down
10 changes: 10 additions & 0 deletions packages/widget/src/state/slices/bridgeTransaction/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export enum BridgeTransactionStatus {
export interface BridgeTransactionState {
txHash: string
bridgeModuleName: string
originAmount: string
originTokenSymbol: string
originChainId: number
destinationChainId: number
estimatedTime: number
Expand All @@ -23,6 +25,8 @@ export interface BridgeTransactionState {
const initialState: BridgeTransactionState = {
txHash: null,
bridgeModuleName: null,
originAmount: null,
originTokenSymbol: null,
originChainId: null,
destinationChainId: null,
estimatedTime: null,
Expand All @@ -48,6 +52,8 @@ export const bridgeTransactionSlice = createSlice({
payload: {
txHash,
bridgeModuleName,
parsedOriginAmount,
originTokenSymbol,
originChainId,
destinationChainId,
estimatedTime,
Expand All @@ -58,6 +64,8 @@ export const bridgeTransactionSlice = createSlice({
state.bridgeTxnStatus = BridgeTransactionStatus.SUCCESS
state.txHash = txHash
state.bridgeModuleName = bridgeModuleName
state.originAmount = parsedOriginAmount
state.originTokenSymbol = originTokenSymbol
state.originChainId = originChainId
state.destinationChainId = destinationChainId
state.estimatedTime = estimatedTime
Expand All @@ -68,6 +76,8 @@ export const bridgeTransactionSlice = createSlice({
state.error = action.payload
state.txHash = null
state.bridgeModuleName = null
state.originAmount = null
state.originTokenSymbol = null
state.originChainId = null
state.destinationChainId = null
state.estimatedTime = null
Expand Down
2 changes: 2 additions & 0 deletions packages/widget/src/state/slices/transactions/reducer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'

export interface TransactionDetails {
originAmount: string
originTokenSymbol: string
originChainId: number
destinationChainId: number
originTxHash: string
Expand Down

0 comments on commit f155ea4

Please sign in to comment.