1

安装库

使用 npm 或 yarn 安装该库:
npm install @skip-go/client
如果你使用的是 yarn(或其他默认不安装对等依赖的包管理器), 你可能还需要安装以下对等依赖:
  yarn add viem @solana/web3.js
2

初始化库

要开始集成 Skip Go API,你不再需要初始化一个 SkipClient 实例。相反,你只需配置一次库,然后直接导入并使用各个独立函数。

初始化选项

可以使用 setClientOptions 或 setApiOptions 来初始化该库。这两个函数都接受 apiUrl 和 apiKey。
  • setClientOptions(options): 如果你计划使用 executeRoute,请使用这个函数。它会配置你的 API 凭据,并允许你提供链级别的设置,例如 endpoints、Amino types 和 registry types。
  • setApiOptions(options): 如果你主要需要配置 API 交互(apiUrl、apiKey)或设置 affiliate fees(chainIdsToAffiliates),请使用这个函数。该选项不会配置 endpointOptions、aminoTypes 或 registryTypes。
你通常会在应用启动时调用其中一个函数一次。
Import and Initialize
import {
  setClientOptions,
  setApiOptions,
  chains,
  assets,
  route,
  executeRoute,
  // ... other functions you need
} from "@skip-go/client";

// Example: Initialize for executeRoute usage
setClientOptions({
  apiUrl: "YOUR_API_URL", // Optional: defaults to Skip API
  apiKey: "YOUR_API_KEY",   // Optional: required for certain features
  endpointOptions: { /* ... */ },
  // ... other options like aminoTypes, registryTypes, cacheDurationMs
});

// Example: Initialize for direct API calls (simpler, if not using executeRoute)
setApiOptions({
  apiUrl: "YOUR_API_URL", // Optional: defaults to Skip API
  apiKey: "YOUR_API_KEY",   // Optional: required for certain features
});

// Now you can call functions directly, e.g.:
// const supportedChains = await chains();

配置参数

以下是常见的配置参数。完整细节请参考 setClientOptions 或 setApiOptions 对应的 options 类型定义。
  • apiUrl?: string:覆盖默认 API URL。可以传给 setClientOptions 或 setApiOptions,如果没有调用这两个初始化函数,也可以直接传给各个 API 函数。
  • apiKey?: string:你的 Skip API key。可以传给 setClientOptions 或 setApiOptions,如果没有调用这两个初始化函数,也可以直接传给各个 API 函数。某些功能需要提供该参数。
  • endpointOptions?: EndpointOptions:为特定链提供 RPC 和 REST endpoints(由 setClientOptions 使用)。
  • aminoTypes?: AminoConverters:用于消息编码的额外 amino types(由 setClientOptions 使用)。
  • registryTypes?: Iterable<[string, GeneratedType]>:额外的 registry types(由 setClientOptions 使用)。
  • cacheDurationMs?: number:为 chains 和 assets 等函数的响应设置缓存时长,单位为毫秒(由 setClientOptions 使用)。
3

设置签名器

要执行交易,你需要为计划交互的生态系统设置签名器。下面是 Cosmos SDK、EVM 和 Solana(SVM)的示例。请注意,对于 EVM 和 SVM,你需要安装额外的库。

签名器设置

// For Cosmos transactions, we'll use Keplr wallet from the window object
const getCosmosSigner = async (chainId: string) => {
  const key = await window.keplr?.getKey(chainId);
  if (!key) throw new Error("Keplr not installed or chain not added");

  return key.isNanoLedger
        ? window.keplr?.getOfflineSignerOnlyAmino(chainId)
        : window.keplr?.getOfflineSigner(chainId);
};

4

查询基础信息

库初始化完成后,你可以使用导入的函数查询余额、支持的链以及资产。

查询示例

import { chains } from "@skip-go/client";

// returns a Chain[] of all supported Cosmos mainnet chains
const cosmosChains = await chains();

// include EVM and SVM chains
const allChains = await chains({
  includeEvm: true,
  includeSvm: true,
});

// only show testnet chains
const testnetChains = await chains({
  onlyTestnets: true
});
5

获取路由

当你选定源链、目标链以及代币后,就可以使用 route 函数生成路由并获取报价。可在这里查看其上下文中的示例。

路由示例

import { route } from "@skip-go/client";

