Skip to content

Commit

Permalink
Merge pull request #744 from vultisig/feat/join-swap
Browse files Browse the repository at this point in the history
Display swap information when joining a swap transaction.
  • Loading branch information
rcoderdev authored Jan 10, 2025
2 parents 393027e + 6d8c380 commit fc606a0
Show file tree
Hide file tree
Showing 13 changed files with 148 additions and 25 deletions.
9 changes: 9 additions & 0 deletions frontend/src/chain/keysign/KeysignSwapPayload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,12 @@ export type KeysignSwapPayload = Exclude<
KeysignPayload['swapPayload'],
{ case: undefined; value?: undefined }
>;

export const toKeysignSwapPayload = (
swapPayload: KeysignPayload['swapPayload']
): KeysignSwapPayload => {
if (swapPayload.case === undefined) {
throw new Error('Swap payload case is undefined');
}
return swapPayload;
};
1 change: 1 addition & 0 deletions frontend/src/chain/swap/oneInch/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const oneInchName = '1inch';
3 changes: 2 additions & 1 deletion frontend/src/chain/swap/quote/getSwapQuoteProviderName.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { matchRecordUnion } from '../../../lib/utils/matchRecordUnion';
import { oneInchName } from '../oneInch/config';
import { SwapQuote } from './SwapQuote';

