diff --git a/lerna.json b/lerna.json index 0ea76fdc4..cf797cd6e 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "packages": ["packages/*"], - "version": "0.8.0", + "version": "0.8.1", "npmClient": "yarn", "useWorkspaces": true } diff --git a/package.json b/package.json index 04630e056..b5c8c5cca 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "0.8.0", + "version": "0.8.1", "private": true, "name": "alephium-browser-extension-wallet", "repository": "github:alephium/extension-wallet", diff --git a/packages/dapp/package.json b/packages/dapp/package.json index de7d16512..2a4f32d8c 100644 --- a/packages/dapp/package.json +++ b/packages/dapp/package.json @@ -1,6 +1,6 @@ { "name": "@alephium/dapp", - "version": "0.8.0", + "version": "0.8.1", "private": true, "scripts": { "dev": "next dev", diff --git a/packages/dapp/src/services/wallet.service.ts b/packages/dapp/src/services/wallet.service.ts index 63ae67e82..f8080e870 100644 --- a/packages/dapp/src/services/wallet.service.ts +++ b/packages/dapp/src/services/wallet.service.ts @@ -43,7 +43,7 @@ export const addToken = async (id: string): Promise => { type: "AddNewToken", params: { id: id, - networkId: '', + networkId: 'devnet', symbol: '', decimals: 0, name: '', diff --git a/packages/extension/manifest/v2.json b/packages/extension/manifest/v2.json index 5a4deb908..15f7738de 100644 --- a/packages/extension/manifest/v2.json +++ b/packages/extension/manifest/v2.json @@ -2,7 +2,7 @@ "$schema": "https://json.schemastore.org/chrome-manifest.json", "name": "Alephium Extension Wallet", "description": "Alephium's official extension wallet with powerful features and a clean UI.", - "version": "0.8.0", + "version": "0.8.1", "manifest_version": 2, "browser_action": { "default_icon": { diff --git a/packages/extension/manifest/v3.json b/packages/extension/manifest/v3.json index c8302ac06..beae75a40 100644 --- a/packages/extension/manifest/v3.json +++ b/packages/extension/manifest/v3.json @@ -2,7 +2,7 @@ "$schema": "https://json.schemastore.org/chrome-manifest.json", "name": "Alephium Extension Wallet", "description": "Alephium's official extension wallet with powerful features and a clean UI.", - "version": "0.8.0", + "version": "0.8.1", "manifest_version": 3, "action": { "default_icon": { diff --git a/packages/extension/package.json b/packages/extension/package.json index 665a55d1b..9e9a3e966 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -1,6 +1,6 @@ { "name": "@alephium/extension", - "version": "0.8.0", + "version": "0.8.1", "main": "index.js", "license": "MIT", "devDependencies": { diff --git a/packages/extension/src/shared/token/storage.ts b/packages/extension/src/shared/token/storage.ts index 686664909..4c4242175 100644 --- a/packages/extension/src/shared/token/storage.ts +++ b/packages/extension/src/shared/token/storage.ts @@ -1,11 +1,10 @@ import * as yup from "yup" - import { ArrayStorage } from "../storage" import { assertSchema } from "../utils/schema" import { BaseToken, Token } from "./type" -import { equalToken, knownAlephiumTokens } from "./utils" +import { equalToken, tokensFromAlephiumTokenList } from "./utils" -export const tokenStore = new ArrayStorage(knownAlephiumTokens, { +export const tokenStore = new ArrayStorage([] as Token[], { namespace: "core:tokens", areaName: "local", compare: equalToken, @@ -28,15 +27,22 @@ export const tokenSchema: yup.Schema = baseTokenSchema decimals: yup.number().required("Decimals is required"), logoURI: yup.string().url(), showAlways: yup.boolean(), + description: yup.string(), + verified: yup.boolean() }) export async function addToken(token: Token) { await assertSchema(tokenSchema, token) - return tokenStore.push(token) + return tokenStore.push({ verified: true, ...token }) } export async function hasToken(token: BaseToken) { await assertSchema(baseTokenSchema, token) + const tokenListHit = tokensFromAlephiumTokenList.find((t) => equalToken(t, token)) + if (tokenListHit) { + return Boolean(tokenListHit) + } + const [hit] = await tokenStore.get((t) => equalToken(t, token)) return Boolean(hit) } diff --git a/packages/extension/src/shared/token/storeMigration.ts b/packages/extension/src/shared/token/storeMigration.ts new file mode 100644 index 000000000..a115400e4 --- /dev/null +++ b/packages/extension/src/shared/token/storeMigration.ts @@ -0,0 +1,16 @@ +import { removeToken, tokenStore } from "./storage" +import { equalToken, tokensFromAlephiumTokenList } from "./utils" +import { Token } from "./type" + +export async function migrateTokens() { + try { + const allTokens: Token[] = await tokenStore.get() + for (const token of allTokens) { + if (tokensFromAlephiumTokenList.findIndex((knownToken) => equalToken(knownToken, token)) !== -1) { + removeToken(token) + } + } + } catch (e) { + console.error(e) + } +} diff --git a/packages/extension/src/shared/token/utils.ts b/packages/extension/src/shared/token/utils.ts index 1de6f69a1..9d6c1c055 100644 --- a/packages/extension/src/shared/token/utils.ts +++ b/packages/extension/src/shared/token/utils.ts @@ -7,7 +7,7 @@ import { defaultNetworkIds } from "../network/defaults" export const equalToken = (a: BaseToken, b: BaseToken) => a.networkId === b.networkId && isEqualTokenId(a.id, b.id) -const alphTokens: Token[] = defaultNetworkIds.map((networkId) => { +export const alphTokens: Token[] = defaultNetworkIds.map((networkId) => { return { ...ALPH, "networkId": networkId, @@ -17,9 +17,9 @@ const alphTokens: Token[] = defaultNetworkIds.map((networkId) => { } }) -const knownTokensFromAlephiumTokenList: Token[] = [mainnetTokensMetadata, testnetTokensMetadata].flatMap(convertTokenList) - -export const knownAlephiumTokens = alphTokens.concat(knownTokensFromAlephiumTokenList) +export const tokensFromAlephiumTokenList: Token[] = alphTokens.concat( + [mainnetTokensMetadata, testnetTokensMetadata].flatMap(convertTokenList) +) export const dustALPHAmount = BigInt(1000000000000000) diff --git a/packages/extension/src/shared/wallet/storeMigration.ts b/packages/extension/src/shared/wallet/storeMigration.ts index ccb660c8e..97f934c89 100644 --- a/packages/extension/src/shared/wallet/storeMigration.ts +++ b/packages/extension/src/shared/wallet/storeMigration.ts @@ -4,6 +4,7 @@ import browser from "webextension-polyfill" import { Wallet } from "../../background/wallet" import { walletStore } from "../../shared/wallet/walletStore" import { migrateWalletAccounts } from "../account/storeMigration" +import { migrateTokens } from "../token/storeMigration" export async function migrateWallet() { await Promise.allSettled([ @@ -11,6 +12,7 @@ export async function migrateWallet() { migrateDiscoveredOnce(), migrateSelected(), migrateWalletAccounts(), + migrateTokens() ]) } diff --git a/packages/extension/src/ui/features/accountTokens/tokens.state.ts b/packages/extension/src/ui/features/accountTokens/tokens.state.ts index 7344963a4..ec9811c27 100644 --- a/packages/extension/src/ui/features/accountTokens/tokens.state.ts +++ b/packages/extension/src/ui/features/accountTokens/tokens.state.ts @@ -7,9 +7,9 @@ import useSWRImmutable from 'swr/immutable' import { getNetwork, Network } from "../../../shared/network" import { useArrayStorage } from "../../../shared/storage/hooks" -import { addToken, tokenStore } from "../../../shared/token/storage" +import { addToken, removeToken, tokenStore } from "../../../shared/token/storage" import { BaseToken, Token } from "../../../shared/token/type" -import { equalToken } from "../../../shared/token/utils" +import { alphTokens, equalToken, tokensFromAlephiumTokenList } from "../../../shared/token/utils" import { BaseWalletAccount } from "../../../shared/wallet.model" import { getAccountIdentifier } from "../../../shared/wallet.service" import { useAccount } from "../accounts/accounts.state" @@ -32,21 +32,13 @@ const networkIdSelector = memoize( (networkId: string) => (token: Token) => token.networkId === networkId, ) -const feeTokenSelector = memoize( - (networkId: string) => (token: Token) => - token.networkId === networkId && token.symbol === "ALPH", -) - export const getNetworkFeeToken = async (networkId: string) => { - const [feeToken] = await tokenStore.get(feeTokenSelector(networkId)) + const feeToken = alphTokens.find((token) => token.networkId === networkId) return feeToken ?? null } export const useNetworkFeeToken = (networkId?: string) => { - const [feeToken] = useArrayStorage( - tokenStore, - networkId ? feeTokenSelector(networkId) : () => false, - ) + const feeToken = alphTokens.find((token) => token.networkId === networkId) return feeToken ?? null } @@ -55,8 +47,22 @@ const tokenSelector = memoize( (baseToken) => getAccountIdentifier({ networkId: baseToken.networkId, address: baseToken.id }), ) -export const useTokensInNetwork = (networkId: string) => - useArrayStorage(tokenStore, networkIdSelector(networkId)) +export const useTokensInNetwork = (networkId: string) => { + const tokensFromTokenList: Token[] = tokensFromAlephiumTokenList.filter(networkIdSelector(networkId)) + const tokens: Token[] = useArrayStorage(tokenStore, networkIdSelector(networkId)) + + const result: Token[] = tokensFromTokenList + for (const token of tokens) { + if (tokensFromTokenList.findIndex((t) => equalToken(t, token)) === -1) { + result.push(token) + } else { + // Remove manually added token when it is already in the token list + removeToken(token) + } + } + return result +} + export const devnetTokenSymbol = (baseToken: { id: string }): string => { return baseToken.id.replace(/[^a-zA-Z]/gi, '').slice(0, 4).toUpperCase() @@ -74,7 +80,13 @@ export const devnetToken = (baseToken: BaseToken): Token => { } export const useToken = (baseToken: BaseToken): Token | undefined => { + const tokenFromTokenList = tokensFromAlephiumTokenList.find((t) => equalToken(t, baseToken)) const [token] = useArrayStorage(tokenStore, tokenSelector(baseToken)) + + if (tokenFromTokenList) { + return tokenFromTokenList + } + if (token === undefined && baseToken.networkId === 'devnet') { return devnetToken(baseToken) } @@ -218,13 +230,13 @@ export const useFungibleTokens = ( }, [selectedAccount?.networkId]) const cachedTokens = useTokensInNetwork(networkId) - const { data: fungibleTokens } = useSWRImmutable( selectedAccount && [ getAccountIdentifier(selectedAccount), allUserTokens, + cachedTokens, "accountFungibleTokens", ], async () => { diff --git a/packages/extension/src/ui/features/actions/AddTokenScreen.tsx b/packages/extension/src/ui/features/actions/AddTokenScreen.tsx index 2a37eada9..b7df22afd 100644 --- a/packages/extension/src/ui/features/actions/AddTokenScreen.tsx +++ b/packages/extension/src/ui/features/actions/AddTokenScreen.tsx @@ -108,7 +108,7 @@ export const AddTokenScreen: FC = ({ setTokenDecimals(found.decimals || 0) setLogoURI(found.logoURI || "") } - }, [tokenId, tokensInNetwork]) + }, [tokenId]) const compiledData = { id: tokenId, diff --git a/packages/stack-router/package.json b/packages/stack-router/package.json index 1834dbeef..acd3d9073 100644 --- a/packages/stack-router/package.json +++ b/packages/stack-router/package.json @@ -1,6 +1,6 @@ { "name": "@argent/stack-router", - "version": "0.8.0", + "version": "0.8.1", "license": "MIT", "private": true, "files": [ @@ -32,7 +32,7 @@ "lodash-es": "^4.17.21" }, "devDependencies": { - "@argent/ui": "^0.8.0", + "@argent/ui": "^0.8.1", "@types/lodash-es": "^4.17.6", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", diff --git a/packages/storybook/package.json b/packages/storybook/package.json index 228561410..5811a5781 100644 --- a/packages/storybook/package.json +++ b/packages/storybook/package.json @@ -1,10 +1,10 @@ { "name": "@argent-x/storybook", - "version": "0.8.0", + "version": "0.8.1", "private": true, "devDependencies": { - "@alephium/extension": "^0.8.0", - "@argent/ui": "^0.8.0", + "@alephium/extension": "^0.8.1", + "@argent/ui": "^0.8.1", "@babel/core": "^7.18.5", "@chakra-ui/storybook-addon": "^4.0.12", "@storybook/addon-actions": "^6.5.9", diff --git a/packages/ui/package.json b/packages/ui/package.json index 8f175583a..b4e6f28f8 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@argent/ui", - "version": "0.8.0", + "version": "0.8.1", "license": "MIT", "private": true, "files": [