Skip to content

Commit

Permalink
feat(HW-463): swap layout
Browse files Browse the repository at this point in the history
  • Loading branch information
iGroza committed Aug 20, 2024
1 parent 43c76e8 commit 0865a6e
Show file tree
Hide file tree
Showing 11 changed files with 999 additions and 381 deletions.
252 changes: 252 additions & 0 deletions src/components/json-rpc-sign/json-rpc-common-transaction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
import React, {useCallback, useMemo} from 'react';

import {ethers} from 'ethers';
import {ActivityIndicator, ScrollView, View} from 'react-native';
import {TouchableWithoutFeedback} from 'react-native-gesture-handler';

import {Color} from '@app/colors';
import {
DataView,
First,
Icon,
IconsName,
InfoBlock,
Spacer,
Text,
TextVariant,
} from '@app/components/ui';
import {createTheme} from '@app/helpers';
import {shortAddress} from '@app/helpers/short-address';
import {I18N} from '@app/i18n';
import {Contracts} from '@app/models/contracts';
import {Fee} from '@app/models/fee';
import {Provider} from '@app/models/provider';
import {Token} from '@app/models/tokens';
import {Balance} from '@app/services/balance';
import {JsonRpcMetadata, JsonRpcTransactionRequest} from '@app/types';
import {getHostnameFromUrl, openInAppBrowser} from '@app/utils';
import {STRINGS} from '@app/variables/common';

import {SiteIconPreview, SiteIconPreviewSize} from '../site-icon-preview';

export interface JsonRpcCommonTransactionProps {
metadata: JsonRpcMetadata;
showSignContratAttention: boolean;
functionName?: string;
isContract: boolean;
provider: Provider | undefined;
isFeeLoading: boolean;
fee: Fee | null | undefined;
tx: Partial<JsonRpcTransactionRequest> | undefined;
parsedInput: ethers.utils.TransactionDescription | undefined;

onFeePress: () => void;
}

export const JsonRpcCommonTransaction = ({
metadata,
showSignContratAttention,
functionName,
isContract,
provider,
isFeeLoading,
fee,
tx,
parsedInput,
onFeePress,
}: JsonRpcCommonTransactionProps) => {
const url = useMemo(() => getHostnameFromUrl(metadata?.url), [metadata]);
const value = useMemo(() => {
if (functionName === 'approve') {
const token = Token.getById(tx?.to!);
return new Balance(
parsedInput?.args?.[1] || '0x0',
token.decimals!,
token.symbol!,
);
}

if (!tx?.value) {
return Balance.Empty;
}

return new Balance(tx.value, provider?.decimals, provider?.denom);
}, [tx, provider, parsedInput]);

const total = useMemo(() => {
if (functionName === 'approve') {
return fee?.calculatedFees?.expectedFee.toBalanceString('auto');
}
return value
.operate(fee?.calculatedFees?.expectedFee ?? Balance.Empty, 'add')
.toBalanceString('auto');
}, [value, fee?.calculatedFees?.expectedFee]);

const onPressToAddress = useCallback(() => {
openInAppBrowser(provider?.getAddressExplorerUrl?.(tx?.to!)!);
}, [provider, tx]);

const onPressApproveSpender = useCallback(() => {
openInAppBrowser(
provider?.getAddressExplorerUrl?.(parsedInput?.args?.[0])!,
);
}, [provider, tx, parsedInput]);

return (
<View style={styles.container}>
<Text
variant={TextVariant.t5}
i18n={I18N.walletConnectSignTransactionForSignature}
/>

<Spacer height={8} />

<View style={styles.fromContainer}>
<Text
variant={TextVariant.t13}
color={Color.textBase2}
i18n={I18N.walletConnectSignForm}
/>
<SiteIconPreview
url={metadata.url}
directIconUrl={metadata.iconUrl}
size={SiteIconPreviewSize.s18}
style={styles.fromImage}
/>
<Text variant={TextVariant.t13} color={Color.textGreen1}>
{url}
</Text>
</View>

<Spacer height={24} />

{showSignContratAttention && (
<>
<InfoBlock
error
icon={<Icon name={'warning'} color={Color.textRed1} />}
i18n={I18N.signContratAttention}
style={styles.signContractAttention}
/>
<Spacer height={24} />
</>
)}

{functionName !== 'approve' && (
<>
<Text
variant={TextVariant.t11}
color={Color.textBase2}
i18n={I18N.walletConnectSignTotalAmount}
/>

<Spacer height={4} />
<Text variant={TextVariant.t3}>{total}</Text>

<Spacer height={16} />
</>
)}

<Text
variant={TextVariant.t11}
color={Color.textBase2}
i18n={I18N.walletConnectSignSendTo}
/>

<Spacer height={4} />

<Text
onPress={onPressToAddress}
variant={TextVariant.t10}
selectable
color={Color.textBase1}>
{tx?.to}
</Text>

<Spacer height={28} />

<ScrollView style={styles.info} showsVerticalScrollIndicator={false}>
<DataView i18n={I18N.transactionInfoTypeOperation}>
<Text variant={TextVariant.t11} color={Color.textBase1}>
{functionName?.length ? (
<Text children={functionName} />
) : (
<Text
i18n={
isContract
? I18N.transactionInfoContractInteraction
: I18N.transactionInfoSendingFunds
}
/>
)}
</Text>
</DataView>
{functionName === 'approve' && (
<DataView i18n={I18N.transactionDetailApproveSpenderTitle}>
<Text
onPress={onPressApproveSpender}
variant={TextVariant.t11}
color={Color.textBlue1}>
{Contracts.getById(parsedInput?.args?.[0])?.name ?? ''}
{STRINGS.NBSP}
{shortAddress(tx?.to!, '•', true)}
</Text>
</DataView>
)}
{!!provider?.id && (
<DataView i18n={I18N.transactionInfoNetwork}>
<Text variant={TextVariant.t11} color={Color.textBase1}>
{provider.name}
</Text>
</DataView>
)}
<DataView i18n={I18N.transactionInfoAmount}>
<Text
variant={TextVariant.t11}
color={Color.textBase1}
children={value.toBalanceString('auto')}
/>
</DataView>
<DataView i18n={I18N.transactionInfoNetworkFee}>
<First>
{isFeeLoading && <ActivityIndicator />}
<TouchableWithoutFeedback onPress={onFeePress}>
<View style={styles.feeContainer}>
<Text variant={TextVariant.t11} color={Color.textGreen1}>
{fee?.expectedFeeString}
</Text>
<Icon name={IconsName.tune} color={Color.textGreen1} />
</View>
</TouchableWithoutFeedback>
</First>
</DataView>
</ScrollView>
<Spacer height={10} />
</View>
);
};

