Skip to content

Commit 562fde6

Browse files
authored
Merge pull request #8 from smartcontractkit/feat/04-hardhat-ccip
Add example 04: Hardhat v3 + CCIP SDK with custom contracts
2 parents 18f4e6e + 653c4f3 commit 562fde6

104 files changed

Lines changed: 7976 additions & 348 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,22 +70,22 @@ ccip-sdk-examples/
7070

7171
## Shared packages
7272

73-
### @ccip-examples/shared-config
73+
### @chainlink/ccip-examples-shared-config
7474

7575
Network and token config; wagmi config and query client; constants (status labels, polling, explorer URLs). RPC URLs come from `getRpcUrl(networkId)` (env vars `RPC_<NETWORK_ID>` or public fallbacks).
7676

7777
- **Exports:** `NETWORKS`, `NETWORK_IDS`, `getNetwork`, `getEVMNetworks`, `getSolanaNetworks`, `getAptosNetworks`, `getAllNetworks`, `getChainIdForNetwork`, `getExplorerTxUrl`, `getExplorerAddressUrl`; `getTokenAddress`, `resolveFeeTokenAddress`, `TOKEN_ADDRESSES`, etc.; `ChainFamily`; `POLLING_CONFIG`, `getStatusDescription`, `getFaucetUrl`, `getDummyReceiver`, etc.
7878
- **Subpaths:** `./wagmi`, `./queryClient`, `./networks`, `./tokens`.
7979

80-
### @ccip-examples/shared-utils
80+
### @chainlink/ccip-examples-shared-utils
8181

82-
Browser-safe utilities: validation (`isValidAddress`, `isValidAmount`, `parseAmount`, `formatAmount`, `truncateAddress`), CCIP error parsing (`getCCIPErrorMessage`, `parseEVMError`, `parseSolanaError`), formatting (`formatLatency`, `formatElapsedTime`, `formatRelativeTime`), message building (`buildTokenTransferMessage`), clipboard (`copyToClipboard`, `COPIED_FEEDBACK_MS`), viem adapter (`toGenericPublicClient`). Node-only wallet/chain helpers live in `@ccip-examples/shared-utils/wallet`.
82+
Browser-safe utilities: validation (`isValidAddress`, `isValidAmount`, `parseAmount`, `formatAmount`, `truncateAddress`), CCIP error parsing (`getCCIPErrorMessage`, `parseEVMError`, `parseSolanaError`), formatting (`formatLatency`, `formatElapsedTime`, `formatRelativeTime`), message building (`buildTokenTransferMessage`), clipboard (`copyToClipboard`, `COPIED_FEEDBACK_MS`), viem adapter (`toGenericPublicClient`). Node-only wallet/chain helpers live in `@chainlink/ccip-examples-shared-utils/wallet`.
8383

8484
- **Subpaths:** `./hooks` (e.g. `useMessageStatus`, `useCopyToClipboard`).
8585

86-
### @ccip-examples/shared-components
86+
### @chainlink/ccip-examples-shared-components
8787

88-
React UI: primitives (Button, Input, Select, Alert), bridge (MessageProgress, TransferStatus, FeeTokenOptions, BalancesList), ErrorBoundary. All use design tokens from `@ccip-examples/shared-components/styles/tokens.css`. Import tokens once in app globals.
88+
React UI: primitives (Button, Input, Select, Alert), bridge (MessageProgress, TransferStatus, FeeTokenOptions, BalancesList), ErrorBoundary. All use design tokens from `@chainlink/ccip-examples-shared-components/styles/tokens.css`. Import tokens once in app globals.
8989

9090
- **FeeTokenOptions:** Radio group for choosing fee token (native currency, LINK, or other tokens discovered from the router). Displays token name, symbol, balance, and a "Native" badge for native currency options.
9191
- **BalancesList:** Displays multiple token balances with loading skeletons.

