Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: add Heiko kbtc #50

Merged
merged 10 commits into from
Mar 1, 2023
156 changes: 78 additions & 78 deletions src/adapters/interlay.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,61 @@
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 { InterlayAdapter, KintsugiAdapter } from "./interlay";
import { StatemintAdapter } from "./statemint";
import { HeikoAdapter } from "./parallel";
import { buildTestTxWithConfigData } from "../utils/shared-spec-methods";

// helper method for getting balances, configs, fees, and constructing xcm extrinsics
async function runMyTestSuite(testAccount: string, bridge: Bridge, from: ChainName, to: ChainName, token: string) {
const {fromBalance, toBalance, inputConfig, destFee, tx} = await buildTestTxWithConfigData(testAccount, bridge, from, to, token);

// from balance prints/checks
console.log(
`balance ${token}: free-${fromBalance.free.toNumber()} locked-${fromBalance.locked.toNumber()} available-${fromBalance.available.toNumber()}`
);
expect(fromBalance.available.toNumber()).toBeGreaterThanOrEqual(0);
expect(fromBalance.free.toNumber()).toBeGreaterThanOrEqual(
fromBalance.available.toNumber()
);
expect(fromBalance.free.toNumber()).toEqual(
fromBalance.locked.add(fromBalance.available).toNumber()
);

// toBalance prints/checks
console.log(
`balance at destination ${token}: free-${toBalance.free.toNumber()} locked-${toBalance.locked.toNumber()} available-${toBalance.available.toNumber()}`
);

// inputConfig prints/checks
console.log(
`inputConfig: min-${inputConfig.minInput.toNumber()} max-${inputConfig.maxInput.toNumber()} ss58-${
inputConfig.ss58Prefix
} estimateFee-${inputConfig.estimateFee}`
);
expect(inputConfig.minInput.toNumber()).toBeGreaterThan(0);
expect(inputConfig.maxInput.toNumber()).toBeLessThanOrEqual(
fromBalance.available.toNumber()
);

// destFee prints/checks
console.log(
`destFee: fee-${destFee.balance.toNumber()} ${destFee.token}`
);
if (to === "polkadot") {
expect(destFee.balance.toNumber()).toEqual(0.1);
} else {
expect(destFee.balance.toNumber()).toBeGreaterThan(0);
}

// tx method & params checks
expect(tx.method.section).toEqual("xTokens");
expect(tx.args.length).toEqual(4);
expect(tx.method.method).toEqual("transfer");
};

describe.skip("interlay-adapter should work", () => {
jest.setTimeout(30000);
Expand All @@ -19,6 +68,31 @@ describe.skip("interlay-adapter should work", () => {
return firstValueFrom(provider.connectFromChain(chains, undefined));
}

test("connect kintsugi to do xcm", async () => {
const fromChains = ["kintsugi", "heiko"] as ChainName[];

await connect(fromChains);

const kintsugi = new KintsugiAdapter();
const heiko = new HeikoAdapter();

await kintsugi.setApi(provider.getApi(fromChains[0]));
await heiko.setApi(provider.getApi(fromChains[1]));

const bridge = new Bridge({
adapters: [kintsugi, heiko],
});

expect(
bridge.router.getDestinationChains({
from: chains.kintsugi,
token: "KBTC",
}).length
).toEqual(1);

await runMyTestSuite(testAccount, bridge, "kintsugi", "heiko", "KBTC");
});

test("connect interlay to do xcm", async () => {
const fromChains = ["interlay", "polkadot", "statemint"] as ChainName[];

Expand Down Expand Up @@ -50,81 +124,7 @@ describe.skip("interlay-adapter should work", () => {
}).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 toAdapter = bridge.findAdapter(to);
const toBalance = await firstValueFrom(
toAdapter.subscribeTokenBalance(token, testAccount)
);
console.log(
`balance at destination ${token}: free-${toBalance.free.toNumber()} locked-${toBalance.locked.toNumber()} available-${toBalance.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
} estimateFee-${inputConfig.estimateFee}`
);
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);
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");
await runMyTestSuite(testAccount, bridge, "interlay", "polkadot", "DOT");
await runMyTestSuite(testAccount, bridge, "interlay", "statemint", "USDT");
});
});
11 changes: 11 additions & 0 deletions src/adapters/interlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ export const kintsugiRoutersConfig: Omit<CrossChainRouterConfigs, "from">[] = [
weightLimit: DEST_WEIGHT,
},
},
{
to: "heiko",
token: "KBTC",
xcm: {
// from local tests on choptsicks: actual fees sat around 103
fee: { token: "KBTC", amount: "200" },
weightLimit: DEST_WEIGHT,
},
},
];

