From 8bae1d5e6db4551f69aa188d1cf1a49556c24fda Mon Sep 17 00:00:00 2001
From: impelcrypto <92044428+impelcrypto@users.noreply.github.com>
Date: Thu, 2 Nov 2023 16:53:53 +0800
Subject: [PATCH] fix: use xTokens pallet on astar (#1004)
* fix: use xtokens pallet on astar
* fix: dest balance
* fix: renamed statemint to AssetHub
---
src/assets/img/chain/asset-hub.svg | 22 ++++
src/hooks/xcm/useXcmBridge.ts | 28 ++++-
src/modules/xcm/index.ts | 20 ++--
src/modules/xcm/tokens/index.ts | 4 +-
.../config/xcm/XcmRepositoryConfiguration.ts | 4 +-
src/v2/models/XcmModels.ts | 8 +-
.../implementations/XcmRepository.ts | 79 --------------
.../implementations/xcm/AstarXcmRepository.ts | 102 ------------------
.../xcm/StatemintXcmRepository.ts | 2 +-
9 files changed, 64 insertions(+), 205 deletions(-)
create mode 100644 src/assets/img/chain/asset-hub.svg
diff --git a/src/assets/img/chain/asset-hub.svg b/src/assets/img/chain/asset-hub.svg
new file mode 100644
index 000000000..322c339af
--- /dev/null
+++ b/src/assets/img/chain/asset-hub.svg
@@ -0,0 +1,22 @@
+
+
+
diff --git a/src/hooks/xcm/useXcmBridge.ts b/src/hooks/xcm/useXcmBridge.ts
index 1c4fbc01a..39048ebe2 100644
--- a/src/hooks/xcm/useXcmBridge.ts
+++ b/src/hooks/xcm/useXcmBridge.ts
@@ -5,6 +5,7 @@ import {
capitalize,
isValidAddressPolkadotAddress,
isValidEvmAddress,
+ wait,
} from '@astar-network/astar-sdk-core';
import { ApiPromise } from '@polkadot/api';
import { ethers } from 'ethers';
@@ -35,6 +36,8 @@ import { Ref, computed, ref, watch, watchEffect } from 'vue';
import { useI18n } from 'vue-i18n';
import { evmToAddress } from '@polkadot/util-crypto';
+import { LOCAL_STORAGE } from 'src/config/localStorage';
+import { castChainName, castXcmEndpoint } from 'src/modules/xcm';
import { Path } from 'src/router';
import { container } from 'src/v2/common';
import { AstarToken } from 'src/v2/config/xcm/XcmRepositoryConfiguration';
@@ -47,8 +50,6 @@ import {
} from 'src/v2/services';
import { Symbols } from 'src/v2/symbols';
import { useRouter } from 'vue-router';
-import { castChainName, castXcmEndpoint } from 'src/modules/xcm';
-import { LOCAL_STORAGE } from 'src/config/localStorage';
const { Acala, Astar, Karura, Polkadot, Shiden } = xcmChainObj;
@@ -610,16 +611,33 @@ export function useXcmBridge(selectedToken: Ref) {
await setOriginChainNativeBal();
});
+ // Memo: to avoid using previous endpoint to fetch destChainBalance and it causes a bug (ex: acala -> statemint)
+ const balMonitorDelay = 500;
+
watch(
[isLoadingApi, currentAccount, selectedToken, srcChain, originChainApiEndpoint],
async () => {
+ // Memo: to display the balance with the same timing as destination balance
+ await wait(balMonitorDelay);
await monitorFromChainBalance();
}
);
- watchEffect(async () => {
- await monitorDestChainBalance(inputtedAddress.value);
- });
+ watch(
+ [
+ isLoadingApi,
+ currentAccount,
+ selectedToken,
+ destChain,
+ originChainApiEndpoint,
+ inputtedAddress,
+ ],
+ async () => {
+ await wait(balMonitorDelay);
+ await monitorDestChainBalance(inputtedAddress.value);
+ },
+ { immediate: true }
+ );
return {
amount,
diff --git a/src/modules/xcm/index.ts b/src/modules/xcm/index.ts
index 73dda41fe..43e157838 100644
--- a/src/modules/xcm/index.ts
+++ b/src/modules/xcm/index.ts
@@ -142,11 +142,11 @@ export let xcmChainObj: XcmChainObj = {
subscan: 'https://shiden.subscan.io',
isAstarNativeToken: false,
},
- [Chain.STATEMINE]: {
- name: Chain.STATEMINE,
+ [Chain.ASSET_HUB_KUSAMA]: {
+ name: Chain.ASSET_HUB_KUSAMA,
relayChain: Chain.KUSAMA,
- img: require('/src/assets/img/chain/statemine.svg'),
- parachainId: parachainIds.STATEMINE,
+ img: require('/src/assets/img/chain/asset-hub.svg'),
+ parachainId: parachainIds.ASSET_HUB_KUSAMA,
endpoints: [
'wss://kusama-asset-hub-rpc.polkadot.io',
'wss://statemine-rpc.dwellir.com',
@@ -154,7 +154,7 @@ export let xcmChainObj: XcmChainObj = {
'wss://statemine.api.onfinality.io/public-ws',
'wss://statemine.public.curie.radiumblock.co/ws',
],
- subscan: 'https://statemine.subscan.io',
+ subscan: 'https://assethub-kusama.subscan.io',
isAstarNativeToken: false,
},
[Chain.KARURA]: {
@@ -220,18 +220,18 @@ export let xcmChainObj: XcmChainObj = {
subscan: 'https://moonbeam.subscan.io',
isAstarNativeToken: true,
},
- [Chain.STATEMINT]: {
- name: Chain.STATEMINT,
+ [Chain.ASSET_HUB]: {
+ name: Chain.ASSET_HUB,
relayChain: Chain.POLKADOT,
- img: require('/src/assets/img/chain/statemine.svg'),
- parachainId: parachainIds.STATEMINT,
+ img: require('/src/assets/img/chain/asset-hub.svg'),
+ parachainId: parachainIds.ASSET_HUB,
endpoints: [
'wss://statemint-rpc.dwellir.com',
'wss://polkadot-asset-hub-rpc.polkadot.io',
'wss://statemint.api.onfinality.io/public-ws',
'wss://statemint.public.curie.radiumblock.co/ws',
],
- subscan: 'https://statemint.subscan.io',
+ subscan: 'https://assethub-polkadot.subscan.io',
isAstarNativeToken: false,
},
[Chain.KINTSUGI]: {
diff --git a/src/modules/xcm/tokens/index.ts b/src/modules/xcm/tokens/index.ts
index 104fbe97d..5398cd73c 100644
--- a/src/modules/xcm/tokens/index.ts
+++ b/src/modules/xcm/tokens/index.ts
@@ -70,7 +70,7 @@ export const xcmToken = {
originAssetId: '1984',
logo: require('/src/assets/img/token/usdt.png'),
isXcmCompatible: true,
- originChain: Chain.STATEMINT,
+ originChain: Chain.ASSET_HUB,
minBridgeAmount: '1.5',
},
{
@@ -203,7 +203,7 @@ export const xcmToken = {
originAssetId: '1984',
logo: require('/src/assets/img/token/usdt.png'),
isXcmCompatible: true,
- originChain: Chain.STATEMINE,
+ originChain: Chain.ASSET_HUB_KUSAMA,
minBridgeAmount: '0.1',
},
{
diff --git a/src/v2/config/xcm/XcmRepositoryConfiguration.ts b/src/v2/config/xcm/XcmRepositoryConfiguration.ts
index 48eff8b66..ce634d71c 100644
--- a/src/v2/config/xcm/XcmRepositoryConfiguration.ts
+++ b/src/v2/config/xcm/XcmRepositoryConfiguration.ts
@@ -19,8 +19,8 @@ export const XcmRepositoryConfiguration: TypeMapping = {
[Chain.SHIDEN]: AstarXcmRepository,
[Chain.ACALA]: AcalaXcmRepository,
[Chain.KARURA]: AcalaXcmRepository,
- [Chain.STATEMINE]: StatemintXcmRepository,
- [Chain.STATEMINT]: StatemintXcmRepository,
+ [Chain.ASSET_HUB_KUSAMA]: StatemintXcmRepository,
+ [Chain.ASSET_HUB]: StatemintXcmRepository,
[Chain.MOONBEAM]: MoonbeamXcmRepository,
[Chain.MOONRIVER]: MoonbeamXcmRepository,
[Chain.POLKADOT]: PolkadotXcmRepository,
diff --git a/src/v2/models/XcmModels.ts b/src/v2/models/XcmModels.ts
index 73fe1c214..cdb8e0929 100644
--- a/src/v2/models/XcmModels.ts
+++ b/src/v2/models/XcmModels.ts
@@ -10,8 +10,8 @@ export enum Chain {
ACALA = 'Acala',
MOONRIVER = 'Moonriver',
MOONBEAM = 'Moonbeam',
- STATEMINE = 'Statemine',
- STATEMINT = 'Statemint',
+ ASSET_HUB = 'Asset-hub',
+ ASSET_HUB_KUSAMA = 'Asset-hub-kusama',
KINTSUGI = 'Kintsugi',
INTERLAY = 'Interlay',
CRUST_SHADOW = 'Crust-shadow',
@@ -30,8 +30,8 @@ export enum parachainIds {
ACALA = 2000,
MOONRIVER = 2023,
MOONBEAM = 2004,
- STATEMINE = 1000,
- STATEMINT = 1000,
+ ASSET_HUB = 1000,
+ ASSET_HUB_KUSAMA = 1000,
KINTSUGI = 2092,
INTERLAY = 2032,
CRUST_SHADOW = 2012,
diff --git a/src/v2/repositories/implementations/XcmRepository.ts b/src/v2/repositories/implementations/XcmRepository.ts
index 92baea457..a376dd181 100644
--- a/src/v2/repositories/implementations/XcmRepository.ts
+++ b/src/v2/repositories/implementations/XcmRepository.ts
@@ -185,18 +185,6 @@ export class XcmRepository implements IXcmRepository {
recipientAddress: string,
amount: BN,
endpoint: string
- ): Promise {
- const isAstar = from.name === 'Astar';
- return isAstar
- ? await this.getPolkadotXcmToOriginChainCall(from, recipientAddress, amount, endpoint)
- : await this.getXtokensToOriginChainCall(from, recipientAddress, amount, endpoint);
- }
-
- private async getXtokensToOriginChainCall(
- from: XcmChain,
- recipientAddress: string,
- amount: BN,
- endpoint: string
): Promise {
const recipientAccountId = getPubkeyFromSS58Addr(recipientAddress);
@@ -244,73 +232,6 @@ export class XcmRepository implements IXcmRepository {
);
}
- // Memo: Remove this method after implementing Xtokens on Astar
- private async getPolkadotXcmToOriginChainCall(
- from: XcmChain,
- recipientAddress: string,
- amount: BN,
- endpoint: string
- ): Promise {
- const recipientAccountId = getPubkeyFromSS58Addr(recipientAddress);
- const version = 'V3';
- const destination = {
- [version]: {
- interior: 'Here',
- parents: new BN(1),
- },
- };
-
- const id = decodeAddress(recipientAccountId);
- const AccountId32 = {
- id,
- };
-
- const beneficiary = {
- [version]: {
- interior: {
- X1: {
- AccountId32,
- },
- },
- parents: new BN(0),
- },
- };
-
- const asset = {
- Concrete: {
- interior: 'Here',
- parents: new BN(1),
- },
- };
-
- const assets = {
- [version]: [
- {
- fun: {
- Fungible: new BN(amount),
- },
- id: asset,
- },
- ],
- };
-
- const weightLimit = {
- Unlimited: null,
- };
-
- return await this.buildTxCall(
- from,
- endpoint,
- 'polkadotXcm',
- 'limitedReserveWithdrawAssets',
- destination,
- beneficiary,
- assets,
- new BN(0),
- weightLimit
- );
- }
-
public getTransferCall(
from: XcmChain,
to: XcmChain,
diff --git a/src/v2/repositories/implementations/xcm/AstarXcmRepository.ts b/src/v2/repositories/implementations/xcm/AstarXcmRepository.ts
index bd3e85e0e..e52a67120 100644
--- a/src/v2/repositories/implementations/xcm/AstarXcmRepository.ts
+++ b/src/v2/repositories/implementations/xcm/AstarXcmRepository.ts
@@ -34,20 +34,7 @@ export class AstarXcmRepository extends XcmRepository {
if (!to.parachainId) {
throw `Parachain id for ${to.name} is not defined`;
}
- const isAstar = from.name === 'Astar';
- return isAstar
- ? await this.getPolkadotXcmCall(from, to, recipientAddress, token, amount, endpoint)
- : await this.getXtokensCall(from, to, recipientAddress, token, amount, endpoint);
- }
- private async getXtokensCall(
- from: XcmChain,
- to: XcmChain,
- recipientAddress: string,
- token: Asset,
- amount: BN,
- endpoint: string
- ): Promise {
const recipientAccountId = getPubkeyFromSS58Addr(recipientAddress);
const isWithdrawAssets = token.id !== this.astarNativeTokenId;
@@ -115,93 +102,4 @@ export class AstarXcmRepository extends XcmRepository {
weightLimit
);
}
-
- // Memo: Remove this method after implementing Xtokens on Astar
- private async getPolkadotXcmCall(
- from: XcmChain,
- to: XcmChain,
- recipientAddress: string,
- token: Asset,
- amount: BN,
- endpoint: string
- ): Promise {
- const recipientAccountId = getPubkeyFromSS58Addr(recipientAddress);
- const version = 'V3';
- const isWithdrawAssets = token.id !== this.astarNativeTokenId;
- const functionName = isWithdrawAssets
- ? 'limitedReserveWithdrawAssets'
- : 'limitedReserveTransferAssets';
-
- const destination = {
- [version]: {
- interior: {
- X1: {
- Parachain: new BN(to.parachainId),
- },
- },
- parents: new BN(1),
- },
- };
-
- const isAccountId20 = ethWalletChains.includes(to.name);
-
- const X1_V3 = isAccountId20
- ? {
- AccountKey20: {
- key: recipientAccountId,
- },
- }
- : {
- AccountId32: {
- id: decodeAddress(recipientAccountId),
- },
- };
-
- const beneficiary = {
- [version]: {
- interior: {
- X1: X1_V3,
- },
- parents: new BN(0),
- },
- };
-
- const asset = isWithdrawAssets
- ? {
- Concrete: await this.fetchAssetConfig(from, token, endpoint),
- }
- : {
- Concrete: {
- interior: 'Here',
- parents: new BN(0),
- },
- };
-
- const assets = {
- [version]: [
- {
- fun: {
- Fungible: new BN(amount),
- },
- id: asset,
- },
- ],
- };
-
- const weightLimit = {
- Unlimited: null,
- };
-
- return await this.buildTxCall(
- from,
- endpoint,
- 'polkadotXcm',
- functionName,
- destination,
- beneficiary,
- assets,
- new BN(0),
- weightLimit
- );
- }
}
diff --git a/src/v2/repositories/implementations/xcm/StatemintXcmRepository.ts b/src/v2/repositories/implementations/xcm/StatemintXcmRepository.ts
index 3d87513b0..6b7016d25 100644
--- a/src/v2/repositories/implementations/xcm/StatemintXcmRepository.ts
+++ b/src/v2/repositories/implementations/xcm/StatemintXcmRepository.ts
@@ -114,7 +114,7 @@ export class StatemintXcmRepository extends XcmRepository {
// Memo: avoid getting a UI error when the `token` is `ASTR` while the `monitorDestChainBalance` function(watch) in useXcmBridge.ts
// Reproduce the UI error: assets page -> transfer ASTR -> XCM -> flip the chains -> To: Statemint
// Todo: The error is because Statemint doesn't have 'ASTR', we can refactor here later
- const statemintChains = [Chain.STATEMINT, Chain.STATEMINE];
+ const statemintChains = [Chain.ASSET_HUB, Chain.ASSET_HUB_KUSAMA];
if (!statemintChains.includes(token.originChain as Chain)) {
return '0';
}