diff --git a/public/changelog.json b/public/changelog.json index 33c74513486..096c7af4b1a 100644 --- a/public/changelog.json +++ b/public/changelog.json @@ -10,6 +10,17 @@ "topic": "ccip", "urls": [] }, + { + "category": "release", + "changes": [], + "date": "2024-12-12", + "description": "The [CCIP JavaScript SDK](https://github.com/smartcontractkit/ccip-javascript-sdk) is now available, introducing two packages to simplify management of cross-chain token transfers, and to integrate CCIP with the frontend of your own app.\n\nThe [CCIP JavaScript SDK guide](https://docs.chain.link/ccip/ccip-javascript-sdk) introduces the features of the SDK and shows how to run an example app so you can explore the SDK's capabilities.", + "relatedNetworks": [], + "relatedTokens": [], + "title": "CCIP JavaScript SDK", + "topic": "ccip", + "urls": [] + }, { "category": "release", "changes": [], diff --git a/public/images/ccip/ccip-sdk-example-app-ui.png b/public/images/ccip/ccip-sdk-example-app-ui.png new file mode 100644 index 00000000000..878b19f0c8d Binary files /dev/null and b/public/images/ccip/ccip-sdk-example-app-ui.png differ diff --git a/src/config/sidebar.ts b/src/config/sidebar.ts index ba4b4603362..04af39711a1 100644 --- a/src/config/sidebar.ts +++ b/src/config/sidebar.ts @@ -1010,6 +1010,10 @@ export const SIDEBAR: Partial> = { { section: "Guides", contents: [ + { + title: "Using the CCIP JavaScript SDK", + url: "ccip/ccip-javascript-sdk", + }, { title: "Transfer Tokens", url: "ccip/tutorials/transfer-tokens-from-contract", diff --git a/src/content/ccip/ccip-javascript-sdk.mdx b/src/content/ccip/ccip-javascript-sdk.mdx new file mode 100644 index 00000000000..cd8682fed42 --- /dev/null +++ b/src/content/ccip/ccip-javascript-sdk.mdx @@ -0,0 +1,285 @@ +--- +section: ccip +date: Last Modified +title: "Using the CCIP JavaScript SDK" +--- + +import { Aside, ClickToZoom } from "@components" +import { Tabs } from "@components/Tabs" + +The [CCIP JavaScript SDK](https://github.com/smartcontractkit/ccip-javascript-sdk/tree/main) is a tool that helps you to simplify management of cross-chain token transfers, and to integrate CCIP with the frontend of your own app. + +The CCIP JavaScript SDK includes two packages: + +- [`ccip-js`](https://github.com/smartcontractkit/ccip-javascript-sdk/blob/main/packages/ccip-js/README.md): A TypeScript library that provides a client for managing cross-chain token transfers that use CCIP routers. This package allows you to manage the steps you need to prepare before sending a CCIP message, as well as checking the transfer status afterward. +- [`ccip-react-components`](https://github.com/smartcontractkit/ccip-javascript-sdk/blob/main/packages/ccip-react-components/README.md): A set of prebuilt ready-to-use UI components built on top of `ccip-js`. This package includes the following features: + - Customize injected wallet providers (MetaMask and Coinbase Wallet) + - Specify preselected chains and tokens that will display as defaults when the component loads + - Customize the UI theme + - Configure allowlists and deny lists for which chains can be used, and which chains can be used as a sources or destinations for cross-chain transfers + +Using both packages together, you can add a fully featured CCIP bridge to your app that can be styled to match your app design. + +You can also use the `ccip-js` package on its own — for example, to build a backend application. The features of the CCIP-JS package include: + +- _Token approvals_: Approve tokens for cross-chain transfers. +- _Allowance checks_: Retrieve the allowance for token transfers. +- _Rate limits_: Get rate refill limits for lanes. +- _Fee calculation_: Calculate the fee required for transfers. +- _Token transfers_: Transfer tokens across chains. +- _Transfer status_: Retrieve the status of a transfer by transaction hash. + +## Install and run the SDK + + + +1. [Install `pnpm`](https://pnpm.io/installation). + +1. Clone the `ccip-javascript-sdk` repo and navigate to the root directory of the `ccip-javascript-sdk` project: + + ```sh + git clone https://github.com/smartcontractkit/ccip-javascript-sdk.git && cd ccip-javascript-sdk + ``` + +1. From the project root, run one of the following commands to install the SDK: + + {/* prettier-ignore */} + + Install SDK and run example app + Install SDK only + + ```sh + pnpm install + pnpm build + pnpm dev-example + ``` + + + ```sh + pnpm install + ``` + + + - `pnpm dev-example` runs an example NextJS app locally. Navigate to http://localhost:3000 in your browser. + +## Run an example app + +The example Next.js app included with the CCIP JavaScript SDK demonstrates the SDK's functionalities within an interactive web application, allowing you to see its features in action. + +To get started: + +1. Launch the app by using the following commands: + + ```sh + pnpm build + pnpm dev-example + ``` + +1. In your browser, navigate to http://localhost:3000/ to see the interactive app: + + + +## Review a basic UI example + +This basic UI example shows a basic token list configuration with CCIP-BnM and CCIP-LnM test tokens, and it lists the testnets you want to use with each one. This example also includes a basic frontend configuration. + +Review the reference documentation: + +- Listing tokens in [`tokensList`](https://github.com/smartcontractkit/ccip-javascript-sdk/tree/main/packages/ccip-react-components#tokens) +- Configuring the frontend components in [`Config`](https://github.com/smartcontractkit/ccip-javascript-sdk/tree/main/packages/ccip-react-components#config) + - Configuring a [theme for frontend styling](https://github.com/smartcontractkit/ccip-javascript-sdk/tree/main/packages/ccip-react-components#theme) + +Review the basic UI example below: + +```ts +import 'ccip-react-components/dist/style.css'; +import { CCIPWidget, Config, Token } from 'ccip-react-components'; +import { sepolia, optimismSepolia } from 'viem/chains'; + +const tokensList: Token[] = [ + { + symbol: 'CCIP-BnM', + address: { + [arbitrumSepolia.id]:'0xA8C0c11bf64AF62CDCA6f93D3769B88BdD7cb93D', + [avalancheFuji.id]: '0xD21341536c5cF5EB1bcb58f6723cE26e8D8E90e4', + [baseSepolia.id]: '0x88A2d74F47a237a62e7A51cdDa67270CE381555e', + [bscTestnet.id]: '0xbFA2ACd33ED6EEc0ed3Cc06bF1ac38d22b36B9e9', + [optimismSepolia.id]: '0x8aF4204e30565DF93352fE8E1De78925F6664dA7', + [polygonAmoy.id]: '0xcab0EF91Bee323d1A617c0a027eE753aFd6997E4', + [sepolia.id]: '0xFd57b4ddBf88a4e07fF4e34C487b99af2Fe82a05' + }, + logoURL: 'https://smartcontract.imgix.net/tokens/ccip-bnm.webp?auto=compress%2Cformat', + tags: ['chainlink', 'default'] + }, + { + symbol: 'CCIP-LnM', + address: { + [optimismSepolia.id]: '0x044a6B4b561af69D2319A2f4be5Ec327a6975D0a', + [sepolia.id]: '0x466D489b6d36E7E3b824ef491C225F5830E81cC1' + }, + logoURL: 'https://smartcontract.imgix.net/tokens/ccip-lnm.webp?auto=compress%2Cformat', + tags: ['chainlink', 'default'] + } +]; + +const config: Config = { + theme: { + pallette: { + background: '#FFFFFF', + border: '#B3B7C0', + text: '#000000', + } + shape: { + radius: 6 + }, + } +}; + +; +``` + +### Theme configuration + +You can customize the component's theme to be in line with your app design. These are all the options available for theme configuration: + +```ts +import { Config } from 'ccip-react-components'; +const config: Config = { theme: + { + /** Define the app colors in HEX format */ + palette?: { + /** Titles color and primary button background, default #000000 */ + primary?: string; + /** Background color, default '#FFFFFF' */ + background?: string; + /** Border color, default '#B3B7C0' */ + border?: string; + /** Text color, default '#000000' */ + text?: string; + /** Secondary text, inactive and placeholders color, default '#6D7480' */ + muted?: string; + /** Input fields background color, default '#FFFFFF' */ + input?: string; + /** Popovers, dropdowns and select fields background color, default '#F5F7FA' */ + popover?: string; + /** Selected field from a dropdown background color, default '#D7DBE0' */ + selected?: string; + /** Warning text color, default '#F7B955' */ + warning?: string; + /** Warning text background color, default '#FFF5E0' */ + warningBackground?: string; + }; + shape?: { + /** Border radius size in px default 6 */ + radius?: number; + }; + };} +``` + +## Review a CCIP-JS example + +This example uses the `ccip-js` package and covers the following steps: + +- Initialize CCIP-JS Client for mainnet +- Approve tokens for transfer +- Get fee for the transfer +- Send the transfer through CCIP using one of the following options for fee payment: + - Using the native token fee + - Using the provided supported token for fee payment + +Review the [reference documentation](https://github.com/smartcontractkit/ccip-javascript-sdk/tree/main/packages/ccip-js#api-reference) for `ccip-js`. + +### Review the code + +```ts +import * as CCIP from "@chainlink/ccip-js" +import { createWalletClient, custom } from "viem" +import { mainnet } from "viem/chains" + +// Initialize CCIP-JS Client for mainnet +const ccipClient = CCIP.createClient() +const publicClient = createPublicClient({ + chain: mainnet, + transport: http(), +}) +const walletClient = createWalletClient({ + chain: mainnet, + transport: custom(window.ethereum!), +}) + +// Approve Router to transfer tokens on user's behalf +const { txHash, txReceipt } = await ccipClient.approveRouter({ + client: walletClient, + routerAddress: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef", + tokenAddress: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef", + amount: 1000000000000000000n, + waitForReceipt: true, +}) + +console.log(`Transfer approved. Transaction hash: ${txHash}. Transaction receipt: ${txReceipt}`) + +// Get fee for the transfer +const fee = await ccipClient.getFee({ + client: publicClient, + routerAddress: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef", + tokenAddress: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef", + amount: 1000000000000000000n, + destinationAccount: "0x1234567890abcdef1234567890abcdef12345678", + destinationChainSelector: "1234", +}) + +console.log(`Fee: ${fee.toLocaleString()}`) + +// Variant 1: Transfer via CCIP using native token fee +const { txHash, messageId } = await client.transferTokens({ + client: walletClient, + routerAddress: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef", + tokenAddress: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef", + amount: 1000000000000000000n, + destinationAccount: "0x1234567890abcdef1234567890abcdef12345678", + destinationChainSelector: "1234", +}) + +console.log(`Transfer success. Transaction hash: ${txHash}. Message ID: ${messageId}`) + +// Variant 2: Transfer via CCIP using the provided supported token for fee payment +const { txHash, messageId } = await client.transferTokens({ + client: walletClient, + routerAddress: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef", + tokenAddress: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef", + amount: 1000000000000000000n, + destinationAccount: "0x1234567890abcdef1234567890abcdef12345678", + destinationChainSelector: "1234", + feeTokenAddress: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef", +}) +``` + +## Build packages + +Optionally, if you need to modify the packages and use your modified version, follow these instructions to build the packages: + +You can use `pnpm build` to build both packages together. If you're building each package individually, make sure to build the `build-ccip-js` package before you build the `ccip-react-components` package. The React components depend on the JS package. + +1. Build the `build-ccip-js` package: + ```sh + pnpm i -w + pnpm build-ccip-js + ``` +1. Build the `ccip-react-components` package: + ```sh + pnpm build-components + ``` +1. Update the `ccip-react-components` package to use the local `ccip-js` version by modifying the `packages/ccip-react-components/package.json` file. Replace the `@chainlink/ccip-js` dependency with the workspace reference: + ``` + "@chainlink/ccip-js": "workspace:*" + ``` +1. Update the `examples/nextjs` app to use both local `ccip-js` and `ccip-react-components` versions by modifying the `examples/nextjs/package.json` file. Replace the `@chainlink/ccip-js` and `@chainlink/ccip-react-components` dependencies with these relative paths: + ``` + "@chainlink/ccip-js": "link:../../packages/ccip-js", + "@chainlink/ccip-react-components": "link:../../packages/ccip-react-components", + ```