diff --git a/package.json b/package.json index 90780345..e7b469ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interlay/bridge", - "version": "0.3.13", + "version": "0.3.14", "description": "polkawallet bridge sdk", "main": "build/index.js", "typings": "build/index.d.ts", diff --git a/scripts/chopsticks-test.ts b/scripts/chopsticks-test.ts index 64343cf7..5c8ed53c 100644 --- a/scripts/chopsticks-test.ts +++ b/scripts/chopsticks-test.ts @@ -217,6 +217,23 @@ export async function runTestCasesAndExit( token: router.token })); + // add in special cases: polkadot/kusama <=> asset hub + const relayId = chains.includes("polkadot") ? "polkadot" : "kusama"; + const assetHubId = relayId === "polkadot" ? "statemint" : "statemine"; + const token = relayId === "polkadot" ? "DOT" : "KSM"; + testCases.push( + { + to: assetHubId as ChainName, + from: relayId as ChainName, + token + }, + { + to: relayId as ChainName, + from: assetHubId as ChainName, + token + }, + ); + const isSkipCase = (testCase: {to: ChainName, from: ChainName, token: string}): boolean => { return skipCases.some((skipCase) => (skipCase.from === undefined || testCase.from === skipCase.from) && diff --git a/src/adapters/polkadot.ts b/src/adapters/polkadot.ts index 13a6a8bd..dfeb69b7 100644 --- a/src/adapters/polkadot.ts +++ b/src/adapters/polkadot.ts @@ -16,7 +16,6 @@ import { CrossChainRouterConfigs, CrossChainTransferParams, } from "../types"; -import { supportsV0V1Multilocation } from "../utils/xcm-versioned-multilocation-check"; export const polkadotRoutersConfig: Omit[] = [ { @@ -27,6 +26,15 @@ export const polkadotRoutersConfig: Omit[] = [ weightLimit: "Unlimited", }, }, + { + to: "statemint", + token: "DOT", + xcm: { + // recent transfer: 1_433_579 - add 10x buffer + fee: { token: "DOT", amount: "14335790" }, + weightLimit: "Unlimited", + }, + }, ]; export const kusamaRoutersConfig: Omit[] = [ { @@ -38,15 +46,21 @@ export const kusamaRoutersConfig: Omit[] = [ weightLimit: "Unlimited", }, }, + { + to: "statemine", + token: "KSM", + xcm: { + // recent transfer: 4_778_331 - add 10x buffer + fee: { token: "KSM", amount: "47783310" }, + weightLimit: "Unlimited", + }, + }, ]; const polkadotTokensConfig: Record> = { polkadot: { DOT: { name: "DOT", symbol: "DOT", decimals: 10, ed: "10000000000" }, }, - interlay: { - DOT: { name: "DOT", symbol: "DOT", decimals: 10, ed: "10000000000" }, - }, kusama: { KSM: { name: "KSM", symbol: "KSM", decimals: 12, ed: "333333333" }, }, @@ -174,34 +188,60 @@ class BasePolkadotAdapter extends BaseCrossChainAdapter { const accountId = this.api?.createType("AccountId32", address).toHex(); - const [dst, acc, ass] = supportsV0V1Multilocation(this.api) - ? [ - { V0: { X1: { Parachain: toChain.paraChainId } } }, - { V0: { X1: { AccountId32: { id: accountId, network: "Any" } } } }, - { V0: [{ ConcreteFungible: { amount: amount.toChainData() } }] }, - ] - : [ - { - V3: { - parents: 0, - interior: { X1: { Parachain: toChain.paraChainId } }, - }, - }, - { - V3: { - parents: 0, - interior: { X1: { AccountId32: { id: accountId } } }, + // to statemine + if (to === "statemine" || to === "statemint") { + const dst = { + interior: { X1: { ParaChain: toChain.paraChainId } }, + parents: 0, + }; + const acc = { + interior: { + X1: { + AccountId32: { + id: accountId, }, }, + }, + parents: 0, + }; + const ass = [ + { + fun: { Fungible: amount.toChainData() }, + id: { Concrete: { interior: "Here", parents: 0 } }, + }, + ]; + + return this.api?.tx.xcmPallet.limitedTeleportAssets( + { V3: dst }, + { V3: acc }, + { V3: ass }, + 0, + "Unlimited" + ); + } + + const [dst, acc, ass] = [ + { + V3: { + parents: 0, + interior: { X1: { Parachain: toChain.paraChainId } }, + }, + }, + { + V3: { + parents: 0, + interior: { X1: { AccountId32: { id: accountId } } }, + }, + }, + { + V3: [ { - V3: [ - { - fun: { Fungible: amount.toChainData() }, - id: { Concrete: { parents: 0, interior: "Here" } }, - }, - ], + fun: { Fungible: amount.toChainData() }, + id: { Concrete: { parents: 0, interior: "Here" } }, }, - ]; + ], + }, + ]; if (to === "kintsugi") { return this.api?.tx.xcmPallet.reserveTransferAssets(dst, acc, ass, 0); diff --git a/src/adapters/statemint.ts b/src/adapters/statemint.ts index b5772dc8..373f7c31 100644 --- a/src/adapters/statemint.ts +++ b/src/adapters/statemint.ts @@ -24,6 +24,15 @@ import { import { supportsV0V1Multilocation } from "../utils/xcm-versioned-multilocation-check"; export const statemintRoutersConfig: Omit[] = [ + { + to: "polkadot", + token: "DOT", + xcm: { + // chopsticks test: 364_421_524 - use 10x buffer + fee: { token: "DOT", amount: "3644215240" }, + weightLimit: "Unlimited", + }, + }, { to: "interlay", token: "USDT", @@ -33,6 +42,15 @@ export const statemintRoutersConfig: Omit[] = [ ]; export const statemineRoutersConfig: Omit[] = [ + { + to: "kusama", + token: "KSM", + xcm: { + // chopsticks test: 91_761_280 - use 10x buffer + fee: { token: "KSM", amount: "917612800" }, + weightLimit: "Unlimited", + }, + }, { to: "kintsugi", token: "USDT", @@ -46,7 +64,7 @@ export const statemineTokensConfig: Record< Record > = { statemine: { - KSM: { name: "KSM", symbol: "KSM", decimals: 12, ed: "3333333" }, + KSM: { name: "KSM", symbol: "KSM", decimals: 12, ed: "33333333" }, // ED set according to minBalance value of assets.asset(1984) USDT: { name: "USDT", symbol: "USDT", decimals: 6, ed: "1000" }, }, @@ -237,6 +255,35 @@ class BaseStatemintAdapter extends BaseCrossChainAdapter { throw new DestinationWeightNotFound(this.chain.id, to, token); } + // to relay chain, support native token + if (to === "kusama" || to === "polkadot") { + if (token !== this.balanceAdapter?.nativeToken) { + throw new CurrencyNotFound(token); + } + + const dst = { interior: "Here", parents: 1 }; + const acc = { + interior: { X1: { AccountId32: { id: accountId } } }, + parents: 0, + }; + const ass = [ + { + id: { + Concrete: { interior: "Here", parents: 1 }, + }, + fun: { Fungible: amount.toChainData() }, + }, + ]; + + return this.api?.tx.polkadotXcm.limitedTeleportAssets( + { V3: dst } as any, + { V3: acc } as any, + { V3: ass } as any, + 0, + this.getDestWeight(token, to)?.toString() as any + ); + } + const assetId = SUPPORTED_TOKENS[token]; if ( (to !== "kintsugi" && to !== "interlay") || diff --git a/src/bridge.spec.ts b/src/bridge.spec.ts index 46417566..bba5b027 100644 --- a/src/bridge.spec.ts +++ b/src/bridge.spec.ts @@ -46,7 +46,7 @@ describe.skip("Bridge sdk usage", () => { const tx = availableAdapters[fromChain].createTx({ to: toChain, token, - amount: FN.fromInner("100000", 10), + amount: FN.fromInner("1000000000", 10), address: testAddress, signer: testAddress, }); @@ -175,18 +175,20 @@ describe.skip("Bridge sdk usage", () => { // printBidirectionalTxs("kintsugi", "karura", "KBTC"); // printBidirectionalTxs("kintsugi", "karura", "LKSM"); // printBidirectionalTxs("kintsugi", "bifrost", "VKSM"); + printBidirectionalTxs("kusama", "statemine", "KSM"); // interlay // printBidirectionalTxs("interlay", "polkadot", "DOT"); // printBidirectionalTxs("interlay", "statemint", "USDT"); // printBidirectionalTxs("interlay", "hydra", "IBTC"); - printBidirectionalTxs("interlay", "hydra", "INTR"); + // printBidirectionalTxs("interlay", "hydra", "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("polkadot", "statemint", "DOT"); }); test("5. getNativeToken should work", () => {