Skip to content

Commit

Permalink
CCIP SDK pointer page (#2208)
Browse files Browse the repository at this point in the history
* Initial pointer page

* Attempt to fix build error

* Attempt 2 build error

* First review round

* Update repo links

* Updates

* Add build command back
  • Loading branch information
thedriftofwords authored Dec 12, 2024
1 parent a2a852a commit 4153e9c
Show file tree
Hide file tree
Showing 4 changed files with 300 additions and 0 deletions.
11 changes: 11 additions & 0 deletions public/changelog.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [],
Expand Down
Binary file added public/images/ccip/ccip-sdk-example-app-ui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/config/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,10 @@ export const SIDEBAR: Partial<Record<Sections, SectionEntry[]>> = {
{
section: "Guides",
contents: [
{
title: "Using the CCIP JavaScript SDK",
url: "ccip/ccip-javascript-sdk",
},
{
title: "Transfer Tokens",
url: "ccip/tutorials/transfer-tokens-from-contract",
Expand Down
285 changes: 285 additions & 0 deletions src/content/ccip/ccip-javascript-sdk.mdx
Original file line number Diff line number Diff line change
@@ -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 &mdash; 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

<Aside type="caution" title="Security Warning: Handle Error Messages with Care">
**Important**: Error messages generated by this SDK are **not escaped**. If your application uses user inputs that may end up in error messages, it is your responsibility to **escape or sanitize these messages** before displaying them to users.

Failure to escape or sanitize error messages could expose your application to **Cross-Site Scripting (XSS)** vulnerabilities, especially when user-generated content is included in error handling logic.

</Aside>

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 */}
<Tabs sharedStore="installOption" client:visible>
<Fragment slot="tab.1">Install SDK and run example app</Fragment>
<Fragment slot="tab.2">Install SDK only</Fragment>
<Fragment slot="panel.1">
```sh
pnpm install
pnpm build
pnpm dev-example
```
</Fragment>
<Fragment slot="panel.2">
```sh
pnpm install
```
</Fragment>
</Tabs>
- `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:

<ClickToZoom src="/images/ccip/ccip-sdk-example-app-ui.png" alt="CCIP JavaScript SDK example 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
},
}
};

<CCIPWidget config={config} tokensList={tokensList} />;
```

### 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",
```

0 comments on commit 4153e9c

Please sign in to comment.