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

Detect invalid brc20 tokens #455

Merged
merged 9 commits into from
Jun 20, 2023
214 changes: 110 additions & 104 deletions src/app/screens/ordinalDetail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,18 +129,18 @@ const RowContainer = styled.div((props) => ({
flexDirection: 'row',
}));

const ColumnContainer = styled.div((props) => ({
const ColumnContainer = styled.div({
display: 'flex',
alignItems: 'flex-start',
flexDirection: 'column',
width: '100%',
}));
});

const Row = styled.div((props) => ({
const Row = styled.div({
display: 'flex',
justifyContent: 'space-between',
flexDirection: 'row',
}));
});

const MintLimitContainer = styled.div((props) => ({
marginLeft: props.theme.spacing(30),
Expand Down Expand Up @@ -287,10 +287,8 @@ function OrdinalDetailScreen() {
}, [selectedOrdinal?.content_type]);

useEffect(() => {
if (textContent) {
if (textContent.includes('brc-20')) {
setIsBrc20Ordinal(true);
}
if (textContent?.includes('brc-20')) {
setIsBrc20Ordinal(true);
}
}, [textContent]);

Expand All @@ -305,6 +303,7 @@ function OrdinalDetailScreen() {
url: chrome.runtime.getURL('options.html#/nft-dashboard/ordinal-detail'),
});
};

const showAlert = () => {
setshowSendOridnalsAlert(true);
};
Expand All @@ -327,79 +326,6 @@ function OrdinalDetailScreen() {
}
};

const showBrc20OrdinalDetail = (isGallery: boolean) => {
const regex = /”/g;
const validBrcContentValue = textContent.replace(regex, '"');
const content = JSON.parse(validBrcContentValue);
if (content.op === 'mint') {
return (
<ColumnContainer>
<OrdinalAttributeComponent title={t('AMOUNT_TO_MINT')} value={content.amt} />
{!isGallery && (
<OrdinalAttributeComponent
title={t('OWNED_BY')}
value={`${ordinalsAddress.substring(0, 4)}...${ordinalsAddress.substring(
ordinalsAddress.length - 4,
ordinalsAddress.length,
)}`}
showOridnalTag
isAddress
/>
)}
</ColumnContainer>
);
}
if (content.op === 'transfer') {
return (
<ColumnContainer>
<DetailSection isGallery={isGalleryOpen}>
<OrdinalAttributeComponent title={t('AMOUNT_TO_TRANSFER')} value={content.amt} />
<OrdinalAttributeComponent
title={t('BRC20_TRANSFER_STATUS')}
value={isTransferValid}
valueColor={isBrcTransferValid(selectedOrdinal!) ? theme.colors.feedback.success : theme.colors.feedback.error}
isAddress
/>
</DetailSection>
{!isGallery && (
<OrdinalAttributeComponent
title={t('OWNED_BY')}
value={`${ordinalsAddress.substring(0, 4)}...${ordinalsAddress.substring(
ordinalsAddress.length - 4,
ordinalsAddress.length,
)}`}
showOridnalTag
isAddress
/>
)}
</ColumnContainer>
);
}
if (content.op === 'deploy') {
return (
<ColumnContainer>
<Row>
<OrdinalAttributeComponent title={t('TOTAL_SUPPLY')} value={content.max} />
<MintLimitContainer>
<OrdinalAttributeComponent title={t('MINT_LIMIT')} value={content.lim} />
</MintLimitContainer>
</Row>
{!isGallery && (
<OrdinalAttributeComponent
title={t('OWNED_BY')}
value={`${ordinalsAddress.substring(0, 4)}...${ordinalsAddress.substring(
ordinalsAddress.length - 4,
ordinalsAddress.length,
)}`}
showOridnalTag
isAddress
/>
)}
</ColumnContainer>
);
}
};

