Skip to content

Commit

Permalink
feat: WT-2054 Add Loading, Success and Failure screens for transaction (
Browse files Browse the repository at this point in the history
  • Loading branch information
sharonsheah authored Feb 1, 2024
1 parent 39334fb commit 0195845
Show file tree
Hide file tree
Showing 13 changed files with 317 additions and 13 deletions.
26 changes: 26 additions & 0 deletions packages/checkout/sdk/src/widgets/definitions/events/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export enum BridgeEventType {
FAILURE = 'failure',
TRANSACTION_SENT = 'transaction-sent',
LANGUAGE_CHANGED = 'language-changed',
CLAIM_WITHDRAWAL_SUCCESS = 'claim-withdrawal-success',
CLAIM_WITHDRAWAL_FAILURE = 'claim-withdrawal-failure',
}

/**
Expand All @@ -28,3 +30,27 @@ export type BridgeFailed = {
/** The timestamp of the failed transaction. */
timestamp: number;
};

/**
* Represents a successful bridge claim withdrawal.
* @property {string} transactionHash
*/
export type BridgeClaimWithdrawalSuccess = {
/** The hash of the successful transaction. */
transactionHash: string;
};

/**
* Represents a failed bridge claim withdrawal.
* @property {string} transactionHash
* @property {string} reason
* @property {number} timestamp
*/
export type BridgeClaimWithdrawalFailed = {
/** The hash of the failed transaction. */
transactionHash: string;
/** The reason for the failed transaction. */
reason: string;
/** The timestamp of the failed transaction. */
timestamp: number;
};
4 changes: 4 additions & 0 deletions packages/checkout/sdk/src/widgets/definitions/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Environment } from '@imtbl/config';
import { Web3Provider } from '@ethersproject/providers';
import {
BridgeClaimWithdrawalFailed,
BridgeClaimWithdrawalSuccess,
BridgeEventType,
BridgeFailed,
BridgeTransactionSent,
Expand Down Expand Up @@ -142,6 +144,8 @@ export type WidgetEventData = {
[BridgeEventType.TRANSACTION_SENT]: BridgeTransactionSent,
[BridgeEventType.FAILURE]: BridgeFailed,
[BridgeEventType.CLOSE_WIDGET]: {}
[BridgeEventType.CLAIM_WITHDRAWAL_SUCCESS]: BridgeClaimWithdrawalSuccess
[BridgeEventType.CLAIM_WITHDRAWAL_FAILURE]: BridgeClaimWithdrawalFailed
} & OrchestrationMapping & ProviderEventMapping,

[WidgetType.ONRAMP]: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { TransactionResponse } from '@ethersproject/providers';
import { useContext, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { UserJourney, useAnalytics } from 'context/analytics-provider/SegmentAnalyticsProvider';
import { ViewActions, ViewContext } from 'context/view-context/ViewContext';
import { BridgeWidgetViews } from 'context/view-context/BridgeViewContextTypes';
import { LoadingView } from 'views/loading/LoadingView';

interface ClaimWithdrawalInProgressProps {
transactionResponse: TransactionResponse;
}

export function ClaimWithdrawalInProgress({ transactionResponse }: ClaimWithdrawalInProgressProps) {
const { t } = useTranslation();
const { viewDispatch } = useContext(ViewContext);

const { page } = useAnalytics();

useEffect(() => {
page({
userJourney: UserJourney.BRIDGE,
screen: 'ClaimWithdrawalInProgress',
});
}, []);

useEffect(() => {
if (!transactionResponse) return;

(async () => {
try {
const receipt = await transactionResponse.wait();

if (receipt.status === 1) {
viewDispatch({
payload: {
type: ViewActions.UPDATE_VIEW,
view: {
type: BridgeWidgetViews.CLAIM_WITHDRAWAL_SUCCESS,
transactionHash: receipt.transactionHash,
},
},
});
return;
}

viewDispatch({
payload: {
type: ViewActions.UPDATE_VIEW,
view: {
type: BridgeWidgetViews.CLAIM_WITHDRAWAL_FAILURE,
transactionHash: receipt.transactionHash,
reason: 'Transaction failed',
},
},
});
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
viewDispatch({
payload: {
type: ViewActions.UPDATE_VIEW,
view: {
type: BridgeWidgetViews.CLAIM_WITHDRAWAL_FAILURE,
transactionHash: '',
reason: 'Transaction failed',
},
},
});
}
})();
}, [transactionResponse]);

return <LoadingView loadingText={t('views.CLAIM_WITHDRAWAL.IN_PROGRESS.loading.text')} showFooterLogo />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ import { KnownNetworkMap } from './transactionsType';
import { TransactionList } from './TransactionList';
import { NoTransactions } from './NoTransactions';

export function Transactions() {
type TransactionsProps = {
onBackButtonClick: () => void;
};

export function Transactions({ onBackButtonClick }: TransactionsProps) {
const { eventTargetState: { eventTarget } } = useContext(EventTargetContext);

const { cryptoFiatDispatch } = useContext(CryptoFiatContext);
Expand Down Expand Up @@ -292,6 +296,7 @@ export function Transactions() {
header={(
<HeaderNavigation
showBack
onBackButtonClick={onBackButtonClick}
title={t('views.TRANSACTIONS.layoutHeading')}
onCloseButtonClick={() => sendBridgeWidgetCloseEvent(eventTarget)}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ApproveBridgeResponse, BridgeTxResponse } from '@imtbl/bridge-sdk';
import { TransactionResponse } from '@ethersproject/providers';
import { Transaction } from 'lib/clients';
import { ViewType } from './ViewType';

Expand All @@ -11,6 +12,9 @@ export enum BridgeWidgetViews {
APPROVE_TRANSACTION = 'APPROVE_TRANSACTION',
TRANSACTIONS = 'TRANSACTIONS',
CLAIM_WITHDRAWAL = 'CLAIM_WITHDRAWAL',
CLAIM_WITHDRAWAL_IN_PROGRESS = 'CLAIM_WITHDRAWAL_IN_PROGRESS',
CLAIM_WITHDRAWAL_SUCCESS = 'CLAIM_WITHDRAWAL_SUCCESS',
CLAIM_WITHDRAWAL_FAILURE = 'CLAIM_WITHDRAWAL_FAILURE',
}

export type BridgeWidgetView =
Expand All @@ -21,7 +25,10 @@ export type BridgeWidgetView =
| BridgeFailure
| BridgeApproveTransaction
| BridgeTransactions
| BridgeClaimWithdrawal;
| BridgeClaimWithdrawal
| BridgeClaimWithdrawalInProgress
| BridgeClaimWithdrawalSuccess
| BridgeClaimWithdrawalFailure;

interface BridgeCrossWalletSelection extends ViewType {
type: BridgeWidgetViews.WALLET_NETWORK_SELECTION,
Expand Down Expand Up @@ -59,3 +66,19 @@ interface BridgeClaimWithdrawal extends ViewType {
type: BridgeWidgetViews.CLAIM_WITHDRAWAL,
transaction: Transaction
}

interface BridgeClaimWithdrawalInProgress extends ViewType {
type: BridgeWidgetViews.CLAIM_WITHDRAWAL_IN_PROGRESS,
transactionResponse: TransactionResponse;
}

export interface BridgeClaimWithdrawalSuccess extends ViewType {
type: BridgeWidgetViews.CLAIM_WITHDRAWAL_SUCCESS,
transactionHash: string;
}

export interface BridgeClaimWithdrawalFailure extends ViewType {
type: BridgeWidgetViews.CLAIM_WITHDRAWAL_FAILURE,
transactionHash: string;
reason: string;
}
13 changes: 13 additions & 0 deletions packages/checkout/widgets-lib/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,19 @@
"footer": {
"buttonText": "Continue",
"retryText": "Try again"
},
"IN_PROGRESS": {
"loading": {
"text": "Processing"
},
"success": {
"text": "Success",
"actionText": "Done"
},
"failure": {
"text": "Transaction failed",
"actionText": "Try again"
}
}
}
},
Expand Down
13 changes: 13 additions & 0 deletions packages/checkout/widgets-lib/src/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,19 @@
"footer": {
"buttonText": "続行",
"retryText": "もう一度試す"
},
"IN_PROGRESS": {
"loading": {
"text": "処理中"
},
"success": {
"text": "成功",
"actionText": "完了"
},
"failure": {
"text": "取引失敗",
"actionText": "再試行"
}
}
}
},
Expand Down
13 changes: 13 additions & 0 deletions packages/checkout/widgets-lib/src/locales/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,19 @@
"footer": {
"buttonText": "계속",
"retryText": "다시 시도"
},
"IN_PROGRESS": {
"loading": {
"text": "처리 중"
},
"success": {
"text": "성공",
"actionText": "완료"
},
"failure": {
"text": "거래 실패",
"actionText": "다시 시도"
}
}
}
},
Expand Down
13 changes: 13 additions & 0 deletions packages/checkout/widgets-lib/src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,19 @@
"footer": {
"buttonText": "继续",
"retryText": "重试"
},
"IN_PROGRESS": {
"loading": {
"text": "处理中"
},
"success": {
"text": "成功",
"actionText": "完成"
},
"failure": {
"text": "交易失败",
"actionText": "请重试"
}
}
}
},
Expand Down
78 changes: 75 additions & 3 deletions packages/checkout/widgets-lib/src/widgets/bridge/BridgeWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { StrongCheckoutWidgetsConfig } from 'lib/withDefaultWidgetConfig';
import { CryptoFiatProvider } from 'context/crypto-fiat-context/CryptoFiatProvider';
import { JsonRpcProvider, Web3Provider } from '@ethersproject/providers';
import { BridgeWidgetViews } from 'context/view-context/BridgeViewContextTypes';
import { BridgeClaimWithdrawalFailure, BridgeWidgetViews } from 'context/view-context/BridgeViewContextTypes';
import { StatusView } from 'components/Status/StatusView';
import { StatusType } from 'components/Status/StatusType';
import { ImmutableConfiguration } from '@imtbl/config';
Expand All @@ -29,6 +29,7 @@ import { Transactions } from 'components/Transactions/Transactions';
import { UserJourney, useAnalytics } from 'context/analytics-provider/SegmentAnalyticsProvider';
import { TopUpView } from 'views/top-up/TopUpView';
import { useTranslation } from 'react-i18next';
import { ClaimWithdrawalInProgress } from 'components/Transactions/ClaimWithdrawalInProgress';
import {
ViewActions,
ViewContext,
Expand All @@ -49,7 +50,15 @@ import { MoveInProgress } from './views/MoveInProgress';
import { ApproveTransaction } from './views/ApproveTransaction';
import { ErrorView } from '../../views/error/ErrorView';
import { EventTargetContext } from '../../context/event-target-context/EventTargetContext';
import { sendBridgeFailedEvent, sendBridgeWidgetCloseEvent } from './BridgeWidgetEvents';
import {
sendBridgeClaimWithdrawalFailedEvent,
sendBridgeClaimWithdrawalSuccessEvent,
sendBridgeFailedEvent,
sendBridgeWidgetCloseEvent,
} from './BridgeWidgetEvents';
import {
BridgeClaimWithdrawalSuccess,
} from '../../context/view-context/BridgeViewContextTypes';
import { ClaimWithdrawal } from './views/ClaimWithdrawal';

export type BridgeWidgetInputs = BridgeWidgetParams & {
Expand Down Expand Up @@ -215,7 +224,7 @@ export function BridgeWidget({
/>
)}
{viewState.view.type === BridgeWidgetViews.TRANSACTIONS && (
<Transactions />
<Transactions onBackButtonClick={goBackToWalletNetworkSelector} />
)}
{viewState.view.type === BridgeWidgetViews.CLAIM_WITHDRAWAL && (
<ClaimWithdrawal transaction={viewState.view.transaction} />
Expand Down Expand Up @@ -245,6 +254,69 @@ export function BridgeWidget({
onCloseButtonClick={() => sendBridgeWidgetCloseEvent(eventTarget)}
/>
)}
{viewState.view.type === BridgeWidgetViews.CLAIM_WITHDRAWAL_IN_PROGRESS && (
<ClaimWithdrawalInProgress
transactionResponse={viewState.view.transactionResponse}
/>
)}
{viewState.view.type === BridgeWidgetViews.CLAIM_WITHDRAWAL_SUCCESS && (
<StatusView
statusText={t('views.CLAIM_WITHDRAWAL.IN_PROGRESS.success.text')}
actionText={t('views.CLAIM_WITHDRAWAL.IN_PROGRESS.success.actionText')}
onRenderEvent={() => {
page({
userJourney: UserJourney.BRIDGE,
screen: 'ClaimWithdrawalSuccess',
});
sendBridgeClaimWithdrawalSuccessEvent(
eventTarget,
(viewState.view as BridgeClaimWithdrawalSuccess).transactionHash,
);
}}
onActionClick={() => sendBridgeWidgetCloseEvent(eventTarget)}
statusType={StatusType.SUCCESS}
testId="claim-withdrawal-success-view"
/>
)}
{viewState.view.type === BridgeWidgetViews.CLAIM_WITHDRAWAL_FAILURE && (
<StatusView
statusText={t('views.CLAIM_WITHDRAWAL.IN_PROGRESS.failure.text')}
actionText={t('views.CLAIM_WITHDRAWAL.IN_PROGRESS.failure.actionText')}
onRenderEvent={() => {
let reason = '';
if (viewState.view.type === BridgeWidgetViews.CLAIM_WITHDRAWAL_FAILURE) {
reason = viewState.view.reason;
}
page({
userJourney: UserJourney.BRIDGE,
screen: 'ClaimWithdrawalFailure',
extras: {
reason,
},
});
sendBridgeClaimWithdrawalFailedEvent(
eventTarget,
(viewState.view as BridgeClaimWithdrawalFailure).transactionHash,
'Transaction failed',
);
}}
onActionClick={() => {
if (viewState.view.type === BridgeWidgetViews.CLAIM_WITHDRAWAL_FAILURE) {
viewDispatch({
payload: {
type: ViewActions.UPDATE_VIEW,
view: {
type: BridgeWidgetViews.TRANSACTIONS,
},
},
});
}
}}
statusType={StatusType.FAILURE}
onCloseClick={() => sendBridgeWidgetCloseEvent(eventTarget)}
testId="claim-withdrawal-fail-view"
/>
)}
</CryptoFiatProvider>
</BridgeContext.Provider>
</ViewContext.Provider>
Expand Down
Loading

0 comments on commit 0195845

Please sign in to comment.