npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xcm-router/sdk

v0.1.2

Published

XRoute integration SDK for route discovery, source-chain execution, and hosted intent status tracking.

Readme

@xcm-router/sdk

XRoute is a multihop cross-chain execution router on Polkadot that gives apps one SDK to transfer assets, swap, and execute calls across Polkadot Hub, Hydration, Moonbeam, and other supported routes.

@xcm-router/sdk is the integration package for XRoute.

Intent Surface

Supported intent surface:

  • transfer: move one supported asset from a source chain to a recipient on a destination chain.
  • swap: route an input asset from the source chain and receive a different asset on the destination path.
  • execute: pay to perform a supported action on the destination chain.
    • call: execute contract calldata on the destination chain.

Install

npm install @xcm-router/sdk

Main Setup

import { createXRouteClient } from "@xcm-router/sdk";

const client = createXRouteClient({
  apiKey: process.env.XROUTE_API_KEY,
});

Leave the apiKey field empty to use at no cost with limits. If you need more usage, pls reach [email protected] to discuss usage.

Wallet Connection

For quote-only usage, no wallet connection is needed.

For source-chain execution, connect the user's source wallet:

client.connectWallet("evm", {
  provider: window.ethereum,
  chainKey: "moonbeam",
});

or:

client.connectWallet("substrate", {
  extension: injectedExtension,
  chainKey: "hydration",
});

You can still pass an XRoute-compatible wallet connector object directly when needed.

Quote

quote(...) accepts the same high-level request shapes used by transfer(...), swap(...), and call(...).

const { intent, quote } = await client.quote({
  sourceChain: "moonbeam",
  destinationChain: "hydration",
  ownerAddress: "0x1111111111111111111111111111111111111111",
  assetIn: "DOT",
  assetOut: "USDT",
  amountIn: "1000000000000",
  minAmountOut: "490000000",
  settlementChain: "polkadot-hub",
  recipient: "0x1111111111111111111111111111111111111111",
});

All asset amount fields are base-unit integers as strings.

  • DOT: 1 DOT -> "10000000000"
  • USDT (6 decimals): 49 USDT -> "49000000"

Transfer

transfer(...) is the high-level helper for transfer intents.

const execution = await client.transfer({
  sourceChain: "polkadot-hub",
  destinationChain: "hydration",
  asset: "DOT",
  amount: "10000000000",
  recipient: "5Frecipient",
});

The SDK fills:

  • deploymentProfile
  • senderAddress
  • refundAddress through the connected wallet
  • a default deadline if you do not provide one

Swap

const execution = await client.swap({
  sourceChain: "moonbeam",
  destinationChain: "hydration",
  assetIn: "DOT",
  assetOut: "USDT",
  amountIn: "1000000000000",
  minAmountOut: "490000000",
  settlementChain: "polkadot-hub",
  recipient: "0x1111111111111111111111111111111111111111",
});

Execute (call)

const execution = await client.call({
  sourceChain: "hydration",
  destinationChain: "moonbeam",
  asset: "DOT",
  maxPaymentAmount: "200000000",
  contractAddress: "0x2222222222222222222222222222222222222222",
  calldata: "0xdeadbeef",
  value: "0",
  gasLimit: "250000",
  fallbackWeight: {
    refTime: 650000000,
    proofSize: 12288,
  },
});

runFlow(...)

runFlow(...) is the high-level helper for sequencing multiple intents.

It is not one atomic onchain batch.

Each step is still:

  • quoted independently
  • submitted independently
  • dispatched independently
  • awaited independently