const routeResult = await route({
  amountIn: "1000000", // Desired amount in smallest denomination (e.g., uatom)
  sourceAssetDenom: "uatom",
  sourceAssetChainId: "cosmoshub-4",
  destAssetDenom: "uosmo",
  destAssetChainId: "osmosis-1",
  cumulativeAffiliateFeeBps: '0',
});
进一步了解联盟费用、Smart Relay 和 EVM Swaps。
6

获取所需地址

生成路由后,你需要为所需链提供用户地址。route.requiredChainAddresses 数组列出了需要地址的链 ID。
只使用你的用户能够签名的地址。 某些失败情况下,你提供的任何地址(包括中间链上的地址)都可能导致资金卡住。请确保你的用户可以为你提供的每个地址签名。 更多细节请参阅跨链失败场景。
我们建议存储用户地址,并创建一个类似 getAddress 的函数,根据链 ID 获取地址。
// Assuming 'routeResult' holds the object from the route() call in Step 5
// get user addresses for each requiredChainAddress to execute the route
  const userAddresses = await Promise.all(
  routeResult.requiredChainAddresses.map(async (chainId) => ({
    chainId,
    address: await getAddress(chainId),
  }))
);
7

执行路由

拿到路由后,你可以通过一次函数调用执行它:传入路由、至少覆盖该路由所包含链的用户地址,以及可选的回调函数。这也会注册该交易以便跟踪。
await executeRoute({
  route: routeResult,
  userAddresses,
  getCosmosSigner,
  getEvmSigner,
  getSvmSigner,
  onTransactionCompleted: async ({ txHash, chainId, status}) => {
    console.log(
      `Route completed on chain ${chainId} with tx hash: ${txHash} & status: ${status?.state}`
    );
  },
  onTransactionBroadcast: async ({ txHash, chainId }) => {
    console.log(`Transaction broadcasted on ${chainId} with tx hash: ${txHash}`);
  },
  onTransactionTracked: async ({ txHash, chainId, explorerLink }) => {
    console.log(`Transaction tracked for ${chainId} with tx hash: ${txHash}, explorer: ${explorerLink}`);
  },
  onTransactionSigned: async ({ chainId }) => {
    console.log(`Transaction signed for ${chainId}`);
  },
  onValidateGasBalance: async (validation) => {
    if (validation.status === "error") {
      console.warn(`Insufficient gas balance or gas validation error on chain ${validation.chainId} (Tx Index: ${validation.txIndex}).`);
    }
  },
  onApproveAllowance: async (approvalInfo) => {
    console.log(`ERC20 allowance ${approvalInfo.status} for token ${approvalInfo.allowance?.tokenContract} on chain ${approvalInfo.allowance?.chainId}`);
  }
});
对于由多笔交易组成的路由,executeRoute 会监控每一笔交易,直到其完成,然后为下一步生成交易,并提示用户使用相应的 signer 进行签名。
或者,你也可以使用各个单独的函数手动处理消息生成、签名和提交:
  • messages:生成交易消息。
  • messagesDirect:一个便捷函数,将 /route 和 /msgs 的功能合并为一次调用。它会返回执行多链兑换或转账所需的最少消息数。
  • broadcastTx:将交易广播到网络。
  • submitTransaction:提交并跟踪交易。 关于这些更底层函数的详细信息,请参考 API 文档。
8

交易跟踪

交易注册为可跟踪后(通过 executeRoute、submitTransaction 或 trackTransaction),你可以轮询其状态:
  • 检查状态: transactionStatus - 接收 txHash 和 chainId,并返回当前的跨链状态。
    // Example of checking transaction status:
    // Assuming you have txHash and chainId from a previous step:
    // const statusResult = await transactionStatus({ txHash: "your_tx_hash", chainId: "your_chain_id" });
    // console.log("Transaction State:", statusResult.state);
    // console.log("Full Status Response:", statusResult);
    // Possible states include: STATE_COMPLETED_SUCCESS, STATE_COMPLETED_ERROR, STATE_ABANDONED, STATE_PENDING_CONFIRMATION, STATE_PENDING_EXECUTION, etc.
    // Refer to the TxStatusResponse type or API documentation for a complete list of states.
    
请记住,如果你使用 executeRoute(步骤 7),它会自动处理交易生命周期,包括等待完成。手动跟踪函数(submitTransaction、trackTransaction、transactionStatus)主要适用于你不使用 executeRoute 进行完整执行的场景(例如直接使用 submitTransaction),或者你需要对跟踪和状态轮询过程进行更细粒度控制的情况。
有问题或反馈?帮助我们做得更好!加入我们的 Discord,并选择 “Skip Go Developer” 角色来分享你的问题和反馈。

