如需更深入的指南,请查看我们的详细上手指南,其中涵盖了 Solana 和 EVM 交易。你也可以进一步了解 EVM 交易,或深入查看 SVM 交易 的具体细节。

前置条件

  • 已安装 Keplr 的浏览器环境(推荐使用 create-next-app)
  • Node.js 和 npm
1

安装库

使用 npm 或 yarn 安装该库:
npm install @skip-go/client
2

初始化客户端

要开始集成 Skip Go API,请先使用 setClientOptions 或 setApiOptions 对该库进行一次性配置。完成配置后,你可以直接导入并调用 route 和 executeRoute 等函数。
import {
  setClientOptions,
  setApiOptions,
  route,
  executeRoute,
  // ...other helpers you might use
} from "@skip-go/client";

// Example initialization for executeRoute usage
setClientOptions({
  apiUrl: "YOUR_API_URL", // optional: defaults to Skip API
  apiKey: "YOUR_API_KEY", // optional: required for some features
  // endpointOptions, aminoTypes, registryTypes, etc.
});

// If only calling API functions directly, you can instead use:
setApiOptions({ apiUrl: "YOUR_API_URL", apiKey: "YOUR_API_KEY" });
3

获取路由

现在,我们可以使用 route 函数请求报价和路由,将 Noble 上的 USDC 交换为 Celestia 上的 TIA。
const routeResult = await route({
  sourceAssetDenom: 'uusdc',
  sourceAssetChainID: 'noble-1',
  destAssetDenom: 'utia',
  destAssetChainID: 'celestia',
  amountIn: '1000000', // 1 uusdc
  smartRelay: true
});
理解路由响应路由响应包含与交换流程相关的重要信息:
  • amountOut:用户在交换后预计收到的数量,已扣除所有费用和价格影响
  • requiredChainAddresses:生成交易时需要提供用户地址的链 ID
  • operations:从源代币移动到目标代币所涉及的步骤
更多详情请参阅 /route 端点参考。
4

获取所需地址

生成路由后,你需要为所需链提供用户地址。routeResult.requiredChainAddresses 数组列出了需要地址的链 ID。
仅使用用户能够签名的地址。 在某些失败情况下,资金可能会滞留在你提供的任意地址中,包括中间链地址。请确保用户能够为你提供的每个地址签名。 更多详情请参阅跨链失败场景。
我们建议存储用户地址,并创建一个类似 getAddress 的函数,根据链 ID 获取对应地址(示例见这里)。
// 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),
  }))
);
绝不要尝试根据一条链上的地址推导另一条链上的地址每当你需要用户地址时,请从对应的钱包或签名器获取。不要尝试使用 bech32 进行跨链地址推导。如果你尝试根据一条链上的地址推导另一条链上的地址,而这两条链的地址推导过程不同,那么你可能会得到一个用户实际上无法签名的地址。例如,如果你根据 Ethereum 地址推导 Cosmos 地址,你将得到一个用户无法签名的地址,从而带来代币丢失的风险。
5

执行路由

获得路由后,你可以通过一次函数调用来执行它:传入路由、至少覆盖该路由所涉及链的用户地址,以及可选的回调函数。这样也会注册该交易以便跟踪。
await executeRoute({
  route: routeResult,
  userAddresses,
  getCosmosSigner: (chainId) => {},
  getEvmSigner: (chainId) => {},
  getSvmSigner: () => {},
  // Executes after all of the operations triggered by a user's signature complete.
  onTransactionCompleted: async (chainID, txHash, status) => {
    console.log(
      `Route completed with tx hash: ${txHash} & status: ${status.state}`
    );
  },
  onTransactionBroadcast: async ({ txHash, chainID }) => {
    console.log(`Transaction broadcasted with tx hash: ${txHash}`);
  },
  onTransactionTracked: async ({ txHash, chainID }) => {
    console.log(`Transaction tracked with tx hash: ${txHash}`);
  },
});
交易完成后,你的 Celestia 地址中就会新增 TIA。

For a more in-depth guide, check out our detailed walkthrough, which covers both Solana and EVM transactions. You can also explore more about EVM Transactions or dive into the specifics of SVM Transactions.

Prerequisites

  • Browser environment setup with Keplr installed (create-next-app is recommended)
  • Node.js and npm
1

Install Library

Install the library using npm or yarn:
npm install @skip-go/client
2

Initialize Client

To start integrating with the Skip Go API, configure the library once using setClientOptions or setApiOptions. After configuration, you import and call functions like route and executeRoute directly.
import {
  setClientOptions,
  setApiOptions,
  route,
  executeRoute,
  // ...other helpers you might use
} from "@skip-go/client";

// Example initialization for executeRoute usage
setClientOptions({
  apiUrl: "YOUR_API_URL", // optional: defaults to Skip API
  apiKey: "YOUR_API_KEY", // optional: required for some features
  // endpointOptions, aminoTypes, registryTypes, etc.
});

// If only calling API functions directly, you can instead use:
setApiOptions({ apiUrl: "YOUR_API_URL", apiKey: "YOUR_API_KEY" });
3

Get a Route

Now, we can use the route function to request a quote and route to swap USDC on Noble to TIA on Celestia.
const routeResult = await route({
  sourceAssetDenom: 'uusdc',
  sourceAssetChainID: 'noble-1',
  destAssetDenom: 'utia',
  destAssetChainID: 'celestia',
  amountIn: '1000000', // 1 uusdc
  smartRelay: true
});
Understanding the Route ResponseThe route response contains important information about the swap process:
  • amountOut: The estimated amount the user will receive after the swap, net of all fees and price impact
  • requiredChainAddresses: Chain IDs where you need to provide user addresses when generating the transaction
  • operations: Steps involved in moving from the source to the destination token
For more details, see the /route endpoint reference.
4

Get Required Addresses

After generating a route, you need to provide user addresses for the required chains. The routeResult.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 (see an example here).
// 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),
  }))
);
Never attempt to derive an address on one chain from an address on another chainWhenever you need a user address, please request it from the corresponding wallet or signer. Do not attempt to use bech32 cross-chain derivation.If you attempt to derive an address on one chain from an address on another chain, you may derive an address that the user cannot actually sign for if the two chains have different address-derivation processes. For example, if you derive a Cosmos address from an Ethereum address, you will get an address that the user cannot sign for and thus risk lost tokens.
5

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: (chainId) => {},
  getEvmSigner: (chainId) => {},
  getSvmSigner: () => {},
  // Executes after all of the operations triggered by a user's signature complete.
  onTransactionCompleted: async (chainID, txHash, status) => {
    console.log(
      `Route completed with tx hash: ${txHash} & status: ${status.state}`
    );
  },
  onTransactionBroadcast: async ({ txHash, chainID }) => {
    console.log(`Transaction broadcasted with tx hash: ${txHash}`);
  },
  onTransactionTracked: async ({ txHash, chainID }) => {
    console.log(`Transaction tracked with tx hash: ${txHash}`);
  },
});
Once the transaction is complete, you’ll have new TIA in your Celestia address!