From 4153e9c755ece34adbe10a9f36323c0e3530c832 Mon Sep 17 00:00:00 2001 From: Crystal Gomes Date: Thu, 12 Dec 2024 14:48:41 -0500 Subject: [PATCH] CCIP SDK pointer page (#2208) * Initial pointer page * Attempt to fix build error * Attempt 2 build error * First review round * Update repo links * Updates * Add build command back --- public/changelog.json | 11 + .../images/ccip/ccip-sdk-example-app-ui.png | Bin 0 -> 51906 bytes src/config/sidebar.ts | 4 + src/content/ccip/ccip-javascript-sdk.mdx | 285 ++++++++++++++++++ 4 files changed, 300 insertions(+) create mode 100644 public/images/ccip/ccip-sdk-example-app-ui.png create mode 100644 src/content/ccip/ccip-javascript-sdk.mdx 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 0000000000000000000000000000000000000000..878b19f0c8db3801d92109de9c879f2d0734c578 GIT binary patch literal 51906 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 z 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 = { { 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", + ```