1

Install Library

Install the library using npm or yarn:
npm install @skip-go/client
If you’re using yarn (or another package manager that doesn’t install peer dependencies by default) you may need to install these peer dependencies as well:
  yarn add viem @solana/web3.js
2

Initialize Library

To start integrating with the Skip Go API, you no longer initialize a SkipClient instance. Instead, you configure the library once and then import and use individual functions directly.

Initialization Options

The library can be initialized using setClientOptions or setApiOptions. Both functions accept apiUrl and apiKey.
  • setClientOptions(options): Use this if you plan to use executeRoute. It configures your API credentials and lets you provide chain-specific settings like endpoints, Amino types, and registry types.
  • setApiOptions(options): Use this if you primarily need to configure API interaction (apiUrl, apiKey) or set up affiliate fees (chainIdsToAffiliates). This option does not configure endpointOptions, aminoTypes, or registryTypes.
You typically call one of these functions once at application startup.
Import and Initialize
import {
  setClientOptions,
  setApiOptions,
  chains,
  assets,
  route,
  executeRoute,
  // ... other functions you need
} from "@skip-go/client";

// Example: Initialize for executeRoute usage
setClientOptions({
  apiUrl: "YOUR_API_URL", // Optional: defaults to Skip API
  apiKey: "YOUR_API_KEY",   // Optional: required for certain features
  endpointOptions: { /* ... */ },
  // ... other options like aminoTypes, registryTypes, cacheDurationMs
});

// Example: Initialize for direct API calls (simpler, if not using executeRoute)
setApiOptions({
  apiUrl: "YOUR_API_URL", // Optional: defaults to Skip API
  apiKey: "YOUR_API_KEY",   // Optional: required for certain features
});

// Now you can call functions directly, e.g.:
// const supportedChains = await chains();

Configuration Parameters

Below are the common configuration parameters. Refer to the specific options type for setClientOptions or setApiOptions for full details.
  • apiUrl?: string: Override the default API URL. Can be passed to setClientOptions or setApiOptions, or directly to individual API functions if neither initialization function is called.
  • apiKey?: string: Your Skip API key. Can be passed to setClientOptions or setApiOptions, or directly to individual API functions if neither initialization function is called. Required for certain features.
  • endpointOptions?: EndpointOptions: Provide RPC and REST endpoints for specific chains (used by setClientOptions).
  • aminoTypes?: AminoConverters: Additional amino types for message encoding (used by setClientOptions).
  • registryTypes?: Iterable<[string, GeneratedType]>: Additional registry types (used by setClientOptions).
  • cacheDurationMs?: number: Duration in milliseconds to cache responses for functions like chains and assets (used by setClientOptions).
3

Setup Signers

To execute transactions, you need to set up signers for the ecosystems you plan to interact with. Below are examples for Cosmos SDK, EVM, and Solana (SVM). Note that for EVM and SVM, you’ll need to install additional libraries.

Signer Setup

// For Cosmos transactions, we'll use Keplr wallet from the window object
const getCosmosSigner = async (chainId: string) => {
  const key = await window.keplr?.getKey(chainId);
  if (!key) throw new Error("Keplr not installed or chain not added");

  return key.isNanoLedger
        ? window.keplr?.getOfflineSignerOnlyAmino(chainId)
        : window.keplr?.getOfflineSigner(chainId);
};

4

Query Basic Info

With the library initialized, you can query balances, supported chains and assets using the imported functions.

Query Examples

import { chains } from "@skip-go/client";

// returns a Chain[] of all supported Cosmos mainnet chains
const cosmosChains = await chains();

// include EVM and SVM chains
const allChains = await chains({
  includeEvm: true,
  includeSvm: true,
});

// only show testnet chains
const testnetChains = await chains({
  onlyTestnets: true
});
5

Get a Route

Once you’ve selected your source and destination chains and tokens, you can generate a route and get a quote using the route function. See it in context here.

Route Examples

import { route } from "@skip-go/client";

