Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TW-1385: Gas token send / receive #1189

Merged
merged 87 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from 85 commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
e7563e1
basic layout
lendihop Aug 27, 2024
a63115b
select token for tezos
lendihop Aug 29, 2024
39abe25
select token
lendihop Sep 3, 2024
f7c46de
dont show tags
lendihop Sep 3, 2024
804f710
fix select asset modal opening after page reload
lendihop Sep 4, 2024
689abf0
fix e2e ts
lendihop Sep 4, 2024
4e9c512
form refactor
lendihop Sep 5, 2024
d247267
resolving evm address from domain
lendihop Sep 5, 2024
6e97893
max amount calculation
lendihop Sep 8, 2024
996b7fe
fix logic for erc20 tokens
lendihop Sep 8, 2024
f72cee4
recipient account select main logic
lendihop Sep 9, 2024
eb334c6
address copying fixed
lendihop Sep 10, 2024
ffa5410
recipient input / select acc state connection + truncation added
lendihop Sep 10, 2024
6d4aa03
tezos form validation fixes
lendihop Sep 10, 2024
5d5192d
evm form validation + react-hook-form v7 used
lendihop Sep 12, 2024
e570f93
add active state for filter network option
lendihop Sep 12, 2024
7b3cc12
scroll to selected network
lendihop Sep 12, 2024
690438f
Merge branch 'refs/heads/TW-1359-epic-evm-transactions-operations' in…
lendihop Sep 13, 2024
8ddb14c
add filter network search
lendihop Sep 17, 2024
73c009e
loader added
lendihop Sep 17, 2024
644f213
always show converted amount
lendihop Sep 17, 2024
ad1da2e
show floating assetSymbol in input
lendihop Sep 18, 2024
0c21a84
track other networks addresses
lendihop Sep 18, 2024
d654a2e
show tezos error toast on form submit
lendihop Sep 18, 2024
5860f3f
maxAmount calculation fixes
lendihop Sep 18, 2024
f20b16f
fix pipeline
lendihop Sep 18, 2024
ff3d019
confirm modal base + segmented control
lendihop Sep 18, 2024
bd25713
confirmation modal layout finished
lendihop Sep 19, 2024
5d8fe51
Evm / tezos component separation Header, DetailsTab
lendihop Sep 20, 2024
98ac994
Merge branch 'refs/heads/TW-1359-epic-evm-transactions-operations' in…
lendihop Sep 23, 2024
1279fa7
fix after-merge conflicts
lendihop Sep 23, 2024
94d04dc
fix network icon
lendihop Sep 23, 2024
a877d1f
more after-merge fixes
lendihop Sep 23, 2024
876f9df
some more fixes
lendihop Sep 23, 2024
4b8c7c7
some more fixes
lendihop Sep 23, 2024
12ef9cd
infoIcon
lendihop Sep 23, 2024
913085d
iconBase memo
lendihop Sep 23, 2024
ed1e0fc
viem update
lendihop Sep 23, 2024
e628332
send evm transaction
lendihop Sep 24, 2024
f322519
send evm transaction / add networks support
lendihop Sep 25, 2024
82abb92
fix various ui bugs
lendihop Sep 26, 2024
f648625
fix fee options calculations
lendihop Sep 26, 2024
bafe37c
fix some more bugs
lendihop Sep 27, 2024
b5c8acf
fix import cycle
lendihop Sep 27, 2024
96b7626
custom transaction params inputs + error handling
lendihop Sep 29, 2024
78b647b
fix ts-prune
lendihop Sep 29, 2024
2000b34
major refactoring and bug fixes
lendihop Oct 2, 2024
4e5d58e
tezos fee options calculation + ui fixes
lendihop Oct 2, 2024
5b79b43
send tezos operations without old confirmation page
lendihop Oct 6, 2024
13623e3
added loading button + proper form reset
lendihop Oct 6, 2024
134cdaf
edit gas fee and storageLimit
lendihop Oct 7, 2024
62bc3d0
show default evm form values
lendihop Oct 7, 2024
083ca2f
some ui fixes
lendihop Oct 8, 2024
0e696a8
non zero validation
lendihop Oct 8, 2024
5a1727a
error tab
lendihop Oct 8, 2024
9561c5c
fix ts-prune
lendihop Oct 8, 2024
063bb51
fix fee calculation with custom gas limit
lendihop Oct 8, 2024
b726cea
refactor
lendihop Oct 10, 2024
f30e851
refactor + minor ui fixes
lendihop Oct 10, 2024
4cbeccb
show default gas fee and storage limit + non zero gas fee validation
lendihop Oct 10, 2024
4765994
storage limit handling
lendihop Oct 10, 2024
0226d97
fix ts-prune
lendihop Oct 10, 2024
e4143b1
Merge branch 'refs/heads/TW-1359-epic-evm-transactions-operations' in…
lendihop Oct 10, 2024
04b33b8
fix some after-merge issues
lendihop Oct 10, 2024
3824fd7
show tezos raw transaction
lendihop Oct 10, 2024
d93dcae
renaming
lendihop Oct 11, 2024
52b12b6
raw transaction json view
lendihop Oct 11, 2024
568d1b1
tezos submit errors handling
lendihop Oct 11, 2024
9b01fa8
Merge branch 'refs/heads/TW-1359-epic-evm-transactions-operations' in…
lendihop Oct 11, 2024
8db086c
fix some after-merge issues
lendihop Oct 11, 2024
39110d7
fix some after-merge issues
lendihop Oct 11, 2024
9b05f98
fix ts-prune
lendihop Oct 11, 2024
3439367
refactor
lendihop Oct 16, 2024
485edc1
more refactor
lendihop Oct 17, 2024
465900a
apply suggestion
lendihop Oct 17, 2024
19c4d5b
fix audit
lendihop Oct 25, 2024
bd6e641
minor bug fixes
lendihop Oct 29, 2024
a8ae54f
Merge branch 'refs/heads/development-2' into TW-1385-gas-token-send-r…
lendihop Oct 29, 2024
6be2621
after merge fixes
lendihop Oct 29, 2024
9c7a4a7
fix minor bugs
lendihop Oct 30, 2024
39ba572
resolve merge conflicts
lendihop Oct 31, 2024
bdac7fd
some more after-merge fixes
lendihop Oct 31, 2024
d0c8ba4
some more after-merge fixes
lendihop Oct 31, 2024
06b60c0
fix info icon size
lendihop Oct 31, 2024
72accc3
fix fiat toggle
lendihop Oct 31, 2024
2314ee5
Merge branch 'development-2' into TW-1385-gas-token-send-receive
alex-tsx Nov 4, 2024
892e9c8
Fix pipeline
alex-tsx Nov 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions e2e/src/page-objects/pages/send.page.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import { SendFormSelectors } from 'src/app/templates/SendForm/selectors';
import { SendFormSelectors } from 'src/app/pages/Send/form/selectors';