const flow = await client.runFlow({
  steps: [
    {
      name: "swap",
      intent: {
        sourceChain: "moonbeam",
        destinationChain: "hydration",
        refundAddress: "0x1111111111111111111111111111111111111111",
        deadline: 1773185200,
        action: {
          type: "swap",
          params: {
            assetIn: "DOT",
            assetOut: "USDT",
            amountIn: "1000000000000",
            minAmountOut: "490000000",
            settlementChain: "polkadot-hub",
            recipient: "0x1111111111111111111111111111111111111111",
          },
        },
      },
    },
    {
      name: "call",
      intent: {
        sourceChain: "hydration",
        destinationChain: "moonbeam",
        refundAddress: "0x1111111111111111111111111111111111111111",
        deadline: 1773185200,
        action: {
          type: "execute",
          params: {
            executionType: "call",
            asset: "DOT",
            maxPaymentAmount: "200000000",
            contractAddress: "0x2222222222222222222222222222222222222222",
            calldata: "0xdeadbeef",
            value: "0",
            gasLimit: "250000",
            fallbackWeight: {
              refTime: 650000000,
              proofSize: 12288,
            },
          },
        },
      },
    },
  ],
});

Status And Timeline

Hosted status lookups do not require a wallet connection:

const status = await client.getStatus(intentId);
const timeline = await client.getTimeline(intentId);
const finalStatus = await client.wait(intentId);

For polling-based tracking:

const tracker = client.track(intentId, {
  pollIntervalMs: 1000,
  onUpdate(snapshot) {
    console.log(snapshot.status?.status);
  },
});

const finalStatus = await tracker.done;

Form Options From The SDK

Use the SDK to drive chain, asset, and route options:

import {
  listChains,
  listAssets,
  getChainWalletType,
  getAssetDecimals,
  parseAssetAmount,
  formatAssetAmount,
} from "@xcm-router/sdk/chains";
import {
  getTransferOptions,
  getSwapOptions,
  getExecuteOptions,
} from "@xcm-router/sdk/routes";

These helpers are the intended source of truth for UI option state.

listChains() returns the chain catalog.

[
  { key: "moonbeam", label: "Moonbeam", ... },
  { key: "hydration", label: "Hydration", ... },
]

listAssets() returns the asset catalog, not route-filtered form options.

[
  { symbol: "DOT", decimals: 10, supportedChains: ["polkadot-hub", "hydration", "moonbeam"] },
]

getChainWalletType(chainKey) tells you which wallet UX to show for a selected source chain.

getChainWalletType("moonbeam"); // "evm"
getChainWalletType("hydration"); // "substrate"

getAssetDecimals(assetKey) gives you the asset precision. parseAssetAmount(...) and formatAssetAmount(...) are the SDK helpers for converting between human form values and base units.

getTransferOptions(sourceChain) returns transfer-valid destinations for the selected source chain.

[
  {
    chain: "hydration",
    label: "Hydration",
    assets: ["DOT", "USDT"],
  },
]

getSwapOptions(sourceChain) returns swap-valid destinations and pairs.

[
  {
    chain: "hydration",
    label: "Hydration",
    pairs: [
      {
        assetIn: "DOT",
        assetOut: "USDT",
        settlementChains: ["polkadot-hub"],
      },
    ],
  },
]

getExecuteOptions(sourceChain) returns execute-valid destinations and capabilities.

[
  {
    chain: "moonbeam",
    label: "Moonbeam",
    capabilities: [
      {
        executionType: "call",
        assets: ["DOT"],
      },
    ],
  },
]

Typical form flow:

const chains = listChains();
const sourceChain = chains[0].key;
const walletType = getChainWalletType(sourceChain);

const transferDestinations = getTransferOptions(sourceChain);
const destinationChain = transferDestinations[0].chain;
const transferAssets =
  transferDestinations.find((option) => option.chain === destinationChain)?.assets ?? [];

const decimals = getAssetDecimals(transferAssets[0]);

Use listAssets() when you need general asset metadata. Use getTransferOptions(...), getSwapOptions(...), and getExecuteOptions(...) when you need route-valid dependent selects.

Amount Conversion

The wire format still uses base-unit integers. If your UI collects human decimal input, use the SDK helpers to convert before calling the client.

Example:

import { parseAssetAmount, formatAssetAmount } from "@xcm-router/sdk/chains";

const amount = parseAssetAmount("DOT", "25");

await client.transfer({
  sourceChain: "moonbeam",
  destinationChain: "hydration",
  asset: "DOT",
  amount,
  recipient: "5Frecipient",
});

const received = formatAssetAmount("USDT", "49000000"); // "49"

Made with love ❤️ by Muwa Team.