Skip to content

Commit 0539da2

Browse files
authored
Feat/transaction success dialog (#1792)
* initial success dialog changes * reset kubb to prod * fix build errors use preview * remove unused chainId * return new response for status code * original tx confirmation turned off on leverage * add emojis * revamp netbalance fetching * change modal title to only show if theres a value * revert to production api in kubb * use render url, seems like index one is cached * add proper entry price and remove border * keep the original failed transaction window * fix linting * dont show review if navigating away * show loading modal too upon mobile as well * remove unnecessary array fallback in usebalances * dont allow closing the modal if the recent trade is in pending state * fix state popping * state machine trade modal handling * handle non-leverage token successful trades * fix transaction modal loader lightmode * revert loading skeleton changes * remove trade-atom * remove TradeMachineStates * fix missig quote reference * reset data if we get back to idle * reset state before closing * reset context tweaks * remove the death on loss * light ic-gray400 on tradeload * remove long15x * disable user zoom * lint fix * add overflow hidden to light effect wrap * use api changes that return position immediately * reset api to prod in kubb * mitigate clientside exception on history being undefined * reset position too in case of closing the modal
1 parent 449486d commit 0539da2

File tree

33 files changed

+869
-458
lines changed

33 files changed

+869
-458
lines changed

package-lock.json

Lines changed: 23 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"framer-motion": "11.2.6",
5252
"jotai": "2.12.0",
5353
"jotai-utils": "0.0.0",
54+
"jotai-xstate": "0.6.1",
5455
"lodash": "4.17.21",
5556
"next": "14.2.13",
5657
"react": "^18.2.0",
@@ -59,6 +60,7 @@
5960
"react-loading-skeleton": "3.5.0",
6061
"tailwind-merge": "2.5.2",
6162
"use-debounce": "^10.0.1",
63+
"xstate": "5.19.2",
6264
"viem": "2.23.6",
6365
"wagmi": "2.14.12"
6466
},

src/app/api/leverage/history/route.ts

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import mapKeys from 'lodash/mapKeys'
88
import { NextRequest, NextResponse } from 'next/server'
99
import { Address } from 'viem'
1010

11+
import { calculateAverageEntryPrice } from '@/app/leverage/utils/fetch-leverage-token-prices'
1112
import {
1213
GetApiV2UserAddressPositionsQueryParamsChainIdEnum as ApiChainId,
1314
getApiV2UserAddressPositions,
14-
GetApiV2UserAddressPositions200,
1515
} from '@/gen'
1616

1717
type TokenTransferRequest = {
@@ -53,44 +53,6 @@ const mapCoingeckoIdToSymbol = (id: string) => {
5353
}
5454
}
5555

