Security News
tea.xyz Spam Plagues npm and RubyGems Package Registries
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
@interlay/bridge
Advanced tools
Readme
Polkadot bridge SDK for multi-chain cross-chain token transfer.
You can integrate the amazing multi-chain bridge into your DApp with this SDK.
And you're welcome to add your parachain-adapter into the SDK.
All channels support transfers in both directions.
channel | tokens |
---|---|
acala | INTR IBTC |
astar | INTR IBTC |
bifrost | BNC VDOT |
parallel | INTR IBTC |
polkadot | DOT |
polkadot asset hub | USDT |
hydradx | HDX IBTC |
channel | tokens |
---|---|
bifrost | VKSM |
heiko | KBTC KINT |
karura | KBTC KINT LKSM |
kusama | KSM |
kusama asset hub | USDT |
channel | tokens |
---|---|
polkadot asset hub | DOT |
channel | tokens |
---|---|
kusama asset hub | KSM |
Example: src/bridge.spec.ts
/// import any parachain-adapters you want in your bridge.
const availableAdapters: Record<string, BaseCrossChainAdapter> = {
polkadot: new PolkadotAdapter(),
// kusama: new KusamaAdapter(),
acala: new AcalaAdapter(),
// karura: new KaruraAdapter(),
// statemine: new StatemineAdapter(),
// bifrost: new BifrostAdapter(),
// ...
};
/// create your bridge instance and pass the adapters to it.
const bridge = new Bridge({
adapters: Object.values(availableAdapters),
});
Then you can get the bridge routers:
const allRouters = bridge.router.getRouters();
/// or the available routers (some may temporarily unavailable)
const availableRouters = bridge.router.getAvailableRouters();
/// and get filtered routers
const destChains = bridge.router.getDestinationChains({ from: "interlay" });
const tokens = bridge.router.getAvailableTokens({
from: "interlay",
to: "polkadot",
});
You can use the ApiProvider
of the SDK which can connect to all the parachains https://polkadot.js.org/apps supported,
or you can use your own apiProvider.
import { ApiProvider } from "./api-provider";
const provider = new ApiProvider();
Connect network and pass the ApiPromise | ApiRx
into the adapters.
// list all available from-chains
const chains = Object.keys(availableAdapters) as ChainName[];
// connect all adapters
const connected = await firstValueFrom(
provider.connectFromChain(chains, undefined)
);
// and set `ApiPromise | ApiRx` for each adapter
await Promise.all(
chains.map((chain) => availableAdapters[chain].setApi(provider.getApi(chain)))
);
/// balance query
const balance = await firstValueFrom(
adapter.subscribeTokenBalance(token, testAccount)
);
/// and you may want to use the inputConfig provided by the SDK
/// to limit user's transfer amount input
const inputConfig = await firstValueFrom(
adapter.subscribeInputConfigs({
to: toChain,
token,
address: toAddress,
signer,
})
);
console.log(
inputConfig.minInput,
inputConfig.maxInput,
inputConfig.destFee,
inputConfig.estimateFee,
inputConfig.ss58Prefix
);
/// create tx & send
const tx = adapter.createTx({
amount: FixedPointNumber.fromInner("10000000000", 10),
to: "polkadot",
token: "DOT",
address: toAddress,
signer: testAccount,
});
tx.signAndSend(keyPair, { tip: "0" }, onStatusChangecCallback);
Add a new item in src/configs/chains/polkadot-chains.ts
or src/configs/chains/kusama-chains.ts
.
/// karura for example
{
karura: {
id: 'karura',
display: 'Karura',
icon: 'https://resources.acala.network/networks/karura.png',
paraChainId: 2000,
ss58Prefix: 8
}
/// ...other parachains
}
Add a new adapter file in src/adapters/
, and create your ParachainAdapter
class extends BaseCrossChainAdapter
.
Example: src/adapters/bifrost.ts
/// bifrost for example
export const bifrostTokensConfig: Record<string, MultiChainToken> = {
BNC: { name: "BNC", symbol: "BNC", decimals: 12, ed: "10000000000" },
VSKSM: { name: "VSKSM", symbol: "VSKSM", decimals: 12, ed: "100000000" },
/// ...other tokens
};
export const bifrostRoutersConfig: Omit<CrossChainRouterConfigs, "from">[] = [
/// router for token `BNC` from `bifrost` to `karura`,
/// `xcm.fee` defines the XCM-Fee on karura,
/// `xcm.weightLimit` defines the weightLimit value used creating Extrinsic.
{
to: "karura",
token: "BNC",
xcm: {
fee: { token: "BNC", amount: "932400000" },
weightLimit: "Unlimited",
},
},
/// router for token `KUSD` from `bifrost` to `karura`
{
to: "karura",
token: "KUSD",
xcm: {
fee: { token: "KUSD", amount: "3826597686" },
weightLimit: "Unlimited",
},
},
];
subscribeTokenBalance()
Implement the subscribeTokenBalance
method so the bridge can query token balances.
/// 1. create `BifrostBalanceAdapter` extends `BalanceAdapter`.
class BifrostBalanceAdapter extends BalanceAdapter {
private storages: ReturnType<typeof createBalanceStorages>;
constructor ({ api, chain, tokens }: BalanceAdapterConfigs) {
super({ api, chain, tokens });
this.storages = createBalanceStorages(api);
}
public subscribeBalance (token: string, address: string): Observable<BalanceData> {
/// ...balance queries
}
}
/// 2. we use a `createBalanceStorages` function with acala `Storage` utils
/// for token balance queries here.
function createBalanceStorages(api: AnyApi) => {
return {
/// balances for native-token (BNC for bifrost)
balances: (address: string) =>
Storage.create<any>({
api,
path: 'query.system.account',
params: [address]
}),
/// assets for non-native-token (KUSD for bifrost)
assets: (tokenId: string, address: string) =>
Storage.create<any>({
api,
path: 'query.tokens.accounts',
params: [tokenId, address]
})
};
};
/// 3. implement the `subscribeTokenBalance` method
class BaseBifrostAdapter extends BaseCrossChainAdapter {
private balanceAdapter?: BifrostBalanceAdapter;
public subscribeTokenBalance (token: string, address: string): Observable<BalanceData> {
return this.balanceAdapter.subscribeBalance(token, address);
}
}
subscribeMaxInput()
Implement the subscribeMaxInput
method so the bridge can set transferable token amount limit.
/// maxInput = availableBalance - estimatedFee - existentialDeposit
class BaseBifrostAdapter extends BaseCrossChainAdapter {
public subscribeMaxInput(
token: string,
address: string,
to: ChainName
): Observable<FN> {
return combineLatest({
txFee:
token === this.balanceAdapter?.nativeToken ? this.estimateTxFee() : "0",
balance: this.balanceAdapter
.subscribeBalance(token, address)
.pipe(map((i) => i.available)),
}).pipe(
map(({ balance, txFee }) => {
const tokenMeta = this.balanceAdapter?.getToken(token);
const feeFactor = 1.2;
const fee = FN.fromInner(txFee, tokenMeta?.decimals).mul(
new FN(feeFactor)
);
return balance
.minus(fee)
.minus(FN.fromInner(tokenMeta?.ed || "0", tokenMeta?.decimals));
})
);
}
}
createTx()
Implement the createTx
method so the bridge can create the cross-chain transfer Extrinsic.
/// maxInput = availableBalance - estimatedFee - existentialDeposit
class BaseBifrostAdapter extends BaseCrossChainAdapter {
public createTx(
params: CrossChainTransferParams
):
| SubmittableExtrinsic<"promise", ISubmittableResult>
| SubmittableExtrinsic<"rxjs", ISubmittableResult> {
const { address, amount, to, token } = params;
const toChain = chains[to];
const accountId = this.api?.createType("AccountId32", address).toHex();
const tokenId = SUPPORTED_TOKENS[token];
if (!tokenId) {
throw new CurrencyNotFound(token);
}
return this.api.tx.xTokens.transfer(
tokenId,
amount.toChainData(),
{
V1: {
parents: 1,
interior: {
X2: [
{ Parachain: toChain.paraChainId },
{ AccountId32: { id: accountId, network: "Any" } },
],
},
},
},
this.getDestWeight(token, to)?.toString()
);
}
}
/// `chains.bifrost` is the config you added in step 1.
/// `bifrostRoutersConfig` & `bifrostTokensConfig` is the config you defined in step 2.1.
export class BifrostAdapter extends BaseBifrostAdapter {
constructor() {
super(chains.bifrost, bifrostRoutersConfig, bifrostTokensConfig);
}
}
And you are all set now!
You can import your ParachainAdapter
into src/bridge.spec.ts to test your adapter.
run testing with
yarn test
.
And remember to run yarn lint
before commit your code.
TODO
FAQs
polkawallet bridge sdk
The npm package @interlay/bridge receives a total of 4 weekly downloads. As such, @interlay/bridge popularity was classified as not popular.
We found that @interlay/bridge demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
Security News
As cyber threats become more autonomous, AI-powered defenses are crucial for businesses to stay ahead of attackers who can exploit software vulnerabilities at scale.
Security News
UnitedHealth Group disclosed that the ransomware attack on Change Healthcare compromised protected health information for millions in the U.S., with estimated costs to the company expected to reach $1 billion.