Skip to content

Commit

Permalink
feat(ts-sdk, explorer): improve object type truncation (#3750)
Browse files Browse the repository at this point in the history
* feat: improve type truncation

* refactor: use format digests for digests

* revert: dapp changes

* feat: improve type truncation

* feat: Add unit test for formatters

* fmt

---------

Co-authored-by: marc2332 <[email protected]>
  • Loading branch information
begonaalvarezd and marc2332 authored Nov 4, 2024
1 parent 08a371a commit bf5189f
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 12 deletions.
4 changes: 2 additions & 2 deletions apps/explorer/src/components/ui/InternalLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Modifications Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { formatAddress, formatDigest } from '@iota/iota-sdk/utils';
import { formatAddress, formatDigest, formatType } from '@iota/iota-sdk/utils';
import { type ReactNode } from 'react';

import { Link, type LinkProps } from '~/components/ui';
Expand Down Expand Up @@ -48,6 +48,6 @@ export const CheckpointSequenceLink = createInternalLink('checkpoint', 'sequence
export const AddressLink = createInternalLink('address', 'address', (addressOrNs) =>
formatAddress(addressOrNs),
);
export const ObjectLink = createInternalLink('object', 'objectId', formatAddress);
export const ObjectLink = createInternalLink('object', 'objectId', formatType);
export const TransactionLink = createInternalLink('txblock', 'digest', formatDigest);
export const ValidatorLink = createInternalLink('validator', 'address', formatAddress);
8 changes: 4 additions & 4 deletions apps/explorer/src/lib/ui/utils/generateObjectListColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import { TableCellBase, TableCellText } from '@iota/apps-ui-kit';
import type { ColumnDef } from '@tanstack/react-table';

import { parseObjectType, trimStdLibPrefix } from '~/lib';
import { ObjectVideoImage, ObjectLink } from '~/components';
import type { IotaObjectResponse } from '@iota/iota-sdk/client';
import { formatAddress, formatType } from '@iota/iota-sdk/utils';
import { ObjectLink, ObjectVideoImage } from '~/components';
import { useResolveVideo } from '~/hooks';
import { formatAddress } from '@iota/iota-sdk/utils';
import { parseObjectType, trimStdLibPrefix } from '~/lib';

function Asset({ object }: { object: IotaObjectResponse }) {
const video = useResolveVideo(object);
Expand Down Expand Up @@ -56,7 +56,7 @@ export function generateObjectListColumns(): ColumnDef<IotaObjectResponse>[] {
cell({ row: { original: object } }) {
const objectId = object?.data?.objectId;
if (!objectId) return null;
const type = trimStdLibPrefix(parseObjectType(object));
const type = formatType(trimStdLibPrefix(parseObjectType(object)));
return (
<TableCellBase>
<ObjectLink objectId={objectId} label={type}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { IotaTransactionBlockKind, IotaTransactionBlockResponse } from '@io
import { TableCellBase, TableCellText } from '@iota/apps-ui-kit';
import type { ColumnDef } from '@tanstack/react-table';
import { AddressLink, TransactionLink } from '../../../components/ui';
import { formatAddress, NANOS_PER_IOTA } from '@iota/iota-sdk/utils';
import { formatAddress, formatDigest, NANOS_PER_IOTA } from '@iota/iota-sdk/utils';
import { getElapsedTime } from '~/pages/epochs/utils';

/**
Expand All @@ -25,7 +25,7 @@ export function generateTransactionsTableColumns(): ColumnDef<IotaTransactionBlo
<TableCellBase>
<TransactionLink
digest={digest}
label={<TableCellText>{formatAddress(digest)}</TableCellText>}
label={<TableCellText>{formatDigest(digest)}</TableCellText>}
/>
</TableCellBase>
);
Expand Down
6 changes: 3 additions & 3 deletions apps/explorer/src/pages/object-result/views/ObjectView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { CoinFormat, useFormatCoin } from '@iota/core';
import { type IotaObjectResponse, type ObjectOwner } from '@iota/iota-sdk/client';
import {
formatAddress,
formatDigest,
IOTA_TYPE_ARG,
normalizeStructTag,
parseStructTag,
Expand Down Expand Up @@ -113,12 +114,11 @@ function TypeCard({ objectType }: TypeCardCardProps): JSX.Element {
};

const normalizedStructTag = normalizeStructTag(structTag);

return (
<DisplayStats
label="Type"
value={
<ObjectLink objectId={`${address}?module=${module}`}>
<ObjectLink objectId={`${address}?module=${module}`} label={normalizedStructTag}>
{normalizedStructTag}
</ObjectLink>
}
Expand All @@ -144,7 +144,7 @@ function LastTxBlockCard({ digest }: LastTxBlockCardProps): JSX.Element {
return (
<DisplayStats
label="Last Transaction Block Digest"
value={<TransactionLink digest={digest}>{formatAddress(digest)}</TransactionLink>}
value={<TransactionLink digest={digest}>{formatDigest(digest)}</TransactionLink>}
/>
);
}
Expand Down
13 changes: 13 additions & 0 deletions sdk/typescript/src/utils/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Modifications Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { isValidIotaAddress, isValidIotaObjectId, IOTA_ADDRESS_LENGTH } from './iota-types.js';

const ELLIPSIS = '\u{2026}';

export function formatAddress(address: string) {
Expand All @@ -18,3 +20,14 @@ export function formatDigest(digest: string) {
// Use 10 first characters
return `${digest.slice(0, 10)}${ELLIPSIS}`;
}

export function formatType(type: string) {
const objectAddressPattern = new RegExp(`0x[a-fA-F0-9]{${IOTA_ADDRESS_LENGTH * 2}}`, 'g');
const matches = type.match(objectAddressPattern) ?? [];
for (const match of matches) {
if (isValidIotaAddress(match) || isValidIotaObjectId(match)) {
type = type.replace(match, formatAddress(match));
}
}
return type;
}
2 changes: 1 addition & 1 deletion sdk/typescript/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Modifications Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

export { formatAddress, formatDigest } from './format.js';
export { formatAddress, formatDigest, formatType } from './format.js';
export {
isValidIotaAddress,
isValidIotaObjectId,
Expand Down
19 changes: 19 additions & 0 deletions sdk/typescript/test/unit/format.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { describe, expect, it } from 'vitest';
import { formatType } from '../../src/utils';

describe('Formatters', () => {
it('formatType formats correctly', async () => {
const typeClock = '0x2::clock::Clock';
expect(formatType(typeClock), '0x0000…0002::clock::Clock');

const typeCoolCoin =
'0x2::coin::Coin<0x2e0b8d1e74947a2d97121bc7b7981eaff1f32911d15c5e0921fdd08cf61f445b::cool_coin::COOL_COIN>';
expect(
formatType(typeCoolCoin),
'0x0000…0002::coin::Coin<x2e0b8d…445b::cool_coin::COOL_COIN>',
);
});
});

0 comments on commit bf5189f

Please sign in to comment.