Skip to content

Commit

Permalink
feat: hqm 377 swap UI (#1930)
Browse files Browse the repository at this point in the history
* feat: sushi swap beta

* fix: sushi swap review

* fix(jsonrpcRequest): temp patch for @haqq/shared-react-native

* fix: sushi new backend logic

* feat: swap screen header

* feat: add provider fee

* feat: swap settings

* fix: sushi swap token select

* feat: show route for sushi swap

* feat: update locales

* feat: hide empty wallets for swap

* fix: android swap arrow symbol

* fix: estimate swap transaction

* chore: update locales

* refactor: swap screen

* fix: swap rates

* feat: add translations for swap

* fix: input swap rates

* feat: add translations for swap settings

* refactor: change swap wallet preview

* fix: PR HQM-377 clean

* feat: getAllPositiveBalance for wallet storage

---------

Co-authored-by: iGroza <[email protected]>
  • Loading branch information
iGroza and iGroza authored Jun 25, 2024
1 parent f7e18eb commit 40fca14
Show file tree
Hide file tree
Showing 48 changed files with 2,128 additions and 372 deletions.
1 change: 1 addition & 0 deletions .metro-health-check-8879-0-5869
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
176332800.69399998
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 35 additions & 3 deletions assets/locales/en/en.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"StakingInfoUnDelegationDay": " ({{day}} day left)",
"StakingInfoUnDelegationDays": " ({{days}} days left)",
"_hash": "4747f3e4f8e461beec94dbf206a23d2013fdc600a9b735a725656a7e6b021f27",
"Welcome_haqq_pin": "Welcome to HAQQ Wallet",
"_hash": "58c4a77ba9d1114d394c90a515c87dab74ce50ba2a53599e48be76186ad1545a",
"accept": "Accept",
"accountInfoNftTabTitle": "NFTs",
"accountInfoTokensTabTitle": "Tokens",
Expand Down Expand Up @@ -178,6 +179,7 @@
"feeSettingsHeader": "Fee settings",
"finishProceed": "Proceed",
"gasLimit": "Gas limit",
"gasLimitDescription": "Gas limit goes directly to miners and incentivizes them to prioritize your transaction. You'll most often pay your max setting. We have updated the gas fee based on current network conditions and have increased it by at least 10% (required by the network).",
"gasPrice": "Gas price",
"goToPhoneSettings": "Go to Phone settings",
"headerPlaceholderSearch": "Search",
Expand Down Expand Up @@ -329,10 +331,14 @@
"lockedTokensVested": "Vested: {{count}}",
"lockedTokensVestedAvailableIn": " (Will be available in: {{value}})",
"low": "Low",
"maxBaseFee": "Max Base Fee",
"maxBaseFeeDescription": "The max fee is the most you'll pay (base fee + priority fee. We have updated the gas fee based on current network conditions and have increased it by at least 10% (required by the network).",
"maxPriorityFee": "Max Priority Fee",
"maxPriorityFeeDescription": "Max priority fee (aka \"miner tip\") goes directly to miners and incentivizes them to prioritize your transaction. You'll most often pay your max setting. We have updated the gas fee based on current network conditions and have increased it by at least 10% (required by the network).",
"modalDetailsQRReceive": "Receive",
"modalDetailsQRWarning": "Only {assetName} related assets on {networkName} are supported.",
"modalDontHaveFeeClose": "Close",
"modalDontHaveFeeError": "You don't have enough {assetWeiName} to pay the fee",
"modalDontHaveFeeError": "You don't have enough {assetWeiName} for transaction",
"modalPinForgotCode": "Forgot\nthe code",
"modalPinTitle": "Welcome to {appName}",
"modalQRNoAccessDescription": "The app does not have access to your camera. Please go to your phone settings and allow the app to use camera. Without this, we will not be able to scan QR Code",
Expand All @@ -358,6 +364,7 @@
"nftDetailsAttributes": "Attributes",
"nftDetailsDescription": "Description",
"nftDetailsLastSalePrice": "Last sale price",
"nftDetailsNumberOfCopies": "Number of copies",
"nftDetailsSend": "Send",
"nftDetailsTokenId": "Token ID",
"nftDetailsYourItems": "Your items",
Expand Down Expand Up @@ -766,10 +773,33 @@
"stakingValidatorsRowWithdrawal": "Withdrawal in process",
"stakingValidatorsStaked": "Staked",
"stakingValidatorsUnStaked": "Unstaked",
"sumAmountNotEnough": "You don't have enough ISLM to pay the fee",
"sumAmountNotEnough": "You don't have enough ISLM for transaction",
"sumAmountTooLow": "Should be equal or greater than {{amount}}",
"sumBlockAvailable": "Available",
"sumBlockMax": "Max",
"swapInputAmountData": "≈ {{currentFiatAmount}} • Available {{availableAmount}}",
"swapScreenApprove": "Approve {{amount}} {{symbol}}",
"swapScreenMax": "MAX",
"swapScreenMinimumReceived": "Min received",
"swapScreenPriceImpact": "Price impact",
"swapScreenProviderFee": "Provider Fee",
"swapScreenRate": "Rate",
"swapScreenRoute": "Route",
"swapScreenRoutingSource": "Routing source",
"swapScreenSwap": "Swap",
"swapScreenTitle": "Swap",
"swapScreenUnwrap": "Unwrap",
"swapScreenWrap": "Wrap",
"swapSettingsApply": "Apply",
"swapSettingsDeadlineError": "deadline must be between 1 min and 60 min",
"swapSettingsDeadlineLabel": "Transaction deadline (min)",
"swapSettingsDeadlinePlaceholder": "from 1 min to 60 min",
"swapSettingsReset": "Reset",
"swapSettingsSlippageError": "slippage must be between 0.05% and 50%",
"swapSettingsSlippageLabel": "Slippage Tolerance (%)",
"swapSettingsSlippagePlaceholder": "from 0.05% to 50%",
"swapSettingsSlippageWarning": "Your transaction may be frontrun due to high slippage tolerance",
"swapTransactionSettingsTitle": "Transaction setting",
"swapWidgetDescription": "Haqq wallet finds the best price for your token swap",
"swapWidgetTitle": "Swap tokens",
"termsAgreementFirst": "By clicking buttons you agree to ",
Expand Down Expand Up @@ -823,6 +853,8 @@
"transactionCrypto": "Crypto",
"transactionDelegationTitle": "Delegate",
"transactionDetailAmount": "Amount",
"transactionDetailAmountIn": "You Pay",
"transactionDetailAmountOut": "You Receive",
"transactionDetailApproveSpenderTitle": "Spender",
"transactionDetailContractName": "Contract name",
"transactionDetailCryptocurrency": "Cryptocurrency",
Expand Down
4 changes: 3 additions & 1 deletion assets/locales/ru/ru.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"StakingInfoUnDelegationDay": " ({{day}} день остался)",
"StakingInfoUnDelegationDays": " ({{days}} дней осталось)",
"_hash": "99bdafd344525d0b6987aa317b103e9b4b8c7e103b1765c03d98a22753344578",
"_hash": "7c486ee08f8280e3cdf3cbfba0339b80c12bcc6358441ff4448974dbe9399cd6",
"accept": "Принять",
"accountInfoTokensTabTitle": "Токены",
"accountInfoTransactionTabTitle": "Транзакции",
Expand All @@ -13,6 +13,8 @@
"backupCreateRecoveryAgreement": "Я понимаю, что если я потеряю фразу восстановления, я не смогу восстановить доступ к своей учетной записи",
"backupFinishCongratulation": "Поздравляем!",
"backupFinishFinish": "Продолжить",
"backupNotificationAlertTitle": "Продолжить без резервной копии? ",
"backupNotificationBackup": "Создать резервную копию сейчас",
"backupSssSuggestionCancel": "Подключить позднее",
"empty": " ",
"erase": "Стереть",
Expand Down
12 changes: 10 additions & 2 deletions ios/haqq.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1454,7 +1454,11 @@
"-DFOLLY_MOBILE=1",
"-DFOLLY_USE_LIBCPP=1",
);
OTHER_LDFLAGS = "$(inherited)";
OTHER_LDFLAGS = (
"$(inherited)",
"-Wl",
"-ld_classic",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
Expand Down Expand Up @@ -1534,7 +1538,11 @@
"-DFOLLY_MOBILE=1",
"-DFOLLY_USE_LIBCPP=1",
);
OTHER_LDFLAGS = "$(inherited)";
OTHER_LDFLAGS = (
"$(inherited)",
"-Wl",
"-ld_classic",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
Expand Down
12 changes: 12 additions & 0 deletions ios/haqq/Images.xcassets/swap_vertical.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images": [
{
"filename": "swap_vertical.svg",
"idiom": "universal"
}
],
"info": {
"author": "xcode",
"version": 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@
"@evmos/transactions": "0.2.13",
"@expo/react-native-action-sheet": "4.0.1",
"@haqq/encryption-react-native": "0.0.4",
"@haqq/format-number-with-subscript-zeros": "^1.0.0",
"@haqq/provider-base": "0.0.23",
"@haqq/provider-hot-react-native": "0.0.10",
"@haqq/provider-keystone-react-native": "0.0.7",
"@haqq/provider-ledger-react-native": "0.0.28",
"@haqq/provider-mnemonic-react-native": "0.0.14",
"@haqq/provider-sss-react-native": "0.0.14",
"@haqq/provider-web3-utils": "0.0.14",
"@haqq/shared-react-native": "0.0.11",
"@haqq/shared-react-native": "0.0.12",
"@invertase/react-native-apple-authentication": "2.2.2",
"@keystonehq/bc-ur-registry-eth": "0.7.7",
"@keystonehq/ur-decoder": "0.12.2",
Expand Down
49 changes: 49 additions & 0 deletions src/components/swap/estimated-value.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, {useMemo} from 'react';

import {observer} from 'mobx-react';
import {View} from 'react-native';

import {Color} from '@app/colors';
import {createTheme} from '@app/helpers';
import {I18N, getText} from '@app/i18n';

import {First, Spacer, Text, TextVariant} from '../ui';

export interface EstimatedValueProps {
title: string | I18N;
value: string | number | React.ReactNode;
valueColor?: Color;
}

export const EstimatedValue = observer(
({title, value, valueColor = Color.textBase1}: EstimatedValueProps) => {
const _title = useMemo(() => {
if (title in I18N) {
return getText(title as I18N);
}
return title;
}, [title]);

return (
<View style={styles.estimatedValueContainer}>
<Text variant={TextVariant.t14} color={Color.textBase2}>
{_title}
</Text>
<Spacer />
<First>
{React.isValidElement(value) && value}
<Text variant={TextVariant.t14} color={valueColor}>
{value}
</Text>
</First>
</View>
);
},
);

const styles = createTheme({
estimatedValueContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
},
});
1 change: 1 addition & 0 deletions src/components/swap/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './swap';
export * from './swap-preview';
export * from './swap-finish';
export * from './swap-settings-bottom-sheet';
168 changes: 168 additions & 0 deletions src/components/swap/swap-input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import React from 'react';

