mirror of
https://github.com/zhigang1992/xverse-web-extension.git
synced 2026-01-12 18:02:19 +08:00
[ENG-5185] change sip10 tokens to default on, if seen on swaps provider lists (#613)
This commit is contained in:
14
package-lock.json
generated
14
package-lock.json
generated
@@ -14,7 +14,7 @@
|
||||
"@playwright/test": "1.46.1",
|
||||
"@react-spring/web": "^9.6.1",
|
||||
"@sats-connect/core": "0.3.0",
|
||||
"@secretkeylabs/xverse-core": "24.1.0",
|
||||
"@secretkeylabs/xverse-core": "24.2.0",
|
||||
"@stacks/connect": "7.4.1",
|
||||
"@stacks/stacks-blockchain-api-types": "6.1.1",
|
||||
"@stacks/transactions": "6.16.1",
|
||||
@@ -1270,9 +1270,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@secretkeylabs/xverse-core": {
|
||||
"version": "24.1.0",
|
||||
"resolved": "https://npm.pkg.github.com/download/@secretkeylabs/xverse-core/24.1.0/0c57f062dd3c9444e284d101756658251fd8681d",
|
||||
"integrity": "sha512-cc01cykJV5YQhAc09VHwD8Iw7voQ+lqBzZWMJ+B5EXasi97O+dEP80JQs2RCpV2MfdsakZO+9JCweP331UqUbw==",
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://npm.pkg.github.com/download/@secretkeylabs/xverse-core/24.2.0/67ae914442d4276dcfd0d1e3b8bdf623133557bb",
|
||||
"integrity": "sha512-mBxIPL6jmGhRZLpUBL0ztTvBporCL/1CzTsz42/XZo7WFZIFfb1Arj2oQkeT+AngV+bf1CH60cV2vXnqH0mYkQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@bitcoinerlab/secp256k1": "^1.0.2",
|
||||
@@ -13635,9 +13635,9 @@
|
||||
}
|
||||
},
|
||||
"@secretkeylabs/xverse-core": {
|
||||
"version": "24.1.0",
|
||||
"resolved": "https://npm.pkg.github.com/download/@secretkeylabs/xverse-core/24.1.0/0c57f062dd3c9444e284d101756658251fd8681d",
|
||||
"integrity": "sha512-cc01cykJV5YQhAc09VHwD8Iw7voQ+lqBzZWMJ+B5EXasi97O+dEP80JQs2RCpV2MfdsakZO+9JCweP331UqUbw==",
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://npm.pkg.github.com/download/@secretkeylabs/xverse-core/24.2.0/67ae914442d4276dcfd0d1e3b8bdf623133557bb",
|
||||
"integrity": "sha512-mBxIPL6jmGhRZLpUBL0ztTvBporCL/1CzTsz42/XZo7WFZIFfb1Arj2oQkeT+AngV+bf1CH60cV2vXnqH0mYkQ==",
|
||||
"requires": {
|
||||
"@bitcoinerlab/secp256k1": "^1.0.2",
|
||||
"@noble/curves": "^1.2.0",
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"@playwright/test": "1.46.1",
|
||||
"@react-spring/web": "^9.6.1",
|
||||
"@sats-connect/core": "0.3.0",
|
||||
"@secretkeylabs/xverse-core": "24.1.0",
|
||||
"@secretkeylabs/xverse-core": "24.2.0",
|
||||
"@stacks/connect": "7.4.1",
|
||||
"@stacks/stacks-blockchain-api-types": "6.1.1",
|
||||
"@stacks/transactions": "6.16.1",
|
||||
|
||||
@@ -33,7 +33,7 @@ const TransactionValue = styled.p((props) => ({
|
||||
|
||||
export default function TransactionAmount(props: TransactionAmountProps): JSX.Element | null {
|
||||
const { transaction, currency, protocol, tokenSymbol } = props;
|
||||
const { visible: sip10CoinsList } = useVisibleSip10FungibleTokens();
|
||||
const { data: sip10CoinsList } = useVisibleSip10FungibleTokens();
|
||||
if (currency === 'STX' || (currency === 'FT' && protocol === 'stacks')) {
|
||||
const stxTransaction = transaction as StxTransactionData;
|
||||
if (stxTransaction.txType === 'token_transfer') {
|
||||
|
||||
@@ -29,7 +29,7 @@ const TransactionTitleText = styled.p((props) => ({
|
||||
export default function TransactionTitle(props: TransactionTitleProps) {
|
||||
const { transaction } = props;
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'COIN_DASHBOARD_SCREEN' });
|
||||
const { visible: sip10CoinsList } = useVisibleSip10FungibleTokens();
|
||||
const { data: sip10CoinsList } = useVisibleSip10FungibleTokens();
|
||||
|
||||
const getTokenTransferTitle = (
|
||||
tx: StxTransactionData | BtcTransactionData | Brc20HistoryTransactionData,
|
||||
|
||||
@@ -60,7 +60,7 @@ interface TxTransfersProps {
|
||||
export default function TxTransfers(props: TxTransfersProps) {
|
||||
const { transaction, coin, txFilter } = props;
|
||||
const selectedAccount = useSelectedAccount();
|
||||
const { visible: sip10CoinsList } = useVisibleSip10FungibleTokens();
|
||||
const { data: sip10CoinsList } = useVisibleSip10FungibleTokens();
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'COIN_DASHBOARD_SCREEN' });
|
||||
|
||||
function formatAddress(addr: string): string {
|
||||
|
||||
@@ -2,13 +2,14 @@ import useSelectedAccount from '@hooks/useSelectedAccount';
|
||||
import useWalletSelector from '@hooks/useWalletSelector';
|
||||
import {
|
||||
getBrc20Tokens,
|
||||
getFungibleTokenStates,
|
||||
getOrdinalsFtBalance,
|
||||
type Brc20Token,
|
||||
type FungibleToken,
|
||||
type FungibleTokenWithStates,
|
||||
type SettingsNetwork,
|
||||
} from '@secretkeylabs/xverse-core';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
const brc20TokenToFungibleToken = (coin: Brc20Token): FungibleToken => ({
|
||||
name: coin.name,
|
||||
@@ -17,7 +18,6 @@ const brc20TokenToFungibleToken = (coin: Brc20Token): FungibleToken => ({
|
||||
total_sent: '',
|
||||
total_received: '',
|
||||
assetName: coin.name ?? coin.ticker,
|
||||
visible: true,
|
||||
ticker: coin.ticker,
|
||||
protocol: 'brc-20',
|
||||
supported: coin.supported,
|
||||
@@ -54,40 +54,38 @@ export const fetchBrc20FungibleTokens =
|
||||
);
|
||||
};
|
||||
|
||||
export const useGetBrc20FungibleTokens = () => {
|
||||
export const useGetBrc20FungibleTokens = (select?: (data: FungibleTokenWithStates[]) => any) => {
|
||||
const { ordinalsAddress } = useSelectedAccount();
|
||||
const { fiatCurrency, network, spamTokens, showSpamTokens } = useWalletSelector();
|
||||
const queryFn = fetchBrc20FungibleTokens(ordinalsAddress, fiatCurrency, network);
|
||||
const { brc20ManageTokens, fiatCurrency, network, spamTokens, showSpamTokens } =
|
||||
useWalletSelector();
|
||||
|
||||
const query = useQuery({
|
||||
const queryFn = fetchBrc20FungibleTokens(ordinalsAddress, fiatCurrency, network);
|
||||
const selectWithDerivedState = (data: FungibleToken[]) => {
|
||||
const withDerivedState = data.map(
|
||||
(ft: FungibleToken) =>
|
||||
({
|
||||
...ft,
|
||||
...getFungibleTokenStates({
|
||||
fungibleToken: ft,
|
||||
manageTokens: brc20ManageTokens,
|
||||
spamTokens,
|
||||
showSpamTokens,
|
||||
}),
|
||||
} as FungibleTokenWithStates),
|
||||
);
|
||||
return select ? select(withDerivedState) : withDerivedState;
|
||||
};
|
||||
|
||||
return useQuery({
|
||||
queryKey: ['brc20-fungible-tokens', ordinalsAddress, network.type, fiatCurrency],
|
||||
queryFn,
|
||||
enabled: Boolean(network && ordinalsAddress),
|
||||
select: selectWithDerivedState,
|
||||
});
|
||||
|
||||
return {
|
||||
...query,
|
||||
unfilteredData: query.data,
|
||||
data: query.data?.filter((ft) => {
|
||||
let passedSpamCheck = true;
|
||||
if (spamTokens?.length) {
|
||||
passedSpamCheck = showSpamTokens || !spamTokens.includes(ft.principal);
|
||||
}
|
||||
return passedSpamCheck;
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
export const useVisibleBrc20FungibleTokens = (): ReturnType<typeof useGetBrc20FungibleTokens> & {
|
||||
visible: FungibleToken[];
|
||||
} => {
|
||||
const { brc20ManageTokens } = useWalletSelector();
|
||||
const brc20Query = useGetBrc20FungibleTokens();
|
||||
return {
|
||||
...brc20Query,
|
||||
visible: (brc20Query.data ?? []).filter((ft) => {
|
||||
const userSetting = brc20ManageTokens[ft.principal];
|
||||
return userSetting === true || (userSetting === undefined && new BigNumber(ft.balance).gt(0));
|
||||
}),
|
||||
};
|
||||
// convenience hook to get only enabled brc20 fungible tokens
|
||||
export const useVisibleBrc20FungibleTokens = () => {
|
||||
const selectEnabled = (data: FungibleTokenWithStates[]) => data.filter((ft) => ft.isEnabled);
|
||||
return useGetBrc20FungibleTokens(selectEnabled);
|
||||
};
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import useRunesApi from '@hooks/apiClients/useRunesApi';
|
||||
import useHasFeature from '@hooks/useHasFeature';
|
||||
import useSelectedAccount from '@hooks/useSelectedAccount';
|
||||
import useWalletSelector from '@hooks/useWalletSelector';
|
||||
import { FeatureId, type FungibleToken } from '@secretkeylabs/xverse-core';
|
||||
import {
|
||||
getFungibleTokenStates,
|
||||
type FungibleToken,
|
||||
type FungibleTokenWithStates,
|
||||
} from '@secretkeylabs/xverse-core';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
export const fetchRuneBalances =
|
||||
(
|
||||
@@ -31,47 +33,44 @@ export const fetchRuneBalances =
|
||||
}
|
||||
};
|
||||
|
||||
export const useRuneFungibleTokensQuery = (backgroundRefetch = true) => {
|
||||
export const useRuneFungibleTokensQuery = (
|
||||
select?: (data: FungibleTokenWithStates[]) => any,
|
||||
backgroundRefetch = true,
|
||||
) => {
|
||||
const { ordinalsAddress } = useSelectedAccount();
|
||||
const { network, fiatCurrency, spamTokens, showSpamTokens } = useWalletSelector();
|
||||
const showRunes = useHasFeature(FeatureId.RUNES_SUPPORT);
|
||||
const { runesManageTokens, network, fiatCurrency, spamTokens, showSpamTokens } =
|
||||
useWalletSelector();
|
||||
const runesApi = useRunesApi();
|
||||
|
||||
const queryFn = fetchRuneBalances(runesApi, ordinalsAddress, fiatCurrency);
|
||||
const query = useQuery({
|
||||
queryKey: ['get-rune-fungible-tokens', network.type, ordinalsAddress, fiatCurrency],
|
||||
enabled: Boolean(network && ordinalsAddress && showRunes),
|
||||
refetchOnWindowFocus: backgroundRefetch,
|
||||
refetchOnReconnect: backgroundRefetch,
|
||||
queryFn,
|
||||
});
|
||||
return {
|
||||
...query,
|
||||
unfilteredData: query.data,
|
||||
data: query.data?.filter((ft) => {
|
||||
let passedSpamCheck = true;
|
||||
if (spamTokens?.length) {
|
||||
passedSpamCheck = showSpamTokens || !spamTokens.includes(ft.principal);
|
||||
}
|
||||
return passedSpamCheck;
|
||||
}),
|
||||
const selectWithDerivedState = (data: FungibleToken[]) => {
|
||||
const withDerivedState = data.map(
|
||||
(ft: FungibleToken) =>
|
||||
({
|
||||
...ft,
|
||||
...getFungibleTokenStates({
|
||||
fungibleToken: ft,
|
||||
manageTokens: runesManageTokens,
|
||||
spamTokens,
|
||||
showSpamTokens,
|
||||
}),
|
||||
} as FungibleTokenWithStates),
|
||||
);
|
||||
return select ? select(withDerivedState) : withDerivedState;
|
||||
};
|
||||
|
||||
return useQuery({
|
||||
queryKey: ['get-rune-fungible-tokens', network.type, ordinalsAddress, fiatCurrency],
|
||||
queryFn,
|
||||
enabled: Boolean(network && ordinalsAddress),
|
||||
select: selectWithDerivedState,
|
||||
refetchOnWindowFocus: !!backgroundRefetch,
|
||||
refetchOnReconnect: !!backgroundRefetch,
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* This hook is used to get the list of runes which the user has not hidden
|
||||
*/
|
||||
export const useVisibleRuneFungibleTokens = (
|
||||
backgroundRefetch = true,
|
||||
): ReturnType<typeof useRuneFungibleTokensQuery> & {
|
||||
visible: FungibleToken[];
|
||||
} => {
|
||||
const { runesManageTokens } = useWalletSelector();
|
||||
const runesQuery = useRuneFungibleTokensQuery(backgroundRefetch);
|
||||
return {
|
||||
...runesQuery,
|
||||
visible: (runesQuery.data ?? []).filter((ft) => {
|
||||
const userSetting = runesManageTokens[ft.principal];
|
||||
return userSetting === true || (userSetting === undefined && new BigNumber(ft.balance).gt(0));
|
||||
}),
|
||||
};
|
||||
// convenience hook to get only enabled rune fungible tokens
|
||||
export const useVisibleRuneFungibleTokens = (backgroundRefetch = true) => {
|
||||
const selectEnabled = (data: FungibleTokenWithStates[]) => data.filter((ft) => ft.isEnabled);
|
||||
return useRuneFungibleTokensQuery(selectEnabled, backgroundRefetch);
|
||||
};
|
||||
|
||||
@@ -3,14 +3,14 @@ import useSelectedAccount from '@hooks/useSelectedAccount';
|
||||
import useWalletSelector from '@hooks/useWalletSelector';
|
||||
import {
|
||||
StacksNetwork,
|
||||
// getCoinMetaData,
|
||||
getCoinsInfo,
|
||||
getFtData,
|
||||
getFungibleTokenStates,
|
||||
getXverseApiClient,
|
||||
type FungibleToken,
|
||||
type FungibleTokenWithStates,
|
||||
type SettingsNetwork,
|
||||
} from '@secretkeylabs/xverse-core';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
export const fetchSip10FungibleTokens =
|
||||
(
|
||||
@@ -18,47 +18,32 @@ export const fetchSip10FungibleTokens =
|
||||
fiatCurrency: string,
|
||||
network: SettingsNetwork,
|
||||
currentNetworkInstance: StacksNetwork,
|
||||
) =>
|
||||
): (() => Promise<FungibleToken[]>) =>
|
||||
async () => {
|
||||
// get sip10 metadata and balances for the stxAddress
|
||||
const sip10Balances = await getFtData(stxAddress, currentNetworkInstance);
|
||||
const sip10ContractInfos =
|
||||
(await getXverseApiClient(network.type).getSip10Tokens(
|
||||
sip10Balances.map((ft) => ft.principal),
|
||||
fiatCurrency,
|
||||
)) || [];
|
||||
|
||||
// getting contract ids of all fts
|
||||
const contractids: string[] = sip10Balances.map((ft) => ft.principal);
|
||||
const sip10ContractInfos = (await getCoinsInfo(network.type, contractids, fiatCurrency)) || [];
|
||||
|
||||
// combine
|
||||
return sip10Balances
|
||||
.map((ft) => {
|
||||
const found = (sip10ContractInfos || []).find((coin) => coin.contract === ft.principal);
|
||||
if (!found) {
|
||||
return ft;
|
||||
}
|
||||
return {
|
||||
...ft,
|
||||
...found,
|
||||
visible: true,
|
||||
name: found.name || ft.principal.split('.')[1],
|
||||
};
|
||||
})
|
||||
.concat(
|
||||
sip10ContractInfos
|
||||
.filter((coin) => !sip10Balances.some((ft) => ft.principal === coin.contract))
|
||||
.map((coin) => ({
|
||||
...coin,
|
||||
principal: coin.contract,
|
||||
assetName: coin.name || coin.contract.split('.')[1],
|
||||
protocol: 'stacks',
|
||||
balance: '0',
|
||||
total_sent: '',
|
||||
total_received: '',
|
||||
})),
|
||||
);
|
||||
return sip10Balances.map((ft) => {
|
||||
const found = sip10ContractInfos.find((coin) => coin.contract === ft.principal);
|
||||
if (!found) {
|
||||
return ft;
|
||||
}
|
||||
return {
|
||||
...ft,
|
||||
...found,
|
||||
name: found.name || ft.principal.split('.')[1],
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetSip10FungibleTokens = () => {
|
||||
export const useGetSip10FungibleTokens = (select?: (data: FungibleTokenWithStates[]) => any) => {
|
||||
const { stxAddress } = useSelectedAccount();
|
||||
const { fiatCurrency, network, spamTokens, showSpamTokens } = useWalletSelector();
|
||||
const { sip10ManageTokens, fiatCurrency, network, spamTokens, showSpamTokens } =
|
||||
useWalletSelector();
|
||||
const currentNetworkInstance = useNetworkSelector();
|
||||
|
||||
const queryFn = fetchSip10FungibleTokens(
|
||||
@@ -67,46 +52,32 @@ export const useGetSip10FungibleTokens = () => {
|
||||
network,
|
||||
currentNetworkInstance,
|
||||
);
|
||||
const selectWithDerivedState = (data: FungibleToken[]) => {
|
||||
const withDerivedState = data.map(
|
||||
(ft: FungibleToken) =>
|
||||
({
|
||||
...ft,
|
||||
...getFungibleTokenStates({
|
||||
fungibleToken: ft,
|
||||
manageTokens: sip10ManageTokens,
|
||||
spamTokens,
|
||||
showSpamTokens,
|
||||
}),
|
||||
} as FungibleTokenWithStates),
|
||||
);
|
||||
return select ? select(withDerivedState) : withDerivedState;
|
||||
};
|
||||
|
||||
const query = useQuery({
|
||||
return useQuery({
|
||||
queryKey: ['sip10-fungible-tokens', network.type, stxAddress, fiatCurrency],
|
||||
queryFn,
|
||||
enabled: Boolean(network && stxAddress),
|
||||
select: selectWithDerivedState,
|
||||
});
|
||||
|
||||
return {
|
||||
...query,
|
||||
unfilteredData: query.data,
|
||||
data: query.data?.filter((ft) => {
|
||||
let passedSpamCheck = true;
|
||||
if (spamTokens?.length) {
|
||||
passedSpamCheck = showSpamTokens || !spamTokens.includes(ft.principal);
|
||||
}
|
||||
return passedSpamCheck;
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
export const useVisibleSip10FungibleTokens = (): ReturnType<typeof useGetSip10FungibleTokens> & {
|
||||
visible: FungibleToken[];
|
||||
} => {
|
||||
const { sip10ManageTokens } = useWalletSelector();
|
||||
const sip10Query = useGetSip10FungibleTokens();
|
||||
// set visible false for unsupported tokens
|
||||
const sip10FTList = sip10Query.data || [];
|
||||
sip10FTList.forEach((ft) => {
|
||||
ft.visible = !!ft.supported;
|
||||
});
|
||||
|
||||
return {
|
||||
...sip10Query,
|
||||
visible: sip10FTList.filter((ft) => {
|
||||
const userSetting = sip10ManageTokens[ft.principal];
|
||||
|
||||
return (
|
||||
userSetting === true ||
|
||||
(userSetting === undefined && ft.supported && new BigNumber(ft.balance).gt(0))
|
||||
);
|
||||
}),
|
||||
};
|
||||
// convenience hook to get only enabled sip10 fungible tokens
|
||||
export const useVisibleSip10FungibleTokens = () => {
|
||||
const selectEnabled = (data: FungibleTokenWithStates[]) => data.filter((ft) => ft.isEnabled);
|
||||
return useGetSip10FungibleTokens(selectEnabled);
|
||||
};
|
||||
|
||||
@@ -15,11 +15,10 @@ const useGetSip10TokenInfo = ({
|
||||
|
||||
const fetchTokensInfo = async () => {
|
||||
if (principal) {
|
||||
const coinsInfo = await xverseApiClient.getCoinsInfo(
|
||||
const coinsInfo = await xverseApiClient.getSip10Tokens(
|
||||
[principal],
|
||||
fiatCurrency ?? defaultFiatCurrency,
|
||||
);
|
||||
|
||||
const tokenInfo = coinsInfo.find((coin) => coin.contract === principal);
|
||||
return tokenInfo;
|
||||
}
|
||||
|
||||
@@ -5,9 +5,11 @@ import useNetworkSelector from '@hooks/useNetwork';
|
||||
import useWalletSelector from '@hooks/useWalletSelector';
|
||||
import {
|
||||
API_TIMEOUT_MILLI,
|
||||
getFungibleTokenStates,
|
||||
type Account,
|
||||
type BtcAddressData,
|
||||
type FungibleToken,
|
||||
type FungibleTokenWithStates,
|
||||
type TokensResponse,
|
||||
} from '@secretkeylabs/xverse-core';
|
||||
import { setAccountBalanceAction } from '@stores/wallet/actions/actionCreators';
|
||||
@@ -30,6 +32,8 @@ const useAccountBalance = () => {
|
||||
brc20ManageTokens,
|
||||
sip10ManageTokens,
|
||||
runesManageTokens,
|
||||
spamTokens,
|
||||
showSpamTokens,
|
||||
} = useWalletSelector();
|
||||
const { btcFiatRate, stxBtcRate } = useSupportedCoinRates();
|
||||
const runesApi = useRunesApi();
|
||||
@@ -38,6 +42,17 @@ const useAccountBalance = () => {
|
||||
const [isProcessingQueue, setIsProcessingQueue] = useState(false);
|
||||
const [queueLength, setQueueLength] = useState(0);
|
||||
|
||||
const withDerivedState = (ft: FungibleToken) =>
|
||||
({
|
||||
...ft,
|
||||
...getFungibleTokenStates({
|
||||
fungibleToken: ft,
|
||||
manageTokens: sip10ManageTokens,
|
||||
spamTokens,
|
||||
showSpamTokens,
|
||||
}),
|
||||
} as FungibleTokenWithStates);
|
||||
|
||||
const fetchBalances = async (account: Account | null) => {
|
||||
if (!account) {
|
||||
return;
|
||||
@@ -45,9 +60,9 @@ const useAccountBalance = () => {
|
||||
|
||||
let btcBalance = '0';
|
||||
let stxBalance = '0';
|
||||
let finalSipCoinsList: FungibleToken[] = [];
|
||||
let finalBrcCoinsList: FungibleToken[] = [];
|
||||
let finalRunesCoinsList: FungibleToken[] = [];
|
||||
let finalSipCoinsList: FungibleTokenWithStates[] = [];
|
||||
let finalBrcCoinsList: FungibleTokenWithStates[] = [];
|
||||
let finalRunesCoinsList: FungibleTokenWithStates[] = [];
|
||||
|
||||
try {
|
||||
if (account.btcAddress) {
|
||||
@@ -61,15 +76,13 @@ const useAccountBalance = () => {
|
||||
fiatCurrency,
|
||||
network,
|
||||
);
|
||||
finalBrcCoinsList = (await fetchBrc20Balances()).filter((ft) => {
|
||||
const setting = brc20ManageTokens[ft.principal];
|
||||
return setting === true || (setting === undefined && new BigNumber(ft.balance).gt(0));
|
||||
});
|
||||
finalBrcCoinsList = (await fetchBrc20Balances())
|
||||
.map(withDerivedState)
|
||||
.filter((ft) => ft.isEnabled);
|
||||
const runeBalances = fetchRuneBalances(runesApi, account.ordinalsAddress, fiatCurrency);
|
||||
finalRunesCoinsList = (await runeBalances()).filter((ft) => {
|
||||
const setting = runesManageTokens[ft.principal];
|
||||
return setting === true || (setting === undefined && new BigNumber(ft.balance).gt(0));
|
||||
});
|
||||
finalRunesCoinsList = (await runeBalances())
|
||||
.map(withDerivedState)
|
||||
.filter((ft) => ft.isEnabled);
|
||||
}
|
||||
if (account.stxAddress) {
|
||||
const apiUrl = `${stacksNetwork.coreApiUrl}/extended/v1/address/${account.stxAddress}/balances`;
|
||||
@@ -88,10 +101,9 @@ const useAccountBalance = () => {
|
||||
network,
|
||||
stacksNetwork,
|
||||
);
|
||||
finalSipCoinsList = (await fetchSip10Balances()).filter((ft) => {
|
||||
const setting = sip10ManageTokens[ft.principal];
|
||||
return setting === true || (setting === undefined && new BigNumber(ft.balance).gt(0));
|
||||
});
|
||||
finalSipCoinsList = (await fetchSip10Balances())
|
||||
.map(withDerivedState)
|
||||
.filter((ft) => ft.isEnabled);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch balances:', error);
|
||||
|
||||
@@ -166,9 +166,9 @@ export default function CoinDashboard() {
|
||||
const { addToSpamTokens } = useSpamTokens();
|
||||
const dispatch = useDispatch();
|
||||
const { currency } = useParams();
|
||||
const { visible: runesCoinsList } = useVisibleRuneFungibleTokens();
|
||||
const { visible: sip10CoinsList } = useVisibleSip10FungibleTokens();
|
||||
const { visible: brc20CoinsList } = useVisibleBrc20FungibleTokens();
|
||||
const { data: runesCoinsList } = useVisibleRuneFungibleTokens();
|
||||
const { data: sip10CoinsList } = useVisibleSip10FungibleTokens();
|
||||
const { data: brc20CoinsList } = useVisibleBrc20FungibleTokens();
|
||||
|
||||
let selectedFt: FungibleToken | undefined;
|
||||
|
||||
|
||||
@@ -80,9 +80,9 @@ function BalanceCard(props: BalanceCardProps) {
|
||||
const { setAccountBalance } = useAccountBalance();
|
||||
const { isLoading, isRefetching } = props;
|
||||
const oldTotalBalance = accountBalances[selectedAccount.btcAddress];
|
||||
const { visible: sip10CoinsList } = useVisibleSip10FungibleTokens();
|
||||
const { visible: brc20CoinsList } = useVisibleBrc20FungibleTokens();
|
||||
const { visible: runesCoinList } = useVisibleRuneFungibleTokens();
|
||||
const { data: sip10CoinsList } = useVisibleSip10FungibleTokens();
|
||||
const { data: brc20CoinsList } = useVisibleBrc20FungibleTokens();
|
||||
const { data: runesCoinList } = useVisibleRuneFungibleTokens();
|
||||
|
||||
const balance = calculateTotalBalance({
|
||||
stxBalance: stxData?.balance.toString() ?? '0',
|
||||
|
||||
@@ -10,9 +10,18 @@ import ReceiveCardComponent from '@components/receiveCardComponent';
|
||||
import ShowBtcReceiveAlert from '@components/showBtcReceiveAlert';
|
||||
import ShowOrdinalReceiveAlert from '@components/showOrdinalReceiveAlert';
|
||||
import BottomBar from '@components/tabBar';
|
||||
import { useVisibleBrc20FungibleTokens } from '@hooks/queries/ordinals/useGetBrc20FungibleTokens';
|
||||
import { useVisibleRuneFungibleTokens } from '@hooks/queries/runes/useRuneFungibleTokensQuery';
|
||||
import { useVisibleSip10FungibleTokens } from '@hooks/queries/stx/useGetSip10FungibleTokens';
|
||||
import {
|
||||
useGetBrc20FungibleTokens,
|
||||
useVisibleBrc20FungibleTokens,
|
||||
} from '@hooks/queries/ordinals/useGetBrc20FungibleTokens';
|
||||
import {
|
||||
useRuneFungibleTokensQuery,
|
||||
useVisibleRuneFungibleTokens,
|
||||
} from '@hooks/queries/runes/useRuneFungibleTokensQuery';
|
||||
import {
|
||||
useGetSip10FungibleTokens,
|
||||
useVisibleSip10FungibleTokens,
|
||||
} from '@hooks/queries/stx/useGetSip10FungibleTokens';
|
||||
import useAppConfig from '@hooks/queries/useAppConfig';
|
||||
import useBtcWalletData from '@hooks/queries/useBtcWalletData';
|
||||
import useFeeMultipliers from '@hooks/queries/useFeeMultipliers';
|
||||
@@ -28,7 +37,12 @@ import useWalletSelector from '@hooks/useWalletSelector';
|
||||
import { ArrowDown, ArrowUp, Plus } from '@phosphor-icons/react';
|
||||
import { animated, useTransition } from '@react-spring/web';
|
||||
import CoinSelectModal from '@screens/home/coinSelectModal';
|
||||
import { AnalyticsEvents, FeatureId, type FungibleToken } from '@secretkeylabs/xverse-core';
|
||||
import {
|
||||
AnalyticsEvents,
|
||||
FeatureId,
|
||||
type FungibleToken,
|
||||
type FungibleTokenWithStates,
|
||||
} from '@secretkeylabs/xverse-core';
|
||||
import {
|
||||
changeShowDataCollectionAlertAction,
|
||||
setBrc20ManageTokensAction,
|
||||
@@ -43,7 +57,6 @@ import type { CurrencyTypes } from '@utils/constants';
|
||||
import { isInOptions, isLedgerAccount } from '@utils/helper';
|
||||
import { optInMixPanel, optOutMixPanel, trackMixPanel } from '@utils/mixpanel';
|
||||
import { sortFtByFiatBalance } from '@utils/tokens';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { useEffect, useState } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -113,21 +126,22 @@ function Home() {
|
||||
const { btcFiatRate, stxBtcRate } = useSupportedCoinRates();
|
||||
const { data: notificationBannersArr, isFetching: isFetchingNotificationBannersArr } =
|
||||
useNotificationBanners();
|
||||
|
||||
const { data: fullSip10CoinsList } = useGetSip10FungibleTokens();
|
||||
const { data: fullBrc20CoinsList } = useGetBrc20FungibleTokens();
|
||||
const { data: fullRunesCoinsList } = useRuneFungibleTokensQuery();
|
||||
const {
|
||||
unfilteredData: fullSip10CoinsList,
|
||||
visible: sip10CoinsList,
|
||||
data: sip10CoinsList,
|
||||
isInitialLoading: loadingStxCoinData,
|
||||
isRefetching: refetchingStxCoinData,
|
||||
} = useVisibleSip10FungibleTokens();
|
||||
const {
|
||||
unfilteredData: fullBrc20CoinsList,
|
||||
visible: brc20CoinsList,
|
||||
data: brc20CoinsList,
|
||||
isInitialLoading: loadingBrcCoinData,
|
||||
isRefetching: refetchingBrcCoinData,
|
||||
} = useVisibleBrc20FungibleTokens();
|
||||
const {
|
||||
unfilteredData: fullRunesCoinsList,
|
||||
visible: runesCoinsList,
|
||||
data: runesCoinsList,
|
||||
isInitialLoading: loadingRunesData,
|
||||
isRefetching: refetchingRunesData,
|
||||
} = useVisibleRuneFungibleTokens();
|
||||
@@ -163,11 +177,23 @@ function Home() {
|
||||
isEnabled: true,
|
||||
};
|
||||
|
||||
if (fullRunesCoinsList?.find((ft) => ft.principal === spamToken.principal)) {
|
||||
if (
|
||||
fullRunesCoinsList?.find(
|
||||
(ft: FungibleTokenWithStates) => ft.principal === spamToken.principal,
|
||||
)
|
||||
) {
|
||||
dispatch(setRunesManageTokensAction(payload));
|
||||
} else if (fullSip10CoinsList?.find((ft) => ft.principal === spamToken.principal)) {
|
||||
} else if (
|
||||
fullSip10CoinsList?.find(
|
||||
(ft: FungibleTokenWithStates) => ft.principal === spamToken.principal,
|
||||
)
|
||||
) {
|
||||
dispatch(setSip10ManageTokensAction(payload));
|
||||
} else if (fullBrc20CoinsList?.find((ft) => ft.principal === spamToken.principal)) {
|
||||
} else if (
|
||||
fullBrc20CoinsList?.find(
|
||||
(ft: FungibleTokenWithStates) => ft.principal === spamToken.principal,
|
||||
)
|
||||
) {
|
||||
dispatch(setBrc20ManageTokensAction(payload));
|
||||
}
|
||||
|
||||
@@ -181,10 +207,12 @@ function Home() {
|
||||
}
|
||||
}, [spamToken]);
|
||||
|
||||
const combinedFtList = sip10CoinsList
|
||||
.concat(brc20CoinsList)
|
||||
.concat(runesCoinsList)
|
||||
.sort((a, b) => sortFtByFiatBalance(a, b, stxBtcRate, btcFiatRate));
|
||||
const combinedFtList = (sip10CoinsList ?? [])
|
||||
.concat(brc20CoinsList ?? [])
|
||||
.concat(runesCoinsList ?? [])
|
||||
.sort((a: FungibleTokenWithStates, b: FungibleTokenWithStates) =>
|
||||
sortFtByFiatBalance(a, b, stxBtcRate, btcFiatRate),
|
||||
);
|
||||
|
||||
const filteredNotificationBannersArr = notificationBannersArr
|
||||
? notificationBannersArr.filter((banner) => !notificationBanners[banner.id])
|
||||
@@ -508,7 +536,7 @@ function Home() {
|
||||
onPress={handleTokenPressed}
|
||||
/>
|
||||
)}
|
||||
{combinedFtList.map((coin) => {
|
||||
{combinedFtList.map((coin: FungibleTokenWithStates) => {
|
||||
const isLoading = loadingStxCoinData || loadingBrcCoinData || loadingRunesData;
|
||||
return (
|
||||
<StyledTokenTile
|
||||
@@ -539,7 +567,7 @@ function Home() {
|
||||
onClose={onSendModalClose}
|
||||
onSelectCoin={onSendFtSelect}
|
||||
visible={openSendModal}
|
||||
coins={combinedFtList.filter((ft) => new BigNumber(ft.balance).gt(0))}
|
||||
coins={combinedFtList}
|
||||
title={t('SEND')}
|
||||
loadingWalletData={loadingStxWalletData || loadingBtcWalletData}
|
||||
/>
|
||||
|
||||
@@ -71,7 +71,7 @@ export default function ListRuneScreen() {
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'LIST_RUNE_SCREEN' });
|
||||
const navigate = useNavigate();
|
||||
const { runeId } = useParams();
|
||||
const { visible: runesCoinsList } = useVisibleRuneFungibleTokens(false);
|
||||
const { data: runesCoinsList } = useVisibleRuneFungibleTokens(false);
|
||||
const selectedRune = runesCoinsList.find((ft) => ft.principal === runeId);
|
||||
const { fiatCurrency } = useWalletSelector();
|
||||
const { btcFiatRate } = useSupportedCoinRates();
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
import stacksIcon from '@assets/img/dashboard/stx_icon.svg';
|
||||
import runesComingSoon from '@assets/img/manageTokens/runes_coming_soon.svg';
|
||||
import OptionsDialog from '@components/optionsDialog/optionsDialog';
|
||||
import BottomBar from '@components/tabBar';
|
||||
import TopRow from '@components/topRow';
|
||||
import { useGetBrc20FungibleTokens } from '@hooks/queries/ordinals/useGetBrc20FungibleTokens';
|
||||
import { useRuneFungibleTokensQuery } from '@hooks/queries/runes/useRuneFungibleTokensQuery';
|
||||
import { useGetSip10FungibleTokens } from '@hooks/queries/stx/useGetSip10FungibleTokens';
|
||||
import useHasFeature from '@hooks/useHasFeature';
|
||||
import useSelectedAccount from '@hooks/useSelectedAccount';
|
||||
import useWalletReducer from '@hooks/useWalletReducer';
|
||||
import useWalletSelector from '@hooks/useWalletSelector';
|
||||
import { Eye, EyeSlash } from '@phosphor-icons/react';
|
||||
import CoinItem from '@screens/manageTokens/coinItem';
|
||||
import {
|
||||
FeatureId,
|
||||
type FungibleToken,
|
||||
type FungibleTokenProtocol,
|
||||
type FungibleTokenWithStates,
|
||||
} from '@secretkeylabs/xverse-core';
|
||||
import {
|
||||
setBrc20ManageTokensAction,
|
||||
@@ -25,7 +22,6 @@ import {
|
||||
} from '@stores/wallet/actions/actionCreators';
|
||||
import { StyledP } from '@ui-library/common.styled';
|
||||
import { SPAM_OPTIONS_WIDTH } from '@utils/constants';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch } from 'react-redux';
|
||||
@@ -97,14 +93,6 @@ const Description = styled.h1((props) => ({
|
||||
marginBottom: props.theme.spacing(16),
|
||||
}));
|
||||
|
||||
const RunesContainer = styled.div((props) => ({
|
||||
marginTop: props.theme.spacing(24),
|
||||
marginRight: props.theme.spacing(5),
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
}));
|
||||
|
||||
const ErrorsText = styled.p((props) => ({
|
||||
...props.theme.typography.body_bold_m,
|
||||
color: props.theme.colors.white_200,
|
||||
@@ -113,10 +101,6 @@ const ErrorsText = styled.p((props) => ({
|
||||
textAlign: 'center',
|
||||
}));
|
||||
|
||||
const RunesComingSoon = styled.img({
|
||||
width: '70%',
|
||||
});
|
||||
|
||||
const ButtonRow = styled.button`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -161,16 +145,20 @@ function ManageTokens() {
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'TOKEN_SCREEN' });
|
||||
|
||||
const selectedAccount = useSelectedAccount();
|
||||
const { sip10ManageTokens, brc20ManageTokens, runesManageTokens, showSpamTokens } =
|
||||
useWalletSelector();
|
||||
const { data: runesList, isError: runeError } = useRuneFungibleTokensQuery();
|
||||
const { data: sip10List, isError: sip10Error } = useGetSip10FungibleTokens();
|
||||
const { data: brc20List, isError: brc20Error } = useGetBrc20FungibleTokens();
|
||||
const { showSpamTokens } = useWalletSelector();
|
||||
const { data: runesList, isError: runeError } = useRuneFungibleTokensQuery((data) =>
|
||||
data.filter((ft) => ft.showToggle),
|
||||
);
|
||||
const { data: sip10List, isError: sip10Error } = useGetSip10FungibleTokens((data) =>
|
||||
data.filter((ft) => ft.showToggle),
|
||||
);
|
||||
const { data: brc20List, isError: brc20Error } = useGetBrc20FungibleTokens((data) =>
|
||||
data.filter((ft) => ft.showToggle),
|
||||
);
|
||||
|
||||
const [selectedProtocol, setSelectedProtocol] = useState<FungibleTokenProtocol>(
|
||||
selectedAccount?.stxAddress ? 'stacks' : 'brc-20',
|
||||
);
|
||||
const showRunes = useHasFeature(FeatureId.RUNES_SUPPORT);
|
||||
const [showOptionsDialog, setShowOptionsDialog] = useState(false);
|
||||
|
||||
const [optionsDialogIndents, setOptionsDialogIndents] = useState<
|
||||
@@ -193,9 +181,9 @@ function ManageTokens() {
|
||||
};
|
||||
|
||||
const toggled = (isEnabled: boolean, _coinName: string, coinKey: string) => {
|
||||
const runeFt = runesList?.find((ft) => ft.principal === coinKey);
|
||||
const sip10Ft = sip10List?.find((ft) => ft.principal === coinKey);
|
||||
const brc20Ft = brc20List?.find((ft) => ft.principal === coinKey);
|
||||
const runeFt = runesList?.find((ft: FungibleTokenWithStates) => ft.principal === coinKey);
|
||||
const sip10Ft = sip10List?.find((ft: FungibleTokenWithStates) => ft.principal === coinKey);
|
||||
const brc20Ft = brc20List?.find((ft: FungibleTokenWithStates) => ft.principal === coinKey);
|
||||
|
||||
const payload = { principal: coinKey, isEnabled };
|
||||
|
||||
@@ -211,29 +199,19 @@ function ManageTokens() {
|
||||
const handleBackButtonClick = () => navigate('/');
|
||||
|
||||
const getCoinsList = () => {
|
||||
let coins: FungibleToken[];
|
||||
let coins: FungibleTokenWithStates[];
|
||||
let error: boolean;
|
||||
switch (selectedProtocol) {
|
||||
case 'stacks':
|
||||
coins = (sip10List ?? []).map((ft) => ({
|
||||
...ft,
|
||||
visible:
|
||||
sip10ManageTokens[ft.principal] ?? (ft.supported && new BigNumber(ft.balance).gt(0)),
|
||||
}));
|
||||
coins = sip10List ?? [];
|
||||
error = sip10Error;
|
||||
break;
|
||||
case 'brc-20':
|
||||
coins = (brc20List ?? []).map((ft) => ({
|
||||
...ft,
|
||||
visible: brc20ManageTokens[ft.principal] ?? new BigNumber(ft.balance).gt(0),
|
||||
}));
|
||||
coins = brc20List ?? [];
|
||||
error = brc20Error;
|
||||
break;
|
||||
case 'runes':
|
||||
coins = (runesList ?? []).map((ft) => ({
|
||||
...ft,
|
||||
visible: runesManageTokens[ft.principal] ?? new BigNumber(ft.balance).gt(0),
|
||||
}));
|
||||
coins = runesList ?? [];
|
||||
error = runeError;
|
||||
break;
|
||||
default:
|
||||
@@ -246,7 +224,7 @@ function ManageTokens() {
|
||||
return (
|
||||
<>
|
||||
{selectedProtocol === 'stacks' && <Stacks />}
|
||||
{coins.map((coin: FungibleToken) => (
|
||||
{coins.map((coin) => (
|
||||
<CoinItem
|
||||
id={coin.principal}
|
||||
key={coin.principal}
|
||||
@@ -257,7 +235,7 @@ function ManageTokens() {
|
||||
runeSymbol={coin.runeSymbol}
|
||||
disabled={false}
|
||||
toggled={toggled}
|
||||
enabled={coin.visible}
|
||||
enabled={coin.isEnabled}
|
||||
/>
|
||||
))}
|
||||
{!coins.length && <ErrorsText>{t('NO_COINS')}</ErrorsText>}
|
||||
@@ -316,15 +294,7 @@ function ManageTokens() {
|
||||
RUNES
|
||||
</Button>
|
||||
</FtInfoContainer>
|
||||
<TokenContainer>
|
||||
{selectedProtocol === 'runes' && !showRunes ? (
|
||||
<RunesContainer>
|
||||
<RunesComingSoon src={runesComingSoon} />
|
||||
</RunesContainer>
|
||||
) : (
|
||||
getCoinsList()
|
||||
)}
|
||||
</TokenContainer>
|
||||
<TokenContainer>{getCoinsList()}</TokenContainer>
|
||||
</ScrollableContainer>
|
||||
</Container>
|
||||
<BottomBar tab="dashboard" />
|
||||
|
||||
@@ -60,7 +60,7 @@ function SendStxScreen() {
|
||||
// Will be used in the future when the summary screen is refactored
|
||||
const [, setRecipientDomain] = useState('');
|
||||
const [memo, setMemo] = useState(stxMemo ?? '');
|
||||
const { visible: sip10CoinsList } = useVisibleSip10FungibleTokens();
|
||||
const { data: sip10CoinsList } = useVisibleSip10FungibleTokens();
|
||||
const [searchParams] = useSearchParams();
|
||||
const principal = searchParams.get('principal');
|
||||
const fungibleToken = sip10CoinsList?.find((coin) => coin.principal === principal);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import useSupportedCoinRates from '@hooks/queries/useSupportedCoinRates';
|
||||
import useMasterCoinsList from '@screens/swap/useMasterCoinsList';
|
||||
import useVisibleMasterCoinsList from '@screens/swap/useVisibleMasterCoinsList';
|
||||
import { mapSwapProtocolToFTProtocol } from '@screens/swap/utils';
|
||||
import { type Token } from '@secretkeylabs/xverse-core';
|
||||
import { sortFtByFiatBalance } from '@utils/tokens';
|
||||
|
||||
const useFromTokens = (toToken?: Token) => {
|
||||
const tokens = useMasterCoinsList();
|
||||
const tokens = useVisibleMasterCoinsList();
|
||||
const { stxBtcRate, btcFiatRate } = useSupportedCoinRates();
|
||||
|
||||
// Sort tokens, keeping BTC as the first element, and STX (if enabled) as the second
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
import useWalletSelector from '@hooks/useWalletSelector';
|
||||
import useVisibleMasterCoinsList from '@screens/swap/useVisibleMasterCoinsList';
|
||||
import useMasterCoinsList from '@screens/swap/useMasterCoinsList';
|
||||
import { mapFTProtocolToSwapProtocol } from '@screens/swap/utils';
|
||||
import { getXverseApiClient, type Protocol, type TokenBasic } from '@secretkeylabs/xverse-core';
|
||||
import {
|
||||
getXverseApiClient,
|
||||
type Protocol,
|
||||
type Token,
|
||||
type TokenBasic,
|
||||
} from '@secretkeylabs/xverse-core';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { handleRetries } from '@utils/query';
|
||||
|
||||
const useToTokens = (protocol: Protocol, from?: TokenBasic, query?: string) => {
|
||||
const coinsMasterList = useVisibleMasterCoinsList();
|
||||
const { network, spamTokens } = useWalletSelector();
|
||||
const coinsMasterList = useMasterCoinsList();
|
||||
const { network, spamTokens, runesManageTokens, sip10ManageTokens } = useWalletSelector();
|
||||
const spamTokenSet = new Set(spamTokens);
|
||||
|
||||
const userTokens =
|
||||
@@ -41,12 +46,20 @@ const useToTokens = (protocol: Protocol, from?: TokenBasic, query?: string) => {
|
||||
return filteredResponse;
|
||||
};
|
||||
|
||||
const select = (data: Token[]) =>
|
||||
data.filter(
|
||||
(token) =>
|
||||
!spamTokenSet.has(token.ticker) ||
|
||||
runesManageTokens[token.ticker] === true || // allow user to enable spam tokens
|
||||
sip10ManageTokens[token.ticker] === true,
|
||||
);
|
||||
|
||||
return useQuery({
|
||||
enabled: userTokens.length > 0,
|
||||
retry: handleRetries,
|
||||
queryKey: ['swap-from-tokens', network.type, userTokens, protocol, from, search],
|
||||
queryFn,
|
||||
select: (data) => data.filter((rune) => !spamTokenSet.has(rune.ticker)),
|
||||
select,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ import trackSwapMixPanel from './mixpanel';
|
||||
import QuoteSummary from './quoteSummary';
|
||||
import QuotesModal from './quotesModal';
|
||||
import type { OrderInfo, Side, StxOrderInfo } from './types';
|
||||
import useMasterCoinsList from './useMasterCoinsList';
|
||||
import useVisibleMasterCoinsList from './useVisibleMasterCoinsList';
|
||||
import {
|
||||
getTrackingIdentifier,
|
||||
isStxTx,
|
||||
@@ -138,7 +138,7 @@ export default function SwapScreen() {
|
||||
const defaultFrom = params.get('from');
|
||||
const { quotes, loading: quotesLoading, error: quotesError, fetchQuotes } = useGetQuotes();
|
||||
const { data: runeFloorPrice } = useRuneFloorPriceQuery(toToken?.name ?? '');
|
||||
const coinsMasterList = useMasterCoinsList();
|
||||
const coinsMasterList = useVisibleMasterCoinsList();
|
||||
const { tokenInfo: sip10FromTokenInfoUSD } = useGetSip10TokenInfo({
|
||||
principal: toToken?.ticker,
|
||||
fiatCurrency: 'USD',
|
||||
@@ -149,7 +149,7 @@ export default function SwapScreen() {
|
||||
const token = coinsMasterList.find((coin) => coin.principal === defaultFrom);
|
||||
setFromToken(token);
|
||||
}
|
||||
}, [defaultFrom, coinsMasterList.length]);
|
||||
}, [defaultFrom, coinsMasterList]);
|
||||
|
||||
const handleGoBack = () => {
|
||||
navigate('/');
|
||||
|
||||
@@ -31,7 +31,7 @@ export const stxFt: FungibleToken = {
|
||||
|
||||
const useMasterCoinsList = () => {
|
||||
const { data: sip10FtList } = useGetSip10FungibleTokens();
|
||||
const { unfilteredData: runesFtList } = useRuneFungibleTokensQuery();
|
||||
const { data: runesFtList } = useRuneFungibleTokensQuery();
|
||||
const { hideStx } = useWalletSelector();
|
||||
const isStacksSwapsEnabled = useHasFeature(FeatureId.STACKS_SWAPS);
|
||||
|
||||
|
||||
@@ -7,20 +7,18 @@ import { useMemo } from 'react';
|
||||
import { btcFt, stxFt } from './useMasterCoinsList';
|
||||
|
||||
const useVisibleMasterCoinsList = () => {
|
||||
const { visible: sip10FtList } = useVisibleSip10FungibleTokens();
|
||||
const { visible: runesFtList } = useVisibleRuneFungibleTokens();
|
||||
const isStacksSwapsEnabled = useHasFeature(FeatureId.STACKS_SWAPS);
|
||||
|
||||
const { data: sip10FtList } = useVisibleSip10FungibleTokens();
|
||||
const { data: runesFtList } = useVisibleRuneFungibleTokens();
|
||||
const { hideStx } = useWalletSelector();
|
||||
const isStacksSwapsEnabled = useHasFeature(FeatureId.STACKS_SWAPS);
|
||||
|
||||
const coinsMasterList = useMemo(
|
||||
() => [
|
||||
...sip10FtList,
|
||||
...runesFtList,
|
||||
...(runesFtList || []),
|
||||
btcFt,
|
||||
...(!hideStx && isStacksSwapsEnabled ? [stxFt] : []),
|
||||
...(!hideStx && isStacksSwapsEnabled ? [stxFt, ...(sip10FtList ?? [])] : []),
|
||||
],
|
||||
[sip10FtList, runesFtList, hideStx, isStacksSwapsEnabled],
|
||||
[runesFtList, hideStx, isStacksSwapsEnabled, sip10FtList],
|
||||
);
|
||||
|
||||
return coinsMasterList;
|
||||
|
||||
@@ -27,7 +27,7 @@ export default function UnlistRuneScreen() {
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'LIST_RUNE_SCREEN' });
|
||||
const navigate = useNavigate();
|
||||
const { runeId } = useParams();
|
||||
const { visible: runesCoinsList } = useVisibleRuneFungibleTokens();
|
||||
const { data: runesCoinsList } = useVisibleRuneFungibleTokens();
|
||||
const selectedRune = runesCoinsList.find((ft) => ft.principal === runeId);
|
||||
const showRunesListing =
|
||||
useHasFeature(FeatureId.RUNES_LISTING) || process.env.NODE_ENV === 'development';
|
||||
|
||||
@@ -29,8 +29,8 @@ const migrations = {
|
||||
},
|
||||
3: (
|
||||
state: WalletState & {
|
||||
brcCoinsList: FungibleToken[] | null; // removed in v3
|
||||
coinsList: FungibleToken[] | null; // removed in v3
|
||||
brcCoinsList: (FungibleToken & { visible?: boolean })[] | null; // removed in v3
|
||||
coinsList: (FungibleToken & { visible?: boolean })[] | null; // removed in v3
|
||||
coins: Coin[]; // removed in v3
|
||||
},
|
||||
) => ({
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
microstacksToStx,
|
||||
satsToBtc,
|
||||
type Account,
|
||||
type FungibleToken,
|
||||
type FungibleTokenWithStates,
|
||||
type NetworkType,
|
||||
type NftData,
|
||||
type SettingsNetwork,
|
||||
@@ -252,9 +252,9 @@ export const calculateTotalBalance = ({
|
||||
}: {
|
||||
stxBalance?: string;
|
||||
btcBalance?: string;
|
||||
sipCoinsList: FungibleToken[];
|
||||
brcCoinsList: FungibleToken[];
|
||||
runesCoinList: FungibleToken[];
|
||||
sipCoinsList: FungibleTokenWithStates[];
|
||||
brcCoinsList: FungibleTokenWithStates[];
|
||||
runesCoinList: FungibleTokenWithStates[];
|
||||
stxBtcRate: string;
|
||||
btcFiatRate: string;
|
||||
hideStx: boolean;
|
||||
@@ -277,7 +277,7 @@ export const calculateTotalBalance = ({
|
||||
|
||||
if (sipCoinsList) {
|
||||
totalBalance = sipCoinsList.reduce((acc, coin) => {
|
||||
if (coin.visible && coin.tokenFiatRate && coin.decimals) {
|
||||
if (coin.isEnabled && coin.tokenFiatRate && coin.decimals) {
|
||||
const tokenUnits = new BigNumber(10).exponentiatedBy(new BigNumber(coin.decimals));
|
||||
const coinFiatValue = new BigNumber(coin.balance)
|
||||
.dividedBy(tokenUnits)
|
||||
@@ -291,7 +291,7 @@ export const calculateTotalBalance = ({
|
||||
|
||||
if (brcCoinsList) {
|
||||
totalBalance = brcCoinsList.reduce((acc, coin) => {
|
||||
if (coin.visible && coin.tokenFiatRate) {
|
||||
if (coin.isEnabled && coin.tokenFiatRate) {
|
||||
const coinFiatValue = new BigNumber(coin.balance).multipliedBy(
|
||||
new BigNumber(coin.tokenFiatRate),
|
||||
);
|
||||
@@ -304,7 +304,7 @@ export const calculateTotalBalance = ({
|
||||
|
||||
if (runesCoinList) {
|
||||
totalBalance = runesCoinList.reduce((acc, coin) => {
|
||||
if (coin.visible && coin.tokenFiatRate) {
|
||||
if (coin.isEnabled && coin.tokenFiatRate) {
|
||||
const coinFiatValue = new BigNumber(getFtBalance(coin)).multipliedBy(
|
||||
new BigNumber(coin.tokenFiatRate),
|
||||
);
|
||||
|
||||
@@ -630,18 +630,18 @@ export default class Wallet {
|
||||
|
||||
await expect(this.labelAccountName).toBeVisible();
|
||||
await expect(this.buttonMenu).toBeVisible();
|
||||
await expect(await this.labelTokenSubtitle.count()).toBeGreaterThanOrEqual(2);
|
||||
expect(await this.labelTokenSubtitle.count()).toBeGreaterThanOrEqual(2);
|
||||
|
||||
await expect(this.navigationDashboard).toBeVisible();
|
||||
await expect(this.navigationNFT).toBeVisible();
|
||||
await expect(this.navigationStacking).toBeVisible();
|
||||
await expect(this.navigationExplore).toBeVisible();
|
||||
await expect(this.navigationSettings).toBeVisible();
|
||||
await expect(await this.divTokenRow.count()).toBeGreaterThan(1);
|
||||
expect(await this.divTokenRow.count()).toBeGreaterThan(1);
|
||||
}
|
||||
|
||||
async checkVisualsSendSTXPage3() {
|
||||
await expect(this.page.url()).toContain('confirm-stx-tx');
|
||||
expect(this.page.url()).toContain('confirm-stx-tx');
|
||||
await expect(this.buttonConfirm).toBeVisible();
|
||||
await expect(this.buttonCancel).toBeVisible();
|
||||
await expect(this.receiveAddress).toBeVisible();
|
||||
@@ -655,10 +655,10 @@ export default class Wallet {
|
||||
* Checks the visibility and state of UI elements state on first page in Send Flow
|
||||
*
|
||||
* @param {string} url - The expected URL to validate the correct page navigation.
|
||||
* @param {boolean} isSTX - Optional flag to apply STX-specific element checks (default: false).
|
||||
* @param {boolean} moreInputFields - (default: false).
|
||||
*/
|
||||
async checkVisualsSendPage1(url: string, moreInputFields: boolean = false) {
|
||||
await expect(this.page.url()).toContain(url);
|
||||
expect(this.page.url()).toContain(url);
|
||||
await expect(this.buttonNext).toBeVisible();
|
||||
await expect(this.buttonNext).toBeDisabled();
|
||||
|
||||
@@ -682,7 +682,7 @@ export default class Wallet {
|
||||
* @param {boolean} isSTX - Indicates if the page is STX-specific; adjusts element checks accordingly (default: false).
|
||||
*/
|
||||
async checkVisualsSendPage2(url: string, isSTX: boolean = false) {
|
||||
await expect(this.page.url()).toContain(url);
|
||||
expect(this.page.url()).toContain(url);
|
||||
await expect(this.buttonNext).toBeVisible();
|
||||
await expect(this.buttonNext).toBeDisabled();
|
||||
|
||||
@@ -722,7 +722,7 @@ export default class Wallet {
|
||||
tokenImageShown: boolean = true,
|
||||
ordinalNumber?: string,
|
||||
) {
|
||||
await expect(this.page.url()).toContain(url);
|
||||
expect(this.page.url()).toContain(url);
|
||||
await expect(this.buttonExpand).toBeVisible();
|
||||
await expect(this.buttonCancel).toBeEnabled();
|
||||
await expect(this.buttonConfirm).toBeEnabled();
|
||||
@@ -749,29 +749,27 @@ export default class Wallet {
|
||||
// Execute these checks only if sendAddress is provided
|
||||
if (sendAddress) {
|
||||
await expect(this.sendAddress.first()).toBeVisible();
|
||||
await expect(await this.sendAddress.first().innerText()).toContain(sendAddress.slice(-4));
|
||||
expect(await this.sendAddress.first().innerText()).toContain(sendAddress.slice(-4));
|
||||
}
|
||||
|
||||
// Execute these checks only if recipientAddress is provided
|
||||
if (recipientAddress) {
|
||||
await expect(this.receiveAddress.first()).toBeVisible();
|
||||
await expect(await this.receiveAddress.first().innerText()).toContain(
|
||||
recipientAddress.slice(-4),
|
||||
);
|
||||
expect(await this.receiveAddress.first().innerText()).toContain(recipientAddress.slice(-4));
|
||||
}
|
||||
// Collection Inscriptions don't have the ordinal number displayed in the Review
|
||||
// Check if the right ordinal number is shown
|
||||
if (ordinalNumber) {
|
||||
const reviewNumberOrdinal = await this.numberInscription.first().innerText();
|
||||
await expect(ordinalNumber).toMatch(reviewNumberOrdinal);
|
||||
expect(ordinalNumber).toMatch(reviewNumberOrdinal);
|
||||
}
|
||||
}
|
||||
|
||||
// Check Visuals of Rune Dashboard (without List button), return balance amount
|
||||
async checkVisualsRunesDashboard(runeName) {
|
||||
async checkVisualsRunesDashboard(runeName: string) {
|
||||
await expect(this.imageToken.first()).toBeVisible();
|
||||
await expect(this.textCoinTitle).toBeVisible();
|
||||
await expect(await this.textCoinTitle).toContainText(runeName);
|
||||
await expect(this.textCoinTitle).toContainText(runeName);
|
||||
await expect(this.coinBalance).toBeVisible();
|
||||
await expect(this.buttonReceive).toBeVisible();
|
||||
await expect(this.buttonSend).toBeVisible();
|
||||
@@ -786,11 +784,11 @@ export default class Wallet {
|
||||
await expect(this.buttonSetPrice).toBeVisible();
|
||||
await expect(this.buttonSetPrice).toBeDisabled();
|
||||
await expect(this.runeItem.first()).toBeVisible();
|
||||
await expect(await this.runeItem.count()).toBeGreaterThanOrEqual(1);
|
||||
expect(await this.runeItem.count()).toBeGreaterThanOrEqual(1);
|
||||
}
|
||||
|
||||
async checkVisualsSwapPage() {
|
||||
await expect(this.page.url()).toContain('swap');
|
||||
expect(this.page.url()).toContain('swap');
|
||||
await expect(this.buttonDownArrow.first()).toBeVisible();
|
||||
await expect(this.buttonGetQuotes.first()).toBeVisible();
|
||||
await expect(this.buttonGetQuotes.first()).toBeDisabled();
|
||||
@@ -798,8 +796,8 @@ export default class Wallet {
|
||||
await expect(this.swapTokenBalance).toContainText('--');
|
||||
await expect(this.buttonBack).toBeVisible();
|
||||
await expect(this.nameToken.first()).toContainText('Select asset');
|
||||
await expect(await this.nameToken).toHaveCount(2);
|
||||
await expect(await this.buttonDownArrow).toHaveCount(2);
|
||||
await expect(this.nameToken).toHaveCount(2);
|
||||
await expect(this.buttonDownArrow).toHaveCount(2);
|
||||
await expect(this.buttonGetQuotes).toBeVisible();
|
||||
await expect(this.textUSD).toBeVisible();
|
||||
await expect(this.buttonSwapToken).toBeVisible();
|
||||
@@ -813,7 +811,7 @@ export default class Wallet {
|
||||
|
||||
const usdAmount = await this.textUSD.innerText();
|
||||
const numericUSDValue = parseFloat(usdAmount.replace(/[^0-9.]/g, ''));
|
||||
await expect(numericUSDValue).toBeGreaterThan(0);
|
||||
expect(numericUSDValue).toBeGreaterThan(0);
|
||||
|
||||
return numericUSDValue;
|
||||
}
|
||||
@@ -823,8 +821,8 @@ export default class Wallet {
|
||||
async checkVisualsQuotePage(
|
||||
tokenName: string,
|
||||
slippage: boolean,
|
||||
numericQuoteValue,
|
||||
numericUSDValue,
|
||||
numericQuoteValue: number,
|
||||
numericUSDValue: number,
|
||||
) {
|
||||
await expect(this.buttonSwap).toBeVisible();
|
||||
await expect(this.buttonEditFee).toBeVisible();
|
||||
@@ -832,7 +830,7 @@ export default class Wallet {
|
||||
await expect(this.buttonSlippage).toBeVisible();
|
||||
}
|
||||
// Only 2 token should be visible
|
||||
await expect(await this.buttonSwapPlace.count()).toBe(2);
|
||||
expect(await this.buttonSwapPlace.count()).toBe(2);
|
||||
// await expect(await this.imageToken.count()).toBe(2);
|
||||
|
||||
// Check Rune token name
|
||||
@@ -841,18 +839,18 @@ export default class Wallet {
|
||||
// Check if USD amount from quote page is the same as from th swap start flow page
|
||||
const usdAmountQuote = await this.textUSD.first().innerText();
|
||||
const numericUSDQuote = parseFloat(usdAmountQuote.replace(/[^0-9.]/g, ''));
|
||||
await expect(numericUSDQuote).toEqual(numericUSDValue);
|
||||
expect(numericUSDQuote).toEqual(numericUSDValue);
|
||||
|
||||
// min-received-amount value should be the same as quoteAmount
|
||||
const minReceivedAmount = await this.minReceivedAmount.innerText();
|
||||
const numericMinReceivedAmount = parseFloat(minReceivedAmount.replace(/[^0-9.]/g, ''));
|
||||
const formattedNumericMinReceivedAmount = parseFloat(numericMinReceivedAmount.toFixed(3));
|
||||
await expect(formattedNumericMinReceivedAmount).toEqual(numericQuoteValue);
|
||||
expect(formattedNumericMinReceivedAmount).toEqual(numericQuoteValue);
|
||||
|
||||
// check if quoteAmount is the same from the page before
|
||||
const quoteAmount2Page = await this.quoteAmount.last().innerText();
|
||||
const numericQuote2Page = parseFloat(quoteAmount2Page.replace(/[^0-9.]/g, ''));
|
||||
await expect(numericQuote2Page).toEqual(numericQuoteValue);
|
||||
expect(numericQuote2Page).toEqual(numericQuoteValue);
|
||||
}
|
||||
|
||||
async checkVisualsListOnMEPage() {
|
||||
@@ -879,7 +877,7 @@ export default class Wallet {
|
||||
// Save the current fee amount for comparison
|
||||
const originalFee = await this.feeAmount.innerText();
|
||||
const numericOriginalFee = parseFloat(originalFee.replace(/[^0-9.]/g, ''));
|
||||
await expect(numericOriginalFee).toBeGreaterThan(0);
|
||||
expect(numericOriginalFee).toBeGreaterThan(0);
|
||||
let feePriority = 'Medium';
|
||||
if (feePriorityShown) {
|
||||
feePriority = await this.labelFeePriority.innerText();
|
||||
@@ -896,7 +894,7 @@ export default class Wallet {
|
||||
.locator(this.labelTotalFee)
|
||||
.innerText();
|
||||
const numericFee = parseFloat(fee.replace(/[^0-9.]/g, ''));
|
||||
await expect(numericFee).toBe(numericOriginalFee);
|
||||
expect(numericFee).toBe(numericOriginalFee);
|
||||
|
||||
// Save high fee rate for comparison
|
||||
const highFee = await this.labelTotalFee.first().innerText();
|
||||
@@ -907,12 +905,12 @@ export default class Wallet {
|
||||
|
||||
const newFee = await this.feeAmount.innerText();
|
||||
const numericNewFee = parseFloat(newFee.replace(/[^0-9.]/g, ''));
|
||||
await expect(numericNewFee).toBe(numericHighFee);
|
||||
expect(numericNewFee).toBe(numericHighFee);
|
||||
}
|
||||
|
||||
async navigateToCollectibles() {
|
||||
await this.navigationNFT.click();
|
||||
await expect(this.page.url()).toContain('nft-dashboard');
|
||||
expect(this.page.url()).toContain('nft-dashboard');
|
||||
// If 'enable' rare sats pop up is appearing
|
||||
if (await this.buttonEnable.isVisible()) {
|
||||
await this.buttonEnable.click();
|
||||
@@ -923,32 +921,30 @@ export default class Wallet {
|
||||
}
|
||||
|
||||
// had to disable this rule as my first assertion was always changed to a wrong assertion
|
||||
/* eslint-disable playwright/prefer-web-first-assertions */
|
||||
async checkAmountsSendingSTX(amountSTXSend, STXTest, sendFee) {
|
||||
await expect(await this.receiveAddress.first().innerText()).toContain(STXTest.slice(-4));
|
||||
expect(await this.receiveAddress.first().innerText()).toContain(STXTest.slice(-4));
|
||||
|
||||
// Sending amount without Fee
|
||||
const sendAmount = await this.confirmAmount.first().innerText();
|
||||
const numericValueSendAmount = parseFloat(sendAmount.replace(/[^0-9.]/g, ''));
|
||||
|
||||
await expect(numericValueSendAmount).toEqual(amountSTXSend);
|
||||
expect(numericValueSendAmount).toEqual(amountSTXSend);
|
||||
|
||||
// Fees
|
||||
const fee = await this.feeAmount.innerText();
|
||||
const numericValueFee = parseFloat(fee.replace(/[^0-9.]/g, ''));
|
||||
await expect(numericValueFee).toEqual(sendFee);
|
||||
expect(numericValueFee).toEqual(sendFee);
|
||||
}
|
||||
|
||||
/* eslint-disable playwright/prefer-web-first-assertions */
|
||||
async checkAmountsSendingBTC(selfBTCTest, BTCTest, amountBTCSend) {
|
||||
// Sending amount without Fee
|
||||
const amountText = await this.confirmAmount.first().innerText();
|
||||
const numericValueAmountText = parseFloat(amountText.replace(/[^0-9.]/g, ''));
|
||||
await expect(numericValueAmountText).toEqual(amountBTCSend);
|
||||
expect(numericValueAmountText).toEqual(amountBTCSend);
|
||||
|
||||
// Address check sending and receiving
|
||||
await expect(await this.sendAddress.innerText()).toContain(selfBTCTest.slice(-4));
|
||||
await expect(await this.receiveAddress.first().innerText()).toContain(BTCTest.slice(-4));
|
||||
expect(await this.sendAddress.innerText()).toContain(selfBTCTest.slice(-4));
|
||||
expect(await this.receiveAddress.first().innerText()).toContain(BTCTest.slice(-4));
|
||||
|
||||
const confirmAmountAfter = await this.confirmAmount.last().innerText();
|
||||
const originalFee = await this.feeAmount.innerText();
|
||||
@@ -963,7 +959,7 @@ export default class Wallet {
|
||||
// Balance - fees - sending amount
|
||||
const roundedResult = Number((num3 - num2 - amountBTCSend).toFixed(9));
|
||||
// Check if Balance value after the transaction is the same as the calculated value
|
||||
await expect(num1).toEqual(roundedResult);
|
||||
expect(num1).toEqual(roundedResult);
|
||||
}
|
||||
|
||||
async confirmSendTransaction(transactionIDShown: boolean = true) {
|
||||
@@ -976,7 +972,7 @@ export default class Wallet {
|
||||
await this.buttonClose.click();
|
||||
}
|
||||
|
||||
async getAddress(whichAddress): Promise<string> {
|
||||
async getAddress(whichAddress: string): Promise<string> {
|
||||
// click on 'Receive' button
|
||||
await this.allUpperButtons.nth(1).click();
|
||||
|
||||
@@ -994,7 +990,7 @@ export default class Wallet {
|
||||
return address;
|
||||
}
|
||||
|
||||
async getTokenBalance(tokenname) {
|
||||
async getTokenBalance(tokenname: string) {
|
||||
const locator = this.page
|
||||
.getByRole('button')
|
||||
.filter({ has: this.labelTokenSubtitle.getByText(tokenname, { exact: true }) })
|
||||
@@ -1005,14 +1001,14 @@ export default class Wallet {
|
||||
return numericValue;
|
||||
}
|
||||
|
||||
async clickOnSpecificToken(tokenname) {
|
||||
async clickOnSpecificToken(tokenname: string) {
|
||||
const specificToken = this.page
|
||||
.getByRole('button')
|
||||
.filter({ has: this.labelTokenSubtitle.getByText(tokenname, { exact: true }) });
|
||||
await specificToken.last().click();
|
||||
}
|
||||
|
||||
async clickOnSpecificInscription(inscriptionName) {
|
||||
async clickOnSpecificInscription(inscriptionName: string) {
|
||||
const specificToken = this.containersCollectibleItem
|
||||
.filter({
|
||||
has: this.nameInscription.getByText(inscriptionName, { exact: true }),
|
||||
@@ -1022,7 +1018,7 @@ export default class Wallet {
|
||||
}
|
||||
|
||||
// This function tries to click on a specific rune, if the rune is not enabled it will enable the test rune and then click on it
|
||||
async checkAndClickOnSpecificRune(tokenname) {
|
||||
async checkAndClickOnSpecificRune(tokenname: string) {
|
||||
// Check if test rune is enabled and if not enabled the test rune
|
||||
try {
|
||||
// click on the test rune
|
||||
@@ -1066,7 +1062,7 @@ export default class Wallet {
|
||||
await expect(this.inputFallbackBTCURL).toBeVisible();
|
||||
}
|
||||
|
||||
async checkTestnetUrls(shouldContainTestnet) {
|
||||
async checkTestnetUrls(shouldContainTestnet: boolean) {
|
||||
const inputsURL = [this.inputStacksURL, this.inputBTCURL, this.inputFallbackBTCURL];
|
||||
const checks = inputsURL.map(async (input) => {
|
||||
const inputValue = await input.inputValue();
|
||||
@@ -1097,6 +1093,7 @@ export default class Wallet {
|
||||
|
||||
await this.checkTestnetUrls(true);
|
||||
|
||||
// TODO think of a better way to do this
|
||||
// Wait for the network to be switched so that API doesn't fail because of the rate limiting
|
||||
await this.page.waitForTimeout(15000);
|
||||
|
||||
@@ -1119,6 +1116,7 @@ export default class Wallet {
|
||||
|
||||
await this.checkTestnetUrls(false);
|
||||
|
||||
// TODO think of a better way to do this
|
||||
// Wait for the network to be switched so that API doesn't fail because of the rate limiting
|
||||
await this.page.waitForTimeout(15000);
|
||||
|
||||
@@ -1156,30 +1154,21 @@ export default class Wallet {
|
||||
const balanceText = await this.labelCoinBalanceCurrency.innerText();
|
||||
totalBalance = parseFloat(balanceText.replace(/[^\d.-]/g, ''));
|
||||
}
|
||||
// Check if total balance of all tokens is the same as total wallet balance
|
||||
const totalBalanceText = await this.balance.innerText();
|
||||
const totalBalanceWallet = parseFloat(totalBalanceText.replace(/[^\d.-]/g, ''));
|
||||
await expect(totalBalanceWallet).toBe(totalBalance);
|
||||
return totalBalance;
|
||||
}
|
||||
|
||||
// The enableRandomToken function takes a parameter tokenType which can either be ‘BRC20’ or ‘SIP10’. This parameter determines additional actions specific to BRC20 tokens.
|
||||
async enableRandomToken(tokenType: 'BRC20' | 'SIP10'): Promise<string> {
|
||||
async selectLastToken(tokenType: 'BRC20' | 'SIP10'): Promise<string> {
|
||||
await this.manageTokenButton.click();
|
||||
await expect(this.page.url()).toContain('manage-tokens');
|
||||
expect(this.page.url()).toContain('manage-tokens');
|
||||
|
||||
// Click on the specific token type button if BRC20 is selected
|
||||
if (tokenType === 'BRC20') {
|
||||
await this.buttonBRC20.click();
|
||||
}
|
||||
|
||||
// Enable a random token
|
||||
const tokenName = await this.toggleRandomToken(true);
|
||||
|
||||
// Navigate back and verify the token is visible
|
||||
const chosenToken = this.divTokenRow.last();
|
||||
const tokenName = (await chosenToken.getAttribute('data-testid')) || 'default-value';
|
||||
await this.buttonBack.click();
|
||||
await expect(this.labelTokenSubtitle.getByText(tokenName, { exact: true })).toBeVisible();
|
||||
|
||||
return tokenName;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ test.describe('Account Management', () => {
|
||||
await page.goto(`chrome-extension://${extensionId}/popup.html`);
|
||||
await wallet.checkVisualsStartpage();
|
||||
await wallet.labelAccountName.click();
|
||||
await expect(page.url()).toContain('account-list');
|
||||
expect(page.url()).toContain('account-list');
|
||||
await expect(wallet.labelAccountName).toHaveCount(1);
|
||||
await expect(wallet.buttonGenerateAccount).toBeVisible();
|
||||
await expect(wallet.buttonConnectHardwareWallet).toBeVisible();
|
||||
@@ -32,7 +32,7 @@ test.describe('Account Management', () => {
|
||||
await page.goto(`chrome-extension://${extensionId}/popup.html`);
|
||||
await wallet.checkVisualsStartpage();
|
||||
await wallet.labelAccountName.click();
|
||||
await expect(page.url()).toContain('account-list');
|
||||
expect(page.url()).toContain('account-list');
|
||||
await expect(wallet.labelAccountName).toHaveCount(1);
|
||||
await wallet.buttonAccountOptions.click();
|
||||
await expect(wallet.buttonRenameAccount).toBeVisible();
|
||||
@@ -65,7 +65,7 @@ test.describe('Account Management', () => {
|
||||
await page.goto(`chrome-extension://${extensionId}/popup.html`);
|
||||
await wallet.checkVisualsStartpage();
|
||||
await wallet.labelAccountName.click();
|
||||
await expect(page.url()).toContain('account-list');
|
||||
expect(page.url()).toContain('account-list');
|
||||
await expect(wallet.labelAccountName).toHaveCount(1);
|
||||
await wallet.buttonAccountOptions.click();
|
||||
await expect(wallet.buttonRenameAccount).toBeVisible();
|
||||
@@ -93,14 +93,14 @@ test.describe('Account Management', () => {
|
||||
await page.goto(`chrome-extension://${extensionId}/popup.html`);
|
||||
await wallet.checkVisualsStartpage();
|
||||
await wallet.labelAccountName.click();
|
||||
await expect(page.url()).toContain('account-list');
|
||||
expect(page.url()).toContain('account-list');
|
||||
await expect(wallet.labelAccountName).toHaveCount(1);
|
||||
await wallet.buttonGenerateAccount.click();
|
||||
await expect(wallet.labelAccountName).toHaveCount(2);
|
||||
await expect(wallet.buttonAccountOptions).toHaveCount(2);
|
||||
await expect(wallet.accountBalance).toHaveCount(2);
|
||||
const balanceText = await wallet.getBalanceOfAllAccounts();
|
||||
await expect(balanceText).toBe(0);
|
||||
expect(balanceText).toBe(0);
|
||||
});
|
||||
|
||||
test('Switch to another account and switch back', async ({ page, extensionId }) => {
|
||||
@@ -111,12 +111,12 @@ test.describe('Account Management', () => {
|
||||
await wallet.checkVisualsStartpage();
|
||||
await expect(wallet.labelAccountName).toHaveText('Account 1');
|
||||
await wallet.labelAccountName.click();
|
||||
await expect(page.url()).toContain('account-list');
|
||||
expect(page.url()).toContain('account-list');
|
||||
await expect(wallet.labelAccountName).toHaveCount(1);
|
||||
await wallet.buttonGenerateAccount.click();
|
||||
await expect(wallet.labelAccountName).toHaveCount(2);
|
||||
const balanceText = await wallet.getBalanceOfAllAccounts();
|
||||
await expect(balanceText).toBe(0);
|
||||
expect(balanceText).toBe(0);
|
||||
await wallet.labelAccountName.last().click();
|
||||
await wallet.checkVisualsStartpage();
|
||||
await expect(wallet.labelAccountName).toHaveText('Account 2');
|
||||
|
||||
@@ -13,278 +13,143 @@ test.describe('Token Management', () => {
|
||||
await wallet.checkVisualsStartpage();
|
||||
await expect(wallet.balance).toHaveText('$0.00');
|
||||
await wallet.manageTokenButton.click();
|
||||
await expect(page.url()).toContain('manage-tokens');
|
||||
expect(page.url()).toContain('manage-tokens');
|
||||
await expect(wallet.buttonBack).toBeVisible();
|
||||
await expect(wallet.buttonSip10).toBeVisible();
|
||||
await expect(wallet.buttonBRC20).toBeVisible();
|
||||
await expect(wallet.buttonRunes).toBeVisible();
|
||||
await expect(wallet.headingTokens).toBeVisible();
|
||||
|
||||
// Check SIP10 token
|
||||
await expect(wallet.checkboxTokenInactive.first()).toBeVisible();
|
||||
const amounttokenSIP = await wallet.labelCoinTitle.count();
|
||||
|
||||
await expect(amounttokenSIP).toBeGreaterThanOrEqual(15);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(amounttokenSIP - 1);
|
||||
// Check SIP10 token tab - only Stacks should be showing when user has no sip10 balances
|
||||
await wallet.buttonSip10.click();
|
||||
await expect(wallet.labelCoinTitle).toHaveCount(1);
|
||||
await expect(wallet.checkboxToken).toHaveCount(1);
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(1);
|
||||
await expect(wallet.checkboxToken).toHaveCount(amounttokenSIP);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(0);
|
||||
|
||||
// Check BRC20 token
|
||||
// Check BRC20 token tab - nothing shows when user has no brc20 balances
|
||||
await wallet.buttonBRC20.click();
|
||||
await expect(wallet.checkboxTokenInactive.first()).toBeVisible();
|
||||
const amounttokenBRC20 = await wallet.labelCoinTitle.count();
|
||||
await expect(amounttokenBRC20).toBeGreaterThanOrEqual(8);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(amounttokenBRC20);
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(0);
|
||||
await expect(wallet.checkboxToken).toHaveCount(amounttokenBRC20);
|
||||
|
||||
// Check rune token
|
||||
await wallet.buttonRunes.click();
|
||||
await expect(wallet.labelCoinTitle).toHaveCount(0);
|
||||
await expect(wallet.checkboxToken).toHaveCount(0);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(0);
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(0);
|
||||
|
||||
// Check rune token tab - nothing shows when user has no runes balances
|
||||
await wallet.buttonRunes.click();
|
||||
await expect(wallet.labelCoinTitle).toHaveCount(0);
|
||||
await expect(wallet.checkboxToken).toHaveCount(0);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(0);
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(0);
|
||||
});
|
||||
|
||||
test('Enable and disable some BRC-20 token', async ({ page, extensionId }) => {
|
||||
const onboardingPage = new Onboarding(page);
|
||||
test('Toggle a BRC-20 token', async ({ page, extensionId }) => {
|
||||
const wallet = new Wallet(page);
|
||||
await onboardingPage.createWalletSkipBackup(strongPW);
|
||||
await wallet.setupTest(extensionId, 'SEED_WORDS1', false);
|
||||
|
||||
await test.step('Enable a random token', async () => {
|
||||
await page.goto(`chrome-extension://${extensionId}/popup.html`);
|
||||
await wallet.checkVisualsStartpage();
|
||||
// Check balances
|
||||
await expect(wallet.balance).toBeVisible();
|
||||
await expect(wallet.balance).toHaveText('$0.00');
|
||||
let balanceText = await wallet.getBalanceOfAllTokens();
|
||||
await expect(balanceText).toBe(0);
|
||||
await wallet.manageTokenButton.click();
|
||||
await expect(page.url()).toContain('manage-tokens');
|
||||
await wallet.buttonBRC20.click();
|
||||
await expect(wallet.checkboxTokenInactive.first()).toBeVisible();
|
||||
const amounttokenBRC20 = await wallet.labelCoinTitle.count();
|
||||
// Enable random token
|
||||
const tokenName = await wallet.toggleRandomToken(true);
|
||||
// Check that amount of checkboxes changed
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(1);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(amounttokenBRC20 - 1);
|
||||
await wallet.buttonBack.click();
|
||||
// new enabled token should be visible on dashboard
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName, { exact: true })).toBeVisible();
|
||||
// Check balances
|
||||
await expect(wallet.balance).toBeVisible();
|
||||
await expect(wallet.balance).toHaveText('$0.00');
|
||||
balanceText = await wallet.getBalanceOfAllTokens();
|
||||
await expect(balanceText).toBe(0);
|
||||
});
|
||||
|
||||
await test.step('Enable some more token', async () => {
|
||||
await test.step('Toggle a random token', async () => {
|
||||
await wallet.manageTokenButton.click();
|
||||
await wallet.buttonBRC20.click();
|
||||
await expect(wallet.checkboxTokenInactive.first()).toBeVisible();
|
||||
const amounttokenBRC20 = await wallet.labelCoinTitle.count();
|
||||
const tokenName1 = await wallet.toggleRandomToken(true);
|
||||
const tokenName2 = await wallet.toggleRandomToken(true);
|
||||
const tokenName3 = await wallet.toggleRandomToken(true);
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(4);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(amounttokenBRC20 - 4);
|
||||
await wallet.buttonBack.click();
|
||||
// new enabled tokens should be visible on dashboard
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName1, { exact: true })).toBeVisible();
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName2, { exact: true })).toBeVisible();
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName3, { exact: true })).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('Disable a random token', async () => {
|
||||
await page.goto(`chrome-extension://${extensionId}/popup.html`);
|
||||
await wallet.checkVisualsStartpage();
|
||||
await wallet.manageTokenButton.click();
|
||||
await expect(page.url()).toContain('manage-tokens');
|
||||
await wallet.buttonBRC20.click();
|
||||
await expect(wallet.checkboxTokenInactive.first()).toBeVisible();
|
||||
const amounttokenBRC20 = await wallet.labelCoinTitle.count();
|
||||
const tokenName = await wallet.toggleRandomToken(false);
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(3);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(amounttokenBRC20 - 3);
|
||||
await wallet.buttonBack.click();
|
||||
// new enabled token should be visible on dashboard
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName, { exact: true })).toBeHidden();
|
||||
// Check balances
|
||||
await expect(wallet.balance).toBeVisible();
|
||||
await expect(wallet.balance).toHaveText('$0.00');
|
||||
const balanceText = await wallet.getBalanceOfAllTokens();
|
||||
await expect(balanceText).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
test('Enable and disable some SIP-10 token', async ({ page, extensionId }) => {
|
||||
const onboardingPage = new Onboarding(page);
|
||||
const wallet = new Wallet(page);
|
||||
await onboardingPage.createWalletSkipBackup(strongPW);
|
||||
|
||||
await test.step('Enable a random token', async () => {
|
||||
await page.goto(`chrome-extension://${extensionId}/popup.html`);
|
||||
await wallet.checkVisualsStartpage();
|
||||
// Check balances
|
||||
await expect(wallet.balance).toBeVisible();
|
||||
await expect(wallet.balance).toHaveText('$0.00');
|
||||
let balanceText = await wallet.getBalanceOfAllTokens();
|
||||
await expect(balanceText).toBe(0);
|
||||
await wallet.manageTokenButton.click();
|
||||
await expect(page.url()).toContain('manage-tokens');
|
||||
await expect(wallet.checkboxTokenInactive.first()).toBeVisible();
|
||||
const amounttokenSIP = await wallet.labelCoinTitle.count();
|
||||
// Enable random token
|
||||
const tokenName = await wallet.toggleRandomToken(true);
|
||||
// Check that amount of checkboxes changed
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(2);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(amounttokenSIP - 2);
|
||||
await wallet.buttonBack.click();
|
||||
// new enabled token should be visible on dashboard
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName, { exact: true })).toBeVisible();
|
||||
// Check balances
|
||||
await expect(wallet.balance).toBeVisible();
|
||||
await expect(wallet.balance).toHaveText('$0.00');
|
||||
balanceText = await wallet.getBalanceOfAllTokens();
|
||||
await expect(balanceText).toBe(0);
|
||||
});
|
||||
|
||||
await test.step('Enable some more token', async () => {
|
||||
await wallet.manageTokenButton.click();
|
||||
await expect(wallet.checkboxTokenInactive.first()).toBeVisible();
|
||||
const amounttokenSIP = await wallet.labelCoinTitle.count();
|
||||
const tokenName1 = await wallet.toggleRandomToken(true);
|
||||
const tokenName2 = await wallet.toggleRandomToken(true);
|
||||
const tokenName3 = await wallet.toggleRandomToken(true);
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(5);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(amounttokenSIP - 5);
|
||||
await wallet.buttonBack.click();
|
||||
// new enabled tokens should be visible on dashboard
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName1, { exact: true })).toBeVisible();
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName2, { exact: true })).toBeVisible();
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName3, { exact: true })).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('Disable a random token', async () => {
|
||||
await page.goto(`chrome-extension://${extensionId}/popup.html`);
|
||||
await wallet.checkVisualsStartpage();
|
||||
await wallet.manageTokenButton.click();
|
||||
await expect(page.url()).toContain('manage-tokens');
|
||||
await expect(wallet.checkboxTokenInactive.first()).toBeVisible();
|
||||
const amounttokenSIP = await wallet.labelCoinTitle.count();
|
||||
const tokenName = await wallet.toggleRandomToken(false);
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(4);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(amounttokenSIP - 4);
|
||||
await wallet.buttonBack.click();
|
||||
// new enabled token should be visible on dashboard
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName, { exact: true })).toBeHidden();
|
||||
// Check balances
|
||||
await expect(wallet.balance).toBeVisible();
|
||||
await expect(wallet.balance).toHaveText('$0.00');
|
||||
const balanceText = await wallet.getBalanceOfAllTokens();
|
||||
await expect(balanceText).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
test('Enable and disable all SIP-10 token', async ({ page, extensionId }) => {
|
||||
const onboardingPage = new Onboarding(page);
|
||||
const wallet = new Wallet(page);
|
||||
await onboardingPage.createWalletSkipBackup(strongPW);
|
||||
|
||||
await test.step('Enable a all tokens', async () => {
|
||||
await page.goto(`chrome-extension://${extensionId}/popup.html`);
|
||||
await wallet.checkVisualsStartpage();
|
||||
// Check balances
|
||||
await expect(wallet.balance).toBeVisible();
|
||||
await expect(wallet.balance).toHaveText('$0.00');
|
||||
let balanceText = await wallet.getBalanceOfAllTokens();
|
||||
await expect(balanceText).toBe(0);
|
||||
await expect(wallet.labelTokenSubtitle).toHaveCount(2);
|
||||
await wallet.manageTokenButton.click();
|
||||
await expect(wallet.checkboxTokenInactive.first()).toBeVisible();
|
||||
const amounttokenSIP = await wallet.labelCoinTitle.count();
|
||||
await expect(page.url()).toContain('manage-tokens');
|
||||
await expect(wallet.checkboxToken).toHaveCount(amounttokenSIP);
|
||||
await wallet.toggleAllTokens(true);
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(amounttokenSIP);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(0);
|
||||
await wallet.buttonBack.click();
|
||||
await expect(wallet.labelTokenSubtitle).toHaveCount(amounttokenSIP + 1);
|
||||
await expect(wallet.balance).toBeVisible();
|
||||
await expect(wallet.balance).toHaveText('$0.00');
|
||||
balanceText = await wallet.getBalanceOfAllTokens();
|
||||
await expect(balanceText).toBe(0);
|
||||
});
|
||||
|
||||
await test.step('Disable all tokens', async () => {
|
||||
await page.goto(`chrome-extension://${extensionId}/popup.html`);
|
||||
await wallet.checkVisualsStartpage();
|
||||
await wallet.manageTokenButton.click();
|
||||
await expect(page.url()).toContain('manage-tokens');
|
||||
await wallet.toggleAllTokens(false);
|
||||
await expect(wallet.checkboxTokenInactive.first()).toBeVisible();
|
||||
const amounttokenSIP = await wallet.labelCoinTitle.count();
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(0);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(amounttokenSIP);
|
||||
await wallet.buttonBack.click();
|
||||
await expect(wallet.labelTokenSubtitle).toHaveCount(1);
|
||||
// Check balances
|
||||
await expect(wallet.balance).toBeVisible();
|
||||
await expect(wallet.balance).toHaveText('$0.00');
|
||||
const balanceText = await wallet.getBalanceOfAllTokens();
|
||||
await expect(balanceText).toBe(0);
|
||||
});
|
||||
});
|
||||
test('Enable and disable all BRC-20 token', async ({ page, extensionId }) => {
|
||||
const onboardingPage = new Onboarding(page);
|
||||
const wallet = new Wallet(page);
|
||||
await onboardingPage.createWalletSkipBackup(strongPW);
|
||||
|
||||
await test.step('Enable a all tokens', async () => {
|
||||
await page.goto(`chrome-extension://${extensionId}/popup.html`);
|
||||
await wallet.checkVisualsStartpage();
|
||||
// Check balances
|
||||
await expect(wallet.balance).toBeVisible();
|
||||
await expect(wallet.balance).toHaveText('$0.00');
|
||||
let balanceText = await wallet.getBalanceOfAllTokens();
|
||||
await expect(balanceText).toBe(0);
|
||||
await expect(wallet.labelTokenSubtitle).toHaveCount(2);
|
||||
await wallet.manageTokenButton.click();
|
||||
await expect(page.url()).toContain('manage-tokens');
|
||||
await wallet.buttonBRC20.click();
|
||||
await expect(wallet.checkboxTokenInactive.first()).toBeVisible();
|
||||
const amounttokenBRC20 = await wallet.labelCoinTitle.count();
|
||||
await expect(wallet.checkboxToken).toHaveCount(amounttokenBRC20);
|
||||
await wallet.toggleAllTokens(true);
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(amounttokenBRC20);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(0);
|
||||
await wallet.buttonBack.click();
|
||||
await expect(wallet.labelTokenSubtitle).toHaveCount(amounttokenBRC20 + 2);
|
||||
await expect(wallet.balance).toBeVisible();
|
||||
await expect(wallet.balance).toHaveText('$0.00');
|
||||
balanceText = await wallet.getBalanceOfAllTokens();
|
||||
await expect(balanceText).toBe(0);
|
||||
});
|
||||
|
||||
await test.step('Disable all tokens', async () => {
|
||||
await page.goto(`chrome-extension://${extensionId}/popup.html`);
|
||||
await wallet.checkVisualsStartpage();
|
||||
await wallet.manageTokenButton.click();
|
||||
await expect(page.url()).toContain('manage-tokens');
|
||||
await wallet.buttonBRC20.click();
|
||||
// NOTE: requires an account with at least 1 brc20 token with balance
|
||||
await expect(wallet.checkboxTokenActive.first()).toBeVisible();
|
||||
const amounttokenBRC20 = await wallet.labelCoinTitle.count();
|
||||
await wallet.toggleAllTokens(false);
|
||||
await expect(wallet.checkboxTokenActive).toHaveCount(0);
|
||||
await expect(wallet.checkboxTokenInactive).toHaveCount(amounttokenBRC20);
|
||||
|
||||
// disable a random token
|
||||
const tokenName = await wallet.toggleRandomToken(false);
|
||||
|
||||
// expect token to be hidden on dashboard
|
||||
const fetchTokens = page.waitForResponse((response) =>
|
||||
response.url().includes('/brc20/tokens'),
|
||||
);
|
||||
await wallet.buttonBack.click();
|
||||
await expect(wallet.labelTokenSubtitle).toHaveCount(2);
|
||||
// Check balances
|
||||
await expect(wallet.balance).toBeVisible();
|
||||
await expect(wallet.balance).toHaveText('$0.00');
|
||||
const balanceText = await wallet.getBalanceOfAllTokens();
|
||||
await expect(balanceText).toBe(0);
|
||||
await fetchTokens;
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName, { exact: true })).toBeHidden();
|
||||
|
||||
// enable the token again
|
||||
await wallet.manageTokenButton.click();
|
||||
await wallet.buttonBRC20.click();
|
||||
await page.getByTestId(tokenName).locator('label').click();
|
||||
|
||||
// expect to be visible again on dashboard
|
||||
const fetchTokensAgain = page.waitForResponse((response) =>
|
||||
response.url().includes('/brc20/tokens'),
|
||||
);
|
||||
await wallet.buttonBack.click();
|
||||
await fetchTokensAgain;
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName, { exact: true })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test('Toggle a SIP-10 token', async ({ page, extensionId }) => {
|
||||
const wallet = new Wallet(page);
|
||||
await wallet.setupTest(extensionId, 'SEED_WORDS1', false);
|
||||
|
||||
await test.step('Toggle a random token', async () => {
|
||||
await wallet.manageTokenButton.click();
|
||||
await wallet.buttonSip10.click();
|
||||
|
||||
// NOTE: requires an account with at least 1 sip10 token with balance
|
||||
await expect(wallet.checkboxTokenActive.first()).toBeVisible();
|
||||
|
||||
// disable a random token
|
||||
const tokenName = await wallet.toggleRandomToken(false);
|
||||
|
||||
// expect token to be hidden on dashboard
|
||||
const fetchTokens = page.waitForResponse((response) =>
|
||||
response.url().includes('/sip10/tokens'),
|
||||
);
|
||||
await wallet.buttonBack.click();
|
||||
await fetchTokens;
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName, { exact: true })).toBeHidden();
|
||||
|
||||
// enable the token again
|
||||
await wallet.manageTokenButton.click();
|
||||
await wallet.buttonSip10.click();
|
||||
await page.getByTestId(tokenName).locator('label').click();
|
||||
|
||||
// expect to be visible again on dashboard
|
||||
const fetchTokensAgain = page.waitForResponse((response) =>
|
||||
response.url().includes('/sip10/tokens'),
|
||||
);
|
||||
await wallet.buttonBack.click();
|
||||
await fetchTokensAgain;
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName, { exact: true })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test('Toggle a Runes token', async ({ page, extensionId }) => {
|
||||
const wallet = new Wallet(page);
|
||||
await wallet.setupTest(extensionId, 'SEED_WORDS1', false);
|
||||
|
||||
await test.step('Toggle a random token', async () => {
|
||||
await wallet.manageTokenButton.click();
|
||||
await wallet.buttonRunes.click();
|
||||
|
||||
// NOTE: requires an account with at least 1 runes token with balance
|
||||
await expect(wallet.checkboxTokenActive.first()).toBeVisible();
|
||||
|
||||
// disable a random token
|
||||
const tokenName = await wallet.toggleRandomToken(false);
|
||||
|
||||
// expect token to be hidden on dashboard
|
||||
const fetchTokens = page.waitForResponse((response) =>
|
||||
response.url().includes('/runes/fiat-rates'),
|
||||
);
|
||||
await wallet.buttonBack.click();
|
||||
await fetchTokens;
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName, { exact: true })).toBeHidden();
|
||||
|
||||
// enable the token again
|
||||
await wallet.manageTokenButton.click();
|
||||
await wallet.buttonRunes.click();
|
||||
await page.getByTestId(tokenName).locator('label').click();
|
||||
|
||||
// expect to be visible again on dashboard
|
||||
const fetchTokensAgain = page.waitForResponse((response) =>
|
||||
response.url().includes('/runes/fiat-rates'),
|
||||
);
|
||||
await wallet.buttonBack.click();
|
||||
await fetchTokensAgain;
|
||||
await expect(wallet.labelTokenSubtitle.getByText(tokenName, { exact: true })).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,12 +5,11 @@ test.describe('Transaction', () => {
|
||||
test('Visual Check SIP 10 Token Transaction history mainnet', async ({ page, extensionId }) => {
|
||||
const wallet = new Wallet(page);
|
||||
await wallet.setupTest(extensionId, 'SEED_WORDS1', false);
|
||||
|
||||
const tokenName = await wallet.enableRandomToken('SIP10');
|
||||
const tokenName = await wallet.selectLastToken('SIP10');
|
||||
|
||||
await wallet.clickOnSpecificToken(tokenName);
|
||||
|
||||
await expect(page.url()).toContain('coinDashboard');
|
||||
expect(page.url()).toContain('coinDashboard');
|
||||
// Check token detail page for token image and coin title
|
||||
await expect(wallet.imageToken).toBeVisible();
|
||||
await expect(wallet.textCoinTitle).toBeVisible();
|
||||
@@ -26,10 +25,10 @@ test.describe('Transaction', () => {
|
||||
test('Visual Check BRC 20 Token Transaction history mainnet', async ({ page, extensionId }) => {
|
||||
const wallet = new Wallet(page);
|
||||
await wallet.setupTest(extensionId, 'SEED_WORDS1', false);
|
||||
const tokenName = await wallet.enableRandomToken('BRC20');
|
||||
const tokenName = await wallet.selectLastToken('BRC20');
|
||||
|
||||
await wallet.clickOnSpecificToken(tokenName);
|
||||
await expect(page.url()).toContain('coinDashboard');
|
||||
expect(page.url()).toContain('coinDashboard');
|
||||
// Check token detail page for coin title
|
||||
await expect(wallet.textCoinTitle).toBeVisible();
|
||||
await expect(wallet.textCoinTitle).toContainText(tokenName);
|
||||
|
||||
Reference in New Issue
Block a user