Commit 17e2f303 authored by tom's avatar tom

multiple nft token transfers

parent 062f9b3f
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.868 1.55a.377.377 0 0 0-.378 0L3.188 6.363A.377.377 0 0 0 3 6.69v9.622c0 .135.072.26.188.327l8.302 4.811a.377.377 0 0 0 .378 0l8.302-4.811a.377.377 0 0 0 .188-.327V6.69a.377.377 0 0 0-.188-.327l-8.302-4.811ZM3.755 16.095V6.906l7.924-4.592 7.925 4.592v9.188l-7.925 4.592-7.924-4.592ZM8.66 6.972a.377.377 0 0 0-.754 0v6.354l-1.53-4.587a.377.377 0 0 0-.734.12v5.66a.377.377 0 0 0 .754 0v-3.335l1.529 4.586a.377.377 0 0 0 .735-.12V6.973Zm2.824-2.448a.377.377 0 0 1 .386-.003l2.262 1.32a.377.377 0 0 1-.38.652l-2.07-1.208-1.89 1.145v4.693h2.265a.377.377 0 0 1 0 .754H9.792v4.906a.377.377 0 0 1-.754 0V6.217c0-.132.069-.254.182-.323l2.264-1.37Zm3.195 2.06a.377.377 0 0 1 .515-.141l2.333 1.333a.377.377 0 1 1-.375.655l-.567-.324v7.544a.377.377 0 1 1-.755 0V7.676l-1.01-.578a.377.377 0 0 1-.141-.515Z" fill="currentColor"/>
</svg>
import type { AddressParam } from './addressParams'; import type { AddressParam } from './addressParams';
export type ERC1155TotalPayload = {
value: string;
token_id: string;
}
export type TokenTransfer = ( export type TokenTransfer = (
{ {
token_type: 'ERC-20'; token_type: 'ERC-20';
...@@ -15,17 +20,7 @@ export type TokenTransfer = ( ...@@ -15,17 +20,7 @@ export type TokenTransfer = (
} | } |
{ {
token_type: 'ERC-1155'; token_type: 'ERC-1155';
total: { total: ERC1155TotalPayload | Array<ERC1155TotalPayload>;
value: string;
token_id: string;
};
} |
{
token_type: 'ERC-1155_batch';
total: Array<{
value: string;
token_id: string;
}>;
} }
) & TokenTransferBase ) & TokenTransferBase
......
...@@ -33,13 +33,13 @@ const CurrencyValue = ({ value, currency = '', unit = 'wei', exchangeRate, class ...@@ -33,13 +33,13 @@ const CurrencyValue = ({ value, currency = '', unit = 'wei', exchangeRate, class
const usdBn = valueCurr.times(exchangeRateBn); const usdBn = valueCurr.times(exchangeRateBn);
return ( return (
<Box as="span" className={ className }> <Box as="span" className={ className } display="inline-flex" rowGap={ 3 } columnGap={ 1 }>
<Text as="span"> <Text as="span">
{ accuracy ? valueCurr.toFixed(accuracy) : valueCurr.toFixed() }{ currency ? ` ${ currency }` : '' } { accuracy ? valueCurr.toFixed(accuracy) : valueCurr.toFixed() }{ currency ? ` ${ currency }` : '' }
</Text> </Text>
{ exchangeRate !== undefined && exchangeRate !== null && { exchangeRate !== undefined && exchangeRate !== null &&
// TODO: mb need to implement rounding to the first significant digit // TODO: mb need to implement rounding to the first significant digit
<Text as="span" variant="secondary" whiteSpace="pre" fontWeight={ 400 }> (${ accuracyUsd ? usdBn.toFixed(accuracyUsd) : usdBn.toFixed() })</Text> <Text as="span" variant="secondary" fontWeight={ 400 }>(${ accuracyUsd ? usdBn.toFixed(accuracyUsd) : usdBn.toFixed() })</Text>
} }
</Box> </Box>
); );
......
import { Flex, Link, Text, Icon } from '@chakra-ui/react';
import React from 'react';
import nftIcon from 'icons/nft_shield.svg';
import link from 'lib/link/link';
import TokenSnippet from 'ui/shared/TokenSnippet';
interface Props {
value: string;
tokenId: string;
hash: string;
symbol: string;
}
const NftTokenTransferSnippet = (props: Props) => {
const num = props.value === '1' ? '' : props.value;
const url = link('token_instance_item', { hash: props.hash, id: props.tokenId });
return (
<Flex alignItems="center">
<Text fontWeight={ 500 } as="span">For { num } token ID:</Text>
<Icon as={ nftIcon } boxSize={ 6 } ml={ 3 } mr={ 1 }/>
<Link href={ url } fontWeight={ 600 }>{ props.tokenId }</Link>
<TokenSnippet symbol={ props.symbol } hash={ props.hash } name="Foo" ml={ 3 }/>
</Flex>
);
};
export default React.memo(NftTokenTransferSnippet);
import { Flex, Icon, Text, Link } from '@chakra-ui/react'; import { Flex, Icon, Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TokenTransfer as TTokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer as TTokenTransfer } from 'types/api/tokenTransfer';
import rightArrowIcon from 'icons/arrows/east.svg'; import rightArrowIcon from 'icons/arrows/east.svg';
import { space } from 'lib/html-entities'; import { space } from 'lib/html-entities';
import link from 'lib/link/link';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import TokenSnippet from 'ui/shared/TokenSnippet'; import TokenSnippet from 'ui/shared/TokenSnippet';
import NftTokenTransferSnippet from 'ui/tx/NftTokenTransferSnippet';
type Props = TTokenTransfer type Props = TTokenTransfer;
const TokenTransfer = (props: Props) => { const TokenTransfer = (props: Props) => {
const isColumnLayout = props.token_type === 'ERC-1155' && Array.isArray(props.total);
const tokenSnippet = <TokenSnippet symbol={ props.token_symbol } hash={ props.token_address } name="Foo" ml={ 3 }/>;
const content = (() => { const content = (() => {
switch (props.token_type) { switch (props.token_type) {
case 'ERC-20': case 'ERC-20':
return ( return (
<Text fontWeight={ 500 } as="span">For:{ space } <Flex>
<CurrencyValue value={ props.total.value } unit="ether" exchangeRate={ props.exchange_rate } fontWeight={ 600 }/> <Text fontWeight={ 500 } as="span">For:{ space }
</Text> <CurrencyValue value={ props.total.value } unit="ether" exchangeRate={ props.exchange_rate } fontWeight={ 600 }/>
</Text>
{ tokenSnippet }
</Flex>
); );
case 'ERC-721': { case 'ERC-721': {
const url = link('token_instance_item', { hash: props.token_address, id: props.total.token_id });
return ( return (
<Text fontWeight={ 500 } as="span">For token ID:{ space } <NftTokenTransferSnippet
<Link href={ url } fontWeight={ 600 }>{ props.total.token_id }</Link> tokenId={ props.total.token_id }
</Text> value="1"
hash={ props.token_address }
symbol={ props.token_symbol }
/>
); );
} }
default: case 'ERC-1155': {
return null; const items = Array.isArray(props.total) ? props.total : [ props.total ];
return items.map((item) => (
<NftTokenTransferSnippet
key={ item.token_id }
tokenId={ item.token_id }
value={ item.value }
hash={ props.token_address }
symbol={ props.token_symbol }
/>
));
}
} }
})(); })();
return ( return (
<Flex alignItems="center" flexWrap="wrap" columnGap={ 3 } rowGap={ 3 }> <Flex
alignItems={ isColumnLayout ? 'flex-start' : 'center' }
flexWrap="wrap"
columnGap={ 3 }
rowGap={ 3 }
flexDir={ isColumnLayout ? 'column' : 'row' }
>
<Flex alignItems="center"> <Flex alignItems="center">
<AddressLink fontWeight="500" hash={ props.from.hash } truncation="constant"/> <AddressLink fontWeight="500" hash={ props.from.hash } truncation="constant"/>
<Icon as={ rightArrowIcon } boxSize={ 6 } mx={ 2 } color="gray.500"/> <Icon as={ rightArrowIcon } boxSize={ 6 } mx={ 2 } color="gray.500"/>
<AddressLink fontWeight="500" hash={ props.to.hash } truncation="constant"/> <AddressLink fontWeight="500" hash={ props.to.hash } truncation="constant"/>
</Flex> </Flex>
{ content } <Flex flexDir="column" rowGap={ 5 }>
<TokenSnippet symbol={ props.token_symbol } hash={ props.token_address } name="Foo"/> { content }
</Flex>
</Flex> </Flex>
); );
}; };
export default TokenTransfer; export default React.memo(TokenTransfer);
...@@ -190,7 +190,12 @@ const TxDetails = () => { ...@@ -190,7 +190,12 @@ const TxDetails = () => {
title="Transaction fee" title="Transaction fee"
hint="Total transaction fee." hint="Total transaction fee."
> >
<CurrencyValue value={ String(data.fee.value) } currency={ appConfig.network.currency } exchangeRate={ data.exchange_rate }/> <CurrencyValue
value={ String(data.fee.value) }
currency={ appConfig.network.currency }
exchangeRate={ data.exchange_rate }
flexWrap="wrap"
/>
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Gas price" title="Gas price"
...@@ -218,18 +223,18 @@ const TxDetails = () => { ...@@ -218,18 +223,18 @@ const TxDetails = () => {
<Box> <Box>
<Text as="span" fontWeight="500">Base: </Text> <Text as="span" fontWeight="500">Base: </Text>
<Text fontWeight="600" as="span">{ BigNumber(data.base_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() }</Text> <Text fontWeight="600" as="span">{ BigNumber(data.base_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() }</Text>
{ (data.max_fee_per_gas || data.max_priority_fee_per_gas) && <TextSeparator/> }
</Box> </Box>
) } ) }
{ data.max_fee_per_gas && ( { data.max_fee_per_gas && (
<Box> <Box>
<TextSeparator/>
<Text as="span" fontWeight="500">Max: </Text> <Text as="span" fontWeight="500">Max: </Text>
<Text fontWeight="600" as="span">{ BigNumber(data.max_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() }</Text> <Text fontWeight="600" as="span">{ BigNumber(data.max_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() }</Text>
{ data.max_priority_fee_per_gas && <TextSeparator/> }
</Box> </Box>
) } ) }
{ data.max_priority_fee_per_gas && ( { data.max_priority_fee_per_gas && (
<Box> <Box>
<TextSeparator/>
<Text as="span" fontWeight="500">Max priority: </Text> <Text as="span" fontWeight="500">Max priority: </Text>
<Text fontWeight="600" as="span">{ BigNumber(data.max_priority_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() }</Text> <Text fontWeight="600" as="span">{ BigNumber(data.max_priority_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() }</Text>
</Box> </Box>
...@@ -242,7 +247,12 @@ const TxDetails = () => { ...@@ -242,7 +247,12 @@ const TxDetails = () => {
hint={ `Amount of ${ appConfig.network.currency } burned for this transaction. Equals Block Base Fee per Gas * Gas Used.` } hint={ `Amount of ${ appConfig.network.currency } burned for this transaction. Equals Block Base Fee per Gas * Gas Used.` }
> >
<Icon as={ flameIcon } mr={ 1 } boxSize={ 5 } color="gray.500"/> <Icon as={ flameIcon } mr={ 1 } boxSize={ 5 } color="gray.500"/>
<CurrencyValue value={ String(data.tx_burnt_fee) } currency={ appConfig.network.currency } exchangeRate={ data.exchange_rate }/> <CurrencyValue
value={ String(data.tx_burnt_fee) }
currency={ appConfig.network.currency }
exchangeRate={ data.exchange_rate }
flexWrap="wrap"
/>
</DetailsInfoItem> </DetailsInfoItem>
) } ) }
<GridItem colSpan={{ base: undefined, lg: 2 }}> <GridItem colSpan={{ base: undefined, lg: 2 }}>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment