11"use client" ;
22
3- import { useState } from "react" ;
3+ import { useCallback , useState } from "react" ;
44import type { Buy , Sell } from "../../../../../bridge/index.js" ;
55import type { TokenWithPrices } from "../../../../../bridge/types/Token.js" ;
66import type { ThirdwebClient } from "../../../../../client/client.js" ;
@@ -12,11 +12,14 @@ import type {
1212 BridgePrepareRequest ,
1313 BridgePrepareResult ,
1414} from "../../../../core/hooks/useBridgePrepare.js" ;
15+ import type { CompletedStatusResult } from "../../../../core/hooks/useStepExecutor.js" ;
1516import { webWindowAdapter } from "../../../adapters/WindowAdapter.js" ;
1617import { EmbedContainer } from "../../ConnectWallet/Modal/ConnectEmbed.js" ;
1718import { DynamicHeight } from "../../components/DynamicHeight.js" ;
1819import type { LocaleId } from "../../types.js" ;
20+ import { ErrorBanner } from "../ErrorBanner.js" ;
1921import { PaymentDetails } from "../payment-details/PaymentDetails.js" ;
22+ import { SuccessScreen } from "../payment-success/SuccessScreen.js" ;
2023import { QuoteLoader } from "../QuoteLoader.js" ;
2124import { StepRunner } from "../StepRunner.js" ;
2225import { useActiveWalletInfo } from "./hooks.js" ;
@@ -102,6 +105,17 @@ type SwapWidgetScreen =
102105 preparedQuote : BridgePrepareResult ;
103106 buyToken : TokenWithPrices ;
104107 sellToken : TokenWithPrices ;
108+ }
109+ | {
110+ id : "5:success" ;
111+ completedStatuses : CompletedStatusResult [ ] ;
112+ preparedQuote : BridgePrepareResult ;
113+ buyToken : TokenWithPrices ;
114+ sellToken : TokenWithPrices ;
115+ }
116+ | {
117+ id : "error" ;
118+ error : Error ;
105119 } ;
106120
107121function SwapWidgetContent ( props : SwapWidgetProps ) {
@@ -111,6 +125,18 @@ function SwapWidgetContent(props: SwapWidgetProps) {
111125 // preload requests
112126 useBridgeChains ( props . client ) ;
113127
128+ const handleError = useCallback (
129+ ( error : Error ) => {
130+ console . error ( error ) ;
131+ props . onError ?.( error ) ;
132+ setScreen ( {
133+ id : "error" ,
134+ error,
135+ } ) ;
136+ } ,
137+ [ props . onError ] ,
138+ ) ;
139+
114140 // if wallet suddenly disconnects, show screen 1
115141 if ( screen . id === "1:swap-ui" || ! activeWalletInfo ) {
116142 return (
@@ -138,17 +164,14 @@ function SwapWidgetContent(props: SwapWidgetProps) {
138164 screen . quote . destinationAmount ,
139165 screen . buyToken . decimals ,
140166 ) }
141- onError = { ( ) => {
142- // TODO
143- } }
167+ onError = { handleError }
144168 onQuoteReceived = { ( preparedQuote , request ) => {
145169 setScreen ( {
146170 ...screen ,
147171 id : "3:preview" ,
148172 preparedQuote,
149173 request,
150174 } ) ;
151- // TODO
152175 } }
153176 receiver = { activeWalletInfo . activeAccount . address }
154177 onBack = { ( ) => setScreen ( { id : "1:swap-ui" } ) }
@@ -183,9 +206,7 @@ function SwapWidgetContent(props: SwapWidgetProps) {
183206 id : "4:execute" ,
184207 } ) ;
185208 } }
186- onError = { ( _error ) => {
187- // TODO
188- } }
209+ onError = { handleError }
189210 paymentMethod = { {
190211 quote : screen . quote ,
191212 type : "wallet" ,
@@ -214,11 +235,13 @@ function SwapWidgetContent(props: SwapWidgetProps) {
214235 id : "3:preview" ,
215236 } ) ;
216237 } }
217- onCancel = { ( ) => {
218- // TODO
219- } }
220- onComplete = { ( ) => {
221- // TODO
238+ onCancel = { props . onCancel }
239+ onComplete = { ( completedStatuses ) => {
240+ setScreen ( {
241+ ...screen ,
242+ id : "5:success" ,
243+ completedStatuses,
244+ } ) ;
222245 } }
223246 request = { screen . request }
224247 wallet = { activeWalletInfo . activeWallet }
@@ -227,5 +250,39 @@ function SwapWidgetContent(props: SwapWidgetProps) {
227250 ) ;
228251 }
229252
253+ if ( screen . id === "5:success" ) {
254+ return (
255+ < SuccessScreen
256+ client = { props . client }
257+ completedStatuses = { screen . completedStatuses }
258+ onDone = { ( ) => {
259+ setScreen ( { id : "1:swap-ui" } ) ;
260+ } }
261+ preparedQuote = { screen . preparedQuote }
262+ uiOptions = { {
263+ destinationToken : screen . buyToken ,
264+ mode : "fund_wallet" ,
265+ currency : props . currency ,
266+ } }
267+ windowAdapter = { webWindowAdapter }
268+ hasPaymentId = { false } // TODO Question: Do we need to expose this as prop?
269+ />
270+ ) ;
271+ }
272+
273+ if ( screen . id === "error" ) {
274+ < ErrorBanner
275+ client = { props . client }
276+ error = { screen . error }
277+ onCancel = { ( ) => {
278+ setScreen ( { id : "1:swap-ui" } ) ;
279+ props . onCancel ?.( ) ;
280+ } }
281+ onRetry = { ( ) => {
282+ setScreen ( { id : "1:swap-ui" } ) ;
283+ } }
284+ /> ;
285+ }
286+
230287 return null ;
231288}
0 commit comments