export const getSwapQuoteProviderName = (quote: SwapQuote) => {
return matchRecordUnion(quote, {
native: ({ swapChain }) => swapChain,
oneInch: () => '1inch',
oneInch: () => oneInchName,
});
};
7 changes: 7 additions & 0 deletions frontend/src/i18n/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -626,4 +626,11 @@ export const de = {
provider: 'Anbieter',
swap_tracking_link: 'Tracking-Link austauschen',
swap_fee: 'Swap-Gebühr',
and: 'Und',
approve: 'Genehmigen',
action: 'Aktion',
from_asset: 'Von Anlagegut',
to_asset: 'Zum Vermögenswert',
allowance_spender: 'Taschengeld-Ausgeber',
allowance_amount: 'Freibetrag',
};
7 changes: 7 additions & 0 deletions frontend/src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ export const en = {
name_your_vault: 'Name your Vault',
join: 'Join',
done: 'Done',
and: 'and',
approve: 'Approve',
information_note1:
'Keep devices on the same WiFi Network, correct vault and pair devices.',
information_note2: 'Make sure no other devices are running Vultisig.',
Expand Down Expand Up @@ -372,6 +374,7 @@ export const en = {
secureVault: 'Secure Vault',
active: 'Active',
sign: 'Sign',
action: 'Action',
fast_vault_setup_prop_0: 'Single Device Setup',
fast_vault_setup_prop_1: 'Transaction Alerts & Policies',
fast_vault_setup_prop_2: 'Vault Backup Emailed',
Expand Down Expand Up @@ -621,4 +624,8 @@ export const en = {
scan_with_devices: 'Scan with devices to join the vault generation',
scan_with_devices_to_sign:
'Scan with devices to participate in signing the transaction',
from_asset: 'From Asset',
to_asset: 'To Asset',
allowance_spender: 'Allowance spender',
allowance_amount: 'Allowance amount',
};
7 changes: 7 additions & 0 deletions frontend/src/i18n/locales/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -626,4 +626,11 @@ export const es = {
provider: 'Proveedor',
swap_tracking_link: 'Enlace de seguimiento de intercambio',
swap_fee: 'Tarifa de intercambio',
and: 'y',
approve: 'Aprobar',
action: 'Acción',
from_asset: 'Desde Activo',
to_asset: 'Al activo',
allowance_spender: 'Gastador de mesadas',
allowance_amount: 'Monto de la asignación',
};
7 changes: 7 additions & 0 deletions frontend/src/i18n/locales/hr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -604,4 +604,11 @@ export const hr = {
provider: 'Davatelj',
swap_tracking_link: 'Swap link za praćenje',
swap_fee: 'Naknada za zamjenu',
and: 'i',
approve: 'Odobriti',
action: 'Akcijski',
from_asset: 'Od imovine',
to_asset: 'Za sredstvo',
allowance_spender: 'Potrošač džeparca',
allowance_amount: 'Iznos dodatka',
};
7 changes: 7 additions & 0 deletions frontend/src/i18n/locales/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -622,4 +622,11 @@ export const it = {
provider: 'Fornitore',
swap_tracking_link: 'Link di monitoraggio dello scambio',
swap_fee: 'Commissione di cambio',
and: 'E',
approve: 'Approvare',
action: 'Azione',
from_asset: 'Da Risorsa',
to_asset: 'Per Risorse',
allowance_spender: 'Spendere indennità',
allowance_amount: "Importo dell'indennità",
};
7 changes: 7 additions & 0 deletions frontend/src/i18n/locales/pt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -617,4 +617,11 @@ export const pt = {
provider: 'Provedor',
swap_tracking_link: 'Link de rastreamento de troca',
swap_fee: 'Taxa de swap',
and: 'e',
approve: 'Aprovar',
action: 'Ação',
from_asset: 'Do Ativo',
to_asset: 'Para Ativo',
allowance_spender: 'Gastador de mesada',
allowance_amount: 'Valor do subsídio',
};
7 changes: 4 additions & 3 deletions frontend/src/lib/utils/matchDiscriminatedUnion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ export function matchDiscriminatedUnion<
D extends string,
V extends string,
U extends { [P in D]: string } & { [Q in V]: unknown },
R,
K extends U[D] = U[D],
R = never,
>(
unionValue: U,
discriminantKey: D,
valueKey: V,
handlers: {
[K in U[D]]: (val: Extract<U, { [P in D]: K }>[V]) => R;
[P in K]: (val: Extract<U, { [Q in D]: P }>[V]) => R;
}
): R {
const discriminantValue = unionValue[discriminantKey] as U[D];
const discriminantValue = unionValue[discriminantKey] as K;
const handler = handlers[discriminantValue];
const value = (
unionValue as Extract<U, { [P in D]: typeof discriminantValue }>
Expand Down
16 changes: 3 additions & 13 deletions frontend/src/vault/keysign/join/verify/KeysignTxOverview.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
import { useTranslation } from 'react-i18next';

import { TxOverviewPanel } from '../../../../chain/tx/components/TxOverviewPanel';
import { TxOverviewPrimaryRow } from '../../../../chain/tx/components/TxOverviewPrimaryRow';
import { shouldBePresent } from '../../../../lib/utils/assert/shouldBePresent';
import { KeysignSwapTxInfo } from '../../../swap/keysign/KeysignSwapTxInfo';
import { KeysignTxPrimaryInfo } from '../../shared/KeysignTxPrimaryInfo';
import { useKeysignPayload } from '../../shared/state/keysignPayload';

export const KeysignTxOverview = () => {
const { coin: potentialCoin } = useKeysignPayload();

const coin = shouldBePresent(potentialCoin);

const { address } = shouldBePresent(coin);

const { t } = useTranslation();
const { swapPayload } = useKeysignPayload();

return (
<TxOverviewPanel>
<TxOverviewPrimaryRow title={t('from')}>{address}</TxOverviewPrimaryRow>
<KeysignTxPrimaryInfo />
{swapPayload.value ? <KeysignSwapTxInfo /> : <KeysignTxPrimaryInfo />}
</TxOverviewPanel>
);
};
17 changes: 9 additions & 8 deletions frontend/src/vault/keysign/shared/KeysignTxPrimaryInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,17 @@ import { MatchQuery } from '../../../lib/ui/query/components/MatchQuery';
import { Text } from '../../../lib/ui/text';
import { shouldBePresent } from '../../../lib/utils/assert/shouldBePresent';
import { formatAmount } from '../../../lib/utils/formatAmount';
import { assertField } from '../../../lib/utils/record/assertField';
import { Chain } from '../../../model/chain';
import { CoinMeta } from '../../../model/coin-meta';
import { useKeysignPayload } from './state/keysignPayload';

export const KeysignTxPrimaryInfo = () => {
const {
coin: potentialCoin,
toAddress,
memo,
toAmount,
blockchainSpecific,
} = useKeysignPayload();
const payload = useKeysignPayload();

const coin = shouldBePresent(potentialCoin);
const { toAddress, memo, toAmount, blockchainSpecific } = payload;

const coin = assertField(payload, 'coin');

const { decimals, ticker } = shouldBePresent(coin);

Expand All @@ -46,6 +43,10 @@ export const KeysignTxPrimaryInfo = () => {

return (
<>
<TxOverviewPrimaryRow title={t('from')}>
{coin.address}
</TxOverviewPrimaryRow>

<TxOverviewPrimaryRow title={t('to')}>{toAddress}</TxOverviewPrimaryRow>
{memo && <TxOverviewMemo value={memo} />}
<TxOverviewAmount
Expand Down
78 changes: 78 additions & 0 deletions frontend/src/vault/swap/keysign/KeysignSwapTxInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { useTranslation } from 'react-i18next';

import { toKeysignSwapPayload } from '../../../chain/keysign/KeysignSwapPayload';
import { oneInchName } from '../../../chain/swap/oneInch/config';
import { TxOverviewPrimaryRow } from '../../../chain/tx/components/TxOverviewPrimaryRow';
import { fromChainAmount } from '../../../chain/utils/fromChainAmount';
import { withoutUndefined } from '../../../lib/utils/array/withoutUndefined';
import { formatAmount } from '../../../lib/utils/formatAmount';
import { getDiscriminatedUnionValue } from '../../../lib/utils/getDiscriminatedUnionValue';
import { matchDiscriminatedUnion } from '../../../lib/utils/matchDiscriminatedUnion';
import { assertField } from '../../../lib/utils/record/assertField';
import { Chain } from '../../../model/chain';
import { useKeysignPayload } from '../../keysign/shared/state/keysignPayload';

export const KeysignSwapTxInfo = () => {
const payload = useKeysignPayload();

const { erc20ApprovePayload, toAmount: fromAmount } = payload;

const fromCoin = assertField(payload, 'coin');

const { t } = useTranslation();

const action = withoutUndefined([
erc20ApprovePayload ? t('approve') : undefined,
t('swap'),
]).join(` ${t('and')} `);

const swapPayload = toKeysignSwapPayload(payload.swapPayload);

const swapPayloadValue = getDiscriminatedUnionValue(
swapPayload,
'case',
'value',
swapPayload.case
);

const toCoin = assertField(swapPayloadValue, 'toCoin');
const toAmount = Number(swapPayloadValue.toAmountDecimal);

const provider = matchDiscriminatedUnion(swapPayload, 'case', 'value', {
thorchainSwapPayload: () => Chain.THORChain,
mayachainSwapPayload: () => Chain.MayaChain,
oneinchSwapPayload: () => oneInchName,
});

return (
<>
<TxOverviewPrimaryRow title={t('action')}>{action}</TxOverviewPrimaryRow>
<TxOverviewPrimaryRow title={t('provider')}>
{provider}
</TxOverviewPrimaryRow>
<TxOverviewPrimaryRow title={t('from_asset')}>
{formatAmount(
fromChainAmount(fromAmount, fromCoin.decimals),
fromCoin.ticker
)}
</TxOverviewPrimaryRow>
<TxOverviewPrimaryRow title={t('to_asset')}>
{formatAmount(toAmount, toCoin.ticker)}
</TxOverviewPrimaryRow>

{erc20ApprovePayload && (
<>
<TxOverviewPrimaryRow title={t('allowance_spender')}>
{erc20ApprovePayload.spender}
</TxOverviewPrimaryRow>
<TxOverviewPrimaryRow title={t('allowance_amount')}>
{formatAmount(
fromChainAmount(erc20ApprovePayload.amount, fromCoin.decimals),
fromCoin.ticker
)}
</TxOverviewPrimaryRow>
</>
)}
</>
);
};

0 comments on commit fc606a0

Please sign in to comment.