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

Fix AMM display #334

Merged
merged 5 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 7 additions & 1 deletion packages/constants/src/xrpl/basic.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import {
TrustSetFlagsInterface,
NFTokenCreateOfferFlagsInterface,
AccountSetFlagsInterface,
OfferCreateFlagsInterface
OfferCreateFlagsInterface,
AMMDepositFlagsInterface,
AMMWithdrawFlagsInterface
} from 'xrpl';

export interface Memo {
Expand Down Expand Up @@ -34,3 +36,7 @@ export type CreateNFTOfferFlags = NFTokenCreateOfferFlagsInterface | number;
export type SetAccountFlags = AccountSetFlagsInterface | number;

export type CreateOfferFlags = OfferCreateFlagsInterface | number;

export type DepositAMMFlags = AMMDepositFlagsInterface | number;

export type WithdrawAMMFlags = AMMWithdrawFlagsInterface | number;
24 changes: 24 additions & 0 deletions packages/extension/src/components/atoms/Tokens/LPToken/LPToken.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { FC, SVGProps } from 'react';

export const LPToken: FC<SVGProps<SVGSVGElement>> = (props) => (
<svg
width={45}
height={45}
viewBox="0 0 200.000000 200.000000"
xmlns="http://www.w3.org/2000/svg"
{...props}
data-testid="lp-token-icon"
>
<circle cx="100" cy="100" r="100" fill="#1E1E1E" />
<g transform="translate(23, 19) scale(0.052)">
<path
d="M1295 2754 c-244 -44 -474 -160 -654 -330 -38 -35 -72 -64 -76 -64 -4 0 -44 34 -90 75 -45 41 -86 75 -90 75 -7 0 1 -669 7 -675 2 -2 64 3 138 11 74 7 212 20 305 29 94 9 183 18 200 22 l30 6 -95 88 -95 88 35 30 c53 46 187 134 260 171 169 85 289 114 470 114 252 0 453 -73 696 -255 118 -88 286 -265 364 -381 l62 -92 -7 59 c-4 33 -21 103 -37 155 -62 194 -171 372 -318 520 -191 191 -416 309 -679 354 -116 20 -316 20 -426 0z"
fill="#FFF"
/>
<path
d="M216 1323 c69 -402 326 -749 689 -931 94 -46 239 -94 345 -113 96 -17 334 -17 430 0 240 42 470 158 648 326 l80 75 88 -79 89 -79 3 336 c1 184 0 337 -2 340 -3 2 -121 -7 -263 -22 -142 -14 -293 -29 -336 -32 -43 -4 -76 -10 -75 -14 2 -4 45 -44 97 -91 l93 -84 -33 -28 c-52 -44 -206 -145 -268 -177 -154 -77 -301 -113 -466 -113 -220 0 -417 65 -628 206 -159 106 -353 304 -456 465 -18 28 -35 52 -37 52 -3 0 -2 -17 2 -37z"
fill="#FFF"
/>
</g>
</svg>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './LPToken';
1 change: 1 addition & 0 deletions packages/extension/src/components/atoms/Tokens/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './GemWallet';
export * from './LPToken';
export * from './Xrp';
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export const TokenDisplay: FC<TokenDisplayProps> = ({
tokenWarningMessage={tokenWarningMessage}
balance={balance}
issuerName={tokenData?.issuerName}
issuerAddress={issuer}
/>
) : (
<TokenInfo
Expand All @@ -112,6 +113,7 @@ export const TokenDisplay: FC<TokenDisplayProps> = ({
token={token}
tokenWarningMessage={tokenWarningMessage}
balance={balance}
issuerAddress={issuer}
/>
)}
{onExplainClick ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,29 @@ import { FC } from 'react';

import { Avatar } from '@mui/material';

import { GemWallet, Xrp } from '../../../../atoms';
import { GemWallet, LPToken, Xrp } from '../../../../atoms';

interface RenderTokenIconProps {
isXRPToken?: boolean;
tokenIconUrl: string;
token: string;
isLPToken?: boolean;
}

export const RenderTokenIcon: FC<RenderTokenIconProps> = ({ isXRPToken, tokenIconUrl, token }) => {
export const RenderTokenIcon: FC<RenderTokenIconProps> = ({
isXRPToken,
tokenIconUrl,
token,
isLPToken
}) => {
if (isXRPToken) {
return <Xrp />;
}

if (isLPToken) {
return <LPToken />;
}

if (tokenIconUrl) {
return <Avatar src={tokenIconUrl} alt={token} style={{ width: '45px', height: '45px' }} />;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Ref, forwardRef } from 'react';
import { Ref, forwardRef, useMemo } from 'react';

import { Typography } from '@mui/material';
import { Tooltip, Typography } from '@mui/material';

import { SECONDARY_GRAY } from '../../../../constants';
import { formatToken } from '../../../../utils';
import { LP_TOKEN_NAME } from '../../../../utils/trustlines';
import { RenderTokenIcon } from './RenderTokenIcon';

export interface TokenInfoProps {
Expand All @@ -13,9 +14,11 @@ export interface TokenInfoProps {
tokenWarningMessage: string | undefined;
balance: number;
issuerName?: string;
issuerAddress?: string;
}

const MAX_TOKEN_LENGTH = 5;
const MAX_ISSUER_LENGTH = 20;

export const TokenInfo = forwardRef((props: TokenInfoProps, ref: Ref<HTMLDivElement>) => {
const {
Expand All @@ -25,17 +28,33 @@ export const TokenInfo = forwardRef((props: TokenInfoProps, ref: Ref<HTMLDivElem
tokenWarningMessage,
balance,
issuerName,
issuerAddress,
...otherProps
} = props;

const displayToken =
token.length > MAX_TOKEN_LENGTH ? `${token.slice(0, MAX_TOKEN_LENGTH)}...` : token;
const isLPToken = useMemo(() => {
return token === LP_TOKEN_NAME;
}, [token]);

const displayToken = useMemo(() => {
return token.length > MAX_TOKEN_LENGTH && !isLPToken
? `${token.slice(0, MAX_TOKEN_LENGTH)}...`
: token;
}, [token, isLPToken]);

const formattedIssuerAddress = useMemo(() => {
return issuerAddress && issuerAddress.length > MAX_ISSUER_LENGTH
? `${issuerAddress.slice(0, MAX_ISSUER_LENGTH)}...`
: issuerAddress;
}, [issuerAddress]);

return (
<div ref={ref} {...otherProps} style={{ display: 'flex', alignItems: 'center' }}>
<RenderTokenIcon {...{ isXRPToken, tokenIconUrl: tokenIconUrl || '', token }} />
<RenderTokenIcon {...{ isXRPToken, tokenIconUrl: tokenIconUrl || '', token, isLPToken }} />
<div style={{ marginLeft: '10px' }}>
<Typography style={tokenWarningMessage ? { color: 'brown', cursor: 'help' } : undefined}>
<Typography
style={tokenWarningMessage && !isLPToken ? { color: 'brown', cursor: 'help' } : undefined}
>
{displayToken}
{issuerName ? (
<Typography
Expand All @@ -51,6 +70,29 @@ export const TokenInfo = forwardRef((props: TokenInfoProps, ref: Ref<HTMLDivElem
by {issuerName}
</Typography>
) : null}
{isLPToken ? (
<Tooltip
title={issuerAddress || ''}
placement="top"
arrow
disableHoverListener={
issuerAddress !== undefined && issuerAddress.length <= MAX_ISSUER_LENGTH
}
>
<Typography
component="span"
variant="caption"
style={{
marginLeft: '15px',
fontSize: 'smaller',
fontStyle: 'italic',
color: SECONDARY_GRAY
}}
>
{formattedIssuerAddress}
</Typography>
</Tooltip>
) : null}
</Typography>
<Typography variant="body2" style={{ color: SECONDARY_GRAY }}>
{formatToken(balance, token)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
import { FC } from 'react';

import { TypographyProps } from '@mui/material';
import { convertHexToString, Transaction } from 'xrpl';
import { convertHexToString, Currency, Transaction } from 'xrpl';
import { Amount, Memo, Signer } from 'xrpl/dist/npm/models/common';
import { GlobalFlags } from 'xrpl/dist/npm/models/transactions/common';

import { useWallet } from '../../../contexts';
import { formatFlags, formatTransferFee, parseAmountObject } from '../../../utils';
import {
convertHexCurrencyString,
formatFlags,
formatTransferFee,
parseAmountObject
} from '../../../utils';
import { KeyValueDisplay } from '../../atoms';

type XRPLTxProps = {
tx: Transaction;
displayTransactionType?: boolean;
useLegacy?: boolean;
hasMultipleAmounts?: boolean;
};

export const XRPLTransaction: FC<XRPLTxProps> = ({
tx,
displayTransactionType = true,
useLegacy = true
useLegacy = true,
hasMultipleAmounts = false
}) => {
const { selectedWallet, wallets } = useWallet();
const keyMap: Record<string, (value: any) => JSX.Element | null> = {
Expand All @@ -32,14 +39,28 @@ export const XRPLTransaction: FC<XRPLTxProps> = ({
renderAmount({
title: 'Amount',
value,
useLegacy
useLegacy,
hasMultipleAmounts
}),
Amount2: (value: Amount) =>
renderAmount({
title: 'Amount 2',
value,
useLegacy,
hasMultipleAmounts
}),
Account: (value: string) =>
wallets[selectedWallet].publicAddress === value
? null
: renderSimpleText({ title: 'Account', value, hasTooltip: true, useLegacy }),
NFTokenID: (value: string) =>
renderSimpleText({ title: 'NFT', value, hasTooltip: true, useLegacy }),
DeliverMin: (value: Amount) =>
renderAmount({
title: 'Deliver Min',
value,
useLegacy
}),
Destination: (value: string) =>
renderSimpleText({ title: 'Destination', value, hasTooltip: true, useLegacy }),
DestinationTag: (value?: number) =>
Expand Down Expand Up @@ -90,7 +111,15 @@ export const XRPLTransaction: FC<XRPLTxProps> = ({
OfferSequence: (value?: number) =>
renderSimpleText({ title: 'Offer Sequence', value, useLegacy }),
EmailHash: (value?: string) => renderSimpleText({ title: 'Email Hash', value, useLegacy }),
NFTokenTaxon: (value?: string) => renderSimpleText({ title: 'Taxon', value, useLegacy })
NFTokenTaxon: (value?: string) => renderSimpleText({ title: 'Taxon', value, useLegacy }),
Asset: (value: Currency) => renderCurrency({ title: 'Asset', value }),
Asset2: (value: Currency) => renderCurrency({ title: 'Asset 2', value }),
SendMax: (value: Amount) =>
renderAmount({
title: 'Send Max',
value,
useLegacy
})
};

const renderSimpleText = (params: {
Expand All @@ -115,14 +144,48 @@ export const XRPLTransaction: FC<XRPLTxProps> = ({
);
};

const renderCurrency = (params: { title: string; value: Currency }) => {
const { title, value } = params;
const currency = convertHexCurrencyString(value.currency);
const formatted = value.issuer ? `${currency}\n${value.issuer}` : currency;
FlorianBouron marked this conversation as resolved.
Show resolved Hide resolved
const hasTooltip = !!value.issuer;
return (
<KeyValueDisplay
keyName={title}
value={formatted}
useLegacy={useLegacy}
hasTooltip={hasTooltip}
/>
);
};

const renderAmount = (params: {
title: string;
value: Amount;
valueTypographyProps?: TypographyProps;
useLegacy: boolean;
hasMultipleAmounts?: boolean;
}) => {
const { title, value, valueTypographyProps, useLegacy } = params;
const res = parseAmountObject(value);
if (hasMultipleAmounts) {
const formattedValue = res.issuer
? `${res.amount} ${res.currency}\n${res.issuer}`
: `${res.amount} ${res.currency}`;

const hasTooltip = !!res.issuer;

return (
<KeyValueDisplay
keyName={title}
value={formattedValue}
valueTypographyProps={valueTypographyProps}
useLegacy={useLegacy}
hasTooltip={hasTooltip}
/>
);
}

return (
<>
<KeyValueDisplay
Expand Down Expand Up @@ -201,13 +264,18 @@ export const XRPLTransaction: FC<XRPLTxProps> = ({
const order = [
'TransactionType',
'Amount',
'Asset',
'Amount2',
'Asset2',
'LimitAmount',
'NFTokenID',
'NFTokenOffers',
'TakerGets',
'TakerPays',
'Destination',
'DestinationTag',
'DeliverMin',
'SendMax',
'NFTokenSellOffer',
'NFTokenBuyOffer',
'NFTokenBrokerFee',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
} from '../../../constants';
import { useLedger, useNetwork, useServer } from '../../../contexts';
import { convertHexCurrencyString, generateKey, saveInChromeSessionStorage } from '../../../utils';
import { isLPToken } from '../../../utils/trustlines';
import { TokenLoader } from '../../atoms';
import { InformationMessage } from '../../molecules/InformationMessage';
import { TokenDisplay } from '../../molecules/TokenDisplay';
Expand Down Expand Up @@ -203,8 +204,10 @@ export const TokenListing: FC<TokenListingProps> = ({ address }) => {
onExplainClick={handleOpen}
/>
{trustLineBalances.map((trustedLine) => {
const isAMMLPToken = isLPToken(trustedLine.currency);
const currencyToDisplay = convertHexCurrencyString(trustedLine.currency);
const canBeEdited = trustedLine.trustlineDetails || trustedLine.value !== '0';
const canBeEdited =
(trustedLine.trustlineDetails || trustedLine.value !== '0') && !isAMMLPToken;
const limit = trustedLine.trustlineDetails?.limit || 0;
const noRipple = trustedLine.trustlineDetails?.noRipple || false;
const flags = noRipple ? TrustSetFlagsBitmask.tfSetNoRipple : undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export const TransactionDetails: FC<TransactionDetailsProps> = ({
return <LoadingOverlay />;
}

const hasMultipleAmounts =
('Amount' in txParam && 'Amount2' in txParam) ||
('DeliverMin' in txParam && 'SendMax' in txParam);

return (
<>
<DataCard
Expand All @@ -37,6 +41,7 @@ export const TransactionDetails: FC<TransactionDetailsProps> = ({
tx={txParam}
useLegacy={false}
displayTransactionType={displayTransactionType}
hasMultipleAmounts={hasMultipleAmounts}
/>
}
dataName="Transaction details"
Expand Down
6 changes: 6 additions & 0 deletions packages/extension/src/utils/convertHexCurrencyString.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { Amount, IssuedCurrencyAmount } from 'xrpl/dist/npm/models/common';

import { currencyToHex } from './hexConverter';
import { isLPToken, LP_TOKEN_NAME } from './trustlines';

export const convertHexCurrencyString = (hexCurrency: string): string => {
if (hexCurrency.length !== 40) {
return hexCurrency;
}

if (isLPToken(hexCurrency)) {
return LP_TOKEN_NAME;
}

// Trim trailing zeros in the hex string
hexCurrency = hexCurrency.toLowerCase().replace(/0+$/, '');

Expand Down
Loading
Loading