import { Page } from '../../classes/page.class';
import { createPageElement } from '../../utils/search.utils';

export class SendPage extends Page {
assetDropDown = createPageElement(SendFormSelectors.assetDropDown);
assetDropDownSearchInput = createPageElement(SendFormSelectors.assetDropDownSearchInput);
amountInput = createPageElement(SendFormSelectors.amountInput);
recipientInput = createPageElement(SendFormSelectors.recipientInput);
sendButton = createPageElement(SendFormSelectors.sendButton);
contactItemButton = createPageElement(SendFormSelectors.contactItemButton);
contactHashValue = createPageElement(SendFormSelectors.contactHashValue);

async isVisible() {
await this.assetDropDown.waitForDisplayed();
await this.recipientInput.waitForDisplayed();
await this.amountInput.waitForDisplayed();
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@
"use-force-update": "1.0.7",
"use-onclickoutside": "0.4.1",
"util": "0.11.1",
"viem": "^2.15.1",
"viem": "^2.21.36",
"wasm-themis": "0.14.6",
"webextension-polyfill": "^0.10.0",
"webpack": "^5",
Expand Down
25 changes: 23 additions & 2 deletions public/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,9 @@
"addAsset": {
"message": "Add Asset"
},
"available": {
"message": "Available"
},
"contractNotAvailable": {
"message": "The contract at this address is not available. Does it exist on this network?"
},
Expand Down Expand Up @@ -738,7 +741,7 @@
}
},
"maximalAmount": {
"message": "Maximal: $amount$",
"message": "Max: $amount$",
"placeholders": {
"amount": {
"content": "$1"
Expand Down Expand Up @@ -1103,6 +1106,9 @@
"asset": {
"message": "Asset"
},
"token": {
"message": "Token"
},
"selectAnotherAssetPrompt": {
"message": "Click on area to select another asset or token."
},
Expand Down Expand Up @@ -2498,7 +2504,7 @@
}
},
"gasFee": {
"message": "Gas fee"
"message": "Gas Fee"
},
"storageFee": {
"message": "Storage fee"
Expand Down Expand Up @@ -3598,6 +3604,21 @@
"allNetworks": {
"message": "All Networks"
},
"gasPrice": {
"message": "Gas Price"
},
"gasLimit": {
"message": "Gas Limit"
},
"nonce": {
"message": "Nonce"
},
"gasLimitInfoContent": {
"message": "Gas limit is the maximum units of gas you are willing to use. Units of gas are a multiplier to “Max priority fee” and “Max fee”."
},
"nonceInfoContent": {
"message": "The nonce is the number of transactions sent from a given address. Each time you send a transaction, the nonce value increases by 1."
},
"enLangName": {
"message": "English"
},
Expand Down
2 changes: 1 addition & 1 deletion public/_locales/en_GB/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@
}
},
"maximalAmount": {
"message": "Maximal: $amount$",
"message": "Max: $amount$",
"placeholders": {
"amount": {
"content": "$1"
Expand Down
6 changes: 4 additions & 2 deletions src/app/PageRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,10 @@ const ROUTE_MAP = Woozie.createMap<RouteContext>([
['/connect-ledger', onlyReady(onlyInFullPage(() => <ConnectLedger />))],
['/receive', onlyReady(() => <Receive />)],
[
'/send/:chainKind?/:tezosChainId?/:assetSlug?',
onlyReady(({ tezosChainId, assetSlug }) => <Send tezosChainId={tezosChainId} assetSlug={assetSlug} />)
'/send/:chainKind?/:chainId?/:assetSlug?',
onlyReady(({ chainKind, chainId, assetSlug }) => (
<Send chainKind={chainKind} chainId={chainId} assetSlug={assetSlug} />
))
],
['/swap', onlyReady(() => <Swap />)],
['/delegate/:tezosChainId', onlyReady(({ tezosChainId }) => <Delegate tezosChainId={tezosChainId!} />)],
Expand Down
2 changes: 1 addition & 1 deletion src/app/atoms/AccLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const AccLabel = memo<Props>(({ type }) => {
}, [type]);

return (
<div className="flex items-center gap-x-px py-1 pl-1.5 pr-2 bg-grey-4 rounded-md">
<div className="flex items-center gap-x-px py-1 pl-1.5 pr-2 bg-grey-4 rounded-md self-end">
<IconBase Icon={Icon} size={12} className="text-grey-2" />

<span className="text-font-num-bold-10 text-grey-1 uppercase">{title}</span>
Expand Down
16 changes: 10 additions & 6 deletions src/app/atoms/AssetField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface AssetFieldProps extends Omit<ComponentProps<typeof FormField>, 'onChan
max?: number;
assetSymbol?: ReactNode;
assetDecimals?: number;
onlyInteger?: boolean;
onChange?: (v?: string) => void;
}

Expand All @@ -22,14 +23,18 @@ const AssetField = forwardRef<HTMLInputElement, AssetFieldProps>(
max = Number.MAX_SAFE_INTEGER,
assetSymbol,
assetDecimals = 6,
onlyInteger = false,
onChange,
onFocus,
onBlur,
...rest
},
ref
) => {
const valueStr = useMemo(() => (value === undefined ? '' : new BigNumber(value).toFixed()), [value]);
const valueStr = useMemo(
() => (value === undefined || value === '' ? '' : new BigNumber(value).toFixed()),
keshan3262 marked this conversation as resolved.
Show resolved Hide resolved
[value]
);

const [localValue, setLocalValue] = useState(valueStr);

Expand All @@ -44,21 +49,20 @@ const AssetField = forwardRef<HTMLInputElement, AssetFieldProps>(
const handleChange = useCallback(
(evt: React.ChangeEvent<HTMLInputElement> & React.ChangeEvent<HTMLTextAreaElement>) => {
let val = evt.target.value.replace(/ /g, '').replace(/,/g, '.');
let numVal = new BigNumber(val || 0);
const indexOfDot = val.indexOf('.');
if (indexOfDot !== -1 && onlyInteger) return;
let numVal = new BigNumber(val || 0);
if (indexOfDot !== -1 && val.length - indexOfDot > assetDecimals + 1) {
val = val.substring(0, indexOfDot + assetDecimals + 1);
numVal = new BigNumber(val);
}

if (!numVal.isNaN() && numVal.isGreaterThanOrEqualTo(min) && numVal.isLessThanOrEqualTo(max)) {
setLocalValue(val);
if (onChange) {
onChange(val !== '' ? numVal.toFixed() : undefined);
}
onChange?.(val !== '' ? numVal.toFixed() : undefined);
}
},
[assetDecimals, setLocalValue, min, max, onChange]
[onlyInteger, assetDecimals, min, max, onChange]
);

return (
Expand Down
41 changes: 32 additions & 9 deletions src/app/atoms/AssetsSegmentControl.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { createContext, memo, RefObject, useContext } from 'react';
import React, { createContext, memo, RefObject, useCallback, useContext, useEffect, useRef, useState } from 'react';

import { SimpleSegmentControl } from './SimpleSegmentControl';
import SegmentedControl from './SegmentedControl';

interface AssetsSegmentControlProps {
tabSlug: string | null;
Expand All @@ -19,15 +19,38 @@ export const AssetsSegmentControl = memo<AssetsSegmentControlProps>(
({ tabSlug, onTokensTabClick, onCollectiblesTabClick, className }) => {
const ref = useAssetsSegmentControlRef();

const [tab, setTab] = useState(tabSlug ?? 'tokens');

useEffect(() => void setTab(tabSlug ?? 'tokens'), [tabSlug]);

const setActiveSegment = useCallback(
(val: string) => {
if (val === 'tokens') onTokensTabClick();
else onCollectiblesTabClick();
setTab(val);
},
[onTokensTabClick, onCollectiblesTabClick]
);

return (
<SimpleSegmentControl
ref={ref}
firstTitle="Tokens"
secondTitle="Collectibles"
activeSecond={tabSlug === 'collectibles'}
<SegmentedControl
name="assets-segment-control"
activeSegment={tab}
setActiveSegment={setActiveSegment}
controlRef={ref}
className={className}
onFirstClick={onTokensTabClick}
onSecondClick={onCollectiblesTabClick}
segments={[
{
label: 'Tokens',
value: 'tokens',
ref: useRef<HTMLDivElement>(null)
},
{
label: 'Collectibles',
value: 'collectibles',
ref: useRef<HTMLDivElement>(null)
}
]}
/>
);
}
Expand Down
5 changes: 3 additions & 2 deletions src/app/atoms/CaptionAlert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface Props {
type: CaptionAlertType;
message: string;
className?: string;
textClassName?: string;
}

const TYPE_CLASSES: Record<CaptionAlertType, string> = {
Expand All @@ -23,7 +24,7 @@ const TYPE_CLASSES: Record<CaptionAlertType, string> = {
};

/** Refer to `./Alert` for existing functionality */
export const CaptionAlert = memo<Props>(({ type, message, className }) => {
export const CaptionAlert = memo<Props>(({ type, message, className, textClassName }) => {
const Icon = (() => {
switch (type) {
case 'success':
Expand All @@ -41,7 +42,7 @@ export const CaptionAlert = memo<Props>(({ type, message, className }) => {
<div className={clsx('flex items-start p-3 gap-x-1 rounded-md', TYPE_CLASSES[type], className)}>
<Icon className="shrink-0 w-6 h-6" />

<p className="flex-1 text-font-description">{message}</p>
<p className={clsx('flex-1 text-font-description', textClassName)}>{message}</p>
</div>
);
});
2 changes: 1 addition & 1 deletion src/app/atoms/CleanButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const CleanButton = memo<Props>(({ className, size = 12, showText, onClick }) =>
return (
<button
id={CLEAN_BUTTON_ID}
ref={buttonRef}
ref={showText ? undefined : buttonRef}
type="button"
className={clsx(className, 'flex items-center ease-in-out duration-200', showText && 'px-1 py-0.5')}
tabIndex={-1}
Expand Down
41 changes: 24 additions & 17 deletions src/app/atoms/ConvertedInputAssetAmount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,47 @@ import React, { memo } from 'react';
import BigNumber from 'bignumber.js';

import InFiat from 'app/templates/InFiat';
import { T } from 'lib/i18n';
import { AssetMetadataBase, getAssetSymbol } from 'lib/metadata';

import Money from './Money';

interface Props {
tezosChainId: string;
chainId: string | number;
assetSlug: string;
assetMetadata?: AssetMetadataBase;
assetSymbol?: string;
amountValue: string;
toFiat: boolean;
evm?: boolean;
}

export const ConvertedInputAssetAmount = memo<Props>(
({ tezosChainId, assetSlug, assetMetadata, amountValue, toFiat }) => {
({ chainId, assetSlug, assetSymbol, amountValue, toFiat, evm }) => {
if (toFiat)
return (
<InFiat chainId={tezosChainId} assetSlug={assetSlug} volume={amountValue} roundingMode={BigNumber.ROUND_FLOOR}>
<InFiat
chainId={chainId}
assetSlug={assetSlug}
volume={amountValue}
smallFractionFont={false}
roundingMode={BigNumber.ROUND_FLOOR}
evm={evm}
>
{({ balance, symbol }) => (
<div className="-mb-1 flex">
<span className="mr-1">≈</span>
<span className="font-normal text-gray-700 mr-1 flex items-baseline">
{balance}
<span className="pr-px">{symbol}</span>
</span>{' '}
<T id="inFiat" />
<div className="flex items-baseline text-font-num-12 text-grey-1">
<span>≈</span>
<span className="mx-1">{balance}</span>
<span>{symbol}</span>
</div>
)}
</InFiat>
);

return (
<div className="-mb-3 flex">
<span className="mr-1">≈</span>
<span className="font-normal text-gray-700 mr-1">{amountValue}</span>{' '}
<T id="inAsset" substitutions={getAssetSymbol(assetMetadata, true)} />
<div className="flex items-baseline text-font-num-12 text-grey-1">
<span className="mr-0.5">≈</span>
<Money smallFractionFont={false} tooltipPlacement="bottom">
{amountValue}
</Money>
<span className="ml-1 truncate">{assetSymbol}</span>
</div>
);
}
Expand Down
25 changes: 17 additions & 8 deletions src/app/atoms/CopyButton.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React, { FC, HTMLAttributes, useCallback, useMemo } from 'react';
import React, { FC, HTMLAttributes, MouseEventHandler, useCallback, useMemo } from 'react';

import clsx from 'clsx';

import { toastSuccess } from 'app/toaster';
import { AnalyticsEventCategory, TestIDProps, setTestID, useAnalytics } from 'lib/analytics';
import { t } from 'lib/i18n';
import useCopyToClipboard from 'lib/ui/useCopyToClipboard';
import useTippy from 'lib/ui/useTippy';

interface CopyButtonProps extends HTMLAttributes<HTMLButtonElement>, TestIDProps {
export interface CopyButtonProps extends HTMLAttributes<HTMLButtonElement>, TestIDProps {
text: string;
isSecret?: boolean;
shouldShowTooltip?: boolean;
Expand All @@ -19,6 +21,8 @@ export const CopyButton: FC<CopyButtonProps> = ({
shouldShowTooltip,
children,
isSecret,
className,
onClick,
...rest
}) => {
const { trackEvent } = useAnalytics();
Expand All @@ -37,20 +41,25 @@ export const CopyButton: FC<CopyButtonProps> = ({

const buttonRef = useTippy<HTMLButtonElement>(tippyProps);

const handleCopyPress = useCallback(() => {
testID && trackEvent(testID, AnalyticsEventCategory.ButtonPress, testIDProperties);
const handleCopyPress = useCallback<MouseEventHandler<HTMLButtonElement>>(
e => {
testID && trackEvent(testID, AnalyticsEventCategory.ButtonPress, testIDProperties);

copy();
toastSuccess(t('copiedHash'));
}, [copy, testID, testIDProperties, trackEvent]);
copy();
toastSuccess(t('copiedHash'));
onClick?.(e);
},
[copy, testID, testIDProperties, trackEvent]
);

return (
<>
<button
ref={shouldShowTooltip ? buttonRef : undefined}
type="button"
{...rest}
className={clsx('w-fit', className)}
onClick={handleCopyPress}
{...rest}
{...setTestID(testID)}
>
{children}
Expand Down
2 changes: 1 addition & 1 deletion src/app/atoms/CustomModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { FC } from 'react';
import classNames from 'clsx';
import Modal from 'react-modal';

export type CustomModalProps = Modal.Props & React.PropsWithChildren;
type CustomModalProps = Modal.Props & React.PropsWithChildren;

const CustomModal: FC<CustomModalProps> = props => {
const { className, overlayClassName, ...restProps } = props;
Expand Down
Loading
Loading