Skip to content

Commit

Permalink
Merge pull request #201 from lc-labs/fix/improve-zapper-UX
Browse files Browse the repository at this point in the history
Fix/improve zapper ux
  • Loading branch information
lcamargof authored Oct 6, 2023
2 parents b23a5c5 + bd0acb6 commit 49717e5
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 27 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@popperjs/core": "^2.11.5",
"@rainbow-me/rainbowkit": "1.0.11",
"@react-spring/web": "^9.7.1",
"@reserve-protocol/token-zapper": "2.5.2",
"@reserve-protocol/token-zapper": "2.5.3",
"@uiw/react-md-editor": "^3.20.5",
"@uniswap/permit2-sdk": "^1.2.0",
"@viem/anvil": "^0.0.6",
Expand Down
16 changes: 15 additions & 1 deletion src/views/issuance/components/zap/components/ZapButton.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import { LoadingButton, LoadingButtonProps } from 'components/button'
import { useAtom } from 'jotai'
import { useAtom, useAtomValue } from 'jotai'
import { ui } from '../state/ui-atoms'
import { previousZapTransaction, zapTransaction } from '../state/atoms'
import { useEffect } from 'react'

const ZapButton = (props: Partial<LoadingButtonProps>) => {
const tx = useAtomValue(zapTransaction)
const [, setPrevious] = useAtom(previousZapTransaction)
const ttx = tx.state === "hasData" ? tx.data : null
useEffect(() => {

if (ttx != null) {
console.log("Setting previous")
setPrevious(ttx)
}

}, [ttx])

const [{ loading, enabled, label, loadingLabel }, onClick] = useAtom(
ui.button
)
Expand Down
15 changes: 10 additions & 5 deletions src/views/issuance/components/zap/components/ZapInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ import { rTokenStateAtom } from 'state/atoms'
import { Box, Checkbox, Flex, Text } from 'theme-ui'
import {
collectDust,
previousZapTransaction,
selectedZapTokenAtom,
zapInputString,
} from '../state/atoms'
import { ui, zapDust, zapDustValue } from '../state/ui-atoms'
import { formatQty, FOUR_DIGITS, TWO_DIGITS } from '../state/formatTokenQuantity'
import {
formatQty,
FOUR_DIGITS,
TWO_DIGITS,
} from '../state/formatTokenQuantity'
import { zapperLoaded } from '../state/zapper'
import { Suspense } from 'react'

Expand All @@ -23,7 +28,7 @@ const ZapDust = () => {
return null
}
const total = dustValue.total

let str = '+ ' + formatQty(total, TWO_DIGITS) + ' in dust'
if (total.amount < 10000n) {
str = '*'
Expand All @@ -36,9 +41,7 @@ const ZapDust = () => {
<span
title={
'Dust generated:\n' +
dust
.map((i) => formatQty(i, FOUR_DIGITS))
.join('\n') +
dust.map((i) => formatQty(i, FOUR_DIGITS)).join('\n') +
(zapCollectDust
? '\n\nDust will be returned to your wallet'
: '\n\nDust will not be returned to your wallet')
Expand Down Expand Up @@ -98,10 +101,12 @@ const ZapOutputLabel = () => {
}
const ZapCollectDust = () => {
const [checked, setChecked] = useAtom(collectDust)
const [, setPrevious] = useAtom(previousZapTransaction)
return (
<Flex
onClick={() => {
setChecked(!checked)
setPrevious(null)
}}
ml={3}
mt={2}
Expand Down
2 changes: 0 additions & 2 deletions src/views/issuance/components/zap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import ZapButton from './components/ZapButton'
import ZapInput from './components/ZapInput'
import { selectedZapTokenAtom } from './state/atoms'
import { resolvedZapState } from './state/zapper'
import { useWalletClient } from 'wagmi'

const UpdateBlockAndGas = () => {
const zapState = useAtomValue(resolvedZapState)
Expand All @@ -28,7 +27,6 @@ const UpdateBlockAndGas = () => {
* Zap widget
*/
const Zap = () => {
const enableZapper = useWalletClient().data?.account != null
const [isZapping, setZapping] = useState(false)
const rToken = useRToken()
const selectedToken = useAtomValue(selectedZapTokenAtom)
Expand Down
12 changes: 12 additions & 0 deletions src/views/issuance/components/zap/state/atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import {
} from 'utils/atoms/utils'

import { resolvedZapState, zappableTokens } from './zapper'
import { type SearcherResult } from '@reserve-protocol/token-zapper/types/searcher/SearcherResult'
import { type ZapTransaction } from '@reserve-protocol/token-zapper/types/searcher/ZapTransaction'

/**
* I've tried to keep react effects to a minimum so most async code is triggered via some signal
Expand All @@ -41,18 +43,28 @@ import { resolvedZapState, zappableTokens } from './zapper'
* view/controller.
*/

export const previousZapTransaction = atom<{
result: SearcherResult,
transaction: ZapTransaction,
permit2?: {
permit: PermitTransferFrom,
signature: string
}
} | null>(null)
// The only actual state the user controls:
export const tokenToZapPopupState = atom(false)
export const collectDust = atom(true)
export const zapInputString = atomWithOnWrite('', (_, set, __) => {
set(permitSignature, null)
set(previousZapTransaction, null)
})
export const tokenToZapUserSelected = atomWithOnWrite(
null as Token | null,
(_, set, prev, next) => {
if (prev !== next) {
set(zapInputString, '')
set(tokenToZapPopupState, false)
set(previousZapTransaction, null)
}
}
)
Expand Down
43 changes: 29 additions & 14 deletions src/views/issuance/components/zap/state/ui-atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
zapTransaction,
zapTransactionGasEstimateUnits,
zapTxHash,
previousZapTransaction,
} from './atoms'
import { formatQty, FOUR_DIGITS } from './formatTokenQuantity'
import { resolvedZapState, zappableTokens, zapperState } from './zapper'
Expand Down Expand Up @@ -111,26 +112,29 @@ export const zapTransactionFeeDisplay = onlyNonNullAtom((get) => {
)
})

export const zapOutputAmount = onlyNonNullAtom((get) => {
const quote = get(zapQuote)
const rTokenOut = get(zapperInputs).rToken

export const zapOutputAmount = atom((get) => {
const previous = get(previousZapTransaction)
const quote = get(zapQuote) ?? previous?.result
const rTokenOut = quote?.outputToken
if (quote == null||rTokenOut==null) {
return '0.0'
}
return formatQty(
quote.swaps.outputs.find((r) => r.token == rTokenOut) ?? rTokenOut.zero,
quote.swaps.outputs.find((r) => r.token === rTokenOut) ?? rTokenOut.zero,
FOUR_DIGITS
)
}, '0.0')
})

export const zapDust = atom((get) => {
const quote = get(zapQuote)
const tx = get(previousZapTransaction)
const quote = tx?.result ?? get(zapQuote)
if (quote == null) {
return []
}
const tx = get(resolvedZapTransaction)

const rTokenOut = get(zapperInputs)?.rToken
const rTokenOut = quote.outputToken

const dust = (tx?.result.swaps.outputs ?? quote.swaps.outputs).filter(i => i.token !== rTokenOut && i.amount !== 0n)
const dust = quote.swaps.outputs.filter(i => i.token !== rTokenOut && i.amount !== 0n)
return dust
})

Expand All @@ -139,7 +143,8 @@ export const zapDustValue = atom(async (get) => {
if (dust == null) {
return null
}
const quote = get(zapQuote)
const tx = get(previousZapTransaction)
const quote = tx?.result ?? get(zapQuote)
if (quote == null) {
return null
}
Expand Down Expand Up @@ -167,9 +172,11 @@ export const zapOutputValue = onlyNonNullAtom((get) => {
return qty.format()
}, '0')


const state = atom((get) => {
const quotePromise = get(zapQuotePromise)
const approvePromise = get(approvalNeededAtom)
const prev = get(previousZapTransaction)
const tx = get(zapTransaction)
const units = get(zapTransactionGasEstimateUnits)
const balances = get(hasSufficientGasTokenAndERC20TokenBalance)
Expand Down Expand Up @@ -236,7 +243,7 @@ const loadingStates = new Set<UIState>([
// 'approval_sent_loading',
'signature_loading',
])
const buttonEnabled = atom((get) => buttonEnabledStates.has(get(state)))
const buttonEnabled = atom((get) => buttonEnabledStates.has(get(state)) || get(previousZapTransaction) != null)
const buttonIsLoading = atom((get) => loadingStates.has(get(state)))
const buttonLabel = atom((get) => {
if (get(zapSender) == null) {
Expand All @@ -247,6 +254,10 @@ const buttonLabel = atom((get) => {
return '+ Zap'
}

if (get(previousZapTransaction) != null) {
return `+ Mint ${loadedState.rToken.symbol}`
}

switch (get(state)) {
case 'insufficient_gas_balance':
return 'Insufficient ETH balance'
Expand Down Expand Up @@ -340,6 +351,9 @@ export const ui = {
textBox: atom((get) => {
const zapPromise = get(zapQuotePromise)
const output = get(zapOutputAmount)
if (get(previousZapTransaction) != null) {
return output ?? '0.0'
}
if (zapPromise.state === 'hasData' && zapPromise.data == null) {
return ''
}
Expand All @@ -359,8 +373,8 @@ export const ui = {
button: atom(
(get) => ({
loadingLabel: get(buttonLoadingLabel),
enabled: get(zapSender) == null || get(buttonEnabled),
loading: get(buttonIsLoading),
enabled: (get(zapSender) == null || get(buttonEnabled)),
loading: get(previousZapTransaction) == null && get(buttonIsLoading),
label: get(buttonLabel),
}),
async (get, set, _) => {
Expand All @@ -369,6 +383,7 @@ export const ui = {
}
const flowState = get(state)
const data = getZapActionState(get)

if (data == null) {
return
}
Expand Down

0 comments on commit 49717e5

Please sign in to comment.