Skip to content

Commit

Permalink
feat: transfer ERC20 tokens via XVM from Native accounts (#627)
Browse files Browse the repository at this point in the history
* feat: added asset options on the XCM assets panel

* refactor: asset option

* feat: added XCV token import modal

* feat: configured v2 settings

* feat: configured v2 settings (2)

* feat: added XVM transfer page

* feat: added transfer logic

* fix: display ERC20 tokens on Shibuya EVM

* feat: display imported tokens on the EVM assets page

* config: updated polkadot.js vesion

* fix: updated H160 tokens transfer for XVM tokens

* feat: sending xvm tokens from H160 (local network)

* feat: added 'remove token' feature

* feat: applied WeightV2

* fix: connect API fallback logic

* Gas estimate (#632)

* Gas limit estimate

* fix: updated WASM_GAS_LIMIT and PROOF_SIZE

Co-authored-by: impelcrypto <impelcrypto@gmail.com>

* feat: defined xvm transfer function in v2 folder

* fix: isRequiredCheckXvm

* fix: words

* feat: added Recent History for XVM transfer

* feat: added import ERC20 tokens button

* feat: added search option on EVM XCM assets liest

* feat: added feature panel

* fix: removed XVM PSP22 and EVM ERC20 contract address inputs on the modal

* feat: added XVM-PSP22-option contract

* feat: added contract wasm files

* fix: modified seatch icon styling

* fix: optimized the way computing 'isXcmAssets' variable

* fix: use existing Erc20Token interface for imported tokens

* refactor: clean up

* fix: removed PSP22 contract

* feat: added test file

* refactor: clean up

* refactor: clean up(2)

* styling: updated styling

* fix: monitor native token balance on transfer page

* feat: convert address format in contract

* fix: updated contract address

* fix: removes event listner when the components are unmounted

* feat: fetch users xvm-assets-transfer-history data from token-api

* fix: fetch native token's USD price on H160 mode

Co-authored-by: Nikhil Ranjan <niklabh811@gmail.com>
  • Loading branch information
impelcrypto and niklabh committed Jan 4, 2023
1 parent bcb96f5 commit 979516a
Show file tree
Hide file tree
Showing 96 changed files with 3,841 additions and 639 deletions.
29 changes: 15 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,23 @@
"heroku-deploy": "git push heroku main"
},
"dependencies": {
"@astar-network/astar-ui": "^0.0.60",
"@astar-network/astar-sdk-core": "^0.1.8",
"@astar-network/astar-ui": "^0.0.69",
"@ethersproject/bignumber": "^5.5.0",
"@polkadot/api": "^9.5.2",
"@polkadot/api-contract": "^9.5.2",
"@polkadot/api": "^9.10.2",
"@polkadot/api-contract": "^9.10.2",
"@polkadot/extension-dapp": "0.44.6",
"@polkadot/keyring": "^10.1.11",
"@polkadot/networks": "^10.1.11",
"@polkadot/types": "^9.5.2",
"@polkadot/types-known": "^9.5.2",
"@polkadot/types-support": "^9.5.2",
"@polkadot/ui-keyring": "^2.9.12",
"@polkadot/util": "^10.1.11",
"@polkadot/util-crypto": "^10.1.11",
"@polkadot/vue-identicon": "^2.9.12",
"@polkadot/wasm-crypto": "^6.3.1",
"@polkadot/x-randomvalues": "^10.1.11",
"@polkadot/keyring": "^10.2.1",
"@polkadot/networks": "^10.2.1",
"@polkadot/types": "^9.10.2",
"@polkadot/types-known": "^9.10.2",
"@polkadot/types-support": "^9.10.2",
"@polkadot/ui-keyring": "^2.9.14",
"@polkadot/util": "^10.2.1",
"@polkadot/util-crypto": "^10.2.1",
"@polkadot/vue-identicon": "^2.9.14",
"@polkadot/wasm-crypto": "^6.4.1",
"@polkadot/x-randomvalues": "^10.2.1",
"@quasar/app": "^3.2.3",
"@quasar/extras": "^1.12.0",
"animate.css": "^4.1.1",
Expand Down
1 change: 1 addition & 0 deletions src/@types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ interface Window {
injectedWeb3?: any;
}
declare module '@astar-network/astar-ui';
declare module '@astar-network/astar-sdk-core';
2 changes: 1 addition & 1 deletion src/boot/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default boot(async ({ store }) => {
}

// set metadata header
const favicon = providerEndpoints[Number(networkIdx.value)].favicon;
const favicon = providerEndpoints[Number(networkIdx.value)].defaultLogo;
useMeta({
title: '',
titleTemplate: (title) => `${title} | Astar Portal - Astar & Shiden Network`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<template>
<div v-click-away="closeOption" class="wrapper--asset-options">
<div class="icon-vert" @click="isOptionsOpen = true">
<astar-icon-vert />
<div class="column--icon-dot" @click="isOptionsOpen = true">
<astar-icon-base class="icon--dot" stroke="currentColor" icon-name="option">
<astar-icon-3dots />
</astar-icon-base>
</div>
<div v-if="isOptionsOpen" class="box--options">
<button class="row--option" @click="handleImportTokens">
<button v-if="isImportModal" class="row--option" @click="handleImportTokens">
<div>
<span class="icon--plus"> + </span>
</div>
<span class="text--option">{{ $t('assets.importTokens') }}</span>
</button>
<button class="row--option" @click="handleHideSmallBalances">
<button v-if="!isOnlyImportTokens" class="row--option" @click="handleHideSmallBalances">
<template v-if="isHideSmallBalances">
<div class="icon-hide">
<astar-icon-unhide />
Expand All @@ -26,34 +28,55 @@
</button>
</div>

<modal-import-tokens
:is-modal-import-tokens="isModalImportTokens"
:handle-modal-import-tokens="handleModalImportTokens"
:tokens="tokens"
/>
<div v-if="isImportModal">
<modal-import-evm-tokens
v-if="isH160"
:is-modal-import-tokens="isModalImportTokens"
:handle-modal-import-tokens="handleModalImportTokens"
:tokens="tokens"
/>
<modal-import-xvm-tokens
v-else
:is-modal-import-tokens="isModalImportTokens"
:handle-modal-import-tokens="handleModalImportTokens"
/>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, PropType, computed } from 'vue';
import ModalImportTokens from 'src/components/assets/modals/ModalImportTokens.vue';
import ModalImportEvmTokens from 'src/components/assets/modals/ModalImportEvmTokens.vue';
import ModalImportXvmTokens from 'src/components/assets/modals/ModalImportXvmTokens.vue';
import { SelectedToken } from 'src/c-bridge';
import { useStore } from 'src/store';
import { Asset } from 'src/v2/models';
export default defineComponent({
components: {
ModalImportTokens,
ModalImportEvmTokens,
ModalImportXvmTokens,
},
props: {
isHideSmallBalances: {
isImportModal: {
type: Boolean,
required: true,
},
isOnlyImportTokens: {
type: Boolean,
required: true,
},
isHideSmallBalances: {
type: Boolean,
required: false,
default: true,
},
toggleIsHideSmallBalances: {
type: Function,
required: true,
required: false,
default: null,
},
tokens: {
type: Object as PropType<SelectedToken[]>,
type: Object as PropType<SelectedToken[] | Asset[]>,
required: false,
default: null,
},
Expand Down Expand Up @@ -81,11 +104,13 @@ export default defineComponent({
};
const store = useStore();
const isLoading = computed<boolean>(() => store.getters['general/isLoading']);
const isH160 = computed<boolean>(() => store.getters['general/isH160Formatted']);
return {
isModalImportTokens,
isOptionsOpen,
isLoading,
isH160,
closeOption,
handleHideSmallBalances,
handleImportTokens,
Expand All @@ -96,5 +121,5 @@ export default defineComponent({
</script>

<style lang="scss" scoped>
@use 'src/components/assets/styles/evm-asset-options.scss';
@use 'src/components/assets/styles/asset-options.scss';
</style>
79 changes: 79 additions & 0 deletions src/components/assets/AssetSearchOption.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<template>
<div class="row--search-option">
<div :class="isSearch && 'search--active'">
<div class="box--search">
<table class="table--search">
<tr class="tr--search">
<td>
<input
type="text"
placeholder="Search"
class="input--search"
@input="setSearch"
@focus="setIsSearch(true)"
@blur="setIsSearch(false)"
/>
</td>
<td>
<div class="icon--search">
<astar-icon-search />
</div>
</td>
</tr>
</table>
</div>
</div>
<asset-options
:is-import-modal="isImportModal"
:toggle-is-hide-small-balances="toggleIsHideSmallBalances"
:is-hide-small-balances="isHideSmallBalances"
:tokens="tokens"
:is-only-import-tokens="false"
/>
</div>
</template>

<script lang="ts">
import { defineComponent, PropType } from 'vue';
import AssetOptions from 'src/components/assets/AssetOptions.vue';
export default defineComponent({
components: {
AssetOptions,
},
props: {
isImportModal: {
type: Boolean,
required: true,
},
isHideSmallBalances: {
type: Boolean,
required: true,
},
isSearch: {
type: Boolean,
required: true,
},
setSearch: {
type: Function as PropType<(payload: Event) => void>,
required: true,
},
setIsSearch: {
type: Function,
required: true,
},
toggleIsHideSmallBalances: {
type: Function,
required: true,
},
tokens: {
type: Array as PropType<any[]>,
required: false,
default: null,
},
},
});
</script>

<style lang="scss" scoped>
@use 'src/components/assets/styles/asset-search-option.scss';
</style>
81 changes: 58 additions & 23 deletions src/components/assets/Assets.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<evm-asset-list :tokens="evmAssets.assets" />
</div>
<div v-else class="container--assets">
<xvm-native-asset-list v-if="isSupportXvmTransfer" :xvm-assets="xvmAssets.xvmAssets" />
<xcm-native-asset-list v-if="isEnableXcm" :xcm-assets="xcmAssets.assets" />
<native-asset-list />
</div>
Expand All @@ -24,20 +25,22 @@ import Account from 'src/components/assets/Account.vue';
import EvmAssetList from 'src/components/assets/EvmAssetList.vue';
import NativeAssetList from 'src/components/assets/NativeAssetList.vue';
import XcmNativeAssetList from 'src/components/assets/XcmNativeAssetList.vue';
import XvmNativeAssetList from 'src/components/assets/XvmNativeAssetList.vue';
import { endpointKey, providerEndpoints } from 'src/config/chainEndpoints';
import { LOCAL_STORAGE } from 'src/config/localStorage';
import { useAccount, useBalance, useDispatchGetDapps, useNetworkInfo } from 'src/hooks';
import { useStore } from 'src/store';
import { EvmAssets, XcmAssets } from 'src/store/assets/state';
import { EvmAssets, XcmAssets, XvmAssets } from 'src/store/assets/state';
import { Asset } from 'src/v2/models';
import { computed, defineComponent, ref, watch, watchEffect } from 'vue';
import { computed, defineComponent, ref, watch, watchEffect, onUnmounted } from 'vue';
export default defineComponent({
components: {
Account,
NativeAssetList,
EvmAssetList,
XcmNativeAssetList,
XvmNativeAssetList,
},
setup() {
const token = ref<Asset | null>(null);
Expand All @@ -47,7 +50,7 @@ export default defineComponent({
const store = useStore();
const { currentAccount } = useAccount();
const { accountData } = useBalance(currentAccount);
const { isMainnet, currentNetworkIdx } = useNetworkInfo();
const { isMainnet, currentNetworkIdx, evmNetworkIdx, isSupportXvmTransfer } = useNetworkInfo();
// Memo: load the dApps data in advance, so that users can access to dApp staging page smoothly
useDispatchGetDapps();
Expand All @@ -59,6 +62,7 @@ export default defineComponent({
const isShibuya = computed(() => currentNetworkIdx.value === endpointKey.SHIBUYA);
const xcmAssets = computed<XcmAssets>(() => store.getters['assets/getAllAssets']);
const xvmAssets = computed<XvmAssets>(() => store.getters['assets/getAllXvmAssets']);
const ttlNativeXcmUsdAmount = computed<number>(() => xcmAssets.value.ttlNativeXcmUsdAmount);
const evmAssets = computed<EvmAssets>(() => store.getters['assets/getEvmAllAssets']);
Expand All @@ -70,33 +74,58 @@ export default defineComponent({
}
});
const handleUpdateXcmTokenAssets = () => {
currentAccount.value &&
const handleUpdateNativeTokenAssets = () => {
if (currentAccount.value && evmNetworkIdx.value) {
store.dispatch('assets/getAssets', { address: currentAccount.value, isFetchUsd: true });
};
const handleUpdateEvmAssets = (): void => {
if (isH160.value) {
currentAccount.value &&
store.dispatch('assets/getEvmAssets', {
!isH160.value &&
store.dispatch('assets/getXvmAssets', {
currentAccount: currentAccount.value,
srcChainId: evmNetworkId.value,
currentNetworkIdx: currentNetworkIdx.value,
isFetchUsd: true,
isFetchUsd: isMainnet.value,
srcChainId: evmNetworkIdx.value,
});
}
};
// Memo: triggered after users have imported custom ERC20 tokens
const handleImportingCustomToken = async (): Promise<void> => {
if (!isH160.value) return;
window.addEventListener(LOCAL_STORAGE.EVM_TOKEN_IMPORTS, () => {
handleUpdateEvmAssets();
});
const handleUpdateEvmAssets = (): void => {
currentAccount.value &&
store.dispatch('assets/getEvmAssets', {
currentAccount: currentAccount.value,
srcChainId: evmNetworkId.value,
currentNetworkIdx: currentNetworkIdx.value,
isFetchUsd: isMainnet.value,
});
return;
};
watch([currentAccount], handleUpdateXcmTokenAssets, { immediate: true });
watch([currentAccount], handleUpdateEvmAssets, { immediate: true });
const handleUpdateXvmAssets = (): void => {
currentAccount.value &&
store.dispatch('assets/getXvmAssets', {
currentAccount: currentAccount.value,
isFetchUsd: isMainnet.value,
srcChainId: evmNetworkIdx.value,
});
return;
};
const getAssetEventAndHandler = (): {
event: LOCAL_STORAGE;
handler: () => void;
} => {
const event = isH160.value
? LOCAL_STORAGE.EVM_TOKEN_IMPORTS
: LOCAL_STORAGE.XVM_TOKEN_IMPORTS;
const handler = isH160.value ? handleUpdateEvmAssets : handleUpdateXvmAssets;
return { event, handler };
};
// Memo: triggered after users have imported custom ERC20/XVM tokens
const handleImportingCustomToken = (): void => {
const { handler, event } = getAssetEventAndHandler();
window.addEventListener(event, handler);
};
watch([currentAccount, evmNetworkIdx], handleUpdateNativeTokenAssets, { immediate: true });
watch([currentAccount], handleUpdateEvmAssets, { immediate: isH160.value });
watchEffect(handleImportingCustomToken);
const isEnableXcm = computed(
Expand All @@ -112,19 +141,25 @@ export default defineComponent({
watch([evmAssets, xcmAssets, isH160, isMainnet], handleEvmAssetLoader, { immediate: true });
onUnmounted(() => {
const { handler, event } = getAssetEventAndHandler();
window.removeEventListener(event, handler);
});
return {
evmAssets,
isLoadingXcmAssetsAmount,
isH160,
isEnableXcm,
xcmAssets,
xvmAssets,
ttlNativeXcmUsdAmount,
isModalXcmTransfer,
token,
accountData,
isModalXcmBridge,
isLoading,
handleUpdateXcmTokenAssets,
isSupportXvmTransfer,
};
},
});
Expand Down
Loading

0 comments on commit 979516a

Please sign in to comment.