From 5e034cacf57a6c7ef55883b2154fbf356eaac76d Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Wed, 29 Jan 2025 19:04:33 +0100 Subject: [PATCH 1/5] feat: zustand boilerplate --- package.json | 3 +- src/constants/assets.ts | 138 ++++++++++++++++++++++++++++++++++++++++ src/store/assets.ts | 24 +++++++ src/types/assets.ts | 21 ++++++ yarn.lock | 22 +++++++ 5 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 src/constants/assets.ts create mode 100644 src/store/assets.ts create mode 100644 src/types/assets.ts diff --git a/package.json b/package.json index 4b33caa..b7856a0 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "react-icons": "^4.12.0", "react-router-dom": "^6.21.1", "react-virtuoso": "^4.6.2", - "viem": "^2.0.3" + "viem": "^2.0.3", + "zustand": "^5.0.3" }, "devDependencies": { "@types/inquirer": "^9.0.7", diff --git a/src/constants/assets.ts b/src/constants/assets.ts new file mode 100644 index 0000000..83e7e63 --- /dev/null +++ b/src/constants/assets.ts @@ -0,0 +1,138 @@ +import type { AssetId } from '@shapeshiftoss/caip' + +import type { Asset } from '../types/assets' + +// Chainflip-supported assets +export const initialAssets: Asset[] = [ + { + assetId: 'eip155:1/slip44:60', + chainId: 'eip155:1', + symbol: 'ETH', + name: 'Ethereum', + precision: 18, + color: '#5C6BC0', + icon: 'https://rawcdn.githack.com/trustwallet/assets/32e51d582a890b3dd3135fe3ee7c20c2fd699a6d/blockchains/ethereum/info/logo.png', + explorer: 'https://etherscan.io', + explorerAddressLink: 'https://etherscan.io/address/', + explorerTxLink: 'https://etherscan.io/tx/', + relatedAssetKey: 'eip155:1/slip44:60', + networkName: 'Ethereum', + }, + { + assetId: 'eip155:1/erc20:0x826180541412d574cf1336d22c0c0a287822678a', + chainId: 'eip155:1', + symbol: 'FLIP', + name: 'Chainflip', + precision: 18, + color: '#040404', + icon: 'https://assets.coingecko.com/coins/images/25576/large/kdt_AgmT_400x400.png?1696524709', + explorer: 'https://etherscan.io', + explorerAddressLink: 'https://etherscan.io/address/', + explorerTxLink: 'https://etherscan.io/tx/', + relatedAssetKey: null, + }, + { + assetId: 'eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + chainId: 'eip155:1', + symbol: 'USDC', + name: 'USDC on Ethereum', + precision: 6, + color: '#2373CB', + icon: 'https://rawcdn.githack.com/trustwallet/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png', + explorer: 'https://etherscan.io', + explorerAddressLink: 'https://etherscan.io/address/', + explorerTxLink: 'https://etherscan.io/tx/', + relatedAssetKey: 'eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, + { + assetId: 'eip155:1/erc20:0xdac17f958d2ee523a2206206994597c13d831ec7', + chainId: 'eip155:1', + symbol: 'USDT', + name: 'Tether on Ethereum', + precision: 6, + color: '#24A37B', + icon: 'https://rawcdn.githack.com/trustwallet/assets/master/blockchains/ethereum/assets/0xdAC17F958D2ee523a2206206994597C13D831ec7/logo.png', + explorer: 'https://etherscan.io', + explorerAddressLink: 'https://etherscan.io/address/', + explorerTxLink: 'https://etherscan.io/tx/', + relatedAssetKey: 'eip155:1/erc20:0xdac17f958d2ee523a2206206994597c13d831ec7', + }, + { + assetId: 'eip155:42161/slip44:60', + chainId: 'eip155:42161', + symbol: 'ETH', + name: 'Ethereum on Arbitrum One', + precision: 18, + color: '#5C6BC0', + icon: 'https://rawcdn.githack.com/trustwallet/assets/32e51d582a890b3dd3135fe3ee7c20c2fd699a6d/blockchains/ethereum/info/logo.png', + explorer: 'https://arbiscan.io', + explorerAddressLink: 'https://arbiscan.io/address/', + explorerTxLink: 'https://arbiscan.io/tx/', + relatedAssetKey: 'eip155:1/slip44:60', + networkName: 'Arbitrum One', + networkIcon: + 'https://raw.githubusercontent.com/trustwallet/assets/b7a5f12d893fcf58e0eb1dd64478f076857b720b/blockchains/arbitrum/info/logo.png', + networkColor: '#213147', + }, + { + assetId: 'eip155:42161/erc20:0xaf88d065e77c8cc2239327c5edb3a432268e5831', + chainId: 'eip155:42161', + symbol: 'USDC', + name: 'USDC on Arbitrum One', + precision: 6, + color: '#2E7ACD', + icon: 'https://assets.coingecko.com/coins/images/6319/large/usdc.png?1696506694', + explorer: 'https://arbiscan.io', + explorerAddressLink: 'https://arbiscan.io/address/', + explorerTxLink: 'https://arbiscan.io/tx/', + relatedAssetKey: 'eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, + { + assetId: 'bip122:000000000019d6689c085ae165831e93/slip44:0', + chainId: 'bip122:000000000019d6689c085ae165831e93', + symbol: 'BTC', + name: 'Bitcoin', + precision: 8, + color: '#FF9800', + icon: 'https://rawcdn.githack.com/trustwallet/assets/b7a5f12d893fcf58e0eb1dd64478f076857b720b/blockchains/bitcoin/info/logo.png', + explorer: 'https://live.blockcypher.com', + explorerAddressLink: 'https://live.blockcypher.com/btc/address/', + explorerTxLink: 'https://live.blockcypher.com/btc/tx/', + relatedAssetKey: null, + networkName: 'Bitcoin', + }, + { + assetId: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501', + chainId: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', + symbol: 'SOL', + name: 'Solana', + precision: 9, + color: '#9971d8', + icon: 'https://rawcdn.githack.com/trustwallet/assets/426526def2f327476e868ecb902c515ab17518af/blockchains/solana/info/logo.png', + explorer: 'https://explorer.solana.com', + explorerAddressLink: 'https://explorer.solana.com/address/', + explorerTxLink: 'https://explorer.solana.com/tx/', + relatedAssetKey: null, + networkName: 'Solana', + networkColor: '#9971d8', + }, + { + assetId: + 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + chainId: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', + symbol: 'USDC', + name: 'USDC on Solana', + precision: 6, + color: '#FFFFFF', + icon: 'https://assets.coingecko.com/coins/images/6319/large/usdc.png?1696506694', + explorer: 'https://explorer.solana.com', + explorerAddressLink: 'https://explorer.solana.com/address/', + explorerTxLink: 'https://explorer.solana.com/tx/', + relatedAssetKey: 'eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, +] + +export const initialAssetsById = initialAssets.reduce>((acc, asset) => { + acc[asset.assetId] = asset + return acc +}, {}) diff --git a/src/store/assets.ts b/src/store/assets.ts new file mode 100644 index 0000000..8eecccb --- /dev/null +++ b/src/store/assets.ts @@ -0,0 +1,24 @@ +import { create } from 'zustand' + +import { initialAssetsById } from '../constants/assets' +import type { Asset, AssetId, AssetsByIdPartial } from '../types/assets' + +interface AssetsState { + byId: AssetsByIdPartial + ids: AssetId[] + getAssetById: (assetId: AssetId) => Asset | undefined +} + +export const useAssetsStore = create((_set, get) => ({ + byId: initialAssetsById, + ids: Object.keys(initialAssetsById), + getAssetById: (assetId: AssetId) => get().byId[assetId], +})) + +export const useAssetById = (assetId: AssetId) => { + return useAssetsStore(state => state.byId[assetId]) +} + +export const useAllAssets = () => { + return useAssetsStore(state => state.ids.map(id => state.byId[id])) +} diff --git a/src/types/assets.ts b/src/types/assets.ts new file mode 100644 index 0000000..476897d --- /dev/null +++ b/src/types/assets.ts @@ -0,0 +1,21 @@ +export type AssetId = string +export type ChainId = string + +export type Asset = { + assetId: AssetId + chainId: ChainId + symbol: string + name: string + precision: number + color: string + icon: string + explorer: string + explorerAddressLink: string + explorerTxLink: string + relatedAssetKey: AssetId | null + networkName?: string + networkIcon?: string + networkColor?: string +} + +export type AssetsByIdPartial = Record \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 714353f..d1e4994 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7377,6 +7377,7 @@ __metadata: vite: "npm:^5.0.8" vite-tsconfig-paths: "npm:^4.2.3" vitest: "npm:^1.1.3" + zustand: "npm:^5.0.3" languageName: unknown linkType: soft @@ -8449,3 +8450,24 @@ __metadata: checksum: 10c0/856117aa15cf5103d2a2fb173f0ab4acb12b4b4d0ed3ab249fdbbf612e55d1cadfd27a6110940e24746fb0a78cf640b522cc8bca76f30a3b00b66e90cf82abe0 languageName: node linkType: hard + +"zustand@npm:^5.0.3": + version: 5.0.3 + resolution: "zustand@npm:5.0.3" + peerDependencies: + "@types/react": ">=18.0.0" + immer: ">=9.0.6" + react: ">=18.0.0" + use-sync-external-store: ">=1.2.0" + peerDependenciesMeta: + "@types/react": + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + checksum: 10c0/dad96c6c123fda088c583d5df6692e9245cd207583078dc15f93d255a67b0f346bad4535545c98852ecde93d254812a0c799579dfde2ab595016b99fbe20e4d5 + languageName: node + linkType: hard From 0afce69ad5238318fc324158240f9af5baf82771 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Wed, 29 Jan 2025 19:07:35 +0100 Subject: [PATCH 2/5] feat: improve types --- src/store/assets.ts | 4 ++-- src/types/assets.ts | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/store/assets.ts b/src/store/assets.ts index 8eecccb..f65c4ab 100644 --- a/src/store/assets.ts +++ b/src/store/assets.ts @@ -1,10 +1,10 @@ import { create } from 'zustand' import { initialAssetsById } from '../constants/assets' -import type { Asset, AssetId, AssetsByIdPartial } from '../types/assets' +import type { Asset, AssetId } from '../types/assets' interface AssetsState { - byId: AssetsByIdPartial + byId: Record ids: AssetId[] getAssetById: (assetId: AssetId) => Asset | undefined } diff --git a/src/types/assets.ts b/src/types/assets.ts index 476897d..6eab3ea 100644 --- a/src/types/assets.ts +++ b/src/types/assets.ts @@ -17,5 +17,3 @@ export type Asset = { networkIcon?: string networkColor?: string } - -export type AssetsByIdPartial = Record \ No newline at end of file From 110aa878eeb5134975cab126db79caa02a6fddb1 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Wed, 29 Jan 2025 19:08:59 +0100 Subject: [PATCH 3/5] feat: improve types some more --- src/store/assets.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/assets.ts b/src/store/assets.ts index f65c4ab..0bf8257 100644 --- a/src/store/assets.ts +++ b/src/store/assets.ts @@ -6,7 +6,7 @@ import type { Asset, AssetId } from '../types/assets' interface AssetsState { byId: Record ids: AssetId[] - getAssetById: (assetId: AssetId) => Asset | undefined + getAssetById: (assetId: AssetId) => Asset } export const useAssetsStore = create((_set, get) => ({ From 239c3aa7830656c6d9f70b34eb3a7523f322c632 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Wed, 29 Jan 2025 19:09:38 +0100 Subject: [PATCH 4/5] feat: last one --- src/types/assets.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/types/assets.ts b/src/types/assets.ts index 6eab3ea..780b2e6 100644 --- a/src/types/assets.ts +++ b/src/types/assets.ts @@ -1,5 +1,4 @@ -export type AssetId = string -export type ChainId = string +import type { AssetId, ChainId } from '@shapeshiftoss/caip' export type Asset = { assetId: AssetId From 62575172dcab6630b7e2eefaaf7e52f297dc1f76 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Wed, 29 Jan 2025 22:17:16 +0100 Subject: [PATCH 5/5] fix: ci --- src/store/assets.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/store/assets.ts b/src/store/assets.ts index 0bf8257..df1a618 100644 --- a/src/store/assets.ts +++ b/src/store/assets.ts @@ -1,7 +1,8 @@ +import type { AssetId } from '@shapeshiftoss/caip' import { create } from 'zustand' import { initialAssetsById } from '../constants/assets' -import type { Asset, AssetId } from '../types/assets' +import type { Asset } from '../types/assets' interface AssetsState { byId: Record