Skip to content

Commit

Permalink
Merge pull request #265 from zkLinkProtocol/preview
Browse files Browse the repository at this point in the history
Preview
  • Loading branch information
zkLeonardo authored Jun 24, 2024
2 parents a22f00e + 0aef37b commit 071b5c9
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 79 deletions.
1 change: 1 addition & 0 deletions components/common/input/TransactionWithdraw.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
:tokens="tokens"
:balances="balances"
:title="from === 'withdraw' ? 'Choose chain and token' : 'Choose token'"
:from="from"
>
<template #body-bottom v-if="$slots['token-dropdown-bottom']">
<slot name="token-dropdown-bottom" />
Expand Down
9 changes: 7 additions & 2 deletions components/token/TokenLine.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
class="flex gap-1"
@click.stop=""
>
<span class="truncate">{{ name }}</span>
<span class="truncate">{{ name }} {{ networkKey ? ` (${getNetworkName(networkKey)})` : "" }}</span>
<ArrowTopRightOnSquareIcon class="h-6 w-6 flex-shrink-0" />
</CommonButtonLabel>
<div v-else class="truncate">{{ name }}</div>
<div v-else class="truncate">{{ name }} {{ networkKey ? ` (${getNetworkName(networkKey)})` : "" }}</div>
</template>
</CommonButtonLineBodyInfo>
</template>
Expand All @@ -44,6 +44,11 @@ import type { Component, PropType } from "vue";
import { iconsList } from "@/data/iconlists";
import { useZkSyncProviderStore } from "@/store/zksync/provider";
const getNetworkName = (networkKey: string) => {
if (!networkKey) return "";
return networkKey === "primary" ? "Linea" : networkKey[0].toUpperCase() + networkKey.slice(1);
};
defineProps({
as: {
type: [String, Object] as PropType<string | Component>,
Expand Down
108 changes: 62 additions & 46 deletions components/token/TokenSelectModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
@after-leave="search = ''"
>
<div v-if="title === 'Choose chain and token'" class="mb-4">
<div class="flex gap-2 flex-wrap">
<div class="flex flex-wrap gap-2">
<div
v-for="(group, groupIndex) in arr"
:key="groupIndex"
class="chainBox cursor-pointer"
:class="{ active: selectChain === group.key }"
@click="buttonClicked(zkSyncNetwork.find(item => item.key === group.key)!);"
@click="buttonClicked(group.key === 'ALL' ? 'ALL' : zkSyncNetwork.find((item) => item.key === group.key)!)"
>
<img :src="group.iconUrl" :alt="group.label" />
<img v-if="group.iconUrl" :src="group.iconUrl" :alt="group.label" />
<p v-else>{{ group.label }}</p>
</div>
</div>
<p v-if="!arr.length" class="mt-block-padding-1/2 text-center">No chains found</p>
Expand Down Expand Up @@ -56,7 +57,7 @@
</template>
<template v-else-if="balanceGroups.length || !search">
<div v-for="(group, index) in balanceGroups" :key="index" class="category">
<TypographyCategoryLabel size="sm" variant="darker" class="group-category-label">
<TypographyCategoryLabel v-if="from === 'deposit'" size="sm" variant="darker" class="group-category-label">
{{ group.title || "Your assets" }}
</TypographyCategoryLabel>
<div class="-mx-block-padding-1/4 sm:-mx-block-padding-1/2">
Expand Down Expand Up @@ -95,21 +96,24 @@ import { MagnifyingGlassIcon } from "@heroicons/vue/24/outline";
import { ethers } from "ethers";
import { storeToRefs } from "pinia";
import useNetworks from "@/composables/useNetworks";
import type { ZkSyncNetwork } from "@/data/networks";
import type { Token, TokenAmount } from "@/types";
import type { Address } from "viem";
import type { PropType } from "vue";
import { useRoute } from "#app";
import { useNetworkStore } from "@/store/network";
import { useOnboardStore } from "@/store/onboard";
import { useSearchtokenStore } from "@/store/searchToken";
import { useZkSyncEthereumBalanceStore } from "@/store/zksync/ethereumBalance";
import { useZkSyncProviderStore } from "@/store/zksync/provider";
import { useZkSyncWalletStore } from "@/store/zksync/wallet";
import { isSupportedMergeToken } from "@/utils/constants";
import { groupBalancesByAmount } from "@/utils/mappers";
import { ETH_ADDRESS, fetchErc20, L2_ETH_TOKEN_ADDRESS } from "~/zksync-web3-nova/src/utils";
import useNetworks from "@/composables/useNetworks";
import type { ZkSyncNetwork } from "@/data/networks";
import { useZkSyncWalletStore } from "@/store/zksync/wallet";
import { useZkSyncProviderStore } from "@/store/zksync/provider";
import { useRoute } from "#app";
const route = useRoute();
const providerStore = useZkSyncProviderStore();
const { zkSyncNetworks } = useNetworks();
Expand All @@ -126,6 +130,10 @@ zkSyncNetwork.map((i) => {
};
arr.push(obj);
});
arr.unshift({
key: "ALL",
label: "All",
});
const props = defineProps({
title: {
type: String,
Expand Down Expand Up @@ -153,6 +161,10 @@ const props = defineProps({
type: Array as PropType<TokenAmount[]>,
default: () => [],
},
from: {
type: String,
default: "deposit",
},
});
const emit = defineEmits<{
(eventName: "update:opened", value: boolean): void;
Expand All @@ -169,11 +181,11 @@ watch(
(value) => {
if (chainList.value.length > 0) {
searchList.value = filterTokens(chainList.value) as TokenAmount[];
balanceGroups = groupBalancesByAmount(searchList);
balanceGroups = groupBalancesByAmount(searchList, props.from);
}
}
);
const selectChain = ref(selectedNetwork.value.key);
const selectChain = ref(props.from === "deposit" ? selectedNetwork.value.key : "ALL");
const showLoading = ref(false);
const hasBalances = computed(() => props.balances.length > 0);
const onboardStore = useOnboardStore();
Expand Down Expand Up @@ -218,7 +230,7 @@ const changeToken = (item: any) => {
return;
}
const url = new URL(route.fullPath, window.location.origin);
url.searchParams.set("network", selectChain.value);
url.searchParams.set("network", selectChain.value === "ALL" ? item.networkKey ?? "ethereum" : selectChain.value);
url.searchParams.set("tokenAddress", item.address);
window.location.href = url.toString();
};
Expand All @@ -230,34 +242,44 @@ const isWithdraw = computed(() => {
return props.title === "Choose chain and token";
});
const buttonClicked = async (network: ZkSyncNetwork) => {
if (isNetworkSelected(network)) {
return;
}
selectChain.value = network.key;
chainLists.value = balance.value.filter((e) => {
if (isSupportedMergeToken(e.address, network.key)) {
return true;
const buttonClicked = async (network: ZkSyncNetwork | "ALL") => {
if (network === "ALL") {
if (selectChain.value === "ALL") {
return;
}
if (!e.l1Address) {
return false;
selectChain.value = "ALL";
chainLists.value = balance.value;
chainList.value = filterTokens(chainLists.value) as TokenAmount[];
balanceGroups = groupBalancesByAmount(chainList, props.from);
} else {
if (isNetworkSelected(network)) {
return;
}
if (isWithdraw.value && network.key === "mantle" && e.l1Address === ETH_ADDRESS) {
selectChain.value = network.key;
chainLists.value = balance.value.filter((e) => {
if (isSupportedMergeToken(e.address, network.key)) {
return true;
}
if (!e.l1Address) {
return false;
}
if (isWithdraw.value && network.key === "mantle" && e.l1Address === ETH_ADDRESS) {
return false;
} else if (e.l1Address === ETH_ADDRESS) {
return true;
}
if (e.networkKey === network.key) {
return true;
}
return false;
} else if (e.l1Address === ETH_ADDRESS) {
return true;
}
if (e.networkKey === network.key) {
return true;
}
return false;
});
chainList.value = filterTokens(
chainLists.value.filter(
(e) => network.isEthGasToken || (e.address !== ETH_ADDRESS && e.address.toLowerCase() !== L2_ETH_TOKEN_ADDRESS)
)
) as TokenAmount[];
balanceGroups = groupBalancesByAmount(chainList);
});
chainList.value = filterTokens(
chainLists.value.filter(
(e) => network.isEthGasToken || (e.address !== ETH_ADDRESS && e.address.toLowerCase() !== L2_ETH_TOKEN_ADDRESS)
)
) as TokenAmount[];
balanceGroups = groupBalancesByAmount(chainList, props.from);
}
};
const displayedTokens = computed(() =>
filterTokens(
Expand All @@ -270,16 +292,9 @@ const displayedTokens = computed(() =>
);
const displayedBalances = computed(
() =>
filterTokens(
props.balances.filter(
(e) =>
selectedNetwork.value.isEthGasToken ||
(e.address !== ETH_ADDRESS && e.address.toLowerCase() !== L2_ETH_TOKEN_ADDRESS)
)
) as TokenAmount[]
() => filterTokens(selectChain.value === "ALL" ? balance.value : props.balances) as TokenAmount[]
);
let balanceGroups = groupBalancesByAmount(displayedBalances);
let balanceGroups = groupBalancesByAmount(displayedBalances, props.from);
const selectedTokenAddress = computed({
get: () => props.tokenAddress,
set: (value) => emit("update:tokenAddress", value),
Expand Down Expand Up @@ -319,6 +334,7 @@ const closeModal = () => {
.token-select-modal {
.modal-card {
@apply grid h-full grid-rows-[max-content_max-content_1fr];
max-height: 680px !important;
}
.category:first-child .group-category-label {
@apply pt-0;
Expand Down
3 changes: 2 additions & 1 deletion data/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ export const confirmedSupportedWallets: WalletEntry[] = [

{ walletName: "Binance Web3", type: "injected" },
{ walletName: "Injected", type: "injected" },
{ walletName: "OKX", type: "injected" },
{ walletName: "OKX", type: "injected" },
{ walletName: "GateWallet", type: "injected" },
{ walletName: "MetaMask", type: "injected" },
{ walletName: "BitKeep", type: "injected" },
{ walletName: "BlockWallet", type: "injected" },
{ walletName: "MathWallet", type: "injected" },
{ walletName: "ImToken", type: "injected" },
{ walletName: "Bitget", type: "injected" },

{ walletName: "GateWallet", type: "walletConnect" },
{ walletName: "MetaMask", type: "walletConnect" },
Expand Down
2 changes: 1 addition & 1 deletion types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type Token = {
networkKey?: string;
l2Address: string;
};
export type TokenAmount = Token & { amount: BigNumberish };
export type TokenAmount = Token & { amount: BigNumberish, usdBalance?: number };

export declare namespace Api {
namespace Response {
Expand Down
69 changes: 41 additions & 28 deletions utils/mappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,49 @@ import { computed } from "vue";
import type { Api, Token, TokenAmount } from "@/types";
import type { Ref } from "vue";

export const groupBalancesByAmount = <T = TokenAmount>(balances: Ref<T[]>) =>
export const groupBalancesByAmount = <T = TokenAmount>(balances: Ref<T[]>, type = "deposit") =>
computed(() => {
const groups: Record<string, { title: string | null; balances: T[] }> = {
default: {
title: null,
balances: [],
},
small: {
title: "Small balances",
balances: [],
},
zero: {
title: "Zero balances",
balances: [],
},
};
for (const balanceItem of balances.value as (T & TokenAmount)[]) {
const decimalBalance =
typeof balanceItem.price === "number"
? removeSmallAmount(balanceItem.amount, balanceItem.decimals, balanceItem.price)
: parseTokenAmount(balanceItem.amount, balanceItem.decimals);
if (!isOnlyZeroes(decimalBalance)) {
groups.default.balances.push(balanceItem);
} else if (decimalBalance === "0") {
groups.zero.balances.push(balanceItem);
} else {
groups.small.balances.push(balanceItem);
if (type === "deposit") {
const groups: Record<string, { title: string | null; balances: T[] }> = {
default: {
title: null,
balances: [],
},
small: {
title: "Small balances",
balances: [],
},
zero: {
title: "Zero balances",
balances: [],
},
};
for (const balanceItem of balances.value as (T & TokenAmount)[]) {
const decimalBalance =
typeof balanceItem.price === "number"
? removeSmallAmount(balanceItem.amount, balanceItem.decimals, balanceItem.price)
: parseTokenAmount(balanceItem.amount, balanceItem.decimals);
if (!isOnlyZeroes(decimalBalance)) {
groups.default.balances.push(balanceItem);
} else if (decimalBalance === "0") {
groups.zero.balances.push(balanceItem);
} else {
groups.small.balances.push(balanceItem);
}
}
const res = [groups.default, groups.small, groups.zero].filter((group) => group.balances.length);
return res;
} else {
const balanceWithUsd = (balances.value as TokenAmount[])
.filter((e) => Number(e.amount) > 0 && (e.l1Address || (!e.l1Address && isMergeToken(e.address))))
.map((item) => ({
...item,
usdBalance: Number(formatRawTokenPrice(item.amount, item.decimals, item.price ?? 0)),
})) as TokenAmount[];

balanceWithUsd.sort((a, b) => (b.usdBalance ?? 0) - (a.usdBalance ?? 0));
return [{ title: null, balances: balanceWithUsd }];
}
return [groups.default, groups.small, groups.zero].filter((group) => group.balances.length);
});

export const mapApiToken = (token: Api.Response.Token): Token => {
Expand Down Expand Up @@ -73,4 +86,4 @@ export function mapApiTransfer(transfer: Api.Response.Transfer) {
};
}
export type Transfer = ReturnType<typeof mapApiTransfer>;
export type Transaction = Api.Response.Transaction;
export type Transaction = Api.Response.Transaction;
2 changes: 1 addition & 1 deletion views/transactions/Withdraw.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
:merge-withdrawal-limit="mergeTokenLockedBalance"
>
<template #token-dropdown-bottom v-if="type === 'withdrawal' && account.address">
<CommonAlert class="sticky bottom-0 mt-3" variant="neutral" :icon="InformationCircleIcon">
<CommonAlert class="bottom-0 mt-3" variant="neutral" :icon="InformationCircleIcon">
<p>Only tokens available for withdrawal are displayed</p>
</CommonAlert>
</template>
Expand Down

0 comments on commit 071b5c9

Please sign in to comment.