docs/LEARNING_PATH.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Progressive examples for using `@chainlink/ccip-sdk` v1.0.0 (testnet only). Each
99
- **Runtime:** Node.js (no browser).
1010
- **Purpose:** SDK basics without UI—chain setup, fee estimation, token discovery, pool inspection, cross-chain transfers.
1111
- **Scripts:** `pnpm chains`, `pnpm fees`, `pnpm tokens`, `pnpm pools`, `pnpm transfer`, `pnpm status` (see example README).
12-
- **Dependencies:** `@chainlink/ccip-sdk`, `@ccip-examples/shared-config`, `@ccip-examples/shared-utils` (chain factory, validation, message building).
12+
- **Dependencies:** `@chainlink/ccip-sdk`, `@chainlink/ccip-examples-shared-config`, `@chainlink/ccip-examples-shared-utils` (chain factory, validation, message building).
1313

1414
### 02-evm-simple-bridge
1515

@@ -19,7 +19,7 @@ Progressive examples for using `@chainlink/ccip-sdk` v1.0.0 (testnet only). Each
1919
- **Fee token:** User selects a fee token via `FeeTokenOptions` (native currency, LINK, or other tokens discovered dynamically from the router via `getFeeTokens()`). Each option shows token name, symbol, balance, and a "Native" badge for native currency.
2020
- **Balances:** `useWalletBalances` fetches native, LINK, and token balances in parallel; displayed via `BalancesList`.
2121
- **Stack:** wagmi, viem, RainbowKit; chain from `getPublicClient` + `fromViemClient(toGenericPublicClient(...))`.
22-
- **Shared:** `@ccip-examples/shared-config` (NETWORKS, wagmi config, tokens), `@ccip-examples/shared-utils` (validation, errors, formatting, hooks), `@ccip-examples/shared-components` (Button, Input, Select, Alert, FeeTokenOptions, BalancesList, TransferStatus, MessageProgress, ErrorBoundary), `@ccip-examples/shared-brand` (design tokens, logo).
22+
- **Shared:** `@chainlink/ccip-examples-shared-config` (NETWORKS, wagmi config, tokens), `@chainlink/ccip-examples-shared-utils` (validation, errors, formatting, hooks), `@chainlink/ccip-examples-shared-components` (Button, Input, Select, Alert, FeeTokenOptions, BalancesList, TransferStatus, MessageProgress, ErrorBoundary), `@chainlink/ccip-examples-shared-brand` (design tokens, logo).
2323
- **RPC:** Optional `.env` with `RPC_<NETWORK_ID>` (e.g. `RPC_ETHEREUM_TESTNET_SEPOLIA`) to override public RPC URLs.
2424

2525
### 03-multichain-bridge-dapp
@@ -54,8 +54,8 @@ CCIP routing uses **chain selectors** (64-bit identifiers), not wallet chain IDs
5454
Call `getFee()` on the source chain before sending. Message shape follows SDK `MessageInput` (receiver, tokenAmounts, feeToken, extraArgs, etc.). Use `buildTokenTransferMessage` (shared-utils) for token transfers:
5555

