From dafc0b59928d9d1eecee7f1045c4a4abbe908d36 Mon Sep 17 00:00:00 2001 From: hassnian Date: Wed, 23 Aug 2023 05:37:13 +0500 Subject: [PATCH 001/167] ref: refactored useToken and crosschains tokens --- components/balance/MultipleBalances.vue | 10 +-- components/shared/format/Money.vue | 5 +- components/transfer/Transfer.vue | 58 ++++++++++-------- composables/useToken.ts | 81 ++++++++++++------------- stores/identity.ts | 6 ++ utils/chain.ts | 9 +++ utils/objects.ts | 37 ----------- 7 files changed, 93 insertions(+), 113 deletions(-) diff --git a/components/balance/MultipleBalances.vue b/components/balance/MultipleBalances.vue index 570b5e1a82..31c6827540 100644 --- a/components/balance/MultipleBalances.vue +++ b/components/balance/MultipleBalances.vue @@ -70,6 +70,7 @@ import { toDefaultAddress } from '@/utils/account' import { ChainToken, useIdentityStore } from '@/stores/identity' import type { PalletBalancesAccountData } from '@polkadot/types/lookup' +import { networkToPrefix } from '@/utils/chain' const { accountId } = useAuth() const { isTestnet } = usePrefix() @@ -82,15 +83,6 @@ const { multiBalanceNetwork, } = storeToRefs(identityStore) -const networkToPrefix = { - polkadot: 'dot', - kusama: 'ksm', - basilisk: 'bsx', - statemine: 'ahk', - 'basilisk-testnet': 'snek', - statemint: 'ahp', -} - const isBalanceLoading = computed( () => identityStore.getStatusMultiBalances === 'loading' ) diff --git a/components/shared/format/Money.vue b/components/shared/format/Money.vue index 8b9caf2e6b..f7751829b5 100644 --- a/components/shared/format/Money.vue +++ b/components/shared/format/Money.vue @@ -23,6 +23,7 @@ const props = withDefaults( inline: boolean hideUnit?: boolean unitSymbol?: string + decimals?: number round?: number }>(), { @@ -32,9 +33,11 @@ const props = withDefaults( } ) -const { decimals, unit } = useChain() +const { decimals: chainDecimals, unit } = useChain() const displayUnit = computed(() => props.unitSymbol || unit.value) +const decimals = computed(() => props.decimals || chainDecimals.value) + const finalValue = computed(() => round( formatBalance(checkInvalidBalanceFilter(props.value), decimals.value, ''), diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 9c743c020d..e5c2e65b18 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -62,7 +62,11 @@ }}
token - +
≈ ${{ balanceUsdValue }} @@ -160,7 +164,11 @@ - + {{ balanceUsdValue }} USD('token') const { getTokenIconBySymbol } = useIcon() -const { tokens, getPrefixByToken, availableTokens } = useToken() + +const { tokens, isTokenValidForChain } = useToken() +const unit = ref(chainUnit.value) +const decimals = computed( + () => tokens.value.find((t) => t.symbol === unit.value)?.tokenDecimals +) const selectedTabFirst = ref(true) const tokenIcon = computed(() => getTokenIconBySymbol(unit.value)) @@ -319,20 +332,25 @@ const disabled = computed( const handleTokenSelect = (newToken: string) => { selectedTabFirst.value = false + const token = tokens.value.find((t) => t.symbol === newToken) - if (token) { - const chain = getPrefixByToken(token.symbol) + if (!token) { + return + } - if (!chain) { - $consola.error( - `[ERR: INVALID TOKEN] Chain for token ${token.symbol} is not valid` - ) - return - } + const isTokenAvailableForCurrentChain = token.chains.includes(urlPrefix.value) - setUrlPrefix(chain) + if (isTokenAvailableForCurrentChain) { + router.replace({ query: { ...route.query, token: token.symbol } }) + return } + + setUrlPrefix(token.defaultChain) + router.replace({ + params: { prefix: token.defaultChain }, + query: { ...route.query, token: token.symbol }, + }) } const generateTokenTabs = ( @@ -626,21 +644,13 @@ const addAddress = () => { } const syncQueryToken = () => { - const { query } = route - - const token = query.token?.toString() - - if (!token || !availableTokens.includes(token)) { - return - } - - const chain = getPrefixByToken(token) + const token = route.query.token?.toString() - if (!chain) { + if (!isTokenValidForChain(token, urlPrefix.value)) { return } - setUrlPrefix(chain) + unit.value = token } watch( diff --git a/composables/useToken.ts b/composables/useToken.ts index 11ddb07958..b0bf391dab 100644 --- a/composables/useToken.ts +++ b/composables/useToken.ts @@ -1,74 +1,71 @@ import { useFiatStore } from '@/stores/fiat' -import { type ChainProperties, type Prefix } from '@kodadot1/static' -import { chainPropListOf } from '@/utils/config/chain.config' -import { groupByNestedProperty } from '@/utils/objects' -import { availablePrefixes } from '@/utils/chain' +import { CHAINS, type Prefix } from '@kodadot1/static' +import { useIdentityStore } from '@/stores/identity' +import { networkToPrefix } from '@/utils/chain' export interface TokenDetails { symbol: string value: number | string | null icon: string chains: Prefix[] + defaultChain: Prefix + tokenDecimals: number } +const getAssetToken = (asset) => asset?.token || 'KSM' +const getUniqueArrayItems = (items: string[]) => [...new Set(items)] + export default function useToken() { const { getCurrentTokenValue } = useFiatStore() const { getTokenIconBySymbol } = useIcon() + const { getAvailableAssets } = useIdentityStore() - const availableChains = availablePrefixes().map( - (item) => item.value as Prefix + const availableAssets = computed(() => getAvailableAssets) + const availableTokensAcrossAllChains = computed(() => + getUniqueArrayItems(Object.values(availableAssets.value).map(getAssetToken)) ) - const availableTokens = ['BSX', 'DOT', 'KSM'] - - const chainsProperties = computed(() => { - return availableChains.reduce( - (reducer, chain: Prefix) => ({ - ...reducer, - [chain]: chainPropListOf(chain), - }), - {} - ) as { [k in Prefix]: ChainProperties }[] - }) - - const groupedTokensByChains = computed(() => - groupByNestedProperty(chainsProperties.value, 'tokenSymbol') - ) + const getTokenChains = (token: string): Prefix[] => { + const chains = Object.values(availableAssets.value).reduce( + (reducer: Prefix[], asset) => { + const assetToken = getAssetToken(asset) + const chainName = asset.chain + if (token === assetToken) { + return [...reducer, networkToPrefix[chainName] as Prefix] + } + return reducer + }, + [] + ) - const getTokenChain = (token: string): Prefix[] => - groupedTokensByChains.value[token] || [] + return chains + } const tokens = computed(() => { - const filteredTokens = Object.keys(groupedTokensByChains.value).filter( - (token) => availableTokens.includes(token) - ) - - return filteredTokens.map((tokenSymbol) => { + return availableTokensAcrossAllChains.value.map((tokenSymbol) => { + const chains = getTokenChains(tokenSymbol) return { symbol: tokenSymbol as string, value: getCurrentTokenValue(tokenSymbol), icon: getTokenIconBySymbol(tokenSymbol), - chains: getTokenChain(tokenSymbol), + chains: chains, + defaultChain: chains[0], // TODO temp, + tokenDecimals: CHAINS[chains[0]].tokenDecimals, } }) }) - const getPrefixByToken = (token: string): Prefix | null => { - switch (token.toLowerCase()) { - case 'bsx': - return 'bsx' - case 'dot': - return 'dot' - case 'ksm': - return 'ksm' - default: - return null - } + const isTokenValidForChain = (token: string, urlPrefix: Prefix) => { + const isValidToken = availableTokensAcrossAllChains.value.includes(token) + const isAvailableForCurrentChain = tokens.value + .map((t) => t.chains.includes(urlPrefix) && t.symbol === token) + .some(Boolean) + return !!token && isValidToken && isAvailableForCurrentChain } return { tokens, - availableTokens, - getPrefixByToken, + availableTokensAcrossAllChains, + isTokenValidForChain, } } diff --git a/stores/identity.ts b/stores/identity.ts index 9b3e9d2b4d..ab0a466a68 100644 --- a/stores/identity.ts +++ b/stores/identity.ts @@ -158,6 +158,12 @@ export const useIdentityStore = defineStore('identity', { return totalAssets < assets.length ? 'loading' : 'done' }, + getAvailableAssets: (state) => { + const { isTestnet } = usePrefix() + return isTestnet.value + ? state.multiBalanceAssetsTestnet + : state.multiBalanceAssets + }, }, actions: { resetAuth() { diff --git a/utils/chain.ts b/utils/chain.ts index 372663c9fb..005b186f6e 100644 --- a/utils/chain.ts +++ b/utils/chain.ts @@ -38,3 +38,12 @@ export const getAvailablePrefix = (prefix: string): string => { ? prefix : '' } + +export const networkToPrefix = { + polkadot: 'dot', + kusama: 'ksm', + basilisk: 'bsx', + statemine: 'ahk', + 'basilisk-testnet': 'snek', + statemint: 'ahp', +} diff --git a/utils/objects.ts b/utils/objects.ts index de718fc919..e0df3a9da9 100644 --- a/utils/objects.ts +++ b/utils/objects.ts @@ -23,40 +23,3 @@ export const getMovedItemToFront = ( return newArr } - -interface GroupedObject { - [key: string]: string[] -} - -export const groupByNestedProperty = ( - obj: { [key: string]: { [nestedKey: string]: string } }, - nestedKey: string -): GroupedObject => { - const grouped: GroupedObject = {} - - for (const outerKey in obj) { - if (isValidProperty(obj[outerKey], nestedKey)) { - addToGroup(grouped, obj[outerKey][nestedKey], outerKey) - } - } - - return grouped -} - -const isValidProperty = ( - object: { [key: string]: string }, - key: string -): boolean => { - return object.hasOwnProperty(key) -} - -const addToGroup = ( - grouped: GroupedObject, - propertyValue: string, - outerKey: string -): void => { - if (!grouped[propertyValue]) { - grouped[propertyValue] = [] - } - grouped[propertyValue].push(outerKey) -} From cfee756de8de1a9425ecaf30f959f717b1c8ead2 Mon Sep 17 00:00:00 2001 From: hassnian Date: Wed, 23 Aug 2023 07:21:04 +0500 Subject: [PATCH 002/167] fix: balance issue --- components/transfer/Transfer.vue | 3 ++- composables/useBalance.ts | 21 +++++++++++++-------- composables/useToken.ts | 6 ++++-- utils/chain.ts | 28 +++++++++++++++++++++------- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index e5c2e65b18..1106f70300 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -283,6 +283,7 @@ const identityStore = useIdentityStore() const { fetchFiatPrice, getCurrentTokenValue } = useFiatStore() const { initTransactionLoader, isLoading, resolveStatus, status } = useTransactionStatus() +const { getBalance } = useBalance() const { toast } = useToast() const isTransferModalVisible = ref(false) @@ -321,7 +322,7 @@ const displayTotalValue = computed(() => : [`${totalTokenAmount.value} ${unit.value}`, `$${totalUsdValue.value}`] ) -const balance = computed(() => identityStore.getAuthBalance) +const balance = computed(() => getBalance(urlPrefix.value, unit.value) || 0) const disabled = computed( () => diff --git a/composables/useBalance.ts b/composables/useBalance.ts index 9c2672369d..b85eaac865 100644 --- a/composables/useBalance.ts +++ b/composables/useBalance.ts @@ -4,26 +4,31 @@ import { getKusamaAssetId } from '@/utils/api/bsx/query' export default function () { const { urlPrefix } = usePrefix() const identityStore = useIdentityStore() - const balance = computed(() => { - switch (urlPrefix.value) { + + const getBalance = (prefix: string, token: string) => { + token = token.toLocaleLowerCase() + switch (prefix) { case 'rmrk': case 'ksm': case 'ahk': case 'ahp': + case 'dot': return identityStore.getAuthBalance case 'bsx': - return identityStore.multiBalances.chains.basilisk?.ksm?.nativeBalance + return identityStore.multiBalances.chains.basilisk?.[token] + ?.nativeBalance case 'snek': - return identityStore.multiBalances.chains['basilisk-testnet']?.ksm + return identityStore.multiBalances.chains['basilisk-testnet']?.[token] ?.nativeBalance default: - return identityStore.getTokenBalanceOf( - getKusamaAssetId(urlPrefix.value) - ) + return identityStore.getTokenBalanceOf(getKusamaAssetId(prefix)) } - }) + } + + const balance = computed(() => getBalance(urlPrefix.value, 'KSM')) return { balance, + getBalance, } } diff --git a/composables/useToken.ts b/composables/useToken.ts index b0bf391dab..a7b4df993f 100644 --- a/composables/useToken.ts +++ b/composables/useToken.ts @@ -44,13 +44,15 @@ export default function useToken() { const tokens = computed(() => { return availableTokensAcrossAllChains.value.map((tokenSymbol) => { const chains = getTokenChains(tokenSymbol) + const defaultChain = chains[0] + return { symbol: tokenSymbol as string, value: getCurrentTokenValue(tokenSymbol), icon: getTokenIconBySymbol(tokenSymbol), chains: chains, - defaultChain: chains[0], // TODO temp, - tokenDecimals: CHAINS[chains[0]].tokenDecimals, + defaultChain: defaultChain, + tokenDecimals: CHAINS[defaultChain].tokenDecimals, } }) }) diff --git a/utils/chain.ts b/utils/chain.ts index 005b186f6e..4fcf3ef3e2 100644 --- a/utils/chain.ts +++ b/utils/chain.ts @@ -1,5 +1,6 @@ import type { Option } from '@kodadot1/static' import { ENDPOINT_MAP, chainList } from '@kodadot1/static' +import { Prefix } from '@kodadot1/static' export const getChainEndpointByPrefix = (prefix: string) => { const endpoint: string | undefined = ENDPOINT_MAP[prefix] @@ -39,11 +40,24 @@ export const getAvailablePrefix = (prefix: string): string => { : '' } -export const networkToPrefix = { - polkadot: 'dot', - kusama: 'ksm', - basilisk: 'bsx', - statemine: 'ahk', - 'basilisk-testnet': 'snek', - statemint: 'ahp', +export enum Network { + KUSAMA = 'kusama', + BASILISK = 'basilisk', + BASILISK_TESTNET = 'basilisk-testnet', + STATEMINE = 'statemine', + STATEMINT = 'statemint', + POLKADOT = 'polkadot', + MOONRIVER = 'moonriver', + MOONBEAM = 'moonbeam', +} + +export const networkToPrefix: Record = { + [Network.POLKADOT]: 'dot', + [Network.KUSAMA]: 'ksm', + [Network.STATEMINT]: 'ahp', + [Network.BASILISK]: 'bsx', + [Network.BASILISK_TESTNET]: 'snek', + [Network.STATEMINE]: 'ahk', + [Network.MOONRIVER]: 'movr', + [Network.MOONBEAM]: 'glmr', } From b2fdb6bd5a1d3b5ca6528776791302d93409ca53 Mon Sep 17 00:00:00 2001 From: hassnian Date: Wed, 23 Aug 2023 07:40:52 +0500 Subject: [PATCH 003/167] ref: isTokenValidForChain and removed unused vars --- components/transfer/Transfer.vue | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 1106f70300..6cdc9119c5 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -251,7 +251,6 @@ import { } from '@/utils/format/balance' import { getNumberSumOfObjectField } from '@/utils/math' import { useFiatStore } from '@/stores/fiat' -import { useIdentityStore } from '@/stores/identity' import Avatar from '@/components/shared/Avatar.vue' import Identity from '@/components/identity/IdentityIndex.vue' import { getMovedItemToFront } from '@/utils/objects' @@ -279,7 +278,6 @@ const { unit: chainUnit } = useChain() const { apiInstance } = useApi() const { urlPrefix, setUrlPrefix } = usePrefix() const { isLogIn, accountId } = useAuth() -const identityStore = useIdentityStore() const { fetchFiatPrice, getCurrentTokenValue } = useFiatStore() const { initTransactionLoader, isLoading, resolveStatus, status } = useTransactionStatus() @@ -340,14 +338,16 @@ const handleTokenSelect = (newToken: string) => { return } - const isTokenAvailableForCurrentChain = token.chains.includes(urlPrefix.value) + const isTokenAvailableForCurrentChain = isTokenValidForChain( + token.symbol, + urlPrefix.value + ) if (isTokenAvailableForCurrentChain) { - router.replace({ query: { ...route.query, token: token.symbol } }) + unit.value = token.symbol return } - setUrlPrefix(token.defaultChain) router.replace({ params: { prefix: token.defaultChain }, query: { ...route.query, token: token.symbol }, From c7d8366280cc027547a5990d69f0618844949a7e Mon Sep 17 00:00:00 2001 From: hassnian Date: Wed, 23 Aug 2023 08:45:18 +0500 Subject: [PATCH 004/167] fix: duplicate import --- utils/chain.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/utils/chain.ts b/utils/chain.ts index 4fcf3ef3e2..8115d68e79 100644 --- a/utils/chain.ts +++ b/utils/chain.ts @@ -1,6 +1,5 @@ -import type { Option } from '@kodadot1/static' +import type { Option, Prefix } from '@kodadot1/static' import { ENDPOINT_MAP, chainList } from '@kodadot1/static' -import { Prefix } from '@kodadot1/static' export const getChainEndpointByPrefix = (prefix: string) => { const endpoint: string | undefined = ENDPOINT_MAP[prefix] From dbd5b6c56d68608bc39266ccdd730b047afbd372 Mon Sep 17 00:00:00 2001 From: hassnian Date: Wed, 23 Aug 2023 10:30:05 +0500 Subject: [PATCH 005/167] fix: unsued prefix param --- components/transfer/Transfer.vue | 2 +- composables/useBalance.ts | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 6cdc9119c5..10bac1e947 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -320,7 +320,7 @@ const displayTotalValue = computed(() => : [`${totalTokenAmount.value} ${unit.value}`, `$${totalUsdValue.value}`] ) -const balance = computed(() => getBalance(urlPrefix.value, unit.value) || 0) +const balance = computed(() => getBalance(unit.value) || 0) const disabled = computed( () => diff --git a/composables/useBalance.ts b/composables/useBalance.ts index b85eaac865..81a182f43b 100644 --- a/composables/useBalance.ts +++ b/composables/useBalance.ts @@ -5,9 +5,9 @@ export default function () { const { urlPrefix } = usePrefix() const identityStore = useIdentityStore() - const getBalance = (prefix: string, token: string) => { + const getBalance = (token: string) => { token = token.toLocaleLowerCase() - switch (prefix) { + switch (urlPrefix.value) { case 'rmrk': case 'ksm': case 'ahk': @@ -21,11 +21,13 @@ export default function () { return identityStore.multiBalances.chains['basilisk-testnet']?.[token] ?.nativeBalance default: - return identityStore.getTokenBalanceOf(getKusamaAssetId(prefix)) + return identityStore.getTokenBalanceOf( + getKusamaAssetId(urlPrefix.value) + ) } } - const balance = computed(() => getBalance(urlPrefix.value, 'KSM')) + const balance = computed(() => getBalance('KSM')) return { balance, From 784f54764d512fd8732f4d0a3b44e252cf77f103 Mon Sep 17 00:00:00 2001 From: hassnian Date: Wed, 23 Aug 2023 11:01:30 +0500 Subject: [PATCH 006/167] ref: removed extra enum and used existing type --- components/balance/MultipleBalances.vue | 7 +++++-- composables/useToken.ts | 3 +-- stores/identity.ts | 14 ++++++++++++++ utils/chain.ts | 24 +----------------------- 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/components/balance/MultipleBalances.vue b/components/balance/MultipleBalances.vue index 31c6827540..e55135010c 100644 --- a/components/balance/MultipleBalances.vue +++ b/components/balance/MultipleBalances.vue @@ -67,10 +67,13 @@ import { calculateExactUsdFromToken } from '@/utils/calculation' import { getAssetIdByAccount } from '@/utils/api/bsx/query' import { toDefaultAddress } from '@/utils/account' -import { ChainToken, useIdentityStore } from '@/stores/identity' +import { + ChainToken, + networkToPrefix, + useIdentityStore, +} from '@/stores/identity' import type { PalletBalancesAccountData } from '@polkadot/types/lookup' -import { networkToPrefix } from '@/utils/chain' const { accountId } = useAuth() const { isTestnet } = usePrefix() diff --git a/composables/useToken.ts b/composables/useToken.ts index a7b4df993f..c3141a575d 100644 --- a/composables/useToken.ts +++ b/composables/useToken.ts @@ -1,7 +1,6 @@ import { useFiatStore } from '@/stores/fiat' import { CHAINS, type Prefix } from '@kodadot1/static' -import { useIdentityStore } from '@/stores/identity' -import { networkToPrefix } from '@/utils/chain' +import { networkToPrefix, useIdentityStore } from '@/stores/identity' export interface TokenDetails { symbol: string diff --git a/stores/identity.ts b/stores/identity.ts index ab0a466a68..12abae5cf5 100644 --- a/stores/identity.ts +++ b/stores/identity.ts @@ -19,6 +19,17 @@ const DEFAULT_BALANCE_STATE = { ahp: '0', } +export const networkToPrefix: Record = { + polkadot: 'dot', + kusama: 'ksm', + statemint: 'ahp', + basilisk: 'bsx', + 'basilisk-testnet': 'snek', + statemine: 'ahk', + moonriver: 'movr', + moonbeam: 'glmr', +} + export interface IdentityMap { [address: string]: Registration } @@ -37,6 +48,9 @@ type ChainType = | 'basilisk-testnet' | 'statemine' | 'statemint' + | 'moonriver' + | 'moonbeam' + type ChainDetail = { balance: string nativeBalance: string diff --git a/utils/chain.ts b/utils/chain.ts index 8115d68e79..372663c9fb 100644 --- a/utils/chain.ts +++ b/utils/chain.ts @@ -1,4 +1,4 @@ -import type { Option, Prefix } from '@kodadot1/static' +import type { Option } from '@kodadot1/static' import { ENDPOINT_MAP, chainList } from '@kodadot1/static' export const getChainEndpointByPrefix = (prefix: string) => { @@ -38,25 +38,3 @@ export const getAvailablePrefix = (prefix: string): string => { ? prefix : '' } - -export enum Network { - KUSAMA = 'kusama', - BASILISK = 'basilisk', - BASILISK_TESTNET = 'basilisk-testnet', - STATEMINE = 'statemine', - STATEMINT = 'statemint', - POLKADOT = 'polkadot', - MOONRIVER = 'moonriver', - MOONBEAM = 'moonbeam', -} - -export const networkToPrefix: Record = { - [Network.POLKADOT]: 'dot', - [Network.KUSAMA]: 'ksm', - [Network.STATEMINT]: 'ahp', - [Network.BASILISK]: 'bsx', - [Network.BASILISK_TESTNET]: 'snek', - [Network.STATEMINE]: 'ahk', - [Network.MOONRIVER]: 'movr', - [Network.MOONBEAM]: 'glmr', -} From dbada4f3db90226bba18776fd44baadf899675c5 Mon Sep 17 00:00:00 2001 From: hassnian Date: Wed, 23 Aug 2023 15:28:48 +0500 Subject: [PATCH 007/167] add: default token and mutilchain tokenDecimals --- components/transfer/Transfer.vue | 7 +++++-- composables/useToken.ts | 18 ++++++++++++++---- utils/config/chain.config.ts | 8 ++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 10bac1e947..9c94fa09a2 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -276,7 +276,7 @@ const router = useRouter() const { $consola, $i18n } = useNuxtApp() const { unit: chainUnit } = useChain() const { apiInstance } = useApi() -const { urlPrefix, setUrlPrefix } = usePrefix() +const { urlPrefix } = usePrefix() const { isLogIn, accountId } = useAuth() const { fetchFiatPrice, getCurrentTokenValue } = useFiatStore() const { initTransactionLoader, isLoading, resolveStatus, status } = @@ -300,7 +300,10 @@ const { getTokenIconBySymbol } = useIcon() const { tokens, isTokenValidForChain } = useToken() const unit = ref(chainUnit.value) const decimals = computed( - () => tokens.value.find((t) => t.symbol === unit.value)?.tokenDecimals + () => + tokens.value.find((t) => t.symbol === unit.value)?.tokenDecimals[ + urlPrefix.value + ] ) const selectedTabFirst = ref(true) diff --git a/composables/useToken.ts b/composables/useToken.ts index c3141a575d..491a49d2f5 100644 --- a/composables/useToken.ts +++ b/composables/useToken.ts @@ -1,14 +1,18 @@ import { useFiatStore } from '@/stores/fiat' import { CHAINS, type Prefix } from '@kodadot1/static' import { networkToPrefix, useIdentityStore } from '@/stores/identity' +import { defultTokenChain } from '@/utils/config/chain.config' +type TokenDecimals = { + [k in Prefix]: number +} export interface TokenDetails { symbol: string value: number | string | null icon: string chains: Prefix[] defaultChain: Prefix - tokenDecimals: number + tokenDecimals: TokenDecimals } const getAssetToken = (asset) => asset?.token || 'KSM' @@ -36,14 +40,20 @@ export default function useToken() { }, [] ) - return chains } const tokens = computed(() => { return availableTokensAcrossAllChains.value.map((tokenSymbol) => { const chains = getTokenChains(tokenSymbol) - const defaultChain = chains[0] + const defaultChain = defultTokenChain[tokenSymbol] + const tokenDecimals = chains.reduce( + (reducer, chain) => ({ + ...reducer, + [chain]: CHAINS[chain].tokenDecimals, + }), + {} as TokenDecimals + ) return { symbol: tokenSymbol as string, @@ -51,7 +61,7 @@ export default function useToken() { icon: getTokenIconBySymbol(tokenSymbol), chains: chains, defaultChain: defaultChain, - tokenDecimals: CHAINS[defaultChain].tokenDecimals, + tokenDecimals: tokenDecimals, } }) }) diff --git a/utils/config/chain.config.ts b/utils/config/chain.config.ts index 9cf841716a..cfc19f03cf 100644 --- a/utils/config/chain.config.ts +++ b/utils/config/chain.config.ts @@ -28,3 +28,11 @@ export const chainAssetOf = (prefix: Prefix): AssetItem => { decimals, } } + +export const defultTokenChain: Record = { + KSM: 'ksm', + DOT: 'dot', + BSX: 'bsx', + GLMR: 'glmr', + MOVR: 'movr', +} From 1aa97df0a9b2baa3a1cfc4b695190475820156ae Mon Sep 17 00:00:00 2001 From: hassnian Date: Wed, 23 Aug 2023 15:48:50 +0500 Subject: [PATCH 008/167] ref: reduce functino size , exceeds 25 allowed --- composables/useBalance.ts | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/composables/useBalance.ts b/composables/useBalance.ts index 81a182f43b..7f167a5044 100644 --- a/composables/useBalance.ts +++ b/composables/useBalance.ts @@ -7,23 +7,15 @@ export default function () { const getBalance = (token: string) => { token = token.toLocaleLowerCase() - switch (urlPrefix.value) { - case 'rmrk': - case 'ksm': - case 'ahk': - case 'ahp': - case 'dot': - return identityStore.getAuthBalance - case 'bsx': - return identityStore.multiBalances.chains.basilisk?.[token] - ?.nativeBalance - case 'snek': - return identityStore.multiBalances.chains['basilisk-testnet']?.[token] - ?.nativeBalance - default: - return identityStore.getTokenBalanceOf( - getKusamaAssetId(urlPrefix.value) - ) + if (['rmrk', 'ksm', 'ahk', 'ahp', 'dot'].includes(urlPrefix.value)) { + return identityStore.getAuthBalance + } else if (urlPrefix.value === 'bsx') { + return identityStore.multiBalances.chains.basilisk?.[token]?.nativeBalance + } else if (urlPrefix.value === 'snek') { + return identityStore.multiBalances.chains['basilisk-testnet']?.[token] + ?.nativeBalance + } else { + return identityStore.getTokenBalanceOf(getKusamaAssetId(urlPrefix.value)) } } From 09d3a732097fde56dec5369b05ba1a977798e0cd Mon Sep 17 00:00:00 2001 From: hassnian Date: Wed, 23 Aug 2023 18:43:51 +0500 Subject: [PATCH 009/167] Revert "ref: reduce functino size , exceeds 25 allowed" This reverts commit 1aa97df0a9b2baa3a1cfc4b695190475820156ae. --- composables/useBalance.ts | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/composables/useBalance.ts b/composables/useBalance.ts index 7f167a5044..81a182f43b 100644 --- a/composables/useBalance.ts +++ b/composables/useBalance.ts @@ -7,15 +7,23 @@ export default function () { const getBalance = (token: string) => { token = token.toLocaleLowerCase() - if (['rmrk', 'ksm', 'ahk', 'ahp', 'dot'].includes(urlPrefix.value)) { - return identityStore.getAuthBalance - } else if (urlPrefix.value === 'bsx') { - return identityStore.multiBalances.chains.basilisk?.[token]?.nativeBalance - } else if (urlPrefix.value === 'snek') { - return identityStore.multiBalances.chains['basilisk-testnet']?.[token] - ?.nativeBalance - } else { - return identityStore.getTokenBalanceOf(getKusamaAssetId(urlPrefix.value)) + switch (urlPrefix.value) { + case 'rmrk': + case 'ksm': + case 'ahk': + case 'ahp': + case 'dot': + return identityStore.getAuthBalance + case 'bsx': + return identityStore.multiBalances.chains.basilisk?.[token] + ?.nativeBalance + case 'snek': + return identityStore.multiBalances.chains['basilisk-testnet']?.[token] + ?.nativeBalance + default: + return identityStore.getTokenBalanceOf( + getKusamaAssetId(urlPrefix.value) + ) } } From e32933dfd4863ad6ace8a6e7847fded7d4b0bd67 Mon Sep 17 00:00:00 2001 From: hassnian Date: Wed, 23 Aug 2023 18:49:08 +0500 Subject: [PATCH 010/167] ref: TokenDecimals type --- composables/useToken.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/composables/useToken.ts b/composables/useToken.ts index 491a49d2f5..807e8cdb62 100644 --- a/composables/useToken.ts +++ b/composables/useToken.ts @@ -3,9 +3,7 @@ import { CHAINS, type Prefix } from '@kodadot1/static' import { networkToPrefix, useIdentityStore } from '@/stores/identity' import { defultTokenChain } from '@/utils/config/chain.config' -type TokenDecimals = { - [k in Prefix]: number -} +type TokenDecimals = Record export interface TokenDetails { symbol: string value: number | string | null From 856e26dc9958b6833f49b41cbb2fcf670d0e8c9b Mon Sep 17 00:00:00 2001 From: hassnian Date: Thu, 24 Aug 2023 14:29:09 +0500 Subject: [PATCH 011/167] add: token trasnfer --- components/transfer/Transfer.vue | 74 +++++++++++++++++++++----------- composables/useToken.ts | 40 +++++++++-------- 2 files changed, 70 insertions(+), 44 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 9c94fa09a2..e0d04993c4 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -299,11 +299,11 @@ const { getTokenIconBySymbol } = useIcon() const { tokens, isTokenValidForChain } = useToken() const unit = ref(chainUnit.value) +const selectedToken = computed(() => + tokens.value.find((t) => t.symbol === unit.value) +) const decimals = computed( - () => - tokens.value.find((t) => t.symbol === unit.value)?.tokenDecimals[ - urlPrefix.value - ] + () => selectedToken.value?.tokenDecimals[urlPrefix.value] ) const selectedTabFirst = ref(true) @@ -525,6 +525,20 @@ const handleOpenConfirmModal = () => { } } +const createTxArgs = ( + target: TargetAddress, + tokenTransfer: boolean, + tokenId: string | undefined, + decimals: number +): [string, string, string] | [string, string] => { + const amountToTransfer = String( + calculateBalance(Number(target.token), decimals) + ) + return tokenTransfer && tokenId !== undefined + ? [target.address as string, tokenId, amountToTransfer] + : [target.address as string, amountToTransfer] +} + const submit = async ( event: any, usedNodeUrls: string[] = [] @@ -535,29 +549,37 @@ const submit = async ( try { const api = await apiInstance.value + const tokenId = selectedToken.value?.tokenIds[urlPrefix.value] + const tokenTransfer = !!tokenId + const numOfTargetAddresses = targetAddresses.value.length - const cb = - numOfTargetAddresses > 1 ? api.tx.utility.batch : api.tx.balances.transfer - const arg = - numOfTargetAddresses > 1 - ? [ - targetAddresses.value.map((target) => { - const amountToTransfer = String( - calculateBalance(Number(target.token), decimals.value) - ) - return api.tx.balances.transfer( - target.address as string, - amountToTransfer - ) - }), - ] - : [ - targetAddresses.value[0].address as string, - calculateBalance( - Number(targetAddresses.value[0].token), - decimals.value - ), - ] + const multipleAddresses = numOfTargetAddresses > 1 + const cb = multipleAddresses + ? api.tx.utility.batch + : tokenTransfer + ? api.tx.tokens.transfer + : api.tx.balances.transfer + + const arg = multipleAddresses + ? [ + targetAddresses.value.map((target) => { + const txArgs = createTxArgs( + target, + tokenTransfer, + tokenId, + decimals.value as number + ) + return tokenTransfer + ? api.tx.tokens.transfer(...txArgs) + : api.tx.balances.transfer(...(txArgs as [string, string])) + }), + ] + : createTxArgs( + targetAddresses.value[0], + tokenTransfer, + tokenId, + decimals.value as number + ) const tx = await exec( accountId.value, diff --git a/composables/useToken.ts b/composables/useToken.ts index 807e8cdb62..3fcdc8540c 100644 --- a/composables/useToken.ts +++ b/composables/useToken.ts @@ -4,6 +4,7 @@ import { networkToPrefix, useIdentityStore } from '@/stores/identity' import { defultTokenChain } from '@/utils/config/chain.config' type TokenDecimals = Record +type TokenIds = Record export interface TokenDetails { symbol: string value: number | string | null @@ -11,6 +12,7 @@ export interface TokenDetails { chains: Prefix[] defaultChain: Prefix tokenDecimals: TokenDecimals + tokenIds: TokenIds } const getAssetToken = (asset) => asset?.token || 'KSM' @@ -26,32 +28,33 @@ export default function useToken() { getUniqueArrayItems(Object.values(availableAssets.value).map(getAssetToken)) ) + const getMatchingAvailableAssetsByToken = (token: string) => { + return Object.values(availableAssets.value).filter( + (asset) => token === getAssetToken(asset) + ) + } + const getTokenChains = (token: string): Prefix[] => { - const chains = Object.values(availableAssets.value).reduce( - (reducer: Prefix[], asset) => { - const assetToken = getAssetToken(asset) - const chainName = asset.chain - if (token === assetToken) { - return [...reducer, networkToPrefix[chainName] as Prefix] - } - return reducer - }, - [] + return getMatchingAvailableAssetsByToken(token).map( + (asset) => networkToPrefix[asset.chain] as Prefix ) - return chains + } + + const getChainTokenIds = (token: string) => { + return getMatchingAvailableAssetsByToken(token).reduce((reducer, asset) => { + const chainPrefix = networkToPrefix[asset.chain] + return { ...reducer, [chainPrefix]: asset.tokenId } + }, {} as TokenIds) } const tokens = computed(() => { return availableTokensAcrossAllChains.value.map((tokenSymbol) => { const chains = getTokenChains(tokenSymbol) const defaultChain = defultTokenChain[tokenSymbol] - const tokenDecimals = chains.reduce( - (reducer, chain) => ({ - ...reducer, - [chain]: CHAINS[chain].tokenDecimals, - }), - {} as TokenDecimals - ) + const tokenDecimals = Object.fromEntries( + chains.map((chain) => [chain, CHAINS[chain].tokenDecimals]) + ) as TokenDecimals + const tokenIds = getChainTokenIds(tokenSymbol) return { symbol: tokenSymbol as string, @@ -60,6 +63,7 @@ export default function useToken() { chains: chains, defaultChain: defaultChain, tokenDecimals: tokenDecimals, + tokenIds: tokenIds, } }) }) From 8dd4ccf2af68dd4ccd48ae4b60d2a9c0c3ac3c19 Mon Sep 17 00:00:00 2001 From: hassnian Date: Thu, 24 Aug 2023 14:30:55 +0500 Subject: [PATCH 012/167] fix: add null --- components/transfer/Transfer.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index e0d04993c4..41aa17a7cd 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -549,7 +549,7 @@ const submit = async ( try { const api = await apiInstance.value - const tokenId = selectedToken.value?.tokenIds[urlPrefix.value] + const tokenId = selectedToken.value?.tokenIds[urlPrefix.value] || null const tokenTransfer = !!tokenId const numOfTargetAddresses = targetAddresses.value.length From fd1bea5f32e7c17d3b9b89b5f3ed63ab60d9ee0f Mon Sep 17 00:00:00 2001 From: hassnian Date: Thu, 24 Aug 2023 14:31:46 +0500 Subject: [PATCH 013/167] fix: add null check --- components/transfer/Transfer.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 41aa17a7cd..466ca74ad1 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -528,13 +528,13 @@ const handleOpenConfirmModal = () => { const createTxArgs = ( target: TargetAddress, tokenTransfer: boolean, - tokenId: string | undefined, + tokenId: string | null, decimals: number ): [string, string, string] | [string, string] => { const amountToTransfer = String( calculateBalance(Number(target.token), decimals) ) - return tokenTransfer && tokenId !== undefined + return tokenTransfer && tokenId !== null ? [target.address as string, tokenId, amountToTransfer] : [target.address as string, amountToTransfer] } From cd512974dbd15034b11d76ec3650c3d945c99fec Mon Sep 17 00:00:00 2001 From: Floyd Li Date: Thu, 24 Aug 2023 18:29:35 +0800 Subject: [PATCH 014/167] refactor: execMintStatemine and execMintStatemine --- .../mintToken/transactionMintBasilisk.ts | 40 ++----------------- .../mintToken/transactionMintStatemine.ts | 35 +--------------- composables/transaction/mintToken/utils.ts | 37 ++++++++++++++++- 3 files changed, 41 insertions(+), 71 deletions(-) diff --git a/composables/transaction/mintToken/transactionMintBasilisk.ts b/composables/transaction/mintToken/transactionMintBasilisk.ts index 23d3fb748c..ded8fb7a4f 100644 --- a/composables/transaction/mintToken/transactionMintBasilisk.ts +++ b/composables/transaction/mintToken/transactionMintBasilisk.ts @@ -1,12 +1,8 @@ -import type { - ActionMintToken, - MintTokenParams, - MintedCollection, - TokenToMint, -} from '../types' +import type { ActionMintToken, MintedCollection, TokenToMint } from '../types' import { isRoyaltyValid } from '@/utils/royalty' import { constructMeta } from './constructMeta' import { BaseMintedCollection } from '@/components/base/types' +import { transactionFactory } from './utils' const prepareTokenMintArgs = async ( token: TokenToMint, @@ -60,34 +56,4 @@ const getArgs = async (item: ActionMintToken, api) => { return [arg] } -export async function execMintBasilisk({ - item, - api, - executeTransaction, - isLoading, - status, -}: MintTokenParams) { - const { $i18n } = useNuxtApp() - isLoading.value = true - status.value = 'loader.ipfs' - const args = await getArgs(item, api) - - const nameInNotifications = Array.isArray(item.token) - ? item.token.map((t) => t.name).join(', ') - : item.token.name - - executeTransaction({ - cb: api.tx.utility.batchAll, - arg: args, - successMessage: - item.successMessage || - ((blockNumber) => - $i18n.t('mint.mintNFTSuccess', { - name: nameInNotifications, - block: blockNumber, - })), - errorMessage: - item.errorMessage || - $i18n.t('mint.errorCreateNewNft', { name: nameInNotifications }), - }) -} +export const execMintStatemine = transactionFactory(getArgs) diff --git a/composables/transaction/mintToken/transactionMintStatemine.ts b/composables/transaction/mintToken/transactionMintStatemine.ts index 4bf171cb17..211bae8f99 100644 --- a/composables/transaction/mintToken/transactionMintStatemine.ts +++ b/composables/transaction/mintToken/transactionMintStatemine.ts @@ -6,7 +6,7 @@ import type { } from '../types' import { TokenToMint } from '../types' import { constructMeta } from './constructMeta' -import { calculateFees, copiesToMint } from './utils' +import { calculateFees, copiesToMint, transactionFactory } from './utils' import { canSupport } from '@/utils/support' type id = { id: number } @@ -117,35 +117,4 @@ const getArgs = async (item: ActionMintToken, api) => { return [[...arg.flat(), ...supportInteraction]] } -export async function execMintStatemine({ - item, - api, - executeTransaction, - isLoading, - status, -}: MintTokenParams) { - const { $i18n } = useNuxtApp() - - isLoading.value = true - status.value = 'loader.ipfs' - const args = await getArgs(item, api) - - const nameInNotifications = Array.isArray(item.token) - ? item.token.map((t) => t.name).join(', ') - : item.token.name - - executeTransaction({ - cb: api.tx.utility.batchAll, - arg: args, - successMessage: - item.successMessage || - ((blockNumber) => - $i18n.t('mint.mintNFTSuccess', { - name: nameInNotifications, - block: blockNumber, - })), - errorMessage: - item.errorMessage || - $i18n.t('mint.errorCreateNewNft', { name: nameInNotifications }), - }) -} +export const execMintStatemine = transactionFactory(getArgs) diff --git a/composables/transaction/mintToken/utils.ts b/composables/transaction/mintToken/utils.ts index c45dc0ef05..c061a3e254 100644 --- a/composables/transaction/mintToken/utils.ts +++ b/composables/transaction/mintToken/utils.ts @@ -1,5 +1,5 @@ import { usePreferencesStore } from '@/stores/preferences' -import { Max, MintedCollection, TokenToMint } from '../types' +import { Max, MintTokenParams, MintedCollection, TokenToMint } from '../types' export const copiesToMint = (token: T): number => { const { copies, selectedCollection } = token @@ -22,3 +22,38 @@ export const calculateFees = () => { return { enabledFees, feeMultiplier } } + +export const transactionFactory = (getArgs) => { + return async ({ + item, + api, + executeTransaction, + isLoading, + status, + }: MintTokenParams) => { + const { $i18n } = useNuxtApp() + + isLoading.value = true + status.value = 'loader.ipfs' + const args = await getArgs(item, api) + + const nameInNotifications = Array.isArray(item.token) + ? item.token.map((t) => t.name).join(', ') + : item.token.name + + executeTransaction({ + cb: api.tx.utility.batchAll, + arg: args, + successMessage: + item.successMessage || + ((blockNumber) => + $i18n.t('mint.mintNFTSuccess', { + name: nameInNotifications, + block: blockNumber, + })), + errorMessage: + item.errorMessage || + $i18n.t('mint.errorCreateNewNft', { name: nameInNotifications }), + }) + } +} From d3597b0f1282067fc91668681e319e21b0b76eb2 Mon Sep 17 00:00:00 2001 From: Floyd Li Date: Thu, 24 Aug 2023 18:38:25 +0800 Subject: [PATCH 015/167] fix: remove unused var --- .../transaction/mintToken/transactionMintStatemine.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/composables/transaction/mintToken/transactionMintStatemine.ts b/composables/transaction/mintToken/transactionMintStatemine.ts index 211bae8f99..4cab7957b9 100644 --- a/composables/transaction/mintToken/transactionMintStatemine.ts +++ b/composables/transaction/mintToken/transactionMintStatemine.ts @@ -1,9 +1,5 @@ import { BaseMintedCollection } from '@/components/base/types' -import type { - ActionMintToken, - MintTokenParams, - MintedCollection, -} from '../types' +import type { ActionMintToken, MintedCollection } from '../types' import { TokenToMint } from '../types' import { constructMeta } from './constructMeta' import { calculateFees, copiesToMint, transactionFactory } from './utils' From 9ce141bc805ffa83ec84e7f4810c898724e82304 Mon Sep 17 00:00:00 2001 From: hassnian Date: Thu, 24 Aug 2023 17:18:00 +0500 Subject: [PATCH 016/167] fix: sonarcloud issues --- components/transfer/Transfer.vue | 114 +++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 36 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 466ca74ad1..6f9344347e 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -267,6 +267,7 @@ import { } from '@kodadot1/brick' import TransferTokenTabs, { TransferTokenTab } from './TransferTokenTabs.vue' import { TokenDetails } from '@/composables/useToken' +import { ApiPromise } from '@polkadot/api' const Money = defineAsyncComponent( () => import('@/components/shared/format/Money.vue') ) @@ -525,18 +526,67 @@ const handleOpenConfirmModal = () => { } } -const createTxArgs = ( - target: TargetAddress, - tokenTransfer: boolean, - tokenId: string | null, +const getAmountToTransfer = (amount: number, decimals: number) => + String(calculateBalance(Number(amount), decimals)) + +interface TransferParams { + api: ApiPromise decimals: number -): [string, string, string] | [string, string] => { - const amountToTransfer = String( - calculateBalance(Number(target.token), decimals) + tokenTransfer: boolean + tokenId: string +} + +const getMultipleAddressesTransferParams = ({ + api, + decimals, + tokenTransfer, + tokenId, +}: TransferParams) => { + const arg = [ + targetAddresses.value.map((target) => { + const amountToTransfer = getAmountToTransfer( + target.token as number, + decimals + ) + + if (tokenTransfer) { + return api.tx.tokens.transfer(target.address, tokenId, amountToTransfer) + } + + return api.tx.balances.transfer( + target.address as string, + amountToTransfer + ) + }), + ] + + return [api.tx.utility.batch, arg] +} + +const getSingleAddressTransferParams = ({ + api, + decimals, + tokenTransfer, + tokenId, +}: TransferParams) => { + const address = targetAddresses.value[0] + + const amountToTransfer = getAmountToTransfer( + address.token as number, + decimals ) - return tokenTransfer && tokenId !== null - ? [target.address as string, tokenId, amountToTransfer] - : [target.address as string, amountToTransfer] + + if (tokenTransfer) { + return [ + api.tx.tokens.transfer, + [address.address, tokenId, amountToTransfer], + ] + } + + return [ + api.tx.balances.transfer, + [address.address as string, amountToTransfer], + ] } const submit = async ( @@ -554,32 +604,24 @@ const submit = async ( const numOfTargetAddresses = targetAddresses.value.length const multipleAddresses = numOfTargetAddresses > 1 - const cb = multipleAddresses - ? api.tx.utility.batch - : tokenTransfer - ? api.tx.tokens.transfer - : api.tx.balances.transfer - - const arg = multipleAddresses - ? [ - targetAddresses.value.map((target) => { - const txArgs = createTxArgs( - target, - tokenTransfer, - tokenId, - decimals.value as number - ) - return tokenTransfer - ? api.tx.tokens.transfer(...txArgs) - : api.tx.balances.transfer(...(txArgs as [string, string])) - }), - ] - : createTxArgs( - targetAddresses.value[0], - tokenTransfer, - tokenId, - decimals.value as number - ) + + let cb, arg + + if (multipleAddresses) { + ;[cb, arg] = getMultipleAddressesTransferParams({ + api, + tokenId: tokenId as string, + tokenTransfer, + decimals: decimals.value as number, + }) + } else { + ;[cb, arg] = getSingleAddressTransferParams({ + api, + tokenId: tokenId as string, + tokenTransfer, + decimals: decimals.value as number, + }) + } const tx = await exec( accountId.value, From 9b6ac484c9ba1449a13a712298a7a6bd1e1c81c5 Mon Sep 17 00:00:00 2001 From: hassnian Date: Thu, 24 Aug 2023 17:20:43 +0500 Subject: [PATCH 017/167] ref: rename --- components/transfer/Transfer.vue | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 6f9344347e..64092db35d 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -569,23 +569,17 @@ const getSingleAddressTransferParams = ({ tokenTransfer, tokenId, }: TransferParams) => { - const address = targetAddresses.value[0] + const target = targetAddresses.value[0] - const amountToTransfer = getAmountToTransfer( - address.token as number, - decimals - ) + const amountToTransfer = getAmountToTransfer(target.token as number, decimals) if (tokenTransfer) { - return [ - api.tx.tokens.transfer, - [address.address, tokenId, amountToTransfer], - ] + return [api.tx.tokens.transfer, [target.address, tokenId, amountToTransfer]] } return [ api.tx.balances.transfer, - [address.address as string, amountToTransfer], + [target.address as string, amountToTransfer], ] } From 121624228d20ed4293c3c02024abbd30253fdecd Mon Sep 17 00:00:00 2001 From: Floyd Li Date: Thu, 24 Aug 2023 22:42:17 +0800 Subject: [PATCH 018/167] refactor: fix code climate issue --- .../mintToken/transactionMintRmrk.ts | 6 ++--- composables/transaction/mintToken/utils.ts | 27 +++++++++++-------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/composables/transaction/mintToken/transactionMintRmrk.ts b/composables/transaction/mintToken/transactionMintRmrk.ts index e097193f94..219b9799e5 100644 --- a/composables/transaction/mintToken/transactionMintRmrk.ts +++ b/composables/transaction/mintToken/transactionMintRmrk.ts @@ -26,7 +26,7 @@ import { } from '../types' import { constructMeta } from './constructMeta' import { isRoyaltyValid } from '@/utils/royalty' -import { calculateFees, copiesToMint } from './utils' +import { calculateFees, copiesToMint, getNameInNotifications } from './utils' const getOnChainProperties = ({ tags, royalty, hasRoyalty }: TokenToMint) => { let onChainProperties = convertAttributesToProperties(tags) @@ -151,9 +151,7 @@ export async function execMintRmrk({ status.value = 'loader.ipfs' const { args, createdNFTs } = await getArgs(item, api) - const nameInNotifications = Array.isArray(item.token) - ? item.token.map((t) => t.name).join(', ') - : item.token.name + const nameInNotifications = getNameInNotifications(item) const isSingle = args.length === 1 const cb = isSingle ? api.tx.system.remark : api.tx.utility.batchAll diff --git a/composables/transaction/mintToken/utils.ts b/composables/transaction/mintToken/utils.ts index c061a3e254..78d2819701 100644 --- a/composables/transaction/mintToken/utils.ts +++ b/composables/transaction/mintToken/utils.ts @@ -1,5 +1,11 @@ import { usePreferencesStore } from '@/stores/preferences' -import { Max, MintTokenParams, MintedCollection, TokenToMint } from '../types' +import { + ActionMintToken, + Max, + MintTokenParams, + MintedCollection, + TokenToMint, +} from '../types' export const copiesToMint = (token: T): number => { const { copies, selectedCollection } = token @@ -23,23 +29,22 @@ export const calculateFees = () => { return { enabledFees, feeMultiplier } } +export const getNameInNotifications = (item: ActionMintToken) => { + return Array.isArray(item.token) + ? item.token.map((t) => t.name).join(', ') + : item.token.name +} + export const transactionFactory = (getArgs) => { - return async ({ - item, - api, - executeTransaction, - isLoading, - status, - }: MintTokenParams) => { + return async (mintTokenParams: MintTokenParams) => { + const { item, api, executeTransaction, isLoading, status } = mintTokenParams const { $i18n } = useNuxtApp() isLoading.value = true status.value = 'loader.ipfs' const args = await getArgs(item, api) - const nameInNotifications = Array.isArray(item.token) - ? item.token.map((t) => t.name).join(', ') - : item.token.name + const nameInNotifications = getNameInNotifications(item) executeTransaction({ cb: api.tx.utility.batchAll, From 45cb28e30b8a6548272d5e69796f18edbe9fc6ac Mon Sep 17 00:00:00 2001 From: daiagi Date: Fri, 25 Aug 2023 11:36:10 +0700 Subject: [PATCH 019/167] get rid of console warnings --- components/shared/AddressInput.vue | 3 ++- components/transfer/Transfer.vue | 14 ++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/components/shared/AddressInput.vue b/components/shared/AddressInput.vue index 169e896f14..149f9853de 100644 --- a/components/shared/AddressInput.vue +++ b/components/shared/AddressInput.vue @@ -21,7 +21,7 @@ const props = withDefaults( defineProps<{ value: string label: string - emptyOnError: boolean + emptyOnError?: boolean strict: boolean icon?: string placeholder?: string @@ -31,6 +31,7 @@ const props = withDefaults( strict: true, icon: '', placeholder: '', + emptyOnError: false, } ) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 9c743c020d..a9eb972fff 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -260,6 +260,7 @@ import { } from '@kodadot1/brick' import TransferTokenTabs, { TransferTokenTab } from './TransferTokenTabs.vue' import { TokenDetails } from '@/composables/useToken' +import AddressInput from '../shared/AddressInput.vue' const Money = defineAsyncComponent( () => import('@/components/shared/format/Money.vue') ) @@ -279,7 +280,7 @@ const { toast } = useToast() const isTransferModalVisible = ref(false) export type TargetAddress = { - address?: string + address: string usd?: number | string token?: number | string } @@ -296,7 +297,7 @@ const tokenIcon = computed(() => getTokenIconBySymbol(unit.value)) const tokenTabs = ref([]) -const targetAddresses = ref([{}]) +const targetAddresses = ref([{ address: '' }]) const hasValidTarget = computed(() => targetAddresses.value.some((item) => isAddress(item.address) && item.token) @@ -523,14 +524,11 @@ const submit = async ( const amountToTransfer = String( calculateBalance(Number(target.token), decimals.value) ) - return api.tx.balances.transfer( - target.address as string, - amountToTransfer - ) + return api.tx.balances.transfer(target.address, amountToTransfer) }), ] : [ - targetAddresses.value[0].address as string, + targetAddresses.value[0].address, calculateBalance( Number(targetAddresses.value[0].token), decimals.value @@ -553,7 +551,7 @@ const submit = async ( notificationTypes.success ) - targetAddresses.value = [{}] + targetAddresses.value = [{ address: '' }] if (route.query && !route.query.donation) { router.push(route.path) } From 6124b5593a736268fe8ed0b3bea4a16e2799b12c Mon Sep 17 00:00:00 2001 From: hassnian Date: Fri, 25 Aug 2023 10:03:11 +0500 Subject: [PATCH 020/167] add: filter by current network --- components/transfer/Transfer.vue | 2 +- composables/useToken.ts | 26 ++++++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 64092db35d..674dc905a8 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -298,7 +298,7 @@ const sendSameAmount = ref(false) const displayUnit = ref<'token' | 'usd'>('token') const { getTokenIconBySymbol } = useIcon() -const { tokens, isTokenValidForChain } = useToken() +const { tokens, isTokenValidForChain } = useToken(true) const unit = ref(chainUnit.value) const selectedToken = computed(() => tokens.value.find((t) => t.symbol === unit.value) diff --git a/composables/useToken.ts b/composables/useToken.ts index 3fcdc8540c..ee2bdca6a4 100644 --- a/composables/useToken.ts +++ b/composables/useToken.ts @@ -18,12 +18,24 @@ export interface TokenDetails { const getAssetToken = (asset) => asset?.token || 'KSM' const getUniqueArrayItems = (items: string[]) => [...new Set(items)] -export default function useToken() { +export default function useToken(filterByCurrentChain = false) { const { getCurrentTokenValue } = useFiatStore() const { getTokenIconBySymbol } = useIcon() const { getAvailableAssets } = useIdentityStore() + const { urlPrefix } = usePrefix() + + const availableAssets = computed(() => { + if (!filterByCurrentChain) { + return getAvailableAssets + } + return getAvailableAssets.filter((asset) => { + if (asset.chain === 'kusama') { + return ['rmrk', 'ksm'].includes(urlPrefix.value) + } + return urlPrefix.value === networkToPrefix[asset.chain] + }) + }) - const availableAssets = computed(() => getAvailableAssets) const availableTokensAcrossAllChains = computed(() => getUniqueArrayItems(Object.values(availableAssets.value).map(getAssetToken)) ) @@ -41,10 +53,12 @@ export default function useToken() { } const getChainTokenIds = (token: string) => { - return getMatchingAvailableAssetsByToken(token).reduce((reducer, asset) => { - const chainPrefix = networkToPrefix[asset.chain] - return { ...reducer, [chainPrefix]: asset.tokenId } - }, {} as TokenIds) + return Object.fromEntries( + getMatchingAvailableAssetsByToken(token).map((asset) => [ + networkToPrefix[asset.chain], + asset.tokenId, + ]) + ) as TokenIds } const tokens = computed(() => { From c06e9c22c09fc1b6a25adc97ffdd34926d3c7455 Mon Sep 17 00:00:00 2001 From: daiagi Date: Fri, 25 Aug 2023 12:13:10 +0700 Subject: [PATCH 021/167] use enum for TransactionStatus --- components/buy/Buy.vue | 5 +- components/massmint/Massmint.vue | 2 +- components/shared/TransactionLoader.vue | 127 ++++++++++++++++++++++++ components/transfer/Transfer.vue | 1 + composables/useTransactionStatus.ts | 26 +++-- 5 files changed, 152 insertions(+), 9 deletions(-) create mode 100644 components/shared/TransactionLoader.vue diff --git a/components/buy/Buy.vue b/components/buy/Buy.vue index 006d3f960e..5eab10a4ec 100644 --- a/components/buy/Buy.vue +++ b/components/buy/Buy.vue @@ -48,7 +48,10 @@ const ShoppingCartItemToTokenToBuy = (item: ShoppingCartItem): TokenToBuy => { } watchEffect(() => { - if (isLoading.value === false && status.value === 'loader.finalized') { + if ( + isLoading.value === false && + status.value === TransactionStatus.Finalized + ) { preferencesStore.setTriggerBuySuccess(true) shoppingCartStore.clear() } diff --git a/components/massmint/Massmint.vue b/components/massmint/Massmint.vue index 617b82a39f..8400460bea 100644 --- a/components/massmint/Massmint.vue +++ b/components/massmint/Massmint.vue @@ -169,7 +169,7 @@ const startMint = () => { if (isLoadingOldV && !isLoadingV) { mintModalOpen.value = false - if (!isError.value && statusV !== 'loader.sign') { + if (!isError.value && statusV !== TransactionStatus.Sign) { showNotification( $i18n.t('massmint.continueToCollectionPage'), notificationTypes.success diff --git a/components/shared/TransactionLoader.vue b/components/shared/TransactionLoader.vue new file mode 100644 index 0000000000..23bfe3954a --- /dev/null +++ b/components/shared/TransactionLoader.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index a9eb972fff..6ef808e2d1 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -261,6 +261,7 @@ import { import TransferTokenTabs, { TransferTokenTab } from './TransferTokenTabs.vue' import { TokenDetails } from '@/composables/useToken' import AddressInput from '../shared/AddressInput.vue' +import Loader from '../shared/Loader.vue' const Money = defineAsyncComponent( () => import('@/components/shared/format/Money.vue') ) diff --git a/composables/useTransactionStatus.ts b/composables/useTransactionStatus.ts index d11216c946..f1c7caf2ff 100644 --- a/composables/useTransactionStatus.ts +++ b/composables/useTransactionStatus.ts @@ -1,7 +1,16 @@ import { ExtrinsicStatus } from '@polkadot/types/interfaces' +export enum TransactionStatus { + Casting = 'loader.casting', + Sign = 'loader.sign', + Block = 'loader.block', + Finalized = 'loader.finalized', + Unkonwn = '', + IPFS = 'loader.ipfs', +} + function useTransactionStatus() { - const status = ref('') + const status = ref(TransactionStatus.Unkonwn) const isLoading = ref(false) const resolveStatus = ( @@ -9,31 +18,34 @@ function useTransactionStatus() { omitFinalized?: boolean ): void => { if (extrinsicStatus.isReady) { - status.value = 'loader.casting' + // status.value = 'loader.casting' + status.value = TransactionStatus.Casting return } if (extrinsicStatus.isInBlock) { - status.value = 'loader.block' + status.value = TransactionStatus.Block return } if (extrinsicStatus.isFinalized) { - status.value = omitFinalized ? '' : 'loader.finalized' + status.value = omitFinalized + ? TransactionStatus.Unkonwn + : TransactionStatus.Finalized return } - status.value = '' + status.value = TransactionStatus.Unkonwn } const initTransactionLoader = (): void => { isLoading.value = true - status.value = 'loader.sign' + status.value = TransactionStatus.Unkonwn } const stopLoader = (): void => { isLoading.value = false - status.value = '' + status.value = TransactionStatus.Unkonwn } return { status, From 89e04e8ab97acf6978f40e78d33b7b8dbc1be319 Mon Sep 17 00:00:00 2001 From: hassnian Date: Fri, 25 Aug 2023 11:18:02 +0500 Subject: [PATCH 022/167] fix: token query not synced --- components/transfer/Transfer.vue | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 674dc905a8..7d2d725b88 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -727,18 +727,29 @@ onMounted(() => { fetchFiatPrice().then(checkQueryParams) }) +const pushQuery = (queryParams) => { + router + .replace({ + query: { + ...route.query, + ...queryParams, + }, + }) + .catch(() => null) // null to further not throw navigation errors +} + +watch(unit, (newToken) => { + pushQuery({ + token: newToken, + }) +}) + watchDebounced( () => targetAddresses.value[0].usd, (usdamount) => { - router - .replace({ - query: { - ...route.query, - usdamount: (usdamount || 0).toString(), - token: unit.value, - }, - }) - .catch(() => null) // null to further not throw navigation errors + pushQuery({ + usdamount: (usdamount || 0).toString(), + }) }, { debounce: 300 } ) From 7390bb436878d0ead5aa867199192e3703bed328 Mon Sep 17 00:00:00 2001 From: hassnian Date: Fri, 25 Aug 2023 11:28:32 +0500 Subject: [PATCH 023/167] remove: not current chain case --- components/transfer/Transfer.vue | 8 ++------ composables/useToken.ts | 4 ---- utils/config/chain.config.ts | 8 -------- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 7d2d725b88..3143a78d90 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -347,15 +347,11 @@ const handleTokenSelect = (newToken: string) => { urlPrefix.value ) - if (isTokenAvailableForCurrentChain) { - unit.value = token.symbol + if (!isTokenAvailableForCurrentChain) { return } - router.replace({ - params: { prefix: token.defaultChain }, - query: { ...route.query, token: token.symbol }, - }) + unit.value = token.symbol } const generateTokenTabs = ( diff --git a/composables/useToken.ts b/composables/useToken.ts index ee2bdca6a4..fd89c579af 100644 --- a/composables/useToken.ts +++ b/composables/useToken.ts @@ -1,7 +1,6 @@ import { useFiatStore } from '@/stores/fiat' import { CHAINS, type Prefix } from '@kodadot1/static' import { networkToPrefix, useIdentityStore } from '@/stores/identity' -import { defultTokenChain } from '@/utils/config/chain.config' type TokenDecimals = Record type TokenIds = Record @@ -10,7 +9,6 @@ export interface TokenDetails { value: number | string | null icon: string chains: Prefix[] - defaultChain: Prefix tokenDecimals: TokenDecimals tokenIds: TokenIds } @@ -64,7 +62,6 @@ export default function useToken(filterByCurrentChain = false) { const tokens = computed(() => { return availableTokensAcrossAllChains.value.map((tokenSymbol) => { const chains = getTokenChains(tokenSymbol) - const defaultChain = defultTokenChain[tokenSymbol] const tokenDecimals = Object.fromEntries( chains.map((chain) => [chain, CHAINS[chain].tokenDecimals]) ) as TokenDecimals @@ -75,7 +72,6 @@ export default function useToken(filterByCurrentChain = false) { value: getCurrentTokenValue(tokenSymbol), icon: getTokenIconBySymbol(tokenSymbol), chains: chains, - defaultChain: defaultChain, tokenDecimals: tokenDecimals, tokenIds: tokenIds, } diff --git a/utils/config/chain.config.ts b/utils/config/chain.config.ts index cfc19f03cf..9cf841716a 100644 --- a/utils/config/chain.config.ts +++ b/utils/config/chain.config.ts @@ -28,11 +28,3 @@ export const chainAssetOf = (prefix: Prefix): AssetItem => { decimals, } } - -export const defultTokenChain: Record = { - KSM: 'ksm', - DOT: 'dot', - BSX: 'bsx', - GLMR: 'glmr', - MOVR: 'movr', -} From ef2f650956a9920d39d8a8b2ddfbe392538ab84a Mon Sep 17 00:00:00 2001 From: hassnian Date: Fri, 25 Aug 2023 11:51:29 +0500 Subject: [PATCH 024/167] fix: on token switch update field on usd value --- components/transfer/Transfer.vue | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 3143a78d90..8c6a5009ba 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -497,11 +497,7 @@ const unifyAddressAmount = (target: TargetAddress) => { const updateTargetAdressesOnTokenSwitch = () => { targetAddresses.value.forEach((targetAddress) => { - if (displayUnit.value === 'usd') { - onUsdFieldChange(targetAddress) - } else { - onAmountFieldChange(targetAddress) - } + onUsdFieldChange(targetAddress) }) } From 1213124a8e9ed0465cfd38936f39010b74461f50 Mon Sep 17 00:00:00 2001 From: Floyd Li Date: Fri, 25 Aug 2023 16:07:47 +0800 Subject: [PATCH 025/167] refactor: execAcceptOfferTx and execWithdrawOfferTx --- .../transaction/transactionOfferAccept.ts | 24 ++----------------- .../transaction/transactionOfferWithdraw.ts | 24 ++----------------- composables/transaction/utils.ts | 20 ++++++++++++++++ 3 files changed, 24 insertions(+), 44 deletions(-) create mode 100644 composables/transaction/utils.ts diff --git a/composables/transaction/transactionOfferAccept.ts b/composables/transaction/transactionOfferAccept.ts index b1a3ee44fe..8126078ee8 100644 --- a/composables/transaction/transactionOfferAccept.ts +++ b/composables/transaction/transactionOfferAccept.ts @@ -1,23 +1,3 @@ -import { warningMessage } from '@/utils/notification' -import { tokenIdToRoute } from '@/components/unique/utils' +import { transactionOfferFactory } from './utils' -import type { ActionWithdrawOffer } from './types' - -export function execAcceptOfferTx( - params: ActionWithdrawOffer, - api, - executeTransaction -) { - try { - const { id, item } = tokenIdToRoute(params.nftId) - const args = [id, item, params.maker] - const cb = api.tx.marketplace.acceptOffer - - executeTransaction({ - cb, - arg: args, - }) - } catch (error) { - warningMessage(error) - } -} +export const execAcceptOfferTx = transactionOfferFactory('acceptOffer') diff --git a/composables/transaction/transactionOfferWithdraw.ts b/composables/transaction/transactionOfferWithdraw.ts index 8bb11efc45..761c594306 100644 --- a/composables/transaction/transactionOfferWithdraw.ts +++ b/composables/transaction/transactionOfferWithdraw.ts @@ -1,23 +1,3 @@ -import { warningMessage } from '@/utils/notification' -import { tokenIdToRoute } from '@/components/unique/utils' +import { transactionOfferFactory } from './utils' -import type { ActionWithdrawOffer } from './types' - -export function execWithdrawOfferTx( - params: ActionWithdrawOffer, - api, - executeTransaction -) { - try { - const { id, item } = tokenIdToRoute(params.nftId) - const args = [id, item, params.maker] - const cb = api.tx.marketplace.withdrawOffer - - executeTransaction({ - cb, - arg: args, - }) - } catch (error) { - warningMessage(error) - } -} +export const execWithdrawOfferTx = transactionOfferFactory('withdrawOffer') diff --git a/composables/transaction/utils.ts b/composables/transaction/utils.ts new file mode 100644 index 0000000000..168512c3a0 --- /dev/null +++ b/composables/transaction/utils.ts @@ -0,0 +1,20 @@ +import { warningMessage } from '@/utils/notification' +import { tokenIdToRoute } from '@/components/unique/utils' + +import type { ActionWithdrawOffer } from './types' + +export function transactionOfferFactory(key: 'acceptOffer' | 'withdrawOffer') { + return function (params: ActionWithdrawOffer, api, executeTransaction) { + try { + const { id, item } = tokenIdToRoute(params.nftId) + const args = [id, item, params.maker] + const cb = api.tx.marketplace[key] + executeTransaction({ + cb, + arg: args, + }) + } catch (error) { + warningMessage(error) + } + } +} From 727eabc8943f11387118284137b4cafc1f0f7b0d Mon Sep 17 00:00:00 2001 From: hassnian Date: Fri, 25 Aug 2023 14:47:34 +0500 Subject: [PATCH 026/167] ref: useTokens tokens current chain --- components/transfer/Transfer.vue | 15 +++----- composables/useToken.ts | 60 ++++++++++---------------------- 2 files changed, 23 insertions(+), 52 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 8c6a5009ba..67a0da7f2e 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -298,14 +298,12 @@ const sendSameAmount = ref(false) const displayUnit = ref<'token' | 'usd'>('token') const { getTokenIconBySymbol } = useIcon() -const { tokens, isTokenValidForChain } = useToken(true) +const { tokens, isTokenValidForChain } = useToken() const unit = ref(chainUnit.value) const selectedToken = computed(() => tokens.value.find((t) => t.symbol === unit.value) ) -const decimals = computed( - () => selectedToken.value?.tokenDecimals[urlPrefix.value] -) +const decimals = computed(() => selectedToken.value?.tokenDecimals) const selectedTabFirst = ref(true) const tokenIcon = computed(() => getTokenIconBySymbol(unit.value)) @@ -342,10 +340,7 @@ const handleTokenSelect = (newToken: string) => { return } - const isTokenAvailableForCurrentChain = isTokenValidForChain( - token.symbol, - urlPrefix.value - ) + const isTokenAvailableForCurrentChain = isTokenValidForChain(token.symbol) if (!isTokenAvailableForCurrentChain) { return @@ -585,7 +580,7 @@ const submit = async ( try { const api = await apiInstance.value - const tokenId = selectedToken.value?.tokenIds[urlPrefix.value] || null + const tokenId = selectedToken.value?.tokenId || null const tokenTransfer = !!tokenId const numOfTargetAddresses = targetAddresses.value.length @@ -700,7 +695,7 @@ const addAddress = () => { const syncQueryToken = () => { const token = route.query.token?.toString() - if (!isTokenValidForChain(token, urlPrefix.value)) { + if (!isTokenValidForChain(token)) { return } diff --git a/composables/useToken.ts b/composables/useToken.ts index fd89c579af..2661ae9c3b 100644 --- a/composables/useToken.ts +++ b/composables/useToken.ts @@ -1,31 +1,25 @@ import { useFiatStore } from '@/stores/fiat' -import { CHAINS, type Prefix } from '@kodadot1/static' +import { CHAINS } from '@kodadot1/static' import { networkToPrefix, useIdentityStore } from '@/stores/identity' -type TokenDecimals = Record -type TokenIds = Record export interface TokenDetails { symbol: string value: number | string | null icon: string - chains: Prefix[] - tokenDecimals: TokenDecimals - tokenIds: TokenIds + tokenDecimals: number + tokenId: string | undefined } const getAssetToken = (asset) => asset?.token || 'KSM' const getUniqueArrayItems = (items: string[]) => [...new Set(items)] -export default function useToken(filterByCurrentChain = false) { +export default function useToken() { const { getCurrentTokenValue } = useFiatStore() const { getTokenIconBySymbol } = useIcon() const { getAvailableAssets } = useIdentityStore() const { urlPrefix } = usePrefix() const availableAssets = computed(() => { - if (!filterByCurrentChain) { - return getAvailableAssets - } return getAvailableAssets.filter((asset) => { if (asset.chain === 'kusama') { return ['rmrk', 'ksm'].includes(urlPrefix.value) @@ -34,61 +28,43 @@ export default function useToken(filterByCurrentChain = false) { }) }) - const availableTokensAcrossAllChains = computed(() => + const availableTokens = computed(() => getUniqueArrayItems(Object.values(availableAssets.value).map(getAssetToken)) ) - const getMatchingAvailableAssetsByToken = (token: string) => { - return Object.values(availableAssets.value).filter( + const getAvailableAssetByToken = (token: string) => { + return Object.values(availableAssets.value).find( (asset) => token === getAssetToken(asset) ) } - const getTokenChains = (token: string): Prefix[] => { - return getMatchingAvailableAssetsByToken(token).map( - (asset) => networkToPrefix[asset.chain] as Prefix - ) - } - - const getChainTokenIds = (token: string) => { - return Object.fromEntries( - getMatchingAvailableAssetsByToken(token).map((asset) => [ - networkToPrefix[asset.chain], - asset.tokenId, - ]) - ) as TokenIds + const getChainTokenId = (token: string): string | undefined => { + const asset = getAvailableAssetByToken(token) + return asset?.tokenId } const tokens = computed(() => { - return availableTokensAcrossAllChains.value.map((tokenSymbol) => { - const chains = getTokenChains(tokenSymbol) - const tokenDecimals = Object.fromEntries( - chains.map((chain) => [chain, CHAINS[chain].tokenDecimals]) - ) as TokenDecimals - const tokenIds = getChainTokenIds(tokenSymbol) + return availableTokens.value.map((tokenSymbol) => { + const tokenId = getChainTokenId(tokenSymbol) + const chainProperties = CHAINS[urlPrefix.value] return { symbol: tokenSymbol as string, value: getCurrentTokenValue(tokenSymbol), icon: getTokenIconBySymbol(tokenSymbol), - chains: chains, - tokenDecimals: tokenDecimals, - tokenIds: tokenIds, + tokenDecimals: chainProperties.tokenDecimals, + tokenId: tokenId, } }) }) - const isTokenValidForChain = (token: string, urlPrefix: Prefix) => { - const isValidToken = availableTokensAcrossAllChains.value.includes(token) - const isAvailableForCurrentChain = tokens.value - .map((t) => t.chains.includes(urlPrefix) && t.symbol === token) - .some(Boolean) - return !!token && isValidToken && isAvailableForCurrentChain + const isTokenValidForChain = (token: string) => { + const isValidToken = availableTokens.value.includes(token) + return !!token && isValidToken } return { tokens, - availableTokensAcrossAllChains, isTokenValidForChain, } } From 9cd6e5294d10f0fdfe1e0f0e533f0ba4d59b1271 Mon Sep 17 00:00:00 2001 From: hassnian Date: Fri, 25 Aug 2023 15:06:12 +0500 Subject: [PATCH 027/167] ref: simplifying code --- composables/useToken.ts | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/composables/useToken.ts b/composables/useToken.ts index 2661ae9c3b..a47b041db9 100644 --- a/composables/useToken.ts +++ b/composables/useToken.ts @@ -32,36 +32,23 @@ export default function useToken() { getUniqueArrayItems(Object.values(availableAssets.value).map(getAssetToken)) ) - const getAvailableAssetByToken = (token: string) => { - return Object.values(availableAssets.value).find( + const getAvailableAssetByToken = (token: string) => + Object.values(availableAssets.value).find( (asset) => token === getAssetToken(asset) ) - } - - const getChainTokenId = (token: string): string | undefined => { - const asset = getAvailableAssetByToken(token) - return asset?.tokenId - } const tokens = computed(() => { - return availableTokens.value.map((tokenSymbol) => { - const tokenId = getChainTokenId(tokenSymbol) - const chainProperties = CHAINS[urlPrefix.value] - - return { - symbol: tokenSymbol as string, - value: getCurrentTokenValue(tokenSymbol), - icon: getTokenIconBySymbol(tokenSymbol), - tokenDecimals: chainProperties.tokenDecimals, - tokenId: tokenId, - } - }) + return availableTokens.value.map((tokenSymbol) => ({ + symbol: tokenSymbol as string, + value: getCurrentTokenValue(tokenSymbol), + icon: getTokenIconBySymbol(tokenSymbol), + tokenDecimals: CHAINS[urlPrefix.value].tokenDecimals, + tokenId: getAvailableAssetByToken(tokenSymbol)?.tokenId, + })) }) - const isTokenValidForChain = (token: string) => { - const isValidToken = availableTokens.value.includes(token) - return !!token && isValidToken - } + const isTokenValidForChain = (token: string) => + !!token && availableTokens.value.includes(token) return { tokens, From c37900cb81c445f6ecfcfbffdb4f9c374a40d0e8 Mon Sep 17 00:00:00 2001 From: hassnian Date: Fri, 25 Aug 2023 15:27:21 +0500 Subject: [PATCH 028/167] fix: clear token from query --- components/transfer/Transfer.vue | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/components/transfer/Transfer.vue b/components/transfer/Transfer.vue index 67a0da7f2e..629ba4fc15 100644 --- a/components/transfer/Transfer.vue +++ b/components/transfer/Transfer.vue @@ -714,29 +714,35 @@ onMounted(() => { fetchFiatPrice().then(checkQueryParams) }) -const pushQuery = (queryParams) => { +const routerReplace = ({ params = {}, query }) => { router .replace({ + params: params, query: { ...route.query, - ...queryParams, + ...query, }, }) .catch(() => null) // null to further not throw navigation errors } watch(unit, (newToken) => { - pushQuery({ - token: newToken, + routerReplace({ query: { token: newToken } }) +}) + +watch(urlPrefix, (chain) => { + routerReplace({ + params: { prefix: chain }, + query: { + token: undefined, + }, }) }) watchDebounced( () => targetAddresses.value[0].usd, (usdamount) => { - pushQuery({ - usdamount: (usdamount || 0).toString(), - }) + routerReplace({ query: { usdamount: (usdamount || 0).toString() } }) }, { debounce: 300 } ) From 71b0f2f8c8ba76c4cf9fcb65b623358e5dd0ba44 Mon Sep 17 00:00:00 2001 From: Peter Kompasz Date: Fri, 25 Aug 2023 15:12:46 +0300 Subject: [PATCH 029/167] refactor(SearchSuggestion) to composition API --- components/search/SearchSuggestion.vue | 736 +++++++++++++------------ 1 file changed, 369 insertions(+), 367 deletions(-) diff --git a/components/search/SearchSuggestion.vue b/components/search/SearchSuggestion.vue index a636ccbea7..6dbf7b98c9 100644 --- a/components/search/SearchSuggestion.vue +++ b/components/search/SearchSuggestion.vue @@ -241,9 +241,7 @@ - From 353fe8ac47ce6638180ddd30228a5b12db1cef92 Mon Sep 17 00:00:00 2001 From: Peter Kompasz Date: Fri, 25 Aug 2023 15:15:37 +0300 Subject: [PATCH 030/167] refactor(SearchSuggestion) to composition API --- components/search/SearchSuggestion.vue | 43 ++++++-------------------- 1 file changed, 9 insertions(+), 34 deletions(-) diff --git a/components/search/SearchSuggestion.vue b/components/search/SearchSuggestion.vue index 6dbf7b98c9..588ae6c8ca 100644 --- a/components/search/SearchSuggestion.vue +++ b/components/search/SearchSuggestion.vue @@ -1,5 +1,8 @@ From f3bda2eec078775245abcc48db0e1e5b7e5cf528 Mon Sep 17 00:00:00 2001 From: daiagi Date: Tue, 29 Aug 2023 12:24:23 +0700 Subject: [PATCH 143/167] fix type --- components/shared/TransactionLoader.vue | 2 +- composables/useTransactionStatus.ts | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/components/shared/TransactionLoader.vue b/components/shared/TransactionLoader.vue index dc93a89cb0..ee648104c2 100644 --- a/components/shared/TransactionLoader.vue +++ b/components/shared/TransactionLoader.vue @@ -116,7 +116,7 @@ const activeStep = computed(() => { switch (props.status) { case TransactionStatus.Finalized: return 3 - case TransactionStatus.Unkonwn: + case TransactionStatus.Unknown: return 1 default: return 2 diff --git a/composables/useTransactionStatus.ts b/composables/useTransactionStatus.ts index 2c15dd3a9f..4235583685 100644 --- a/composables/useTransactionStatus.ts +++ b/composables/useTransactionStatus.ts @@ -6,12 +6,12 @@ export enum TransactionStatus { Sign = 'loader.sign', Block = 'loader.block', Finalized = 'loader.finalized', - Unkonwn = '', + Unknown = '', IPFS = 'loader.ipfs', } function useTransactionStatus() { - const status = ref(TransactionStatus.Unkonwn) + const status = ref(TransactionStatus.Unknown) const isLoading = ref(false) const resolveStatus = ( @@ -34,22 +34,22 @@ function useTransactionStatus() { if (extrinsicStatus.isFinalized) { status.value = omitFinalized - ? TransactionStatus.Unkonwn + ? TransactionStatus.Unknown : TransactionStatus.Finalized return } - status.value = TransactionStatus.Unkonwn + status.value = TransactionStatus.Unknown } const initTransactionLoader = (): void => { isLoading.value = true - status.value = TransactionStatus.Unkonwn + status.value = TransactionStatus.Unknown } const stopLoader = (): void => { isLoading.value = false - status.value = TransactionStatus.Unkonwn + status.value = TransactionStatus.Unknown } return { status, From 7ad52611efe879ff937319206f8ac96cf84fe315 Mon Sep 17 00:00:00 2001 From: daiagi Date: Tue, 29 Aug 2023 12:28:19 +0700 Subject: [PATCH 144/167] implement viki code review --- composables/useBlockTime.ts | 15 +++++---------- utils/config/types.ts | 4 ++-- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/composables/useBlockTime.ts b/composables/useBlockTime.ts index 7e99ef909d..c922ccf4a5 100644 --- a/composables/useBlockTime.ts +++ b/composables/useBlockTime.ts @@ -1,4 +1,4 @@ -import { Prefix } from '@kodadot1/static' +import { PartialConfig } from '@/utils/config/types' export default function () { const { urlPrefix } = usePrefix() @@ -6,20 +6,15 @@ export default function () { const paraChainBlockTime = 12 //seconds const relayChainBlockTime = 6 //seconds - const chainBlockTimes: { [K in Prefix]: number } = { + const chainBlockTimes: PartialConfig = { ksm: relayChainBlockTime, dot: relayChainBlockTime, rmrk: relayChainBlockTime, - ahk: paraChainBlockTime, - ahp: paraChainBlockTime, - bsx: paraChainBlockTime, - snek: paraChainBlockTime, - movr: paraChainBlockTime, - glmr: paraChainBlockTime, } - const blocktime = computed(() => chainBlockTimes[urlPrefix.value]) - + const blocktime = computed( + () => chainBlockTimes[urlPrefix.value] ?? paraChainBlockTime + ) return { blocktime, } diff --git a/utils/config/types.ts b/utils/config/types.ts index 754650398f..26f808370b 100644 --- a/utils/config/types.ts +++ b/utils/config/types.ts @@ -1,6 +1,6 @@ import type { Prefix as ChainPrefix } from '@kodadot1/static' export type Prefix = ChainPrefix -export type PartialConfig = { - [K in Prefix]?: boolean +export type PartialConfig = { + [K in Prefix]?: T } From 055852491c29ddf6529f3b07ec447e34c49800f0 Mon Sep 17 00:00:00 2001 From: Skinny Wu <17610879+justskinny5@users.noreply.github.com> Date: Tue, 29 Aug 2023 14:31:17 +0900 Subject: [PATCH 145/167] feature: show original content if the user clicks the preview button --- components/gallery/GalleryItem.vue | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/components/gallery/GalleryItem.vue b/components/gallery/GalleryItem.vue index 32fc8a71bd..6d4a64c538 100644 --- a/components/gallery/GalleryItem.vue +++ b/components/gallery/GalleryItem.vue @@ -176,7 +176,7 @@ import GalleryItemAction from './GalleryItemAction/GalleryItemAction.vue' import GalleryItemPreviewer from './GalleryItemPreviewer.vue' import { convertMarkdownToText } from '@/utils/markdown' import { exist } from '@/utils/exist' -import { sanitizeIpfsUrl } from '@/utils/ipfs' +import { sanitizeIpfsUrl, toOriginalContentUrl } from '@/utils/ipfs' import { generateNftImage } from '@/utils/seoImageGenerator' import { formatBalanceEmptyOnZero } from '@/utils/format/balance' import { MediaType } from '@/components/rmrk/types' @@ -234,9 +234,11 @@ const hasAnimatedResources = computed( nftResources.value[1].animation ) -const previewItemSrc = computed( - () => (hasResources.value && activeCarouselImage.value) || nftImage.value -) +const previewItemSrc = computed(() => { + const baseUrl = + (hasResources.value && activeCarouselImage.value) || nftImage.value + return baseUrl ? toOriginalContentUrl(baseUrl) : baseUrl +}) const onNFTBought = () => { activeTab.value = tabs.activity From c9b810b9ca7dc7756cb38d2afa5c290ab1a29cde Mon Sep 17 00:00:00 2001 From: Jarsen <31397967+Jarsen136@users.noreply.github.com> Date: Tue, 29 Aug 2023 13:44:48 +0800 Subject: [PATCH 146/167] feat: Fix denomination to single decimal and bigger numbers short with k & M --- components/balance/MultipleBalances.vue | 26 ++++++----------- .../GalleryItemActivityTable.vue | 9 ++++-- tests/utils/formatBalance.spec.ts | 28 ++++++++++++++++++- utils/format/balance.ts | 25 +++++++++++++++++ 4 files changed, 66 insertions(+), 22 deletions(-) diff --git a/components/balance/MultipleBalances.vue b/components/balance/MultipleBalances.vue index 570b5e1a82..08eaae6795 100644 --- a/components/balance/MultipleBalances.vue +++ b/components/balance/MultipleBalances.vue @@ -31,10 +31,10 @@
- {{ token.details?.balance }} + {{ formatNumber(token.details?.balance) }}
- ${{ delimiter(token.details?.usd || '0') }} + ${{ formatNumber(token.details?.usd || '0') }}
@@ -48,7 +48,9 @@

{{ $i18n.t('spotlight.total') }}: - ${{ delimiter(identityStore.getTotalUsd) }} + ${{ formatNumber(identityStore.getTotalUsd) }}

@@ -60,8 +62,7 @@ import { decodeAddress, encodeAddress } from '@polkadot/util-crypto' import { CHAINS, ENDPOINT_MAP } from '@kodadot1/static' import { NeoSkeleton } from '@kodadot1/brick' import { balanceOf } from '@kodadot1/sub-api' - -import format from '@/utils/format/balance' +import format, { formatNumber } from '@/utils/format/balance' import { useFiatStore } from '@/stores/fiat' import { calculateExactUsdFromToken } from '@/utils/calculation' import { getAssetIdByAccount } from '@/utils/api/bsx/query' @@ -115,16 +116,6 @@ const currentNetwork = computed(() => isTestnet.value ? 'test-network' : 'main-network' ) -function delimiter(amount: string | number) { - const formatAmount = typeof amount === 'number' ? amount.toString() : amount - const number = parseFloat(formatAmount.replace(/,/g, '')) - - return number.toLocaleString('en-US', { - minimumFractionDigits: 0, - maximumFractionDigits: 2, - }) -} - const fiatStore = useFiatStore() function calculateUsd(amount: string, token = 'KSM') { if (!amount) { @@ -174,8 +165,7 @@ async function getBalance(chainName: string, token = 'KSM', tokenId = 0) { selectedTokenId = await getAssetIdByAccount(api, prefixAddress) } - const balance = delimiter(currentBalance) - const usd = calculateUsd(balance, token) + const usd = calculateUsd(currentBalance, token) identityStore.setMultiBalances({ address: defaultAddress, @@ -183,7 +173,7 @@ async function getBalance(chainName: string, token = 'KSM', tokenId = 0) { [chainName]: { [token.toLowerCase()]: { address: prefixAddress, - balance, + balance: currentBalance, nativeBalance, usd, selected: selectedTokenId === String(tokenId), diff --git a/components/gallery/GalleryItemTabsPanel/GalleryItemActivityTable.vue b/components/gallery/GalleryItemTabsPanel/GalleryItemActivityTable.vue index bdb1d9c303..aa7a957dac 100644 --- a/components/gallery/GalleryItemTabsPanel/GalleryItemActivityTable.vue +++ b/components/gallery/GalleryItemTabsPanel/GalleryItemActivityTable.vue @@ -103,7 +103,10 @@ import { NeoTooltip, } from '@kodadot1/brick' import { formatToNow } from '@/utils/format/time' -import formatBalance, { withoutDigitSeparator } from '@/utils/format/balance' +import formatBalance, { + formatNumber, + withoutDigitSeparator, +} from '@/utils/format/balance' import { parseDate } from '@/utils/datetime' import { getApproximatePriceOf } from '@/utils/coingecko' @@ -169,10 +172,10 @@ watchEffect(() => { const formatPrice = (price) => { const tokenAmount = formatBalance(price, decimals.value, false) - const flatPrice = `${Math.round( + const flatPrice = `${formatNumber( Number(withoutDigitSeparator(tokenAmount)) * tokenPrice.value )}` - return [tokenAmount, flatPrice] + return [formatNumber(tokenAmount), flatPrice] }