import {observer} from 'mobx-react';
import {View} from 'react-native';

import {Color} from '@app/colors';
import {createTheme} from '@app/helpers';
import {useSumAmount} from '@app/hooks';
import {I18N} from '@app/i18n';
import {Balance} from '@app/services/balance';
import {IContract} from '@app/types';

import {ImageWrapper} from '../image-wrapper';
import {
Button,
ButtonSize,
ButtonVariant,
First,
LabeledBlock,
Spacer,
Text,
TextField,
TextFieldProps,
TextVariant,
} from '../ui';
import {Placeholder} from '../ui/placeholder';

export type SwapInputProps = {
token: IContract;
currentBalance: Balance;
availableBalance: Balance;
amounts: ReturnType<typeof useSumAmount>;
isLoading?: boolean;
showMaxButton?: boolean;
disableTextFieldLoader?: boolean;
onPressMax?(): void;
onPressChangeToken(): void;
} & Pick<
TextFieldProps,
'onBlur' | 'editable' | 'label' | 'placeholder' | 'autoFocus'
>;

export const SwapInput = observer(
({
amounts,
availableBalance,
currentBalance,
token,
isLoading,
showMaxButton = false,
disableTextFieldLoader = false,
onPressChangeToken,
onPressMax,
...inputProps
}: SwapInputProps) => {
return (
<View>
<View style={styles.amountContainer}>
<First>
{isLoading && disableTextFieldLoader === false && (
<View style={styles.amountInput}>
<Placeholder opacity={0.7}>
<Placeholder.Item width={'100%'} height={58} />
</Placeholder>
</View>
)}
<TextField
rightAction={
showMaxButton ? (
<Button
i18n={I18N.swapScreenMax}
variant={ButtonVariant.text}
textColor={
isLoading ? Color.textBase2 : Color.graphicGreen1
}
size={ButtonSize.small}
onPress={onPressMax}
disabled={isLoading}
/>
) : undefined
}
style={styles.amountInput}
error={!!amounts.error}
errorText={amounts.error}
{...inputProps}
value={amounts.amount}
onChangeText={amounts.setAmount}
keyboardType="numeric"
inputMode="decimal"
returnKeyType="done"
/>
</First>
<Spacer width={10} />

<LabeledBlock
i18nLabel={I18N.transactionCrypto}
style={styles.cryptoBlock}
onPress={onPressChangeToken}>
<View style={styles.cryptoBlockWrapper}>
{!!token.icon && (
<ImageWrapper
style={styles.cryptoBlockImage}
source={token.icon}
/>
)}
<Text
style={styles.cryptoBlockTitle}
t11
color={Color.textBase1}
numberOfLines={1}
ellipsizeMode="middle">
{token.symbol}
</Text>
</View>
</LabeledBlock>
</View>

<View>
<Spacer height={4} />
<Text
variant={TextVariant.t14}
color={Color.textBase2}
i18n={I18N.swapInputAmountData}
i18params={{
currentFiatAmount: currentBalance.toFiat({
useDefaultCurrency: true,
}),
availableAmount: availableBalance.toBalanceString('auto'),
}}
/>
</View>
</View>
);
},
);

const styles = createTheme({
amountContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
},
amountInput: {
flex: 3.8,
},
cryptoBlockImage: {
maxHeight: 12,
maxWidth: 12,
width: 12,
height: 12,
borderRadius: 5,
overflow: 'hidden',
alignSelf: 'center',
marginRight: 4,
},
cryptoBlockTitle: {
marginRight: 8,
},
cryptoBlockWrapper: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
cryptoBlock: {
flex: 1,
alignItems: 'center',
height: 58,
},
});
Loading

0 comments on commit 40fca14

Please sign in to comment.