5656
```typescript
57-
import { buildTokenTransferMessage } from "@ccip-examples/shared-utils";
58-
import { resolveFeeTokenAddress } from "@ccip-examples/shared-config";
57+
import { buildTokenTransferMessage } from "@chainlink/ccip-examples-shared-utils";
58+
import { resolveFeeTokenAddress } from "@chainlink/ccip-examples-shared-config";
5959

6060
// feeToken: undefined = native currency, address = ERC20 (e.g. LINK)
6161
const feeTokenAddress = resolveFeeTokenAddress("link", sourceNetworkId);

examples/01-getting-started/README.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ Message Found!
239239

240240
### Chain (base class)
241241

242-
All scripts use the abstract `Chain` base class. Concrete instances are created via the `createChain(networkId, rpcUrl)` factory from `@ccip-examples/shared-utils`.
242+
All scripts use the abstract `Chain` base class. Concrete instances are created via the `createChain(networkId, rpcUrl)` factory from `@chainlink/ccip-examples-shared-utils`.
243243

244244
| Method | Description |
245245
| ---------------------------------- | ------------------------------------- |
@@ -263,17 +263,17 @@ Used by `get-status.ts` for message lookups. No chain instance needed.
263263

264264
### Shared Utilities
265265

266-
| Function | Package | Description |
267-
| ----------------------------- | ------------------------------ | ------------------------------------------------- |
268-
| `createChain()` | `@ccip-examples/shared-utils` | Family-agnostic chain factory |
269-
| `createWallet()` | `@ccip-examples/shared-utils` | Family-agnostic wallet factory (reads env vars) |
270-
| `createSolanaWallet()` | `@ccip-examples/shared-utils` | Solana wallet from file path, hex, or base58 |
271-
| `createAptosWallet()` | `@ccip-examples/shared-utils` | Aptos wallet from AIP-80 or hex private key |
272-
| `createLogger()` | `@ccip-examples/shared-utils` | Logger with configurable verbosity |
273-
| `buildTokenTransferMessage()` | `@ccip-examples/shared-utils` | Build a `MessageInput` for token transfers |
274-
| `networkInfo()` | `@chainlink/ccip-sdk` | Get chain selector and metadata |
275-
| `resolveFeeTokenAddress()` | `@ccip-examples/shared-config` | Resolve `"native"`/`"link"` to on-chain address |
276-
| `getDummyReceiver()` | `@ccip-examples/shared-config` | Get a format-valid dummy address per chain family |
266+
| Function | Package | Description |
267+
| ----------------------------- | ---------------------------------------- | ------------------------------------------------- |
268+
| `createChain()` | `@chainlink/ccip-examples-shared-utils` | Family-agnostic chain factory |
269+
| `createWallet()` | `@chainlink/ccip-examples-shared-utils` | Family-agnostic wallet factory (reads env vars) |
270+
| `createSolanaWallet()` | `@chainlink/ccip-examples-shared-utils` | Solana wallet from file path, hex, or base58 |
271+
| `createAptosWallet()` | `@chainlink/ccip-examples-shared-utils` | Aptos wallet from AIP-80 or hex private key |
272+
| `createLogger()` | `@chainlink/ccip-examples-shared-utils` | Logger with configurable verbosity |
273+
| `buildTokenTransferMessage()` | `@chainlink/ccip-examples-shared-utils` | Build a `MessageInput` for token transfers |
274+
| `networkInfo()` | `@chainlink/ccip-sdk` | Get chain selector and metadata |
275+
| `resolveFeeTokenAddress()` | `@chainlink/ccip-examples-shared-config` | Resolve `"native"`/`"link"` to on-chain address |
276+
| `getDummyReceiver()` | `@chainlink/ccip-examples-shared-config` | Get a format-valid dummy address per chain family |
277277

278278
## Solana-Specific Notes
279279

examples/01-getting-started/package.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
{
2-
"name": "@ccip-examples/01-getting-started",
2+
"name": "@chainlink/ccip-examples-01-getting-started",
3+
"private": true,
34
"version": "1.0.0",
5+
"engines": {
6+
"node": ">=22.0.0"
7+
},
48
"description": "Getting started with CCIP SDK - Node.js scripts for basic operations",
59
"type": "module",
610
"scripts": {
@@ -18,9 +22,9 @@
1822
"clean": "rm -rf dist"
1923
},
2024
"dependencies": {
21-
"@ccip-examples/shared-config": "workspace:*",
22-
"@ccip-examples/shared-utils": "workspace:*",
23-
"@chainlink/ccip-sdk": "1.0.0",
25+
"@chainlink/ccip-examples-shared-config": "workspace:*",
26+
"@chainlink/ccip-examples-shared-utils": "workspace:*",
27+
"@chainlink/ccip-sdk": "1.3.1",
2428
"@coral-xyz/anchor": "^0.30.1",
2529
"@solana/web3.js": "^1.98.0",
2630
"bs58": "^6.0.0",

examples/01-getting-started/src/estimate-fees.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ import {
2626
resolveFeeTokenAddress,
2727
type FeeTokenOption,
2828
type NetworkConfig,
29-
} from "@ccip-examples/shared-config";
29+
} from "@chainlink/ccip-examples-shared-config";
3030
import {
3131
formatAmount,
3232
parseAmount,
3333
buildTokenTransferMessage,
3434
createChain,
3535
getErrorMessage,
36-
} from "@ccip-examples/shared-utils";
36+
} from "@chainlink/ccip-examples-shared-utils";
3737

3838
const DEFAULT_TOKEN = "CCIP-BnM";
3939
const DEFAULT_AMOUNT = "1.0";

examples/01-getting-started/src/get-status.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import {
3737
CCIPMessageIdNotFoundError,
3838
withRetry,
3939
} from "@chainlink/ccip-sdk";
40-
import { getStatusDescription, POLLING_CONFIG } from "@ccip-examples/shared-config";
40+
import { getStatusDescription, POLLING_CONFIG } from "@chainlink/ccip-examples-shared-config";
4141

4242
async function main() {
4343
const args = process.argv.slice(2);

examples/01-getting-started/src/inspect-pools.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
import "dotenv/config";
1919
import type { Chain, RateLimiterState, TokenInfo } from "@chainlink/ccip-sdk";
2020
import { networkInfo, CCIPError, CCIPTokenPoolChainConfigNotFoundError } from "@chainlink/ccip-sdk";
21-
import { NETWORKS, NETWORK_IDS, getTokenAddress } from "@ccip-examples/shared-config";
22-
import { formatAmount, createChain } from "@ccip-examples/shared-utils";
21+
import { NETWORKS, NETWORK_IDS, getTokenAddress } from "@chainlink/ccip-examples-shared-config";
22+
import { formatAmount, createChain } from "@chainlink/ccip-examples-shared-utils";
2323

2424
/**
2525
* Format a rate limiter state for display.

examples/01-getting-started/src/list-chains.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
type ChainFamily,
1414
getAllNetworks,
1515
CHAIN_FAMILY_LABELS,
16-
} from "@ccip-examples/shared-config";
16+
} from "@chainlink/ccip-examples-shared-config";
1717

1818
function main() {
1919
console.log("=".repeat(60));

examples/01-getting-started/src/supported-tokens.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
import "dotenv/config";
1717
import { Command } from "commander";
1818
import { networkInfo, CCIPError, CCIPTokenPoolChainConfigNotFoundError } from "@chainlink/ccip-sdk";
19-
import { NETWORKS, NETWORK_IDS, CHAIN_FAMILY_LABELS } from "@ccip-examples/shared-config";
20-
import { formatAmount, createChain } from "@ccip-examples/shared-utils";
19+
import { NETWORKS, NETWORK_IDS, CHAIN_FAMILY_LABELS } from "@chainlink/ccip-examples-shared-config";
20+
import { formatAmount, createChain } from "@chainlink/ccip-examples-shared-utils";
2121

2222
function validateChainKey(key: string): string {
2323
if (!NETWORK_IDS.includes(key)) {

examples/01-getting-started/src/transfer-tokens.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ import {
3232
getDummyReceiver,
3333
resolveFeeTokenAddress,
3434
type FeeTokenOption,
35-
} from "@ccip-examples/shared-config";
35+
} from "@chainlink/ccip-examples-shared-config";
3636
import {
3737
formatAmount,
3838
parseAmount,
3939
buildTokenTransferMessage,
4040
createChain,
4141
createLogger,
42-
} from "@ccip-examples/shared-utils";
43-
import { createWallet } from "@ccip-examples/shared-utils/wallet";
42+
} from "@chainlink/ccip-examples-shared-utils";
43+
import { createWallet } from "@chainlink/ccip-examples-shared-utils/wallet";
4444

4545
const DEFAULT_TOKEN = "CCIP-BnM";
4646
const DEFAULT_AMOUNT = "0.001";

0 commit comments

Comments
 (0)