Skip to content

Commit

Permalink
fix: is asset transferable logic, closes #2154
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranjamie committed Jan 24, 2022
1 parent 881e88d commit d3e5927
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 3 deletions.
74 changes: 74 additions & 0 deletions src/app/common/transactions/is-transferable-asset.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { AssetWithMeta } from '../asset-types';
import { isTransferableAsset } from './is-transferable-asset';

describe(isTransferableAsset.name, () => {
test('assets with a name, symbol and decimals are allowed to be transferred', () => {
const asset = {
type: 'ft',
meta: {
name: 'Test token',
symbol: 'TEST',
decimals: 2,
},
} as AssetWithMeta;
expect(isTransferableAsset(asset)).toBeTruthy();
});

test('stella the cat token', () => {
const asset = {
type: 'ft',
subtitle: 'ST6G7…PSTK7.stella-the-cat',
contractAddress: 'ST6G7N19FKNW24XH5JQ5P5WR1DN10QWMKQSPSTK7',
contractName: 'stella-the-cat',
name: 'stella-token',
canTransfer: true,
meta: {
token_uri: 'https://example.com',
name: 'SteLLa the Cat',
description: '',
image_uri: '',
image_canonical_uri: '',
symbol: 'CAT',
decimals: 9,
tx_id: '0x56c6381874c8f6b152c8815d950764b8759b97660fdc50091f3c1368d7f1c514',
sender_address: 'ST6G7N19FKNW24XH5JQ5P5WR1DN10QWMKQSPSTK7',
},
} as unknown as AssetWithMeta;
expect(isTransferableAsset(asset)).toBeTruthy();
});

test('a token with no decimals is transferable', () => {
const asset = {
type: 'ft',
meta: {
token_uri: 'https://example.com',
name: 'SteLLa the Cat',
description: '',
image_uri: '',
image_canonical_uri: '',
symbol: 'CAT',
decimals: 0,
tx_id: '0x56c6381874c8f6b152c8815d950764b8759b97660fdc50091f3c1368d7f1c514',
sender_address: 'ST6G7N19FKNW24XH5JQ5P5WR1DN10QWMKQSPSTK7',
},
} as unknown as AssetWithMeta;
expect(isTransferableAsset(asset)).toBeTruthy();
});

test('assets missing either name, symbol or decimals may not be transferred', () => {
const asset = {
type: 'ft',
meta: {
name: 'Test token',
symbol: 'TEST',
decimals: undefined,
},
} as unknown as AssetWithMeta;
expect(isTransferableAsset(asset)).toBeFalsy();
});

test('NFTs cannot be sent', () => {
const asset = { type: 'nft' } as unknown as AssetWithMeta;
expect(isTransferableAsset(asset)).toBeFalsy();
});
});
11 changes: 11 additions & 0 deletions src/app/common/transactions/is-transferable-asset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { AssetWithMeta } from '../asset-types';

export function isTransferableAsset(asset: AssetWithMeta) {
if (asset.type === 'stx') return true;
if (asset.type === 'ft') {
return asset.meta
? Boolean(typeof asset.meta.decimals === 'number' && asset.meta.name && asset.meta.symbol)
: false;
}
return false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export const AssetSearch: React.FC<AssetSearchProps> = memo(
({ autoFocus, onItemClick, ...rest }) => {
const { selectedAsset } = useSelectedAsset();
const assets = useTransferableAssets();
console.log(assets);

if (!assets) {
return (
Expand Down
7 changes: 4 additions & 3 deletions src/app/store/assets/asset.hooks.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useMemo } from 'react';
import { useAtomValue, useUpdateAtom } from 'jotai/utils';
import { baseAssetsAnchoredState, mergeAssetBalances } from '@app/store/assets/tokens';
import type { Asset, AssetWithMeta } from '@app/common/asset-types';
Expand All @@ -13,24 +14,24 @@ import { transformAssets } from './utils';
import { useAssetsWithMetadata } from '@app/query/tokens/fungible-token-metadata.query';
import { getFullyQualifiedAssetName } from '@app/common/hooks/use-selected-asset';
import { useFungibleTokenMetadata } from '@app/query/tokens/fungible-token-metadata.hook';
import { useMemo } from 'react';
import { formatContractId } from '@app/common/utils';
import { isTransferableAsset } from '@app/common/transactions/is-transferable-asset';

export function useAssets() {
return useAtomValue(baseAssetsAnchoredState);
}

export function useTransferableAssets() {
const assets = useAssetsWithMetadata();
return assets.filter(a => !!a.meta || a.type !== 'nft') as AssetWithMeta[];
return assets.filter(asset => isTransferableAsset(asset));
}

export function useAssetWithMetadata(asset: Asset) {
const assetMetadata = useFungibleTokenMetadata(
formatContractId(asset.contractAddress, asset.contractName)
);
if (asset.type === 'ft') {
const canTransfer = !!assetMetadata;
const canTransfer = assetMetadata ? isTransferableAsset(asset) : false;
return { ...asset, meta: assetMetadata, canTransfer, hasMemo: canTransfer } as AssetWithMeta;
}
return asset as AssetWithMeta;
Expand Down

0 comments on commit d3e5927

Please sign in to comment.