Skip to content

Commit

Permalink
refactor(frontend): change visual name for ckERC20 tokens (#1962)
Browse files Browse the repository at this point in the history
# Motivation

We will mark the ckERC20 tokens with a tag for the "ck" initial part.

# Changes

- Create new prop `DisplayName` for type `Token`.
- Add new prop for ck tokens in `ICRC_TOKENS` list.
- Create `Tag` component.
- Adapt `TokenCard` with the new prop.
  • Loading branch information
AntonioVentilii-DFINITY authored Aug 6, 2024
1 parent 0e34582 commit 2e780e8
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 10 deletions.
4 changes: 2 additions & 2 deletions src/frontend/src/env/tokens.env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import eth from '$icp-eth/assets/eth.svg';
import icpLight from '$icp/assets/icp_light.svg';
import { ICP_TRANSACTION_FEE_E8S } from '$icp/constants/icp.constants';
import type { IcToken } from '$icp/types/ic';
import type { RequiredToken } from '$lib/types/token';
import type { RequiredToken, TokenAppearance } from '$lib/types/token';

/**
* Ethereum
Expand Down Expand Up @@ -61,7 +61,7 @@ export const ICP_SYMBOL = 'ICP';

export const ICP_TOKEN_ID = Symbol(ICP_SYMBOL);

export const ICP_TOKEN: Required<IcToken> = {
export const ICP_TOKEN: Required<Omit<IcToken, keyof TokenAppearance>> & TokenAppearance = {
id: ICP_TOKEN_ID,
network: ICP_NETWORK,
standard: 'icp',
Expand Down
5 changes: 3 additions & 2 deletions src/frontend/src/eth/types/erc20.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import type { ContractAddress } from '$eth/types/address';
import type { Exchange } from '$lib/types/exchange';
import type { Token, TokenMetadata } from '$lib/types/token';
import type { Token, TokenAppearance, TokenMetadata } from '$lib/types/token';

export type Erc20Token = Erc20Contract & Token;

export type RequiredErc20Token = Required<Erc20Token>;
export type RequiredErc20Token = Required<Omit<Erc20Token, keyof TokenAppearance>> &
TokenAppearance;

export type Erc20ContractAddress = ContractAddress;
export type Erc20Contract = Erc20ContractAddress & { exchange: Exchange; twinTokenSymbol?: string };
Expand Down
9 changes: 7 additions & 2 deletions src/frontend/src/icp/services/icrc.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { IcInterface } from '$icp/types/ic';
import type { IcrcCustomTokenWithoutId } from '$icp/types/icrc-custom-token';
import {
buildIcrcCustomTokenMetadataPseudoResponse,
mapCkTokenOisyName,
mapIcrcToken,
type IcrcLoadData
} from '$icp/utils/icrc.utils';
Expand All @@ -31,12 +32,16 @@ export const loadIcrcTokens = async ({ identity }: { identity: OptionIdentity })

export const unsafeLoadDefaultPublicIcrcTokens = async () => {
await Promise.all(
PUBLIC_ICRC_TOKENS.map((token) => loadDefaultIcrc({ data: token, strategy: 'query' }))
PUBLIC_ICRC_TOKENS.map(mapCkTokenOisyName).map((token) =>
loadDefaultIcrc({ data: token, strategy: 'query' })
)
);
};

const loadDefaultIcrcTokens = async () => {
await Promise.all(ICRC_TOKENS.map((token) => loadDefaultIcrc({ data: token })));
await Promise.all(
ICRC_TOKENS.map(mapCkTokenOisyName).map((token) => loadDefaultIcrc({ data: token }))
);
};

export const loadCustomTokens = ({ identity }: { identity: OptionIdentity }): Promise<void> =>
Expand Down
12 changes: 11 additions & 1 deletion src/frontend/src/icp/utils/icrc.utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ICP_NETWORK } from '$env/networks.env';
import type { LedgerCanisterIdText } from '$icp/types/canister';
import type { IcFee, IcInterface, IcToken } from '$icp/types/ic';
import type { IcCkInterface, IcFee, IcInterface, IcToken } from '$icp/types/ic';
import type { IcTokenWithoutIdExtended, IcrcCustomToken } from '$icp/types/icrc-custom-token';
import type { CanisterIdText } from '$lib/types/canister';
import type { TokenCategory, TokenMetadata } from '$lib/types/token';
Expand Down Expand Up @@ -134,3 +134,13 @@ export const buildIcrcCustomTokenMetadataPseudoResponse = ({

export const icTokenIcrcCustomToken = (token: Partial<IcrcCustomToken>): token is IcrcCustomToken =>
(token.standard === 'icp' || token.standard === 'icrc') && 'enabled' in token;

export const mapCkTokenOisyName = (token: IcCkInterface): IcCkInterface => ({
...token,
...(nonNullish(token.twinToken) && {
oisyName: {
prefix: 'ck',
oisyName: token.twinToken.name
}
})
});
13 changes: 12 additions & 1 deletion src/frontend/src/lib/components/tokens/TokenCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,23 @@
import Card from '$lib/components/ui/Card.svelte';
import TokenLogo from '$lib/components/tokens/TokenLogo.svelte';
import type { Token } from '$lib/types/token';
import Tag from '$lib/components/ui/Tag.svelte';
import { nonNullish } from '@dfinity/utils';
export let token: Token;
const ariaLabel = nonNullish(token.oisyName)
? `${token.oisyName.prefix ?? ''}${token.oisyName.oisyName}`
: token.name;
</script>

<Card noMargin>
{token.name}
<span aria-label={ariaLabel}>
{#if nonNullish(token.oisyName?.prefix)}
<Tag ariaHidden>{token.oisyName.prefix}</Tag>
{/if}
<span aria-hidden="true">{token.oisyName?.oisyName ?? token.name}</span>
</span>

<TokenLogo {token} slot="icon" color="white" />

Expand Down
7 changes: 7 additions & 0 deletions src/frontend/src/lib/components/ui/Tag.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script lang="ts">
export let ariaHidden = false;
</script>

<span aria-hidden={ariaHidden} class="rounded-sm border border-grey px-0.5 text-sm">
<slot />
</span>
14 changes: 12 additions & 2 deletions src/frontend/src/lib/types/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export type Token = {
network: Network;
standard: TokenStandard;
category: TokenCategory;
} & TokenMetadata;
} & TokenMetadata &
TokenAppearance;

export interface TokenMetadata {
name: string;
Expand All @@ -20,7 +21,16 @@ export interface TokenMetadata {
icon?: string;
}

export type RequiredToken = Required<Token>;
export interface TokenAppearance {
oisyName?: TokenOisyName;
}

export type TokenOisyName = {
prefix: string | undefined;
oisyName: string;
};

export type RequiredToken = Required<Omit<Token, keyof TokenAppearance>> & TokenAppearance;

export type OptionToken = Token | undefined | null;
export type OptionTokenId = TokenId | undefined | null;
Expand Down

0 comments on commit 2e780e8

Please sign in to comment.