const ownedByView = (
<RowContainer>
<NftOwnedByText>{t('OWNED_BY')}</NftOwnedByText>
Expand All @@ -415,29 +341,6 @@ function OrdinalDetailScreen() {
</OrdinalsTag>
</RowContainer>
);
const extensionView = (
<ExtensionContainer>
<CollectibleText>{isBrc20Ordinal ? t('BRC20_INSCRIPTION') : t('COLLECTIBLE')}</CollectibleText>
<OrdinalTitleText>{`${t('INSCRIPTION')} ${selectedOrdinal?.number}`}</OrdinalTitleText>
<WebGalleryButton onClick={openInGalleryView}>
<>
<ButtonImage src={SquaresFour} />
<WebGalleryButtonText>{t('WEB_GALLERY')}</WebGalleryButtonText>
</>
</WebGalleryButton>
<ExtensionOrdinalsContainer>
<OrdinalImage ordinal={selectedOrdinal!} />
</ExtensionOrdinalsContainer>
{notSupportedOrdinal && <InfoContainer bodyText={t('ORDINAL_NOT_DISPLAYED')} />}
<ButtonContainer>
<SendButton onClick={handleSendOrdinal}>
<img src={ArrowUp} alt="arrow" />
<h1>{t('SEND')}</h1>
</SendButton>
</ButtonContainer>
{isBrc20Ordinal ? showBrc20OrdinalDetail(false) : ownedByView}
</ExtensionContainer>
);

const ordinalDescriptionData = (
<>
Expand Down Expand Up @@ -469,6 +372,109 @@ function OrdinalDetailScreen() {
</>
);

const showBrc20OrdinalDetail = (isGallery: boolean) => {
try {
const regex = /”/g;
const validBrcContentValue = textContent.replace(regex, '"');
const content = JSON.parse(validBrcContentValue);

switch (content.op) {
case 'mint':
return (
<ColumnContainer>
<OrdinalAttributeComponent title={t('AMOUNT_TO_MINT')} value={content.amt} />
{!isGallery && (
<OrdinalAttributeComponent
title={t('OWNED_BY')}
value={`${ordinalsAddress.substring(0, 4)}...${ordinalsAddress.substring(
ordinalsAddress.length - 4,
ordinalsAddress.length,
)}`}
showOridnalTag
isAddress
/>
)}
</ColumnContainer>
);
case 'transfer':
return (
<ColumnContainer>
<DetailSection isGallery={isGalleryOpen}>
<OrdinalAttributeComponent title={t('AMOUNT_TO_TRANSFER')} value={content.amt} />
<OrdinalAttributeComponent
title={t('BRC20_TRANSFER_STATUS')}
value={isTransferValid}
valueColor={isBrcTransferValid(selectedOrdinal!) ? theme.colors.feedback.success : theme.colors.feedback.error}
isAddress
/>
</DetailSection>
{!isGallery && (
<OrdinalAttributeComponent
title={t('OWNED_BY')}
value={`${ordinalsAddress.substring(0, 4)}...${ordinalsAddress.substring(
ordinalsAddress.length - 4,
ordinalsAddress.length,
)}`}
showOridnalTag
isAddress
/>
)}
</ColumnContainer>
);
case 'deploy':
return (
<ColumnContainer>
<Row>
<OrdinalAttributeComponent title={t('TOTAL_SUPPLY')} value={content.max} />
<MintLimitContainer>
<OrdinalAttributeComponent title={t('MINT_LIMIT')} value={content.lim} />
</MintLimitContainer>
</Row>
{!isGallery && (
<OrdinalAttributeComponent
title={t('OWNED_BY')}
value={`${ordinalsAddress.substring(0, 4)}...${ordinalsAddress.substring(
ordinalsAddress.length - 4,
ordinalsAddress.length,
)}`}
showOridnalTag
isAddress
/>
)}
</ColumnContainer>
);
default:
return null;
}
} catch (error) {
return isGallery ? ordinalDescriptionData : ownedByView;
}
};

const extensionView = (
<ExtensionContainer>
<CollectibleText>{isBrc20Ordinal ? t('BRC20_INSCRIPTION') : t('COLLECTIBLE')}</CollectibleText>
<OrdinalTitleText>{`${t('INSCRIPTION')} ${selectedOrdinal?.number}`}</OrdinalTitleText>
<WebGalleryButton onClick={openInGalleryView}>
<>
<ButtonImage src={SquaresFour} />
<WebGalleryButtonText>{t('WEB_GALLERY')}</WebGalleryButtonText>
</>
</WebGalleryButton>
<ExtensionOrdinalsContainer>
<OrdinalImage ordinal={selectedOrdinal!} />
</ExtensionOrdinalsContainer>
{notSupportedOrdinal && <InfoContainer bodyText={t('ORDINAL_NOT_DISPLAYED')} />}
<ButtonContainer>
<SendButton onClick={handleSendOrdinal}>
<img src={ArrowUp} alt="arrow" />
<h1>{t('SEND')}</h1>
</SendButton>
</ButtonContainer>
{isBrc20Ordinal ? showBrc20OrdinalDetail(false) : ownedByView}
</ExtensionContainer>
);

const galleryView = (
<Container>
<BackButtonContainer>
Expand Down
Loading