56-
const calculateAverageEntryPrice = (
57-
positions: GetApiV2UserAddressPositions200,
58-
) => {
59-
const grouped = positions.reduce(
60-
(acc, position) => {
61-
if (
62-
position.trade &&
63-
position.metrics &&
64-
position.trade.transactionType === 'buy'
65-
) {
66-
const tokenAddress = position.metrics.tokenAddress
67-
68-
if (!acc[tokenAddress]) {
69-
acc[tokenAddress] = { sum: 0, count: 0 }
70-
}
71-
72-
acc[tokenAddress].sum +=
73-
(position.trade.underlyingAssetUnitPrice ?? 0) *
74-
(position.metrics.totalPurchaseSize ?? 0)
75-
acc[tokenAddress].count += position.metrics.totalPurchaseSize ?? 0
76-
}
77-
return acc
78-
},
79-
{} as Record<string, { sum: number; count: number }>,
80-
)
81-
82-
const averages = Object.keys(grouped).reduce(
83-
(acc, tokenAddress) => {
84-
acc[tokenAddress] =
85-
grouped[tokenAddress].sum / grouped[tokenAddress].count
86-
return acc
87-
},
88-
{} as Record<string, number>,
89-
)
90-
91-
return averages
92-
}
93-
9456
export async function POST(req: NextRequest) {
9557
try {
9658
const { user, chainId } = (await req.json()) as TokenTransferRequest

src/app/api/user/trade/route.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { NextRequest, NextResponse } from 'next/server'
1+
import { NextRequest } from 'next/server'
22

33
import {
44
postApiV2Trade,
@@ -10,18 +10,21 @@ export async function POST(req: NextRequest) {
1010
const trade: PostApiV2TradeMutationRequest = await req.json()
1111

1212
if (!trade) {
13-
return NextResponse.json(
14-
{ error: 'Bad Request: Missing Parameters.' },
13+
return new Response(
14+
JSON.stringify({ error: 'Bad Request: Missing Parameters.' }),
1515
{ status: 400 },
1616
)
1717
}
1818

1919
try {
2020
const res = await postApiV2Trade(trade)
21-
return NextResponse.json(res.data, { status: res.status })
21+
22+
return new Response(JSON.stringify(res.data), { status: res.status })
2223
} catch (e) {
23-
return NextResponse.json(
24-
{ error: (e as PostApiV2TradeMutation['Errors']).message },
24+
return new Response(
25+
JSON.stringify({
26+
error: (e as PostApiV2TradeMutation['Errors']).message,
27+
}),
2528
{ status: 500 },
2629
)
2730
}

src/app/earn/components/earn-widget/index.tsx

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
'use client'
22

3+
import { useAtom } from 'jotai'
34
import { useCallback, useEffect } from 'react'
45

56
import { Summary } from '@/app/earn/components/earn-widget/components/summary'
67
import { supportedNetworks } from '@/app/earn/constants'
78
import { useEarnContext } from '@/app/earn/provider'
89
import { useQueryParams } from '@/app/earn/use-query-params'
10+
import { tradeMachineAtom } from '@/app/store/trade-machine'
911
import { Receive } from '@/components/receive'
1012
import { BuySellSelector } from '@/components/selectors/buy-sell-selector'
1113
import { Settings } from '@/components/settings'
@@ -43,7 +45,6 @@ export function EarnWidget() {
4345
inputValue,
4446
isMinting,
4547
outputTokens,
46-
transactionReview,
4748
onChangeInputTokenAmount,
4849
onSelectInputToken,
4950
onSelectOutputToken,
@@ -73,11 +74,8 @@ export function EarnWidget() {
7374
onOpen: onOpenSelectOutputToken,
7475
onClose: onCloseSelectOutputToken,
7576
} = useDisclosure()
76-
const {
77-
isOpen: isTransactionReviewOpen,
78-
onOpen: onOpenTransactionReview,
79-
onClose: onCloseTransactionReview,
80-
} = useDisclosure()
77+
78+
const [tradeState, sendTradeEvent] = useAtom(tradeMachineAtom)
8179

8280
const {
8381
auto: autoSlippage,
@@ -97,6 +95,14 @@ export function EarnWidget() {
9795
setSlippageForToken(isMinting ? outputToken.symbol : inputToken.symbol)
9896
}, [inputToken, isMinting, outputToken, setSlippageForToken])
9997

98+
useEffect(() => {
99+
if (tradeState.matches('reset')) {
100+
reset()
101+
resetData()
102+
sendTradeEvent({ type: 'RESET_DONE' })
103+
}
104+
}, [tradeState, reset, resetData, sendTradeEvent])
105+
100106
return (
101107
<div className='earn-widget flex h-fit flex-col gap-3 rounded-lg px-4 py-6 lg:ml-auto'>
102108
<div className='flex justify-between'>
@@ -143,7 +149,7 @@ export function EarnWidget() {
143149
buttonLabelOverrides={{
144150
[TradeButtonState.default]: 'Review Transaction',
145151
}}
146-
onOpenTransactionReview={onOpenTransactionReview}
152+
onOpenTransactionReview={() => sendTradeEvent({ type: 'REVIEW' })}
147153
onRefetchQuote={() => {}}
148154
/>
149155
<SelectTokenModal
@@ -168,17 +174,13 @@ export function EarnWidget() {
168174
tokens={outputTokens}
169175
showNetworks={isMinting}
170176
/>
171-
{transactionReview && (
172-
<TransactionReviewModal
173-
isOpen={isTransactionReviewOpen}
174-
onClose={() => {
175-
reset()
176-
resetData()
177-
onCloseTransactionReview()
178-
}}
179-
transactionReview={transactionReview}
180-
/>
181-
)}
177+
<TransactionReviewModal
178+
onClose={() => {
179+
reset()
180+
resetData()
181+
sendTradeEvent({ type: 'CLOSE' })
182+
}}
183+
/>
182184
</div>
183185
)
184186
}

src/app/earn/provider.tsx

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,10 @@ import { isAddress } from 'viem'
1313
import { base } from 'viem/chains'
1414

1515
import { useQueryParams } from '@/app/earn/use-query-params'
16-
import { TransactionReview } from '@/components/swap/components/transaction-review/types'
1716
import { ETH, Token } from '@/constants/tokens'
1817
import { TokenBalance, useBalances } from '@/lib/hooks/use-balance'
1918
import { QuoteResult } from '@/lib/hooks/use-best-quote/types'
2019
import { useNetwork } from '@/lib/hooks/use-network'
21-
import { usePrepareTransactionReview } from '@/lib/hooks/use-prepare-transaction-review'
2220
import { useQuoteResult } from '@/lib/hooks/use-quote-result'
2321
import { useWallet } from '@/lib/hooks/use-wallet'
2422
import { useSlippage } from '@/lib/providers/slippage'
@@ -54,7 +52,6 @@ interface Context {
5452
isFetchingQuote: boolean
5553
isFetchingStats: boolean
5654
quoteResult: QuoteResult | null
57-
transactionReview: TransactionReview | null
5855
onChangeInputTokenAmount: (input: string) => void
5956
onSelectIndexToken: (tokenSymbol: string, chainId: number) => void
6057
onSelectInputToken: (tokenSymbol: string, chainId: number) => void
@@ -82,7 +79,6 @@ export const EarnContext = createContext<Context>({
8279
isFetchingQuote: false,
8380
isFetchingStats: true,
8481
quoteResult: null,
85-
transactionReview: null,
8682
onChangeInputTokenAmount: () => {},
8783
onSelectIndexToken: () => {},
8884
onSelectInputToken: () => {},
@@ -168,10 +164,6 @@ export function EarnProvider(props: { children: any }) {
168164
inputValue,
169165
slippage,
170166
})
171-
const transactionReview = usePrepareTransactionReview(
172-
isFetchingQuote,
173-
quoteResult,
174-
)
175167

176168
const {
177169
data: { apy, nav, tvl },
@@ -329,7 +321,6 @@ export function EarnProvider(props: { children: any }) {
329321
isFetchingQuote,
330322
isFetchingStats: isFetchingLatestStats || isFetchingApyStats,
331323
quoteResult,
332-
transactionReview,
333324
onChangeInputTokenAmount,
334325
onSelectIndexToken,
335326
onSelectInputToken,

src/app/layout.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Viewport } from 'next'
2+
13
import { MavaScript } from '@/components/external/mava-script'
24
import { SafaryScript } from '@/components/external/safary-script'
35
import './globals.css'
@@ -14,7 +16,8 @@ export const metadata = {
1416
type: 'website',
1517
}
1618

17-
export const viewport = {
19+
export const viewport: Viewport = {
20+
userScalable: false,
1821
themeColor: '#000000',
1922
}
2023

0 commit comments

Comments
 (0)