const styles = createTheme({
info: {
width: '100%',
borderRadius: 16,
backgroundColor: Color.bg3,
},
fromContainer: {
flexDirection: 'row',
},
fromImage: {
marginHorizontal: 4,
},
signContractAttention: {
width: '100%',
},
container: {
flex: 1,
width: '100%',
alignItems: 'center',
},
feeContainer: {
flexDirection: 'row',
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ import {
} from '@app/utils';
import {EIP155_SIGNING_METHODS} from '@app/variables/EIP155';

import {JsonViewer} from './json-viewer';
import {SiteIconPreview, SiteIconPreviewSize} from './site-icon-preview';
import {TypedDataViewer} from './typed-data-viewer';
import {WalletRow, WalletRowTypes} from './wallet-row';
import {JsonViewer} from '../json-viewer';
import {SiteIconPreview, SiteIconPreviewSize} from '../site-icon-preview';
import {TypedDataViewer} from '../typed-data-viewer';
import {WalletRow, WalletRowTypes} from '../wallet-row';

interface WalletConnectSignInfoProps {
request: PartialJsonRpcRequest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {View} from 'react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';

import {Color} from '@app/colors';
import {JsonRpcSignInfo} from '@app/components/json-rpc-sign-info';
import {JsonRpcTransactionInfo} from '@app/components/json-rpc-transaction-info';
import {JsonRpcSignInfo} from '@app/components/json-rpc-sign/json-rpc-sign-info';
import {JsonRpcTransactionInfo} from '@app/components/json-rpc-sign/json-rpc-transaction-info';
import {Button, ButtonVariant, Spacer} from '@app/components/ui';
import {createTheme} from '@app/helpers';
import {EthereumSignInMessage} from '@app/helpers/ethereum-message-checker';
Expand Down Expand Up @@ -96,6 +96,7 @@ export const JsonRpcSign = ({
<View style={styles.container}>
<View style={styles.txContainer}>
{isTransaction && (
// it renderns common transaction component for all transactions and custom uni/suhi swap transactions
<JsonRpcTransactionInfo
metadata={metadata}
request={request}
Expand All @@ -108,6 +109,7 @@ export const JsonRpcSign = ({
)}

{!isTransaction && (
// it renders: typed data v4 (with custom cosmos stakinkg actions render), personal sign, eth sign
<JsonRpcSignInfo
metadata={metadata}
request={request}
Expand Down
Loading

0 comments on commit 0865a6e

Please sign in to comment.