export const interlayTokensConfig: Record<
Expand All @@ -68,11 +77,13 @@ export const interlayTokensConfig: Record<
kintsugi: {
KSM: { name: "KSM", symbol: "KSM", decimals: 12, ed: "0" },
USDT: { name: "USDT", symbol: "USDT", decimals: 6, ed: "0" },
KBTC: { name: "KBTC", symbol: "KBTC", decimals: 8, ed: "0" },
},
};

const KINTSUGI_SUPPORTED_TOKENS: Record<string, unknown> = {
KSM: { Token: "KSM" },
KBTC: { Token: "KBTC" },
USDT: { ForeignAsset: 3 },
};

Expand Down
115 changes: 115 additions & 0 deletions src/adapters/parallel.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { firstValueFrom } from "rxjs";

import { ApiProvider } from "../api-provider";
import { chains, ChainName } from "../configs";
import { Bridge } from "..";
import { KintsugiAdapter } from "./interlay";
import { HeikoAdapter } from "./parallel";
import { buildTestTxWithConfigData } from "../utils/shared-spec-methods";

// helper method for getting balances, configs, fees, and constructing xcm extrinsics
async function runMyTestSuite(testAccount: string, bridge: Bridge, from: ChainName, to: ChainName, token: string) {
const {fromBalance, toBalance, inputConfig, destFee, tx} = await buildTestTxWithConfigData(testAccount, bridge, from, to, token);

// from balance prints/checks
console.log(
`balance ${token}: free-${fromBalance.free.toNumber()} locked-${fromBalance.locked.toNumber()} available-${fromBalance.available.toNumber()}`
);
expect(fromBalance.available.toNumber()).toBeGreaterThanOrEqual(0);
expect(fromBalance.free.toNumber()).toBeGreaterThanOrEqual(
fromBalance.available.toNumber()
);
expect(fromBalance.free.toNumber()).toEqual(
fromBalance.locked.add(fromBalance.available).toNumber()
);

// toBalance prints/checks
console.log(
`balance at destination ${token}: free-${toBalance.free.toNumber()} locked-${toBalance.locked.toNumber()} available-${toBalance.available.toNumber()}`
);

// inputConfig prints/checks
console.log(
`inputConfig: min-${inputConfig.minInput.toNumber()} max-${inputConfig.maxInput.toNumber()} ss58-${
inputConfig.ss58Prefix
} estimateFee-${inputConfig.estimateFee}`
);
expect(inputConfig.minInput.toNumber()).toBeGreaterThan(0);
expect(inputConfig.maxInput.toNumber()).toBeLessThanOrEqual(
fromBalance.available.toNumber()
);

// destFee prints/checks
console.log(
`destFee: fee-${destFee.balance.toNumber()} ${destFee.token}`
);
expect(destFee.balance.toNumber()).toBeGreaterThan(0);

// tx method & params checks
expect(tx.method.section).toEqual("xTokens");
expect(tx.args.length).toEqual(4);
expect(tx.method.method).toEqual("transfer");
};

describe.skip("parallel-adapter should work", () => {
jest.setTimeout(30000);

// alice
const testAccount = "hJKzPoi3MQnSLvbShxeDmzbtHncrMXe5zwS3Wa36P6kXeNpcv";
const provider = new ApiProvider("mainnet");

async function connect(chains: ChainName[]) {
return firstValueFrom(provider.connectFromChain(chains, undefined));
}

test("connect parallel-heiko to do xcm", async () => {
const fromChains = ["heiko", "kintsugi"] as ChainName[];

await connect(fromChains);

const heiko = new HeikoAdapter();
const kintsugi = new KintsugiAdapter();

await heiko.setApi(provider.getApi(fromChains[0]));
await kintsugi.setApi(provider.getApi(fromChains[1]));

const bridge = new Bridge({
adapters: [heiko, kintsugi],
});

expect(
bridge.router.getDestinationChains({
from: chains.heiko,
token: "KBTC",
}).length
).toEqual(1);

await runMyTestSuite(testAccount, bridge, "heiko", "kintsugi", "KBTC");
});

// in preparation for later addition of parallel <-> interlay XCM
// test("connect parallel to do xcm", async () => {
// const fromChains = ["parallel", "interlay"] as ChainName[];

// await connect(fromChains);

// const parallel = new ParallelAdapter();
// const interlay = new InterlayAdapter();

// await parallel.setApi(provider.getApi(fromChains[0]));
// await interlay.setApi(provider.getApi(fromChains[1]));

// const bridge = new Bridge({
// adapters: [parallel, interlay],
// });

// expect(
// bridge.router.getDestinationChains({
// from: chains.interlay,
// token: "IBTC",
// }).length
// ).toEqual(1);

// await runMyTestSuite(testAccount, bridge, "parallel", "interlay", "IBTC");
// });
});
Loading