Skip to content

Commit

Permalink
bydirectional teleport
Browse files Browse the repository at this point in the history
  • Loading branch information
Szegoo committed Aug 28, 2023
1 parent 8fbe8d8 commit d427b17
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 23 deletions.
50 changes: 33 additions & 17 deletions src/pages/transfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ import { AccountType } from 'types/types-arguments/identity';
import AssetRegistry, { Asset } from '@/utils/assetRegistry';
import IdentityKey from '@/utils/identityKey';
import KeyStore from '@/utils/keyStore';
import TransactionRouter from '@/utils/transactionRouter';
import TransactionRouter, { isTeleport } from '@/utils/transactionRouter';

import { chainsSupportingXcmExecute, RELAY_CHAIN } from '@/consts';
import { useRelayApi } from '@/contexts/RelayApi';
import { useToast } from '@/contexts/Toast';
import { useIdentity } from '@/contracts';
import { useAddressBook } from '@/contracts/addressbook/context';
import { getTeleportableAssets } from '@/utils/transactionRouter/teleportableRoutes';
import { Fungible } from '@/utils/transactionRouter/types';

const TransferPage = () => {
const {
Expand Down Expand Up @@ -190,19 +191,30 @@ const TransferPage = () => {
}, [recipientId]);

// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
const isTransferSupported = (
originParaId: number,
reserveParaId: number
): boolean => {
const isTransferSupported = (): boolean => {
if (
sourceChainId === undefined ||
destChainId === undefined ||
selectedAssetXcmInterior === undefined
) {
return false;
}
const reserveParaId = getParaIdFromXcmInterior(selectedAssetXcmInterior);
// If the origin is the reserve chain that means that we can use the existing
// `limitedReserveTransferAssets` or `limitedTeleportAssets` extrinsics which are
// supported on all chains that have the xcm pallet.
if (originParaId == reserveParaId) {
if (sourceChainId == reserveParaId) {
return true;
}

const isSourceParachain = sourceChainId > 0;

if (isTeleport(sourceChainId, destChainId, getFungible(selectedAssetXcmInterior, isSourceParachain, 0))) {
return true;
}

const isOriginSupportingLocalXCM = chainsSupportingXcmExecute.findIndex(
(chain) => chain.paraId == originParaId && chain.relayChain == RELAY_CHAIN
(chain) => chain.paraId == sourceChainId && chain.relayChain == RELAY_CHAIN
);

// We only need the origin chain to support XCM for any other type of transfer to
Expand Down Expand Up @@ -259,14 +271,7 @@ const TransferPage = () => {
: AccountType.accountKey20,
},
reserveChainId,
{
multiAsset: AssetRegistry.xcmInteriorToMultiAsset(
JSON.parse(selectedAssetXcmInterior.toString()),
isSourceParachain,
sourceChainId
),
amount,
},
getFungible(selectedAssetXcmInterior, isSourceParachain, amount),
{
originApi: await getApi(chains[sourceChainId].rpcUrls[rpcIndex]),
destApi: await getApi(chains[destChainId].rpcUrls[rpcIndex]),
Expand All @@ -276,7 +281,7 @@ const TransferPage = () => {
);
};

const getParaIdFromXcmInterior = (xcmInterior: any[]): number => {
const getParaIdFromXcmInterior = (xcmInterior: any): number => {
if (xcmInterior.length > 1 && Object.hasOwn(xcmInterior[1], 'parachain')) {
return xcmInterior[1].parachain;
} else {
Expand All @@ -290,10 +295,21 @@ const TransferPage = () => {
return api;
};

const getFungible = (xcmInterior: any, isSourceParachain: boolean, amount: number): Fungible => {
return {
multiAsset: AssetRegistry.xcmInteriorToMultiAsset(
JSON.parse(xcmInterior.toString()),
isSourceParachain,
sourceChainId
),
amount,
};
}

const canTransfer =
assetSelected &&
recipientId !== undefined &&
isTransferSupported(sourceChainId, destChainId);
isTransferSupported();

return (
<Box className={styles.transferContainer}>
Expand Down
17 changes: 11 additions & 6 deletions src/utils/transactionRouter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,7 @@ class TransactionRouter {
const originParaId = sender.chain;
const destParaId = receiver.chain;

if (teleportableRoutes.some(route => {
return process.env.RELAY_CHAIN ? process.env.RELAY_CHAIN : "rococo" === route.relayChain &&
originParaId === route.originParaId &&
destParaId === route.destParaId &&
JSON.stringify(asset.multiAsset) === JSON.stringify(route.multiAsset)
})) {
if (isTeleport(originParaId, destParaId, asset)) {
// The asset is allowed to be teleported between the origin and the destination.
await TeleportTransfer.send(
transferRpcApis.originApi,
Expand Down Expand Up @@ -207,3 +202,13 @@ const ensureContainsXcmPallet = (api: ApiPromise) => {
throw new Error("The blockchain does not support XCM");
}
}

// Returns whether the transfer is a teleport.
export const isTeleport = (originParaId: number, destParaId: number, asset: Fungible): boolean => {
return teleportableRoutes.some(route => {
return process.env.RELAY_CHAIN ? process.env.RELAY_CHAIN : "rococo" === route.relayChain &&
originParaId === route.originParaId &&
destParaId === route.destParaId &&
JSON.stringify(asset.multiAsset) === JSON.stringify(route.multiAsset)
});
}
60 changes: 60 additions & 0 deletions src/utils/transactionRouter/teleportableRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,26 @@ export const teleportableRoutes: TeleportableRoute[] = [
false
)
},
{
relayChain: "polkadot",
originParaId: 1000,
destParaId: 0,
asset: {
asset: {
Token: "DOT"
},
name: "DOT",
symbol: "DOT",
decimals: 10,
xcmInteriorKey: '[{"network":"polkadot"},"here"]',
inferred: true,
confidence: 0
},
multiAsset: AssetRegistry.xcmInteriorToMultiAsset(
JSON.parse('[{"network":"polkadot"},"here"]'),
false
)
},
{
relayChain: "kusama",
originParaId: 0,
Expand All @@ -53,6 +73,26 @@ export const teleportableRoutes: TeleportableRoute[] = [
false
)
},
{
relayChain: "kusama",
originParaId: 1000,
destParaId: 0,
asset: {
asset: {
Token: "KSM"
},
name: "KSM",
symbol: "KSM",
decimals: 12,
xcmInteriorKey: '[{"network":"kusama"},"here"]',
inferred: true,
confidence: 0
},
multiAsset: AssetRegistry.xcmInteriorToMultiAsset(
JSON.parse('[{"network":"kusama"},"here"]'),
false
)
},
{
relayChain: "rococo",
originParaId: 0,
Expand All @@ -73,6 +113,26 @@ export const teleportableRoutes: TeleportableRoute[] = [
false
)
},
{
relayChain: "rococo",
originParaId: 1000,
destParaId: 0,
asset: {
asset: {
Token: "ROC"
},
name: "ROC",
symbol: "ROC",
decimals: 12,
xcmInteriorKey: '[{"network":"rococo"},"here"]',
inferred: true,
confidence: 0
},
multiAsset: AssetRegistry.xcmInteriorToMultiAsset(
JSON.parse('[{"network":"rococo"},"here"]'),
false
)
}
];

export const getTeleportableAssets = (originChainId: number, destChainId: number): Asset[] => {
Expand Down

0 comments on commit d427b17

Please sign in to comment.