From b0febcfd6966e47e7cf52aa72f2f2d6b19c35f6e Mon Sep 17 00:00:00 2001 From: Brendon Votteler Date: Tue, 12 Mar 2024 17:07:31 +1100 Subject: [PATCH 1/7] feat: add new and update existing routes from interlay --- src/adapters/interlay.ts | 124 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 3 deletions(-) diff --git a/src/adapters/interlay.ts b/src/adapters/interlay.ts index d68c01e..6235216 100644 --- a/src/adapters/interlay.ts +++ b/src/adapters/interlay.ts @@ -27,15 +27,73 @@ export const interlayRouteConfigs = createRouteConfigs("interlay", [ token: "IBTC", xcm: { fee: { token: "IBTC", amount: "9" } }, }, + { + to: "astar", + token: "INTR", + xcm: { + fee: { token: "INTR", amount: "40000000" }, + weightLimit: DEST_WEIGHT, + }, + }, + { + to: "astar", + token: "IBTC", + xcm: { fee: { token: "IBTC", amount: "5" }, weightLimit: DEST_WEIGHT }, + }, + { + to: "parallel", + token: "INTR", + xcm: { + fee: { token: "INTR", amount: "7000000000" }, + weightLimit: DEST_WEIGHT, + }, + }, + { + to: "parallel", + token: "IBTC", + xcm: { fee: { token: "IBTC", amount: "110" }, weightLimit: DEST_WEIGHT }, + }, + { + to: "polkadot", + token: "DOT", + xcm: { + fee: { token: "DOT", amount: "1000000000" }, + weightLimit: DEST_WEIGHT, + }, + }, + { + to: "assetHubPolkadot", + token: "USDC", + xcm: { + fee: { token: "USDC", amount: "80000" }, + weightLimit: DEST_WEIGHT, + }, + }, { to: "assetHubPolkadot", token: "USDT", - xcm: { fee: { token: "USDT", amount: "9" } }, + xcm: { fee: { token: "USDT", amount: "80000" } }, }, { to: "hydradx", token: "IBTC", - xcm: { fee: { token: "IBTC", amount: "7" } }, + xcm: { fee: { token: "IBTC", amount: "15" } }, + }, + { + to: "hydradx", + token: "INTR", + xcm: { + fee: { token: "INTR", amount: "1500000000" }, + weightLimit: DEST_WEIGHT, + }, + }, + { + to: "bifrostPolkadot", + token: "VDOT", + xcm: { + fee: { token: "VDOT", amount: "725" }, + weightLimit: DEST_WEIGHT, + }, }, ]); @@ -61,6 +119,38 @@ export const kintsugiRouteConfigs = createRouteConfigs("kintsugi", [ weightLimit: DEST_WEIGHT, }, }, + { + to: "assetHubKusama", + token: "USDT", + xcm: { + fee: { token: "USDT", amount: "10000" }, + weightLimit: DEST_WEIGHT, + }, + }, + { + to: "heiko", + token: "KBTC", + xcm: { + fee: { token: "KBTC", amount: "110" }, + weightLimit: DEST_WEIGHT, + }, + }, + { + to: "heiko", + token: "KINT", + xcm: { + fee: { token: "KINT", amount: "18000000000" }, + weightLimit: DEST_WEIGHT, + }, + }, + { + to: "bifrost", + token: "VKSM", + xcm: { + fee: { token: "VKSM", amount: "85000000" }, + weightLimit: DEST_WEIGHT, + }, + }, ]); export const interlayTokensConfig: Record< @@ -82,12 +172,26 @@ export const interlayTokensConfig: Record< ed: "0", toRaw: () => ({ Token: "IBTC" }), }, + USDC: { + name: "USDC", + symbol: "USDC", + decimals: 6, + ed: "0", + toRaw: () => ({ ForeignAsset: 12 }), + }, USDT: { name: "USDT", symbol: "USDT", decimals: 6, ed: "0", - toRaw: () => ({ Token: "USDT" }), + toRaw: () => ({ ForeignAsset: 2 }), + }, + VDOT: { + name: "VDOT", + symbol: "VDOT", + decimals: 10, + ed: "0", + toRaw: () => ({ ForeignAsset: 3 }), }, }, kintsugi: { @@ -112,6 +216,20 @@ export const interlayTokensConfig: Record< ed: "0", toRaw: () => ({ ForeignAsset: 2 }), }, + USDT: { + name: "USDT", + symbol: "USDT", + decimals: 6, + ed: "0", + toRaw: () => ({ ForeignAsset: 3 }), + }, + VKSM: { + name: "VKSM", + symbol: "VKSM", + decimals: 12, + ed: "0", + toRaw: () => ({ ForeignAsset: 5 }), + }, }, }; From b298bb4d9434e19b2e38c58df161c4ab206bb4e7 Mon Sep 17 00:00:00 2001 From: Brendon Votteler Date: Tue, 12 Mar 2024 17:08:42 +1100 Subject: [PATCH 2/7] chore: add .vscode to .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 91741d2..5d5f975 100644 --- a/.gitignore +++ b/.gitignore @@ -110,3 +110,6 @@ dist # TernJS port file .tern-port + +# VSCode +.vscode \ No newline at end of file From bd4250dabfbf2cedab6cddc1b8b051f365dd36b1 Mon Sep 17 00:00:00 2001 From: Brendon Votteler Date: Tue, 12 Mar 2024 18:04:35 +1100 Subject: [PATCH 3/7] feat: add/update xcm route configs from parachains toward interlay and kintsugi --- src/adapters/acala/acala-configs.ts | 2 +- src/adapters/assethub.ts | 18 +++++++- src/adapters/astar.ts | 34 ++++++++++++++ src/adapters/bifrost.ts | 64 ++++++++++++++++++++++++--- src/adapters/hydradx.ts | 14 ++++++ src/adapters/parallel.ts | 60 +++++++++++++++++++++++++ src/adapters/polkadot.ts | 16 +++++++ src/configs/chains/polkadot-chains.ts | 7 +++ 8 files changed, 208 insertions(+), 7 deletions(-) diff --git a/src/adapters/acala/acala-configs.ts b/src/adapters/acala/acala-configs.ts index 89230d3..de1c36f 100644 --- a/src/adapters/acala/acala-configs.ts +++ b/src/adapters/acala/acala-configs.ts @@ -104,7 +104,7 @@ export const acalaRouteConfigs = createRouteConfigs("acala", [ to: "interlay", token: "INTR", xcm: { - fee: { token: "INTR", amount: "19000000" }, + fee: { token: "INTR", amount: "20000000" }, }, }, { diff --git a/src/adapters/assethub.ts b/src/adapters/assethub.ts index 2537066..3ac05bc 100644 --- a/src/adapters/assethub.ts +++ b/src/adapters/assethub.ts @@ -73,7 +73,15 @@ export const assetHubPolkadotRouteConfigs = createRouteConfigs( to: "interlay", token: "USDT", xcm: { - fee: { token: "USDT", amount: "808" }, + fee: { token: "USDT", amount: "25000" }, + weightLimit: "Unlimited", + }, + }, + { + to: "interlay", + token: "USDC", + xcm: { + fee: { token: "USDC", amount: "25000" }, weightLimit: "Unlimited", }, }, @@ -126,6 +134,14 @@ export const assetHubKusamaRouteConfigs = createRouteConfigs("assetHubKusama", [ token: "USDT", xcm: { fee: { token: "USDT", amount: "808" }, weightLimit: "Unlimited" }, }, + { + to: "kintsugi", + token: "USDT", + xcm: { + fee: { token: "USDT", amount: "20000" }, + weightLimit: "Unlimited", + }, + }, ]); export const assetHubPolkadotTokensConfig: Record = { diff --git a/src/adapters/astar.ts b/src/adapters/astar.ts index b84e82d..5264ad8 100644 --- a/src/adapters/astar.ts +++ b/src/adapters/astar.ts @@ -70,6 +70,22 @@ export const astarRouteConfigs = createRouteConfigs("astar", [ weightLimit: "Unlimited", }, }, + { + to: "interlay", + token: "IBTC", + xcm: { + fee: { token: "IBTC", amount: "75" }, + weightLimit: "Unlimited", + }, + }, + { + to: "interlay", + token: "INTR", + xcm: { + fee: { token: "INTR", amount: "20000000" }, + weightLimit: "Unlimited", + }, + }, ]); export const shidenRouteConfigs = createRouteConfigs("shiden", [ @@ -134,6 +150,24 @@ export const astarTokensConfig: Record> = { toRaw: () => "1984", toQuery: () => "18446744073709551618", }, + IBTC: { + name: "IBTC", + symbol: "IBTC", + decimals: 8, + ed: "1", + toRaw: () => + "0x0001000000000000000000000000000000000000000000000000000000000000", + toQuery: () => "18446744073709551620", + }, + INTR: { + name: "INTR", + symbol: "INTR", + decimals: 10, + ed: "1", + toRaw: () => + "0x0002000000000000000000000000000000000000000000000000000000000000", + toQuery: () => "18446744073709551621", + }, }, shiden: { SDN: { diff --git a/src/adapters/bifrost.ts b/src/adapters/bifrost.ts index ed7aa3e..c7486f6 100644 --- a/src/adapters/bifrost.ts +++ b/src/adapters/bifrost.ts @@ -12,7 +12,7 @@ import { ApiNotFound, InvalidAddress, TokenNotFound } from "../errors"; import { BalanceData, ExtendedToken, TransferParams } from "../types"; import { createRouteConfigs, validateAddress } from "../utils"; -export const bifrostRouteConfigs = createRouteConfigs("bifrost", [ +export const bifrostKusamaRouteConfigs = createRouteConfigs("bifrost", [ { to: "karura", token: "BNC", @@ -48,9 +48,29 @@ export const bifrostRouteConfigs = createRouteConfigs("bifrost", [ fee: { token: "KUSD", amount: "10011896008" }, }, }, + { + to: "kintsugi", + token: "VKSM", + xcm: { + fee: { token: "VKSM", amount: "175000000" }, + }, + }, ]); -export const bifrostTokensConfig: Record = { +export const bifrostPolkadotRoutersConfig = createRouteConfigs( + "bifrostPolkadot", + [ + { + to: "interlay", + token: "VDOT", + xcm: { + fee: { token: "VDOT", amount: "20000000" }, + }, + }, + ] +); + +export const bifrostKusamaTokensConfig: Record = { BNC: { name: "BNC", symbol: "BNC", @@ -86,6 +106,30 @@ export const bifrostTokensConfig: Record = { ed: "100000000", toRaw: () => ({ Stable: "KUSD" }), }, + VKSM: { + name: "VKSM", + symbol: "VKSM", + decimals: 12, + ed: "100000000", + toRaw: () => ({ VToken: "KSM" }), + }, +}; + +export const bifrostPolkadotTokensConfig: Record = { + BNC: { + name: "BNC", + symbol: "BNC", + decimals: 12, + ed: "10000000000", + toRaw: () => ({ Native: "BNC" }), + }, + VDOT: { + name: "VDOT", + symbol: "VDOT", + decimals: 10, + ed: "1000000", + toRaw: () => ({ VToken2: 0 }), + }, }; // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types @@ -168,7 +212,7 @@ class BaseBifrostAdapter extends BaseCrossChainAdapter { this.balanceAdapter = new BifrostBalanceAdapter({ chain: this.chain.id as ChainId, api, - tokens: bifrostTokensConfig, + tokens: bifrostKusamaTokensConfig, }); } @@ -231,8 +275,18 @@ class BaseBifrostAdapter extends BaseCrossChainAdapter { } } -export class BifrostAdapter extends BaseBifrostAdapter { +export class BifrostKusamaAdapter extends BaseBifrostAdapter { + constructor() { + super(chains.bifrost, bifrostKusamaRouteConfigs, bifrostKusamaTokensConfig); + } +} + +export class BifrostPolkadotAdapter extends BaseBifrostAdapter { constructor() { - super(chains.bifrost, bifrostRouteConfigs, bifrostTokensConfig); + super( + chains.bifrostPolkadot, + bifrostPolkadotRoutersConfig, + bifrostPolkadotTokensConfig + ); } } diff --git a/src/adapters/hydradx.ts b/src/adapters/hydradx.ts index 4693756..fc06103 100644 --- a/src/adapters/hydradx.ts +++ b/src/adapters/hydradx.ts @@ -227,6 +227,13 @@ export const hydradxRoutersConfig = createRouteConfigs("hydradx", [ token: "IBTC", xcm: { fee: { token: "IBTC", amount: "62" } }, }, + { + to: "interlay", + token: "INTR", + xcm: { + fee: { token: "INTR", amount: "20000000" }, + }, + }, { to: "assetHubPolkadot", token: "USDT", @@ -280,6 +287,13 @@ export const hydradxTokensConfig: Record = { ed: "36", toRaw: () => 11, }, + INTR: { + name: "INTR", + symbol: "INTR", + decimals: 10, + ed: "6164274209", + toRaw: () => 17, + }, SUB: { name: "SUB", symbol: "SUB", diff --git a/src/adapters/parallel.ts b/src/adapters/parallel.ts index 5b51ea1..b87f11e 100644 --- a/src/adapters/parallel.ts +++ b/src/adapters/parallel.ts @@ -56,6 +56,22 @@ export const parallelRouteConfigs = createRouteConfigs("parallel", [ weightLimit: DEST_WEIGHT, }, }, + { + to: "interlay", + token: "IBTC", + xcm: { + fee: { token: "IBTC", amount: "72" }, + weightLimit: DEST_WEIGHT, + }, + }, + { + to: "interlay", + token: "INTR", + xcm: { + fee: { token: "INTR", amount: "20000000" }, + weightLimit: DEST_WEIGHT, + }, + }, ]); export const heikoRouteConfigs = createRouteConfigs("heiko", [ @@ -83,6 +99,22 @@ export const heikoRouteConfigs = createRouteConfigs("heiko", [ weightLimit: DEST_WEIGHT, }, }, + { + to: "kintsugi", + token: "KBTC", + xcm: { + fee: { token: "KBTC", amount: "110" }, + weightLimit: DEST_WEIGHT, + }, + }, + { + to: "kintsugi", + token: "KINT", + xcm: { + fee: { token: "KINT", amount: "225000000" }, + weightLimit: DEST_WEIGHT, + }, + }, ]); export const parallelTokensConfig: Record< @@ -125,6 +157,20 @@ export const parallelTokensConfig: Record< ed: "500000000", toRaw: () => "110", }, + IBTC: { + name: "IBTC", + symbol: "IBTC", + decimals: 8, + ed: "1", + toRaw: () => 122, + }, + INTR: { + name: "INTR", + symbol: "INTR", + decimals: 10, + ed: "1", + toRaw: () => 120, + }, }, heiko: { HKO: { @@ -155,6 +201,20 @@ export const parallelTokensConfig: Record< ed: "0", toRaw: () => "109", }, + KBTC: { + name: "KBTC", + symbol: "KBTC", + decimals: 8, + ed: "0", + toRaw: () => 121, + }, + KINT: { + name: "Kintsugi", + symbol: "KINT", + decimals: 12, + ed: "0", + toRaw: () => 119, + }, }, }; diff --git a/src/adapters/polkadot.ts b/src/adapters/polkadot.ts index fbfd935..ccf51ed 100644 --- a/src/adapters/polkadot.ts +++ b/src/adapters/polkadot.ts @@ -43,6 +43,14 @@ export const polkadotRouteConfigs = createRouteConfigs("polkadot", [ weightLimit: "Unlimited", }, }, + { + to: "interlay", + token: "DOT", + xcm: { + fee: { token: "DOT", amount: "25000000" }, + weightLimit: "Unlimited", + }, + }, ]); export const kusamaRouteConfigs = createRouteConfigs("kusama", [ @@ -71,6 +79,14 @@ export const kusamaRouteConfigs = createRouteConfigs("kusama", [ weightLimit: "Unlimited", }, }, + { + to: "kintsugi", + token: "KSM", + xcm: { + fee: { token: "KSM", amount: "250000000" }, + weightLimit: "Unlimited", + }, + }, ]); const polkadotTokensConfig: Record> = { diff --git a/src/configs/chains/polkadot-chains.ts b/src/configs/chains/polkadot-chains.ts index bac9911..e66cc04 100644 --- a/src/configs/chains/polkadot-chains.ts +++ b/src/configs/chains/polkadot-chains.ts @@ -84,4 +84,11 @@ export const polkadotChains = { paraChainId: 2101, ss58Prefix: 28, }, + bifrostPolkadot: { + display: "Bifrost", + type: "substrate", + icon: "https://resources.acala.network/_next/image?url=%2Fnetworks%2Fbifrost.png&w=96&q=75", + paraChainId: 2030, + ss58Prefix: 6, + }, }; From 9dc1ec5fc996e6082f0cd87d42a1844c3cc69efb Mon Sep 17 00:00:00 2001 From: Brendon Votteler Date: Tue, 12 Mar 2024 18:08:09 +1100 Subject: [PATCH 4/7] chore: revert bifrost kusama adapter name change back to what it was previously --- src/adapters/bifrost.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/adapters/bifrost.ts b/src/adapters/bifrost.ts index c7486f6..dc97353 100644 --- a/src/adapters/bifrost.ts +++ b/src/adapters/bifrost.ts @@ -275,7 +275,7 @@ class BaseBifrostAdapter extends BaseCrossChainAdapter { } } -export class BifrostKusamaAdapter extends BaseBifrostAdapter { +export class BifrostAdapter extends BaseBifrostAdapter { constructor() { super(chains.bifrost, bifrostKusamaRouteConfigs, bifrostKusamaTokensConfig); } From df6909fdb676bb1d99b972e757058240f91a88b9 Mon Sep 17 00:00:00 2001 From: Brendon Votteler Date: Wed, 13 Mar 2024 14:48:58 +1100 Subject: [PATCH 5/7] feat: add fallback mode to search for wss nodes by parachain id definition instead of ChainId if necessary --- src/api-provider.ts | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/api-provider.ts b/src/api-provider.ts index 8a047d2..ecafdad 100644 --- a/src/api-provider.ts +++ b/src/api-provider.ts @@ -6,12 +6,18 @@ import { prodParasKusama, prodParasKusamaCommon, prodParasPolkadot, + prodParasPolkadotCommon, prodRelayKusama, prodRelayPolkadot, } from "@polkadot/apps-config/endpoints"; import { isChainEqual } from "./utils/is-chain-equal"; -import { ChainId } from "./configs"; +import { ChainId, chains } from "./configs"; +import { polkadotChains } from "./configs/chains/polkadot-chains"; +import { kusamaChains } from "./configs/chains/kusama-chains"; + +const kusamaChainIds = new Set(Object.keys(kusamaChains)); +const polkadotChainIds = new Set(Object.keys(polkadotChains)); export class ApiProvider { protected apis: Record = {}; @@ -56,6 +62,24 @@ export class ApiProvider { } } + if (!nodes?.length) { + const paraId = chains[chain].paraChainId; + + const haystack = []; + if (kusamaChainIds.has(chain)) { + haystack.push(...prodParasKusamaCommon); + haystack.push(...prodParasKusama); + } else if (polkadotChainIds.has(chain)) { + haystack.push(...prodParasPolkadotCommon); + haystack.push(...prodParasPolkadot); + } + + // find by parachain id + nodes = Object.values( + haystack.find((e) => e.paraId === paraId)?.providers || {} + ).filter((e) => e.startsWith("wss://")); + } + if (nodes.length > 1) { return race(nodes.map((node) => this.connect([node], chain))); } From 604cb33afa5b9364b24cb7ef10c94ab47b794527 Mon Sep 17 00:00:00 2001 From: Brendon Votteler Date: Wed, 13 Mar 2024 15:02:05 +1100 Subject: [PATCH 6/7] feat: add DOT token to interlay adapter, and add KSM route from kintsugi to kusama --- src/adapters/interlay.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/adapters/interlay.ts b/src/adapters/interlay.ts index 6235216..8d0c120 100644 --- a/src/adapters/interlay.ts +++ b/src/adapters/interlay.ts @@ -119,6 +119,14 @@ export const kintsugiRouteConfigs = createRouteConfigs("kintsugi", [ weightLimit: DEST_WEIGHT, }, }, + { + to: "kusama", + token: "KSM", + xcm: { + fee: { token: "KSM", amount: "100000000" }, + weightLimit: DEST_WEIGHT, + }, + }, { to: "assetHubKusama", token: "USDT", @@ -172,6 +180,13 @@ export const interlayTokensConfig: Record< ed: "0", toRaw: () => ({ Token: "IBTC" }), }, + DOT: { + name: "DOT", + symbol: "DOT", + decimals: 10, + ed: "0", + toRaw: () => ({ Token: "DOT" }), + }, USDC: { name: "USDC", symbol: "USDC", @@ -209,6 +224,13 @@ export const interlayTokensConfig: Record< ed: "0", toRaw: () => ({ Token: "KBTC" }), }, + KSM: { + name: "KSM", + symbol: "KSM", + decimals: 12, + ed: "0", + toRaw: () => ({ Token: "DOT" }), + }, LKSM: { name: "LKSM", symbol: "LKSM", From f48d1322bb5ab298670a2c6afbd8a9088030c956 Mon Sep 17 00:00:00 2001 From: Brendon Votteler Date: Wed, 13 Mar 2024 15:28:31 +1100 Subject: [PATCH 7/7] test: add interlay and kintsugi specific xcm test cases --- src/adapters/interlay.spec.ts | 204 ++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 src/adapters/interlay.spec.ts diff --git a/src/adapters/interlay.spec.ts b/src/adapters/interlay.spec.ts new file mode 100644 index 0000000..9d2204e --- /dev/null +++ b/src/adapters/interlay.spec.ts @@ -0,0 +1,204 @@ +import { firstValueFrom } from "rxjs"; + +import { BaseCrossChainAdapter } from "../base-chain-adapter"; +import { Bridge, ChainId, ApiProvider, FN, chains } from "../index"; +import { KintsugiAdapter, InterlayAdapter } from "./interlay"; +import { KusamaAdapter, PolkadotAdapter } from "./polkadot"; +import { AssetHubKusamaAdapter, AssetHubPolkadotAdapter } from "./assethub"; +import { HeikoAdapter, ParallelAdapter } from "./parallel"; +import { AcalaAdapter, KaruraAdapter } from "./acala"; +import { BifrostAdapter, BifrostPolkadotAdapter } from "./bifrost"; +import { HydraDxAdapter } from "./hydradx"; +import { AstarAdapter } from "./astar"; + +describe("Interlay/Kintsugi connections tests", () => { + jest.setTimeout(30000); + + const provider = new ApiProvider(); + + const availableAdapters: Record = { + polkadot: new PolkadotAdapter(), + interlay: new InterlayAdapter(), + assetHubPolkadot: new AssetHubPolkadotAdapter(), + acala: new AcalaAdapter(), + parallel: new ParallelAdapter(), + bifrostPolkadot: new BifrostPolkadotAdapter(), + hydradx: new HydraDxAdapter(), + astar: new AstarAdapter(), + kusama: new KusamaAdapter(), + kintsugi: new KintsugiAdapter(), + assetHubKusama: new AssetHubKusamaAdapter(), + karura: new KaruraAdapter(), + heiko: new HeikoAdapter(), + bifrost: new BifrostAdapter(), + }; + + const bridge = new Bridge({ + adapters: Object.values(availableAdapters), + }); + + const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); + + const printTx = (fromChain: ChainId, toChain: ChainId, token: string) => { + // Alice test address + const testAddress = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"; + + const tx = availableAdapters[fromChain].createTx({ + to: toChain, + token, + amount: FN.fromInner("1000000000", 10), + address: testAddress, + }); + console.log( + "transfer", + token, + "from", + fromChain, + "to", + toChain + ": " + tx.method.toHex() + ); + } + + function printBidirectionalTxs(chainA: ChainId, chainB: ChainId, token: any) { + printTx(chainA, chainB, token); + printTx(chainB, chainA, token); + } + + afterAll(async () => { + const chains = Object.keys(availableAdapters) as ChainId[]; + chains.forEach((chainId) => provider.disconnect(chainId)); + + // fake wait + await wait(3000); + + }, 6000); + + test("1. connect fromChain should be ok", async () => { + const chains = Object.keys(availableAdapters) as ChainId[]; + + expect(provider.getApi(chains[0])).toEqual(undefined); + expect(provider.getApi(chains[1])).toEqual(undefined); + + // connect all adapters + const connected = await firstValueFrom( + provider.connectFromChain(chains, { + polkadot: ["wss://polkadot-rpc.dwellir.com"], + interlay: ["wss://api.interlay.io/parachain"], + assetHubPolkadot: ["wss://statemint-rpc.dwellir.com"], + acala: ["wss://acala-rpc.aca-api.network"], + parallel: ["wss://parallel-rpc.dwellir.com"], + bifrostPolkadot: ["wss://bifrost-polkadot-rpc.dwellir.com"], + hydradx: ["wss://rpc.hydradx.cloud"], + astar: ["wss://rpc.astar.network"], + kusama: ["wss://kusama-rpc.dwellir.com"], + kintsugi: ["wss://api-kusama.interlay.io/parachain"], + assetHubKusama: ["wss://statemine-rpc.dwellir.com"], + karura: ["wss://karura-rpc-0.aca-api.network"], + heiko: ["wss://heiko-rpc.parallel.fi"], + bifrost: ["wss://bifrost-rpc.dwellir.com"], + }) + ); + // and set apiProvider for each adapter + await Promise.all( + chains.map((chain) => + availableAdapters[chain].init(provider.getApi(chain)) + ) + ); + }); + + test("2. token balance query & create tx should be ok", async () => { + const chain: ChainId = "interlay"; + const toChain: ChainId = "polkadot"; + const token = "DOT"; + const testAddress = "23M5ttkmR6Kco7bReRDve6bQUSAcwqebatp3fWGJYb4hDSDJ"; + + const balance = await firstValueFrom( + availableAdapters[chain].subscribeTokenBalance(token, testAddress) + ); + + expect(balance.free.toNumber()).toBeGreaterThanOrEqual(0); + expect(balance.available.toNumber()).toBeGreaterThanOrEqual(0); + + const available = availableAdapters[chain].subscribeInputConfig({ + to: toChain, + token, + address: testAddress, + signer: testAddress, + }); + + const inputConfig = await firstValueFrom(available); + + expect(inputConfig.estimateFee.balance.toNumber()).toBeGreaterThan(0); + expect(inputConfig.minInput.toNumber()).toBeGreaterThan(0); + expect(inputConfig.maxInput.toNumber()).toBeLessThanOrEqual( + balance.available.toNumber() + ); + + const tx = availableAdapters[chain].createTx({ + to: toChain, + token, + amount: FN.fromInner("10000000000", 10), + address: testAddress, + }); + + expect(tx.args.length).toBeGreaterThan(1); + }); + + test("3. all transfer tx should be constructable", async () => { + // kintsugi + printBidirectionalTxs("kintsugi", "kusama", "KSM"); + printBidirectionalTxs("kintsugi", "assetHubKusama", "USDT"); + printBidirectionalTxs("kintsugi", "heiko", "KBTC"); + printBidirectionalTxs("kintsugi", "karura", "KINT"); + printBidirectionalTxs("kintsugi", "karura", "KBTC"); + printBidirectionalTxs("kintsugi", "karura", "LKSM"); + printBidirectionalTxs("kintsugi", "bifrost", "VKSM"); + printBidirectionalTxs("kusama", "assetHubKusama", "KSM"); + + // interlay + printBidirectionalTxs("interlay", "polkadot", "DOT"); + printBidirectionalTxs("interlay", "assetHubPolkadot", "USDT"); + printBidirectionalTxs("interlay", "hydradx", "IBTC"); + printBidirectionalTxs("interlay", "hydradx", "INTR"); + printBidirectionalTxs("interlay", "acala", "INTR"); + printBidirectionalTxs("interlay", "acala", "IBTC"); + printBidirectionalTxs("interlay", "parallel", "INTR"); + printBidirectionalTxs("interlay", "parallel", "IBTC"); + printBidirectionalTxs("interlay", "astar", "INTR"); + printBidirectionalTxs("interlay", "astar", "IBTC"); + printBidirectionalTxs("interlay", "bifrostPolkadot", "VDOT"); + printBidirectionalTxs("polkadot", "assetHubPolkadot", "DOT"); + }); + + test("4. getting native token should work", () => { + const testCases: [ChainId, string][] = [ + // kusama network + ["kusama", "KSM"], + ["kintsugi", "KINT"], + ["karura", "KAR"], + ["bifrost", "BNC"], + ["heiko", "HKO"], + ["assetHubKusama", "KSM"], + // polkadot network + ["polkadot", "DOT"], + ["interlay", "INTR"], + ["acala", "ACA"], + ["hydradx", "HDX"], + ["parallel", "PARA"], + ["bifrostPolkadot", "BNC"], + ["assetHubPolkadot", "DOT"], + ]; + + for (const [chainId, expectedNativeTokenSymbol] of testCases) { + const adapter = bridge.router.findAdapterByName(chainId); + if (!adapter) { + fail(`Unable to find adapter for chain: ${chainId}`); + } + + const nativeTokenSymbol = adapter.getApi()!.registry.chainTokens[0]; + + const nativeToken = adapter.getToken(nativeTokenSymbol); + expect(nativeToken.symbol).toBe(expectedNativeTokenSymbol); + } + }); + }); \ No newline at end of file