diff --git a/package.json b/package.json index a81ef848..d778be59 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interlay/bridge", - "version": "0.1.8", + "version": "0.1.9", "description": "polkawallet bridge sdk", "main": "build/index.js", "typings": "build/index.d.ts", diff --git a/src/adapters/interlay.spec.ts b/src/adapters/interlay.spec.ts new file mode 100644 index 00000000..d615ac16 --- /dev/null +++ b/src/adapters/interlay.spec.ts @@ -0,0 +1,129 @@ +import { FixedPointNumber } from "@acala-network/sdk-core"; +import { firstValueFrom } from "rxjs"; + +import { ApiProvider } from "../api-provider"; +import { chains, ChainName } from "../configs"; +import { Bridge } from ".."; +import { PolkadotAdapter } from "./polkadot"; +import { InterlayAdapter } from "./interlay"; +// import { StatemintAdapter } from "./statemint"; + +describe("interlay-adapter should work", () => { + jest.setTimeout(30000); + + const testAccount = "5GREeQcGHt7na341Py6Y6Grr38KUYRvVoiFSiDB52Gt7VZiN"; + const provider = new ApiProvider("mainnet"); + + async function connect(chains: ChainName[]) { + // return firstValueFrom(provider.connectFromChain([chain], { karura: ["wss://crosschain-dev.polkawallet.io:9907"] })); + return firstValueFrom(provider.connectFromChain(chains, undefined)); + } + + test("connect interlay to do xcm", async () => { + // const fromChains = ["interlay", "polkadot", "statemint"] as ChainName[]; + const fromChains = ["interlay", "polkadot"] as ChainName[]; + + await connect(fromChains); + + const interlay = new InterlayAdapter(); + const polkadot = new PolkadotAdapter(); + // const statemint = new StatemintAdapter(); + + await interlay.setApi(provider.getApi(fromChains[0])); + await polkadot.setApi(provider.getApi(fromChains[1])); + // await statemint.setApi(provider.getApi(fromChains[2])); + + // const bridge = new Bridge({ + // adapters: [interlay, polkadot, statemint], + // }); + + const bridge = new Bridge({ + adapters: [interlay, polkadot], + }); + + expect( + bridge.router.getDestinationChains({ + from: chains.interlay, + token: "DOT", + }).length + ).toEqual(1); + + // expect( + // bridge.router.getDestinationChains({ from: chains.interlay, token: "USDT" }) + // .length + // ).toEqual(1); + + const adapter = bridge.findAdapter(fromChains[0]); + + async function runMyTestSuit(to: ChainName, token: string) { + if (adapter) { + const balance = await firstValueFrom( + adapter.subscribeTokenBalance(token, testAccount) + ); + + console.log( + `balance ${token}: free-${balance.free.toNumber()} locked-${balance.locked.toNumber()} available-${balance.available.toNumber()}` + ); + expect(balance.available.toNumber()).toBeGreaterThanOrEqual(0); + expect(balance.free.toNumber()).toBeGreaterThanOrEqual( + balance.available.toNumber() + ); + expect(balance.free.toNumber()).toEqual( + balance.locked.add(balance.available).toNumber() + ); + + const inputConfig = await firstValueFrom( + adapter.subscribeInputConfigs({ + to, + token, + address: testAccount, + signer: testAccount, + }) + ); + + console.log( + `inputConfig: min-${inputConfig.minInput.toNumber()} max-${inputConfig.maxInput.toNumber()} ss58-${ + inputConfig.ss58Prefix + }` + ); + expect(inputConfig.minInput.toNumber()).toBeGreaterThan(0); + expect(inputConfig.maxInput.toNumber()).toBeLessThanOrEqual( + balance.available.toNumber() + ); + + const destFee = adapter.getCrossChainFee(token, to); + + console.log( + `destFee: fee-${destFee.balance.toNumber()} ${destFee.token}` + ); + if (to != "polkadot") { + expect(destFee.balance.toNumber()).toBeGreaterThan(0); + } else { + expect(destFee.balance.toNumber()).toEqual(0.1); + } + + const tx = adapter.createTx({ + amount: FixedPointNumber.fromInner("10000000000", 10), + to, + token, + address: testAccount, + signer: testAccount, + }); + + expect(tx.method.section).toEqual("xTokens"); + // expect(tx.args.length).toEqual(4); + // if (to === "statemint") { + // expect(tx.method.method).toEqual("transferMulticurrencies"); + // } else { + // expect(tx.method.method).toEqual("transfer"); + // } + + expect(tx.args.length).toEqual(4); + expect(tx.method.method).toEqual("transfer"); + } + } + + await runMyTestSuit("polkadot", "DOT"); + // await runMyTestSuit("statemint", "USDT"); + }); +}); diff --git a/src/adapters/interlay.ts b/src/adapters/interlay.ts index 8719b94a..d1a64318 100644 --- a/src/adapters/interlay.ts +++ b/src/adapters/interlay.ts @@ -23,13 +23,18 @@ export const interlayRoutersConfig: Omit[] = [ { to: "polkadot", token: "DOT", - xcm: { fee: { token: "DOT", amount: "0" }, weightLimit: DEST_WEIGHT }, + xcm: { + fee: { token: "DOT", amount: "1000000000" }, + weightLimit: DEST_WEIGHT, + }, }, // { // to: "statemint", // token: "USDT", - // // todo: determine fee amount - current value is a placeholder - // xcm: { fee: { token: "USDT", amount: "10" }, weightLimit: DEST_WEIGHT }, + // xcm: { + // fee: { token: "DOT", amount: "1000000000" }, + // weightLimit: DEST_WEIGHT, + // }, // }, ]; @@ -64,12 +69,12 @@ export const interlayTokensConfig: Record< const KINTSUGI_SUPPORTED_TOKENS: Record = { KSM: { Token: "KSM" }, - USDT: { ForeignAsset: 3 }, + // USDT: { ForeignAsset: 3 }, }; const INTERLAY_SUPPORTED_TOKENS: Record = { DOT: { Token: "DOT" }, - USDT: { ForeignAsset: 2 }, + // USDT: { ForeignAsset: 2 }, }; const getSupportedTokens = (chainname: string): Record => { @@ -232,6 +237,25 @@ class BaseInterlayAdapter extends BaseCrossChainAdapter { }; } + if ( + isChainEqual(toChain, "statemine") || + isChainEqual(toChain, "statemint") + ) { + const destFee = this.getCrossChainFee(token, to); + const destWeight = this.getDestWeight(token, to); + + // do the needful, use multi currencies + return this.api.tx.xTokens.transferMulticurrencies( + [ + [tokenId, amount.toChainData()], + [{ Token: destFee.token }, destFee.balance.toChainData()], + ], + 1, + { V1: dst }, + destWeight?.toString() + ); + } + return this.api.tx.xTokens.transfer( tokenId, amount.toChainData(), diff --git a/src/adapters/statemint.ts b/src/adapters/statemint.ts index afbcfe33..5bd85ce3 100644 --- a/src/adapters/statemint.ts +++ b/src/adapters/statemint.ts @@ -19,15 +19,6 @@ import { } from "../types"; export const statemintRoutersConfig: Omit[] = [ - { - to: "polkadot", - token: "DOT", - xcm: { - // TODO: fee might need tweaking, to be checked in tests - fee: { token: "DOT", amount: "3549633" }, - weightLimit: "Unlimited", - }, - }, { to: "interlay", token: "USDT", @@ -36,35 +27,6 @@ export const statemintRoutersConfig: Omit[] = [ ]; export const statemineRoutersConfig: Omit[] = [ - { - to: "kusama", - token: "KSM", - xcm: { - fee: { token: "KSM", amount: "106666660" }, - weightLimit: "Unlimited", - }, - }, - { - to: "karura", - token: "RMRK", - xcm: { - fee: { token: "RMRK", amount: "6400000" }, - weightLimit: "Unlimited", - }, - }, - { - to: "karura", - token: "ARIS", - xcm: { - fee: { token: "ARIS", amount: "6400000" }, - weightLimit: "Unlimited", - }, - }, - { - to: "karura", - token: "USDT", - xcm: { fee: { token: "USDT", amount: "640" }, weightLimit: "Unlimited" }, - }, { to: "kintsugi", token: "USDT", @@ -78,13 +40,11 @@ export const statemineTokensConfig: Record< > = { statemine: { KSM: { name: "KSM", symbol: "KSM", decimals: 12, ed: "3333333" }, - RMRK: { name: "RMRK", symbol: "RMRK", decimals: 10, ed: "100000000" }, - ARIS: { name: "ARIS", symbol: "ARIS", decimals: 8, ed: "10000000" }, - USDT: { name: "USDT", symbol: "USDT", decimals: 8, ed: "1000" }, + USDT: { name: "USDT", symbol: "USDT", decimals: 6, ed: "1000" }, }, statemint: { DOT: { name: "DOT", symbol: "DOT", decimals: 10, ed: "1000000000" }, - USDT: { name: "USDT", symbol: "USDT", decimals: 8, ed: "1000" }, + USDT: { name: "USDT", symbol: "USDT", decimals: 6, ed: "1000" }, }, };