const routeResult = await route({
  amountIn: "1000000", // Desired amount in smallest denomination (e.g., uatom)
  sourceAssetDenom: "uatom",
  sourceAssetChainId: "cosmoshub-4",
  destAssetDenom: "uosmo",
  destAssetChainId: "osmosis-1",
  cumulativeAffiliateFeeBps: '0',
});
Read more about affiliate fees, Smart Relay and EVM Swaps.
6

Get Required Addresses

After generating a route, you need to provide user addresses for the required chains. The route.requiredChainAddresses array lists the chain IDs for which addresses are needed.
Only use addresses your user can sign for. Funds could get stuck in any address you provide, including intermediate chains in certain failure conditions. Ensure your user can sign for each address you provide. See Cross-chain Failure Cases for more details.
We recommend storing the user’s addresses and creating a function like getAddress that retrieves the address based on the chain ID.
// Assuming 'routeResult' holds the object from the route() call in Step 5
// get user addresses for each requiredChainAddress to execute the route
  const userAddresses = await Promise.all(
  routeResult.requiredChainAddresses.map(async (chainId) => ({
    chainId,
    address: await getAddress(chainId),
  }))
);
7

Execute the Route

Once you have a route, you can execute it in a single function call by passing in the route, the user addresses for at least the chains the route includes, and optional callback functions. This also registers the transaction for tracking.
await executeRoute({
  route: routeResult,
  userAddresses,
  getCosmosSigner,
  getEvmSigner,
  getSvmSigner,
  onTransactionCompleted: async ({ txHash, chainId, status}) => {
    console.log(
      `Route completed on chain ${chainId} with tx hash: ${txHash} & status: ${status?.state}`
    );
  },
  onTransactionBroadcast: async ({ txHash, chainId }) => {
    console.log(`Transaction broadcasted on ${chainId} with tx hash: ${txHash}`);
  },
  onTransactionTracked: async ({ txHash, chainId, explorerLink }) => {
    console.log(`Transaction tracked for ${chainId} with tx hash: ${txHash}, explorer: ${explorerLink}`);
  },
  onTransactionSigned: async ({ chainId }) => {
    console.log(`Transaction signed for ${chainId}`);
  },
  onValidateGasBalance: async (validation) => {
    if (validation.status === "error") {
      console.warn(`Insufficient gas balance or gas validation error on chain ${validation.chainId} (Tx Index: ${validation.txIndex}).`);
    }
  },
  onApproveAllowance: async (approvalInfo) => {
    console.log(`ERC20 allowance ${approvalInfo.status} for token ${approvalInfo.allowance?.tokenContract} on chain ${approvalInfo.allowance?.chainId}`);
  }
});
For routes that consist of multiple transactions, executeRoute will monitor each transaction until it completes, then generate the transaction for the next step and prompt the user to sign it using the appropriate signer.
Alternatively, you can handle message generation, signing, and submission manually using the individual functions:
  • messages: Generate transaction messages.
  • messagesDirect: A convenience function that combines the functionality of /route and /msgs into a single call. It returns the minimal number of messages required to execute a multi-chain swap or transfer.
  • broadcastTx: Broadcast transactions to the network.
  • submitTransaction: Submit and track transactions. Refer to the API documentation for details on these lower-level functions.
8

Transaction Tracking

After a transaction is registered for tracking (either via executeRoute, submitTransaction, or trackTransaction), you can poll for its status:
  • Check Status: transactionStatus - Takes a txHash and chainId and returns the current cross-chain status.
    // Example of checking transaction status:
    // Assuming you have txHash and chainId from a previous step:
    // const statusResult = await transactionStatus({ txHash: "your_tx_hash", chainId: "your_chain_id" });
    // console.log("Transaction State:", statusResult.state);
    // console.log("Full Status Response:", statusResult);
    // Possible states include: STATE_COMPLETED_SUCCESS, STATE_COMPLETED_ERROR, STATE_ABANDONED, STATE_PENDING_CONFIRMATION, STATE_PENDING_EXECUTION, etc.
    // Refer to the TxStatusResponse type or API documentation for a complete list of states.
    
Remember, if you use executeRoute (Step 7), it automatically handles the transaction lifecycle, including waiting for completion. The manual tracking functions (submitTransaction, trackTransaction, transactionStatus) are primarily for scenarios where you are not using executeRoute for full execution (e.g., if you use submitTransaction directly) or if you need more granular control over the tracking and status polling process.
Have questions or feedback? Help us get better!Join our Discord and select the “Skip Go Developer” role to share your questions and feedback.