From cb907d76a4ce17aebf4201edbe31740ffbbc644f Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Sat, 14 Mar 2026 03:40:31 +0000 Subject: [PATCH 1/6] Add example 04: Hardhat v3 + CCIP SDK with production-grade sender/receiver contracts - CCIPSender: peer registration, extraArgs passthrough, fee token deduplication, native fee refund, Ownable2Step, Pausable, ReentrancyGuard - CCIPReceiverExample: defensive try/catch, double-mapping allowlist, failed message tracking, token recovery with configurable amounts - Hardhat tasks: deploy-sender, deploy-receiver, send-via-sender, send-via-router, check-status with SDK gas estimation - Solhint with Chainlink's exact config and chainlink-solidity plugin - Upgrade ccip-sdk to 1.2.0 across all workspace packages --- examples/01-getting-started/package.json | 2 +- examples/02-evm-simple-bridge/package.json | 2 +- .../03-multichain-bridge-dapp/package.json | 2 +- examples/04-hardhat-ccip/.env.example | 7 + examples/04-hardhat-ccip/.gitignore | 3 + examples/04-hardhat-ccip/.solhint.json | 39 + examples/04-hardhat-ccip/.solhintignore | 1 + .../contracts/CCIPReceiver.sol | 184 + .../04-hardhat-ccip/contracts/CCIPSender.sol | 177 + examples/04-hardhat-ccip/hardhat.config.ts | 121 + examples/04-hardhat-ccip/helpers/sdk.ts | 57 + examples/04-hardhat-ccip/package.json | 35 + .../04-hardhat-ccip/tasks/check-status.ts | 106 + .../04-hardhat-ccip/tasks/deploy-receiver.ts | 73 + .../04-hardhat-ccip/tasks/deploy-sender.ts | 73 + .../04-hardhat-ccip/tasks/send-via-router.ts | 217 ++ .../04-hardhat-ccip/tasks/send-via-sender.ts | 222 ++ examples/04-hardhat-ccip/tsconfig.json | 10 + package.json | 1 + packages/shared-components/package.json | 4 +- packages/shared-config/package.json | 4 +- packages/shared-utils/package.json | 4 +- pnpm-lock.yaml | 3092 ++++++++++++++++- 23 files changed, 4276 insertions(+), 160 deletions(-) create mode 100644 examples/04-hardhat-ccip/.env.example create mode 100644 examples/04-hardhat-ccip/.gitignore create mode 100644 examples/04-hardhat-ccip/.solhint.json create mode 100644 examples/04-hardhat-ccip/.solhintignore create mode 100644 examples/04-hardhat-ccip/contracts/CCIPReceiver.sol create mode 100644 examples/04-hardhat-ccip/contracts/CCIPSender.sol create mode 100644 examples/04-hardhat-ccip/hardhat.config.ts create mode 100644 examples/04-hardhat-ccip/helpers/sdk.ts create mode 100644 examples/04-hardhat-ccip/package.json create mode 100644 examples/04-hardhat-ccip/tasks/check-status.ts create mode 100644 examples/04-hardhat-ccip/tasks/deploy-receiver.ts create mode 100644 examples/04-hardhat-ccip/tasks/deploy-sender.ts create mode 100644 examples/04-hardhat-ccip/tasks/send-via-router.ts create mode 100644 examples/04-hardhat-ccip/tasks/send-via-sender.ts create mode 100644 examples/04-hardhat-ccip/tsconfig.json diff --git a/examples/01-getting-started/package.json b/examples/01-getting-started/package.json index d03446d..ecf4e01 100644 --- a/examples/01-getting-started/package.json +++ b/examples/01-getting-started/package.json @@ -20,7 +20,7 @@ "dependencies": { "@ccip-examples/shared-config": "workspace:*", "@ccip-examples/shared-utils": "workspace:*", - "@chainlink/ccip-sdk": "1.0.0", + "@chainlink/ccip-sdk": "1.2.0", "@coral-xyz/anchor": "^0.30.1", "@solana/web3.js": "^1.98.0", "bs58": "^6.0.0", diff --git a/examples/02-evm-simple-bridge/package.json b/examples/02-evm-simple-bridge/package.json index eac0f42..f9bb483 100644 --- a/examples/02-evm-simple-bridge/package.json +++ b/examples/02-evm-simple-bridge/package.json @@ -13,7 +13,7 @@ "clean": "rm -rf dist" }, "dependencies": { - "@chainlink/ccip-sdk": "1.0.0", + "@chainlink/ccip-sdk": "1.2.0", "@ccip-examples/shared-brand": "workspace:*", "@ccip-examples/shared-config": "workspace:*", "@ccip-examples/shared-components": "workspace:*", diff --git a/examples/03-multichain-bridge-dapp/package.json b/examples/03-multichain-bridge-dapp/package.json index c3420ae..f5541c7 100644 --- a/examples/03-multichain-bridge-dapp/package.json +++ b/examples/03-multichain-bridge-dapp/package.json @@ -15,7 +15,7 @@ "dependencies": { "@aptos-labs/ts-sdk": "^5.2.1", "@aptos-labs/wallet-adapter-react": "^3.7.2", - "@chainlink/ccip-sdk": "1.0.0", + "@chainlink/ccip-sdk": "1.2.0", "@ccip-examples/shared-brand": "workspace:*", "@ccip-examples/shared-config": "workspace:*", "@ccip-examples/shared-components": "workspace:*", diff --git a/examples/04-hardhat-ccip/.env.example b/examples/04-hardhat-ccip/.env.example new file mode 100644 index 0000000..e566a7d --- /dev/null +++ b/examples/04-hardhat-ccip/.env.example @@ -0,0 +1,7 @@ +# Private key for deploying contracts and sending transactions +EVM_PRIVATE_KEY=0x... + +# RPC URLs (optional - falls back to public endpoints) +RPC_ETHEREUM_TESTNET_SEPOLIA=https://... +RPC_ETHEREUM_TESTNET_SEPOLIA_BASE_1=https://... +RPC_AVALANCHE_TESTNET_FUJI=https://... diff --git a/examples/04-hardhat-ccip/.gitignore b/examples/04-hardhat-ccip/.gitignore new file mode 100644 index 0000000..b83e07e --- /dev/null +++ b/examples/04-hardhat-ccip/.gitignore @@ -0,0 +1,3 @@ +artifacts/ +cache/ +dist/ diff --git a/examples/04-hardhat-ccip/.solhint.json b/examples/04-hardhat-ccip/.solhint.json new file mode 100644 index 0000000..bc3e505 --- /dev/null +++ b/examples/04-hardhat-ccip/.solhint.json @@ -0,0 +1,39 @@ +{ + "extends": "solhint:recommended", + "plugins": ["chainlink-solidity"], + "rules": { + "compiler-version": ["off", "^0.8.0"], + "const-name-snakecase": "off", + "var-name-mixedcase": "off", + "func-named-parameters": "off", + "immutable-vars-naming": "off", + "no-inline-assembly": "off", + "contract-name-capwords": "off", + "use-natspec": "off", + "gas-indexed-events": "off", + "function-max-lines": "off", + "gas-strict-inequalities": "off", + "gas-increment-by-one": "off", + "gas-calldata-parameters": "off", + "gas-small-strings": "off", + "not-rely-on-time": "off", + "no-empty-blocks": "off", + "no-unused-import": "error", + "import-path-check": "off", + "func-visibility": [ + "error", + { + "ignoreConstructors": true + } + ], + "quotes": ["error", "double"], + "chainlink-solidity/prefix-internal-functions-with-underscore": "warn", + "chainlink-solidity/prefix-private-functions-with-underscore": "warn", + "chainlink-solidity/prefix-storage-variables-with-s-underscore": "warn", + "chainlink-solidity/prefix-immutable-variables-with-i": "warn", + "chainlink-solidity/all-caps-constant-storage-variables": "warn", + "chainlink-solidity/no-hardhat-imports": "warn", + "chainlink-solidity/inherited-constructor-args-not-in-contract-definition": "warn", + "chainlink-solidity/explicit-returns": "warn" + } +} diff --git a/examples/04-hardhat-ccip/.solhintignore b/examples/04-hardhat-ccip/.solhintignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/examples/04-hardhat-ccip/.solhintignore @@ -0,0 +1 @@ +node_modules/ diff --git a/examples/04-hardhat-ccip/contracts/CCIPReceiver.sol b/examples/04-hardhat-ccip/contracts/CCIPReceiver.sol new file mode 100644 index 0000000..dac0251 --- /dev/null +++ b/examples/04-hardhat-ccip/contracts/CCIPReceiver.sol @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {CCIPReceiver} from "@chainlink/contracts-ccip/contracts/applications/CCIPReceiver.sol"; +import {Client} from "@chainlink/contracts-ccip/contracts/libraries/Client.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {Ownable2Step, Ownable} from "@openzeppelin/contracts/access/Ownable2Step.sol"; +import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol"; +import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; + +/// @title CCIPReceiverExample +/// @notice CCIP receiver with 3 modes: token-only, data-only, and data+tokens. +/// @dev Implements the defensive pattern recommended by Chainlink: +/// - Separates message reception from business logic via try/catch +/// - Uses try/catch to prevent message failure from locking tokens +/// - Tracks failed message IDs for owner-driven recovery via withdrawToken +/// +/// Message modes: +/// - Token-only: holds received tokens in the contract. +/// - Data-only: emits event with the data payload. +/// - Data+tokens: decodes a recipient address from data and forwards tokens. +/// +/// Security patterns: +/// - Ownable2Step: prevents accidental ownership transfer to wrong address +/// - Pausable: when paused, _ccipReceive reverts — CCIP marks message as failed +/// and it can be manually re-executed later once unpaused +/// - ReentrancyGuard: prevents reentrancy via malicious token callbacks +/// - Double-mapping allowlist: (sourceChainSelector, sender) prevents cross-chain +/// sender impersonation +/// - Defensive try/catch: failed processing stores messageId, tokens stay in contract +contract CCIPReceiverExample is CCIPReceiver, Ownable2Step, Pausable, ReentrancyGuard { + using SafeERC20 for IERC20; + + // Allowlisting: sender is allowlisted per source chain to prevent + // a contract on chain B from impersonating an allowlisted sender on chain A. + mapping(uint64 sourceChainSelector => mapping(address sender => bool allowed)) public allowlistedSenders; + + // Failed message tracking (defensive pattern) + mapping(bytes32 => bool) public failedMessages; + + // Custom errors + error SenderNotAllowed(uint64 sourceChainSelector, address sender); + error InvalidRecipient(); + error NothingToWithdraw(); + error FailedToWithdrawEth(address owner, address target, uint256 value); + error OnlySelf(); + + // Events + event TokensReceived(bytes32 indexed messageId, address[] tokens, uint256[] amounts); + event DataReceived(bytes32 indexed messageId, bytes data); + event TokensForwarded(bytes32 indexed messageId, address indexed recipient, address[] tokens, uint256[] amounts); + event MessageFailed(bytes32 indexed messageId, bytes reason); + + /// @dev Only this contract can call processMessage (used by the try/catch pattern). + modifier onlySelf() { + if (msg.sender != address(this)) revert OnlySelf(); + _; + } + + constructor(address _router) CCIPReceiver(_router) Ownable(msg.sender) {} + + /// @notice Allowlist or deny a sender on a specific source chain. + /// @param sourceChainSelector The CCIP chain selector of the source chain. + /// @param sender The sender address to allowlist on that chain. + /// @param allowed Whether the sender is allowed. + function allowlistSender(uint64 sourceChainSelector, address sender, bool allowed) external onlyOwner { + allowlistedSenders[sourceChainSelector][sender] = allowed; + } + + /// @notice Defensive receive: validates allowlists, then delegates to processMessage + /// via try/catch. If processing fails, tokens stay in the contract and the + /// message ID is recorded. The owner can recover tokens via withdrawToken. + /// @dev When paused, this reverts — CCIP marks the message as failed and it can be + /// manually re-executed later via the CCIP explorer once unpaused. + function _ccipReceive(Client.Any2EVMMessage memory message) internal override whenNotPaused nonReentrant { + address sender = abi.decode(message.sender, (address)); + if (!allowlistedSenders[message.sourceChainSelector][sender]) { + revert SenderNotAllowed(message.sourceChainSelector, sender); + } + + // Defensive pattern: try processing, catch and record on failure. + // On failure, tokens remain in this contract (they were already transferred + // by the router before _ccipReceive is called) and can be recovered by the owner. + try this.processMessage(message) { + // Success — events are emitted inside processMessage + } catch (bytes memory reason) { + failedMessages[message.messageId] = true; + emit MessageFailed(message.messageId, reason); + } + } + + /// @notice Process a CCIP message. Called by _ccipReceive via this.processMessage() + /// so that failures are caught by the try/catch wrapper. + /// @dev Must be external for try/catch but restricted to onlySelf. + function processMessage(Client.Any2EVMMessage calldata message) external onlySelf { + bool hasData = message.data.length > 0; + bool hasTokens = message.destTokenAmounts.length > 0; + + if (hasTokens && !hasData) { + _handleTokensOnly(message); + } else if (hasData && !hasTokens) { + _handleDataOnly(message); + } else if (hasData && hasTokens) { + _handleDataAndTokens(message); + } + } + + function _handleTokensOnly(Client.Any2EVMMessage memory message) internal { + (address[] memory tokens, uint256[] memory amounts) = _extractTokenInfo(message); + emit TokensReceived(message.messageId, tokens, amounts); + } + + function _handleDataOnly(Client.Any2EVMMessage memory message) internal { + emit DataReceived(message.messageId, message.data); + } + + function _handleDataAndTokens(Client.Any2EVMMessage memory message) internal { + address recipient = abi.decode(message.data, (address)); + if (recipient == address(0)) revert InvalidRecipient(); + + (address[] memory tokens, uint256[] memory amounts) = _extractTokenInfo(message); + + for (uint256 i = 0; i < message.destTokenAmounts.length; i++) { + IERC20(message.destTokenAmounts[i].token).safeTransfer( + recipient, message.destTokenAmounts[i].amount + ); + } + + emit TokensForwarded(message.messageId, recipient, tokens, amounts); + } + + function _extractTokenInfo(Client.Any2EVMMessage memory message) + internal pure returns (address[] memory tokens, uint256[] memory amounts) + { + tokens = new address[](message.destTokenAmounts.length); + amounts = new uint256[](message.destTokenAmounts.length); + for (uint256 i = 0; i < message.destTokenAmounts.length; i++) { + tokens[i] = message.destTokenAmounts[i].token; + amounts[i] = message.destTokenAmounts[i].amount; + } + + return (tokens, amounts); + } + + /// @notice Pause message processing (owner only). Use in case of emergency. + /// @dev While paused, incoming CCIP messages will revert and can be manually + /// re-executed later via the CCIP explorer once unpaused. + function pause() external onlyOwner { + _pause(); + } + + /// @notice Unpause message processing (owner only). + function unpause() external onlyOwner { + _unpause(); + } + + /// @notice Fallback to allow the contract to receive native currency. + receive() external payable {} + + /// @notice Withdraw native currency from this contract (owner only). + /// @param beneficiary The address to send the native currency to. + function withdraw(address beneficiary) public onlyOwner { + uint256 amount = address(this).balance; + if (amount == 0) revert NothingToWithdraw(); + + (bool sent, ) = beneficiary.call{value: amount}(""); + if (!sent) revert FailedToWithdrawEth(msg.sender, beneficiary, amount); + } + + /// @notice Withdraw ERC20 tokens from this contract (owner only). + /// @dev Use this to recover tokens from failed messages or any stuck tokens. + /// Pass 0 for amount to withdraw the full balance. + /// @param beneficiary The address to send the tokens to. + /// @param token The ERC20 token contract address. + /// @param amount The amount to withdraw (0 = full balance). + function withdrawToken(address beneficiary, address token, uint256 amount) public onlyOwner { + uint256 balance = IERC20(token).balanceOf(address(this)); + if (balance == 0) revert NothingToWithdraw(); + + uint256 transferAmount = amount == 0 ? balance : amount; + IERC20(token).safeTransfer(beneficiary, transferAmount); + } +} diff --git a/examples/04-hardhat-ccip/contracts/CCIPSender.sol b/examples/04-hardhat-ccip/contracts/CCIPSender.sol new file mode 100644 index 0000000..79c3f4a --- /dev/null +++ b/examples/04-hardhat-ccip/contracts/CCIPSender.sol @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {IRouterClient} from "@chainlink/contracts-ccip/contracts/interfaces/IRouterClient.sol"; +import {Client} from "@chainlink/contracts-ccip/contracts/libraries/Client.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {Ownable2Step, Ownable} from "@openzeppelin/contracts/access/Ownable2Step.sol"; +import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol"; +import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; + +/// @title CCIPSender +/// @notice CCIP sender with pre-encoded extraArgs passthrough and peer registration. +/// @dev Supports all 3 message types: token-only, data-only, and data+tokens (programmable token transfer). +/// The extraArgs passthrough pattern lets offchain code (e.g. the CCIP SDK) build +/// the correct extraArgs for the destination chain, keeping the contract simple and chain-agnostic. +/// +/// Follows the industry-standard peer registration pattern (used by LayerZero OApp, +/// Wormhole NTT, Hyperlane Router): the owner registers trusted (destChainSelector, receiver) +/// pairs. Sends to unregistered destinations revert. +/// +/// Security patterns: +/// - Ownable2Step: prevents accidental ownership transfer to wrong address +/// - Pausable: emergency circuit breaker for owner to halt sends +/// - ReentrancyGuard: prevents reentrancy via malicious token callbacks +/// - Peer registration: only allows sends to registered (chain, receiver) pairs +/// - Exact fee handling: calculates fee via i_router.getFee(), refunds excess native +/// - Fee token deduplication: optimizes when fee token == a transfer token +contract CCIPSender is Ownable2Step, Pausable, ReentrancyGuard { + using SafeERC20 for IERC20; + + IRouterClient public immutable i_router; + + /// @notice Registered peers: destChainSelector => trusted receiver address. + /// @dev Only registered (chain, receiver) pairs can be used as destinations. + mapping(uint64 destChainSelector => address peer) public peers; + + error NothingToWithdraw(); + error FailedToWithdrawEth(address owner, address target, uint256 value); + error InsufficientNativeFee(uint256 required, uint256 provided); + error PeerNotRegistered(uint64 destChainSelector, address receiver); + + event MessageSent(bytes32 indexed messageId, uint64 indexed destChainSelector); + event PeerSet(uint64 indexed destChainSelector, address peer); + + constructor(address _router) Ownable(msg.sender) { + i_router = IRouterClient(_router); + } + + /// @notice Register or remove a trusted peer on a destination chain. + /// @param destChainSelector The CCIP chain selector of the destination. + /// @param peer The trusted receiver address (address(0) to remove). + function setPeer(uint64 destChainSelector, address peer) external onlyOwner { + peers[destChainSelector] = peer; + emit PeerSet(destChainSelector, peer); + } + + /// @notice Send a CCIP message with pre-encoded extraArgs. + /// @dev Handles both native and ERC20 fee payment. When the fee token is the same + /// as a transfer token, combines into a single transferFrom + approval for gas efficiency. + /// Excess native fees are refunded to the caller. + /// @param destChainSelector Destination chain selector + /// @param receiver Receiver address on destination (must match registered peer) + /// @param data Arbitrary data payload (empty bytes for token-only) + /// @param tokenAmounts Token transfers (empty array for data-only) + /// @param extraArgs Pre-encoded extra args (built offchain via SDK) + /// @param feeToken Fee token address (address(0) for native) + function send( + uint64 destChainSelector, + address receiver, + bytes calldata data, + Client.EVMTokenAmount[] calldata tokenAmounts, + bytes calldata extraArgs, + address feeToken + ) external payable nonReentrant whenNotPaused returns (bytes32 messageId) { + // Validate destination is a registered peer + address registeredPeer = peers[destChainSelector]; + if (registeredPeer == address(0) || registeredPeer != receiver) { + revert PeerNotRegistered(destChainSelector, receiver); + } + + // Build the CCIP message and calculate fees first + Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ + receiver: abi.encode(receiver), + data: data, + tokenAmounts: tokenAmounts, + extraArgs: extraArgs, + feeToken: feeToken + }); + + uint256 fees = i_router.getFee(destChainSelector, message); + + if (feeToken == address(0)) { + // Native fee payment + if (msg.value < fees) revert InsufficientNativeFee(fees, msg.value); + + // Transfer tokens from caller to this contract, then approve router + for (uint256 i = 0; i < tokenAmounts.length; i++) { + IERC20(tokenAmounts[i].token).safeTransferFrom(msg.sender, address(this), tokenAmounts[i].amount); + IERC20(tokenAmounts[i].token).safeIncreaseAllowance(address(i_router), tokenAmounts[i].amount); + } + + messageId = i_router.ccipSend{value: fees}(destChainSelector, message); + + // Refund excess native to caller + uint256 excess = msg.value - fees; + if (excess > 0) { + (bool sent, ) = msg.sender.call{value: excess}(""); + if (!sent) revert FailedToWithdrawEth(msg.sender, msg.sender, excess); + } + } else { + // ERC20 fee payment — handle the case where feeToken == a transfer token + bool feeIncludedInTransfer = false; + + for (uint256 i = 0; i < tokenAmounts.length; i++) { + if (tokenAmounts[i].token == feeToken && !feeIncludedInTransfer) { + // Fee token matches this transfer token: pull combined amount in one transferFrom + uint256 combined = tokenAmounts[i].amount + fees; + IERC20(feeToken).safeTransferFrom(msg.sender, address(this), combined); + IERC20(feeToken).safeIncreaseAllowance(address(i_router), combined); + feeIncludedInTransfer = true; + } else { + IERC20(tokenAmounts[i].token).safeTransferFrom(msg.sender, address(this), tokenAmounts[i].amount); + IERC20(tokenAmounts[i].token).safeIncreaseAllowance(address(i_router), tokenAmounts[i].amount); + } + } + + // If fee token was not among the transfer tokens, pull it separately + if (!feeIncludedInTransfer) { + IERC20(feeToken).safeTransferFrom(msg.sender, address(this), fees); + IERC20(feeToken).safeIncreaseAllowance(address(i_router), fees); + } + + messageId = i_router.ccipSend(destChainSelector, message); + } + + emit MessageSent(messageId, destChainSelector); + + return messageId; + } + + /// @notice Pause all sends (owner only). Use in case of emergency. + function pause() external onlyOwner { + _pause(); + } + + /// @notice Unpause sends (owner only). + function unpause() external onlyOwner { + _unpause(); + } + + /// @notice Fallback to allow the contract to receive native currency. + receive() external payable {} + + /// @notice Withdraw native currency from this contract (owner only). + /// @param beneficiary The address to send the native currency to. + function withdraw(address beneficiary) public onlyOwner { + uint256 amount = address(this).balance; + if (amount == 0) revert NothingToWithdraw(); + + (bool sent, ) = beneficiary.call{value: amount}(""); + if (!sent) revert FailedToWithdrawEth(msg.sender, beneficiary, amount); + } + + /// @notice Withdraw ERC20 tokens from this contract (owner only). + /// @dev Pass 0 for amount to withdraw the full balance. + /// @param beneficiary The address to send the tokens to. + /// @param token The ERC20 token contract address. + /// @param amount The amount to withdraw (0 = full balance). + function withdrawToken(address beneficiary, address token, uint256 amount) public onlyOwner { + uint256 balance = IERC20(token).balanceOf(address(this)); + if (balance == 0) revert NothingToWithdraw(); + + uint256 transferAmount = amount == 0 ? balance : amount; + IERC20(token).safeTransfer(beneficiary, transferAmount); + } +} diff --git a/examples/04-hardhat-ccip/hardhat.config.ts b/examples/04-hardhat-ccip/hardhat.config.ts new file mode 100644 index 0000000..1bb7726 --- /dev/null +++ b/examples/04-hardhat-ccip/hardhat.config.ts @@ -0,0 +1,121 @@ +import "dotenv/config"; +import { defineConfig, configVariable, task } from "hardhat/config"; +import { NETWORKS, getChainIdForNetwork } from "@ccip-examples/shared-config"; + +// Build Hardhat network entries from shared-config NETWORKS (EVM only) +// Network names === CCIP SDK canonical networkIds — no mapping needed +const networks = Object.fromEntries( + Object.entries(NETWORKS) + .filter(([id]) => getChainIdForNetwork(id) !== undefined) + .map(([id]) => [ + id, + { + type: "http" as const, + url: configVariable(`RPC_${id.toUpperCase().replace(/-/g, "_")}`), + accounts: [configVariable("EVM_PRIVATE_KEY")], + }, + ]) +); + +// Register tasks +const tasks = [ + task("deploy-sender", "Deploy CCIPSender contract") + .addOption({ + name: "peerChain", + description: "Destination chain to register as peer (network ID)", + defaultValue: "", + }) + .addOption({ + name: "peerAddress", + description: "Trusted receiver address on the peer chain", + defaultValue: "", + }) + .setAction(() => import("./tasks/deploy-sender.js")) + .build(), + + task("deploy-receiver", "Deploy CCIPReceiverExample contract") + .addOption({ + name: "allowlistChain", + description: "Source chain to allowlist (network ID)", + defaultValue: "", + }) + .addOption({ + name: "allowlistSender", + description: "Sender address to allowlist", + defaultValue: "", + }) + .setAction(() => import("./tasks/deploy-receiver.js")) + .build(), + + task("send-via-sender", "Send CCIP message through deployed sender contract") + .addOption({ name: "dest", description: "Destination network ID", defaultValue: "" }) + .addOption({ + name: "senderContract", + description: "Deployed CCIPSender address", + defaultValue: "", + }) + .addOption({ + name: "receiver", + description: "Receiver address on destination", + defaultValue: "", + }) + .addOption({ name: "mode", description: "Message mode: tt, data, or ptt", defaultValue: "" }) + .addOption({ + name: "amount", + description: "Token amount (for tt/ptt modes)", + defaultValue: "0", + }) + .addOption({ + name: "token", + description: "Token key (e.g. CCIP-BnM)", + defaultValue: "CCIP-BnM", + }) + .addOption({ + name: "feeToken", + description: "Fee payment: native or link", + defaultValue: "native", + }) + .addOption({ name: "gasLimit", description: "Dest execution gas limit", defaultValue: "0" }) + .addOption({ name: "data", description: "Hex-encoded data payload", defaultValue: "" }) + .setAction(() => import("./tasks/send-via-sender.js")) + .build(), + + task("send-via-router", "Send CCIP message directly via router using SDK") + .addOption({ name: "dest", description: "Destination network ID", defaultValue: "" }) + .addOption({ + name: "receiver", + description: "Receiver address on destination", + defaultValue: "", + }) + .addOption({ name: "mode", description: "Message mode: tt, data, or ptt", defaultValue: "" }) + .addOption({ + name: "amount", + description: "Token amount (for tt/ptt modes)", + defaultValue: "0", + }) + .addOption({ + name: "token", + description: "Token key (e.g. CCIP-BnM)", + defaultValue: "CCIP-BnM", + }) + .addOption({ + name: "feeToken", + description: "Fee payment: native or link", + defaultValue: "native", + }) + .addOption({ name: "gasLimit", description: "Dest execution gas limit", defaultValue: "0" }) + .addOption({ name: "data", description: "Hex-encoded data payload", defaultValue: "" }) + .setAction(() => import("./tasks/send-via-router.js")) + .build(), + + task("check-status", "Check CCIP message delivery status") + .addOption({ name: "messageId", description: "CCIP message ID to check", defaultValue: "" }) + .setAction(() => import("./tasks/check-status.js")) + .build(), +]; + +export default defineConfig({ + solidity: { version: "0.8.24" }, + networks, + tasks, +}); diff --git a/examples/04-hardhat-ccip/helpers/sdk.ts b/examples/04-hardhat-ccip/helpers/sdk.ts new file mode 100644 index 0000000..bb5ea94 --- /dev/null +++ b/examples/04-hardhat-ccip/helpers/sdk.ts @@ -0,0 +1,57 @@ +/** + * SDK helper functions for Hardhat tasks + * + * Reuses shared packages and wraps CCIP SDK operations + * for convenient use in Hardhat tasks. + */ + +import { createPublicClient, createWalletClient, http, defineChain } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; +import { networkInfo } from "@chainlink/ccip-sdk"; +import { NETWORKS, getChainIdForNetwork } from "@ccip-examples/shared-config"; + +/** + * Create viem clients for a given network + */ +export function createClients(networkId: string) { + const network = NETWORKS[networkId]; + if (!network) throw new Error(`Unknown network: ${networkId}`); + + const chainId = getChainIdForNetwork(networkId); + if (chainId === undefined) throw new Error(`Not an EVM network: ${networkId}`); + + const privateKey = process.env.EVM_PRIVATE_KEY; + if (!privateKey) throw new Error("EVM_PRIVATE_KEY env var not set"); + + const account = privateKeyToAccount(privateKey as `0x${string}`); + const transport = http(network.rpcUrl); + const chain = defineChain({ + id: chainId, + name: network.name, + nativeCurrency: network.nativeCurrency, + rpcUrls: { default: { http: [network.rpcUrl] } }, + }); + + return { + account, + chain, + publicClient: createPublicClient({ chain, transport }), + walletClient: createWalletClient({ account, chain, transport }), + }; +} + +/** + * Get the CCIP router address for a network + */ +export function getRouterAddress(networkId: string): string { + const network = NETWORKS[networkId]; + if (!network) throw new Error(`Unknown network: ${networkId}`); + return network.routerAddress; +} + +/** + * Get the CCIP chain selector for a network + */ +export function getDestChainSelector(networkId: string): bigint { + return networkInfo(networkId).chainSelector; +} diff --git a/examples/04-hardhat-ccip/package.json b/examples/04-hardhat-ccip/package.json new file mode 100644 index 0000000..998b32f --- /dev/null +++ b/examples/04-hardhat-ccip/package.json @@ -0,0 +1,35 @@ +{ + "name": "@ccip-examples/04-hardhat-ccip", + "version": "1.0.0", + "description": "Hardhat v3 project with CCIP SDK for deploying and interacting with custom Sender/Receiver contracts", + "type": "module", + "scripts": { + "build": "hardhat compile", + "typecheck": "tsc --noEmit", + "lint": "solhint --max-warnings 0 \"./contracts/**/*.sol\" && eslint hardhat.config.ts tasks helpers --max-warnings 0", + "lint:fix": "solhint --fix --max-warnings 0 \"./contracts/**/*.sol\" --noPrompt && eslint hardhat.config.ts tasks helpers --fix", + "clean": "hardhat clean && rm -rf dist" + }, + "dependencies": { + "@ccip-examples/shared-config": "workspace:*", + "@ccip-examples/shared-utils": "workspace:*", + "@chainlink/ccip-sdk": "1.2.0", + "@chainlink/contracts-ccip": "^1.6.4", + "@openzeppelin/contracts": "^5.1.0", + "dotenv": "^16.4.5", + "viem": "^2.21.0" + }, + "devDependencies": { + "hardhat": "^3.0.0", + "solhint": "^6.0.2", + "solhint-plugin-chainlink-solidity": "github:smartcontractkit/chainlink-solhint-rules#v1.2.1", + "typescript": "^5.9.3" + }, + "keywords": [ + "ccip", + "hardhat", + "smart-contracts", + "sender", + "receiver" + ] +} diff --git a/examples/04-hardhat-ccip/tasks/check-status.ts b/examples/04-hardhat-ccip/tasks/check-status.ts new file mode 100644 index 0000000..3a9cfb0 --- /dev/null +++ b/examples/04-hardhat-ccip/tasks/check-status.ts @@ -0,0 +1,106 @@ +/** + * Task: Check CCIP message delivery status + * + * Uses the CCIP API client from the SDK to query message status + * with built-in retry logic for transient errors. + * + * Usage: + * npx hardhat check-status --message-id 0x... + */ + +import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; +import { + CCIPAPIClient, + getCCIPExplorerUrl, + CCIPMessageIdNotFoundError, + CCIPError, + withRetry, +} from "@chainlink/ccip-sdk"; +import { getStatusDescription, POLLING_CONFIG } from "@ccip-examples/shared-config"; + +interface CheckStatusArgs { + messageId: string; +} + +const checkStatus = async ( + args: CheckStatusArgs, + _hre: HardhatRuntimeEnvironment +): Promise => { + const { messageId } = args; + + console.log(`\nChecking status for message: ${messageId}`); + console.log(` CCIP Explorer: ${getCCIPExplorerUrl("msg", messageId)}`); + console.log(`\nQuerying CCIP API (with retry for transient errors)...\n`); + + const apiClient = new CCIPAPIClient(); + + try { + // Use SDK's built-in retry logic for transient errors (e.g. indexing delay) + const request = await withRetry(() => apiClient.getMessageById(messageId), { + maxRetries: Math.min(POLLING_CONFIG.maxNotFoundRetries, 10), + initialDelayMs: POLLING_CONFIG.initialDelay, + maxDelayMs: POLLING_CONFIG.maxDelay, + backoffMultiplier: 1.5, + respectRetryAfterHint: true, + logger: { + debug: (...debugArgs: unknown[]) => console.log(" [retry]", ...debugArgs), + warn: (...warnArgs: unknown[]) => console.warn(" [retry]", ...warnArgs), + }, + }); + + const { metadata } = request; + const status = metadata.status; + const description = getStatusDescription(status); + + console.log(` Status: ${status}`); + console.log(` Description: ${description}`); + console.log(` Source: ${metadata.sourceNetworkInfo.name}`); + console.log(` Destination: ${metadata.destNetworkInfo.name}`); + + if (metadata.receiptTransactionHash) { + console.log(` Dest tx: ${metadata.receiptTransactionHash}`); + } + + if (metadata.deliveryTime != null) { + const seconds = Number(metadata.deliveryTime) / 1000; + console.log(` Delivery: ${seconds.toFixed(1)}s`); + } + + if (status === "SUCCESS") { + console.log(`\n Message delivered successfully!`); + } else if (status === "FAILED") { + console.error(`\n Message execution failed on destination.`); + console.log(` Check CCIP Explorer for details.`); + } else { + console.log(`\n Message still in progress. Check again later or view in explorer:`); + console.log(` ${getCCIPExplorerUrl("msg", messageId)}`); + } + + if (metadata.readyForManualExecution) { + console.log(`\n This message is ready for manual execution.`); + } + } catch (error) { + if (error instanceof CCIPMessageIdNotFoundError) { + console.log(" Message not found."); + console.log(); + console.log(" Possible reasons:"); + console.log(" - Message was sent recently and not yet indexed"); + console.log(" - Message ID is incorrect"); + console.log(); + console.log(" Try checking CCIP Explorer:"); + console.log(` ${getCCIPExplorerUrl("msg", messageId)}`); + } else if (CCIPError.isCCIPError(error)) { + console.error(` Error: ${error.message}`); + if (error.recovery) { + console.error(` Recovery: ${error.recovery}`); + } + if (error.isTransient) { + console.error(" Note: This error may be transient. Try again later."); + } + } else { + console.error(` Error: ${error instanceof Error ? error.message : String(error)}`); + } + } +}; + +export default checkStatus; diff --git a/examples/04-hardhat-ccip/tasks/deploy-receiver.ts b/examples/04-hardhat-ccip/tasks/deploy-receiver.ts new file mode 100644 index 0000000..dced5c3 --- /dev/null +++ b/examples/04-hardhat-ccip/tasks/deploy-receiver.ts @@ -0,0 +1,73 @@ +/** + * Task: Deploy CCIPReceiverExample contract + * + * Usage: + * npx hardhat --network ethereum-testnet-sepolia-base-1 deploy-receiver + * npx hardhat --network ethereum-testnet-sepolia-base-1 deploy-receiver \ + * --allowlist-chain ethereum-testnet-sepolia \ + * --allowlist-sender 0x1234... + */ + +import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; +import { networkInfo } from "@chainlink/ccip-sdk"; +import { getExplorerTxUrl } from "@ccip-examples/shared-config"; +import { createClients, getRouterAddress } from "../helpers/sdk.js"; + +interface DeployReceiverArgs { + allowlistChain: string; + allowlistSender: string; +} + +const deployReceiver = async ( + args: DeployReceiverArgs, + hre: HardhatRuntimeEnvironment +): Promise => { + const connection = await hre.network.connect(); + const networkId = connection.networkName; + const routerAddress = getRouterAddress(networkId); + + console.log(`\nDeploying CCIPReceiverExample on ${networkId}...`); + console.log(` Router: ${routerAddress}`); + + const { publicClient, walletClient } = createClients(networkId); + const artifact = await hre.artifacts.readArtifact("CCIPReceiverExample"); + + const hash = await walletClient.deployContract({ + abi: artifact.abi, + bytecode: artifact.bytecode as `0x${string}`, + args: [routerAddress as `0x${string}`], + }); + + console.log(` Tx hash: ${hash}`); + console.log(` Explorer: ${getExplorerTxUrl(networkId, hash)}`); + + const receipt = await publicClient.waitForTransactionReceipt({ hash }); + + if (!receipt.contractAddress) { + throw new Error("Deployment failed: no contract address in receipt"); + } + + const receiverAddress = receipt.contractAddress; + console.log(`\n CCIPReceiverExample deployed at: ${receiverAddress}`); + + // Optionally allowlist a sender on a specific source chain + if (args.allowlistChain !== "" && args.allowlistSender !== "") { + const sourceChainSelector = networkInfo(args.allowlistChain).chainSelector; + console.log( + `\n Allowlisting sender ${args.allowlistSender} on source chain ${args.allowlistChain} (selector: ${sourceChainSelector})` + ); + + const allowlistHash = await walletClient.writeContract({ + address: receiverAddress, + abi: artifact.abi, + functionName: "allowlistSender", + args: [sourceChainSelector, args.allowlistSender as `0x${string}`, true], + }); + await publicClient.waitForTransactionReceipt({ hash: allowlistHash }); + console.log(` Sender allowlisted on source chain.`); + } + + console.log(`\nSave this address for use as --receiver in send tasks.`); +}; + +export default deployReceiver; diff --git a/examples/04-hardhat-ccip/tasks/deploy-sender.ts b/examples/04-hardhat-ccip/tasks/deploy-sender.ts new file mode 100644 index 0000000..71b4826 --- /dev/null +++ b/examples/04-hardhat-ccip/tasks/deploy-sender.ts @@ -0,0 +1,73 @@ +/** + * Task: Deploy CCIPSender contract + * + * Usage: + * npx hardhat --network ethereum-testnet-sepolia deploy-sender + * npx hardhat --network ethereum-testnet-sepolia deploy-sender \ + * --peer-chain ethereum-testnet-sepolia-base-1 \ + * --peer-address 0x1234... + */ + +import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; +import { networkInfo } from "@chainlink/ccip-sdk"; +import { getExplorerTxUrl } from "@ccip-examples/shared-config"; +import { createClients, getRouterAddress } from "../helpers/sdk.js"; + +interface DeploySenderArgs { + peerChain: string; + peerAddress: string; +} + +const deploySender = async ( + args: DeploySenderArgs, + hre: HardhatRuntimeEnvironment +): Promise => { + const connection = await hre.network.connect(); + const networkId = connection.networkName; + const routerAddress = getRouterAddress(networkId); + + console.log(`\nDeploying CCIPSender on ${networkId}...`); + console.log(` Router: ${routerAddress}`); + + const { publicClient, walletClient } = createClients(networkId); + const artifact = await hre.artifacts.readArtifact("CCIPSender"); + + const hash = await walletClient.deployContract({ + abi: artifact.abi, + bytecode: artifact.bytecode as `0x${string}`, + args: [routerAddress as `0x${string}`], + }); + + console.log(` Tx hash: ${hash}`); + console.log(` Explorer: ${getExplorerTxUrl(networkId, hash)}`); + + const receipt = await publicClient.waitForTransactionReceipt({ hash }); + + if (!receipt.contractAddress) { + throw new Error("Deployment failed: no contract address in receipt"); + } + + const senderAddress = receipt.contractAddress; + console.log(`\n CCIPSender deployed at: ${senderAddress}`); + + // Optionally register a peer (trusted destination chain + receiver) + if (args.peerChain !== "" && args.peerAddress !== "") { + const destChainSelector = networkInfo(args.peerChain).chainSelector; + console.log( + `\n Registering peer ${args.peerAddress} on dest chain ${args.peerChain} (selector: ${destChainSelector})` + ); + + const setPeerHash = await walletClient.writeContract({ + address: senderAddress, + abi: artifact.abi, + functionName: "setPeer", + args: [destChainSelector, args.peerAddress as `0x${string}`], + }); + await publicClient.waitForTransactionReceipt({ hash: setPeerHash }); + console.log(` Peer registered.`); + } + + console.log(`\nSave this address for use with send-via-sender task.`); +}; + +export default deploySender; diff --git a/examples/04-hardhat-ccip/tasks/send-via-router.ts b/examples/04-hardhat-ccip/tasks/send-via-router.ts new file mode 100644 index 0000000..bb1c434 --- /dev/null +++ b/examples/04-hardhat-ccip/tasks/send-via-router.ts @@ -0,0 +1,217 @@ +/** + * Task: Send CCIP message directly through the router using the SDK + * + * Demonstrates the SDK building the complete message and interacting with + * the router directly (no custom sender contract needed). + * + * Gas limit is auto-estimated via the SDK's estimateReceiveExecution() when + * not explicitly provided (for data and ptt modes). + * + * Usage: + * # Token transfer — gasLimit auto 0 + * npx hardhat --network ethereum-testnet-sepolia send-via-router \ + * --dest ethereum-testnet-sepolia-base-1 \ + * --receiver 0x... --mode tt --amount 0.001 --token CCIP-BnM + * + * # Data-only — gasLimit auto-estimated + * npx hardhat --network ethereum-testnet-sepolia send-via-router \ + * --dest ethereum-testnet-sepolia-base-1 \ + * --receiver 0x... --mode data + * + * # Programmable token transfer — gasLimit auto-estimated + * npx hardhat --network ethereum-testnet-sepolia send-via-router \ + * --dest ethereum-testnet-sepolia-base-1 \ + * --receiver 0x... --mode ptt --amount 0.001 --token CCIP-BnM + */ + +import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; +import { encodePacked, encodeAbiParameters, parseUnits } from "viem"; +import { + type MessageInput, + estimateReceiveExecution, + getCCIPExplorerUrl, +} from "@chainlink/ccip-sdk"; +import { fromViemClient, viemWallet } from "@chainlink/ccip-sdk/viem"; +import { + type FeeTokenOption, + getExplorerTxUrl, + getTokenAddress, + resolveFeeTokenAddress, +} from "@ccip-examples/shared-config"; +import { buildTokenTransferMessage } from "@ccip-examples/shared-utils"; +import { createClients, getRouterAddress, getDestChainSelector } from "../helpers/sdk.js"; + +interface SendViaRouterArgs { + dest: string; + receiver: string; + mode: string; + amount: string; + token: string; + feeToken: string; + gasLimit: string; + data: string; +} + +const sendViaRouter = async ( + args: SendViaRouterArgs, + hre: HardhatRuntimeEnvironment +): Promise => { + const connection = await hre.network.connect(); + const sourceNetworkId = connection.networkName; + const { mode, dest, receiver } = args; + + console.log(`\nSending CCIP message directly via router (SDK)...`); + console.log(` Source: ${sourceNetworkId}`); + console.log(` Destination: ${dest}`); + console.log(` Mode: ${mode}`); + console.log(` Receiver: ${receiver}`); + + const routerAddress = getRouterAddress(sourceNetworkId); + const destChainSelector = getDestChainSelector(dest); + + // Create viem clients and SDK chains for source and destination + const { account, publicClient, walletClient } = createClients(sourceNetworkId); + const { publicClient: destPublicClient } = createClients(dest); + const sourceChain = await fromViemClient(publicClient); + const destChain = await fromViemClient(destPublicClient); + + // Resolve fee token + const feeTokenOption = args.feeToken as FeeTokenOption; + const feeToken = resolveFeeTokenAddress(feeTokenOption, sourceNetworkId); + + // Determine gasLimit: use provided value or auto-estimate via SDK + let gasLimit: bigint; + if (args.gasLimit !== "0") { + gasLimit = BigInt(args.gasLimit); + console.log(` Gas limit (manual): ${gasLimit}`); + } else if (mode === "tt") { + // Token-only transfers don't execute receiver logic + gasLimit = 0n; + console.log(` Gas limit: 0 (token-only, no receiver execution)`); + } else { + // Build a preliminary data payload for estimation + let estimationData = "0x"; + const estimationTokenAmounts: { token: string; amount: bigint }[] = []; + + if (mode === "data") { + estimationData = encodePacked(["string"], ["Hello from CCIP!"]); + } else if (mode === "ptt") { + const tokenAddress = getTokenAddress(args.token, sourceNetworkId); + if (!tokenAddress) throw new Error(`Token ${args.token} not found on ${sourceNetworkId}`); + const tokenInfo = await sourceChain.getTokenInfo(tokenAddress); + const amount = parseUnits(args.amount, tokenInfo.decimals); + estimationData = + args.data !== "" + ? args.data + : encodeAbiParameters([{ type: "address" }], [receiver as `0x${string}`]); + estimationTokenAmounts.push({ token: tokenAddress, amount }); + } + + console.log(`\n Estimating destination gas for ccipReceive...`); + const estimatedGas = await estimateReceiveExecution({ + source: sourceChain, + dest: destChain, + routerOrRamp: routerAddress, + message: { + sender: account.address, + receiver, + data: estimationData, + tokenAmounts: estimationTokenAmounts, + }, + }); + + // Add 10% safety margin + gasLimit = BigInt(Math.ceil(estimatedGas * 1.1)); + console.log(` Gas limit (estimated): ${estimatedGas} → ${gasLimit} (with 10% margin)`); + } + + // Build message based on mode + let message: MessageInput; + + if (mode === "tt") { + // Token transfer - use shared-utils helper + const tokenAddress = getTokenAddress(args.token, sourceNetworkId); + if (!tokenAddress) throw new Error(`Token ${args.token} not found on ${sourceNetworkId}`); + + const tokenInfo = await sourceChain.getTokenInfo(tokenAddress); + const amount = parseUnits(args.amount, tokenInfo.decimals); + + message = buildTokenTransferMessage({ + receiver, + tokenAddress, + amount, + feeToken, + }); + console.log(` Token: ${tokenInfo.symbol} (${tokenAddress})`); + console.log(` Amount: ${args.amount}`); + } else if (mode === "data") { + // Data-only message + const dataPayload = encodePacked(["string"], ["Hello from CCIP!"]); + message = { + receiver, + data: dataPayload, + extraArgs: { gasLimit, allowOutOfOrderExecution: true }, + ...(feeToken && { feeToken }), + }; + console.log(` Data: ${dataPayload}`); + console.log(` Gas limit: ${gasLimit}`); + } else if (mode === "ptt") { + // Programmable token transfer + const tokenAddress = getTokenAddress(args.token, sourceNetworkId); + if (!tokenAddress) throw new Error(`Token ${args.token} not found on ${sourceNetworkId}`); + + const tokenInfo = await sourceChain.getTokenInfo(tokenAddress); + const amount = parseUnits(args.amount, tokenInfo.decimals); + const dataPayload = + args.data !== "" + ? args.data + : encodeAbiParameters([{ type: "address" }], [receiver as `0x${string}`]); + + message = { + receiver, + data: dataPayload, + tokenAmounts: [{ token: tokenAddress, amount }], + extraArgs: { gasLimit, allowOutOfOrderExecution: true }, + ...(feeToken && { feeToken }), + }; + console.log(` Token: ${tokenInfo.symbol}, Amount: ${args.amount}`); + console.log(` Data: ${dataPayload}`); + console.log(` Gas limit: ${gasLimit}`); + } else { + throw new Error(`Unknown mode: ${mode}. Use tt, data, or ptt.`); + } + + // Get fee estimate + console.log(`\n Estimating fee...`); + const fee = await sourceChain.getFee({ + router: routerAddress, + destChainSelector, + message, + }); + console.log(` Fee: ${fee} (smallest unit)`); + + // Send message using SDK (handles approvals + ccipSend) + console.log(`\n Sending message from ${account.address}...`); + + const result = await sourceChain.sendMessage({ + router: routerAddress, + destChainSelector, + message: { ...message, fee }, + wallet: viemWallet(walletClient), + }); + + const txHash = result.tx.hash; + console.log(` Tx hash: ${txHash}`); + console.log(` Explorer: ${getExplorerTxUrl(sourceNetworkId, txHash)}`); + + // Extract messageId from the result + const messageId = result.message.messageId; + console.log(`\n Message ID: ${messageId}`); + console.log(` CCIP Explorer: ${getCCIPExplorerUrl("msg", messageId)}`); + console.log(`\n Track status with:`); + console.log(` npx hardhat check-status --message-id ${messageId}`); + + console.log(`\nDone! Message sent directly via router.`); +}; + +export default sendViaRouter; diff --git a/examples/04-hardhat-ccip/tasks/send-via-sender.ts b/examples/04-hardhat-ccip/tasks/send-via-sender.ts new file mode 100644 index 0000000..8a1529c --- /dev/null +++ b/examples/04-hardhat-ccip/tasks/send-via-sender.ts @@ -0,0 +1,222 @@ +/** + * Task: Send CCIP message through the deployed CCIPSender contract + * + * Demonstrates the "extraArgs passthrough" pattern: + * 1. Build extraArgs offchain using the CCIP SDK's encodeExtraArgs() + * 2. Pass them to the sender contract which forwards them to the router + * + * Gas limit is auto-estimated via the SDK's estimateReceiveExecution() when + * not explicitly provided (for data and ptt modes). + * + * Usage: + * # Token transfer (TT) — gasLimit auto 0 + * npx hardhat --network ethereum-testnet-sepolia send-via-sender \ + * --dest ethereum-testnet-sepolia-base-1 \ + * --sender-contract 0x... --receiver 0x... \ + * --mode tt --amount 0.001 --token CCIP-BnM + * + * # Data-only — gasLimit auto-estimated + * npx hardhat --network ethereum-testnet-sepolia send-via-sender \ + * --dest ethereum-testnet-sepolia-base-1 \ + * --sender-contract 0x... --receiver 0x... \ + * --mode data + * + * # Programmable token transfer (PTT) — gasLimit auto-estimated + * npx hardhat --network ethereum-testnet-sepolia send-via-sender \ + * --dest ethereum-testnet-sepolia-base-1 \ + * --sender-contract 0x... --receiver 0x... \ + * --mode ptt --amount 0.001 --token CCIP-BnM + */ + +import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; +import { parseUnits, encodePacked, encodeAbiParameters, erc20Abi } from "viem"; +import { encodeExtraArgs, estimateReceiveExecution, getCCIPExplorerUrl } from "@chainlink/ccip-sdk"; +import { fromViemClient } from "@chainlink/ccip-sdk/viem"; +import { + type FeeTokenOption, + getExplorerTxUrl, + getTokenAddress, + resolveFeeTokenAddress, +} from "@ccip-examples/shared-config"; +import { createClients, getRouterAddress, getDestChainSelector } from "../helpers/sdk.js"; + +interface SendViaSenderArgs { + dest: string; + senderContract: string; + receiver: string; + mode: string; + amount: string; + token: string; + feeToken: string; + gasLimit: string; + data: string; +} + +const sendViaSender = async ( + args: SendViaSenderArgs, + hre: HardhatRuntimeEnvironment +): Promise => { + const connection = await hre.network.connect(); + const sourceNetworkId = connection.networkName; + const { mode, dest, receiver } = args; + + console.log(`\nSending CCIP message via sender contract...`); + console.log(` Source: ${sourceNetworkId}`); + console.log(` Destination: ${dest}`); + console.log(` Mode: ${mode}`); + console.log(` Receiver: ${receiver}`); + + const { account, publicClient, walletClient } = createClients(sourceNetworkId); + const { publicClient: destPublicClient } = createClients(dest); + const senderArtifact = await hre.artifacts.readArtifact("CCIPSender"); + const destChainSelector = getDestChainSelector(dest); + const routerAddress = getRouterAddress(sourceNetworkId); + + // Build token amounts (for tt and ptt modes) + interface TokenAmount { + token: `0x${string}`; + amount: bigint; + } + let tokenAmounts: TokenAmount[] = []; + + if (mode === "tt" || mode === "ptt") { + const tokenAddress = getTokenAddress(args.token, sourceNetworkId); + if (!tokenAddress) throw new Error(`Token ${args.token} not found on ${sourceNetworkId}`); + + const decimals = await publicClient.readContract({ + address: tokenAddress as `0x${string}`, + abi: erc20Abi, + functionName: "decimals", + }); + + const amount = parseUnits(args.amount, decimals); + tokenAmounts = [{ token: tokenAddress as `0x${string}`, amount }]; + } + + // Build data payload + let data: `0x${string}` = "0x"; + if (mode === "data") { + data = encodePacked(["string"], ["Hello from CCIP!"]); + console.log(` Data: ${data}`); + } else if (mode === "ptt") { + data = + args.data !== "" + ? (args.data as `0x${string}`) + : encodeAbiParameters([{ type: "address" }], [receiver as `0x${string}`]); + console.log(` Data (encoded address): ${data}`); + } + + // Determine gasLimit: use provided value or auto-estimate via SDK + let gasLimit: bigint; + if (args.gasLimit !== "0") { + gasLimit = BigInt(args.gasLimit); + console.log(` Gas limit (manual): ${gasLimit}`); + } else if (mode === "tt") { + // Token-only transfers don't execute receiver logic + gasLimit = 0n; + console.log(` Gas limit: 0 (token-only, no receiver execution)`); + } else { + // Auto-estimate gas for data/ptt modes using SDK + console.log(`\n Estimating destination gas for ccipReceive...`); + const sourceChain = await fromViemClient(publicClient); + const destChain = await fromViemClient(destPublicClient); + + const estimatedGas = await estimateReceiveExecution({ + source: sourceChain, + dest: destChain, + routerOrRamp: routerAddress, + message: { + sender: args.senderContract, + receiver, + data, + tokenAmounts: tokenAmounts.map((ta) => ({ + token: ta.token, + amount: ta.amount, + })), + }, + }); + + // Add 10% safety margin + gasLimit = BigInt(Math.ceil(estimatedGas * 1.1)); + console.log(` Gas limit (estimated): ${estimatedGas} → ${gasLimit} (with 10% margin)`); + } + + // Build extraArgs offchain using the SDK + const extraArgs = encodeExtraArgs({ + gasLimit, + allowOutOfOrderExecution: true, + }) as `0x${string}`; + console.log(` Extra args (encoded): ${extraArgs}`); + + const firstToken = tokenAmounts[0]; + if ((mode === "tt" || mode === "ptt") && firstToken) { + // Approve sender contract to spend tokens + console.log(`\n Approving ${args.amount} ${args.token} for sender contract...`); + const approveHash = await walletClient.writeContract({ + address: firstToken.token, + abi: erc20Abi, + functionName: "approve", + args: [args.senderContract as `0x${string}`, firstToken.amount], + }); + await publicClient.waitForTransactionReceipt({ hash: approveHash }); + console.log(` Approved.`); + } + + // Resolve fee token + const feeTokenOption = args.feeToken as FeeTokenOption; + const feeTokenAddress = resolveFeeTokenAddress(feeTokenOption, sourceNetworkId); + const feeTokenForContract = feeTokenAddress + ? (feeTokenAddress as `0x${string}`) + : ("0x0000000000000000000000000000000000000000" as `0x${string}`); + + // If paying with LINK, approve sender contract for fees + if (feeTokenAddress) { + console.log(`\n Approving LINK for fee payment...`); + const approveFeeHash = await walletClient.writeContract({ + address: feeTokenAddress as `0x${string}`, + abi: erc20Abi, + functionName: "approve", + args: [args.senderContract as `0x${string}`, parseUnits("1", 18)], // 1 LINK max + }); + await publicClient.waitForTransactionReceipt({ hash: approveFeeHash }); + console.log(` LINK approved for fees.`); + } + + // Send the message + console.log(`\n Sending CCIP message...`); + const sendHash = await walletClient.writeContract({ + address: args.senderContract as `0x${string}`, + abi: senderArtifact.abi, + functionName: "send", + args: [ + destChainSelector, + receiver as `0x${string}`, + data, + tokenAmounts, + extraArgs, + feeTokenForContract, + ], + value: feeTokenAddress ? 0n : parseUnits("0.01", 18), // Send extra native for fees + account, + }); + + console.log(` Tx hash: ${sendHash}`); + console.log(` Explorer: ${getExplorerTxUrl(sourceNetworkId, sendHash)}`); + + // Extract messageId using the SDK's getMessagesInTx + const chain = await fromViemClient(publicClient); + const requests = await chain.getMessagesInTx(sendHash); + + const firstRequest = requests[0]; + if (firstRequest) { + const messageId = firstRequest.message.messageId; + console.log(`\n Message ID: ${messageId}`); + console.log(` CCIP Explorer: ${getCCIPExplorerUrl("msg", messageId)}`); + console.log(`\n Track status with:`); + console.log(` npx hardhat check-status --message-id ${messageId}`); + } + + console.log(`\nDone! Message sent via sender contract.`); +}; + +export default sendViaSender; diff --git a/examples/04-hardhat-ccip/tsconfig.json b/examples/04-hardhat-ccip/tsconfig.json new file mode 100644 index 0000000..203cd7d --- /dev/null +++ b/examples/04-hardhat-ccip/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": ".", + "noEmit": true + }, + "include": ["hardhat.config.ts", "tasks/**/*", "helpers/**/*"], + "exclude": ["node_modules", "dist", "artifacts", "cache"] +} diff --git a/package.json b/package.json index 6a02b4a..0c8d001 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dev:01": "pnpm -F 01-getting-started dev", "dev:02": "pnpm -F 02-evm-simple-bridge dev", "dev:03": "pnpm -F 03-multichain-bridge-dapp dev", + "dev:04": "pnpm -F 04-hardhat-ccip dev", "prod:02": "pnpm -F 02-evm-simple-bridge build && pnpm -F 02-evm-simple-bridge preview", "prod:03": "pnpm -F 03-multichain-bridge-dapp build && pnpm -F 03-multichain-bridge-dapp preview", "build": "pnpm -r build", diff --git a/packages/shared-components/package.json b/packages/shared-components/package.json index 19262b6..7b9fd33 100644 --- a/packages/shared-components/package.json +++ b/packages/shared-components/package.json @@ -44,7 +44,7 @@ "peerDependencies": { "react": ">=18.0.0", "react-dom": ">=18.0.0", - "@chainlink/ccip-sdk": "1.0.0" + "@chainlink/ccip-sdk": "1.2.0" }, "devDependencies": { "@types/react": "^18.3.12", @@ -52,7 +52,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "typescript": "^5.9.3", - "@chainlink/ccip-sdk": "1.0.0" + "@chainlink/ccip-sdk": "1.2.0" }, "keywords": [ "ccip", diff --git a/packages/shared-config/package.json b/packages/shared-config/package.json index 995512c..f847738 100644 --- a/packages/shared-config/package.json +++ b/packages/shared-config/package.json @@ -39,7 +39,7 @@ "clean": "rm -rf dist" }, "devDependencies": { - "@chainlink/ccip-sdk": "1.0.0", + "@chainlink/ccip-sdk": "1.2.0", "@rainbow-me/rainbowkit": "^2.2.10", "@tanstack/react-query": "^5.62.0", "typescript": "^5.9.3", @@ -53,7 +53,7 @@ "tokens" ], "peerDependencies": { - "@chainlink/ccip-sdk": "1.0.0", + "@chainlink/ccip-sdk": "1.2.0", "@rainbow-me/rainbowkit": ">=2.2.0", "@tanstack/react-query": ">=5.0.0", "viem": ">=2.21.0", diff --git a/packages/shared-utils/package.json b/packages/shared-utils/package.json index 3f639f1..2ec6cd6 100644 --- a/packages/shared-utils/package.json +++ b/packages/shared-utils/package.json @@ -74,7 +74,7 @@ }, "devDependencies": { "typescript": "^5.9.3", - "@chainlink/ccip-sdk": "1.0.0" + "@chainlink/ccip-sdk": "1.2.0" }, "keywords": [ "ccip", @@ -84,6 +84,6 @@ ], "peerDependencies": { "react": ">=18.0.0", - "@chainlink/ccip-sdk": "1.0.0" + "@chainlink/ccip-sdk": "1.2.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 50b90da..5742fa4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,8 +50,8 @@ importers: specifier: workspace:* version: link:../../packages/shared-utils "@chainlink/ccip-sdk": - specifier: 1.0.0 - version: 1.0.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + specifier: 1.2.0 + version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) "@coral-xyz/anchor": specifier: ^0.30.1 version: 0.30.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) @@ -96,8 +96,8 @@ importers: specifier: workspace:* version: link:../../packages/shared-utils "@chainlink/ccip-sdk": - specifier: 1.0.0 - version: 1.0.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + specifier: 1.2.0 + version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) "@rainbow-me/rainbowkit": specifier: ^2.2.10 version: 2.2.10(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.19.5(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)) @@ -146,10 +146,10 @@ importers: dependencies: "@aptos-labs/ts-sdk": specifier: ^5.2.1 - version: 5.2.1(got@11.8.6) + version: 5.2.1(got@12.6.1) "@aptos-labs/wallet-adapter-react": specifier: ^3.7.2 - version: 3.8.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)))(@mizuwallet-sdk/protocol@0.0.6)(@telegram-apps/bridge@1.9.2)(@types/react@18.3.28)(@wallet-standard/core@1.1.1)(aptos@1.22.1(got@11.8.6))(axios@1.13.5)(got@11.8.6)(react@18.3.1) + version: 3.8.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)))(@mizuwallet-sdk/protocol@0.0.6)(@telegram-apps/bridge@1.9.2)(@types/react@18.3.28)(@wallet-standard/core@1.1.1)(aptos@1.22.1(got@12.6.1))(axios@1.13.5)(got@12.6.1)(react@18.3.1) "@ccip-examples/shared-brand": specifier: workspace:* version: link:../../packages/shared-brand @@ -163,8 +163,8 @@ importers: specifier: workspace:* version: link:../../packages/shared-utils "@chainlink/ccip-sdk": - specifier: 1.0.0 - version: 1.0.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + specifier: 1.2.0 + version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) "@rainbow-me/rainbowkit": specifier: ^2.2.10 version: 2.2.10(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) @@ -179,7 +179,7 @@ importers: version: 0.9.35(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bs58@5.0.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(typescript@5.9.3) "@solana/wallet-adapter-wallets": specifier: 0.19.32 - version: 0.19.32(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bs58@5.0.0)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.76) + version: 0.19.32(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bs58@5.0.0)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.76) "@solana/web3.js": specifier: 1.98.0 version: 1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) @@ -224,6 +224,43 @@ importers: specifier: ^0.25.0 version: 0.25.0(rollup@4.57.1)(vite@6.4.1(@types/node@22.19.11)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + examples/04-hardhat-ccip: + dependencies: + "@ccip-examples/shared-config": + specifier: workspace:* + version: link:../../packages/shared-config + "@ccip-examples/shared-utils": + specifier: workspace:* + version: link:../../packages/shared-utils + "@chainlink/ccip-sdk": + specifier: 1.2.0 + version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + "@chainlink/contracts-ccip": + specifier: ^1.6.4 + version: 1.6.4(@types/node@22.19.11)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + "@openzeppelin/contracts": + specifier: ^5.1.0 + version: 5.6.1 + dotenv: + specifier: ^16.4.5 + version: 16.6.1 + viem: + specifier: ^2.21.0 + version: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + devDependencies: + hardhat: + specifier: ^3.0.0 + version: 3.1.12(bufferutil@4.1.0)(utf-8-validate@5.0.10) + solhint: + specifier: ^6.0.2 + version: 6.0.3(typescript@5.9.3) + solhint-plugin-chainlink-solidity: + specifier: github:smartcontractkit/chainlink-solhint-rules#v1.2.1 + version: "@chainlink/solhint-plugin-chainlink-solidity@https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c" + typescript: + specifier: ^5.9.3 + version: 5.9.3 + packages/shared-brand: devDependencies: typescript: @@ -243,8 +280,8 @@ importers: version: link:../shared-utils devDependencies: "@chainlink/ccip-sdk": - specifier: 1.0.0 - version: 1.0.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + specifier: 1.2.0 + version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) "@types/react": specifier: ^18.3.12 version: 18.3.28 @@ -264,8 +301,8 @@ importers: packages/shared-config: devDependencies: "@chainlink/ccip-sdk": - specifier: 1.0.0 - version: 1.0.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + specifier: 1.2.0 + version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) "@rainbow-me/rainbowkit": specifier: ^2.2.10 version: 2.2.10(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) @@ -286,7 +323,7 @@ importers: dependencies: "@aptos-labs/ts-sdk": specifier: ^5.2.1 - version: 5.2.1(got@11.8.6) + version: 5.2.1(got@12.6.1) "@ccip-examples/shared-config": specifier: workspace:* version: link:../shared-config @@ -310,8 +347,8 @@ importers: version: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) devDependencies: "@chainlink/ccip-sdk": - specifier: 1.0.0 - version: 1.0.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + specifier: 1.2.0 + version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) typescript: specifier: ^5.9.3 version: 5.9.3 @@ -477,6 +514,12 @@ packages: "@aptos-labs/ts-sdk": ^3.1.3 || ^4.0.0 || ^5.0.0 "@wallet-standard/core": ^1.0.3 + "@arbitrum/nitro-contracts@3.0.0": + resolution: + { + integrity: sha512-7VzNW9TxvrX9iONDDsi7AZlEUPa6z+cjBkB4Mxlnog9VQZAapRC3CdRXyUzHnBYmUhRzyNJdyxkWPw59QGcLmA==, + } + "@atomrigslab/aptos-wallet-adapter@0.1.21": resolution: { @@ -776,10 +819,10 @@ packages: integrity: sha512-A4Umpi8B9/pqR78D1Yoze4xHyQaujioVRqqO3d6xuDFw9VRtjg6tK3bPlwE0aW+nVH/ntllCpPa2PbI8Rnjcug==, } - "@chainlink/ccip-sdk@1.0.0": + "@chainlink/ccip-sdk@1.2.0": resolution: { - integrity: sha512-Ac1BJvE51/ATXNLFR/MED2QklE/owps6WRqV4LbKL9m05/gvIbt1jm+WGg6I1uAvgoEtzaeSZ+3l9SiqtqwTFA==, + integrity: sha512-XFrNxIXdaEYQqyOQWuxms/QJqA+tJX67EFebI7MPYeBWQMHNnMrVB6pF1yVP9eFk4yisN4+DyZ128rcN4gWfTQ==, } peerDependencies: viem: ^2.0.0 @@ -787,6 +830,142 @@ packages: viem: optional: true + "@chainlink/contracts-ccip@1.6.4": + resolution: + { + integrity: sha512-+kHHZJ4DtSd0mO6EIrPpK9UzEwVhMNR0wzbjuRDcn1UwX4wibnrEbY5RYuGOrTwmXPRoMFsDVeN47O5zgFg5cw==, + } + engines: { node: ">=20", pnpm: ">=10" } + + "@chainlink/contracts@1.5.0": + resolution: + { + integrity: sha512-1fGJwjvivqAxvVOTqZUEXGR54CATtg0vjcXgSIk4Cfoad2nUhSG/qaWHXjLg1CkNTeOoteoxGQcpP/HiA5HsUA==, + } + engines: { node: ">=22", pnpm: ">=10" } + + "@chainlink/solhint-plugin-chainlink-solidity@https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c": + resolution: + { + tarball: https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c, + } + version: 1.2.0 + + "@changesets/apply-release-plan@7.1.0": + resolution: + { + integrity: sha512-yq8ML3YS7koKQ/9bk1PqO0HMzApIFNwjlwCnwFEXMzNe8NpzeeYYKCmnhWJGkN8g7E51MnWaSbqRcTcdIxUgnQ==, + } + + "@changesets/assemble-release-plan@6.0.9": + resolution: + { + integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==, + } + + "@changesets/changelog-git@0.2.1": + resolution: + { + integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==, + } + + "@changesets/cli@2.30.0": + resolution: + { + integrity: sha512-5D3Nk2JPqMI1wK25pEymeWRSlSMdo5QOGlyfrKg0AOufrUcjEE3RQgaCpHoBiM31CSNrtSgdJ0U6zL1rLDDfBA==, + } + hasBin: true + + "@changesets/config@3.1.3": + resolution: + { + integrity: sha512-vnXjcey8YgBn2L1OPWd3ORs0bGC4LoYcK/ubpgvzNVr53JXV5GiTVj7fWdMRsoKUH7hhhMAQnsJUqLr21EncNw==, + } + + "@changesets/errors@0.2.0": + resolution: + { + integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==, + } + + "@changesets/get-dependents-graph@2.1.3": + resolution: + { + integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==, + } + + "@changesets/get-github-info@0.6.0": + resolution: + { + integrity: sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==, + } + + "@changesets/get-release-plan@4.0.15": + resolution: + { + integrity: sha512-Q04ZaRPuEVZtA+auOYgFaVQQSA98dXiVe/yFaZfY7hoSmQICHGvP0TF4u3EDNHWmmCS4ekA/XSpKlSM2PyTS2g==, + } + + "@changesets/get-version-range-type@0.4.0": + resolution: + { + integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==, + } + + "@changesets/git@3.0.4": + resolution: + { + integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==, + } + + "@changesets/logger@0.1.1": + resolution: + { + integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==, + } + + "@changesets/parse@0.4.3": + resolution: + { + integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==, + } + + "@changesets/pre@2.0.2": + resolution: + { + integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==, + } + + "@changesets/read@0.6.7": + resolution: + { + integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==, + } + + "@changesets/should-skip-package@0.1.2": + resolution: + { + integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==, + } + + "@changesets/types@4.1.0": + resolution: + { + integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==, + } + + "@changesets/types@6.1.0": + resolution: + { + integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==, + } + + "@changesets/write@0.4.0": + resolution: + { + integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==, + } + "@coinbase/cdp-sdk@1.44.1": resolution: { @@ -1376,6 +1555,13 @@ packages: } engines: { node: ^20.19.0 || ^22.13.0 || >=24 } + "@eslint/eslintrc@3.3.5": + resolution: + { + integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + "@eslint/js@10.0.1": resolution: { @@ -1402,6 +1588,20 @@ packages: } engines: { node: ^20.19.0 || ^22.13.0 || >=24 } + "@eth-optimism/contracts@0.6.0": + resolution: + { + integrity: sha512-vQ04wfG9kMf1Fwy3FEMqH2QZbgS0gldKhcBeBUPfO8zu68L61VI97UDXmsMQXzTsEAxK8HnokW3/gosl4/NW3w==, + } + peerDependencies: + ethers: ^5 + + "@eth-optimism/core-utils@0.12.0": + resolution: + { + integrity: sha512-qW+7LZYCz7i8dRa7SRlUKIo1VBU8lvN0HeXCxJR+z+xtMzMQpPds20XJNCMclszxYQHkXY00fOT6GvFw9ZL6nw==, + } + "@ethereumjs/common@10.1.1": resolution: { @@ -1473,6 +1673,144 @@ packages: } engines: { node: ">=18" } + "@ethersproject/abi@5.8.0": + resolution: + { + integrity: sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==, + } + + "@ethersproject/abstract-provider@5.8.0": + resolution: + { + integrity: sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==, + } + + "@ethersproject/abstract-signer@5.8.0": + resolution: + { + integrity: sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==, + } + + "@ethersproject/address@5.8.0": + resolution: + { + integrity: sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==, + } + + "@ethersproject/base64@5.8.0": + resolution: + { + integrity: sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==, + } + + "@ethersproject/basex@5.8.0": + resolution: + { + integrity: sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q==, + } + + "@ethersproject/bignumber@5.8.0": + resolution: + { + integrity: sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==, + } + + "@ethersproject/bytes@5.8.0": + resolution: + { + integrity: sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==, + } + + "@ethersproject/constants@5.8.0": + resolution: + { + integrity: sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==, + } + + "@ethersproject/contracts@5.8.0": + resolution: + { + integrity: sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==, + } + + "@ethersproject/hash@5.8.0": + resolution: + { + integrity: sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==, + } + + "@ethersproject/keccak256@5.8.0": + resolution: + { + integrity: sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==, + } + + "@ethersproject/logger@5.8.0": + resolution: + { + integrity: sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==, + } + + "@ethersproject/networks@5.8.0": + resolution: + { + integrity: sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==, + } + + "@ethersproject/properties@5.8.0": + resolution: + { + integrity: sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==, + } + + "@ethersproject/providers@5.8.0": + resolution: + { + integrity: sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==, + } + + "@ethersproject/random@5.8.0": + resolution: + { + integrity: sha512-E4I5TDl7SVqyg4/kkA/qTfuLWAQGXmSOgYyO01So8hLfwgKvYK5snIlzxJMk72IFdG/7oh8yuSqY2KX7MMwg+A==, + } + + "@ethersproject/rlp@5.8.0": + resolution: + { + integrity: sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==, + } + + "@ethersproject/sha2@5.8.0": + resolution: + { + integrity: sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==, + } + + "@ethersproject/signing-key@5.8.0": + resolution: + { + integrity: sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==, + } + + "@ethersproject/strings@5.8.0": + resolution: + { + integrity: sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==, + } + + "@ethersproject/transactions@5.8.0": + resolution: + { + integrity: sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==, + } + + "@ethersproject/web@5.8.0": + resolution: + { + integrity: sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==, + } + "@fivebinaries/coin-selection@3.0.0": resolution: { @@ -1557,6 +1895,13 @@ packages: } engines: { node: ">=12.22" } + "@humanwhocodes/momoa@2.0.4": + resolution: + { + integrity: sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==, + } + engines: { node: ">=10.10.0" } + "@humanwhocodes/retry@0.4.3": resolution: { @@ -1595,6 +1940,18 @@ packages: peerDependencies: "@aptos-labs/ts-sdk": ^1.33.1 || ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 + "@inquirer/external-editor@1.0.3": + resolution: + { + integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==, + } + engines: { node: ">=18" } + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + "@isaacs/cliui@9.0.0": resolution: { @@ -1783,6 +2140,18 @@ packages: integrity: sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==, } + "@manypkg/find-root@1.1.0": + resolution: + { + integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==, + } + + "@manypkg/get-packages@1.1.3": + resolution: + { + integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==, + } + "@metamask/eth-json-rpc-provider@1.0.1": resolution: { @@ -2110,38 +2479,251 @@ packages: } engines: { node: ">= 20.19.0" } - "@particle-network/analytics@1.0.2": + "@nodelib/fs.scandir@2.1.5": resolution: { - integrity: sha512-E4EpTRYcfNOkxj+bgNdQydBrvdLGo4HfVStZCuOr3967dYek30r6L7Nkaa9zJXRE2eGT4lPvcAXDV2WxDZl/Xg==, + integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, } + engines: { node: ">= 8" } - "@particle-network/auth@1.3.1": + "@nodelib/fs.stat@2.0.5": resolution: { - integrity: sha512-hu6ie5RjjN4X+6y/vfjyCsSX3pQuS8k8ZoMb61QWwhWsnZXKzpBUVeAEk55aGfxxXY+KfBkSmZosyaZHGoHnfw==, + integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, } + engines: { node: ">= 8" } - "@particle-network/chains@1.8.3": + "@nodelib/fs.walk@1.2.8": resolution: { - integrity: sha512-WgzY2Hp3tpQYBKXF0pOFdCyJ4yekTTOCzBvBt2tvt7Wbzti2bLyRlfGZAoP57TvIMiy1S1oUfasVfM0Dqd6k5w==, + integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, } + engines: { node: ">= 8" } - "@particle-network/crypto@1.0.1": + "@nomicfoundation/edr-darwin-arm64@0.12.0-next.28": resolution: { - integrity: sha512-GgvHmHcFiNkCLZdcJOgctSbgvs251yp+EAdUydOE3gSoIxN6KEr/Snu9DebENhd/nFb7FDk5ap0Hg49P7pj1fg==, + integrity: sha512-fJsQ8enlgp4Sky98jHcAFXXmb3EYNoYlwtGlmfoYjDsIeL74a2lozNzyo55CtduHD/sugffjtyF0nDyxZEdwMg==, } + engines: { node: ">= 20" } - "@particle-network/solana-wallet@1.3.2": + "@nomicfoundation/edr-darwin-x64@0.12.0-next.28": resolution: { - integrity: sha512-KviKVP87OtWq813y8IumM3rIQMNkTjHBaQmCUbTWGebz3csFOv54JIoy1r+3J3NnA+mBxBdZeRedZ5g+07v75w==, + integrity: sha512-QST3PPJPejfRJhxThR5CoCxQAfIty0n8k40JtI+wLwKGCDT86JRKkJ3AaXPM1a72nUqMYoQK+gzQyA11zZGd4Q==, } - peerDependencies: - "@solana/web3.js": ^1.50.1 - bs58: ^4.0.1 + engines: { node: ">= 20" } + + "@nomicfoundation/edr-linux-arm64-gnu@0.12.0-next.28": + resolution: + { + integrity: sha512-sj4p6jeQfkiePxn1goZFZzz7V0SVFfZDH6ngPileQcAoFBWHKqi17UOG4IZ4NFpjYmDCcdrUWDNRbxC7OhgEqQ==, + } + engines: { node: ">= 20" } + + "@nomicfoundation/edr-linux-arm64-musl@0.12.0-next.28": + resolution: + { + integrity: sha512-d0hV02jMTozPEqRF3PO65Xi6/RqN5EywU5KaiDMcO+8b0nk+pJZ6VdcugRgv3lMMJbM/sP3LDFQn2eoOhalp7w==, + } + engines: { node: ">= 20" } + + "@nomicfoundation/edr-linux-x64-gnu@0.12.0-next.28": + resolution: + { + integrity: sha512-x3z4xbmCtSyZZg9MOhHcw1DOscngj50KK+6ZG0HKkGEbZ7WvDB9BnmRFEWo1rvIM+gqIcZvUBJbpLIdkA/BQYw==, + } + engines: { node: ">= 20" } + + "@nomicfoundation/edr-linux-x64-musl@0.12.0-next.28": + resolution: + { + integrity: sha512-CKGcvP7enTo7gTXVxQiR8txPDOTNqS+wPLPkKXFzQBuVJ0FDj8eKIMRlZaw3Wbcd8QObaAKmKH7KzHVO5zzXmQ==, + } + engines: { node: ">= 20" } + + "@nomicfoundation/edr-win32-x64-msvc@0.12.0-next.28": + resolution: + { + integrity: sha512-QAzb9dZGwOU7Ee2N96dvdSLiUMmjlPVxgLqTKsQbkibcBZ9I+Zs8TGisGUZsDccrbUcR4wDv8S9tD1EM9fEs/g==, + } + engines: { node: ">= 20" } + + "@nomicfoundation/edr@0.12.0-next.28": + resolution: + { + integrity: sha512-DOW5VFGIZWpuB6Llx+5ewn9HingN7uV/6nI3ecB3pZ4qc5OnwxnfG/KatYS6Fq3J55SuWMSxgDMHHA0kAVTFHQ==, + } + engines: { node: ">= 20" } + + "@nomicfoundation/hardhat-errors@3.0.8": + resolution: + { + integrity: sha512-gHAZDYb0e5joq+WecgC3ciz5OcgqUBgK2zLQmNoKSn/I52h3SH1stxXsY4dcVsj0OY4ZksqIRhJDKskHC5DvTA==, + } + + "@nomicfoundation/hardhat-utils@4.0.1": + resolution: + { + integrity: sha512-9xxD6WXLn+kopd+hmF+XYcJJ38Gm06QmZxKf/fIJzlzs9FuNI6C7Lvdd4qHv8/3ReegIbpBCrzozaL2GISmNrA==, + } + + "@nomicfoundation/hardhat-vendored@3.0.1": + resolution: + { + integrity: sha512-jBOAqmEAMJ8zdfiQmTLV+c0IaSyySqkDSJ9spTy8Ts/m/mO8w364TClyfn+p4ZpxBjyX4LMa3NfC402hoDtwCg==, + } + + "@nomicfoundation/hardhat-zod-utils@3.0.3": + resolution: + { + integrity: sha512-WER4/UKLpm7/nz1asvNR7EKZKKBW+48Hw7GOdcd3Rhdr3VTNuTaeIxCJpl6YxTTg+Eq/sPAWX0mr25+USs6KWw==, + } + peerDependencies: + zod: ^3.23.8 + + "@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2": + resolution: + { + integrity: sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==, + } + engines: { node: ">= 12" } + + "@nomicfoundation/solidity-analyzer-darwin-x64@0.1.2": + resolution: + { + integrity: sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==, + } + engines: { node: ">= 12" } + + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.2": + resolution: + { + integrity: sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==, + } + engines: { node: ">= 12" } + + "@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.2": + resolution: + { + integrity: sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==, + } + engines: { node: ">= 12" } + + "@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.2": + resolution: + { + integrity: sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==, + } + engines: { node: ">= 12" } + + "@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.2": + resolution: + { + integrity: sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==, + } + engines: { node: ">= 12" } + + "@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.2": + resolution: + { + integrity: sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==, + } + engines: { node: ">= 12" } + + "@nomicfoundation/solidity-analyzer@0.1.2": + resolution: + { + integrity: sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==, + } + engines: { node: ">= 12" } + + "@offchainlabs/upgrade-executor@1.1.0-beta.0": + resolution: + { + integrity: sha512-mpn6PHjH/KDDjNX0pXHEKdyv8m6DVGQiI2nGzQn0JbM1nOSHJpWx6fvfjtH7YxHJ6zBZTcsKkqGkFKDtCfoSLw==, + } + + "@openzeppelin/contracts-upgradeable@4.7.3": + resolution: + { + integrity: sha512-+wuegAMaLcZnLCJIvrVUDzA9z/Wp93f0Dla/4jJvIhijRrPabjQbZe6fWiECLaJyfn5ci9fqf9vTw3xpQOad2A==, + } + + "@openzeppelin/contracts-upgradeable@4.9.6": + resolution: + { + integrity: sha512-m4iHazOsOCv1DgM7eD7GupTJ+NFVujRZt1wzddDPSVGpWdKq1SKkla5htKG7+IS4d2XOCtzkUNwRZ7Vq5aEUMA==, + } + + "@openzeppelin/contracts@4.7.3": + resolution: + { + integrity: sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw==, + } + + "@openzeppelin/contracts@4.8.3": + resolution: + { + integrity: sha512-bQHV8R9Me8IaJoJ2vPG4rXcL7seB7YVuskr4f+f5RyOStSZetwzkWtoqDMl5erkBJy0lDRUnIR2WIkPiC0GJlg==, + } + + "@openzeppelin/contracts@4.9.6": + resolution: + { + integrity: sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA==, + } + + "@openzeppelin/contracts@5.0.2": + resolution: + { + integrity: sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA==, + } + + "@openzeppelin/contracts@5.1.0": + resolution: + { + integrity: sha512-p1ULhl7BXzjjbha5aqst+QMLY+4/LCWADXOCsmLHRM77AqiPjnd9vvUN9sosUfhL9JGKpZ0TjEGxgvnizmWGSA==, + } + + "@openzeppelin/contracts@5.6.1": + resolution: + { + integrity: sha512-Ly6SlsVJ3mj+b18W3R8gNufB7dTICT105fJhodGAGgyC2oqnBAhqSiNDJ8V8DLY05cCz81GLI0CU5vNYA1EC/w==, + } + + "@particle-network/analytics@1.0.2": + resolution: + { + integrity: sha512-E4EpTRYcfNOkxj+bgNdQydBrvdLGo4HfVStZCuOr3967dYek30r6L7Nkaa9zJXRE2eGT4lPvcAXDV2WxDZl/Xg==, + } + + "@particle-network/auth@1.3.1": + resolution: + { + integrity: sha512-hu6ie5RjjN4X+6y/vfjyCsSX3pQuS8k8ZoMb61QWwhWsnZXKzpBUVeAEk55aGfxxXY+KfBkSmZosyaZHGoHnfw==, + } + + "@particle-network/chains@1.8.3": + resolution: + { + integrity: sha512-WgzY2Hp3tpQYBKXF0pOFdCyJ4yekTTOCzBvBt2tvt7Wbzti2bLyRlfGZAoP57TvIMiy1S1oUfasVfM0Dqd6k5w==, + } + + "@particle-network/crypto@1.0.1": + resolution: + { + integrity: sha512-GgvHmHcFiNkCLZdcJOgctSbgvs251yp+EAdUydOE3gSoIxN6KEr/Snu9DebENhd/nFb7FDk5ap0Hg49P7pj1fg==, + } + + "@particle-network/solana-wallet@1.3.2": + resolution: + { + integrity: sha512-KviKVP87OtWq813y8IumM3rIQMNkTjHBaQmCUbTWGebz3csFOv54JIoy1r+3J3NnA+mBxBdZeRedZ5g+07v75w==, + } + peerDependencies: + "@solana/web3.js": ^1.50.1 + bs58: ^4.0.1 "@paulmillr/qr@0.2.1": resolution: @@ -2150,6 +2732,27 @@ packages: } deprecated: 'The package is now available as "qr": npm install qr' + "@pnpm/config.env-replace@1.1.0": + resolution: + { + integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==, + } + engines: { node: ">=12.22.0" } + + "@pnpm/network.ca-file@1.0.2": + resolution: + { + integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==, + } + engines: { node: ">=12.22.0" } + + "@pnpm/npm-conf@3.0.2": + resolution: + { + integrity: sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==, + } + engines: { node: ">=12" } + "@project-serum/sol-wallet-adapter@0.2.6": resolution: { @@ -2723,6 +3326,12 @@ packages: } engines: { node: ">=16" } + "@scroll-tech/contracts@2.0.0": + resolution: + { + integrity: sha512-O8sVaA/bVKH/mp+bBfUjZ/vYr5mdBExCpKRLre4r9TbXTtiaY9Uo5xU8dcG3weLxyK0BZqDTP2aCNp4Q0f7SeA==, + } + "@scure/base@1.1.9": resolution: { @@ -2777,6 +3386,13 @@ packages: integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==, } + "@sentry/core@9.47.1": + resolution: + { + integrity: sha512-KX62+qIt4xgy8eHKHiikfhz2p5fOciXd0Cl+dNzhgPFq8klq4MGMNaf148GB3M/vBqP4nw/eFvRMAayFCgdRQw==, + } + engines: { node: ">=18" } + "@sinclair/typebox@0.27.10": resolution: { @@ -2796,6 +3412,13 @@ packages: } engines: { node: ">=10" } + "@sindresorhus/is@5.6.0": + resolution: + { + integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==, + } + engines: { node: ">=14.16" } + "@sinonjs/commons@3.0.1": resolution: { @@ -4309,6 +4932,12 @@ packages: peerDependencies: "@solana/web3.js": "*" + "@solidity-parser/parser@0.20.2": + resolution: + { + integrity: sha512-rbu0bzwNvMcwAjH86hiEAcOeRI2EeK8zCkHDrFykh/Al8mvJeFmjy3UrE7GYQjNwOgbGUUtCn5/k8CB8zIu7QA==, + } + "@stellar/js-xdr@3.1.2": resolution: { @@ -4329,6 +4958,18 @@ packages: } engines: { node: ">=20.0.0" } + "@streamparser/json-node@0.0.22": + resolution: + { + integrity: sha512-sJT2ptNRwqB1lIsQrQlCoWk5rF4tif9wDh+7yluAGijJamAhrHGYpFB/Zg3hJeceoZypi74ftXk8DHzwYpbZSg==, + } + + "@streamparser/json@0.0.22": + resolution: + { + integrity: sha512-b6gTSBjJ8G8SuO3Gbbj+zXbVx8NSs1EbpbMKpzGLWMdkR+98McH9bEjSz3+0mPJf68c5nxa3CrJHp5EQNXM6zQ==, + } + "@swc/helpers@0.5.18": resolution: { @@ -4342,6 +4983,13 @@ packages: } engines: { node: ">=10" } + "@szmarczak/http-timer@5.0.1": + resolution: + { + integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==, + } + engines: { node: ">=14.16" } + "@tanstack/query-core@5.90.20": resolution: { @@ -5358,6 +6006,12 @@ packages: integrity: sha512-z3AOibRTE9E8MbjgzxqMpG1RNaBhQ1jnfhNCa1cGf2reZUJzPMYs4TggQTc7j8+0WyV3cr7y/U8Oz99SXIkN5Q==, } + "@yarnpkg/lockfile@1.1.0": + resolution: + { + integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==, + } + abitype@1.0.6: resolution: { @@ -5430,6 +6084,13 @@ packages: engines: { node: ">=0.4.0" } hasBin: true + adm-zip@0.4.16: + resolution: + { + integrity: sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==, + } + engines: { node: ">=0.3.0" } + aes-js@4.0.0-beta.5: resolution: { @@ -5450,18 +6111,45 @@ packages: } engines: { node: ">= 8.0.0" } + ajv-errors@1.0.1: + resolution: + { + integrity: sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==, + } + peerDependencies: + ajv: ">=5.0.0" + ajv@6.12.6: resolution: { integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==, } + ajv@6.14.0: + resolution: + { + integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==, + } + + ajv@8.18.0: + resolution: + { + integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==, + } + anser@1.4.10: resolution: { integrity: sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==, } + ansi-colors@4.1.3: + resolution: + { + integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==, + } + engines: { node: ">=6" } + ansi-escapes@7.3.0: resolution: { @@ -5525,6 +6213,19 @@ packages: integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, } + argparse@2.0.1: + resolution: + { + integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, + } + + array-union@2.1.0: + resolution: + { + integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==, + } + engines: { node: ">=8" } + asap@2.0.6: resolution: { @@ -5543,6 +6244,25 @@ packages: integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==, } + assertion-error@1.1.0: + resolution: + { + integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==, + } + + ast-parents@0.0.1: + resolution: + { + integrity: sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==, + } + + astral-regex@2.0.0: + resolution: + { + integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==, + } + engines: { node: ">=8" } + async-mutex@0.2.6: resolution: { @@ -5561,6 +6281,13 @@ packages: integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, } + at-least-node@1.0.0: + resolution: + { + integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==, + } + engines: { node: ">= 4.0.0" } + atomic-sleep@1.0.0: resolution: { @@ -5693,29 +6420,51 @@ packages: } hasBin: true - bech32@2.0.0: + bech32@1.1.4: resolution: { - integrity: sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==, + integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==, } - big-integer@1.6.36: + bech32@2.0.0: resolution: { - integrity: sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==, + integrity: sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==, } - engines: { node: ">=0.6" } - big.js@6.2.2: + better-ajv-errors@2.0.3: resolution: { - integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==, + integrity: sha512-t1vxUP+vYKsaYi/BbKo2K98nEAZmfi4sjwvmRT8aOPDzPJeAtLurfoIDazVkLILxO4K+Sw4YrLYnBQ46l6pePg==, } + engines: { node: ">= 18.20.6" } + peerDependencies: + ajv: 4.11.8 - 8 - bigint-buffer@1.1.5: + better-path-resolve@1.0.0: resolution: { - integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==, + integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==, + } + engines: { node: ">=4" } + + big-integer@1.6.36: + resolution: + { + integrity: sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==, + } + engines: { node: ">=0.6" } + + big.js@6.2.2: + resolution: + { + integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==, + } + + bigint-buffer@1.1.5: + resolution: + { + integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==, } engines: { node: ">= 10.0.0" } @@ -5950,6 +6699,13 @@ packages: } engines: { node: ">=6.14.2" } + bufio@1.2.3: + resolution: + { + integrity: sha512-5Tt66bRzYUSlVZatc0E92uDenreJ+DpTBmSAUwL4VSxJn3e6cUyYwx+PoqML0GRZatgA/VX8ybhxItF8InZgqA==, + } + engines: { node: ">=8.0.0" } + builtin-status-codes@3.0.0: resolution: { @@ -5963,6 +6719,20 @@ packages: } engines: { node: ">=10.6.0" } + cacheable-lookup@7.0.0: + resolution: + { + integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==, + } + engines: { node: ">=14.16" } + + cacheable-request@10.2.14: + resolution: + { + integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==, + } + engines: { node: ">=14.16" } + cacheable-request@7.0.4: resolution: { @@ -5991,6 +6761,13 @@ packages: } engines: { node: ">= 0.4" } + callsites@3.1.0: + resolution: + { + integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, + } + engines: { node: ">=6" } + camelcase@5.3.1: resolution: { @@ -6030,6 +6807,13 @@ packages: } engines: { node: ">=20" } + chai@4.5.0: + resolution: + { + integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==, + } + engines: { node: ">=4" } + chalk@4.1.2: resolution: { @@ -6044,12 +6828,31 @@ packages: } engines: { node: ^12.17.0 || ^14.13 || >=16.0.0 } + chardet@2.1.1: + resolution: + { + integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==, + } + charenc@0.0.2: resolution: { integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==, } + check-error@1.0.3: + resolution: + { + integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==, + } + + chokidar@4.0.3: + resolution: + { + integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==, + } + engines: { node: ">= 14.16.0" } + chokidar@5.0.0: resolution: { @@ -6177,6 +6980,13 @@ packages: } engines: { node: ">= 0.8" } + commander@10.0.1: + resolution: + { + integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==, + } + engines: { node: ">=14" } + commander@12.1.0: resolution: { @@ -6218,6 +7028,12 @@ packages: integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==, } + config-chain@1.1.13: + resolution: + { + integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==, + } + connect@3.7.0: resolution: { @@ -6255,6 +7071,18 @@ packages: integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==, } + cosmiconfig@8.3.6: + resolution: + { + integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==, + } + engines: { node: ">=14" } + peerDependencies: + typescript: ">=4.9.5" + peerDependenciesMeta: + typescript: + optional: true + crc-32@1.2.2: resolution: { @@ -6305,6 +7133,13 @@ packages: integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==, } + cross-spawn@6.0.6: + resolution: + { + integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==, + } + engines: { node: ">=4.8" } + cross-spawn@7.0.6: resolution: { @@ -6384,6 +7219,12 @@ packages: typescript: optional: true + dataloader@1.4.0: + resolution: + { + integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==, + } + dataloader@2.2.3: resolution: { @@ -6470,6 +7311,20 @@ packages: babel-plugin-macros: optional: true + deep-eql@4.1.4: + resolution: + { + integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==, + } + engines: { node: ">=6" } + + deep-extend@0.6.0: + resolution: + { + integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==, + } + engines: { node: ">=4.0.0" } + deep-is@0.1.4: resolution: { @@ -6576,6 +7431,13 @@ packages: integrity: sha512-lgdERlL3u0aUdHocoouzT10d9I89VVhk0qNRmll7mXdGfJT1/wqZ2ZLA4oJAjeACPY5fT1wsbq2AT+GkuInsow==, } + detect-indent@6.1.0: + resolution: + { + integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==, + } + engines: { node: ">=8" } + detect-node-es@1.1.0: resolution: { @@ -6594,6 +7456,13 @@ packages: integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==, } + dir-glob@3.0.1: + resolution: + { + integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==, + } + engines: { node: ">=8" } + domain-browser@4.22.0: resolution: { @@ -6721,6 +7590,20 @@ packages: } engines: { node: ">=10.0.0" } + enquirer@2.4.1: + resolution: + { + integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==, + } + engines: { node: ">=8.6" } + + env-paths@2.2.1: + resolution: + { + integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==, + } + engines: { node: ">=6" } + environment@1.1.0: resolution: { @@ -6728,6 +7611,19 @@ packages: } engines: { node: ">=18" } + era-contracts@https://codeload.github.com/matter-labs/era-contracts/tar.gz/446d391d34bdb48255d5f8fef8a8248925fc98b9: + resolution: + { + tarball: https://codeload.github.com/matter-labs/era-contracts/tar.gz/446d391d34bdb48255d5f8fef8a8248925fc98b9, + } + version: 0.1.0 + + error-ex@1.3.4: + resolution: + { + integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==, + } + error-stack-parser@2.1.4: resolution: { @@ -6890,6 +7786,13 @@ packages: jiti: optional: true + espree@10.4.0: + resolution: + { + integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + espree@11.1.0: resolution: { @@ -7054,6 +7957,12 @@ packages: integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==, } + extendable-error@0.1.7: + resolution: + { + integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==, + } + extension-port-stream@2.1.1: resolution: { @@ -7087,6 +7996,12 @@ packages: integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, } + fast-diff@1.3.0: + resolution: + { + integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==, + } + fast-equals@5.4.0: resolution: { @@ -7094,6 +8009,13 @@ packages: } engines: { node: ">=6.0.0" } + fast-glob@3.3.3: + resolution: + { + integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==, + } + engines: { node: ">=8.6.0" } + fast-json-stable-stringify@2.1.0: resolution: { @@ -7131,12 +8053,24 @@ packages: integrity: sha512-lE2DIivBaLysf6hK5WH/VfMgqRbvBVHcpGVVTmA5Zi8oWIjq9YxIt6lYGdUgP1HNSXxTIat7HEIDnrSvXSeKQw==, } + fast-uri@3.1.0: + resolution: + { + integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==, + } + fastestsmallesttextencoderdecoder@1.0.22: resolution: { integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==, } + fastq@1.20.1: + resolution: + { + integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==, + } + fb-dotslash@0.5.8: resolution: { @@ -7217,6 +8151,12 @@ packages: } engines: { node: ">=10" } + find-yarn-workspace-root@2.0.0: + resolution: + { + integrity: sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==, + } + flat-cache@4.0.1: resolution: { @@ -7255,6 +8195,13 @@ packages: } engines: { node: ">= 0.4" } + form-data-encoder@2.1.4: + resolution: + { + integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==, + } + engines: { node: ">= 14.17" } + form-data@4.0.5: resolution: { @@ -7269,6 +8216,27 @@ packages: } engines: { node: ">= 0.6" } + fs-extra@7.0.1: + resolution: + { + integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==, + } + engines: { node: ">=6 <7 || >=8" } + + fs-extra@8.1.0: + resolution: + { + integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==, + } + engines: { node: ">=6 <7 || >=8" } + + fs-extra@9.1.0: + resolution: + { + integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==, + } + engines: { node: ">=10" } + fs.realpath@1.0.0: resolution: { @@ -7317,6 +8285,12 @@ packages: } engines: { node: ">=18" } + get-func-name@2.0.2: + resolution: + { + integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==, + } + get-intrinsic@1.3.0: resolution: { @@ -7358,12 +8332,26 @@ packages: } engines: { node: ">=8" } + get-stream@6.0.1: + resolution: + { + integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, + } + engines: { node: ">=10" } + get-tsconfig@4.13.6: resolution: { integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==, } + glob-parent@5.1.2: + resolution: + { + integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, + } + engines: { node: ">= 6" } + glob-parent@6.0.2: resolution: { @@ -7378,6 +8366,21 @@ packages: } deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + glob@8.1.0: + resolution: + { + integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==, + } + engines: { node: ">=12" } + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + globals@14.0.0: + resolution: + { + integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==, + } + engines: { node: ">=18" } + globals@16.5.0: resolution: { @@ -7385,6 +8388,13 @@ packages: } engines: { node: ">=18" } + globby@11.1.0: + resolution: + { + integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==, + } + engines: { node: ">=10" } + gopd@1.2.0: resolution: { @@ -7399,6 +8409,13 @@ packages: } engines: { node: ">=10.19.0" } + got@12.6.1: + resolution: + { + integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==, + } + engines: { node: ">=14.16" } + gql.tada@1.9.0: resolution: { @@ -7408,6 +8425,12 @@ packages: peerDependencies: typescript: ^5.0.0 + graceful-fs@4.2.10: + resolution: + { + integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==, + } + graceful-fs@4.2.11: resolution: { @@ -7435,6 +8458,13 @@ packages: integrity: sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg==, } + hardhat@3.1.12: + resolution: + { + integrity: sha512-/3TrZV4ViCIKgy2K5XwPS5xla2v4xjxYA2Ms1pi/0t+1GQQ1dWQpKJhDjKBc02UWYiWihIZFAv9RS30anyhqpQ==, + } + hasBin: true + has-flag@4.0.0: resolution: { @@ -7552,6 +8582,13 @@ packages: } engines: { node: ">=10.19.0" } + http2-wrapper@2.2.1: + resolution: + { + integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==, + } + engines: { node: ">=10.19.0" } + https-browserify@1.0.0: resolution: { @@ -7565,6 +8602,13 @@ packages: } engines: { node: ">= 14" } + human-id@4.1.3: + resolution: + { + integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==, + } + hasBin: true + humanize-ms@1.2.1: resolution: { @@ -7579,6 +8623,13 @@ packages: engines: { node: ">=18" } hasBin: true + iconv-lite@0.7.2: + resolution: + { + integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==, + } + engines: { node: ">=0.10.0" } + idb-keyval@6.2.1: resolution: { @@ -7619,6 +8670,13 @@ packages: engines: { node: ">=16.x" } hasBin: true + import-fresh@3.3.1: + resolution: + { + integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==, + } + engines: { node: ">=6" } + imurmurhash@0.1.4: resolution: { @@ -7639,6 +8697,12 @@ packages: integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, } + ini@1.3.8: + resolution: + { + integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==, + } + int64-buffer@1.1.0: resolution: { @@ -7671,6 +8735,12 @@ packages: } engines: { node: ">= 0.4" } + is-arrayish@0.2.1: + resolution: + { + integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, + } + is-arrayish@0.3.4: resolution: { @@ -7690,6 +8760,13 @@ packages: } engines: { node: ">= 0.4" } + is-ci@2.0.0: + resolution: + { + integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==, + } + hasBin: true + is-core-module@2.16.1: resolution: { @@ -7795,6 +8872,13 @@ packages: } engines: { node: ">=8" } + is-subdir@1.2.0: + resolution: + { + integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==, + } + engines: { node: ">=4" } + is-typed-array@1.1.15: resolution: { @@ -7802,6 +8886,13 @@ packages: } engines: { node: ">= 0.4" } + is-windows@1.0.2: + resolution: + { + integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==, + } + engines: { node: ">=0.10.0" } + is-wsl@2.2.0: resolution: { @@ -7962,6 +9053,12 @@ packages: integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==, } + js-sha3@0.8.0: + resolution: + { + integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==, + } + js-tokens@4.0.0: resolution: { @@ -7975,6 +9072,13 @@ packages: } hasBin: true + js-yaml@4.1.1: + resolution: + { + integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==, + } + hasBin: true + jsbi@3.2.5: resolution: { @@ -8001,6 +9105,12 @@ packages: integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==, } + json-parse-even-better-errors@2.3.1: + resolution: + { + integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, + } + json-rpc-engine@6.1.0: resolution: { @@ -8026,6 +9136,12 @@ packages: integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==, } + json-schema-traverse@1.0.0: + resolution: + { + integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==, + } + json-stable-stringify-without-jsonify@1.0.1: resolution: { @@ -8039,6 +9155,13 @@ packages: } engines: { node: ">= 0.4" } + json-stream-stringify@3.1.6: + resolution: + { + integrity: sha512-x7fpwxOkbhFCaJDJ8vb1fBY3DdSa4AlITaz+HHILQJzdPMnHEFjxPwVUi1ALIbcIxDE0PNe/0i7frnY8QnBQog==, + } + engines: { node: ">=7.10.1" } + json-stringify-safe@5.0.1: resolution: { @@ -8053,12 +9176,31 @@ packages: engines: { node: ">=6" } hasBin: true + jsonfile@4.0.0: + resolution: + { + integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==, + } + + jsonfile@6.2.0: + resolution: + { + integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==, + } + jsonify@0.0.1: resolution: { integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==, } + jsonpointer@5.0.1: + resolution: + { + integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==, + } + engines: { node: ">=0.10.0" } + jsqr@1.4.0: resolution: { @@ -8109,6 +9251,19 @@ packages: integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==, } + klaw-sync@6.0.0: + resolution: + { + integrity: sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==, + } + + latest-version@7.0.0: + resolution: + { + integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==, + } + engines: { node: ">=14.16" } + leven@3.1.0: resolution: { @@ -8129,6 +9284,12 @@ packages: integrity: sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==, } + lines-and-columns@1.2.4: + resolution: + { + integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, + } + lint-staged@16.2.7: resolution: { @@ -8201,12 +9362,24 @@ packages: integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, } + lodash.startcase@4.4.0: + resolution: + { + integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==, + } + lodash.throttle@4.1.1: resolution: { integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==, } + lodash.truncate@4.4.2: + resolution: + { + integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==, + } + lodash@4.17.21: resolution: { @@ -8246,6 +9419,12 @@ packages: } hasBin: true + loupe@2.3.7: + resolution: + { + integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==, + } + lower-case@2.0.2: resolution: { @@ -8259,6 +9438,13 @@ packages: } engines: { node: ">=8" } + lowercase-keys@3.0.0: + resolution: + { + integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + lru-cache@10.4.3: resolution: { @@ -8340,6 +9526,13 @@ packages: integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, } + merge2@1.4.1: + resolution: + { + integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, + } + engines: { node: ">= 8" } + metro-babel-transformer@0.83.4: resolution: { @@ -8440,6 +9633,12 @@ packages: engines: { node: ">=20.19.4" } hasBin: true + micro-eth-signer@0.14.0: + resolution: + { + integrity: sha512-5PLLzHiVYPWClEvZIXXFu5yutzpadb73rnQCpUqIHu3No3coFuWQNfE5tkBQJ7djuLYl6aRLaS0MgWJYGoqiBw==, + } + micro-ftch@0.3.1: resolution: { @@ -8452,6 +9651,12 @@ packages: integrity: sha512-QDwluos8YeMijiKxZGwaV4f4tzj0soS6+xcsJhJ3+4wdEIHMyKbIKVUziebOgWX3e6yiijdoaHo+9tyhbnaWXA==, } + micro-packed@0.7.3: + resolution: + { + integrity: sha512-2Milxs+WNC00TRlem41oRswvw31146GiSaoCT7s3Xi2gMUglW5QBeqlQaZeHr5tJx9nm3i57LNXPqxOOaWtTYg==, + } + micromatch@4.0.8: resolution: { @@ -8523,6 +9728,13 @@ packages: } engines: { node: ">=10" } + mimic-response@4.0.0: + resolution: + { + integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + minimalistic-assert@1.0.1: resolution: { @@ -8542,6 +9754,13 @@ packages: } engines: { node: 20 || >=22 } + minimatch@5.1.9: + resolution: + { + integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==, + } + engines: { node: ">=10" } + minimatch@9.0.5: resolution: { @@ -8549,6 +9768,12 @@ packages: } engines: { node: ">=16 || 14 >=14.17" } + minimist@1.2.8: + resolution: + { + integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==, + } + mipd@0.0.7: resolution: { @@ -8574,6 +9799,13 @@ packages: integrity: sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ==, } + mri@1.2.0: + resolution: + { + integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==, + } + engines: { node: ">=4" } + ms@2.0.0: resolution: { @@ -8632,6 +9864,12 @@ packages: } engines: { node: ">= 0.6" } + nice-try@1.0.5: + resolution: + { + integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==, + } + no-case@3.0.4: resolution: { @@ -8728,6 +9966,13 @@ packages: } engines: { node: ">=10" } + normalize-url@8.1.1: + resolution: + { + integrity: sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==, + } + engines: { node: ">=14.16" } + nullthrows@1.1.1: resolution: { @@ -8860,6 +10105,19 @@ packages: integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==, } + os-tmpdir@1.0.2: + resolution: + { + integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==, + } + engines: { node: ">=0.10.0" } + + outdent@0.5.0: + resolution: + { + integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==, + } + ox@0.12.1: resolution: { @@ -8911,6 +10169,20 @@ packages: } engines: { node: ">=8" } + p-cancelable@3.0.0: + resolution: + { + integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==, + } + engines: { node: ">=12.20" } + + p-filter@2.1.0: + resolution: + { + integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==, + } + engines: { node: ">=8" } + p-limit@2.3.0: resolution: { @@ -8921,30 +10193,57 @@ packages: p-limit@3.1.0: resolution: { - integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, + integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, + } + engines: { node: ">=10" } + + p-locate@4.1.0: + resolution: + { + integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, + } + engines: { node: ">=8" } + + p-locate@5.0.0: + resolution: + { + integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, + } + engines: { node: ">=10" } + + p-map@2.1.0: + resolution: + { + integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==, + } + engines: { node: ">=6" } + + p-map@7.0.4: + resolution: + { + integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==, } - engines: { node: ">=10" } + engines: { node: ">=18" } - p-locate@4.1.0: + p-try@2.2.0: resolution: { - integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, + integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, } - engines: { node: ">=8" } + engines: { node: ">=6" } - p-locate@5.0.0: + package-json@8.1.1: resolution: { - integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, + integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==, } - engines: { node: ">=10" } + engines: { node: ">=14.16" } - p-try@2.2.0: + package-manager-detector@0.2.11: resolution: { - integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, + integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==, } - engines: { node: ">=6" } pako@1.0.11: resolution: @@ -8958,6 +10257,13 @@ packages: integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==, } + parent-module@1.0.1: + resolution: + { + integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, + } + engines: { node: ">=6" } + parse-asn1@5.1.9: resolution: { @@ -8965,6 +10271,13 @@ packages: } engines: { node: ">= 0.10" } + parse-json@5.2.0: + resolution: + { + integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==, + } + engines: { node: ">=8" } + parseurl@1.3.3: resolution: { @@ -8972,6 +10285,14 @@ packages: } engines: { node: ">= 0.8" } + patch-package@6.5.1: + resolution: + { + integrity: sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==, + } + engines: { node: ">=10", npm: ">5" } + hasBin: true + path-browserify@1.0.1: resolution: { @@ -8992,6 +10313,13 @@ packages: } engines: { node: ">=0.10.0" } + path-key@2.0.1: + resolution: + { + integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==, + } + engines: { node: ">=4" } + path-key@3.1.1: resolution: { @@ -9005,6 +10333,19 @@ packages: integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, } + path-type@4.0.0: + resolution: + { + integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, + } + engines: { node: ">=8" } + + pathval@1.1.1: + resolution: + { + integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==, + } + pbkdf2@3.1.5: resolution: { @@ -9047,6 +10388,13 @@ packages: } engines: { node: ">=4" } + pify@4.0.1: + resolution: + { + integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==, + } + engines: { node: ">=6" } + pify@5.0.0: resolution: { @@ -9087,6 +10435,13 @@ packages: } engines: { node: ">=10" } + pluralize@8.0.0: + resolution: + { + integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==, + } + engines: { node: ">=4" } + pngjs@5.0.0: resolution: { @@ -9175,6 +10530,14 @@ packages: } engines: { node: ">= 0.8.0" } + prettier@2.8.8: + resolution: + { + integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==, + } + engines: { node: ">=10.13.0" } + hasBin: true + prettier@3.8.1: resolution: { @@ -9221,6 +10584,12 @@ packages: integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==, } + proto-list@1.2.4: + resolution: + { + integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==, + } + protobufjs@7.4.0: resolution: { @@ -9315,6 +10684,12 @@ packages: } engines: { node: ">=0.6" } + quansync@0.2.11: + resolution: + { + integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==, + } + query-string@7.1.3: resolution: { @@ -9329,6 +10704,12 @@ packages: } engines: { node: ">=0.4.x" } + queue-microtask@1.2.3: + resolution: + { + integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, + } + queue@6.0.2: resolution: { @@ -9373,6 +10754,13 @@ packages: } engines: { node: ">= 0.6" } + rc@1.2.8: + resolution: + { + integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==, + } + hasBin: true + react-devtools-core@6.1.5: resolution: { @@ -9497,6 +10885,13 @@ packages: } engines: { node: ">=0.10.0" } + read-yaml-file@1.1.0: + resolution: + { + integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==, + } + engines: { node: ">=6" } + readable-stream@2.3.8: resolution: { @@ -9517,6 +10912,13 @@ packages: } engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } + readdirp@4.1.2: + resolution: + { + integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==, + } + engines: { node: ">= 14.18.0" } + readdirp@5.0.0: resolution: { @@ -9537,6 +10939,20 @@ packages: integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==, } + registry-auth-token@5.1.1: + resolution: + { + integrity: sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==, + } + engines: { node: ">=14" } + + registry-url@6.0.1: + resolution: + { + integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==, + } + engines: { node: ">=12" } + require-directory@2.1.1: resolution: { @@ -9544,6 +10960,13 @@ packages: } engines: { node: ">=0.10.0" } + require-from-string@2.0.2: + resolution: + { + integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==, + } + engines: { node: ">=0.10.0" } + require-main-filename@2.0.0: resolution: { @@ -9556,6 +10979,13 @@ packages: integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==, } + resolve-from@4.0.0: + resolution: + { + integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, + } + engines: { node: ">=4" } + resolve-from@5.0.0: resolution: { @@ -9569,6 +10999,13 @@ packages: integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==, } + resolve.exports@2.0.3: + resolution: + { + integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==, + } + engines: { node: ">=10" } + resolve@1.22.11: resolution: { @@ -9583,6 +11020,13 @@ packages: integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==, } + responselike@3.0.0: + resolution: + { + integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==, + } + engines: { node: ">=14.16" } + restore-cursor@5.1.0: resolution: { @@ -9590,12 +11034,27 @@ packages: } engines: { node: ">=18" } + reusify@1.1.0: + resolution: + { + integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==, + } + engines: { iojs: ">=1.0.0", node: ">=0.10.0" } + rfdc@1.4.1: resolution: { integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==, } + rimraf@2.7.1: + resolution: + { + integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==, + } + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + rimraf@3.0.2: resolution: { @@ -9653,6 +11112,12 @@ packages: } engines: { node: ">=6.0.0", npm: ">=3.10.0" } + run-parallel@1.2.0: + resolution: + { + integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, + } + rxjs@6.6.7: resolution: { @@ -9692,6 +11157,12 @@ packages: } engines: { node: ">=10" } + safer-buffer@2.1.2: + resolution: + { + integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, + } + salmon-adapter-sdk@1.1.1: resolution: { @@ -9718,6 +11189,13 @@ packages: integrity: sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw==, } + semver@5.7.2: + resolution: + { + integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==, + } + hasBin: true + semver@6.3.1: resolution: { @@ -9795,6 +11273,13 @@ packages: engines: { node: ">= 0.10" } hasBin: true + shebang-command@1.2.0: + resolution: + { + integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==, + } + engines: { node: ">=0.10.0" } + shebang-command@2.0.0: resolution: { @@ -9802,6 +11287,13 @@ packages: } engines: { node: ">=8" } + shebang-regex@1.0.0: + resolution: + { + integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==, + } + engines: { node: ">=0.10.0" } + shebang-regex@3.0.0: resolution: { @@ -9863,6 +11355,13 @@ packages: integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==, } + slash@2.0.0: + resolution: + { + integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==, + } + engines: { node: ">=6" } + slash@3.0.0: resolution: { @@ -9870,6 +11369,13 @@ packages: } engines: { node: ">=8" } + slice-ansi@4.0.0: + resolution: + { + integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==, + } + engines: { node: ">=10" } + slice-ansi@7.1.2: resolution: { @@ -9918,6 +11424,19 @@ packages: } engines: { node: ">= 10.0.0", npm: ">= 3.0.0" } + solady@0.0.182: + resolution: + { + integrity: sha512-FW6xo1akJoYpkXMzu58/56FcNU3HYYNamEbnFO3iSibXk0nSHo0DV2Gu/zI3FPg3So5CCX6IYli1TT1IWATnvg==, + } + + solhint@6.0.3: + resolution: + { + integrity: sha512-LYiy1bN8X9eUsti13mbS4fY6ILVxhP6VoOgqbHxCsHl5VPnxOWf7U1V9ZvgizxdInKBMW82D1FNJO+daAcWHbA==, + } + hasBin: true + sonic-boom@2.8.0: resolution: { @@ -9951,6 +11470,12 @@ packages: } engines: { node: ">=0.10.0" } + spawndamnit@3.0.1: + resolution: + { + integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==, + } + split-on-first@1.1.0: resolution: { @@ -10096,6 +11621,27 @@ packages: } engines: { node: ">=12" } + strip-bom@3.0.0: + resolution: + { + integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==, + } + engines: { node: ">=4" } + + strip-json-comments@2.0.1: + resolution: + { + integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==, + } + engines: { node: ">=0.10.0" } + + strip-json-comments@3.1.1: + resolution: + { + integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, + } + engines: { node: ">=8" } + superstruct@0.15.5: resolution: { @@ -10137,6 +11683,13 @@ packages: } engines: { node: ">= 0.4" } + table@6.9.0: + resolution: + { + integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==, + } + engines: { node: ">=10.0.0" } + tagged-tag@1.0.0: resolution: { @@ -10144,6 +11697,13 @@ packages: } engines: { node: ">=20" } + term-size@2.2.1: + resolution: + { + integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==, + } + engines: { node: ">=8" } + terser@5.46.0: resolution: { @@ -10165,6 +11725,12 @@ packages: integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==, } + text-table@0.2.0: + resolution: + { + integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==, + } + thread-stream@0.15.2: resolution: { @@ -10198,6 +11764,13 @@ packages: } engines: { node: ">=12.0.0" } + tmp@0.0.33: + resolution: + { + integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==, + } + engines: { node: ">=0.6.0" } + tmpl@1.0.5: resolution: { @@ -10310,6 +11883,13 @@ packages: } engines: { node: ">=4" } + type-detect@4.1.0: + resolution: + { + integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==, + } + engines: { node: ">=4" } + type-fest@0.7.1: resolution: { @@ -10418,12 +11998,33 @@ packages: integrity: sha512-w9IMgQrz4O0YN1LtB7K5P63vhlIOvC7opSmouCJ+ZywlPAlO9gIkJ+otk6LvGpAs2wg4econaCz3TvQ9xPoyuQ==, } + undici@6.24.0: + resolution: + { + integrity: sha512-lVLNosgqo5EkGqh5XUDhGfsMSoO8K0BAN0TyJLvwNRSl4xWGZlCVYsAIpa/OpA3TvmnM01GWcoKmc3ZWo5wKKA==, + } + engines: { node: ">=18.17" } + unidragger@3.0.1: resolution: { integrity: sha512-RngbGSwBFmqGBWjkaH+yB677uzR95blSQyxq6hYbrQCejH3Mx1nm8DVOuh3M9k2fQyTstWUG5qlgCnNqV/9jVw==, } + universalify@0.1.2: + resolution: + { + integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==, + } + engines: { node: ">= 4.0.0" } + + universalify@2.0.1: + resolution: + { + integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==, + } + engines: { node: ">= 10.0.0" } + unload@2.4.1: resolution: { @@ -10826,6 +12427,13 @@ packages: } engines: { node: ">= 0.4" } + which@1.3.1: + resolution: + { + integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==, + } + hasBin: true + which@2.0.2: resolution: { @@ -10996,6 +12604,13 @@ packages: integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, } + yaml@1.10.2: + resolution: + { + integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==, + } + engines: { node: ">= 6" } + yaml@2.8.2: resolution: { @@ -11135,31 +12750,31 @@ snapshots: "@adraffy/ens-normalize@1.11.1": {} - "@aptos-connect/wallet-adapter-plugin@2.8.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1)": + "@aptos-connect/wallet-adapter-plugin@2.8.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1)": dependencies: - "@aptos-connect/wallet-api": 0.6.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1) - "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) - "@aptos-labs/wallet-standard": 0.5.2(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1) - "@identity-connect/crypto": 0.3.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1) - "@identity-connect/dapp-sdk": 0.15.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@aptos-labs/wallet-standard@0.5.2(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1))(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1) + "@aptos-connect/wallet-api": 0.6.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1) + "@aptos-labs/ts-sdk": 5.2.1(got@12.6.1) + "@aptos-labs/wallet-standard": 0.5.2(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1) + "@identity-connect/crypto": 0.3.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1) + "@identity-connect/dapp-sdk": 0.15.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@aptos-labs/wallet-standard@0.5.2(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1))(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1) transitivePeerDependencies: - "@telegram-apps/bridge" - "@wallet-standard/core" - debug - "@aptos-connect/wallet-api@0.6.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1)": + "@aptos-connect/wallet-api@0.6.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1)": dependencies: - "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) - "@aptos-labs/wallet-standard": 0.5.2(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1) + "@aptos-labs/ts-sdk": 5.2.1(got@12.6.1) + "@aptos-labs/wallet-standard": 0.5.2(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1) "@identity-connect/api": 0.8.0 transitivePeerDependencies: - "@wallet-standard/core" - "@aptos-connect/web-transport@0.5.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@aptos-labs/wallet-standard@0.5.2(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1))(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1)": + "@aptos-connect/web-transport@0.5.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@aptos-labs/wallet-standard@0.5.2(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1))(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1)": dependencies: - "@aptos-connect/wallet-api": 0.6.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1) - "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) - "@aptos-labs/wallet-standard": 0.5.2(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1) + "@aptos-connect/wallet-api": 0.6.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1) + "@aptos-labs/ts-sdk": 5.2.1(got@12.6.1) + "@aptos-labs/wallet-standard": 0.5.2(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1) "@telegram-apps/bridge": 1.9.2 uuid: 9.0.1 transitivePeerDependencies: @@ -11169,25 +12784,29 @@ snapshots: dependencies: commander: 12.1.0 - "@aptos-labs/aptos-client@1.2.0(axios@1.13.5)(got@11.8.6)": + "@aptos-labs/aptos-client@1.2.0(axios@1.13.5)(got@12.6.1)": dependencies: axios: 1.13.5 - got: 11.8.6 + got: 12.6.1 "@aptos-labs/aptos-client@2.1.0(got@11.8.6)": dependencies: got: 11.8.6 + "@aptos-labs/aptos-client@2.1.0(got@12.6.1)": + dependencies: + got: 12.6.1 + "@aptos-labs/aptos-dynamic-transaction-composer@0.1.5": {} "@aptos-labs/script-composer-pack@0.0.9": dependencies: "@aptos-labs/aptos-dynamic-transaction-composer": 0.1.5 - "@aptos-labs/ts-sdk@1.39.0(axios@1.13.5)(got@11.8.6)": + "@aptos-labs/ts-sdk@1.39.0(axios@1.13.5)(got@12.6.1)": dependencies: "@aptos-labs/aptos-cli": 1.1.1 - "@aptos-labs/aptos-client": 1.2.0(axios@1.13.5)(got@11.8.6) + "@aptos-labs/aptos-client": 1.2.0(axios@1.13.5)(got@12.6.1) "@aptos-labs/script-composer-pack": 0.0.9 "@noble/curves": 1.9.7 "@noble/hashes": 1.8.0 @@ -11217,14 +12836,29 @@ snapshots: transitivePeerDependencies: - got - "@aptos-labs/wallet-adapter-core@4.25.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)))(@mizuwallet-sdk/protocol@0.0.6)(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1)(aptos@1.22.1(got@11.8.6))(axios@1.13.5)(got@11.8.6)": + "@aptos-labs/ts-sdk@5.2.1(got@12.6.1)": dependencies: - "@aptos-connect/wallet-adapter-plugin": 2.8.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1) - "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) - "@aptos-labs/wallet-standard": 0.2.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1) - "@atomrigslab/aptos-wallet-adapter": 0.1.21(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(axios@1.13.5)(got@11.8.6) - "@mizuwallet-sdk/aptos-wallet-adapter": 0.3.2(@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)))(@mizuwallet-sdk/protocol@0.0.6)(@wallet-standard/core@1.1.1)(axios@1.13.5)(got@11.8.6) - aptos: 1.22.1(got@11.8.6) + "@aptos-labs/aptos-cli": 1.1.1 + "@aptos-labs/aptos-client": 2.1.0(got@12.6.1) + "@noble/curves": 1.9.7 + "@noble/hashes": 1.8.0 + "@scure/bip32": 1.7.0 + "@scure/bip39": 1.6.0 + eventemitter3: 5.0.4 + js-base64: 3.7.8 + jwt-decode: 4.0.0 + poseidon-lite: 0.2.1 + transitivePeerDependencies: + - got + + "@aptos-labs/wallet-adapter-core@4.25.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)))(@mizuwallet-sdk/protocol@0.0.6)(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1)(aptos@1.22.1(got@12.6.1))(axios@1.13.5)(got@12.6.1)": + dependencies: + "@aptos-connect/wallet-adapter-plugin": 2.8.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1) + "@aptos-labs/ts-sdk": 5.2.1(got@12.6.1) + "@aptos-labs/wallet-standard": 0.2.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1) + "@atomrigslab/aptos-wallet-adapter": 0.1.21(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(axios@1.13.5)(got@12.6.1) + "@mizuwallet-sdk/aptos-wallet-adapter": 0.3.2(@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)))(@mizuwallet-sdk/protocol@0.0.6)(@wallet-standard/core@1.1.1)(axios@1.13.5)(got@12.6.1) + aptos: 1.22.1(got@12.6.1) buffer: 6.0.3 eventemitter3: 4.0.7 tweetnacl: 1.0.3 @@ -11237,9 +12871,9 @@ snapshots: - debug - got - "@aptos-labs/wallet-adapter-react@3.8.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)))(@mizuwallet-sdk/protocol@0.0.6)(@telegram-apps/bridge@1.9.2)(@types/react@18.3.28)(@wallet-standard/core@1.1.1)(aptos@1.22.1(got@11.8.6))(axios@1.13.5)(got@11.8.6)(react@18.3.1)": + "@aptos-labs/wallet-adapter-react@3.8.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)))(@mizuwallet-sdk/protocol@0.0.6)(@telegram-apps/bridge@1.9.2)(@types/react@18.3.28)(@wallet-standard/core@1.1.1)(aptos@1.22.1(got@12.6.1))(axios@1.13.5)(got@12.6.1)(react@18.3.1)": dependencies: - "@aptos-labs/wallet-adapter-core": 4.25.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)))(@mizuwallet-sdk/protocol@0.0.6)(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1)(aptos@1.22.1(got@11.8.6))(axios@1.13.5)(got@11.8.6) + "@aptos-labs/wallet-adapter-core": 4.25.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)))(@mizuwallet-sdk/protocol@0.0.6)(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1)(aptos@1.22.1(got@12.6.1))(axios@1.13.5)(got@12.6.1) "@radix-ui/react-slot": 1.2.4(@types/react@18.3.28)(react@18.3.1) react: 18.3.1 transitivePeerDependencies: @@ -11254,33 +12888,41 @@ snapshots: - debug - got - "@aptos-labs/wallet-standard@0.0.11(axios@1.13.5)(got@11.8.6)": + "@aptos-labs/wallet-standard@0.0.11(axios@1.13.5)(got@12.6.1)": dependencies: - "@aptos-labs/ts-sdk": 1.39.0(axios@1.13.5)(got@11.8.6) + "@aptos-labs/ts-sdk": 1.39.0(axios@1.13.5)(got@12.6.1) "@wallet-standard/core": 1.0.3 transitivePeerDependencies: - axios - got - "@aptos-labs/wallet-standard@0.1.0-ms.1(@aptos-labs/ts-sdk@1.39.0(axios@1.13.5)(got@11.8.6))(@wallet-standard/core@1.1.1)": + "@aptos-labs/wallet-standard@0.1.0-ms.1(@aptos-labs/ts-sdk@1.39.0(axios@1.13.5)(got@12.6.1))(@wallet-standard/core@1.1.1)": dependencies: - "@aptos-labs/ts-sdk": 1.39.0(axios@1.13.5)(got@11.8.6) + "@aptos-labs/ts-sdk": 1.39.0(axios@1.13.5)(got@12.6.1) "@wallet-standard/core": 1.1.1 - "@aptos-labs/wallet-standard@0.2.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1)": + "@aptos-labs/wallet-standard@0.2.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1)": dependencies: - "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) + "@aptos-labs/ts-sdk": 5.2.1(got@12.6.1) "@wallet-standard/core": 1.1.1 - "@aptos-labs/wallet-standard@0.5.2(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1)": + "@aptos-labs/wallet-standard@0.5.2(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1)": dependencies: - "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) + "@aptos-labs/ts-sdk": 5.2.1(got@12.6.1) "@wallet-standard/core": 1.1.1 - "@atomrigslab/aptos-wallet-adapter@0.1.21(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(axios@1.13.5)(got@11.8.6)": + "@arbitrum/nitro-contracts@3.0.0": + dependencies: + "@offchainlabs/upgrade-executor": 1.1.0-beta.0 + "@openzeppelin/contracts": 4.7.3 + "@openzeppelin/contracts-upgradeable": 4.7.3 + patch-package: 6.5.1 + solady: 0.0.182 + + "@atomrigslab/aptos-wallet-adapter@0.1.21(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(axios@1.13.5)(got@12.6.1)": dependencies: - "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) - "@aptos-labs/wallet-standard": 0.0.11(axios@1.13.5)(got@11.8.6) + "@aptos-labs/ts-sdk": 5.2.1(got@12.6.1) + "@aptos-labs/wallet-standard": 0.0.11(axios@1.13.5)(got@12.6.1) "@atomrigslab/dekey-web-wallet-provider": 1.2.1 transitivePeerDependencies: - axios @@ -11542,7 +13184,7 @@ snapshots: - utf-8-validate - zod - "@chainlink/ccip-sdk@1.0.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)": + "@chainlink/ccip-sdk@1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)": dependencies: "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) "@coral-xyz/anchor": 0.29.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) @@ -11576,7 +13218,7 @@ snapshots: - utf-8-validate - zod - "@chainlink/ccip-sdk@1.0.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)": + "@chainlink/ccip-sdk@1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)": dependencies: "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) "@coral-xyz/anchor": 0.29.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) @@ -11610,6 +13252,199 @@ snapshots: - utf-8-validate - zod + "@chainlink/contracts-ccip@1.6.4(@types/node@22.19.11)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)": + dependencies: + "@chainlink/contracts": 1.5.0(@types/node@22.19.11)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + "@changesets/cli": 2.30.0(@types/node@22.19.11) + "@changesets/get-github-info": 0.6.0 + "@openzeppelin/contracts-4.8.3": "@openzeppelin/contracts@4.8.3" + "@openzeppelin/contracts-5.0.2": "@openzeppelin/contracts@5.0.2" + semver: 7.7.4 + transitivePeerDependencies: + - "@types/node" + - bufferutil + - encoding + - ethers + - supports-color + - utf-8-validate + + "@chainlink/contracts@1.5.0(@types/node@22.19.11)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)": + dependencies: + "@arbitrum/nitro-contracts": 3.0.0 + "@changesets/cli": 2.30.0(@types/node@22.19.11) + "@changesets/get-github-info": 0.6.0 + "@eslint/eslintrc": 3.3.5 + "@eth-optimism/contracts": 0.6.0(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + "@openzeppelin/contracts-4.7.3": "@openzeppelin/contracts@4.7.3" + "@openzeppelin/contracts-4.8.3": "@openzeppelin/contracts@4.8.3" + "@openzeppelin/contracts-4.9.6": "@openzeppelin/contracts@4.9.6" + "@openzeppelin/contracts-5.0.2": "@openzeppelin/contracts@5.0.2" + "@openzeppelin/contracts-5.1.0": "@openzeppelin/contracts@5.1.0" + "@openzeppelin/contracts-upgradeable": 4.9.6 + "@scroll-tech/contracts": 2.0.0 + "@zksync/contracts": era-contracts@https://codeload.github.com/matter-labs/era-contracts/tar.gz/446d391d34bdb48255d5f8fef8a8248925fc98b9 + semver: 7.7.4 + transitivePeerDependencies: + - "@types/node" + - bufferutil + - encoding + - ethers + - supports-color + - utf-8-validate + + "@chainlink/solhint-plugin-chainlink-solidity@https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c": + {} + + "@changesets/apply-release-plan@7.1.0": + dependencies: + "@changesets/config": 3.1.3 + "@changesets/get-version-range-type": 0.4.0 + "@changesets/git": 3.0.4 + "@changesets/should-skip-package": 0.1.2 + "@changesets/types": 6.1.0 + "@manypkg/get-packages": 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.7.4 + + "@changesets/assemble-release-plan@6.0.9": + dependencies: + "@changesets/errors": 0.2.0 + "@changesets/get-dependents-graph": 2.1.3 + "@changesets/should-skip-package": 0.1.2 + "@changesets/types": 6.1.0 + "@manypkg/get-packages": 1.1.3 + semver: 7.7.4 + + "@changesets/changelog-git@0.2.1": + dependencies: + "@changesets/types": 6.1.0 + + "@changesets/cli@2.30.0(@types/node@22.19.11)": + dependencies: + "@changesets/apply-release-plan": 7.1.0 + "@changesets/assemble-release-plan": 6.0.9 + "@changesets/changelog-git": 0.2.1 + "@changesets/config": 3.1.3 + "@changesets/errors": 0.2.0 + "@changesets/get-dependents-graph": 2.1.3 + "@changesets/get-release-plan": 4.0.15 + "@changesets/git": 3.0.4 + "@changesets/logger": 0.1.1 + "@changesets/pre": 2.0.2 + "@changesets/read": 0.6.7 + "@changesets/should-skip-package": 0.1.2 + "@changesets/types": 6.1.0 + "@changesets/write": 0.4.0 + "@inquirer/external-editor": 1.0.3(@types/node@22.19.11) + "@manypkg/get-packages": 1.1.3 + ansi-colors: 4.1.3 + enquirer: 2.4.1 + fs-extra: 7.0.1 + mri: 1.2.0 + package-manager-detector: 0.2.11 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.7.4 + spawndamnit: 3.0.1 + term-size: 2.2.1 + transitivePeerDependencies: + - "@types/node" + + "@changesets/config@3.1.3": + dependencies: + "@changesets/errors": 0.2.0 + "@changesets/get-dependents-graph": 2.1.3 + "@changesets/logger": 0.1.1 + "@changesets/should-skip-package": 0.1.2 + "@changesets/types": 6.1.0 + "@manypkg/get-packages": 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + "@changesets/errors@0.2.0": + dependencies: + extendable-error: 0.1.7 + + "@changesets/get-dependents-graph@2.1.3": + dependencies: + "@changesets/types": 6.1.0 + "@manypkg/get-packages": 1.1.3 + picocolors: 1.1.1 + semver: 7.7.4 + + "@changesets/get-github-info@0.6.0": + dependencies: + dataloader: 1.4.0 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + "@changesets/get-release-plan@4.0.15": + dependencies: + "@changesets/assemble-release-plan": 6.0.9 + "@changesets/config": 3.1.3 + "@changesets/pre": 2.0.2 + "@changesets/read": 0.6.7 + "@changesets/types": 6.1.0 + "@manypkg/get-packages": 1.1.3 + + "@changesets/get-version-range-type@0.4.0": {} + + "@changesets/git@3.0.4": + dependencies: + "@changesets/errors": 0.2.0 + "@manypkg/get-packages": 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 + + "@changesets/logger@0.1.1": + dependencies: + picocolors: 1.1.1 + + "@changesets/parse@0.4.3": + dependencies: + "@changesets/types": 6.1.0 + js-yaml: 4.1.1 + + "@changesets/pre@2.0.2": + dependencies: + "@changesets/errors": 0.2.0 + "@changesets/types": 6.1.0 + "@manypkg/get-packages": 1.1.3 + fs-extra: 7.0.1 + + "@changesets/read@0.6.7": + dependencies: + "@changesets/git": 3.0.4 + "@changesets/logger": 0.1.1 + "@changesets/parse": 0.4.3 + "@changesets/types": 6.1.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + "@changesets/should-skip-package@0.1.2": + dependencies: + "@changesets/types": 6.1.0 + "@manypkg/get-packages": 1.1.3 + + "@changesets/types@4.1.0": {} + + "@changesets/types@6.1.0": {} + + "@changesets/write@0.4.0": + dependencies: + "@changesets/types": 6.1.0 + fs-extra: 7.0.1 + human-id: 4.1.3 + prettier: 2.8.8 + "@coinbase/cdp-sdk@1.44.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)": dependencies: "@solana-program/system": 0.10.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)) @@ -11933,6 +13768,20 @@ snapshots: dependencies: "@types/json-schema": 7.0.15 + "@eslint/eslintrc@3.3.5": + dependencies: + ajv: 6.14.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 10.2.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + "@eslint/js@10.0.1(eslint@10.0.0)": optionalDependencies: eslint: 10.0.0 @@ -11944,6 +13793,38 @@ snapshots: "@eslint/core": 1.1.0 levn: 0.4.1 + "@eth-optimism/contracts@0.6.0(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)": + dependencies: + "@eth-optimism/core-utils": 0.12.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + "@ethersproject/abstract-provider": 5.8.0 + "@ethersproject/abstract-signer": 5.8.0 + ethers: 6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + "@eth-optimism/core-utils@0.12.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)": + dependencies: + "@ethersproject/abi": 5.8.0 + "@ethersproject/abstract-provider": 5.8.0 + "@ethersproject/address": 5.8.0 + "@ethersproject/bignumber": 5.8.0 + "@ethersproject/bytes": 5.8.0 + "@ethersproject/constants": 5.8.0 + "@ethersproject/contracts": 5.8.0 + "@ethersproject/hash": 5.8.0 + "@ethersproject/keccak256": 5.8.0 + "@ethersproject/properties": 5.8.0 + "@ethersproject/providers": 5.8.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + "@ethersproject/rlp": 5.8.0 + "@ethersproject/transactions": 5.8.0 + "@ethersproject/web": 5.8.0 + bufio: 1.2.3 + chai: 4.5.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + "@ethereumjs/common@10.1.1": dependencies: "@ethereumjs/util": 10.1.1 @@ -11992,6 +13873,184 @@ snapshots: "@ethereumjs/rlp": 5.0.2 ethereum-cryptography: 2.2.1 + "@ethersproject/abi@5.8.0": + dependencies: + "@ethersproject/address": 5.8.0 + "@ethersproject/bignumber": 5.8.0 + "@ethersproject/bytes": 5.8.0 + "@ethersproject/constants": 5.8.0 + "@ethersproject/hash": 5.8.0 + "@ethersproject/keccak256": 5.8.0 + "@ethersproject/logger": 5.8.0 + "@ethersproject/properties": 5.8.0 + "@ethersproject/strings": 5.8.0 + + "@ethersproject/abstract-provider@5.8.0": + dependencies: + "@ethersproject/bignumber": 5.8.0 + "@ethersproject/bytes": 5.8.0 + "@ethersproject/logger": 5.8.0 + "@ethersproject/networks": 5.8.0 + "@ethersproject/properties": 5.8.0 + "@ethersproject/transactions": 5.8.0 + "@ethersproject/web": 5.8.0 + + "@ethersproject/abstract-signer@5.8.0": + dependencies: + "@ethersproject/abstract-provider": 5.8.0 + "@ethersproject/bignumber": 5.8.0 + "@ethersproject/bytes": 5.8.0 + "@ethersproject/logger": 5.8.0 + "@ethersproject/properties": 5.8.0 + + "@ethersproject/address@5.8.0": + dependencies: + "@ethersproject/bignumber": 5.8.0 + "@ethersproject/bytes": 5.8.0 + "@ethersproject/keccak256": 5.8.0 + "@ethersproject/logger": 5.8.0 + "@ethersproject/rlp": 5.8.0 + + "@ethersproject/base64@5.8.0": + dependencies: + "@ethersproject/bytes": 5.8.0 + + "@ethersproject/basex@5.8.0": + dependencies: + "@ethersproject/bytes": 5.8.0 + "@ethersproject/properties": 5.8.0 + + "@ethersproject/bignumber@5.8.0": + dependencies: + "@ethersproject/bytes": 5.8.0 + "@ethersproject/logger": 5.8.0 + bn.js: 5.2.3 + + "@ethersproject/bytes@5.8.0": + dependencies: + "@ethersproject/logger": 5.8.0 + + "@ethersproject/constants@5.8.0": + dependencies: + "@ethersproject/bignumber": 5.8.0 + + "@ethersproject/contracts@5.8.0": + dependencies: + "@ethersproject/abi": 5.8.0 + "@ethersproject/abstract-provider": 5.8.0 + "@ethersproject/abstract-signer": 5.8.0 + "@ethersproject/address": 5.8.0 + "@ethersproject/bignumber": 5.8.0 + "@ethersproject/bytes": 5.8.0 + "@ethersproject/constants": 5.8.0 + "@ethersproject/logger": 5.8.0 + "@ethersproject/properties": 5.8.0 + "@ethersproject/transactions": 5.8.0 + + "@ethersproject/hash@5.8.0": + dependencies: + "@ethersproject/abstract-signer": 5.8.0 + "@ethersproject/address": 5.8.0 + "@ethersproject/base64": 5.8.0 + "@ethersproject/bignumber": 5.8.0 + "@ethersproject/bytes": 5.8.0 + "@ethersproject/keccak256": 5.8.0 + "@ethersproject/logger": 5.8.0 + "@ethersproject/properties": 5.8.0 + "@ethersproject/strings": 5.8.0 + + "@ethersproject/keccak256@5.8.0": + dependencies: + "@ethersproject/bytes": 5.8.0 + js-sha3: 0.8.0 + + "@ethersproject/logger@5.8.0": {} + + "@ethersproject/networks@5.8.0": + dependencies: + "@ethersproject/logger": 5.8.0 + + "@ethersproject/properties@5.8.0": + dependencies: + "@ethersproject/logger": 5.8.0 + + "@ethersproject/providers@5.8.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)": + dependencies: + "@ethersproject/abstract-provider": 5.8.0 + "@ethersproject/abstract-signer": 5.8.0 + "@ethersproject/address": 5.8.0 + "@ethersproject/base64": 5.8.0 + "@ethersproject/basex": 5.8.0 + "@ethersproject/bignumber": 5.8.0 + "@ethersproject/bytes": 5.8.0 + "@ethersproject/constants": 5.8.0 + "@ethersproject/hash": 5.8.0 + "@ethersproject/logger": 5.8.0 + "@ethersproject/networks": 5.8.0 + "@ethersproject/properties": 5.8.0 + "@ethersproject/random": 5.8.0 + "@ethersproject/rlp": 5.8.0 + "@ethersproject/sha2": 5.8.0 + "@ethersproject/strings": 5.8.0 + "@ethersproject/transactions": 5.8.0 + "@ethersproject/web": 5.8.0 + bech32: 1.1.4 + ws: 8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + "@ethersproject/random@5.8.0": + dependencies: + "@ethersproject/bytes": 5.8.0 + "@ethersproject/logger": 5.8.0 + + "@ethersproject/rlp@5.8.0": + dependencies: + "@ethersproject/bytes": 5.8.0 + "@ethersproject/logger": 5.8.0 + + "@ethersproject/sha2@5.8.0": + dependencies: + "@ethersproject/bytes": 5.8.0 + "@ethersproject/logger": 5.8.0 + hash.js: 1.1.7 + + "@ethersproject/signing-key@5.8.0": + dependencies: + "@ethersproject/bytes": 5.8.0 + "@ethersproject/logger": 5.8.0 + "@ethersproject/properties": 5.8.0 + bn.js: 5.2.3 + elliptic: 6.6.1 + hash.js: 1.1.7 + + "@ethersproject/strings@5.8.0": + dependencies: + "@ethersproject/bytes": 5.8.0 + "@ethersproject/constants": 5.8.0 + "@ethersproject/logger": 5.8.0 + + "@ethersproject/transactions@5.8.0": + dependencies: + "@ethersproject/address": 5.8.0 + "@ethersproject/bignumber": 5.8.0 + "@ethersproject/bytes": 5.8.0 + "@ethersproject/constants": 5.8.0 + "@ethersproject/keccak256": 5.8.0 + "@ethersproject/logger": 5.8.0 + "@ethersproject/properties": 5.8.0 + "@ethersproject/rlp": 5.8.0 + "@ethersproject/signing-key": 5.8.0 + + "@ethersproject/web@5.8.0": + dependencies: + "@ethersproject/base64": 5.8.0 + "@ethersproject/bytes": 5.8.0 + "@ethersproject/logger": 5.8.0 + "@ethersproject/properties": 5.8.0 + "@ethersproject/strings": 5.8.0 + "@fivebinaries/coin-selection@3.0.0": dependencies: "@emurgo/cardano-serialization-lib-browser": 13.2.1 @@ -12054,29 +14113,31 @@ snapshots: "@humanwhocodes/module-importer@1.0.1": {} + "@humanwhocodes/momoa@2.0.4": {} + "@humanwhocodes/retry@0.4.3": {} "@identity-connect/api@0.8.0": {} - "@identity-connect/crypto@0.3.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1)": + "@identity-connect/crypto@0.3.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1)": dependencies: - "@aptos-connect/wallet-api": 0.6.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1) - "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) + "@aptos-connect/wallet-api": 0.6.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1) + "@aptos-labs/ts-sdk": 5.2.1(got@12.6.1) "@noble/hashes": 1.8.0 ed2curve: 0.3.0 tweetnacl: 1.0.3 transitivePeerDependencies: - "@wallet-standard/core" - "@identity-connect/dapp-sdk@0.15.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@aptos-labs/wallet-standard@0.5.2(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1))(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1)": + "@identity-connect/dapp-sdk@0.15.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@aptos-labs/wallet-standard@0.5.2(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1))(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1)": dependencies: - "@aptos-connect/wallet-api": 0.6.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1) - "@aptos-connect/web-transport": 0.5.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@aptos-labs/wallet-standard@0.5.2(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1))(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1) - "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) - "@aptos-labs/wallet-standard": 0.5.2(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1) + "@aptos-connect/wallet-api": 0.6.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1) + "@aptos-connect/web-transport": 0.5.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@aptos-labs/wallet-standard@0.5.2(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1))(@telegram-apps/bridge@1.9.2)(@wallet-standard/core@1.1.1) + "@aptos-labs/ts-sdk": 5.2.1(got@12.6.1) + "@aptos-labs/wallet-standard": 0.5.2(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1) "@identity-connect/api": 0.8.0 - "@identity-connect/crypto": 0.3.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@wallet-standard/core@1.1.1) - "@identity-connect/wallet-api": 0.2.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6)) + "@identity-connect/crypto": 0.3.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@wallet-standard/core@1.1.1) + "@identity-connect/wallet-api": 0.2.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1)) axios: 1.13.5 uuid: 9.0.1 transitivePeerDependencies: @@ -12084,9 +14145,16 @@ snapshots: - "@wallet-standard/core" - debug - "@identity-connect/wallet-api@0.2.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))": + "@identity-connect/wallet-api@0.2.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))": dependencies: - "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) + "@aptos-labs/ts-sdk": 5.2.1(got@12.6.1) + + "@inquirer/external-editor@1.0.3(@types/node@22.19.11)": + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + "@types/node": 22.19.11 "@isaacs/cliui@9.0.0": {} @@ -12255,6 +14323,22 @@ snapshots: dependencies: "@lit-labs/ssr-dom-shim": 1.5.1 + "@manypkg/find-root@1.1.0": + dependencies: + "@babel/runtime": 7.28.6 + "@types/node": 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + "@manypkg/get-packages@1.1.3": + dependencies: + "@babel/runtime": 7.28.6 + "@changesets/types": 4.1.0 + "@manypkg/find-root": 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + "@metamask/eth-json-rpc-provider@1.0.1": dependencies: "@metamask/json-rpc-engine": 7.3.3 @@ -12448,11 +14532,11 @@ snapshots: "@microsoft/fetch-event-source@2.0.1": {} - "@mizuwallet-sdk/aptos-wallet-adapter@0.3.2(@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)))(@mizuwallet-sdk/protocol@0.0.6)(@wallet-standard/core@1.1.1)(axios@1.13.5)(got@11.8.6)": + "@mizuwallet-sdk/aptos-wallet-adapter@0.3.2(@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)))(@mizuwallet-sdk/protocol@0.0.6)(@wallet-standard/core@1.1.1)(axios@1.13.5)(got@12.6.1)": dependencies: - "@aptos-labs/ts-sdk": 1.39.0(axios@1.13.5)(got@11.8.6) - "@aptos-labs/wallet-standard": 0.1.0-ms.1(@aptos-labs/ts-sdk@1.39.0(axios@1.13.5)(got@11.8.6))(@wallet-standard/core@1.1.1) - "@mizuwallet-sdk/core": 1.4.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)) + "@aptos-labs/ts-sdk": 1.39.0(axios@1.13.5)(got@12.6.1) + "@aptos-labs/wallet-standard": 0.1.0-ms.1(@aptos-labs/ts-sdk@1.39.0(axios@1.13.5)(got@12.6.1))(@wallet-standard/core@1.1.1) + "@mizuwallet-sdk/core": 1.4.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)) "@mizuwallet-sdk/protocol": 0.0.6 buffer: 6.0.3 transitivePeerDependencies: @@ -12460,9 +14544,9 @@ snapshots: - axios - got - "@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@11.8.6))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0))": + "@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0))": dependencies: - "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) + "@aptos-labs/ts-sdk": 5.2.1(got@12.6.1) "@mizuwallet-sdk/protocol": 0.0.6 buffer: 6.0.3 graphql-request: 7.4.0(graphql@16.12.0) @@ -12567,6 +14651,123 @@ snapshots: "@noble/hashes@2.0.1": {} + "@nodelib/fs.scandir@2.1.5": + dependencies: + "@nodelib/fs.stat": 2.0.5 + run-parallel: 1.2.0 + + "@nodelib/fs.stat@2.0.5": {} + + "@nodelib/fs.walk@1.2.8": + dependencies: + "@nodelib/fs.scandir": 2.1.5 + fastq: 1.20.1 + + "@nomicfoundation/edr-darwin-arm64@0.12.0-next.28": {} + + "@nomicfoundation/edr-darwin-x64@0.12.0-next.28": {} + + "@nomicfoundation/edr-linux-arm64-gnu@0.12.0-next.28": {} + + "@nomicfoundation/edr-linux-arm64-musl@0.12.0-next.28": {} + + "@nomicfoundation/edr-linux-x64-gnu@0.12.0-next.28": {} + + "@nomicfoundation/edr-linux-x64-musl@0.12.0-next.28": {} + + "@nomicfoundation/edr-win32-x64-msvc@0.12.0-next.28": {} + + "@nomicfoundation/edr@0.12.0-next.28": + dependencies: + "@nomicfoundation/edr-darwin-arm64": 0.12.0-next.28 + "@nomicfoundation/edr-darwin-x64": 0.12.0-next.28 + "@nomicfoundation/edr-linux-arm64-gnu": 0.12.0-next.28 + "@nomicfoundation/edr-linux-arm64-musl": 0.12.0-next.28 + "@nomicfoundation/edr-linux-x64-gnu": 0.12.0-next.28 + "@nomicfoundation/edr-linux-x64-musl": 0.12.0-next.28 + "@nomicfoundation/edr-win32-x64-msvc": 0.12.0-next.28 + + "@nomicfoundation/hardhat-errors@3.0.8": + dependencies: + "@nomicfoundation/hardhat-utils": 4.0.1 + transitivePeerDependencies: + - supports-color + + "@nomicfoundation/hardhat-utils@4.0.1": + dependencies: + "@streamparser/json-node": 0.0.22 + debug: 4.4.3 + env-paths: 2.2.1 + ethereum-cryptography: 2.2.1 + fast-equals: 5.4.0 + json-stream-stringify: 3.1.6 + rfdc: 1.4.1 + undici: 6.24.0 + transitivePeerDependencies: + - supports-color + + "@nomicfoundation/hardhat-vendored@3.0.1": {} + + "@nomicfoundation/hardhat-zod-utils@3.0.3(zod@3.25.76)": + dependencies: + "@nomicfoundation/hardhat-errors": 3.0.8 + "@nomicfoundation/hardhat-utils": 4.0.1 + zod: 3.25.76 + transitivePeerDependencies: + - supports-color + + "@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2": + optional: true + + "@nomicfoundation/solidity-analyzer-darwin-x64@0.1.2": + optional: true + + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.2": + optional: true + + "@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.2": + optional: true + + "@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.2": + optional: true + + "@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.2": + optional: true + + "@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.2": + optional: true + + "@nomicfoundation/solidity-analyzer@0.1.2": + optionalDependencies: + "@nomicfoundation/solidity-analyzer-darwin-arm64": 0.1.2 + "@nomicfoundation/solidity-analyzer-darwin-x64": 0.1.2 + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": 0.1.2 + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": 0.1.2 + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": 0.1.2 + "@nomicfoundation/solidity-analyzer-linux-x64-musl": 0.1.2 + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": 0.1.2 + + "@offchainlabs/upgrade-executor@1.1.0-beta.0": + dependencies: + "@openzeppelin/contracts": 4.7.3 + "@openzeppelin/contracts-upgradeable": 4.7.3 + + "@openzeppelin/contracts-upgradeable@4.7.3": {} + + "@openzeppelin/contracts-upgradeable@4.9.6": {} + + "@openzeppelin/contracts@4.7.3": {} + + "@openzeppelin/contracts@4.8.3": {} + + "@openzeppelin/contracts@4.9.6": {} + + "@openzeppelin/contracts@5.0.2": {} + + "@openzeppelin/contracts@5.1.0": {} + + "@openzeppelin/contracts@5.6.1": {} + "@particle-network/analytics@1.0.2": dependencies: hash.js: 1.1.7 @@ -12595,6 +14796,18 @@ snapshots: "@paulmillr/qr@0.2.1": {} + "@pnpm/config.env-replace@1.1.0": {} + + "@pnpm/network.ca-file@1.0.2": + dependencies: + graceful-fs: 4.2.10 + + "@pnpm/npm-conf@3.0.2": + dependencies: + "@pnpm/config.env-replace": 1.1.0 + "@pnpm/network.ca-file": 1.0.2 + config-chain: 1.1.13 + "@project-serum/sol-wallet-adapter@0.2.6(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/web3.js": 1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) @@ -13617,6 +15830,8 @@ snapshots: "@safe-global/safe-gateway-typescript-sdk@3.23.1": {} + "@scroll-tech/contracts@2.0.0": {} + "@scure/base@1.1.9": {} "@scure/base@1.2.6": {} @@ -13659,12 +15874,16 @@ snapshots: "@noble/hashes": 1.8.0 "@scure/base": 1.2.6 + "@sentry/core@9.47.1": {} + "@sinclair/typebox@0.27.10": {} "@sinclair/typebox@0.33.22": {} "@sindresorhus/is@4.6.0": {} + "@sindresorhus/is@5.6.0": {} + "@sinonjs/commons@3.0.1": dependencies: type-detect: 4.0.8 @@ -13738,30 +15957,30 @@ snapshots: - react-native - typescript - "@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": + "@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - "@solana-program/stake@0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": + "@solana-program/stake@0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana-program/system@0.10.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10))": dependencies: "@solana/kit": 5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) - "@solana-program/system@0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": + "@solana-program/system@0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - "@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))": + "@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/sysvars": 5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": + "@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana-program/token@0.9.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10))": dependencies: @@ -14066,7 +16285,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - "@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/accounts": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/addresses": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -14079,11 +16298,11 @@ snapshots: "@solana/rpc": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/rpc-parsed-types": 2.3.0(typescript@5.9.3) "@solana/rpc-spec-types": 2.3.0(typescript@5.9.3) - "@solana/rpc-subscriptions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/rpc-subscriptions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/rpc-types": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/signers": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/sysvars": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana/transaction-confirmation": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/transaction-confirmation": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/transaction-messages": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/transactions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) typescript: 5.9.3 @@ -14299,14 +16518,14 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - "@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/errors": 2.3.0(typescript@5.9.3) "@solana/functional": 2.3.0(typescript@5.9.3) "@solana/rpc-subscriptions-spec": 2.3.0(typescript@5.9.3) "@solana/subscribable": 2.3.0(typescript@5.9.3) typescript: 5.9.3 - ws: 8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) "@solana/rpc-subscriptions-channel-websocket@5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)": dependencies: @@ -14338,7 +16557,7 @@ snapshots: optionalDependencies: typescript: 5.9.3 - "@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/errors": 2.3.0(typescript@5.9.3) "@solana/fast-stable-stringify": 2.3.0(typescript@5.9.3) @@ -14346,7 +16565,7 @@ snapshots: "@solana/promises": 2.3.0(typescript@5.9.3) "@solana/rpc-spec-types": 2.3.0(typescript@5.9.3) "@solana/rpc-subscriptions-api": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana/rpc-subscriptions-channel-websocket": 2.3.0(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/rpc-subscriptions-channel-websocket": 2.3.0(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/rpc-subscriptions-spec": 2.3.0(typescript@5.9.3) "@solana/rpc-transformers": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/rpc-types": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -14565,7 +16784,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - "@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/addresses": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/codecs-strings": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -14573,7 +16792,7 @@ snapshots: "@solana/keys": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/promises": 2.3.0(typescript@5.9.3) "@solana/rpc": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana/rpc-subscriptions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/rpc-subscriptions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/rpc-types": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/transaction-messages": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/transactions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -14916,11 +17135,11 @@ snapshots: - supports-color - utf-8-validate - "@solana/wallet-adapter-trezor@0.1.6(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/wallet-adapter-trezor@0.1.6(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/wallet-adapter-base": 0.9.27(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/web3.js": 1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) - "@trezor/connect-web": 9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@trezor/connect-web": 9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) buffer: 6.0.3 transitivePeerDependencies: - "@solana/sysvars" @@ -14983,7 +17202,7 @@ snapshots: - utf-8-validate - zod - "@solana/wallet-adapter-wallets@0.19.32(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bs58@5.0.0)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.76)": + "@solana/wallet-adapter-wallets@0.19.32(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bs58@5.0.0)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.76)": dependencies: "@solana/wallet-adapter-alpha": 0.1.14(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-avana": 0.1.17(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) @@ -15016,7 +17235,7 @@ snapshots: "@solana/wallet-adapter-tokenary": 0.1.16(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-tokenpocket": 0.4.23(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-torus": 0.11.32(@babel/runtime@7.28.6)(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(utf-8-validate@5.0.10) - "@solana/wallet-adapter-trezor": 0.1.6(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/wallet-adapter-trezor": 0.1.6(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-trust": 0.1.17(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-unsafe-burner": 0.1.11(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-walletconnect": 0.1.21(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -15205,6 +17424,8 @@ snapshots: eventemitter3: 5.0.4 uuid: 9.0.1 + "@solidity-parser/parser@0.20.2": {} + "@stellar/js-xdr@3.1.2": {} "@stellar/stellar-base@14.0.4": @@ -15229,6 +17450,12 @@ snapshots: transitivePeerDependencies: - debug + "@streamparser/json-node@0.0.22": + dependencies: + "@streamparser/json": 0.0.22 + + "@streamparser/json@0.0.22": {} + "@swc/helpers@0.5.18": dependencies: tslib: 2.8.1 @@ -15237,6 +17464,10 @@ snapshots: dependencies: defer-to-connect: 2.0.1 + "@szmarczak/http-timer@5.0.1": + dependencies: + defer-to-connect: 2.0.1 + "@tanstack/query-core@5.90.20": {} "@tanstack/react-query@5.90.21(react@18.3.1)": @@ -15414,13 +17645,13 @@ snapshots: - react-native - utf-8-validate - "@trezor/blockchain-link@2.6.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@trezor/blockchain-link@2.6.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: - "@solana-program/compute-budget": 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/stake": 0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/token": 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/token-2022": 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana-program/compute-budget": 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/stake": 0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/token": 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/token-2022": 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/rpc-types": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@stellar/stellar-sdk": 14.2.0 "@trezor/blockchain-link-types": 1.5.0(tslib@2.8.1) @@ -15468,9 +17699,9 @@ snapshots: - expo-localization - react-native - "@trezor/connect-web@9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@trezor/connect-web@9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: - "@trezor/connect": 9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@trezor/connect": 9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@trezor/connect-common": 0.5.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1) "@trezor/utils": 9.5.0(tslib@2.8.1) "@trezor/websocket-client": 1.3.0(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@5.0.10) @@ -15489,7 +17720,7 @@ snapshots: - utf-8-validate - ws - "@trezor/connect@9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@trezor/connect@9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@ethereumjs/common": 10.1.1 "@ethereumjs/tx": 10.1.1 @@ -15497,12 +17728,12 @@ snapshots: "@mobily/ts-belt": 3.13.1 "@noble/hashes": 1.8.0 "@scure/bip39": 1.6.0 - "@solana-program/compute-budget": 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/system": 0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/token": 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/token-2022": 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - "@trezor/blockchain-link": 2.6.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana-program/compute-budget": 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/system": 0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/token": 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/token-2022": 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@trezor/blockchain-link": 2.6.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@trezor/blockchain-link-types": 1.5.0(tslib@2.8.1) "@trezor/blockchain-link-utils": 1.5.1(bufferutil@4.1.0)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(utf-8-validate@5.0.10) "@trezor/connect-analytics": 1.4.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1) @@ -17404,6 +19635,8 @@ snapshots: - bufferutil - utf-8-validate + "@yarnpkg/lockfile@1.1.0": {} + abitype@1.0.6(typescript@5.9.3)(zod@3.25.76): optionalDependencies: typescript: 5.9.3 @@ -17449,6 +19682,8 @@ snapshots: acorn@8.15.0: {} + adm-zip@0.4.16: {} + aes-js@4.0.0-beta.5: {} agent-base@7.1.4: {} @@ -17457,6 +19692,10 @@ snapshots: dependencies: humanize-ms: 1.2.1 + ajv-errors@1.0.1(ajv@6.14.0): + dependencies: + ajv: 6.14.0 + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -17464,8 +19703,24 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ajv@6.14.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + anser@1.4.10: {} + ansi-colors@4.1.3: {} + ansi-escapes@7.3.0: dependencies: environment: 1.1.0 @@ -17487,9 +19742,9 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 - aptos@1.22.1(got@11.8.6): + aptos@1.22.1(got@12.6.1): dependencies: - "@aptos-labs/aptos-client": 2.1.0(got@11.8.6) + "@aptos-labs/aptos-client": 2.1.0(got@12.6.1) "@noble/hashes": 1.3.3 "@scure/bip39": 1.2.1 eventemitter3: 5.0.4 @@ -17501,6 +19756,10 @@ snapshots: dependencies: sprintf-js: 1.0.3 + argparse@2.0.1: {} + + array-union@2.1.0: {} + asap@2.0.6: {} asn1.js@4.10.1: @@ -17517,6 +19776,12 @@ snapshots: object.assign: 4.1.7 util: 0.12.5 + assertion-error@1.1.0: {} + + ast-parents@0.0.1: {} + + astral-regex@2.0.0: {} + async-mutex@0.2.6: dependencies: tslib: 2.8.1 @@ -17527,6 +19792,8 @@ snapshots: asynckit@0.4.0: {} + at-least-node@1.0.0: {} + atomic-sleep@1.0.0: {} available-typed-arrays@1.0.7: @@ -17627,7 +19894,22 @@ snapshots: baseline-browser-mapping@2.9.19: {} - bech32@2.0.0: {} + bech32@1.1.4: {} + + bech32@2.0.0: {} + + better-ajv-errors@2.0.3(ajv@6.14.0): + dependencies: + "@babel/code-frame": 7.29.0 + "@humanwhocodes/momoa": 2.0.4 + ajv: 6.14.0 + chalk: 4.1.2 + jsonpointer: 5.0.1 + leven: 3.1.0 + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 big-integer@1.6.36: {} @@ -17713,13 +19995,13 @@ snapshots: browserify-rsa@4.1.1: dependencies: - bn.js: 5.2.2 + bn.js: 5.2.3 randombytes: 2.1.0 safe-buffer: 5.2.1 browserify-sign@4.2.5: dependencies: - bn.js: 5.2.2 + bn.js: 5.2.3 browserify-rsa: 4.1.1 create-hash: 1.2.0 create-hmac: 1.1.7 @@ -17790,10 +20072,24 @@ snapshots: dependencies: node-gyp-build: 4.8.4 + bufio@1.2.3: {} + builtin-status-codes@3.0.0: {} cacheable-lookup@5.0.4: {} + cacheable-lookup@7.0.0: {} + + cacheable-request@10.2.14: + dependencies: + "@types/http-cache-semantics": 4.2.0 + get-stream: 6.0.1 + http-cache-semantics: 4.2.0 + keyv: 4.5.4 + mimic-response: 4.0.0 + normalize-url: 8.1.1 + responselike: 3.0.0 + cacheable-request@7.0.4: dependencies: clone-response: 1.0.3 @@ -17821,6 +20117,8 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 + callsites@3.1.0: {} + camelcase@5.3.1: {} camelcase@6.3.0: {} @@ -17837,6 +20135,16 @@ snapshots: dependencies: nofilter: 3.1.0 + chai@4.5.0: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.1.0 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -17844,8 +20152,18 @@ snapshots: chalk@5.6.2: {} + chardet@2.1.1: {} + charenc@0.0.2: {} + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + chokidar@5.0.0: dependencies: readdirp: 5.0.0 @@ -17931,6 +20249,8 @@ snapshots: dependencies: delayed-stream: 1.0.0 + commander@10.0.1: {} + commander@12.1.0: {} commander@13.1.0: {} @@ -17943,6 +20263,11 @@ snapshots: commander@2.20.3: {} + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + connect@3.7.0: dependencies: debug: 2.6.9 @@ -17962,6 +20287,15 @@ snapshots: core-util-is@1.0.3: {} + cosmiconfig@8.3.6(typescript@5.9.3): + dependencies: + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.9.3 + crc-32@1.2.2: {} crc@3.8.0: @@ -18004,6 +20338,14 @@ snapshots: transitivePeerDependencies: - encoding + cross-spawn@6.0.6: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -18063,6 +20405,8 @@ snapshots: optionalDependencies: typescript: 5.9.3 + dataloader@1.4.0: {} + dataloader@2.2.3: {} date-fns@2.30.0: @@ -18093,6 +20437,12 @@ snapshots: dedent@1.7.1: {} + deep-eql@4.1.4: + dependencies: + type-detect: 4.1.0 + + deep-extend@0.6.0: {} + deep-is@0.1.4: {} deep-object-diff@1.1.9: {} @@ -18138,6 +20488,8 @@ snapshots: detect-europe-js@0.1.2: {} + detect-indent@6.1.0: {} + detect-node-es@1.1.0: {} diffie-hellman@5.0.3: @@ -18148,6 +20500,10 @@ snapshots: dijkstrajs@1.0.3: {} + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + domain-browser@4.22.0: {} dot-case@3.0.4: @@ -18232,8 +20588,22 @@ snapshots: engine.io-parser@5.2.3: {} + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + env-paths@2.2.1: {} + environment@1.1.0: {} + era-contracts@https://codeload.github.com/matter-labs/era-contracts/tar.gz/446d391d34bdb48255d5f8fef8a8248925fc98b9: + {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + error-stack-parser@2.1.4: dependencies: stackframe: 1.3.4 @@ -18387,6 +20757,12 @@ snapshots: transitivePeerDependencies: - supports-color + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + espree@11.1.0: dependencies: acorn: 8.15.0 @@ -18483,6 +20859,8 @@ snapshots: exponential-backoff@3.1.3: {} + extendable-error@0.1.7: {} + extension-port-stream@2.1.1: dependencies: webextension-polyfill: 0.10.0 @@ -18498,8 +20876,18 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-diff@1.3.0: {} + fast-equals@5.4.0: {} + fast-glob@3.3.3: + dependencies: + "@nodelib/fs.stat": 2.0.5 + "@nodelib/fs.walk": 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} @@ -18512,8 +20900,14 @@ snapshots: fast-stringify@4.0.0: {} + fast-uri@3.1.0: {} + fastestsmallesttextencoderdecoder@1.0.22: {} + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + fb-dotslash@0.5.8: {} fb-watchman@2.0.2: @@ -18562,6 +20956,10 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + find-yarn-workspace-root@2.0.0: + dependencies: + micromatch: 4.0.8 + flat-cache@4.0.1: dependencies: flatted: 3.3.3 @@ -18577,6 +20975,8 @@ snapshots: dependencies: is-callable: 1.2.7 + form-data-encoder@2.1.4: {} + form-data@4.0.5: dependencies: asynckit: 0.4.0 @@ -18587,6 +20987,25 @@ snapshots: fresh@0.5.2: {} + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@9.1.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -18602,6 +21021,8 @@ snapshots: get-east-asian-width@1.4.0: {} + get-func-name@2.0.2: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -18630,10 +21051,16 @@ snapshots: dependencies: pump: 3.0.3 + get-stream@6.0.1: {} + get-tsconfig@4.13.6: dependencies: resolve-pkg-maps: 1.0.0 + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + glob-parent@6.0.2: dependencies: is-glob: 4.0.3 @@ -18647,8 +21074,27 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.9 + once: 1.4.0 + + globals@14.0.0: {} + globals@16.5.0: {} + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + gopd@1.2.0: {} got@11.8.6: @@ -18665,6 +21111,20 @@ snapshots: p-cancelable: 2.1.1 responselike: 2.0.1 + got@12.6.1: + dependencies: + "@sindresorhus/is": 5.6.0 + "@szmarczak/http-timer": 5.0.1 + cacheable-lookup: 7.0.0 + cacheable-request: 10.2.14 + decompress-response: 6.0.0 + form-data-encoder: 2.1.4 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 3.0.0 + gql.tada@1.9.0(graphql@16.12.0)(typescript@5.9.3): dependencies: "@0no-co/graphql.web": 1.2.0(graphql@16.12.0) @@ -18677,6 +21137,8 @@ snapshots: - "@gql.tada/vue-support" - graphql + graceful-fs@4.2.10: {} + graceful-fs@4.2.11: {} graphql-request@7.4.0(graphql@16.12.0): @@ -18698,6 +21160,33 @@ snapshots: ufo: 1.6.3 uncrypto: 0.1.3 + hardhat@3.1.12(bufferutil@4.1.0)(utf-8-validate@5.0.10): + dependencies: + "@nomicfoundation/edr": 0.12.0-next.28 + "@nomicfoundation/hardhat-errors": 3.0.8 + "@nomicfoundation/hardhat-utils": 4.0.1 + "@nomicfoundation/hardhat-vendored": 3.0.1 + "@nomicfoundation/hardhat-zod-utils": 3.0.3(zod@3.25.76) + "@nomicfoundation/solidity-analyzer": 0.1.2 + "@sentry/core": 9.47.1 + adm-zip: 0.4.16 + chalk: 5.6.2 + chokidar: 4.0.3 + debug: 4.4.3 + enquirer: 2.4.1 + ethereum-cryptography: 2.2.1 + micro-eth-signer: 0.14.0 + p-map: 7.0.4 + resolve.exports: 2.0.3 + semver: 7.7.4 + tsx: 4.21.0 + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + zod: 3.25.76 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + has-flag@4.0.0: {} has-property-descriptors@1.0.2: @@ -18768,6 +21257,11 @@ snapshots: quick-lru: 5.1.1 resolve-alpn: 1.2.1 + http2-wrapper@2.2.1: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + https-browserify@1.0.0: {} https-proxy-agent@7.0.6: @@ -18777,12 +21271,18 @@ snapshots: transitivePeerDependencies: - supports-color + human-id@4.1.3: {} + humanize-ms@1.2.1: dependencies: ms: 2.1.3 husky@9.1.7: {} + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + idb-keyval@6.2.1: {} idb-keyval@6.2.2: {} @@ -18797,6 +21297,11 @@ snapshots: dependencies: queue: 6.0.2 + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + imurmurhash@0.1.4: {} inflight@1.0.6: @@ -18806,6 +21311,8 @@ snapshots: inherits@2.0.4: {} + ini@1.3.8: {} + int64-buffer@1.1.0: {} invariant@2.2.4: @@ -18821,12 +21328,18 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-arrayish@0.2.1: {} + is-arrayish@0.3.4: {} is-buffer@1.1.6: {} is-callable@1.2.7: {} + is-ci@2.0.0: + dependencies: + ci-info: 2.0.0 + is-core-module@2.16.1: dependencies: hasown: 2.0.2 @@ -18878,10 +21391,16 @@ snapshots: is-stream@2.0.1: {} + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + is-typed-array@1.1.15: dependencies: which-typed-array: 1.1.20 + is-windows@1.0.2: {} + is-wsl@2.2.0: dependencies: is-docker: 2.2.1 @@ -19016,6 +21535,8 @@ snapshots: js-base64@3.7.8: {} + js-sha3@0.8.0: {} + js-tokens@4.0.0: {} js-yaml@3.14.2: @@ -19023,6 +21544,10 @@ snapshots: argparse: 1.0.10 esprima: 4.0.1 + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + jsbi@3.2.5: {} jsc-safe-url@0.2.4: {} @@ -19031,6 +21556,8 @@ snapshots: json-buffer@3.0.1: {} + json-parse-even-better-errors@2.3.1: {} + json-rpc-engine@6.1.0: dependencies: "@metamask/safe-event-emitter": 2.0.0 @@ -19045,6 +21572,8 @@ snapshots: json-schema-traverse@0.4.1: {} + json-schema-traverse@1.0.0: {} + json-stable-stringify-without-jsonify@1.0.1: {} json-stable-stringify@1.3.0: @@ -19055,12 +21584,26 @@ snapshots: jsonify: 0.0.1 object-keys: 1.1.1 + json-stream-stringify@3.1.6: {} + json-stringify-safe@5.0.1: {} json5@2.2.3: {} + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + jsonify@0.0.1: {} + jsonpointer@5.0.1: {} + jsqr@1.4.0: {} jssha@3.2.0: {} @@ -19090,6 +21633,14 @@ snapshots: keyvaluestorage-interface@1.0.0: {} + klaw-sync@6.0.0: + dependencies: + graceful-fs: 4.2.11 + + latest-version@7.0.0: + dependencies: + package-json: 8.1.1 + leven@3.1.0: {} levn@0.4.1: @@ -19104,6 +21655,8 @@ snapshots: transitivePeerDependencies: - supports-color + lines-and-columns@1.2.4: {} + lint-staged@16.2.7: dependencies: commander: 14.0.3 @@ -19159,8 +21712,12 @@ snapshots: lodash.merge@4.6.2: {} + lodash.startcase@4.4.0: {} + lodash.throttle@4.1.1: {} + lodash.truncate@4.4.2: {} + lodash@4.17.21: {} lodash@4.17.23: {} @@ -19181,12 +21738,18 @@ snapshots: dependencies: js-tokens: 4.0.0 + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + lower-case@2.0.2: dependencies: tslib: 2.8.1 lowercase-keys@2.0.0: {} + lowercase-keys@3.0.0: {} + lru-cache@10.4.3: {} lru-cache@11.2.6: {} @@ -19232,6 +21795,8 @@ snapshots: merge-stream@2.0.0: {} + merge2@1.4.1: {} + metro-babel-transformer@0.83.4: dependencies: "@babel/core": 7.29.0 @@ -19406,6 +21971,12 @@ snapshots: - supports-color - utf-8-validate + micro-eth-signer@0.14.0: + dependencies: + "@noble/curves": 1.8.1 + "@noble/hashes": 1.7.1 + micro-packed: 0.7.3 + micro-ftch@0.3.1: {} micro-memoize@5.1.1: @@ -19413,6 +21984,10 @@ snapshots: fast-equals: 5.4.0 fast-stringify: 4.0.0 + micro-packed@0.7.3: + dependencies: + "@scure/base": 1.2.6 + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -19443,6 +22018,8 @@ snapshots: mimic-response@3.1.0: {} + mimic-response@4.0.0: {} + minimalistic-assert@1.0.1: {} minimalistic-crypto-utils@1.0.1: {} @@ -19451,10 +22028,16 @@ snapshots: dependencies: brace-expansion: 5.0.2 + minimatch@5.1.9: + dependencies: + brace-expansion: 2.0.2 + minimatch@9.0.5: dependencies: brace-expansion: 2.0.2 + minimist@1.2.8: {} + mipd@0.0.7(typescript@5.9.3): optionalDependencies: typescript: 5.9.3 @@ -19463,6 +22046,8 @@ snapshots: modern-ahocorasick@1.1.0: {} + mri@1.2.0: {} + ms@2.0.0: {} ms@2.1.2: {} @@ -19481,6 +22066,8 @@ snapshots: negotiator@1.0.0: {} + nice-try@1.0.5: {} + no-case@3.0.4: dependencies: lower-case: 2.0.2 @@ -19542,6 +22129,8 @@ snapshots: normalize-url@6.1.0: {} + normalize-url@8.1.1: {} + nullthrows@1.1.1: {} ob1@0.83.4: @@ -19622,6 +22211,10 @@ snapshots: os-browserify@0.3.0: {} + os-tmpdir@1.0.2: {} + + outdent@0.5.0: {} + ox@0.12.1(typescript@5.9.3)(zod@3.22.4): dependencies: "@adraffy/ens-normalize": 1.11.1 @@ -19740,6 +22333,12 @@ snapshots: p-cancelable@2.1.1: {} + p-cancelable@3.0.0: {} + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -19756,12 +22355,31 @@ snapshots: dependencies: p-limit: 3.1.0 + p-map@2.1.0: {} + + p-map@7.0.4: {} + p-try@2.2.0: {} + package-json@8.1.1: + dependencies: + got: 12.6.1 + registry-auth-token: 5.1.1 + registry-url: 6.0.1 + semver: 7.7.4 + + package-manager-detector@0.2.11: + dependencies: + quansync: 0.2.11 + pako@1.0.11: {} pako@2.1.0: {} + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + parse-asn1@5.1.9: dependencies: asn1.js: 4.10.1 @@ -19770,18 +22388,48 @@ snapshots: pbkdf2: 3.1.5 safe-buffer: 5.2.1 + parse-json@5.2.0: + dependencies: + "@babel/code-frame": 7.29.0 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + parseurl@1.3.3: {} + patch-package@6.5.1: + dependencies: + "@yarnpkg/lockfile": 1.1.0 + chalk: 4.1.2 + cross-spawn: 6.0.6 + find-yarn-workspace-root: 2.0.0 + fs-extra: 9.1.0 + is-ci: 2.0.0 + klaw-sync: 6.0.0 + minimist: 1.2.8 + open: 7.4.2 + rimraf: 2.7.1 + semver: 5.7.2 + slash: 2.0.0 + tmp: 0.0.33 + yaml: 1.10.2 + path-browserify@1.0.1: {} path-exists@4.0.0: {} path-is-absolute@1.0.1: {} + path-key@2.0.1: {} + path-key@3.1.1: {} path-parse@1.0.7: {} + path-type@4.0.0: {} + + pathval@1.1.1: {} + pbkdf2@3.1.5: dependencies: create-hash: 1.2.0 @@ -19801,6 +22449,8 @@ snapshots: pify@3.0.0: {} + pify@4.0.1: {} + pify@5.0.0: {} pino-abstract-transport@0.5.0: @@ -19830,6 +22480,8 @@ snapshots: dependencies: find-up: 5.0.0 + pluralize@8.0.0: {} + pngjs@5.0.0: {} pony-cause@2.1.11: {} @@ -19892,6 +22544,8 @@ snapshots: prelude-ls@1.2.1: {} + prettier@2.8.8: {} + prettier@3.8.1: {} pretty-format@29.7.0: @@ -19916,6 +22570,8 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + proto-list@1.2.4: {} + protobufjs@7.4.0: dependencies: "@protobufjs/aspromise": 1.1.2 @@ -19985,6 +22641,8 @@ snapshots: dependencies: side-channel: 1.1.0 + quansync@0.2.11: {} + query-string@7.1.3: dependencies: decode-uri-component: 0.2.2 @@ -19994,6 +22652,8 @@ snapshots: querystring-es3@0.2.1: {} + queue-microtask@1.2.3: {} + queue@6.0.2: dependencies: inherits: 2.0.4 @@ -20015,6 +22675,13 @@ snapshots: range-parser@1.2.1: {} + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@5.0.10): dependencies: shell-quote: 1.8.3 @@ -20135,6 +22802,13 @@ snapshots: dependencies: loose-envify: 1.4.0 + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.2 + pify: 4.0.1 + strip-bom: 3.0.0 + readable-stream@2.3.8: dependencies: core-util-is: 1.0.3 @@ -20159,22 +22833,38 @@ snapshots: process: 0.11.10 string_decoder: 1.3.0 + readdirp@4.1.2: {} + readdirp@5.0.0: {} real-require@0.1.0: {} regenerator-runtime@0.13.11: {} + registry-auth-token@5.1.1: + dependencies: + "@pnpm/npm-conf": 3.0.2 + + registry-url@6.0.1: + dependencies: + rc: 1.2.8 + require-directory@2.1.1: {} + require-from-string@2.0.2: {} + require-main-filename@2.0.0: {} resolve-alpn@1.2.1: {} + resolve-from@4.0.0: {} + resolve-from@5.0.0: {} resolve-pkg-maps@1.0.0: {} + resolve.exports@2.0.3: {} + resolve@1.22.11: dependencies: is-core-module: 2.16.1 @@ -20185,13 +22875,23 @@ snapshots: dependencies: lowercase-keys: 2.0.0 + responselike@3.0.0: + dependencies: + lowercase-keys: 3.0.0 + restore-cursor@5.1.0: dependencies: onetime: 7.0.0 signal-exit: 4.1.0 + reusify@1.1.0: {} + rfdc@1.4.1: {} + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + rimraf@3.0.2: dependencies: glob: 7.2.3 @@ -20275,6 +22975,10 @@ snapshots: dependencies: sdp: 2.12.0 + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + rxjs@6.6.7: dependencies: tslib: 1.14.1 @@ -20295,6 +22999,8 @@ snapshots: safe-stable-stringify@2.5.0: {} + safer-buffer@2.1.2: {} + salmon-adapter-sdk@1.1.1(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)): dependencies: "@project-serum/sol-wallet-adapter": 0.2.6(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) @@ -20309,6 +23015,8 @@ snapshots: sdp@2.12.0: {} + semver@5.7.2: {} + semver@6.3.1: {} semver@7.7.3: {} @@ -20365,10 +23073,16 @@ snapshots: safe-buffer: 5.2.1 to-buffer: 1.2.2 + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 + shebang-regex@1.0.0: {} + shebang-regex@3.0.0: {} shell-quote@1.8.3: {} @@ -20409,8 +23123,16 @@ snapshots: dependencies: is-arrayish: 0.3.4 + slash@2.0.0: {} + slash@3.0.0: {} + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + slice-ansi@7.1.2: dependencies: ansi-styles: 6.2.3 @@ -20454,6 +23176,33 @@ snapshots: ip-address: 10.1.0 smart-buffer: 4.2.0 + solady@0.0.182: {} + + solhint@6.0.3(typescript@5.9.3): + dependencies: + "@solidity-parser/parser": 0.20.2 + ajv: 6.14.0 + ajv-errors: 1.0.1(ajv@6.14.0) + ast-parents: 0.0.1 + better-ajv-errors: 2.0.3(ajv@6.14.0) + chalk: 4.1.2 + commander: 10.0.1 + cosmiconfig: 8.3.6(typescript@5.9.3) + fast-diff: 1.3.0 + glob: 8.1.0 + ignore: 5.3.2 + js-yaml: 4.1.1 + latest-version: 7.0.0 + lodash: 4.17.23 + pluralize: 8.0.0 + semver: 7.7.4 + table: 6.9.0 + text-table: 0.2.0 + optionalDependencies: + prettier: 2.8.8 + transitivePeerDependencies: + - typescript + sonic-boom@2.8.0: dependencies: atomic-sleep: 1.0.0 @@ -20469,6 +23218,11 @@ snapshots: source-map@0.6.1: {} + spawndamnit@3.0.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + split-on-first@1.1.0: {} split2@4.2.0: {} @@ -20546,6 +23300,12 @@ snapshots: dependencies: ansi-regex: 6.2.2 + strip-bom@3.0.0: {} + + strip-json-comments@2.0.1: {} + + strip-json-comments@3.1.1: {} + superstruct@0.15.5: {} superstruct@1.0.4: {} @@ -20562,8 +23322,18 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + table@6.9.0: + dependencies: + ajv: 8.18.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + tagged-tag@1.0.0: {} + term-size@2.2.1: {} + terser@5.46.0: dependencies: "@jridgewell/source-map": 0.3.11 @@ -20579,6 +23349,8 @@ snapshots: text-encoding-utf-8@1.0.2: {} + text-table@0.2.0: {} + thread-stream@0.15.2: dependencies: real-require: 0.1.0 @@ -20602,6 +23374,10 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + tmpl@1.0.5: {} to-buffer@1.2.2: @@ -20651,6 +23427,8 @@ snapshots: type-detect@4.0.8: {} + type-detect@4.1.0: {} + type-fest@0.7.1: {} type-fest@5.4.4: @@ -20704,10 +23482,16 @@ snapshots: undici-types@7.21.0: {} + undici@6.24.0: {} + unidragger@3.0.1: dependencies: ev-emitter: 2.1.2 + universalify@0.1.2: {} + + universalify@2.0.1: {} + unload@2.4.1: {} unpipe@1.0.0: {} @@ -21057,6 +23841,10 @@ snapshots: gopd: 1.2.0 has-tostringtag: 1.0.2 + which@1.3.1: + dependencies: + isexe: 2.0.0 + which@2.0.2: dependencies: isexe: 2.0.0 @@ -21143,6 +23931,8 @@ snapshots: yallist@3.1.1: {} + yaml@1.10.2: {} + yaml@2.8.2: {} yargs-parser@18.1.3: From 06a1153aaf3601a6897c9d19c1292eefeb20845d Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Sat, 14 Mar 2026 04:28:46 +0000 Subject: [PATCH 2/6] Add comprehensive guide for example 04 Hardhat CCIP project --- examples/01-getting-started/package.json | 5 +- examples/02-evm-simple-bridge/package.json | 5 +- .../03-multichain-bridge-dapp/package.json | 5 +- examples/04-hardhat-ccip/.solhintignore | 1 + examples/04-hardhat-ccip/README.md | 755 ++++++++++++++++++ .../contracts/CCIPReceiver.sol | 72 +- .../04-hardhat-ccip/contracts/CCIPSender.sol | 12 + .../04-hardhat-ccip/contracts/test/Setup.sol | 7 + examples/04-hardhat-ccip/hardhat.config.ts | 162 ++++ examples/04-hardhat-ccip/package.json | 13 +- examples/04-hardhat-ccip/tasks/check-inbox.ts | 190 +++++ .../04-hardhat-ccip/tasks/list-messages.ts | 164 ++++ .../04-hardhat-ccip/tasks/manage-allowlist.ts | 208 +++++ .../04-hardhat-ccip/tasks/manual-execute.ts | 158 ++++ .../04-hardhat-ccip/tasks/pause-contract.ts | 81 ++ .../04-hardhat-ccip/tasks/query-config.ts | 152 ++++ .../04-hardhat-ccip/tasks/send-via-router.ts | 246 +++++- .../04-hardhat-ccip/tasks/send-via-sender.ts | 320 ++++++-- .../04-hardhat-ccip/tasks/withdraw-funds.ts | 131 +++ .../04-hardhat-ccip/test/CCIPReceiver.test.ts | 266 ++++++ .../04-hardhat-ccip/test/CCIPSender.test.ts | 235 ++++++ .../04-hardhat-ccip/test/Integration.test.ts | 325 ++++++++ examples/04-hardhat-ccip/tsconfig.json | 2 +- packages/shared-brand/package.json | 3 + packages/shared-components/package.json | 7 +- packages/shared-config/package.json | 7 +- packages/shared-utils/package.json | 7 +- pnpm-lock.yaml | 252 +++++- 28 files changed, 3645 insertions(+), 146 deletions(-) create mode 100644 examples/04-hardhat-ccip/README.md create mode 100644 examples/04-hardhat-ccip/contracts/test/Setup.sol create mode 100644 examples/04-hardhat-ccip/tasks/check-inbox.ts create mode 100644 examples/04-hardhat-ccip/tasks/list-messages.ts create mode 100644 examples/04-hardhat-ccip/tasks/manage-allowlist.ts create mode 100644 examples/04-hardhat-ccip/tasks/manual-execute.ts create mode 100644 examples/04-hardhat-ccip/tasks/pause-contract.ts create mode 100644 examples/04-hardhat-ccip/tasks/query-config.ts create mode 100644 examples/04-hardhat-ccip/tasks/withdraw-funds.ts create mode 100644 examples/04-hardhat-ccip/test/CCIPReceiver.test.ts create mode 100644 examples/04-hardhat-ccip/test/CCIPSender.test.ts create mode 100644 examples/04-hardhat-ccip/test/Integration.test.ts diff --git a/examples/01-getting-started/package.json b/examples/01-getting-started/package.json index ecf4e01..4708857 100644 --- a/examples/01-getting-started/package.json +++ b/examples/01-getting-started/package.json @@ -1,6 +1,9 @@ { "name": "@ccip-examples/01-getting-started", "version": "1.0.0", + "engines": { + "node": ">=22.0.0" + }, "description": "Getting started with CCIP SDK - Node.js scripts for basic operations", "type": "module", "scripts": { @@ -20,7 +23,7 @@ "dependencies": { "@ccip-examples/shared-config": "workspace:*", "@ccip-examples/shared-utils": "workspace:*", - "@chainlink/ccip-sdk": "1.2.0", + "@chainlink/ccip-sdk": "1.3.1", "@coral-xyz/anchor": "^0.30.1", "@solana/web3.js": "^1.98.0", "bs58": "^6.0.0", diff --git a/examples/02-evm-simple-bridge/package.json b/examples/02-evm-simple-bridge/package.json index f9bb483..ea67d34 100644 --- a/examples/02-evm-simple-bridge/package.json +++ b/examples/02-evm-simple-bridge/package.json @@ -1,6 +1,9 @@ { "name": "@ccip-examples/02-evm-simple-bridge", "version": "1.0.0", + "engines": { + "node": ">=22.0.0" + }, "description": "Simple EVM-to-EVM bridge using wagmi, viem, and RainbowKit", "type": "module", "scripts": { @@ -13,7 +16,7 @@ "clean": "rm -rf dist" }, "dependencies": { - "@chainlink/ccip-sdk": "1.2.0", + "@chainlink/ccip-sdk": "1.3.1", "@ccip-examples/shared-brand": "workspace:*", "@ccip-examples/shared-config": "workspace:*", "@ccip-examples/shared-components": "workspace:*", diff --git a/examples/03-multichain-bridge-dapp/package.json b/examples/03-multichain-bridge-dapp/package.json index f5541c7..194a195 100644 --- a/examples/03-multichain-bridge-dapp/package.json +++ b/examples/03-multichain-bridge-dapp/package.json @@ -1,6 +1,9 @@ { "name": "@ccip-examples/03-multichain-bridge-dapp", "version": "1.0.0", + "engines": { + "node": ">=22.0.0" + }, "description": "Multichain EVM + Solana + Aptos bridge using CCIP SDK", "type": "module", "scripts": { @@ -15,7 +18,7 @@ "dependencies": { "@aptos-labs/ts-sdk": "^5.2.1", "@aptos-labs/wallet-adapter-react": "^3.7.2", - "@chainlink/ccip-sdk": "1.2.0", + "@chainlink/ccip-sdk": "1.3.1", "@ccip-examples/shared-brand": "workspace:*", "@ccip-examples/shared-config": "workspace:*", "@ccip-examples/shared-components": "workspace:*", diff --git a/examples/04-hardhat-ccip/.solhintignore b/examples/04-hardhat-ccip/.solhintignore index c2658d7..0991d4a 100644 --- a/examples/04-hardhat-ccip/.solhintignore +++ b/examples/04-hardhat-ccip/.solhintignore @@ -1 +1,2 @@ node_modules/ +contracts/test/ diff --git a/examples/04-hardhat-ccip/README.md b/examples/04-hardhat-ccip/README.md new file mode 100644 index 0000000..8d2c944 --- /dev/null +++ b/examples/04-hardhat-ccip/README.md @@ -0,0 +1,755 @@ +# 04 - Hardhat v3 + CCIP SDK + +> **CCIP SDK** [`@chainlink/ccip-sdk@1.2.0`](https://www.npmjs.com/package/@chainlink/ccip-sdk/v/1.2.0) | **Testnet only** | [CCIP Docs](https://docs.chain.link/ccip) | [CCIP Explorer](https://ccip.chain.link) + +> **Disclaimer** +> +> _This tutorial represents an educational example to use a Chainlink system, product, or service and is provided to demonstrate how to interact with Chainlink's systems, products, and services to integrate them into your own. This template is provided "AS IS" and "AS AVAILABLE" without warranties of any kind, it has not been audited, and it may be missing key checks or error handling to make the usage of the system, product or service more clear. Do not use the code in this example in a production environment without completing your own audits and application of best practices. Neither Chainlink Labs, the Chainlink Foundation, nor Chainlink node operators are responsible for unintended outputs that are generated due to errors in code._ + +Examples 01–03 use the SDK as the entire execution layer — `chain.sendMessage()` handles approvals, message building, and `ccipSend` with no custom contracts. + +This example uses custom sender and receiver contracts for the on-chain execution, and the SDK for offchain operations: gas estimation, extraArgs encoding, fee calculation, message tracking, status monitoring, and manual execution of failed messages. It covers all three CCIP message types (token transfer, data-only, and programmable token transfer). + +## Architecture + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ Hardhat v3 Tasks │ +│ │ +│ deploy-sender deploy-receiver manage-allowlist send-via-sender │ +│ send-via-router check-status check-inbox manual-execute │ +│ list-messages pause-contract withdraw-funds query-config │ +└───────────────────────────────────┬─────────────────────────────────────────┘ + │ + ┌─────────────────────┼─────────────────────┐ + │ │ │ + ▼ ▼ ▼ +┌──────────────────────┐ ┌──────────────────┐ ┌────────────────────────────┐ +│ hre.artifacts │ │ viem clients │ │ CCIP SDK │ +│ .readArtifact() │ │ │ │ (@chainlink/ccip-sdk) │ +│ │ │ publicClient │ │ │ +│ CCIPSender ABI │ │ walletClient │ │ encodeExtraArgs() │ +│ CCIPReceiver ABI │ │ erc20Abi │ │ estimateReceiveExecution()│ +│ │ │ │ │ getLaneLatency() │ +│ │ │ │ │ chain.execute() │ +│ │ │ │ │ searchMessages() │ +│ │ │ │ │ fromViemClient() │ +│ │ │ │ │ viemWallet() │ +│ │ │ │ │ getCCIPExplorerUrl() │ +│ │ │ │ │ CCIPAPIClient │ +└──────────────────────┘ └────────┬─────────┘ └──────────────┬─────────────┘ + │ │ + ▼ ▼ + ┌─────────────────────────────────────────────┐ + │ Blockchain RPCs │ + │ │ + │ Source Chain Destination Chain │ + │ ┌───────────┐ ┌───────────────┐ │ + │ │CCIPSender │──CCIP──▶│CCIPReceiver │ │ + │ │ .send() │ │ .ccipReceive()│ │ + │ └───────────┘ └───────────────┘ │ + └─────────────────────────────────────────────┘ +``` + +## What You'll Learn + +**CCIP contracts:** + +- Deploy CCIP sender and receiver contracts with Hardhat v3 +- Three message types: token transfer (TT), data-only (cross-chain inbox), programmable token transfer (PTT) +- Peer registration, double-mapping allowlist, defensive try/catch, Ownable2Step, Pausable, ReentrancyGuard + +**SDK with custom contracts:** + +- Build `extraArgs` offchain via `encodeExtraArgs()` and pass them to your sender contract +- Estimate destination gas via `estimateReceiveExecution()` +- Estimate CCIP fees offchain via `getFee()` +- Extract the messageId from transaction logs via `getMessagesInTx()` +- Track delivery status, search messages, and query lane latency + +**SDK without contracts (direct router):** + +- Send via `sendMessage()` — the SDK handles approvals and `ccipSend` + +**Failure handling:** + +- Manual execution of failed messages via `chain.execute()` with auto gas estimation +- Recover tokens stuck in the receiver contract after processing failures +- Query failed message status and contract configuration + +## Smart Contracts + +### CCIPSender + +A sender contract that accepts pre-encoded `extraArgs` from offchain code. The SDK builds the `extraArgs` offchain; the contract forwards them to the router unchanged. + +| Pattern | Description | +| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Peer registration | `setPeer(destChainSelector, receiver)` — owner registers trusted (chain, receiver) pairs. `setPeers()` for batch. Sends to unregistered destinations revert. | +| Fee token deduplication | When the fee token (e.g., LINK) is the same as a transfer token, the contract combines into a single `transferFrom` + `approve` instead of two. | +| Excess native refund | If `msg.value` exceeds the actual CCIP fee, the excess is returned to the caller. | +| Ownable2Step | Two-step ownership transfer — new owner must call `acceptOwnership()`. | +| Pausable | Owner can halt all sends via `pause()`. | +| ReentrancyGuard | Prevents reentrancy via malicious ERC20 token callbacks. | +| SafeERC20 | Handles non-standard ERC20 tokens (e.g., USDT). | +| Recovery | `withdraw()` for native, `withdrawToken(beneficiary, token, amount)` for ERC20. | + +### CCIPReceiverExample + +A receiver contract that handles three message modes using the defensive pattern from the [Chainlink CCIP best practices](https://docs.chain.link/ccip/best-practices). + +| Pattern | Description | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Defensive try/catch | `_ccipReceive` wraps `processMessage()` in try/catch. If processing fails, tokens stay in the contract and the `messageId` is recorded in `failedMessages`. Owner recovers via `withdrawToken()`. | +| Double-mapping allowlist | `allowlistedSenders[sourceChainSelector][sender]` — prevents a contract on chain B from impersonating an allowlisted sender on chain A. `updateAllowlist()` for batch add/remove. | +| onlySelf modifier | `processMessage()` is `external` (required for try/catch) but restricted to `address(this)`. | +| Pausable | When paused, `_ccipReceive` reverts. CCIP marks the message as failed — it can be manually re-executed via the CCIP explorer once unpaused. | +| Ownable2Step | Same as sender. | +| ReentrancyGuard | Same as sender. | +| Recovery | `withdrawToken(beneficiary, token, amount)` — pass a specific amount to recover tokens from individual failed messages, or 0 for full balance. | + +**Message modes:** + +| Mode | Condition | Behavior | +| ------------------- | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| Token-only (TT) | `data.length == 0`, `destTokenAmounts.length > 0` | Holds tokens in contract. Emits `TokensReceived`. | +| Data-only (Inbox) | `data.length > 0`, `destTokenAmounts.length == 0` | Stores message in on-chain `inbox` array (sender, source chain, data, timestamp). Queryable via `getLatestMessages()`. Emits `DataReceived`. | +| Data + Tokens (PTT) | `data.length > 0`, `destTokenAmounts.length > 0` | Decodes a `recipient` address from `data`, forwards tokens to that address via `safeTransfer`. Emits `TokensForwarded`. | + +## Prerequisites + +### Node.js Version + +**Node.js v22+** is required. Use [nvm](https://github.com/nvm-sh/nvm) to manage versions: + +```bash +nvm install 22 +nvm use 22 +node --version # Should show v22.x.x +``` + +### pnpm Package Manager + +```bash +npm install -g pnpm +``` + +### Configured Networks + +| Network ID | Chain | +| --------------------------------- | ---------------- | +| `ethereum-testnet-sepolia` | Ethereum Sepolia | +| `ethereum-testnet-sepolia-base-1` | Base Sepolia | +| `avalanche-testnet-fuji` | Avalanche Fuji | + +These are the values used in `--network` and `--dest`/`--chains` flags throughout all tasks. + +### Testnet Tokens + +| What | Where | +| ------------------------------------- | ------------------------------------------------------------ | +| Sepolia ETH (gas) | [Chainlink Faucet](https://faucets.chain.link/sepolia) | +| Base Sepolia ETH (gas) | [Chainlink Faucet](https://faucets.chain.link/base-sepolia) | +| CCIP-BnM (transfer token) | [CCIP Test Tokens](https://docs.chain.link/ccip/test-tokens) | +| LINK (optional, for LINK fee payment) | [Chainlink Faucet](https://faucets.chain.link/) | + +## Installation + +```bash +# From the repository root +cd ccip-sdk-examples + +# Install all dependencies +pnpm install + +# Build shared packages (required for all examples) +pnpm build:packages +``` + +## Quick Start + +```bash +cd examples/04-hardhat-ccip + +# Copy environment file +cp .env.example .env +# Edit .env: +# EVM_PRIVATE_KEY= +# RPC_ETHEREUM_TESTNET_SEPOLIA= +# RPC_ETHEREUM_TESTNET_SEPOLIA_BASE_1= +# RPC_AVALANCHE_TESTNET_FUJI= + +# Compile contracts +pnpm build + +# Deploy receiver on Base Sepolia +npx hardhat --network ethereum-testnet-sepolia-base-1 deploy-receiver + +# Deploy sender on Sepolia, register receiver as peer +npx hardhat --network ethereum-testnet-sepolia deploy-sender \ + --peer-chain ethereum-testnet-sepolia-base-1 \ + --peer-address + +# Allowlist the sender on the existing receiver +npx hardhat --network ethereum-testnet-sepolia-base-1 manage-allowlist \ + --contract --type receiver \ + --chains ethereum-testnet-sepolia \ + --senders + +# Send a token transfer through the sender contract +npx hardhat --network ethereum-testnet-sepolia send-via-sender \ + --dest ethereum-testnet-sepolia-base-1 \ + --sender-contract \ + --receiver \ + --mode tt --amount 0.001 --token CCIP-BnM + +# Check status +npx hardhat check-status --message-id +``` + +## Hardhat Tasks + +### `deploy-sender` + +Deploys `CCIPSender` with the network's CCIP router. Can register a peer at deploy time. + +```bash +# Deploy only +npx hardhat --network ethereum-testnet-sepolia deploy-sender + +# Deploy and register a peer +npx hardhat --network ethereum-testnet-sepolia deploy-sender \ + --peer-chain ethereum-testnet-sepolia-base-1 \ + --peer-address 0x... +``` + +| Flag | Description | Default | +| ---------------- | ------------------------------------------ | ------- | +| `--peer-chain` | Destination chain to register (network ID) | — | +| `--peer-address` | Trusted receiver address on that chain | — | + +### `deploy-receiver` + +Deploys `CCIPReceiverExample` with the network's CCIP router. Can allowlist a source chain + sender at deploy time. + +```bash +# Deploy only +npx hardhat --network ethereum-testnet-sepolia-base-1 deploy-receiver + +# Deploy and allowlist a sender +npx hardhat --network ethereum-testnet-sepolia-base-1 deploy-receiver \ + --allowlist-chain ethereum-testnet-sepolia \ + --allowlist-sender 0x... +``` + +| Flag | Description | Default | +| -------------------- | ----------------------------------------- | ------- | +| `--allowlist-chain` | Source chain to allowlist (network ID) | — | +| `--allowlist-sender` | Sender address to allowlist on that chain | — | + +### `manage-allowlist` + +Manages allowlists on deployed `CCIPSender` (peers) or `CCIPReceiverExample` (senders) contracts. Supports single and batch operations. + +```bash +# Sender: register a peer +npx hardhat --network ethereum-testnet-sepolia manage-allowlist \ + --contract 0x... --type sender \ + --chains ethereum-testnet-sepolia-base-1 --peers 0x... + +# Receiver: batch allowlist (comma-separated chains and senders) +npx hardhat --network ethereum-testnet-sepolia-base-1 manage-allowlist \ + --contract 0x... --type receiver \ + --chains ethereum-testnet-sepolia,avalanche-testnet-fuji \ + --senders 0x...,0x... + +# Remove from allowlist +npx hardhat --network ethereum-testnet-sepolia manage-allowlist \ + --contract 0x... --type sender \ + --chains ethereum-testnet-sepolia-base-1 --peers 0x... --remove true +``` + +| Flag | Description | Default | +| ------------ | ------------------------------------------------ | ------- | +| `--contract` | Deployed contract address | — | +| `--type` | Contract type: `sender` or `receiver` | — | +| `--chains` | Comma-separated chain network IDs | — | +| `--peers` | Comma-separated peer addresses (sender type) | — | +| `--senders` | Comma-separated sender addresses (receiver type) | — | +| `--remove` | Set to `true` to remove from allowlist | — | + +### `send-via-sender` + +Sends a CCIP message through a deployed `CCIPSender` contract. The SDK builds `extraArgs` offchain, the contract forwards them to the router. + +Gas limit is auto-estimated via `estimateReceiveExecution()` for `data` and `ptt` modes. Override with `--gas-limit`. + +```bash +# Token transfer (TT) — gasLimit defaults to 0 (no data to process) +npx hardhat --network ethereum-testnet-sepolia send-via-sender \ + --dest ethereum-testnet-sepolia-base-1 \ + --sender-contract 0x... --receiver 0x... \ + --mode tt --amount 0.001 --token CCIP-BnM + +# Data-only — gasLimit auto-estimated +npx hardhat --network ethereum-testnet-sepolia send-via-sender \ + --dest ethereum-testnet-sepolia-base-1 \ + --sender-contract 0x... --receiver 0x... \ + --mode data + +# Programmable token transfer (PTT) — gasLimit auto-estimated +npx hardhat --network ethereum-testnet-sepolia send-via-sender \ + --dest ethereum-testnet-sepolia-base-1 \ + --sender-contract 0x... --receiver 0x... \ + --mode ptt --amount 0.001 --token CCIP-BnM +``` + +| Flag | Description | Default | +| ------------------- | ---------------------------------- | ---------- | +| `--dest` | Destination network ID | — | +| `--sender-contract` | Deployed CCIPSender address | — | +| `--receiver` | Receiver address on destination | — | +| `--mode` | `tt`, `data`, or `ptt` | — | +| `--amount` | Token amount (for tt/ptt) | `0` | +| `--token` | Token key | `CCIP-BnM` | +| `--fee-token` | `native` or `link` | `native` | +| `--gas-limit` | Override auto-estimated gas limit | `0` (auto) | +| `--data` | Hex-encoded data payload (for ptt) | — | + +### `send-via-router` + +Sends a CCIP message directly through the router using the SDK. No custom sender contract. The SDK builds the message, handles token approvals, and calls `ccipSend`. + +```bash +# Token transfer +npx hardhat --network ethereum-testnet-sepolia send-via-router \ + --dest ethereum-testnet-sepolia-base-1 \ + --receiver 0x... --mode tt --amount 0.001 --token CCIP-BnM + +# Data-only +npx hardhat --network ethereum-testnet-sepolia send-via-router \ + --dest ethereum-testnet-sepolia-base-1 \ + --receiver 0x... --mode data + +# PTT +npx hardhat --network ethereum-testnet-sepolia send-via-router \ + --dest ethereum-testnet-sepolia-base-1 \ + --receiver 0x... --mode ptt --amount 0.001 --token CCIP-BnM +``` + +| Flag | Description | Default | +| ------------- | ---------------------------------- | ---------- | +| `--dest` | Destination network ID | — | +| `--receiver` | Receiver address on destination | — | +| `--mode` | `tt`, `data`, or `ptt` | — | +| `--amount` | Token amount (for tt/ptt) | `0` | +| `--token` | Token key | `CCIP-BnM` | +| `--fee-token` | `native` or `link` | `native` | +| `--gas-limit` | Override auto-estimated gas limit | `0` (auto) | +| `--data` | Hex-encoded data payload (for ptt) | — | + +### `check-status` + +Checks CCIP message delivery status via the CCIP API. Retries automatically with exponential backoff. + +```bash +npx hardhat check-status --message-id 0x... +``` + +### `check-inbox` + +Reads the on-chain inbox from a deployed `CCIPReceiverExample`. Data-only messages are stored in the contract's `inbox` array with sender, source chain, data, and timestamp. + +```bash +# Show last 5 messages (default) +npx hardhat --network ethereum-testnet-sepolia-base-1 check-inbox \ + --receiver-contract 0x... + +# Show last 10 messages +npx hardhat --network ethereum-testnet-sepolia-base-1 check-inbox \ + --receiver-contract 0x... --count 10 + +# Look up a specific message by ID +npx hardhat --network ethereum-testnet-sepolia-base-1 check-inbox \ + --receiver-contract 0x... --message-id 0x... +``` + +| Flag | Description | Default | +| --------------------- | ------------------------------------ | ------- | +| `--receiver-contract` | Deployed CCIPReceiverExample address | — | +| `--count` | Number of latest messages to show | `5` | +| `--message-id` | Look up a specific message by ID | — | + +### `manual-execute` + +Manually re-executes a failed CCIP message on the destination chain. The SDK fetches merkle proofs and offchain token data from the CCIP API, then submits the execution transaction. + +When `--gas-limit` is not provided, the task estimates gas via `estimateReceiveExecution()` and adds a 10% margin. + +```bash +# Re-execute a failed message (gas auto-estimated) +npx hardhat --network ethereum-testnet-sepolia-base-1 manual-execute \ + --message-id 0x... + +# With a manual gas limit override +npx hardhat --network ethereum-testnet-sepolia-base-1 manual-execute \ + --message-id 0x... --gas-limit 300000 +``` + +| Flag | Description | Default | +| -------------- | ---------------------------------- | ---------- | +| `--message-id` | CCIP message ID to execute | — | +| `--gas-limit` | Gas limit override for ccipReceive | `0` (auto) | + +**Simulating a failure for testing:** + +```bash +# 1. Send a data-only message with a deliberately low gas limit +npx hardhat --network ethereum-testnet-sepolia send-via-router \ + --dest ethereum-testnet-sepolia-base-1 \ + --receiver 0x... --mode data --gas-limit 1000 + +# 2. The message will fail on destination (out of gas) +# 3. Wait for it to become eligible for manual execution (~20 min) +npx hardhat check-status --message-id 0x... + +# 4. Re-execute with a proper gas limit +npx hardhat --network ethereum-testnet-sepolia-base-1 manual-execute \ + --message-id 0x... --gas-limit 300000 +``` + +### `list-messages` + +Searches CCIP messages using the SDK's `searchAllMessages()` async generator. Handles pagination automatically. + +```bash +# List recent messages (default: 10) +npx hardhat list-messages + +# Filter by sender address +npx hardhat list-messages --sender 0x... + +# Filter by source and destination chain +npx hardhat list-messages \ + --source-chain ethereum-testnet-sepolia \ + --dest-chain ethereum-testnet-sepolia-base-1 + +# Filter by source transaction hash +npx hardhat list-messages --tx-hash 0x... + +# Show only messages ready for manual execution +npx hardhat list-messages --ready-for-exec true + +# Fetch more results +npx hardhat list-messages --limit 25 +``` + +| Flag | Description | Default | +| ------------------ | --------------------------------------------- | ------- | +| `--sender` | Filter by sender address | — | +| `--receiver` | Filter by receiver address | — | +| `--source-chain` | Filter by source chain (network ID) | — | +| `--dest-chain` | Filter by destination chain (network ID) | — | +| `--tx-hash` | Filter by source transaction hash | — | +| `--ready-for-exec` | Show only messages ready for manual execution | — | +| `--limit` | Maximum number of messages to show | `10` | + +### `pause-contract` + +Pauses or unpauses a `CCIPSender` or `CCIPReceiverExample` contract. When paused, the sender reverts on `send()` and the receiver reverts on `_ccipReceive()` (CCIP marks the message as failed; it can be manually re-executed once unpaused). + +```bash +# Pause sender contract +npx hardhat --network avalanche-testnet-fuji pause-contract \ + --contract 0x... --type sender --action pause + +# Unpause receiver contract +npx hardhat --network ethereum-testnet-sepolia pause-contract \ + --contract 0x... --type receiver --action unpause +``` + +| Flag | Description | Default | +| ------------ | ------------------------- | ------- | +| `--contract` | Deployed contract address | — | +| `--type` | `sender` or `receiver` | — | +| `--action` | `pause` or `unpause` | — | + +### `withdraw-funds` + +Withdraws native currency or ERC20 tokens from a contract. + +```bash +# Withdraw native currency +npx hardhat --network avalanche-testnet-fuji withdraw-funds \ + --contract 0x... --type sender --beneficiary 0x... + +# Withdraw ERC20 tokens (full balance) +npx hardhat --network ethereum-testnet-sepolia withdraw-funds \ + --contract 0x... --type receiver --beneficiary 0x... --token 0x... + +# Withdraw specific amount of ERC20 tokens +npx hardhat --network ethereum-testnet-sepolia withdraw-funds \ + --contract 0x... --type receiver --beneficiary 0x... --token 0x... --amount 1000000 +``` + +| Flag | Description | Default | +| --------------- | ------------------------------------------ | ------- | +| `--contract` | Deployed contract address | — | +| `--type` | `sender` or `receiver` | — | +| `--beneficiary` | Address to receive the withdrawn funds | — | +| `--token` | ERC20 token address (omit for native) | — | +| `--amount` | Amount in smallest unit (0 = full balance) | `0` | + +### `query-config` + +Queries contract configuration: peer registration, allowlist status, failed messages, and pause state. + +```bash +# Check if a peer is registered on sender +npx hardhat --network avalanche-testnet-fuji query-config \ + --contract 0x... --type sender --query peer \ + --chain ethereum-testnet-sepolia + +# Check if a sender is allowlisted on receiver +npx hardhat --network ethereum-testnet-sepolia query-config \ + --contract 0x... --type receiver --query allowlist \ + --chain avalanche-testnet-fuji --address 0x... + +# Check if a message failed on receiver +npx hardhat --network ethereum-testnet-sepolia query-config \ + --contract 0x... --type receiver --query failed \ + --message-id 0x... + +# Check contract pause status and owner +npx hardhat --network ethereum-testnet-sepolia query-config \ + --contract 0x... --type receiver --query status +``` + +| Flag | Description | Default | +| -------------- | ------------------------------------------ | ------- | +| `--contract` | Deployed contract address | — | +| `--type` | `sender` or `receiver` | — | +| `--query` | `peer`, `allowlist`, `failed`, or `status` | — | +| `--chain` | Chain network ID (for peer/allowlist) | — | +| `--address` | Sender address (for allowlist query) | — | +| `--message-id` | Message ID (for failed query) | — | + +## Sending Patterns + +### Pattern 1: Custom Contracts + SDK (`send-via-sender`) + +``` + Offchain (SDK) On-chain (CCIPSender) + ───────────── ───────────────────── + + estimateReceiveExecution() function send( + → gasLimit for ccipReceive destChainSelector, + receiver, + encodeExtraArgs({ data, + gasLimit, tokenAmounts, + allowOutOfOrderExecution extraArgs, ← passthrough + }) → bytes extraArgs ─────────────▶ feeToken + ) + getFee({ router, message }) │ + → estimated fee (display) ▼ + router.ccipSend( + getBalance(), getTokenInfo() destChainSelector, + → balance checks (display) message ← extraArgs forwarded as-is + ) + ─── after send ─── + + getMessagesInTx(txHash) + → messageId from logs + + CCIPAPIClient.getMessageById() + → delivery status tracking + + chain.execute({ messageId }) + → manual re-execution if failed +``` + +The contract does not encode `extraArgs` itself. The SDK handles version-specific encoding (EVMExtraArgsV1, V2, GenericExtraArgsV3). + +### Pattern 2: SDK Only (`send-via-router`, same as examples 01–03) + +``` + Offchain (SDK) + ───────────── + chain = fromViemClient(publicClient) + message = { receiver, data, tokenAmounts, extraArgs: { gasLimit } } + fee = chain.getFee({ router, destChainSelector, message }) + result = chain.sendMessage({ + router, destChainSelector, + message: { ...message, fee }, + wallet: viemWallet(walletClient) + }) + // result.message.messageId — already parsed, no getMessagesInTx needed +``` + +### Comparison + +| Consideration | Pattern 1 (Custom Contracts) | Pattern 2 (SDK Only) | +| --------------- | ------------------------------------ | -------------------------------- | +| Access control | On-chain `onlyOwner`, peer registry | Wallet-level only | +| Pausability | On-chain `whenNotPaused` | N/A | +| Fee management | On-chain deduplication, refunds | SDK handles | +| Token approvals | User approves the contract | SDK approves the router directly | +| Upgradability | Redeploy contract, re-register peers | Update the script | +| Auditability | Contract is on-chain, immutable | Script can change | + +## Gas Estimation + +Both send tasks auto-estimate `gasLimit` for `data` and `ptt` modes using `estimateReceiveExecution()`. Steps: + +1. Resolves onRamp and offRamp addresses from the router +2. Maps source token addresses to destination token addresses +3. Builds `eth_estimateGas` `stateOverride` with `stateDiff` entries that set the receiver's token balances as if the OffRamp had already transferred them +4. Calls `eth_estimateGas` on the destination chain with `from: router, to: receiver, data: ccipReceive(message)` and the state overrides from step 3 +5. Subtracts `(21,000 - 700)` to convert from transaction gas to internal CALL gas (21,000 is the base tx cost; 700 is the CALL opcode cost) +6. The task adds a 10% safety margin to the estimate + +For token-only transfers (`tt` mode), gasLimit is 0 — the SDK defaults to 0 when there is no data payload. + +## Lane Latency + +Both send tasks call `getLaneLatency()` before sending to display the estimated delivery time. The SDK queries the CCIP API for historical lane latency data. If the API is unavailable, the send proceeds without an estimate. + +## Key SDK Functions Used + +| Function | Package | Used In | Description | +| ---------------------------------- | -------------------------- | ---------------------------- | ------------------------------------------------------- | +| `encodeExtraArgs()` | `@chainlink/ccip-sdk` | send-via-sender | Encode gasLimit + flags into bytes for the router | +| `estimateReceiveExecution()` | `@chainlink/ccip-sdk` | send-via-sender/router | Simulate `ccipReceive` on destination to estimate gas | +| `chain.getLaneLatency()` | `@chainlink/ccip-sdk` | send-via-sender/router | Query historical lane latency from CCIP API | +| `chain.sendMessage()` | `@chainlink/ccip-sdk` | send-via-router | Build message, handle approvals, call `ccipSend` | +| `chain.getFee()` | `@chainlink/ccip-sdk` | send-via-router | Get CCIP fee for a message | +| `chain.execute()` | `@chainlink/ccip-sdk` | manual-execute | Manually execute a failed message on destination | +| `chain.estimateReceiveExecution()` | `@chainlink/ccip-sdk` | manual-execute | Estimate gas for `ccipReceive` on destination | +| `chain.getMessagesInTx()` | `@chainlink/ccip-sdk` | send-via-sender | Extract CCIP messages from a transaction | +| `searchAllMessages()` | `@chainlink/ccip-sdk` | list-messages | Async generator that paginates through CCIP API results | +| `getCCIPExplorerUrl()` | `@chainlink/ccip-sdk` | all tasks | Build CCIP Explorer URL for a message | +| `networkInfo()` | `@chainlink/ccip-sdk` | deploy, list-messages | Get chain selector and metadata for a network | +| `fromViemClient()` | `@chainlink/ccip-sdk/viem` | send, manual-execute | Create SDK chain instance from a viem PublicClient | +| `viemWallet()` | `@chainlink/ccip-sdk/viem` | send, manual-execute | Wrap viem WalletClient for SDK signing | +| `CCIPAPIClient` | `@chainlink/ccip-sdk` | check-status, list, execute | Query CCIP API for message status and search | +| `withRetry()` | `@chainlink/ccip-sdk` | check-status, manual-execute | Retry with exponential backoff and Retry-After | + +## Testing + +Tests use [`@chainlink/local`](https://www.npmjs.com/package/@chainlink/local) which provides a `CCIPLocalSimulator` with a `MockRouter`. The mock router delivers CCIP messages in the same transaction. + +```bash +pnpm test +``` + +Three test suites (28 tests total): + +| Suite | Description | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `CCIPSender.test.ts` | Unit tests: deployment, `setPeer`, `setPeers` batch, pause, access control, `withdraw`, `withdrawToken` | +| `CCIPReceiver.test.ts` | Unit tests: `allowlistSender`, `updateAllowlist` batch, pause, access control, `withdraw`, `withdrawToken`, `failedMessages` query | +| `Integration.test.ts` | End-to-end via LocalSimulator: data-only, token-only, PTT, batch allowlist, defensive try/catch, sender allowlist rejection | + +## Solidity Linting + +Contracts are linted with [solhint](https://protofire.github.io/solhint/): + +- `solhint ^6.0.2` with the [`chainlink-solidity`](https://github.com/smartcontractkit/chainlink-solhint-rules) plugin (v1.2.1) +- Extends `solhint:recommended` +- Chainlink naming conventions: `i_` prefix for immutables, `_` prefix for internal/private functions, explicit returns +- Zero warnings tolerance (`--max-warnings 0`) + +```bash +pnpm lint # Runs both solhint and eslint +pnpm lint:fix # Auto-fix both +``` + +## Project Structure + +``` +04-hardhat-ccip/ +├── contracts/ +│ ├── CCIPSender.sol # Sender: peer registration, extraArgs passthrough, batch setPeers +│ ├── CCIPReceiver.sol # Receiver: defensive try/catch, inbox, 3 message modes, batch updateAllowlist +│ └── test/ +│ └── Setup.sol # Re-exports CCIPLocalSimulator for test artifact generation +├── test/ +│ ├── CCIPSender.test.ts # Unit tests for sender contract +│ ├── CCIPReceiver.test.ts # Unit tests for receiver contract +│ └── Integration.test.ts # End-to-end tests with CCIPLocalSimulator +├── tasks/ +│ ├── deploy-sender.ts # Deploy + optional peer registration +│ ├── deploy-receiver.ts # Deploy + optional sender allowlisting +│ ├── manage-allowlist.ts # Manage peers (sender) or allowlist (receiver), single + batch +│ ├── send-via-sender.ts # Send through sender contract (+ lane latency) +│ ├── send-via-router.ts # Send directly via router (SDK) (+ lane latency) +│ ├── check-status.ts # Track message delivery via CCIP API +│ ├── check-inbox.ts # Read on-chain inbox from receiver contract +│ ├── manual-execute.ts # Re-execute failed messages on destination (auto gas estimation) +│ ├── list-messages.ts # Search messages with filters (async generator) +│ ├── pause-contract.ts # Pause/unpause sender or receiver contracts +│ ├── withdraw-funds.ts # Withdraw native or ERC20 tokens from contracts +│ └── query-config.ts # Query peers, allowlist, failed messages, pause status +├── helpers/ +│ └── sdk.ts # Shared SDK helpers (viem clients, router address) +├── hardhat.config.ts # Hardhat v3 config (networks from shared-config) +├── .solhint.json # Chainlink-matching solhint rules +├── .env.example # Environment variables template +├── package.json +├── tsconfig.json +└── README.md +``` + +## Troubleshooting + +### "PeerNotRegistered" + +No peer registered for the destination chain. + +Register the peer before sending: + +```bash +npx hardhat --network ethereum-testnet-sepolia deploy-sender \ + --peer-chain ethereum-testnet-sepolia-base-1 \ + --peer-address +``` + +Or call `setPeer()` on an already-deployed sender contract. + +### "SenderNotAllowed" + +The receiver contract hasn't allowlisted the sender address for the source chain. + +Allowlist the sender: + +```bash +npx hardhat --network ethereum-testnet-sepolia-base-1 manage-allowlist \ + --contract --type receiver \ + --chains ethereum-testnet-sepolia \ + --senders +``` + +### "Insufficient balance" / "InsufficientNativeFee" + +Not enough native tokens for gas or CCIP fees. Get testnet tokens from the faucets linked above. + +### Gas estimation fails + +The receiver contract isn't deployed, or the allowlist isn't configured. The SDK simulates `ccipReceive` on the destination contract — it must be deployed and configured. + +### "Message not found" in check-status + +CCIP messages take 20-40 seconds to be indexed by the API. The command retries with exponential backoff. If retries are exhausted, check the [CCIP Explorer](https://ccip.chain.link). + +### Node.js version errors + +Node.js v22+ required: + +```bash +node --version # Should be v22.x.x or higher +nvm use 22 # Switch if using nvm +``` + +## Note on Security + +The contracts implement application-level patterns documented in the [CCIPSender](#ccipsender) and [CCIPReceiverExample](#ccipreceiverexample) sections above. Protocol-level protections (rate limiting, replay protection, multi-attestation via DON + RMN, block finality, decimal normalization) are handled by CCIP itself and are not reimplemented here. diff --git a/examples/04-hardhat-ccip/contracts/CCIPReceiver.sol b/examples/04-hardhat-ccip/contracts/CCIPReceiver.sol index dac0251..b794878 100644 --- a/examples/04-hardhat-ccip/contracts/CCIPReceiver.sol +++ b/examples/04-hardhat-ccip/contracts/CCIPReceiver.sol @@ -10,7 +10,7 @@ import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; /// @title CCIPReceiverExample -/// @notice CCIP receiver with 3 modes: token-only, data-only, and data+tokens. +/// @notice CCIP receiver with 3 modes: token-only, data-only (inbox), and data+tokens. /// @dev Implements the defensive pattern recommended by Chainlink: /// - Separates message reception from business logic via try/catch /// - Uses try/catch to prevent message failure from locking tokens @@ -18,7 +18,7 @@ import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol /// /// Message modes: /// - Token-only: holds received tokens in the contract. -/// - Data-only: emits event with the data payload. +/// - Data-only: stores messages in an on-chain inbox, queryable by anyone. /// - Data+tokens: decodes a recipient address from data and forwards tokens. /// /// Security patterns: @@ -32,6 +32,26 @@ import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol contract CCIPReceiverExample is CCIPReceiver, Ownable2Step, Pausable, ReentrancyGuard { using SafeERC20 for IERC20; + // Cross-chain inbox: stores data-only messages for on-chain querying + struct InboxMessage { + bytes32 messageId; + uint64 sourceChainSelector; + address sender; + bytes data; + uint256 timestamp; + } + + InboxMessage[] public inbox; + /// @dev Stores index + 1, so 0 means "not found". Subtract 1 to get the actual inbox index. + mapping(bytes32 messageId => uint256 indexPlusOne) public messageIndex; + + // Batch allowlist entry + struct AllowlistEntry { + uint64 sourceChainSelector; + address sender; + bool allowed; + } + // Allowlisting: sender is allowlisted per source chain to prevent // a contract on chain B from impersonating an allowlisted sender on chain A. mapping(uint64 sourceChainSelector => mapping(address sender => bool allowed)) public allowlistedSenders; @@ -48,8 +68,9 @@ contract CCIPReceiverExample is CCIPReceiver, Ownable2Step, Pausable, Reentrancy // Events event TokensReceived(bytes32 indexed messageId, address[] tokens, uint256[] amounts); - event DataReceived(bytes32 indexed messageId, bytes data); + event DataReceived(bytes32 indexed messageId, uint64 indexed sourceChainSelector, address sender, bytes data); event TokensForwarded(bytes32 indexed messageId, address indexed recipient, address[] tokens, uint256[] amounts); + event AllowlistUpdated(uint64 indexed sourceChainSelector, address indexed sender, bool allowed); event MessageFailed(bytes32 indexed messageId, bytes reason); /// @dev Only this contract can call processMessage (used by the try/catch pattern). @@ -68,6 +89,15 @@ contract CCIPReceiverExample is CCIPReceiver, Ownable2Step, Pausable, Reentrancy allowlistedSenders[sourceChainSelector][sender] = allowed; } + /// @notice Batch update the allowlist — add/remove multiple (chain, sender) pairs in one call. + /// @param entries Array of AllowlistEntry structs with chain selector, sender, and allowed flag. + function updateAllowlist(AllowlistEntry[] calldata entries) external onlyOwner { + for (uint256 i = 0; i < entries.length; i++) { + allowlistedSenders[entries[i].sourceChainSelector][entries[i].sender] = entries[i].allowed; + emit AllowlistUpdated(entries[i].sourceChainSelector, entries[i].sender, entries[i].allowed); + } + } + /// @notice Defensive receive: validates allowlists, then delegates to processMessage /// via try/catch. If processing fails, tokens stay in the contract and the /// message ID is recorded. The owner can recover tokens via withdrawToken. @@ -112,7 +142,41 @@ contract CCIPReceiverExample is CCIPReceiver, Ownable2Step, Pausable, Reentrancy } function _handleDataOnly(Client.Any2EVMMessage memory message) internal { - emit DataReceived(message.messageId, message.data); + address sender = abi.decode(message.sender, (address)); + messageIndex[message.messageId] = inbox.length + 1; // +1 so that 0 means "not found" + inbox.push(InboxMessage({ + messageId: message.messageId, + sourceChainSelector: message.sourceChainSelector, + sender: sender, + data: message.data, + timestamp: block.timestamp + })); + emit DataReceived(message.messageId, message.sourceChainSelector, sender, message.data); + } + + /// @notice Get the total number of messages in the inbox. + function getInboxLength() external view returns (uint256) { + return inbox.length; + } + + /// @notice Get a message from the inbox by index. + /// @param index The inbox index (0-based). + function getInboxMessage(uint256 index) external view returns (InboxMessage memory) { + return inbox[index]; + } + + /// @notice Get the latest N messages from the inbox. + /// @param count Maximum number of messages to return. + function getLatestMessages(uint256 count) external view returns (InboxMessage[] memory) { + uint256 len = inbox.length; + if (count > len) { + count = len; + } + InboxMessage[] memory result = new InboxMessage[](count); + for (uint256 i = 0; i < count; i++) { + result[i] = inbox[len - count + i]; + } + return result; } function _handleDataAndTokens(Client.Any2EVMMessage memory message) internal { diff --git a/examples/04-hardhat-ccip/contracts/CCIPSender.sol b/examples/04-hardhat-ccip/contracts/CCIPSender.sol index 79c3f4a..03fa3ce 100644 --- a/examples/04-hardhat-ccip/contracts/CCIPSender.sol +++ b/examples/04-hardhat-ccip/contracts/CCIPSender.sol @@ -35,6 +35,7 @@ contract CCIPSender is Ownable2Step, Pausable, ReentrancyGuard { /// @dev Only registered (chain, receiver) pairs can be used as destinations. mapping(uint64 destChainSelector => address peer) public peers; + error ArrayLengthMismatch(); error NothingToWithdraw(); error FailedToWithdrawEth(address owner, address target, uint256 value); error InsufficientNativeFee(uint256 required, uint256 provided); @@ -55,6 +56,17 @@ contract CCIPSender is Ownable2Step, Pausable, ReentrancyGuard { emit PeerSet(destChainSelector, peer); } + /// @notice Register or remove multiple trusted peers in one call. + /// @param destChainSelectors The CCIP chain selectors of the destinations. + /// @param peerAddresses The trusted receiver addresses (address(0) to remove). + function setPeers(uint64[] calldata destChainSelectors, address[] calldata peerAddresses) external onlyOwner { + if (destChainSelectors.length != peerAddresses.length) revert ArrayLengthMismatch(); + for (uint256 i = 0; i < destChainSelectors.length; i++) { + peers[destChainSelectors[i]] = peerAddresses[i]; + emit PeerSet(destChainSelectors[i], peerAddresses[i]); + } + } + /// @notice Send a CCIP message with pre-encoded extraArgs. /// @dev Handles both native and ERC20 fee payment. When the fee token is the same /// as a transfer token, combines into a single transferFrom + approval for gas efficiency. diff --git a/examples/04-hardhat-ccip/contracts/test/Setup.sol b/examples/04-hardhat-ccip/contracts/test/Setup.sol new file mode 100644 index 0000000..24ebb33 --- /dev/null +++ b/examples/04-hardhat-ccip/contracts/test/Setup.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {CCIPLocalSimulator} from "@chainlink/local/src/ccip/CCIPLocalSimulator.sol"; + +/// @dev Re-export CCIPLocalSimulator so Hardhat generates an artifact for it. +contract LocalSimulator is CCIPLocalSimulator {} diff --git a/examples/04-hardhat-ccip/hardhat.config.ts b/examples/04-hardhat-ccip/hardhat.config.ts index 1bb7726..959f41a 100644 --- a/examples/04-hardhat-ccip/hardhat.config.ts +++ b/examples/04-hardhat-ccip/hardhat.config.ts @@ -1,5 +1,7 @@ import "dotenv/config"; import { defineConfig, configVariable, task } from "hardhat/config"; +import hardhatViemPlugin from "@nomicfoundation/hardhat-viem"; +import hardhatNodeTestRunnerPlugin from "@nomicfoundation/hardhat-node-test-runner"; import { NETWORKS, getChainIdForNetwork } from "@ccip-examples/shared-config"; // Build Hardhat network entries from shared-config NETWORKS (EVM only) @@ -47,6 +49,43 @@ const tasks = [ .setAction(() => import("./tasks/deploy-receiver.js")) .build(), + task( + "manage-allowlist", + "Manage allowlist on CCIPSender (peers) or CCIPReceiverExample (senders)" + ) + .addOption({ + name: "contract", + description: "Deployed contract address", + defaultValue: "", + }) + .addOption({ + name: "type", + description: "Contract type: sender or receiver", + defaultValue: "", + }) + .addOption({ + name: "chains", + description: "Comma-separated chain network IDs", + defaultValue: "", + }) + .addOption({ + name: "peers", + description: "Comma-separated peer addresses (for sender type)", + defaultValue: "", + }) + .addOption({ + name: "senders", + description: "Comma-separated sender addresses (for receiver type)", + defaultValue: "", + }) + .addOption({ + name: "remove", + description: "Set to 'true' to remove from allowlist", + defaultValue: "", + }) + .setAction(() => import("./tasks/manage-allowlist.js")) + .build(), + task("send-via-sender", "Send CCIP message through deployed sender contract") .addOption({ name: "dest", description: "Destination network ID", defaultValue: "" }) .addOption({ @@ -112,9 +151,132 @@ const tasks = [ .addOption({ name: "messageId", description: "CCIP message ID to check", defaultValue: "" }) .setAction(() => import("./tasks/check-status.js")) .build(), + + task("check-inbox", "Read cross-chain inbox messages from receiver contract") + .addOption({ + name: "receiverContract", + description: "Deployed CCIPReceiverExample address", + defaultValue: "", + }) + .addOption({ + name: "count", + description: "Number of latest messages to show", + defaultValue: "5", + }) + .addOption({ + name: "messageId", + description: "Look up a specific message by ID", + defaultValue: "", + }) + .setAction(() => import("./tasks/check-inbox.js")) + .build(), + + task("manual-execute", "Manually execute a failed CCIP message on destination") + .addOption({ + name: "messageId", + description: "CCIP message ID to execute", + defaultValue: "", + }) + .addOption({ + name: "gasLimit", + description: "Gas limit override for ccipReceive execution", + defaultValue: "0", + }) + .setAction(() => import("./tasks/manual-execute.js")) + .build(), + + task("list-messages", "Search and list CCIP messages with filters") + .addOption({ name: "sender", description: "Filter by sender address", defaultValue: "" }) + .addOption({ name: "receiver", description: "Filter by receiver address", defaultValue: "" }) + .addOption({ + name: "sourceChain", + description: "Filter by source chain (network ID)", + defaultValue: "", + }) + .addOption({ + name: "destChain", + description: "Filter by destination chain (network ID)", + defaultValue: "", + }) + .addOption({ + name: "txHash", + description: "Filter by source transaction hash", + defaultValue: "", + }) + .addOption({ + name: "readyForExec", + description: "Show only messages ready for manual execution (true/false)", + defaultValue: "", + }) + .addOption({ + name: "limit", + description: "Maximum number of messages to show", + defaultValue: "10", + }) + .setAction(() => import("./tasks/list-messages.js")) + .build(), + + task("pause-contract", "Pause or unpause a CCIPSender or CCIPReceiverExample contract") + .addOption({ name: "contract", description: "Deployed contract address", defaultValue: "" }) + .addOption({ name: "type", description: "Contract type: sender or receiver", defaultValue: "" }) + .addOption({ + name: "action", + description: "Action: pause or unpause", + defaultValue: "", + }) + .setAction(() => import("./tasks/pause-contract.js")) + .build(), + + task("withdraw-funds", "Withdraw native currency or ERC20 tokens from a contract") + .addOption({ name: "contract", description: "Deployed contract address", defaultValue: "" }) + .addOption({ name: "type", description: "Contract type: sender or receiver", defaultValue: "" }) + .addOption({ + name: "beneficiary", + description: "Address to receive the withdrawn funds", + defaultValue: "", + }) + .addOption({ + name: "token", + description: "ERC20 token address (omit for native withdrawal)", + defaultValue: "", + }) + .addOption({ + name: "amount", + description: "Amount to withdraw in smallest unit (0 = full balance)", + defaultValue: "0", + }) + .setAction(() => import("./tasks/withdraw-funds.js")) + .build(), + + task("query-config", "Query contract configuration (peers, allowlist, failed messages, status)") + .addOption({ name: "contract", description: "Deployed contract address", defaultValue: "" }) + .addOption({ name: "type", description: "Contract type: sender or receiver", defaultValue: "" }) + .addOption({ + name: "query", + description: "Query type: peer, allowlist, failed, or status", + defaultValue: "", + }) + .addOption({ + name: "chain", + description: "Chain network ID (for peer/allowlist queries)", + defaultValue: "", + }) + .addOption({ + name: "address", + description: "Sender address to check (for allowlist query)", + defaultValue: "", + }) + .addOption({ + name: "messageId", + description: "Message ID to check (for failed query)", + defaultValue: "", + }) + .setAction(() => import("./tasks/query-config.js")) + .build(), ]; export default defineConfig({ + plugins: [hardhatViemPlugin, hardhatNodeTestRunnerPlugin], solidity: { version: "0.8.24" }, networks, tasks, diff --git a/examples/04-hardhat-ccip/package.json b/examples/04-hardhat-ccip/package.json index 998b32f..49b5336 100644 --- a/examples/04-hardhat-ccip/package.json +++ b/examples/04-hardhat-ccip/package.json @@ -1,6 +1,9 @@ { "name": "@ccip-examples/04-hardhat-ccip", "version": "1.0.0", + "engines": { + "node": ">=22.0.0" + }, "description": "Hardhat v3 project with CCIP SDK for deploying and interacting with custom Sender/Receiver contracts", "type": "module", "scripts": { @@ -8,18 +11,22 @@ "typecheck": "tsc --noEmit", "lint": "solhint --max-warnings 0 \"./contracts/**/*.sol\" && eslint hardhat.config.ts tasks helpers --max-warnings 0", "lint:fix": "solhint --fix --max-warnings 0 \"./contracts/**/*.sol\" --noPrompt && eslint hardhat.config.ts tasks helpers --fix", + "test": "hardhat test", "clean": "hardhat clean && rm -rf dist" }, "dependencies": { "@ccip-examples/shared-config": "workspace:*", "@ccip-examples/shared-utils": "workspace:*", - "@chainlink/ccip-sdk": "1.2.0", - "@chainlink/contracts-ccip": "^1.6.4", - "@openzeppelin/contracts": "^5.1.0", + "@chainlink/ccip-sdk": "1.3.1", + "@chainlink/contracts-ccip": "1.6.4", + "@openzeppelin/contracts": "5.1.0", "dotenv": "^16.4.5", "viem": "^2.21.0" }, "devDependencies": { + "@chainlink/local": "0.2.7", + "@nomicfoundation/hardhat-node-test-runner": "^3.0.0", + "@nomicfoundation/hardhat-viem": "^3.0.4", "hardhat": "^3.0.0", "solhint": "^6.0.2", "solhint-plugin-chainlink-solidity": "github:smartcontractkit/chainlink-solhint-rules#v1.2.1", diff --git a/examples/04-hardhat-ccip/tasks/check-inbox.ts b/examples/04-hardhat-ccip/tasks/check-inbox.ts new file mode 100644 index 0000000..4c5887a --- /dev/null +++ b/examples/04-hardhat-ccip/tasks/check-inbox.ts @@ -0,0 +1,190 @@ +/** + * Task: Check the receiver contract's cross-chain inbox + * + * Reads stored data-only messages from the CCIPReceiverExample contract. + * Each message includes source chain, sender, data payload, and timestamp. + * + * Usage: + * # Show last 5 messages (default) + * npx hardhat --network ethereum-testnet-sepolia-base-1 check-inbox \ + * --receiver-contract 0x... + * + * # Show last 10 messages + * npx hardhat --network ethereum-testnet-sepolia-base-1 check-inbox \ + * --receiver-contract 0x... --count 10 + * + * # Look up a specific message by ID + * npx hardhat --network ethereum-testnet-sepolia-base-1 check-inbox \ + * --receiver-contract 0x... --message-id 0x... + */ + +import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; +import { hexToString } from "viem"; +import { getCCIPExplorerUrl } from "@chainlink/ccip-sdk"; +import { createClients } from "../helpers/sdk.js"; + +interface CheckInboxArgs { + receiverContract: string; + count: string; + messageId: string; +} + +// Minimal ABI for inbox read functions +const inboxAbi = [ + { + name: "getInboxLength", + type: "function", + stateMutability: "view", + inputs: [], + outputs: [{ type: "uint256" }], + }, + { + name: "getLatestMessages", + type: "function", + stateMutability: "view", + inputs: [{ name: "count", type: "uint256" }], + outputs: [ + { + type: "tuple[]", + components: [ + { name: "messageId", type: "bytes32" }, + { name: "sourceChainSelector", type: "uint64" }, + { name: "sender", type: "address" }, + { name: "data", type: "bytes" }, + { name: "timestamp", type: "uint256" }, + ], + }, + ], + }, + { + name: "messageIndex", + type: "function", + stateMutability: "view", + inputs: [{ name: "messageId", type: "bytes32" }], + outputs: [{ type: "uint256" }], + }, + { + name: "getInboxMessage", + type: "function", + stateMutability: "view", + inputs: [{ name: "index", type: "uint256" }], + outputs: [ + { + type: "tuple", + components: [ + { name: "messageId", type: "bytes32" }, + { name: "sourceChainSelector", type: "uint64" }, + { name: "sender", type: "address" }, + { name: "data", type: "bytes" }, + { name: "timestamp", type: "uint256" }, + ], + }, + ], + }, +] as const; + +interface InboxMessage { + messageId: `0x${string}`; + sourceChainSelector: bigint; + sender: `0x${string}`; + data: `0x${string}`; + timestamp: bigint; +} + +const checkInbox = async (args: CheckInboxArgs, hre: HardhatRuntimeEnvironment): Promise => { + const connection = await hre.network.connect(); + const networkId = connection.networkName; + const { publicClient } = createClients(networkId); + const contractAddress = args.receiverContract as `0x${string}`; + + // Get inbox length + const inboxLength = await publicClient.readContract({ + address: contractAddress, + abi: inboxAbi, + functionName: "getInboxLength", + }); + + console.log(`\nCCIP Receiver Inbox on ${networkId}`); + console.log(` Contract: ${contractAddress}`); + console.log(` Total messages: ${inboxLength}`); + + if (inboxLength === 0n) { + console.log(`\n Inbox is empty. No data-only messages received yet.`); + return; + } + + // Look up a specific message by ID + if (args.messageId !== "") { + // messageIndex stores index + 1, so 0 means "not found" + const indexPlusOne = await publicClient.readContract({ + address: contractAddress, + abi: inboxAbi, + functionName: "messageIndex", + args: [args.messageId as `0x${string}`], + }); + + if (indexPlusOne === 0n) { + console.log(`\n Message ID not found in inbox.`); + return; + } + + const index = indexPlusOne - 1n; + const msg = (await publicClient.readContract({ + address: contractAddress, + abi: inboxAbi, + functionName: "getInboxMessage", + args: [index], + })) as InboxMessage; + + console.log(`\n Message found at index ${index}:`); + printMessage(msg); + return; + } + + // Show latest N messages + const parsedCount = parseInt(args.count, 10); + if (isNaN(parsedCount) || parsedCount <= 0) { + throw new Error(`Invalid --count: "${args.count}". Must be a positive number.`); + } + const count = BigInt(parsedCount); + const messages = (await publicClient.readContract({ + address: contractAddress, + abi: inboxAbi, + functionName: "getLatestMessages", + args: [count], + })) as readonly InboxMessage[]; + + console.log(`\n Showing latest ${messages.length} message(s):\n`); + + for (let i = 0; i < messages.length; i++) { + const msg = messages[i]; + if (!msg) continue; + console.log(` --- Message ${i + 1} ---`); + printMessage(msg); + console.log(); + } +}; + +function printMessage(msg: InboxMessage): void { + const date = new Date(Number(msg.timestamp) * 1000); + + console.log(` Message ID: ${msg.messageId}`); + console.log(` Source chain: ${msg.sourceChainSelector}`); + console.log(` Sender: ${msg.sender}`); + console.log(` Data: ${msg.data}`); + + // Try to decode as UTF-8 string (data-only messages use encodePacked string) + try { + const text = hexToString(msg.data); + if (text.length > 0 && /^[\x20-\x7E]+$/.test(text)) { + console.log(` Data (text): "${text}"`); + } + } catch { + // Not decodable as text — that's fine, it might be ABI-encoded (e.g., PTT address) + } + + console.log(` Received: ${date.toISOString()}`); + console.log(` CCIP Explorer: ${getCCIPExplorerUrl("msg", msg.messageId)}`); +} + +export default checkInbox; diff --git a/examples/04-hardhat-ccip/tasks/list-messages.ts b/examples/04-hardhat-ccip/tasks/list-messages.ts new file mode 100644 index 0000000..05e4cce --- /dev/null +++ b/examples/04-hardhat-ccip/tasks/list-messages.ts @@ -0,0 +1,164 @@ +/** + * Task: List CCIP messages using the SDK's searchAllMessages() async generator + * + * Streams messages across all pages automatically — no manual cursor handling. + * Collects up to --limit results and displays them. + * + * Usage: + * # List recent messages (default: 10) + * npx hardhat list-messages + * + * # Filter by sender + * npx hardhat list-messages --sender 0x... + * + * # Filter by source and destination chain + * npx hardhat list-messages \ + * --source-chain ethereum-testnet-sepolia \ + * --dest-chain ethereum-testnet-sepolia-base-1 + * + * # Filter by source tx hash + * npx hardhat list-messages --tx-hash 0x... + * + * # Show only messages ready for manual execution + * npx hardhat list-messages --ready-for-exec true + * + * # Fetch more results + * npx hardhat list-messages --limit 25 + */ + +import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; +import { + type MessageSearchFilters, + CCIPAPIClient, + getCCIPExplorerUrl, + networkInfo, +} from "@chainlink/ccip-sdk"; +import { formatRelativeTime } from "@ccip-examples/shared-utils"; + +interface ListMessagesArgs { + sender: string; + receiver: string; + sourceChain: string; + destChain: string; + txHash: string; + readyForExec: string; + limit: string; +} + +const listMessages = async ( + args: ListMessagesArgs, + _hre: HardhatRuntimeEnvironment +): Promise => { + const limit = parseInt(args.limit, 10); + if (isNaN(limit) || limit <= 0) { + throw new Error(`Invalid --limit: "${args.limit}". Must be a positive number.`); + } + + // Build filters from flags + const filters: MessageSearchFilters = {}; + if (args.sender !== "") filters.sender = args.sender; + if (args.receiver !== "") filters.receiver = args.receiver; + if (args.sourceChain !== "") { + try { + filters.sourceChainSelector = networkInfo(args.sourceChain).chainSelector; + } catch { + throw new Error(`Unknown source chain: "${args.sourceChain}". Use a valid CCIP network ID.`); + } + } + if (args.destChain !== "") { + try { + filters.destChainSelector = networkInfo(args.destChain).chainSelector; + } catch { + throw new Error( + `Unknown destination chain: "${args.destChain}". Use a valid CCIP network ID.` + ); + } + } + if (args.txHash !== "") filters.sourceTransactionHash = args.txHash; + if (args.readyForExec !== "" && args.readyForExec !== "true" && args.readyForExec !== "false") { + throw new Error(`Invalid --ready-for-exec: "${args.readyForExec}". Must be "true" or "false".`); + } + if (args.readyForExec === "true") filters.readyForManualExecOnly = true; + + // Display active filters + const activeFilters = Object.entries(filters); + console.log(`\nCCIP Message Search`); + if (activeFilters.length > 0) { + console.log(` Filters:`); + for (const [key, value] of activeFilters) { + console.log(` ${key}: ${value}`); + } + } else { + console.log(` Filters: none (showing recent messages)`); + } + console.log(` Limit: ${limit}`); + + const apiClient = new CCIPAPIClient(); + + // Stream messages using the async generator — handles pagination automatically + interface SearchResult { + messageId: string; + status: string; + origin: string; + sender: string; + receiver: string; + sourceNetworkInfo: { name: string }; + destNetworkInfo: { name: string }; + sendTransactionHash: string; + sendTimestamp: string; + } + const results: SearchResult[] = []; + + console.log(`\n Fetching messages...\n`); + + for await (const msg of apiClient.searchAllMessages(filters)) { + results.push(msg); + if (results.length >= limit) break; + } + + if (results.length === 0) { + console.log(` No messages found matching the filters.`); + return; + } + + console.log(` Showing ${results.length} message(s):\n`); + + for (let i = 0; i < results.length; i++) { + const msg = results[i]; + if (!msg) continue; + const statusIcon = getStatusIcon(msg.status); + + console.log(` ${i + 1}. ${statusIcon} ${msg.messageId}`); + console.log(` Status: ${msg.status}`); + console.log(` Route: ${msg.sourceNetworkInfo.name} → ${msg.destNetworkInfo.name}`); + if (msg.sender) console.log(` Sender: ${msg.sender}`); + if (msg.receiver) console.log(` Receiver: ${msg.receiver}`); + if (msg.sendTimestamp) { + console.log(` Sent: ${formatRelativeTime(new Date(msg.sendTimestamp).getTime())}`); + } + console.log(` Explorer: ${getCCIPExplorerUrl("msg", msg.messageId)}`); + console.log(); + } + + console.log(` --- End of results ---`); +}; + +function getStatusIcon(status: string): string { + switch (status) { + case "SUCCESS": + return "[OK]"; + case "FAILED": + return "[FAIL]"; + case "SENT": + case "SOURCE_FINALIZED": + case "COMMITTED": + case "BLESSED": + case "VERIFYING": + case "VERIFIED": + return "[..]"; + default: + return "[??]"; + } +} + +export default listMessages; diff --git a/examples/04-hardhat-ccip/tasks/manage-allowlist.ts b/examples/04-hardhat-ccip/tasks/manage-allowlist.ts new file mode 100644 index 0000000..0747f00 --- /dev/null +++ b/examples/04-hardhat-ccip/tasks/manage-allowlist.ts @@ -0,0 +1,208 @@ +/** + * Task: Manage allowlist on CCIPSender (peers) or CCIPReceiverExample (senders) + * + * Supports both single and batch operations: + * + * # Sender: register a single peer + * npx hardhat --network ethereum-testnet-sepolia manage-allowlist \ + * --contract 0x... --type sender --chains ethereum-testnet-sepolia-base-1 --peers 0x... + * + * # Sender: batch register peers (comma-separated) + * npx hardhat --network ethereum-testnet-sepolia manage-allowlist \ + * --contract 0x... --type sender \ + * --chains ethereum-testnet-sepolia-base-1,ethereum-testnet-sepolia-arbitrum-1 \ + * --peers 0xReceiverBase,0xReceiverArb + * + * # Receiver: allowlist a single sender + * npx hardhat --network ethereum-testnet-sepolia-base-1 manage-allowlist \ + * --contract 0x... --type receiver --chains ethereum-testnet-sepolia --senders 0x... + * + * # Receiver: batch allowlist (comma-separated) + * npx hardhat --network ethereum-testnet-sepolia-base-1 manage-allowlist \ + * --contract 0x... --type receiver \ + * --chains ethereum-testnet-sepolia,ethereum-testnet-sepolia-arbitrum-1 \ + * --senders 0xSenderSepolia,0xSenderArb + * + * # Remove with --remove flag + * npx hardhat --network ethereum-testnet-sepolia manage-allowlist \ + * --contract 0x... --type sender --chains ethereum-testnet-sepolia-base-1 --peers 0x... --remove true + */ + +import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; +import { networkInfo } from "@chainlink/ccip-sdk"; +import { getExplorerTxUrl } from "@ccip-examples/shared-config"; +import { createClients } from "../helpers/sdk.js"; + +interface ManageAllowlistArgs { + contract: string; + type: string; + chains: string; + peers: string; + senders: string; + remove: string; +} + +const manageAllowlist = async ( + args: ManageAllowlistArgs, + hre: HardhatRuntimeEnvironment +): Promise => { + const connection = await hre.network.connect(); + const networkId = connection.networkName; + + if (!args.contract) throw new Error("--contract is required"); + if (!args.type || (args.type !== "sender" && args.type !== "receiver")) { + throw new Error("--type must be 'sender' or 'receiver'"); + } + if (!args.chains) throw new Error("--chains is required"); + + const chainIds = args.chains + .split(",") + .map((c) => c.trim()) + .filter((c) => c !== ""); + if (chainIds.length === 0) throw new Error("--chains must contain at least one chain ID"); + const isRemove = args.remove === "true"; + + // Validate all chain IDs upfront + for (const id of chainIds) { + try { + networkInfo(id); + } catch { + throw new Error(`Unknown chain: "${id}". Use a valid CCIP network ID.`); + } + } + + const { publicClient, walletClient } = createClients(networkId); + + if (args.type === "sender") { + await handleSender(args, chainIds, isRemove, hre, publicClient, walletClient, networkId); + } else { + await handleReceiver(args, chainIds, isRemove, hre, publicClient, walletClient, networkId); + } +}; + +async function handleSender( + args: ManageAllowlistArgs, + chainIds: string[], + isRemove: boolean, + hre: HardhatRuntimeEnvironment, + publicClient: ReturnType["publicClient"], + walletClient: ReturnType["walletClient"], + networkId: string +): Promise { + const peerAddresses = args.peers ? args.peers.split(",").map((p) => p.trim()) : []; + if (peerAddresses.length === 0) throw new Error("--peers is required for sender type"); + if (chainIds.length !== peerAddresses.length) { + throw new Error( + `--chains count (${chainIds.length}) must match --peers count (${peerAddresses.length})` + ); + } + + const artifact = await hre.artifacts.readArtifact("CCIPSender"); + const selectors = chainIds.map((id) => networkInfo(id).chainSelector); + const peers = isRemove + ? peerAddresses.map(() => "0x0000000000000000000000000000000000000000" as `0x${string}`) + : peerAddresses.map((p) => p as `0x${string}`); + + const action = isRemove ? "Removing" : "Registering"; + console.log(`\n${action} ${chainIds.length} peer(s) on CCIPSender...`); + console.log(` Network: ${networkId}`); + console.log(` Contract: ${args.contract}`); + + for (let i = 0; i < chainIds.length; i++) { + console.log(` [${i + 1}] ${chainIds[i]} (selector: ${selectors[i]}) → ${peers[i]}`); + } + + let hash: `0x${string}`; + + if (chainIds.length === 1) { + hash = await walletClient.writeContract({ + address: args.contract as `0x${string}`, + abi: artifact.abi, + functionName: "setPeer", + args: [selectors[0], peers[0]], + }); + } else { + hash = await walletClient.writeContract({ + address: args.contract as `0x${string}`, + abi: artifact.abi, + functionName: "setPeers", + args: [selectors, peers], + }); + } + + console.log(` Tx hash: ${hash}`); + console.log(` Explorer: ${getExplorerTxUrl(networkId, hash)}`); + + await publicClient.waitForTransactionReceipt({ hash }); + console.log( + `\n ${chainIds.length} peer(s) ${isRemove ? "removed" : "registered"} successfully.` + ); +} + +async function handleReceiver( + args: ManageAllowlistArgs, + chainIds: string[], + isRemove: boolean, + hre: HardhatRuntimeEnvironment, + publicClient: ReturnType["publicClient"], + walletClient: ReturnType["walletClient"], + networkId: string +): Promise { + const senderAddresses = args.senders ? args.senders.split(",").map((s) => s.trim()) : []; + if (senderAddresses.length === 0) throw new Error("--senders is required for receiver type"); + if (chainIds.length !== senderAddresses.length) { + throw new Error( + `--chains count (${chainIds.length}) must match --senders count (${senderAddresses.length})` + ); + } + + const artifact = await hre.artifacts.readArtifact("CCIPReceiverExample"); + const allowed = !isRemove; + const action = isRemove ? "Removing" : "Allowlisting"; + + console.log(`\n${action} ${chainIds.length} sender(s) on CCIPReceiverExample...`); + console.log(` Network: ${networkId}`); + console.log(` Contract: ${args.contract}`); + + const selectors = chainIds.map((id) => networkInfo(id).chainSelector); + + for (let i = 0; i < chainIds.length; i++) { + console.log( + ` [${i + 1}] ${chainIds[i]} (selector: ${selectors[i]}) → ${senderAddresses[i]} (allowed: ${allowed})` + ); + } + + let hash: `0x${string}`; + + if (chainIds.length === 1) { + hash = await walletClient.writeContract({ + address: args.contract as `0x${string}`, + abi: artifact.abi, + functionName: "allowlistSender", + args: [selectors[0], senderAddresses[0] as `0x${string}`, allowed], + }); + } else { + const entries = chainIds.map((_, i) => ({ + sourceChainSelector: selectors[i], + sender: senderAddresses[i] as `0x${string}`, + allowed, + })); + + hash = await walletClient.writeContract({ + address: args.contract as `0x${string}`, + abi: artifact.abi, + functionName: "updateAllowlist", + args: [entries], + }); + } + + console.log(` Tx hash: ${hash}`); + console.log(` Explorer: ${getExplorerTxUrl(networkId, hash)}`); + + await publicClient.waitForTransactionReceipt({ hash }); + console.log( + `\n ${chainIds.length} sender(s) ${isRemove ? "removed" : "allowlisted"} successfully.` + ); +} + +export default manageAllowlist; diff --git a/examples/04-hardhat-ccip/tasks/manual-execute.ts b/examples/04-hardhat-ccip/tasks/manual-execute.ts new file mode 100644 index 0000000..0c9fd4a --- /dev/null +++ b/examples/04-hardhat-ccip/tasks/manual-execute.ts @@ -0,0 +1,158 @@ +/** + * Task: Manually execute a failed/stuck CCIP message on the destination chain + * + * Uses the SDK's simplified API-based execution path: the SDK fetches + * the execution input (merkle proofs, offchain token data) from the CCIP API + * and submits the manual execution transaction on the destination chain. + * + * Typical workflow: + * 1. Send a data-only message with a deliberately low --gas-limit (e.g. 1000) + * 2. The message fails on destination due to out-of-gas + * 3. Wait for the message to become eligible for manual execution + * 4. Run this task to retry with a higher gas limit + * + * Usage: + * npx hardhat --network ethereum-testnet-sepolia-base-1 manual-execute \ + * --message-id 0x... + * + * # With a custom gas limit override + * npx hardhat --network ethereum-testnet-sepolia-base-1 manual-execute \ + * --message-id 0x... --gas-limit 300000 + */ + +import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; +import { + CCIPAPIClient, + getCCIPExplorerUrl, + CCIPError, + CCIPMessageIdNotFoundError, + withRetry, +} from "@chainlink/ccip-sdk"; +import { fromViemClient, viemWallet } from "@chainlink/ccip-sdk/viem"; +import { getExplorerTxUrl } from "@ccip-examples/shared-config"; +import { createClients } from "../helpers/sdk.js"; + +interface ManualExecuteArgs { + messageId: string; + gasLimit: string; +} + +const manualExecute = async ( + args: ManualExecuteArgs, + hre: HardhatRuntimeEnvironment +): Promise => { + const connection = await hre.network.connect(); + const destNetworkId = connection.networkName; + const { messageId } = args; + + console.log(`\nManual execution of failed CCIP message`); + console.log(` Destination network: ${destNetworkId}`); + console.log(` Message ID: ${messageId}`); + console.log(` CCIP Explorer: ${getCCIPExplorerUrl("msg", messageId)}`); + + // Step 1: Check message status via API + console.log(`\n Checking message status...`); + const apiClient = new CCIPAPIClient(); + + const request = await withRetry(() => apiClient.getMessageById(messageId), { + maxRetries: 5, + initialDelayMs: 2000, + backoffMultiplier: 1.5, + maxDelayMs: 15000, + respectRetryAfterHint: true, + logger: { + debug: (...debugArgs: unknown[]) => console.log(" [retry]", ...debugArgs), + warn: (...warnArgs: unknown[]) => console.warn(" [retry]", ...warnArgs), + }, + }); + + const { metadata } = request; + console.log(` Status: ${metadata.status}`); + console.log(` Source: ${metadata.sourceNetworkInfo.name}`); + console.log(` Destination: ${metadata.destNetworkInfo.name}`); + + if (metadata.status === "SUCCESS") { + console.log(`\n Message already executed successfully. Nothing to do.`); + return; + } + + if (!metadata.readyForManualExecution) { + console.log(`\n Message is not yet ready for manual execution.`); + console.log(` Current status: ${metadata.status}`); + console.log(` The message must be committed and blessed before it can be manually executed.`); + console.log(` Try again later or check the CCIP Explorer.`); + return; + } + + // Step 2: Estimate or resolve gas limit + console.log(`\n Message is ready for manual execution.`); + + const { walletClient, publicClient } = createClients(destNetworkId); + const destChain = await fromViemClient(publicClient); + + let gasLimit: number | undefined; + if (args.gasLimit !== "0") { + gasLimit = Number(args.gasLimit); + if (isNaN(gasLimit) || gasLimit <= 0) { + throw new Error(`Invalid --gas-limit: "${args.gasLimit}". Must be a positive number.`); + } + console.log(` Gas limit (manual override): ${gasLimit}`); + } else { + // Auto-estimate gas for ccipReceive on the destination chain. + // The SDK fetches the message details from the API and simulates + // ccipReceive() to determine the exact gas needed. + console.log(` Auto-estimating gas for ccipReceive...`); + try { + const estimated = await destChain.estimateReceiveExecution({ messageId }); + gasLimit = Math.ceil(estimated * 1.1); + console.log(` Estimated gas: ${estimated}`); + console.log(` Gas limit (with 10% margin): ${gasLimit}`); + } catch (err) { + console.log( + ` Could not auto-estimate gas: ${err instanceof Error ? err.message : String(err)}` + ); + console.log(` Proceeding without gas limit override (SDK will use its default).`); + } + } + + console.log(` Submitting execution transaction on ${destNetworkId}...`); + + try { + const execution = await destChain.execute({ + messageId, + wallet: viemWallet(walletClient), + ...(gasLimit && { gasLimit }), + }); + + const txHash = execution.log.tx?.hash; + console.log(`\n Execution submitted!`); + if (txHash) { + console.log(` Tx hash: ${txHash}`); + console.log(` Explorer: ${getExplorerTxUrl(destNetworkId, txHash)}`); + } + + const state = execution.receipt.state; + if (state === 2) { + console.log(`\n Message executed successfully!`); + } else if (state === 3) { + console.log(`\n Execution reverted on destination.`); + console.log(` The receiver's ccipReceive may need a higher gas limit.`); + console.log(` Try again with: --gas-limit `); + } else { + console.log(`\n Execution state: ${state}`); + } + } catch (error) { + if (error instanceof CCIPMessageIdNotFoundError) { + console.error(`\n Message not found. It may not be indexed yet. Try again later.`); + } else if (CCIPError.isCCIPError(error)) { + console.error(`\n Execution failed: ${error.message}`); + if (error.recovery) { + console.error(` Recovery: ${error.recovery}`); + } + } else { + console.error(`\n Error: ${error instanceof Error ? error.message : String(error)}`); + } + } +}; + +export default manualExecute; diff --git a/examples/04-hardhat-ccip/tasks/pause-contract.ts b/examples/04-hardhat-ccip/tasks/pause-contract.ts new file mode 100644 index 0000000..ec6c63b --- /dev/null +++ b/examples/04-hardhat-ccip/tasks/pause-contract.ts @@ -0,0 +1,81 @@ +/** + * Task: Pause or unpause a CCIPSender or CCIPReceiverExample contract + * + * When paused: + * - CCIPSender: send() reverts (no new messages can be sent) + * - CCIPReceiverExample: _ccipReceive reverts — CCIP marks the message + * as failed and it can be manually re-executed later once unpaused + * + * Usage: + * # Pause sender contract + * npx hardhat --network avalanche-testnet-fuji pause-contract \ + * --contract 0x... --type sender --action pause + * + * # Unpause receiver contract + * npx hardhat --network ethereum-testnet-sepolia pause-contract \ + * --contract 0x... --type receiver --action unpause + */ + +import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; +import { getExplorerTxUrl } from "@ccip-examples/shared-config"; +import { createClients } from "../helpers/sdk.js"; + +interface PauseContractArgs { + contract: string; + type: string; + action: string; +} + +const pauseContract = async ( + args: PauseContractArgs, + hre: HardhatRuntimeEnvironment +): Promise => { + const connection = await hre.network.connect(); + const networkId = connection.networkName; + + if (!args.contract) throw new Error("--contract is required"); + if (args.type !== "sender" && args.type !== "receiver") { + throw new Error(`Invalid --type: "${args.type}". Must be "sender" or "receiver".`); + } + if (args.action !== "pause" && args.action !== "unpause") { + throw new Error(`Invalid --action: "${args.action}". Must be "pause" or "unpause".`); + } + + const artifactName = args.type === "sender" ? "CCIPSender" : "CCIPReceiverExample"; + const artifact = await hre.artifacts.readArtifact(artifactName); + const { publicClient, walletClient } = createClients(networkId); + + // Check current pause state + const isPaused = await publicClient.readContract({ + address: args.contract as `0x${string}`, + abi: artifact.abi, + functionName: "paused", + }); + + if (args.action === "pause" && isPaused) { + console.log(`\n Contract is already paused. Nothing to do.`); + return; + } + if (args.action === "unpause" && !isPaused) { + console.log(`\n Contract is already unpaused. Nothing to do.`); + return; + } + + console.log(`\n${args.action === "pause" ? "Pausing" : "Unpausing"} ${artifactName}...`); + console.log(` Network: ${networkId}`); + console.log(` Contract: ${args.contract}`); + + const hash = await walletClient.writeContract({ + address: args.contract as `0x${string}`, + abi: artifact.abi, + functionName: args.action, + }); + + console.log(` Tx hash: ${hash}`); + console.log(` Explorer: ${getExplorerTxUrl(networkId, hash)}`); + + await publicClient.waitForTransactionReceipt({ hash }); + console.log(`\n Contract ${args.action === "pause" ? "paused" : "unpaused"} successfully.`); +}; + +export default pauseContract; diff --git a/examples/04-hardhat-ccip/tasks/query-config.ts b/examples/04-hardhat-ccip/tasks/query-config.ts new file mode 100644 index 0000000..e3cf4e9 --- /dev/null +++ b/examples/04-hardhat-ccip/tasks/query-config.ts @@ -0,0 +1,152 @@ +/** + * Task: Query contract configuration (peers, allowlist, failed messages) + * + * Usage: + * # Check if a peer is registered on sender + * npx hardhat --network avalanche-testnet-fuji query-config \ + * --contract 0x... --type sender --query peer \ + * --chain ethereum-testnet-sepolia + * + * # Check if a sender is allowlisted on receiver + * npx hardhat --network ethereum-testnet-sepolia query-config \ + * --contract 0x... --type receiver --query allowlist \ + * --chain avalanche-testnet-fuji --address 0x... + * + * # Check if a message failed on receiver + * npx hardhat --network ethereum-testnet-sepolia query-config \ + * --contract 0x... --type receiver --query failed \ + * --message-id 0x... + * + * # Check contract pause status + * npx hardhat --network ethereum-testnet-sepolia query-config \ + * --contract 0x... --type receiver --query status + */ + +import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; +import { networkInfo } from "@chainlink/ccip-sdk"; +import { createClients } from "../helpers/sdk.js"; + +interface QueryConfigArgs { + contract: string; + type: string; + query: string; + chain: string; + address: string; + messageId: string; +} + +const queryConfig = async ( + args: QueryConfigArgs, + hre: HardhatRuntimeEnvironment +): Promise => { + const connection = await hre.network.connect(); + const networkId = connection.networkName; + + if (!args.contract) throw new Error("--contract is required"); + if (args.type !== "sender" && args.type !== "receiver") { + throw new Error(`Invalid --type: "${args.type}". Must be "sender" or "receiver".`); + } + + const validQueries = ["peer", "allowlist", "failed", "status"]; + if (!validQueries.includes(args.query)) { + throw new Error(`Invalid --query: "${args.query}". Must be one of: ${validQueries.join(", ")}`); + } + + const artifactName = args.type === "sender" ? "CCIPSender" : "CCIPReceiverExample"; + const artifact = await hre.artifacts.readArtifact(artifactName); + const { publicClient } = createClients(networkId); + const contractAddress = args.contract as `0x${string}`; + + console.log(`\nQuerying ${artifactName} on ${networkId}`); + console.log(` Contract: ${contractAddress}`); + + if (args.query === "status") { + const isPaused = (await publicClient.readContract({ + address: contractAddress, + abi: artifact.abi, + functionName: "paused", + })) as boolean; + const owner = (await publicClient.readContract({ + address: contractAddress, + abi: artifact.abi, + functionName: "owner", + })) as string; + console.log(` Owner: ${owner}`); + console.log(` Paused: ${String(isPaused)}`); + return; + } + + if (args.query === "peer") { + if (args.type !== "sender") { + throw new Error("--query peer is only valid for --type sender"); + } + if (!args.chain) throw new Error("--chain is required for peer query"); + + let chainSelector: bigint; + try { + chainSelector = networkInfo(args.chain).chainSelector; + } catch { + throw new Error(`Unknown chain: "${args.chain}". Use a valid CCIP network ID.`); + } + + const peerAddress = (await publicClient.readContract({ + address: contractAddress, + abi: artifact.abi, + functionName: "peers", + args: [chainSelector], + })) as string; + + const isRegistered = peerAddress !== "0x0000000000000000000000000000000000000000"; + console.log(` Chain: ${args.chain} (selector: ${chainSelector})`); + console.log(` Peer: ${peerAddress}`); + console.log(` Registered: ${String(isRegistered)}`); + return; + } + + if (args.query === "allowlist") { + if (args.type !== "receiver") { + throw new Error("--query allowlist is only valid for --type receiver"); + } + if (!args.chain) throw new Error("--chain is required for allowlist query"); + if (!args.address) throw new Error("--address is required for allowlist query"); + + let chainSelector: bigint; + try { + chainSelector = networkInfo(args.chain).chainSelector; + } catch { + throw new Error(`Unknown chain: "${args.chain}". Use a valid CCIP network ID.`); + } + + const isAllowed = (await publicClient.readContract({ + address: contractAddress, + abi: artifact.abi, + functionName: "allowlistedSenders", + args: [chainSelector, args.address as `0x${string}`], + })) as boolean; + + console.log(` Chain: ${args.chain} (selector: ${chainSelector})`); + console.log(` Sender: ${args.address}`); + console.log(` Allowed: ${String(isAllowed)}`); + return; + } + + if (args.query === "failed") { + if (args.type !== "receiver") { + throw new Error("--query failed is only valid for --type receiver"); + } + if (!args.messageId) throw new Error("--message-id is required for failed query"); + + const isFailed = (await publicClient.readContract({ + address: contractAddress, + abi: artifact.abi, + functionName: "failedMessages", + args: [args.messageId as `0x${string}`], + })) as boolean; + + console.log(` Message ID: ${args.messageId}`); + console.log(` Failed: ${String(isFailed)}`); + return; + } +}; + +export default queryConfig; diff --git a/examples/04-hardhat-ccip/tasks/send-via-router.ts b/examples/04-hardhat-ccip/tasks/send-via-router.ts index bb1c434..915a7ff 100644 --- a/examples/04-hardhat-ccip/tasks/send-via-router.ts +++ b/examples/04-hardhat-ccip/tasks/send-via-router.ts @@ -1,11 +1,15 @@ /** * Task: Send CCIP message directly through the router using the SDK * - * Demonstrates the SDK building the complete message and interacting with - * the router directly (no custom sender contract needed). + * Demonstrates the SDK-managed approach — the SDK builds the complete message, + * handles token approvals, and interacts with the router directly. + * No custom sender contract needed. * - * Gas limit is auto-estimated via the SDK's estimateReceiveExecution() when - * not explicitly provided (for data and ptt modes). + * Key SDK features demonstrated: + * - estimateReceiveExecution() — auto-estimates destination gas for ccipReceive + * - getFee() — estimates CCIP fee in native or LINK with human-readable display + * - sendMessage() — handles approvals + ccipSend in one call + * - MessageInput type — strongly typed message construction * * Usage: * # Token transfer — gasLimit auto 0 @@ -18,10 +22,10 @@ * --dest ethereum-testnet-sepolia-base-1 \ * --receiver 0x... --mode data * - * # Programmable token transfer — gasLimit auto-estimated + * # Programmable token transfer — gasLimit auto-estimated, pay with LINK * npx hardhat --network ethereum-testnet-sepolia send-via-router \ * --dest ethereum-testnet-sepolia-base-1 \ - * --receiver 0x... --mode ptt --amount 0.001 --token CCIP-BnM + * --receiver 0x... --mode ptt --amount 0.001 --token CCIP-BnM --fee-token link */ import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; @@ -34,11 +38,16 @@ import { import { fromViemClient, viemWallet } from "@chainlink/ccip-sdk/viem"; import { type FeeTokenOption, + NETWORKS, getExplorerTxUrl, getTokenAddress, resolveFeeTokenAddress, } from "@ccip-examples/shared-config"; -import { buildTokenTransferMessage } from "@ccip-examples/shared-utils"; +import { + buildTokenTransferMessage, + formatAmount, + formatLatency, +} from "@ccip-examples/shared-utils"; import { createClients, getRouterAddress, getDestChainSelector } from "../helpers/sdk.js"; interface SendViaRouterArgs { @@ -59,37 +68,89 @@ const sendViaRouter = async ( const connection = await hre.network.connect(); const sourceNetworkId = connection.networkName; const { mode, dest, receiver } = args; + const sourceConfig = NETWORKS[sourceNetworkId]; + if (!sourceConfig) throw new Error(`Unknown source network: ${sourceNetworkId}`); + + // Validate mode early + const validModes = ["tt", "data", "ptt"]; + if (!validModes.includes(mode)) { + throw new Error(`Invalid mode: "${mode}". Must be one of: ${validModes.join(", ")}`); + } + + // Validate gasLimit if provided + if (args.gasLimit !== "0") { + const parsed = Number(args.gasLimit); + if (isNaN(parsed) || parsed < 0) { + throw new Error(`Invalid --gas-limit: "${args.gasLimit}". Must be a non-negative number.`); + } + } - console.log(`\nSending CCIP message directly via router (SDK)...`); - console.log(` Source: ${sourceNetworkId}`); + console.log("\n" + "=".repeat(60)); + console.log("CCIP Message via Router (SDK-managed)"); + console.log("=".repeat(60)); + console.log(` Source: ${sourceConfig.name} (${sourceNetworkId})`); console.log(` Destination: ${dest}`); - console.log(` Mode: ${mode}`); - console.log(` Receiver: ${receiver}`); + console.log(` Mode: ${mode}`); + console.log(` Receiver: ${receiver}`); + console.log(` Fee token: ${args.feeToken}`); + // ────────────────────────────────────────────── + // Step 1: Initialize SDK clients + // ────────────────────────────────────────────── + console.log("\nStep 1: Initializing SDK clients..."); const routerAddress = getRouterAddress(sourceNetworkId); const destChainSelector = getDestChainSelector(dest); - // Create viem clients and SDK chains for source and destination const { account, publicClient, walletClient } = createClients(sourceNetworkId); const { publicClient: destPublicClient } = createClients(dest); const sourceChain = await fromViemClient(publicClient); const destChain = await fromViemClient(destPublicClient); + console.log(` Wallet: ${account.address}`); - // Resolve fee token + // Estimate lane latency (informational) + try { + const latency = await sourceChain.getLaneLatency(destChainSelector); + console.log(` Estimated delivery: ${formatLatency(latency.totalMs)}`); + } catch { + // Lane latency is informational — don't block the send + } + + // Resolve fee token: "native" → undefined, "link" → LINK address const feeTokenOption = args.feeToken as FeeTokenOption; const feeToken = resolveFeeTokenAddress(feeTokenOption, sourceNetworkId); - // Determine gasLimit: use provided value or auto-estimate via SDK + // Resolve fee token metadata for human-readable display + let feeDecimals: number; + let feeSymbol: string; + + if (feeToken) { + const feeTokenInfo = await sourceChain.getTokenInfo(feeToken); + feeDecimals = feeTokenInfo.decimals; + feeSymbol = feeTokenInfo.symbol; + } else { + feeDecimals = sourceConfig.nativeCurrency.decimals; + feeSymbol = sourceConfig.nativeCurrency.symbol; + } + console.log(` Fee token: ${feeSymbol}${feeToken ? ` (${feeToken})` : " (native)"}`); + + // ────────────────────────────────────────────── + // Step 2: Estimate destination gas limit + // ────────────────────────────────────────────── + console.log("\nStep 2: Estimating destination gas for ccipReceive..."); + let gasLimit: bigint; if (args.gasLimit !== "0") { gasLimit = BigInt(args.gasLimit); - console.log(` Gas limit (manual): ${gasLimit}`); + console.log(` Gas limit (manual override): ${gasLimit}`); } else if (mode === "tt") { - // Token-only transfers don't execute receiver logic + // Token-only transfers don't execute receiver logic — the router + // delivers tokens directly without calling ccipReceive() gasLimit = 0n; - console.log(` Gas limit: 0 (token-only, no receiver execution)`); + console.log(` Gas limit: 0 (token-only transfer — no receiver execution needed)`); } else { - // Build a preliminary data payload for estimation + // Build a preliminary payload for gas estimation. + // estimateReceiveExecution() simulates ccipReceive() on the destination + // chain to determine the exact gas needed. let estimationData = "0x"; const estimationTokenAmounts: { token: string; amount: bigint }[] = []; @@ -103,11 +164,10 @@ const sendViaRouter = async ( estimationData = args.data !== "" ? args.data - : encodeAbiParameters([{ type: "address" }], [receiver as `0x${string}`]); + : encodeAbiParameters([{ type: "address" }], [account.address]); estimationTokenAmounts.push({ token: tokenAddress, amount }); } - console.log(`\n Estimating destination gas for ccipReceive...`); const estimatedGas = await estimateReceiveExecution({ source: sourceChain, dest: destChain, @@ -120,21 +180,28 @@ const sendViaRouter = async ( }, }); - // Add 10% safety margin + // Add 10% safety margin on top of the SDK's estimate gasLimit = BigInt(Math.ceil(estimatedGas * 1.1)); - console.log(` Gas limit (estimated): ${estimatedGas} → ${gasLimit} (with 10% margin)`); + console.log(` Estimated gas: ${estimatedGas}`); + console.log(` Gas limit (with 10% margin): ${gasLimit}`); } - // Build message based on mode + // ────────────────────────────────────────────── + // Step 3: Build CCIP message (strongly typed MessageInput) + // ────────────────────────────────────────────── + console.log("\nStep 3: Building CCIP message..."); + let message: MessageInput; + let tokenSymbol = ""; if (mode === "tt") { - // Token transfer - use shared-utils helper + // Token transfer — use shared-utils helper for typed message construction const tokenAddress = getTokenAddress(args.token, sourceNetworkId); if (!tokenAddress) throw new Error(`Token ${args.token} not found on ${sourceNetworkId}`); const tokenInfo = await sourceChain.getTokenInfo(tokenAddress); const amount = parseUnits(args.amount, tokenInfo.decimals); + tokenSymbol = tokenInfo.symbol; message = buildTokenTransferMessage({ receiver, @@ -143,9 +210,10 @@ const sendViaRouter = async ( feeToken, }); console.log(` Token: ${tokenInfo.symbol} (${tokenAddress})`); - console.log(` Amount: ${args.amount}`); + console.log(` Amount: ${args.amount} ${tokenInfo.symbol} (${amount} smallest unit)`); + console.log(` Data payload: (none — token-only transfer)`); } else if (mode === "data") { - // Data-only message + // Data-only message — no tokens, just arbitrary data const dataPayload = encodePacked(["string"], ["Hello from CCIP!"]); message = { receiver, @@ -153,19 +221,19 @@ const sendViaRouter = async ( extraArgs: { gasLimit, allowOutOfOrderExecution: true }, ...(feeToken && { feeToken }), }; - console.log(` Data: ${dataPayload}`); + console.log(` Data payload: ${dataPayload}`); + console.log(` (Encoded string: "Hello from CCIP!")`); console.log(` Gas limit: ${gasLimit}`); } else if (mode === "ptt") { - // Programmable token transfer + // Programmable token transfer — data + tokens const tokenAddress = getTokenAddress(args.token, sourceNetworkId); if (!tokenAddress) throw new Error(`Token ${args.token} not found on ${sourceNetworkId}`); const tokenInfo = await sourceChain.getTokenInfo(tokenAddress); const amount = parseUnits(args.amount, tokenInfo.decimals); + tokenSymbol = tokenInfo.symbol; const dataPayload = - args.data !== "" - ? args.data - : encodeAbiParameters([{ type: "address" }], [receiver as `0x${string}`]); + args.data !== "" ? args.data : encodeAbiParameters([{ type: "address" }], [account.address]); message = { receiver, @@ -174,24 +242,107 @@ const sendViaRouter = async ( extraArgs: { gasLimit, allowOutOfOrderExecution: true }, ...(feeToken && { feeToken }), }; - console.log(` Token: ${tokenInfo.symbol}, Amount: ${args.amount}`); - console.log(` Data: ${dataPayload}`); + console.log(` Token: ${tokenInfo.symbol} (${tokenAddress})`); + console.log(` Amount: ${args.amount} ${tokenInfo.symbol} (${amount} smallest unit)`); + console.log(` Data payload: ${dataPayload}`); console.log(` Gas limit: ${gasLimit}`); } else { throw new Error(`Unknown mode: ${mode}. Use tt, data, or ptt.`); } - // Get fee estimate - console.log(`\n Estimating fee...`); + // ────────────────────────────────────────────── + // Step 4: Estimate CCIP fee + // ────────────────────────────────────────────── + console.log("\nStep 4: Estimating CCIP fee..."); const fee = await sourceChain.getFee({ router: routerAddress, destChainSelector, message, }); - console.log(` Fee: ${fee} (smallest unit)`); + console.log(` Estimated fee: ${formatAmount(fee, feeDecimals)} ${feeSymbol}`); + + // ────────────────────────────────────────────── + // Step 5: Check balances + // ────────────────────────────────────────────── + console.log("\nStep 5: Checking balances..."); + const nativeBalance = await sourceChain.getBalance({ holder: account.address }); + console.log( + ` Native balance: ${formatAmount(nativeBalance, sourceConfig.nativeCurrency.decimals)} ${sourceConfig.nativeCurrency.symbol}` + ); + + if (mode === "tt" || mode === "ptt") { + const tokenAddress = getTokenAddress(args.token, sourceNetworkId); + if (tokenAddress) { + const tokenInfo = await sourceChain.getTokenInfo(tokenAddress); + const tokenBalance = await sourceChain.getBalance({ + holder: account.address, + token: tokenAddress, + }); + const parsedAmount = parseUnits(args.amount, tokenInfo.decimals); + console.log( + ` Token balance: ${formatAmount(tokenBalance, tokenInfo.decimals)} ${tokenInfo.symbol}` + ); + if (tokenBalance < parsedAmount) { + throw new Error( + `Insufficient ${tokenInfo.symbol} balance: have ${formatAmount(tokenBalance, tokenInfo.decimals)}, need ${args.amount}` + ); + } + } + } + + if (feeToken) { + const feeTokenBalance = await sourceChain.getBalance({ + holder: account.address, + token: feeToken, + }); + console.log(` Fee token balance: ${formatAmount(feeTokenBalance, feeDecimals)} ${feeSymbol}`); + if (feeTokenBalance < fee) { + throw new Error( + `Insufficient ${feeSymbol} for fee: have ${formatAmount(feeTokenBalance, feeDecimals)}, need ${formatAmount(fee, feeDecimals)}` + ); + } + console.log( + ` After send (est): ~${formatAmount(nativeBalance, sourceConfig.nativeCurrency.decimals)} ${sourceConfig.nativeCurrency.symbol} (gas only)` + ); + console.log( + ` ~${formatAmount(feeTokenBalance - fee, feeDecimals)} ${feeSymbol}` + ); + } else { + if (nativeBalance < fee) { + throw new Error( + `Insufficient ${sourceConfig.nativeCurrency.symbol} for fee: have ${formatAmount(nativeBalance, sourceConfig.nativeCurrency.decimals)}, need ${formatAmount(fee, feeDecimals)}` + ); + } + console.log( + ` After send (est): ~${formatAmount(nativeBalance - fee, sourceConfig.nativeCurrency.decimals)} ${sourceConfig.nativeCurrency.symbol}` + ); + } + + // ────────────────────────────────────────────── + // Transfer Summary + // ────────────────────────────────────────────── + console.log("\n" + "=".repeat(60)); + console.log("Transfer Summary:"); + console.log(` Mode: ${mode}`); + console.log(` From: ${sourceConfig.name}`); + console.log(` To: ${dest}`); + console.log(` Receiver: ${receiver}`); + if (tokenSymbol) { + console.log(` Amount: ${args.amount} ${tokenSymbol}`); + } + console.log(` Gas limit: ${gasLimit}`); + console.log(` Fee: ${formatAmount(fee, feeDecimals)} ${feeSymbol}`); + console.log(` Fee payment: ${feeToken ? `LINK (${feeToken})` : `native (${feeSymbol})`}`); + console.log("=".repeat(60)); - // Send message using SDK (handles approvals + ccipSend) - console.log(`\n Sending message from ${account.address}...`); + // ────────────────────────────────────────────── + // Step 6: Send message via SDK + // ────────────────────────────────────────────── + // The SDK's sendMessage() handles token approvals (if needed) and + // calls router.ccipSend() in one step. It returns the tx hash and + // the parsed CCIP message with messageId. + console.log("\nStep 6: Sending CCIP message via router..."); + console.log(` (SDK handles token approvals + ccipSend in one call)`); const result = await sourceChain.sendMessage({ router: routerAddress, @@ -201,17 +352,24 @@ const sendViaRouter = async ( }); const txHash = result.tx.hash; - console.log(` Tx hash: ${txHash}`); - console.log(` Explorer: ${getExplorerTxUrl(sourceNetworkId, txHash)}`); + console.log(` Tx confirmed: ${txHash}`); + console.log(` Block explorer: ${getExplorerTxUrl(sourceNetworkId, txHash)}`); - // Extract messageId from the result + // ────────────────────────────────────────────── + // Step 7: Track message + // ────────────────────────────────────────────── + // sendMessage() already parses the CCIPSendRequested event and returns + // the messageId — no need for a separate getMessagesInTx call. const messageId = result.message.messageId; - console.log(`\n Message ID: ${messageId}`); + console.log(`\nStep 7: Message submitted successfully!`); + console.log(` Message ID: ${messageId}`); console.log(` CCIP Explorer: ${getCCIPExplorerUrl("msg", messageId)}`); - console.log(`\n Track status with:`); + console.log(`\n Track delivery status with:`); console.log(` npx hardhat check-status --message-id ${messageId}`); - console.log(`\nDone! Message sent directly via router.`); + console.log("\n" + "=".repeat(60)); + console.log("Done! Message sent directly via router."); + console.log("=".repeat(60) + "\n"); }; export default sendViaRouter; diff --git a/examples/04-hardhat-ccip/tasks/send-via-sender.ts b/examples/04-hardhat-ccip/tasks/send-via-sender.ts index 8a1529c..ed69cfd 100644 --- a/examples/04-hardhat-ccip/tasks/send-via-sender.ts +++ b/examples/04-hardhat-ccip/tasks/send-via-sender.ts @@ -3,10 +3,12 @@ * * Demonstrates the "extraArgs passthrough" pattern: * 1. Build extraArgs offchain using the CCIP SDK's encodeExtraArgs() - * 2. Pass them to the sender contract which forwards them to the router + * 2. Estimate the destination gas limit for ccipReceive via estimateReceiveExecution() + * 3. Estimate the CCIP fee via getFee() and display it in human-readable format + * 4. Pass everything to the sender contract which forwards to the router * - * Gas limit is auto-estimated via the SDK's estimateReceiveExecution() when - * not explicitly provided (for data and ptt modes). + * Supports both native and LINK fee payment. Gas limit is auto-estimated via + * the SDK for data and ptt modes. * * Usage: * # Token transfer (TT) — gasLimit auto 0 @@ -21,23 +23,30 @@ * --sender-contract 0x... --receiver 0x... \ * --mode data * - * # Programmable token transfer (PTT) — gasLimit auto-estimated + * # Programmable token transfer (PTT) — gasLimit auto-estimated, pay with LINK * npx hardhat --network ethereum-testnet-sepolia send-via-sender \ * --dest ethereum-testnet-sepolia-base-1 \ * --sender-contract 0x... --receiver 0x... \ - * --mode ptt --amount 0.001 --token CCIP-BnM + * --mode ptt --amount 0.001 --token CCIP-BnM --fee-token link */ import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; import { parseUnits, encodePacked, encodeAbiParameters, erc20Abi } from "viem"; -import { encodeExtraArgs, estimateReceiveExecution, getCCIPExplorerUrl } from "@chainlink/ccip-sdk"; +import { + encodeExtraArgs, + estimateReceiveExecution, + getCCIPExplorerUrl, + withRetry, +} from "@chainlink/ccip-sdk"; import { fromViemClient } from "@chainlink/ccip-sdk/viem"; import { type FeeTokenOption, + NETWORKS, getExplorerTxUrl, getTokenAddress, resolveFeeTokenAddress, } from "@ccip-examples/shared-config"; +import { formatAmount, formatLatency } from "@ccip-examples/shared-utils"; import { createClients, getRouterAddress, getDestChainSelector } from "../helpers/sdk.js"; interface SendViaSenderArgs { @@ -59,25 +68,66 @@ const sendViaSender = async ( const connection = await hre.network.connect(); const sourceNetworkId = connection.networkName; const { mode, dest, receiver } = args; + const sourceConfig = NETWORKS[sourceNetworkId]; + if (!sourceConfig) throw new Error(`Unknown source network: ${sourceNetworkId}`); + + // Validate mode early + const validModes = ["tt", "data", "ptt"]; + if (!validModes.includes(mode)) { + throw new Error(`Invalid mode: "${mode}". Must be one of: ${validModes.join(", ")}`); + } + + // Validate gasLimit if provided + if (args.gasLimit !== "0") { + const parsed = Number(args.gasLimit); + if (isNaN(parsed) || parsed < 0) { + throw new Error(`Invalid --gas-limit: "${args.gasLimit}". Must be a non-negative number.`); + } + } - console.log(`\nSending CCIP message via sender contract...`); - console.log(` Source: ${sourceNetworkId}`); + console.log("\n" + "=".repeat(60)); + console.log("CCIP Message via Sender Contract (extraArgs passthrough)"); + console.log("=".repeat(60)); + console.log(` Source: ${sourceConfig.name} (${sourceNetworkId})`); console.log(` Destination: ${dest}`); - console.log(` Mode: ${mode}`); - console.log(` Receiver: ${receiver}`); + console.log(` Mode: ${mode}`); + console.log(` Receiver: ${receiver}`); + console.log(` Fee token: ${args.feeToken}`); + // ────────────────────────────────────────────── + // Step 1: Initialize SDK clients + // ────────────────────────────────────────────── + console.log("\nStep 1: Initializing SDK clients..."); const { account, publicClient, walletClient } = createClients(sourceNetworkId); const { publicClient: destPublicClient } = createClients(dest); const senderArtifact = await hre.artifacts.readArtifact("CCIPSender"); const destChainSelector = getDestChainSelector(dest); const routerAddress = getRouterAddress(sourceNetworkId); - // Build token amounts (for tt and ptt modes) + const sourceChain = await fromViemClient(publicClient); + const destChain = await fromViemClient(destPublicClient); + console.log(` Wallet: ${account.address}`); + + // Estimate lane latency (informational) + try { + const latency = await sourceChain.getLaneLatency(destChainSelector); + console.log(` Estimated delivery: ${formatLatency(latency.totalMs)}`); + } catch { + // Lane latency is informational — don't block the send + } + + // ────────────────────────────────────────────── + // Step 2: Prepare message payload (tokens + data) + // ────────────────────────────────────────────── + console.log("\nStep 2: Preparing message payload..."); + interface TokenAmount { token: `0x${string}`; amount: bigint; } let tokenAmounts: TokenAmount[] = []; + let tokenSymbol = ""; + let tokenDecimals = 18; if (mode === "tt" || mode === "ptt") { const tokenAddress = getTokenAddress(args.token, sourceNetworkId); @@ -88,39 +138,49 @@ const sendViaSender = async ( abi: erc20Abi, functionName: "decimals", }); + tokenSymbol = args.token; + tokenDecimals = decimals; const amount = parseUnits(args.amount, decimals); tokenAmounts = [{ token: tokenAddress as `0x${string}`, amount }]; + console.log(` Token: ${tokenSymbol} (${tokenAddress})`); + console.log(` Amount: ${args.amount} ${tokenSymbol} (${amount} smallest unit)`); } // Build data payload let data: `0x${string}` = "0x"; if (mode === "data") { data = encodePacked(["string"], ["Hello from CCIP!"]); - console.log(` Data: ${data}`); + console.log(` Data payload: ${data}`); + console.log(` (Encoded string: "Hello from CCIP!")`); } else if (mode === "ptt") { data = args.data !== "" ? (args.data as `0x${string}`) - : encodeAbiParameters([{ type: "address" }], [receiver as `0x${string}`]); - console.log(` Data (encoded address): ${data}`); + : encodeAbiParameters([{ type: "address" }], [account.address]); + console.log(` Data payload (encoded address): ${data}`); + } else if (mode === "tt") { + console.log(` Data payload: (none — token-only transfer)`); } - // Determine gasLimit: use provided value or auto-estimate via SDK + // ────────────────────────────────────────────── + // Step 3: Estimate destination gas limit + // ────────────────────────────────────────────── + console.log("\nStep 3: Estimating destination gas for ccipReceive..."); + let gasLimit: bigint; if (args.gasLimit !== "0") { gasLimit = BigInt(args.gasLimit); - console.log(` Gas limit (manual): ${gasLimit}`); + console.log(` Gas limit (manual override): ${gasLimit}`); } else if (mode === "tt") { - // Token-only transfers don't execute receiver logic + // Token-only transfers don't execute receiver logic — the router + // delivers tokens directly without calling ccipReceive() gasLimit = 0n; - console.log(` Gas limit: 0 (token-only, no receiver execution)`); + console.log(` Gas limit: 0 (token-only transfer — no receiver execution needed)`); } else { - // Auto-estimate gas for data/ptt modes using SDK - console.log(`\n Estimating destination gas for ccipReceive...`); - const sourceChain = await fromViemClient(publicClient); - const destChain = await fromViemClient(destPublicClient); - + // Auto-estimate gas for data/ptt modes using the SDK's estimateReceiveExecution. + // This simulates ccipReceive() on the destination chain to determine the exact + // gas needed, then we add a 10% safety margin. const estimatedGas = await estimateReceiveExecution({ source: sourceChain, dest: destChain, @@ -136,22 +196,28 @@ const sendViaSender = async ( }, }); - // Add 10% safety margin gasLimit = BigInt(Math.ceil(estimatedGas * 1.1)); - console.log(` Gas limit (estimated): ${estimatedGas} → ${gasLimit} (with 10% margin)`); + console.log(` Estimated gas: ${estimatedGas}`); + console.log(` Gas limit (with 10% margin): ${gasLimit}`); } - // Build extraArgs offchain using the SDK + // ────────────────────────────────────────────── + // Step 4: Encode extraArgs + // ────────────────────────────────────────────── + console.log("\nStep 4: Encoding extraArgs (offchain via SDK)..."); const extraArgs = encodeExtraArgs({ gasLimit, allowOutOfOrderExecution: true, }) as `0x${string}`; - console.log(` Extra args (encoded): ${extraArgs}`); + console.log(` extraArgs: ${extraArgs}`); + console.log(` (gasLimit=${gasLimit}, allowOutOfOrderExecution=true)`); + // ────────────────────────────────────────────── + // Step 5: Approve token spending (if needed) + // ────────────────────────────────────────────── const firstToken = tokenAmounts[0]; if ((mode === "tt" || mode === "ptt") && firstToken) { - // Approve sender contract to spend tokens - console.log(`\n Approving ${args.amount} ${args.token} for sender contract...`); + console.log(`\nStep 5: Approving ${args.amount} ${tokenSymbol} for sender contract...`); const approveHash = await walletClient.writeContract({ address: firstToken.token, abi: erc20Abi, @@ -159,31 +225,156 @@ const sendViaSender = async ( args: [args.senderContract as `0x${string}`, firstToken.amount], }); await publicClient.waitForTransactionReceipt({ hash: approveHash }); - console.log(` Approved.`); + console.log(` Approved: ${getExplorerTxUrl(sourceNetworkId, approveHash)}`); + } else { + console.log("\nStep 5: Token approval — skipped (no tokens in this message)"); } - // Resolve fee token + // ────────────────────────────────────────────── + // Step 6: Estimate CCIP fee + // ────────────────────────────────────────────── + console.log("\nStep 6: Estimating CCIP fee..."); + + // Resolve fee token address: "native" → undefined, "link" → LINK address const feeTokenOption = args.feeToken as FeeTokenOption; const feeTokenAddress = resolveFeeTokenAddress(feeTokenOption, sourceNetworkId); const feeTokenForContract = feeTokenAddress ? (feeTokenAddress as `0x${string}`) : ("0x0000000000000000000000000000000000000000" as `0x${string}`); - // If paying with LINK, approve sender contract for fees + // Resolve fee token metadata for human-readable display + let feeDecimals: number; + let feeSymbol: string; + + if (feeTokenAddress) { + const feeTokenInfo = await sourceChain.getTokenInfo(feeTokenAddress); + feeDecimals = feeTokenInfo.decimals; + feeSymbol = feeTokenInfo.symbol; + } else { + feeDecimals = sourceConfig.nativeCurrency.decimals; + feeSymbol = sourceConfig.nativeCurrency.symbol; + } + + // Estimate fee using the SDK — this mirrors the router.getFee() call + // that the sender contract makes on-chain + const fee = await sourceChain.getFee({ + router: routerAddress, + destChainSelector, + message: { + receiver, + data, + tokenAmounts: tokenAmounts.map((ta) => ({ token: ta.token, amount: ta.amount })), + extraArgs: { gasLimit, allowOutOfOrderExecution: true }, + ...(feeTokenAddress && { feeToken: feeTokenAddress }), + }, + }); + + // Add 10% buffer — the sender contract calls router.getFee() on-chain + // and refunds any excess + const feeWithBuffer = (fee * 110n) / 100n; + console.log(` Estimated fee: ${formatAmount(fee, feeDecimals)} ${feeSymbol}`); + console.log(` Fee with 10% buffer: ${formatAmount(feeWithBuffer, feeDecimals)} ${feeSymbol}`); + console.log(` (Excess is refunded by the sender contract)`); + + // ────────────────────────────────────────────── + // Step 7: Check balances + // ────────────────────────────────────────────── + console.log("\nStep 7: Checking balances..."); + const nativeBalance = await sourceChain.getBalance({ holder: account.address }); + console.log( + ` Native balance: ${formatAmount(nativeBalance, sourceConfig.nativeCurrency.decimals)} ${sourceConfig.nativeCurrency.symbol}` + ); + + if (firstToken) { + const tokenBalance = await sourceChain.getBalance({ + holder: account.address, + token: firstToken.token, + }); + console.log(` Token balance: ${formatAmount(tokenBalance, tokenDecimals)} ${tokenSymbol}`); + if (tokenBalance < firstToken.amount) { + throw new Error( + `Insufficient ${tokenSymbol} balance: have ${formatAmount(tokenBalance, tokenDecimals)}, need ${args.amount}` + ); + } + } + + if (feeTokenAddress) { + const feeTokenBalance = await sourceChain.getBalance({ + holder: account.address, + token: feeTokenAddress, + }); + console.log(` Fee token balance: ${formatAmount(feeTokenBalance, feeDecimals)} ${feeSymbol}`); + if (feeTokenBalance < feeWithBuffer) { + throw new Error( + `Insufficient ${feeSymbol} for fee: have ${formatAmount(feeTokenBalance, feeDecimals)}, need ${formatAmount(feeWithBuffer, feeDecimals)}` + ); + } + } else if (nativeBalance < feeWithBuffer) { + throw new Error( + `Insufficient ${sourceConfig.nativeCurrency.symbol} for fee: have ${formatAmount(nativeBalance, sourceConfig.nativeCurrency.decimals)}, need ${formatAmount(feeWithBuffer, feeDecimals)}` + ); + } + + // Estimate balance after send if (feeTokenAddress) { - console.log(`\n Approving LINK for fee payment...`); + console.log( + ` After send (est): ~${formatAmount(nativeBalance, sourceConfig.nativeCurrency.decimals)} ${sourceConfig.nativeCurrency.symbol} (gas only)` + ); + const feeTokenBalance = await sourceChain.getBalance({ + holder: account.address, + token: feeTokenAddress, + }); + console.log( + ` ~${formatAmount(feeTokenBalance - feeWithBuffer, feeDecimals)} ${feeSymbol}` + ); + } else { + console.log( + ` After send (est): ~${formatAmount(nativeBalance - feeWithBuffer, sourceConfig.nativeCurrency.decimals)} ${sourceConfig.nativeCurrency.symbol}` + ); + } + + // ────────────────────────────────────────────── + // Step 8: Approve LINK for fees (if paying with LINK) + // ────────────────────────────────────────────── + if (feeTokenAddress) { + console.log( + `\nStep 8: Approving ${formatAmount(feeWithBuffer, feeDecimals)} ${feeSymbol} for fee payment...` + ); const approveFeeHash = await walletClient.writeContract({ address: feeTokenAddress as `0x${string}`, abi: erc20Abi, functionName: "approve", - args: [args.senderContract as `0x${string}`, parseUnits("1", 18)], // 1 LINK max + args: [args.senderContract as `0x${string}`, feeWithBuffer], }); await publicClient.waitForTransactionReceipt({ hash: approveFeeHash }); - console.log(` LINK approved for fees.`); + console.log(` Approved: ${getExplorerTxUrl(sourceNetworkId, approveFeeHash)}`); + } else { + console.log("\nStep 8: LINK fee approval — skipped (paying with native token)"); + } + + // ────────────────────────────────────────────── + // Transfer Summary + // ────────────────────────────────────────────── + console.log("\n" + "=".repeat(60)); + console.log("Transfer Summary:"); + console.log(` Mode: ${mode}`); + console.log(` From: ${sourceConfig.name}`); + console.log(` To: ${dest}`); + console.log(` Receiver: ${receiver}`); + if (firstToken) { + console.log(` Amount: ${args.amount} ${tokenSymbol}`); } + console.log(` Gas limit: ${gasLimit}`); + console.log(` Fee: ~${formatAmount(feeWithBuffer, feeDecimals)} ${feeSymbol}`); + console.log( + ` Fee payment: ${feeTokenAddress ? `LINK (${feeTokenAddress})` : `native (${feeSymbol})`}` + ); + console.log("=".repeat(60)); - // Send the message - console.log(`\n Sending CCIP message...`); + // ────────────────────────────────────────────── + // Step 9: Send the CCIP message + // ────────────────────────────────────────────── + console.log("\nStep 9: Sending CCIP message via sender contract..."); const sendHash = await walletClient.writeContract({ address: args.senderContract as `0x${string}`, abi: senderArtifact.abi, @@ -196,27 +387,54 @@ const sendViaSender = async ( extraArgs, feeTokenForContract, ], - value: feeTokenAddress ? 0n : parseUnits("0.01", 18), // Send extra native for fees + value: feeTokenAddress ? 0n : feeWithBuffer, account, }); - console.log(` Tx hash: ${sendHash}`); - console.log(` Explorer: ${getExplorerTxUrl(sourceNetworkId, sendHash)}`); + console.log(` Tx submitted: ${sendHash}`); + console.log(` Waiting for on-chain confirmation...`); + const receipt = await publicClient.waitForTransactionReceipt({ hash: sendHash }); + console.log(` Confirmed in block ${receipt.blockNumber}`); + console.log(` Block explorer: ${getExplorerTxUrl(sourceNetworkId, sendHash)}`); - // Extract messageId using the SDK's getMessagesInTx - const chain = await fromViemClient(publicClient); - const requests = await chain.getMessagesInTx(sendHash); + // ────────────────────────────────────────────── + // Step 10: Extract message ID and track + // ────────────────────────────────────────────── + console.log("\nStep 10: Extracting CCIP message ID from transaction logs..."); + try { + // getMessagesInTx parses the CCIPSendRequested event from the transaction + // receipt logs — no API call needed. We waited for the receipt above so + // the logs are guaranteed to be available. + const requests = await withRetry(() => sourceChain.getMessagesInTx(sendHash), { + maxRetries: 3, + initialDelayMs: 1000, + maxDelayMs: 5000, + backoffMultiplier: 1.5, + respectRetryAfterHint: true, + logger: { + debug: (...logArgs: unknown[]) => console.log(" [retry]", ...logArgs), + warn: (...logArgs: unknown[]) => console.warn(" [retry]", ...logArgs), + }, + }); - const firstRequest = requests[0]; - if (firstRequest) { - const messageId = firstRequest.message.messageId; - console.log(`\n Message ID: ${messageId}`); - console.log(` CCIP Explorer: ${getCCIPExplorerUrl("msg", messageId)}`); - console.log(`\n Track status with:`); - console.log(` npx hardhat check-status --message-id ${messageId}`); + const firstRequest = requests[0]; + if (firstRequest) { + const messageId = firstRequest.message.messageId; + console.log(` Message ID: ${messageId}`); + console.log(` CCIP Explorer: ${getCCIPExplorerUrl("msg", messageId)}`); + console.log(`\n Track delivery status with:`); + console.log(` npx hardhat check-status --message-id ${messageId}`); + } + } catch (err) { + console.warn( + ` Could not extract message ID: ${err instanceof Error ? err.message : String(err)}` + ); + console.log(` You can find your message on the CCIP Explorer using the tx hash above.`); } - console.log(`\nDone! Message sent via sender contract.`); + console.log("\n" + "=".repeat(60)); + console.log("Done! Message sent via sender contract."); + console.log("=".repeat(60) + "\n"); }; export default sendViaSender; diff --git a/examples/04-hardhat-ccip/tasks/withdraw-funds.ts b/examples/04-hardhat-ccip/tasks/withdraw-funds.ts new file mode 100644 index 0000000..3977525 --- /dev/null +++ b/examples/04-hardhat-ccip/tasks/withdraw-funds.ts @@ -0,0 +1,131 @@ +/** + * Task: Withdraw native currency or ERC20 tokens from a contract + * + * Use this to recover: + * - Native currency sent to the contract + * - ERC20 tokens from failed CCIP messages (tokens stay in the receiver contract) + * - Any stuck tokens + * + * Usage: + * # Withdraw native currency from sender contract + * npx hardhat --network avalanche-testnet-fuji withdraw-funds \ + * --contract 0x... --type sender --beneficiary 0x... + * + * # Withdraw ERC20 tokens from receiver contract (full balance) + * npx hardhat --network ethereum-testnet-sepolia withdraw-funds \ + * --contract 0x... --type receiver --beneficiary 0x... --token 0x... + * + * # Withdraw specific amount of ERC20 tokens + * npx hardhat --network ethereum-testnet-sepolia withdraw-funds \ + * --contract 0x... --type receiver --beneficiary 0x... --token 0x... --amount 1000000 + */ + +import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; +import { erc20Abi, formatUnits } from "viem"; +import { getExplorerTxUrl } from "@ccip-examples/shared-config"; +import { createClients } from "../helpers/sdk.js"; + +interface WithdrawFundsArgs { + contract: string; + type: string; + beneficiary: string; + token: string; + amount: string; +} + +const withdrawFunds = async ( + args: WithdrawFundsArgs, + hre: HardhatRuntimeEnvironment +): Promise => { + const connection = await hre.network.connect(); + const networkId = connection.networkName; + + if (!args.contract) throw new Error("--contract is required"); + if (!args.beneficiary) throw new Error("--beneficiary is required"); + if (args.type !== "sender" && args.type !== "receiver") { + throw new Error(`Invalid --type: "${args.type}". Must be "sender" or "receiver".`); + } + + const artifactName = args.type === "sender" ? "CCIPSender" : "CCIPReceiverExample"; + const artifact = await hre.artifacts.readArtifact(artifactName); + const { publicClient, walletClient } = createClients(networkId); + const contractAddress = args.contract as `0x${string}`; + const beneficiary = args.beneficiary as `0x${string}`; + + if (args.token !== "") { + // ERC20 withdrawal + const tokenAddress = args.token as `0x${string}`; + + const [symbol, decimals, balance] = await Promise.all([ + publicClient.readContract({ address: tokenAddress, abi: erc20Abi, functionName: "symbol" }), + publicClient.readContract({ address: tokenAddress, abi: erc20Abi, functionName: "decimals" }), + publicClient.readContract({ + address: tokenAddress, + abi: erc20Abi, + functionName: "balanceOf", + args: [contractAddress], + }), + ]); + + if (balance === 0n) { + console.log(`\n No ${symbol} tokens in contract. Nothing to withdraw.`); + return; + } + + const withdrawAmount = args.amount !== "0" ? BigInt(args.amount) : 0n; + const displayAmount = + withdrawAmount === 0n + ? `${formatUnits(balance, decimals)} ${symbol} (full balance)` + : `${formatUnits(withdrawAmount, decimals)} ${symbol}`; + + console.log(`\nWithdrawing ERC20 tokens from ${artifactName}...`); + console.log(` Network: ${networkId}`); + console.log(` Contract: ${contractAddress}`); + console.log(` Token: ${symbol} (${tokenAddress})`); + console.log(` Balance: ${formatUnits(balance, decimals)} ${symbol}`); + console.log(` Withdrawing: ${displayAmount}`); + console.log(` Beneficiary: ${beneficiary}`); + + const hash = await walletClient.writeContract({ + address: contractAddress, + abi: artifact.abi, + functionName: "withdrawToken", + args: [beneficiary, tokenAddress, withdrawAmount], + }); + + console.log(` Tx hash: ${hash}`); + console.log(` Explorer: ${getExplorerTxUrl(networkId, hash)}`); + + await publicClient.waitForTransactionReceipt({ hash }); + console.log(`\n Tokens withdrawn successfully.`); + } else { + // Native currency withdrawal + const balance = await publicClient.getBalance({ address: contractAddress }); + + if (balance === 0n) { + console.log(`\n No native currency in contract. Nothing to withdraw.`); + return; + } + + console.log(`\nWithdrawing native currency from ${artifactName}...`); + console.log(` Network: ${networkId}`); + console.log(` Contract: ${contractAddress}`); + console.log(` Balance: ${formatUnits(balance, 18)} ETH/AVAX`); + console.log(` Beneficiary: ${beneficiary}`); + + const hash = await walletClient.writeContract({ + address: contractAddress, + abi: artifact.abi, + functionName: "withdraw", + args: [beneficiary], + }); + + console.log(` Tx hash: ${hash}`); + console.log(` Explorer: ${getExplorerTxUrl(networkId, hash)}`); + + await publicClient.waitForTransactionReceipt({ hash }); + console.log(`\n Native currency withdrawn successfully.`); + } +}; + +export default withdrawFunds; diff --git a/examples/04-hardhat-ccip/test/CCIPReceiver.test.ts b/examples/04-hardhat-ccip/test/CCIPReceiver.test.ts new file mode 100644 index 0000000..020811e --- /dev/null +++ b/examples/04-hardhat-ccip/test/CCIPReceiver.test.ts @@ -0,0 +1,266 @@ +import assert from "node:assert/strict"; +import { describe, it } from "node:test"; +import { parseAbi } from "viem"; + +import { network } from "hardhat"; + +void describe("CCIPReceiverExample", async function () { + const { viem } = await network.connect(); + const publicClient = await viem.getPublicClient(); + const walletClients = await viem.getWalletClients(); + const owner = walletClients[0]!; + const nonOwner = walletClients[1]!; + + const simulator = await viem.deployContract("LocalSimulator"); + const config = await simulator.read.configuration!(); + const chainSelector = (config as [bigint, ...unknown[]])[0]; + const routerAddress = (config as [bigint, string])[1] as `0x${string}`; + + void it("Should deploy with correct router and owner", async function () { + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + const contractOwner = (await receiver.read.owner!()) as string; + assert.equal(contractOwner.toLowerCase(), owner.account.address.toLowerCase()); + }); + + void it("Should allowlist a single sender", async function () { + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + const senderAddr = "0x1111111111111111111111111111111111111111" as `0x${string}`; + + await receiver.write.allowlistSender!([chainSelector, senderAddr, true]); + const allowed = await receiver.read.allowlistedSenders!([chainSelector, senderAddr]); + assert.equal(allowed, true); + }); + + void it("Should batch update allowlist via updateAllowlist", async function () { + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + const entries = [ + { + sourceChainSelector: chainSelector, + sender: "0x1111111111111111111111111111111111111111" as `0x${string}`, + allowed: true, + }, + { + sourceChainSelector: 1n, + sender: "0x2222222222222222222222222222222222222222" as `0x${string}`, + allowed: true, + }, + ]; + + const hash = await receiver.write.updateAllowlist!([entries]); + const receipt = await publicClient.waitForTransactionReceipt({ hash }); + + // Verify events + const events = await publicClient.getContractEvents({ + address: receiver.address, + abi: receiver.abi, + eventName: "AllowlistUpdated", + fromBlock: receipt.blockNumber, + strict: true, + }); + assert.equal(events.length, 2); + + // Verify state + for (const entry of entries) { + const allowed = await receiver.read.allowlistedSenders!([ + entry.sourceChainSelector, + entry.sender, + ]); + assert.equal(allowed, true); + } + }); + + void it("Should batch update allowlist with mixed add/remove", async function () { + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + const senderAddr = "0x1111111111111111111111111111111111111111" as `0x${string}`; + + // First allowlist + await receiver.write.allowlistSender!([chainSelector, senderAddr, true]); + assert.equal(await receiver.read.allowlistedSenders!([chainSelector, senderAddr]), true); + + // Now batch: remove first, add second + const entries = [ + { sourceChainSelector: chainSelector, sender: senderAddr, allowed: false }, + { + sourceChainSelector: chainSelector, + sender: "0x2222222222222222222222222222222222222222" as `0x${string}`, + allowed: true, + }, + ]; + + await receiver.write.updateAllowlist!([entries]); + + assert.equal(await receiver.read.allowlistedSenders!([chainSelector, senderAddr]), false); + assert.equal( + await receiver.read.allowlistedSenders!([ + chainSelector, + "0x2222222222222222222222222222222222222222", + ]), + true + ); + }); + + void it("Should reject non-owner calls to allowlistSender, updateAllowlist, pause, withdraw", async function () { + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + const receiverAsNonOwner = await viem.getContractAt("CCIPReceiverExample", receiver.address, { + client: { public: publicClient, wallet: nonOwner }, + }); + + await assert.rejects( + receiverAsNonOwner.write.allowlistSender!([ + chainSelector, + "0x1111111111111111111111111111111111111111", + true, + ]), + (err: Error) => { + assert.ok(err.message.includes("OwnableUnauthorizedAccount")); + return true; + } + ); + + await assert.rejects( + receiverAsNonOwner.write.updateAllowlist!([ + [ + { + sourceChainSelector: chainSelector, + sender: "0x1111111111111111111111111111111111111111" as `0x${string}`, + allowed: true, + }, + ], + ]), + (err: Error) => { + assert.ok(err.message.includes("OwnableUnauthorizedAccount")); + return true; + } + ); + + await assert.rejects(receiverAsNonOwner.write.pause!(), (err: Error) => { + assert.ok(err.message.includes("OwnableUnauthorizedAccount")); + return true; + }); + + await assert.rejects( + receiverAsNonOwner.write.withdraw!([nonOwner.account.address]), + (err: Error) => { + assert.ok(err.message.includes("OwnableUnauthorizedAccount")); + return true; + } + ); + }); + + void it("Should pause and block _ccipReceive when paused", async function () { + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + + await receiver.write.pause!(); + assert.equal(await receiver.read.paused!(), true); + + await receiver.write.unpause!(); + assert.equal(await receiver.read.paused!(), false); + }); + + void it("Should revert withdraw when nothing to withdraw", async function () { + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + + await assert.rejects(receiver.write.withdraw!([owner.account.address]), (err: Error) => { + assert.ok(err.message.includes("NothingToWithdraw")); + return true; + }); + }); + + void it("Should withdraw native balance", async function () { + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + + // Send ETH to the contract + await owner.sendTransaction({ + to: receiver.address, + value: 1000000000000000n, + }); + + const balanceBefore = await publicClient.getBalance({ address: owner.account.address }); + await receiver.write.withdraw!([owner.account.address]); + const balanceAfter = await publicClient.getBalance({ address: owner.account.address }); + + assert.ok(balanceAfter > balanceBefore - 1000000000000000n); + }); + + void it("Should withdrawToken ERC20 tokens", async function () { + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + + // Get ccipBnM token from simulator + const config2 = await simulator.read.configuration!(); + const ccipBnMAddress = ( + config2 as [bigint, string, string, string, string, string] + )[5] as `0x${string}`; + + const erc20Abi = parseAbi([ + "function drip(address to) external", + "function transfer(address to, uint256 amount) returns (bool)", + "function balanceOf(address account) view returns (uint256)", + ]); + + // Drip tokens and transfer some to the receiver contract + await owner.writeContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "drip", + args: [owner.account.address], + }); + + const transferAmount = 500000000000000000n; + await owner.writeContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "transfer", + args: [receiver.address, transferAmount], + }); + + // Verify tokens are in the contract + const contractBalance = await publicClient.readContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "balanceOf", + args: [receiver.address], + }); + assert.equal(contractBalance, transferAmount); + + // Withdraw full balance (amount = 0) + await receiver.write.withdrawToken!([owner.account.address, ccipBnMAddress, 0n]); + + // Verify contract balance is now 0 + const contractBalanceAfter = await publicClient.readContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "balanceOf", + args: [receiver.address], + }); + assert.equal(contractBalanceAfter, 0n); + }); + + void it("Should reject non-owner withdrawToken call", async function () { + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + const receiverAsNonOwner = await viem.getContractAt("CCIPReceiverExample", receiver.address, { + client: { public: publicClient, wallet: nonOwner }, + }); + + await assert.rejects( + receiverAsNonOwner.write.withdrawToken!([ + nonOwner.account.address, + "0x1111111111111111111111111111111111111111", + 0n, + ]), + (err: Error) => { + assert.ok(err.message.includes("OwnableUnauthorizedAccount")); + return true; + } + ); + }); + + void it("Should query failedMessages mapping", async function () { + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + const fakeMessageId = + "0x0000000000000000000000000000000000000000000000000000000000000001" as `0x${string}`; + + // Should be false for any unknown message ID + const isFailed = await receiver.read.failedMessages!([fakeMessageId]); + assert.equal(isFailed, false); + }); +}); diff --git a/examples/04-hardhat-ccip/test/CCIPSender.test.ts b/examples/04-hardhat-ccip/test/CCIPSender.test.ts new file mode 100644 index 0000000..c436117 --- /dev/null +++ b/examples/04-hardhat-ccip/test/CCIPSender.test.ts @@ -0,0 +1,235 @@ +import assert from "node:assert/strict"; +import { describe, it } from "node:test"; +import { parseAbi } from "viem"; + +import { network } from "hardhat"; + +void describe("CCIPSender", async function () { + const { viem } = await network.connect(); + const publicClient = await viem.getPublicClient(); + const walletClients = await viem.getWalletClients(); + const owner = walletClients[0]!; + const nonOwner = walletClients[1]!; + + // Deploy a fresh LocalSimulator for router address + const simulator = await viem.deployContract("LocalSimulator"); + const config = await simulator.read.configuration!(); + const chainSelector = (config as [bigint, ...unknown[]])[0]; + const routerAddress = (config as [bigint, string])[1] as `0x${string}`; + + void it("Should deploy with correct router and owner", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + const router = (await sender.read.i_router!()) as string; + assert.equal(router.toLowerCase(), routerAddress.toLowerCase()); + + const contractOwner = (await sender.read.owner!()) as string; + assert.equal(contractOwner.toLowerCase(), owner.account.address.toLowerCase()); + }); + + void it("Should register a peer via setPeer", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + const peerAddress = "0x1111111111111111111111111111111111111111" as `0x${string}`; + + const hash = await sender.write.setPeer!([chainSelector, peerAddress]); + const receipt = await publicClient.waitForTransactionReceipt({ hash }); + + // Verify PeerSet event + const events = await publicClient.getContractEvents({ + address: sender.address, + abi: sender.abi, + eventName: "PeerSet", + fromBlock: receipt.blockNumber, + strict: true, + }); + assert.equal(events.length, 1); + const eventArgs = events[0]!.args as { destChainSelector: bigint; peer: string }; + assert.equal(eventArgs.destChainSelector, chainSelector); + assert.equal(eventArgs.peer.toLowerCase(), peerAddress.toLowerCase()); + + const registered = (await sender.read.peers!([chainSelector])) as string; + assert.equal(registered.toLowerCase(), peerAddress.toLowerCase()); + }); + + void it("Should batch register peers via setPeers", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + const selectors = [chainSelector, 1n]; + const addresses = [ + "0x1111111111111111111111111111111111111111" as `0x${string}`, + "0x2222222222222222222222222222222222222222" as `0x${string}`, + ]; + + const hash = await sender.write.setPeers!([selectors, addresses]); + await publicClient.waitForTransactionReceipt({ hash }); + + for (let i = 0; i < selectors.length; i++) { + const registered = (await sender.read.peers!([selectors[i]!])) as string; + assert.equal(registered.toLowerCase(), addresses[i]!.toLowerCase()); + } + }); + + void it("Should revert setPeers on array length mismatch", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + + await assert.rejects( + sender.write.setPeers!([ + [chainSelector], + [ + "0x1111111111111111111111111111111111111111" as `0x${string}`, + "0x2222222222222222222222222222222222222222" as `0x${string}`, + ], + ]), + (err: Error) => { + assert.ok(err.message.includes("ArrayLengthMismatch")); + return true; + } + ); + }); + + void it("Should revert send on unregistered peer", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + const receiver = "0x1111111111111111111111111111111111111111" as `0x${string}`; + + await assert.rejects( + sender.write.send!( + [chainSelector, receiver, "0x", [], "0x", "0x0000000000000000000000000000000000000000"], + { value: 1000000000000000n } + ), + (err: Error) => { + assert.ok(err.message.includes("PeerNotRegistered")); + return true; + } + ); + }); + + void it("Should pause and unpause", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + + await sender.write.pause!(); + const paused = await sender.read.paused!(); + assert.equal(paused, true); + + await sender.write.unpause!(); + const unpaused = await sender.read.paused!(); + assert.equal(unpaused, false); + }); + + void it("Should block sends when paused", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + const receiver = "0x1111111111111111111111111111111111111111" as `0x${string}`; + + await sender.write.setPeer!([chainSelector, receiver]); + await sender.write.pause!(); + + await assert.rejects( + sender.write.send!( + [chainSelector, receiver, "0x", [], "0x", "0x0000000000000000000000000000000000000000"], + { value: 1000000000000000n } + ), + (err: Error) => { + assert.ok(err.message.includes("EnforcedPause")); + return true; + } + ); + }); + + void it("Should reject non-owner calls to setPeer, pause, withdraw", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + const senderAsNonOwner = await viem.getContractAt("CCIPSender", sender.address, { + client: { public: publicClient, wallet: nonOwner }, + }); + + await assert.rejects( + senderAsNonOwner.write.setPeer!([ + chainSelector, + "0x1111111111111111111111111111111111111111", + ]), + (err: Error) => { + assert.ok(err.message.includes("OwnableUnauthorizedAccount")); + return true; + } + ); + + await assert.rejects(senderAsNonOwner.write.pause!(), (err: Error) => { + assert.ok(err.message.includes("OwnableUnauthorizedAccount")); + return true; + }); + + await assert.rejects( + senderAsNonOwner.write.withdraw!([nonOwner.account.address]), + (err: Error) => { + assert.ok(err.message.includes("OwnableUnauthorizedAccount")); + return true; + } + ); + }); + + void it("Should withdraw native balance", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + + // Send ETH to the contract + await owner.sendTransaction({ + to: sender.address, + value: 1000000000000000n, + }); + + const balanceBefore = await publicClient.getBalance({ address: owner.account.address }); + await sender.write.withdraw!([owner.account.address]); + const balanceAfter = await publicClient.getBalance({ address: owner.account.address }); + + // Balance should increase (minus gas), but at least more than before minus gas cost + assert.ok(balanceAfter > balanceBefore - 1000000000000000n); + }); + + void it("Should revert withdraw when nothing to withdraw", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + + await assert.rejects(sender.write.withdraw!([owner.account.address]), (err: Error) => { + assert.ok(err.message.includes("NothingToWithdraw")); + return true; + }); + }); + + void it("Should withdrawToken ERC20 tokens", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + + // Get ccipBnM token from simulator + const config2 = await simulator.read.configuration!(); + const ccipBnMAddress = ( + config2 as [bigint, string, string, string, string, string] + )[5] as `0x${string}`; + + const erc20Abi = parseAbi([ + "function drip(address to) external", + "function transfer(address to, uint256 amount) returns (bool)", + "function balanceOf(address account) view returns (uint256)", + ]); + + // Drip tokens and transfer some to the sender contract + await owner.writeContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "drip", + args: [owner.account.address], + }); + + const transferAmount = 500000000000000000n; + await owner.writeContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "transfer", + args: [sender.address, transferAmount], + }); + + // Withdraw full balance (amount = 0) + await sender.write.withdrawToken!([owner.account.address, ccipBnMAddress, 0n]); + + // Verify contract balance is now 0 + const contractBalance = await publicClient.readContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "balanceOf", + args: [sender.address], + }); + assert.equal(contractBalance, 0n); + }); +}); diff --git a/examples/04-hardhat-ccip/test/Integration.test.ts b/examples/04-hardhat-ccip/test/Integration.test.ts new file mode 100644 index 0000000..9e6d9d1 --- /dev/null +++ b/examples/04-hardhat-ccip/test/Integration.test.ts @@ -0,0 +1,325 @@ +import assert from "node:assert/strict"; +import { describe, it } from "node:test"; +import { zeroAddress, encodeAbiParameters, concat, parseAbi } from "viem"; + +import { network } from "hardhat"; + +// EVM_EXTRA_ARGS_V1_TAG (0x97a657c9) + abi.encode(uint256 gasLimit) +// The MockRouter parses this to set the gas limit for ccipReceive execution. +// Default (empty extraArgs) is only 200k, which is insufficient for storage-heavy operations. +function encodeExtraArgsV1(gasLimit: bigint): `0x${string}` { + const tag = "0x97a657c9" as `0x${string}`; + const encoded = encodeAbiParameters([{ type: "uint256" }], [gasLimit]); + return concat([tag, encoded]); +} + +void describe("Integration — LocalSimulator", async function () { + const { viem } = await network.connect(); + const publicClient = await viem.getPublicClient(); + const walletClients = await viem.getWalletClients(); + const owner = walletClients[0]!; + + // Deploy LocalSimulator and get configuration + const simulator = await viem.deployContract("LocalSimulator"); + const config = await simulator.read.configuration!(); + const chainSelector = (config as [bigint, ...unknown[]])[0]; + // Source and destination router are the same in local simulator + const routerAddress = (config as [bigint, string])[1] as `0x${string}`; + const ccipBnMAddress = ( + config as [bigint, string, string, string, string, string] + )[5] as `0x${string}`; + + // Sufficient gas for receiver execution (covers storage writes in inbox, try/catch, etc.) + const extraArgs = encodeExtraArgsV1(500_000n); + + // ERC20 ABI for token interactions + const erc20Abi = parseAbi([ + "function approve(address spender, uint256 amount) returns (bool)", + "function balanceOf(address account) view returns (uint256)", + "function drip(address to) external", + ]); + + void it("Should send a data-only message end-to-end", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + + // Register peer and allowlist + await sender.write.setPeer!([chainSelector, receiver.address]); + await receiver.write.allowlistSender!([chainSelector, sender.address, true]); + + // Send data-only message (no tokens, native fee) + const testData = encodeAbiParameters([{ type: "string" }], ["Hello CCIP"]); + + const hash = await sender.write.send!( + [chainSelector, receiver.address, testData, [], extraArgs, zeroAddress], + { value: 1000000000000000000n } + ); + const receipt = await publicClient.waitForTransactionReceipt({ hash }); + assert.equal(receipt.status, "success"); + + // Verify inbox has the message + const inboxLength = await receiver.read.getInboxLength!(); + assert.equal(inboxLength, 1n); + + // Verify DataReceived event + const dataEvents = await publicClient.getContractEvents({ + address: receiver.address, + abi: receiver.abi, + eventName: "DataReceived", + fromBlock: receipt.blockNumber, + strict: true, + }); + assert.equal(dataEvents.length, 1); + assert.equal( + (dataEvents[0]!.args as { sender: string }).sender.toLowerCase(), + sender.address.toLowerCase() + ); + }); + + void it("Should send a token-only transfer end-to-end", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + + await sender.write.setPeer!([chainSelector, receiver.address]); + await receiver.write.allowlistSender!([chainSelector, sender.address, true]); + + // Drip tokens to the owner + await owner.writeContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "drip", + args: [owner.account.address], + }); + + const amount = 500000000000000000n; // 0.5 tokens + + // Approve sender contract to pull tokens + await owner.writeContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "approve", + args: [sender.address, amount], + }); + + // Send token-only transfer with extraArgs for receiver execution gas. + // Explicit gas limit avoids auto-estimation inflation from CallWithExactGas in MockRouter. + const hash = await sender.write.send!( + [ + chainSelector, + receiver.address, + "0x", + [{ token: ccipBnMAddress, amount }], + extraArgs, + zeroAddress, + ], + { value: 1000000000000000000n, gas: 2_000_000n } + ); + const receipt = await publicClient.waitForTransactionReceipt({ hash }); + assert.equal(receipt.status, "success"); + + // Verify TokensReceived event on receiver + const tokenEvents = await publicClient.getContractEvents({ + address: receiver.address, + abi: receiver.abi, + eventName: "TokensReceived", + fromBlock: receipt.blockNumber, + strict: true, + }); + assert.equal(tokenEvents.length, 1); + }); + + void it("Should send a programmable token transfer (PTT) end-to-end", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + + await sender.write.setPeer!([chainSelector, receiver.address]); + await receiver.write.allowlistSender!([chainSelector, sender.address, true]); + + // Drip tokens + await owner.writeContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "drip", + args: [owner.account.address], + }); + + const amount = 500000000000000000n; + // Use a different address as recipient to isolate the balance change + const recipient = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" as `0x${string}`; + + // Approve + await owner.writeContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "approve", + args: [sender.address, amount], + }); + + // Encode recipient address as data payload (PTT pattern) + const data = encodeAbiParameters([{ type: "address" }], [recipient]); + + const balanceBefore = await publicClient.readContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "balanceOf", + args: [recipient], + }); + + const hash = await sender.write.send!( + [ + chainSelector, + receiver.address, + data, + [{ token: ccipBnMAddress, amount }], + extraArgs, + zeroAddress, + ], + { value: 1000000000000000000n, gas: 2_000_000n } + ); + const receipt = await publicClient.waitForTransactionReceipt({ hash }); + assert.equal(receipt.status, "success"); + + // Verify tokens forwarded to recipient + const balanceAfter = await publicClient.readContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "balanceOf", + args: [recipient], + }); + assert.equal(balanceAfter - balanceBefore, amount); + + // Verify TokensForwarded event + const fwdEvents = await publicClient.getContractEvents({ + address: receiver.address, + abi: receiver.abi, + eventName: "TokensForwarded", + fromBlock: receipt.blockNumber, + strict: true, + }); + assert.equal(fwdEvents.length, 1); + assert.equal( + (fwdEvents[0]!.args as { recipient: string }).recipient.toLowerCase(), + recipient.toLowerCase() + ); + }); + + void it("Should batch allowlist multiple senders via updateAllowlist", async function () { + const sender1 = await viem.deployContract("CCIPSender", [routerAddress]); + const sender2 = await viem.deployContract("CCIPSender", [routerAddress]); + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + + // Register peers on both senders + await sender1.write.setPeer!([chainSelector, receiver.address]); + await sender2.write.setPeer!([chainSelector, receiver.address]); + + // Batch allowlist both senders + await receiver.write.updateAllowlist!([ + [ + { sourceChainSelector: chainSelector, sender: sender1.address, allowed: true }, + { sourceChainSelector: chainSelector, sender: sender2.address, allowed: true }, + ], + ]); + + // Verify both can send data-only messages + const testData = encodeAbiParameters([{ type: "string" }], ["test"]); + + const hash1 = await sender1.write.send!( + [chainSelector, receiver.address, testData, [], extraArgs, zeroAddress], + { value: 1000000000000000000n } + ); + const receipt1 = await publicClient.waitForTransactionReceipt({ hash: hash1 }); + assert.equal(receipt1.status, "success"); + + const hash2 = await sender2.write.send!( + [chainSelector, receiver.address, testData, [], extraArgs, zeroAddress], + { value: 1000000000000000000n } + ); + const receipt2 = await publicClient.waitForTransactionReceipt({ hash: hash2 }); + assert.equal(receipt2.status, "success"); + + // Both messages in inbox + const inboxLength = await receiver.read.getInboxLength!(); + assert.equal(inboxLength, 2n); + }); + + void it("Should handle failed message via defensive try/catch (PTT with address(0))", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + + await sender.write.setPeer!([chainSelector, receiver.address]); + await receiver.write.allowlistSender!([chainSelector, sender.address, true]); + + // Drip tokens + await owner.writeContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "drip", + args: [owner.account.address], + }); + + const amount = 500000000000000000n; + await owner.writeContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "approve", + args: [sender.address, amount], + }); + + // PTT with address(0) as recipient — processMessage will revert with InvalidRecipient + const badData = encodeAbiParameters([{ type: "address" }], [zeroAddress]); + + const hash = await sender.write.send!( + [ + chainSelector, + receiver.address, + badData, + [{ token: ccipBnMAddress, amount }], + extraArgs, + zeroAddress, + ], + { value: 1000000000000000000n, gas: 2_000_000n } + ); + const receipt = await publicClient.waitForTransactionReceipt({ hash }); + assert.equal(receipt.status, "success"); // tx succeeds — try/catch caught the error + + // Verify MessageFailed event was emitted + const failEvents = await publicClient.getContractEvents({ + address: receiver.address, + abi: receiver.abi, + eventName: "MessageFailed", + fromBlock: receipt.blockNumber, + strict: true, + }); + assert.equal(failEvents.length, 1); + + // Tokens should remain in the receiver contract (not forwarded) + const receiverBalance = await publicClient.readContract({ + address: ccipBnMAddress, + abi: erc20Abi, + functionName: "balanceOf", + args: [receiver.address], + }); + assert.equal(receiverBalance, amount); + }); + + void it("Should revert when sender is not allowlisted", async function () { + const sender = await viem.deployContract("CCIPSender", [routerAddress]); + const receiver = await viem.deployContract("CCIPReceiverExample", [routerAddress]); + + // Register peer but do NOT allowlist + await sender.write.setPeer!([chainSelector, receiver.address]); + + const testData = encodeAbiParameters([{ type: "string" }], ["test"]); + + // Should revert — MockRouter wraps receiver errors in ReceiverError + await assert.rejects( + sender.write.send!([chainSelector, receiver.address, testData, [], extraArgs, zeroAddress], { + value: 1000000000000000000n, + }), + (err: Error) => { + assert.ok(err.message.includes("ReceiverError")); + return true; + } + ); + }); +}); diff --git a/examples/04-hardhat-ccip/tsconfig.json b/examples/04-hardhat-ccip/tsconfig.json index 203cd7d..534693d 100644 --- a/examples/04-hardhat-ccip/tsconfig.json +++ b/examples/04-hardhat-ccip/tsconfig.json @@ -5,6 +5,6 @@ "rootDir": ".", "noEmit": true }, - "include": ["hardhat.config.ts", "tasks/**/*", "helpers/**/*"], + "include": ["hardhat.config.ts", "tasks/**/*", "helpers/**/*", "test/**/*"], "exclude": ["node_modules", "dist", "artifacts", "cache"] } diff --git a/packages/shared-brand/package.json b/packages/shared-brand/package.json index ba83e4c..a88c771 100644 --- a/packages/shared-brand/package.json +++ b/packages/shared-brand/package.json @@ -1,6 +1,9 @@ { "name": "@ccip-examples/shared-brand", "version": "1.0.0", + "engines": { + "node": ">=22.0.0" + }, "description": "Shared brand assets and design tokens for CCIP SDK examples", "type": "module", "exports": { diff --git a/packages/shared-components/package.json b/packages/shared-components/package.json index 7b9fd33..48ea8fc 100644 --- a/packages/shared-components/package.json +++ b/packages/shared-components/package.json @@ -1,6 +1,9 @@ { "name": "@ccip-examples/shared-components", "version": "1.0.0", + "engines": { + "node": ">=22.0.0" + }, "description": "Shared UI components for CCIP SDK examples", "type": "module", "main": "./dist/index.js", @@ -44,7 +47,7 @@ "peerDependencies": { "react": ">=18.0.0", "react-dom": ">=18.0.0", - "@chainlink/ccip-sdk": "1.2.0" + "@chainlink/ccip-sdk": "1.3.1" }, "devDependencies": { "@types/react": "^18.3.12", @@ -52,7 +55,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "typescript": "^5.9.3", - "@chainlink/ccip-sdk": "1.2.0" + "@chainlink/ccip-sdk": "1.3.1" }, "keywords": [ "ccip", diff --git a/packages/shared-config/package.json b/packages/shared-config/package.json index f847738..d38afdf 100644 --- a/packages/shared-config/package.json +++ b/packages/shared-config/package.json @@ -1,6 +1,9 @@ { "name": "@ccip-examples/shared-config", "version": "1.0.0", + "engines": { + "node": ">=22.0.0" + }, "description": "Shared network and token configuration for CCIP SDK examples", "type": "module", "main": "./dist/index.js", @@ -39,7 +42,7 @@ "clean": "rm -rf dist" }, "devDependencies": { - "@chainlink/ccip-sdk": "1.2.0", + "@chainlink/ccip-sdk": "1.3.1", "@rainbow-me/rainbowkit": "^2.2.10", "@tanstack/react-query": "^5.62.0", "typescript": "^5.9.3", @@ -53,7 +56,7 @@ "tokens" ], "peerDependencies": { - "@chainlink/ccip-sdk": "1.2.0", + "@chainlink/ccip-sdk": "1.3.1", "@rainbow-me/rainbowkit": ">=2.2.0", "@tanstack/react-query": ">=5.0.0", "viem": ">=2.21.0", diff --git a/packages/shared-utils/package.json b/packages/shared-utils/package.json index 2ec6cd6..de5cea3 100644 --- a/packages/shared-utils/package.json +++ b/packages/shared-utils/package.json @@ -1,6 +1,9 @@ { "name": "@ccip-examples/shared-utils", "version": "1.0.0", + "engines": { + "node": ">=22.0.0" + }, "description": "Shared utilities for CCIP SDK examples", "type": "module", "main": "./dist/index.js", @@ -74,7 +77,7 @@ }, "devDependencies": { "typescript": "^5.9.3", - "@chainlink/ccip-sdk": "1.2.0" + "@chainlink/ccip-sdk": "1.3.1" }, "keywords": [ "ccip", @@ -84,6 +87,6 @@ ], "peerDependencies": { "react": ">=18.0.0", - "@chainlink/ccip-sdk": "1.2.0" + "@chainlink/ccip-sdk": "1.3.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5742fa4..01ae6bb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,8 +50,8 @@ importers: specifier: workspace:* version: link:../../packages/shared-utils "@chainlink/ccip-sdk": - specifier: 1.2.0 - version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + specifier: 1.3.1 + version: 1.3.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) "@coral-xyz/anchor": specifier: ^0.30.1 version: 0.30.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) @@ -96,8 +96,8 @@ importers: specifier: workspace:* version: link:../../packages/shared-utils "@chainlink/ccip-sdk": - specifier: 1.2.0 - version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + specifier: 1.3.1 + version: 1.3.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) "@rainbow-me/rainbowkit": specifier: ^2.2.10 version: 2.2.10(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.19.5(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)) @@ -163,8 +163,8 @@ importers: specifier: workspace:* version: link:../../packages/shared-utils "@chainlink/ccip-sdk": - specifier: 1.2.0 - version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + specifier: 1.3.1 + version: 1.3.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) "@rainbow-me/rainbowkit": specifier: ^2.2.10 version: 2.2.10(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) @@ -233,14 +233,14 @@ importers: specifier: workspace:* version: link:../../packages/shared-utils "@chainlink/ccip-sdk": - specifier: 1.2.0 - version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + specifier: 1.3.1 + version: 1.3.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) "@chainlink/contracts-ccip": - specifier: ^1.6.4 + specifier: 1.6.4 version: 1.6.4(@types/node@22.19.11)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) "@openzeppelin/contracts": - specifier: ^5.1.0 - version: 5.6.1 + specifier: 5.1.0 + version: 5.1.0 dotenv: specifier: ^16.4.5 version: 16.6.1 @@ -248,6 +248,15 @@ importers: specifier: ^2.21.0 version: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) devDependencies: + "@chainlink/local": + specifier: 0.2.7 + version: 0.2.7(@types/node@22.19.11)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + "@nomicfoundation/hardhat-node-test-runner": + specifier: ^3.0.0 + version: 3.0.11(hardhat@3.1.12(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@nomicfoundation/hardhat-viem": + specifier: ^3.0.4 + version: 3.0.4(hardhat@3.1.12(bufferutil@4.1.0)(utf-8-validate@5.0.10))(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) hardhat: specifier: ^3.0.0 version: 3.1.12(bufferutil@4.1.0)(utf-8-validate@5.0.10) @@ -280,8 +289,8 @@ importers: version: link:../shared-utils devDependencies: "@chainlink/ccip-sdk": - specifier: 1.2.0 - version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + specifier: 1.3.1 + version: 1.3.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) "@types/react": specifier: ^18.3.12 version: 18.3.28 @@ -301,8 +310,8 @@ importers: packages/shared-config: devDependencies: "@chainlink/ccip-sdk": - specifier: 1.2.0 - version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + specifier: 1.3.1 + version: 1.3.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) "@rainbow-me/rainbowkit": specifier: ^2.2.10 version: 2.2.10(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) @@ -347,8 +356,8 @@ importers: version: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) devDependencies: "@chainlink/ccip-sdk": - specifier: 1.2.0 - version: 1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + specifier: 1.3.1 + version: 1.3.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) typescript: specifier: ^5.9.3 version: 5.9.3 @@ -374,6 +383,30 @@ packages: graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 typescript: ^5.0.0 + "@actions/core@1.11.1": + resolution: + { + integrity: sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==, + } + + "@actions/exec@1.1.1": + resolution: + { + integrity: sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==, + } + + "@actions/http-client@2.2.3": + resolution: + { + integrity: sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==, + } + + "@actions/io@1.1.3": + resolution: + { + integrity: sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==, + } + "@adraffy/ens-normalize@1.10.1": resolution: { @@ -819,10 +852,10 @@ packages: integrity: sha512-A4Umpi8B9/pqR78D1Yoze4xHyQaujioVRqqO3d6xuDFw9VRtjg6tK3bPlwE0aW+nVH/ntllCpPa2PbI8Rnjcug==, } - "@chainlink/ccip-sdk@1.2.0": + "@chainlink/ccip-sdk@1.3.1": resolution: { - integrity: sha512-XFrNxIXdaEYQqyOQWuxms/QJqA+tJX67EFebI7MPYeBWQMHNnMrVB6pF1yVP9eFk4yisN4+DyZ128rcN4gWfTQ==, + integrity: sha512-bklap2InR527XTXOXRrINfYB87cTEIeZDlrFUuwP2FUhbMP/djhMfhQoZ10nJ4eHnkeEUrxipC8KMHmb+aBoNw==, } peerDependencies: viem: ^2.0.0 @@ -830,6 +863,13 @@ packages: viem: optional: true + "@chainlink/contracts-ccip@1.6.2": + resolution: + { + integrity: sha512-dHAOxhpTo9Dp1S5wFeSEN3hV9t2gy7iCXNdnZxmskD+gRVb7qGpTqoXPXXu8qEf2zVmRsrs/nSbrTU/UpqfHQg==, + } + engines: { node: ">=20", pnpm: ">=10" } + "@chainlink/contracts-ccip@1.6.4": resolution: { @@ -844,6 +884,12 @@ packages: } engines: { node: ">=22", pnpm: ">=10" } + "@chainlink/local@0.2.7": + resolution: + { + integrity: sha512-tdsRQEkiZE5nHv35bRcMKSIvIkNl0SV7hQV4wPpimTgIDqe60YH4NAC/j21k7f+ief/oUpyi+gNacvxZBPN9sw==, + } + "@chainlink/solhint-plugin-chainlink-solidity@https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c": resolution: { @@ -1811,6 +1857,13 @@ packages: integrity: sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==, } + "@fastify/busboy@2.1.1": + resolution: + { + integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==, + } + engines: { node: ">=14" } + "@fivebinaries/coin-selection@3.0.0": resolution: { @@ -2562,6 +2615,20 @@ packages: integrity: sha512-gHAZDYb0e5joq+WecgC3ciz5OcgqUBgK2zLQmNoKSn/I52h3SH1stxXsY4dcVsj0OY4ZksqIRhJDKskHC5DvTA==, } + "@nomicfoundation/hardhat-node-test-reporter@3.0.2": + resolution: + { + integrity: sha512-lbbOVOVxHY+x3olztf8m19nuxpkx/6zN8dmGlbb1CA0V3QvN8EyQWl8O6xtxmTQhLTPKUGwA2r02ikE5Qa02dw==, + } + + "@nomicfoundation/hardhat-node-test-runner@3.0.11": + resolution: + { + integrity: sha512-agkepXlHGbMiTHqrbL/4aIaezlUhV2xf+Od7HmbRyp31Ppqit/GWIbaE45jx5w5/eNXhA5IKjEghYCwzIZb8AA==, + } + peerDependencies: + hardhat: ^3.1.12 + "@nomicfoundation/hardhat-utils@4.0.1": resolution: { @@ -2574,6 +2641,15 @@ packages: integrity: sha512-jBOAqmEAMJ8zdfiQmTLV+c0IaSyySqkDSJ9spTy8Ts/m/mO8w364TClyfn+p4ZpxBjyX4LMa3NfC402hoDtwCg==, } + "@nomicfoundation/hardhat-viem@3.0.4": + resolution: + { + integrity: sha512-zauCnEMOgy8+nijwVOAQr7piGYsWtUFb0i2snaBF4e7TJWbcXbyJL3wGBplo3h0D9UOYYmLDE7DWTxuqZjEsZA==, + } + peerDependencies: + hardhat: ^3.1.11 + viem: ^2.43.0 + "@nomicfoundation/hardhat-zod-utils@3.0.3": resolution: { @@ -2686,12 +2762,6 @@ packages: integrity: sha512-p1ULhl7BXzjjbha5aqst+QMLY+4/LCWADXOCsmLHRM77AqiPjnd9vvUN9sosUfhL9JGKpZ0TjEGxgvnizmWGSA==, } - "@openzeppelin/contracts@5.6.1": - resolution: - { - integrity: sha512-Ly6SlsVJ3mj+b18W3R8gNufB7dTICT105fJhodGAGgyC2oqnBAhqSiNDJ8V8DLY05cCz81GLI0CU5vNYA1EC/w==, - } - "@particle-network/analytics@1.0.2": resolution: { @@ -7444,6 +7514,13 @@ packages: integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==, } + diff-sequences@29.6.3: + resolution: + { + integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + diffie-hellman@5.0.3: resolution: { @@ -8978,6 +9055,13 @@ packages: engines: { node: ">=8" } hasBin: true + jest-diff@29.7.0: + resolution: + { + integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + jest-environment-node@29.7.0: resolution: { @@ -11857,6 +11941,13 @@ packages: integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==, } + tunnel@0.0.6: + resolution: + { + integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==, + } + engines: { node: ">=0.6.11 <=0.7.0 || >=0.7.3" } + tweetnacl-util@0.15.1: resolution: { @@ -11897,10 +11988,10 @@ packages: } engines: { node: ">=8" } - type-fest@5.4.4: + type-fest@5.5.0: resolution: { - integrity: sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==, + integrity: sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==, } engines: { node: ">=20" } @@ -11998,6 +12089,13 @@ packages: integrity: sha512-w9IMgQrz4O0YN1LtB7K5P63vhlIOvC7opSmouCJ+ZywlPAlO9gIkJ+otk6LvGpAs2wg4econaCz3TvQ9xPoyuQ==, } + undici@5.29.0: + resolution: + { + integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==, + } + engines: { node: ">=14.0" } + undici@6.24.0: resolution: { @@ -12746,6 +12844,22 @@ snapshots: graphql: 16.12.0 typescript: 5.9.3 + "@actions/core@1.11.1": + dependencies: + "@actions/exec": 1.1.1 + "@actions/http-client": 2.2.3 + + "@actions/exec@1.1.1": + dependencies: + "@actions/io": 1.1.3 + + "@actions/http-client@2.2.3": + dependencies: + tunnel: 0.0.6 + undici: 5.29.0 + + "@actions/io@1.1.3": {} + "@adraffy/ens-normalize@1.10.1": {} "@adraffy/ens-normalize@1.11.1": {} @@ -13184,7 +13298,7 @@ snapshots: - utf-8-validate - zod - "@chainlink/ccip-sdk@1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)": + "@chainlink/ccip-sdk@1.3.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)": dependencies: "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) "@coral-xyz/anchor": 0.29.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) @@ -13203,7 +13317,7 @@ snapshots: ethers: 6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) got: 11.8.6 micro-memoize: 5.1.1 - type-fest: 5.4.4 + type-fest: 5.5.0 yaml: 2.8.2 optionalDependencies: viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -13218,7 +13332,7 @@ snapshots: - utf-8-validate - zod - "@chainlink/ccip-sdk@1.2.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)": + "@chainlink/ccip-sdk@1.3.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)": dependencies: "@aptos-labs/ts-sdk": 5.2.1(got@11.8.6) "@coral-xyz/anchor": 0.29.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) @@ -13237,7 +13351,7 @@ snapshots: ethers: 6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) got: 11.8.6 micro-memoize: 5.1.1 - type-fest: 5.4.4 + type-fest: 5.5.0 yaml: 2.8.2 optionalDependencies: viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) @@ -13252,6 +13366,22 @@ snapshots: - utf-8-validate - zod + "@chainlink/contracts-ccip@1.6.2(@types/node@22.19.11)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)": + dependencies: + "@chainlink/contracts": 1.5.0(@types/node@22.19.11)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + "@changesets/cli": 2.30.0(@types/node@22.19.11) + "@changesets/get-github-info": 0.6.0 + "@openzeppelin/contracts-4.8.3": "@openzeppelin/contracts@4.8.3" + "@openzeppelin/contracts-5.0.2": "@openzeppelin/contracts@5.0.2" + semver: 7.7.4 + transitivePeerDependencies: + - "@types/node" + - bufferutil + - encoding + - ethers + - supports-color + - utf-8-validate + "@chainlink/contracts-ccip@1.6.4(@types/node@22.19.11)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)": dependencies: "@chainlink/contracts": 1.5.0(@types/node@22.19.11)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) @@ -13292,6 +13422,18 @@ snapshots: - supports-color - utf-8-validate + "@chainlink/local@0.2.7(@types/node@22.19.11)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)": + dependencies: + "@chainlink/contracts": 1.5.0(@types/node@22.19.11)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + "@chainlink/contracts-ccip": 1.6.2(@types/node@22.19.11)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + transitivePeerDependencies: + - "@types/node" + - bufferutil + - encoding + - ethers + - supports-color + - utf-8-validate + "@chainlink/solhint-plugin-chainlink-solidity@https://codeload.github.com/smartcontractkit/chainlink-solhint-rules/tar.gz/1b4c0c2663fcd983589d4f33a2e73908624ed43c": {} @@ -14051,6 +14193,8 @@ snapshots: "@ethersproject/properties": 5.8.0 "@ethersproject/strings": 5.8.0 + "@fastify/busboy@2.1.1": {} + "@fivebinaries/coin-selection@3.0.0": dependencies: "@emurgo/cardano-serialization-lib-browser": 13.2.1 @@ -14693,6 +14837,24 @@ snapshots: transitivePeerDependencies: - supports-color + "@nomicfoundation/hardhat-node-test-reporter@3.0.2": + dependencies: + "@actions/core": 1.11.1 + chalk: 5.6.2 + jest-diff: 29.7.0 + + "@nomicfoundation/hardhat-node-test-runner@3.0.11(hardhat@3.1.12(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + dependencies: + "@nomicfoundation/hardhat-errors": 3.0.8 + "@nomicfoundation/hardhat-node-test-reporter": 3.0.2 + "@nomicfoundation/hardhat-utils": 4.0.1 + "@nomicfoundation/hardhat-zod-utils": 3.0.3(zod@3.25.76) + hardhat: 3.1.12(bufferutil@4.1.0)(utf-8-validate@5.0.10) + tsx: 4.21.0 + zod: 3.25.76 + transitivePeerDependencies: + - supports-color + "@nomicfoundation/hardhat-utils@4.0.1": dependencies: "@streamparser/json-node": 0.0.22 @@ -14708,6 +14870,15 @@ snapshots: "@nomicfoundation/hardhat-vendored@3.0.1": {} + "@nomicfoundation/hardhat-viem@3.0.4(hardhat@3.1.12(bufferutil@4.1.0)(utf-8-validate@5.0.10))(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))": + dependencies: + "@nomicfoundation/hardhat-errors": 3.0.8 + "@nomicfoundation/hardhat-utils": 4.0.1 + hardhat: 3.1.12(bufferutil@4.1.0)(utf-8-validate@5.0.10) + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - supports-color + "@nomicfoundation/hardhat-zod-utils@3.0.3(zod@3.25.76)": dependencies: "@nomicfoundation/hardhat-errors": 3.0.8 @@ -14766,8 +14937,6 @@ snapshots: "@openzeppelin/contracts@5.1.0": {} - "@openzeppelin/contracts@5.6.1": {} - "@particle-network/analytics@1.0.2": dependencies: hash.js: 1.1.7 @@ -20492,6 +20661,8 @@ snapshots: detect-node-es@1.1.0: {} + diff-sequences@29.6.3: {} + diffie-hellman@5.0.3: dependencies: bn.js: 4.12.3 @@ -21459,6 +21630,13 @@ snapshots: - bufferutil - utf-8-validate + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + jest-environment-node@29.7.0: dependencies: "@jest/environment": 29.7.0 @@ -23417,6 +23595,8 @@ snapshots: tty-browserify@0.0.1: {} + tunnel@0.0.6: {} + tweetnacl-util@0.15.1: {} tweetnacl@1.0.3: {} @@ -23431,7 +23611,7 @@ snapshots: type-fest@0.7.1: {} - type-fest@5.4.4: + type-fest@5.5.0: dependencies: tagged-tag: 1.0.0 @@ -23482,6 +23662,10 @@ snapshots: undici-types@7.21.0: {} + undici@5.29.0: + dependencies: + "@fastify/busboy": 2.1.1 + undici@6.24.0: {} unidragger@3.0.1: From dc14d998ca52ffcf16d24c066b0c82f10475ca8a Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Tue, 24 Mar 2026 22:38:31 +0100 Subject: [PATCH 3/6] Rename all internal packages from @ccip-examples/* to @chainlink/ccip-examples-* and mark as private --- README.md | 10 +- docs/LEARNING_PATH.md | 8 +- examples/01-getting-started/README.md | 24 ++-- examples/01-getting-started/package.json | 7 +- .../01-getting-started/src/estimate-fees.ts | 4 +- examples/01-getting-started/src/get-status.ts | 2 +- .../01-getting-started/src/inspect-pools.ts | 4 +- .../01-getting-started/src/list-chains.ts | 2 +- .../src/supported-tokens.ts | 4 +- .../01-getting-started/src/transfer-tokens.ts | 6 +- examples/02-evm-simple-bridge/README.md | 6 +- examples/02-evm-simple-bridge/package.json | 11 +- examples/02-evm-simple-bridge/src/App.tsx | 14 +-- .../src/components/bridge/BridgeForm.tsx | 16 ++- .../src/components/bridge/WalletConnect.tsx | 2 +- .../src/components/bridge/index.ts | 2 +- .../src/components/layout/Footer.tsx | 2 +- .../src/components/layout/index.ts | 2 +- .../02-evm-simple-bridge/src/config/index.ts | 2 +- .../02-evm-simple-bridge/src/hooks/index.ts | 11 +- .../src/hooks/useGetChain.ts | 4 +- .../src/hooks/useTransfer.ts | 10 +- examples/03-multichain-bridge-dapp/README.md | 4 +- .../03-multichain-bridge-dapp/package.json | 11 +- .../03-multichain-bridge-dapp/src/App.tsx | 22 ++-- .../src/components/bridge/BridgeForm.tsx | 14 +-- .../src/components/bridge/PoolInfo.tsx | 2 +- .../components/bridge/RateLimitDisplay.tsx | 2 +- .../src/components/bridge/WalletConnect.tsx | 4 +- .../transaction/TransactionHistoryItem.tsx | 8 +- .../transaction/TransactionStatusView.tsx | 16 ++- .../transaction/TransferBalances.tsx | 4 +- .../transaction/TransferRateLimits.tsx | 2 +- .../src/hooks/ChainContext.tsx | 10 +- .../src/hooks/index.ts | 15 ++- .../src/hooks/useAptosTransfer.ts | 2 +- .../src/hooks/useDestinationBalance.ts | 2 +- .../src/hooks/useEVMTransfer.ts | 4 +- .../src/hooks/useSolanaTransfer.ts | 4 +- .../src/hooks/useTokenPoolInfo.ts | 4 +- .../src/hooks/useTransactionExecution.ts | 2 +- .../src/hooks/useTransfer.ts | 8 +- .../src/hooks/useTransferBalances.ts | 2 +- .../src/hooks/useTransferRateLimits.ts | 6 +- .../src/inspector/annotations.ts | 2 +- .../src/inspector/index.ts | 6 +- examples/04-hardhat-ccip/hardhat.config.ts | 2 +- examples/04-hardhat-ccip/helpers/sdk.ts | 2 +- examples/04-hardhat-ccip/package.json | 7 +- .../04-hardhat-ccip/tasks/check-status.ts | 2 +- .../04-hardhat-ccip/tasks/deploy-receiver.ts | 2 +- .../04-hardhat-ccip/tasks/deploy-sender.ts | 2 +- .../04-hardhat-ccip/tasks/list-messages.ts | 2 +- .../04-hardhat-ccip/tasks/manage-allowlist.ts | 2 +- .../04-hardhat-ccip/tasks/manual-execute.ts | 2 +- .../04-hardhat-ccip/tasks/pause-contract.ts | 2 +- .../04-hardhat-ccip/tasks/send-via-router.ts | 4 +- .../04-hardhat-ccip/tasks/send-via-sender.ts | 4 +- .../04-hardhat-ccip/tasks/withdraw-funds.ts | 2 +- packages/shared-brand/README.md | 22 ++-- packages/shared-brand/package.json | 3 +- packages/shared-brand/src/design-tokens.css | 4 +- packages/shared-brand/src/index.ts | 2 +- packages/shared-components/package.json | 9 +- .../src/FeeEstimateDisplay.tsx | 4 +- .../shared-components/src/FeeTokenOptions.tsx | 2 +- .../src/bridge/MessageProgress.tsx | 4 +- .../src/bridge/TransferStatus.tsx | 2 +- .../shared-components/src/bridge/index.ts | 2 +- .../src/inspector/CallEntry.tsx | 2 +- .../src/inspector/CodeSnippet.tsx | 2 +- .../src/inspector/PhaseGroup.tsx | 2 +- .../src/inspector/SDKInspectorPanel.tsx | 2 +- .../src/inspector/SDKInspectorToggle.tsx | 5 +- .../src/primitives/ErrorMessage.tsx | 4 +- .../shared-components/src/styles/globals.css | 2 +- packages/shared-config/package.json | 3 +- packages/shared-config/src/index.ts | 2 +- packages/shared-config/src/queryClient.ts | 2 +- packages/shared-config/src/wagmi.ts | 2 +- packages/shared-utils/package.json | 5 +- packages/shared-utils/src/ccipErrors.ts | 2 +- packages/shared-utils/src/hooks/index.ts | 2 +- .../shared-utils/src/hooks/useFeeTokens.ts | 2 +- .../src/hooks/useMessageStatus.ts | 2 +- .../src/hooks/useWalletBalances.ts | 2 +- packages/shared-utils/src/index.ts | 4 +- packages/shared-utils/src/viem.ts | 2 +- pnpm-lock.yaml | 110 +++++++++--------- 89 files changed, 299 insertions(+), 258 deletions(-) diff --git a/README.md b/README.md index db30bdf..f25648b 100644 --- a/README.md +++ b/README.md @@ -70,22 +70,22 @@ ccip-sdk-examples/ ## Shared packages -### @ccip-examples/shared-config +### @chainlink/ccip-examples-shared-config Network and token config; wagmi config and query client; constants (status labels, polling, explorer URLs). RPC URLs come from `getRpcUrl(networkId)` (env vars `RPC_` or public fallbacks). - **Exports:** `NETWORKS`, `NETWORK_IDS`, `getNetwork`, `getEVMNetworks`, `getSolanaNetworks`, `getAptosNetworks`, `getAllNetworks`, `getChainIdForNetwork`, `getExplorerTxUrl`, `getExplorerAddressUrl`; `getTokenAddress`, `resolveFeeTokenAddress`, `TOKEN_ADDRESSES`, etc.; `ChainFamily`; `POLLING_CONFIG`, `getStatusDescription`, `getFaucetUrl`, `getDummyReceiver`, etc. - **Subpaths:** `./wagmi`, `./queryClient`, `./networks`, `./tokens`. -### @ccip-examples/shared-utils +### @chainlink/ccip-examples-shared-utils -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`. +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`. - **Subpaths:** `./hooks` (e.g. `useMessageStatus`, `useCopyToClipboard`). -### @ccip-examples/shared-components +### @chainlink/ccip-examples-shared-components -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. +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. - **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. - **BalancesList:** Displays multiple token balances with loading skeletons. diff --git a/docs/LEARNING_PATH.md b/docs/LEARNING_PATH.md index a4a1e70..2cac71e 100644 --- a/docs/LEARNING_PATH.md +++ b/docs/LEARNING_PATH.md @@ -9,7 +9,7 @@ Progressive examples for using `@chainlink/ccip-sdk` v1.0.0 (testnet only). Each - **Runtime:** Node.js (no browser). - **Purpose:** SDK basics without UI—chain setup, fee estimation, token discovery, pool inspection, cross-chain transfers. - **Scripts:** `pnpm chains`, `pnpm fees`, `pnpm tokens`, `pnpm pools`, `pnpm transfer`, `pnpm status` (see example README). -- **Dependencies:** `@chainlink/ccip-sdk`, `@ccip-examples/shared-config`, `@ccip-examples/shared-utils` (chain factory, validation, message building). +- **Dependencies:** `@chainlink/ccip-sdk`, `@chainlink/ccip-examples-shared-config`, `@chainlink/ccip-examples-shared-utils` (chain factory, validation, message building). ### 02-evm-simple-bridge @@ -19,7 +19,7 @@ Progressive examples for using `@chainlink/ccip-sdk` v1.0.0 (testnet only). Each - **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. - **Balances:** `useWalletBalances` fetches native, LINK, and token balances in parallel; displayed via `BalancesList`. - **Stack:** wagmi, viem, RainbowKit; chain from `getPublicClient` + `fromViemClient(toGenericPublicClient(...))`. -- **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). +- **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). - **RPC:** Optional `.env` with `RPC_` (e.g. `RPC_ETHEREUM_TESTNET_SEPOLIA`) to override public RPC URLs. ### 03-multichain-bridge-dapp @@ -54,8 +54,8 @@ CCIP routing uses **chain selectors** (64-bit identifiers), not wallet chain IDs 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: ```typescript -import { buildTokenTransferMessage } from "@ccip-examples/shared-utils"; -import { resolveFeeTokenAddress } from "@ccip-examples/shared-config"; +import { buildTokenTransferMessage } from "@chainlink/ccip-examples-shared-utils"; +import { resolveFeeTokenAddress } from "@chainlink/ccip-examples-shared-config"; // feeToken: undefined = native currency, address = ERC20 (e.g. LINK) const feeTokenAddress = resolveFeeTokenAddress("link", sourceNetworkId); diff --git a/examples/01-getting-started/README.md b/examples/01-getting-started/README.md index 126720c..9656a91 100644 --- a/examples/01-getting-started/README.md +++ b/examples/01-getting-started/README.md @@ -239,7 +239,7 @@ Message Found! ### Chain (base class) -All scripts use the abstract `Chain` base class. Concrete instances are created via the `createChain(networkId, rpcUrl)` factory from `@ccip-examples/shared-utils`. +All scripts use the abstract `Chain` base class. Concrete instances are created via the `createChain(networkId, rpcUrl)` factory from `@chainlink/ccip-examples-shared-utils`. | Method | Description | | ---------------------------------- | ------------------------------------- | @@ -263,17 +263,17 @@ Used by `get-status.ts` for message lookups. No chain instance needed. ### Shared Utilities -| Function | Package | Description | -| ----------------------------- | ------------------------------ | ------------------------------------------------- | -| `createChain()` | `@ccip-examples/shared-utils` | Family-agnostic chain factory | -| `createWallet()` | `@ccip-examples/shared-utils` | Family-agnostic wallet factory (reads env vars) | -| `createSolanaWallet()` | `@ccip-examples/shared-utils` | Solana wallet from file path, hex, or base58 | -| `createAptosWallet()` | `@ccip-examples/shared-utils` | Aptos wallet from AIP-80 or hex private key | -| `createLogger()` | `@ccip-examples/shared-utils` | Logger with configurable verbosity | -| `buildTokenTransferMessage()` | `@ccip-examples/shared-utils` | Build a `MessageInput` for token transfers | -| `networkInfo()` | `@chainlink/ccip-sdk` | Get chain selector and metadata | -| `resolveFeeTokenAddress()` | `@ccip-examples/shared-config` | Resolve `"native"`/`"link"` to on-chain address | -| `getDummyReceiver()` | `@ccip-examples/shared-config` | Get a format-valid dummy address per chain family | +| Function | Package | Description | +| ----------------------------- | ---------------------------------------- | ------------------------------------------------- | +| `createChain()` | `@chainlink/ccip-examples-shared-utils` | Family-agnostic chain factory | +| `createWallet()` | `@chainlink/ccip-examples-shared-utils` | Family-agnostic wallet factory (reads env vars) | +| `createSolanaWallet()` | `@chainlink/ccip-examples-shared-utils` | Solana wallet from file path, hex, or base58 | +| `createAptosWallet()` | `@chainlink/ccip-examples-shared-utils` | Aptos wallet from AIP-80 or hex private key | +| `createLogger()` | `@chainlink/ccip-examples-shared-utils` | Logger with configurable verbosity | +| `buildTokenTransferMessage()` | `@chainlink/ccip-examples-shared-utils` | Build a `MessageInput` for token transfers | +| `networkInfo()` | `@chainlink/ccip-sdk` | Get chain selector and metadata | +| `resolveFeeTokenAddress()` | `@chainlink/ccip-examples-shared-config` | Resolve `"native"`/`"link"` to on-chain address | +| `getDummyReceiver()` | `@chainlink/ccip-examples-shared-config` | Get a format-valid dummy address per chain family | ## Solana-Specific Notes diff --git a/examples/01-getting-started/package.json b/examples/01-getting-started/package.json index 4708857..634fa01 100644 --- a/examples/01-getting-started/package.json +++ b/examples/01-getting-started/package.json @@ -1,5 +1,6 @@ { - "name": "@ccip-examples/01-getting-started", + "name": "@chainlink/ccip-examples-01-getting-started", + "private": true, "version": "1.0.0", "engines": { "node": ">=22.0.0" @@ -21,8 +22,8 @@ "clean": "rm -rf dist" }, "dependencies": { - "@ccip-examples/shared-config": "workspace:*", - "@ccip-examples/shared-utils": "workspace:*", + "@chainlink/ccip-examples-shared-config": "workspace:*", + "@chainlink/ccip-examples-shared-utils": "workspace:*", "@chainlink/ccip-sdk": "1.3.1", "@coral-xyz/anchor": "^0.30.1", "@solana/web3.js": "^1.98.0", diff --git a/examples/01-getting-started/src/estimate-fees.ts b/examples/01-getting-started/src/estimate-fees.ts index dbcffd9..38beed1 100644 --- a/examples/01-getting-started/src/estimate-fees.ts +++ b/examples/01-getting-started/src/estimate-fees.ts @@ -26,14 +26,14 @@ import { resolveFeeTokenAddress, type FeeTokenOption, type NetworkConfig, -} from "@ccip-examples/shared-config"; +} from "@chainlink/ccip-examples-shared-config"; import { formatAmount, parseAmount, buildTokenTransferMessage, createChain, getErrorMessage, -} from "@ccip-examples/shared-utils"; +} from "@chainlink/ccip-examples-shared-utils"; const DEFAULT_TOKEN = "CCIP-BnM"; const DEFAULT_AMOUNT = "1.0"; diff --git a/examples/01-getting-started/src/get-status.ts b/examples/01-getting-started/src/get-status.ts index 1ecb9af..7af556b 100644 --- a/examples/01-getting-started/src/get-status.ts +++ b/examples/01-getting-started/src/get-status.ts @@ -37,7 +37,7 @@ import { CCIPMessageIdNotFoundError, withRetry, } from "@chainlink/ccip-sdk"; -import { getStatusDescription, POLLING_CONFIG } from "@ccip-examples/shared-config"; +import { getStatusDescription, POLLING_CONFIG } from "@chainlink/ccip-examples-shared-config"; async function main() { const args = process.argv.slice(2); diff --git a/examples/01-getting-started/src/inspect-pools.ts b/examples/01-getting-started/src/inspect-pools.ts index 3a7929c..b25d6ec 100644 --- a/examples/01-getting-started/src/inspect-pools.ts +++ b/examples/01-getting-started/src/inspect-pools.ts @@ -18,8 +18,8 @@ import "dotenv/config"; import type { Chain, RateLimiterState, TokenInfo } from "@chainlink/ccip-sdk"; import { networkInfo, CCIPError, CCIPTokenPoolChainConfigNotFoundError } from "@chainlink/ccip-sdk"; -import { NETWORKS, NETWORK_IDS, getTokenAddress } from "@ccip-examples/shared-config"; -import { formatAmount, createChain } from "@ccip-examples/shared-utils"; +import { NETWORKS, NETWORK_IDS, getTokenAddress } from "@chainlink/ccip-examples-shared-config"; +import { formatAmount, createChain } from "@chainlink/ccip-examples-shared-utils"; /** * Format a rate limiter state for display. diff --git a/examples/01-getting-started/src/list-chains.ts b/examples/01-getting-started/src/list-chains.ts index e39315b..a8a4156 100644 --- a/examples/01-getting-started/src/list-chains.ts +++ b/examples/01-getting-started/src/list-chains.ts @@ -13,7 +13,7 @@ import { type ChainFamily, getAllNetworks, CHAIN_FAMILY_LABELS, -} from "@ccip-examples/shared-config"; +} from "@chainlink/ccip-examples-shared-config"; function main() { console.log("=".repeat(60)); diff --git a/examples/01-getting-started/src/supported-tokens.ts b/examples/01-getting-started/src/supported-tokens.ts index a3f38cc..d321b5f 100644 --- a/examples/01-getting-started/src/supported-tokens.ts +++ b/examples/01-getting-started/src/supported-tokens.ts @@ -16,8 +16,8 @@ import "dotenv/config"; import { Command } from "commander"; import { networkInfo, CCIPError, CCIPTokenPoolChainConfigNotFoundError } from "@chainlink/ccip-sdk"; -import { NETWORKS, NETWORK_IDS, CHAIN_FAMILY_LABELS } from "@ccip-examples/shared-config"; -import { formatAmount, createChain } from "@ccip-examples/shared-utils"; +import { NETWORKS, NETWORK_IDS, CHAIN_FAMILY_LABELS } from "@chainlink/ccip-examples-shared-config"; +import { formatAmount, createChain } from "@chainlink/ccip-examples-shared-utils"; function validateChainKey(key: string): string { if (!NETWORK_IDS.includes(key)) { diff --git a/examples/01-getting-started/src/transfer-tokens.ts b/examples/01-getting-started/src/transfer-tokens.ts index e9b1b51..a1e1a4f 100644 --- a/examples/01-getting-started/src/transfer-tokens.ts +++ b/examples/01-getting-started/src/transfer-tokens.ts @@ -32,15 +32,15 @@ import { getDummyReceiver, resolveFeeTokenAddress, type FeeTokenOption, -} from "@ccip-examples/shared-config"; +} from "@chainlink/ccip-examples-shared-config"; import { formatAmount, parseAmount, buildTokenTransferMessage, createChain, createLogger, -} from "@ccip-examples/shared-utils"; -import { createWallet } from "@ccip-examples/shared-utils/wallet"; +} from "@chainlink/ccip-examples-shared-utils"; +import { createWallet } from "@chainlink/ccip-examples-shared-utils/wallet"; const DEFAULT_TOKEN = "CCIP-BnM"; const DEFAULT_AMOUNT = "0.001"; diff --git a/examples/02-evm-simple-bridge/README.md b/examples/02-evm-simple-bridge/README.md index 5bd7370..14b9835 100644 --- a/examples/02-evm-simple-bridge/README.md +++ b/examples/02-evm-simple-bridge/README.md @@ -131,7 +131,7 @@ const walletClient = useWalletClient(); // 2. viem → CCIP SDK (adapters from SDK + shared-utils) import { fromViemClient, viemWallet } from "@chainlink/ccip-sdk/viem"; import { CCIPAPIClient, networkInfo } from "@chainlink/ccip-sdk"; -import { toGenericPublicClient } from "@ccip-examples/shared-utils"; +import { toGenericPublicClient } from "@chainlink/ccip-examples-shared-utils"; // Chain instance for on-chain operations (fee, send) const chain = await fromViemClient(toGenericPublicClient(publicClient)); @@ -298,7 +298,7 @@ src/ └── main.tsx # Entry point ``` -**From shared packages** (via `@ccip-examples/*`): +**From shared packages** (via `@chainlink/ccip-examples-*`): | Import | Package | Purpose | | ------------------------------------------------------- | --------------------- | ------------------------- | @@ -333,7 +333,7 @@ import { buildTokenTransferMessage, toGenericPublicClient, categorizeError, -} from "@ccip-examples/shared-utils"; +} from "@chainlink/ccip-examples-shared-utils"; // Create SDK chain from wagmi's public client const publicClient = getPublicClient(wagmiConfig, { chainId }); diff --git a/examples/02-evm-simple-bridge/package.json b/examples/02-evm-simple-bridge/package.json index ea67d34..e1fc3e3 100644 --- a/examples/02-evm-simple-bridge/package.json +++ b/examples/02-evm-simple-bridge/package.json @@ -1,5 +1,6 @@ { - "name": "@ccip-examples/02-evm-simple-bridge", + "name": "@chainlink/ccip-examples-02-evm-simple-bridge", + "private": true, "version": "1.0.0", "engines": { "node": ">=22.0.0" @@ -17,10 +18,10 @@ }, "dependencies": { "@chainlink/ccip-sdk": "1.3.1", - "@ccip-examples/shared-brand": "workspace:*", - "@ccip-examples/shared-config": "workspace:*", - "@ccip-examples/shared-components": "workspace:*", - "@ccip-examples/shared-utils": "workspace:*", + "@chainlink/ccip-examples-shared-brand": "workspace:*", + "@chainlink/ccip-examples-shared-config": "workspace:*", + "@chainlink/ccip-examples-shared-components": "workspace:*", + "@chainlink/ccip-examples-shared-utils": "workspace:*", "@rainbow-me/rainbowkit": "^2.2.10", "@tanstack/react-query": "^5.62.0", "react": "^18.3.1", diff --git a/examples/02-evm-simple-bridge/src/App.tsx b/examples/02-evm-simple-bridge/src/App.tsx index ad118f3..9a3860a 100644 --- a/examples/02-evm-simple-bridge/src/App.tsx +++ b/examples/02-evm-simple-bridge/src/App.tsx @@ -25,22 +25,22 @@ import { WagmiProvider } from "wagmi"; import { RainbowKitProvider, darkTheme } from "@rainbow-me/rainbowkit"; import { useAccount, useSwitchChain } from "wagmi"; -import { BRAND_COLORS } from "@ccip-examples/shared-brand"; -import { wagmiConfig } from "@ccip-examples/shared-config/wagmi"; -import { createDefaultQueryClient } from "@ccip-examples/shared-config/queryClient"; -import type { FeeTokenOptionItem } from "@ccip-examples/shared-config"; +import { BRAND_COLORS } from "@chainlink/ccip-examples-shared-brand"; +import { wagmiConfig } from "@chainlink/ccip-examples-shared-config/wagmi"; +import { createDefaultQueryClient } from "@chainlink/ccip-examples-shared-config/queryClient"; +import type { FeeTokenOptionItem } from "@chainlink/ccip-examples-shared-config"; import { ErrorBoundary, MessageProgress, TransferStatus, Header, -} from "@ccip-examples/shared-components"; +} from "@chainlink/ccip-examples-shared-components"; import { Footer } from "./components/layout"; import { WalletConnect, BridgeForm } from "./components/bridge"; import { useTransfer } from "./hooks"; -import "@ccip-examples/shared-components/styles/globals.css"; +import "@chainlink/ccip-examples-shared-components/styles/globals.css"; import "@rainbow-me/rainbowkit/styles.css"; -import styles from "@ccip-examples/shared-components/layout/AppLayout.module.css"; +import styles from "@chainlink/ccip-examples-shared-components/layout/AppLayout.module.css"; const queryClient = createDefaultQueryClient(); diff --git a/examples/02-evm-simple-bridge/src/components/bridge/BridgeForm.tsx b/examples/02-evm-simple-bridge/src/components/bridge/BridgeForm.tsx index 313310d..e465cbc 100644 --- a/examples/02-evm-simple-bridge/src/components/bridge/BridgeForm.tsx +++ b/examples/02-evm-simple-bridge/src/components/bridge/BridgeForm.tsx @@ -7,14 +7,18 @@ import { useState, useEffect, useCallback, useMemo } from "react"; import { networkInfo, ChainFamily } from "@chainlink/ccip-sdk"; -import { NETWORKS, getTokenAddress, type FeeTokenOptionItem } from "@ccip-examples/shared-config"; +import { + NETWORKS, + getTokenAddress, + type FeeTokenOptionItem, +} from "@chainlink/ccip-examples-shared-config"; import { isValidEVMAddress, isValidAmount, formatAmountFull, copyToClipboard, COPIED_FEEDBACK_MS, -} from "@ccip-examples/shared-utils"; +} from "@chainlink/ccip-examples-shared-utils"; import { Select, Input, @@ -26,11 +30,11 @@ import { CopyIcon, CheckIcon, type BalanceItem, -} from "@ccip-examples/shared-components"; -import { useWalletBalances, useFeeTokens } from "@ccip-examples/shared-utils/hooks"; +} from "@chainlink/ccip-examples-shared-components"; +import { useWalletBalances, useFeeTokens } from "@chainlink/ccip-examples-shared-utils/hooks"; import { useGetChain } from "../../hooks/useGetChain.js"; -import { NETWORK_TO_CHAIN_ID } from "@ccip-examples/shared-config/wagmi"; -import styles from "@ccip-examples/shared-components/bridge/BridgeForm.module.css"; +import { NETWORK_TO_CHAIN_ID } from "@chainlink/ccip-examples-shared-config/wagmi"; +import styles from "@chainlink/ccip-examples-shared-components/bridge/BridgeForm.module.css"; /** Fixed token symbol for this bridge example */ const TOKEN_SYMBOL = "CCIP-BnM"; diff --git a/examples/02-evm-simple-bridge/src/components/bridge/WalletConnect.tsx b/examples/02-evm-simple-bridge/src/components/bridge/WalletConnect.tsx index a1910b6..9036584 100644 --- a/examples/02-evm-simple-bridge/src/components/bridge/WalletConnect.tsx +++ b/examples/02-evm-simple-bridge/src/components/bridge/WalletConnect.tsx @@ -14,7 +14,7 @@ */ import { ConnectButton } from "@rainbow-me/rainbowkit"; -import styles from "@ccip-examples/shared-components/bridge/WalletConnect.module.css"; +import styles from "@chainlink/ccip-examples-shared-components/bridge/WalletConnect.module.css"; /** * Wallet connection with RainbowKit diff --git a/examples/02-evm-simple-bridge/src/components/bridge/index.ts b/examples/02-evm-simple-bridge/src/components/bridge/index.ts index ae0cda7..50afdc1 100644 --- a/examples/02-evm-simple-bridge/src/components/bridge/index.ts +++ b/examples/02-evm-simple-bridge/src/components/bridge/index.ts @@ -1,5 +1,5 @@ /** - * Bridge components (WalletConnect, BridgeForm). MessageProgress and TransferStatus from @ccip-examples/shared-components. + * Bridge components (WalletConnect, BridgeForm). MessageProgress and TransferStatus from @chainlink/ccip-examples-shared-components. */ export { WalletConnect } from "./WalletConnect"; export { BridgeForm } from "./BridgeForm"; diff --git a/examples/02-evm-simple-bridge/src/components/layout/Footer.tsx b/examples/02-evm-simple-bridge/src/components/layout/Footer.tsx index 45685ac..9c7b38b 100644 --- a/examples/02-evm-simple-bridge/src/components/layout/Footer.tsx +++ b/examples/02-evm-simple-bridge/src/components/layout/Footer.tsx @@ -4,7 +4,7 @@ * Uses centralized URLs from shared-config to avoid duplication. */ -import { EXTERNAL_URLS } from "@ccip-examples/shared-config"; +import { EXTERNAL_URLS } from "@chainlink/ccip-examples-shared-config"; import styles from "./Footer.module.css"; export function Footer() { diff --git a/examples/02-evm-simple-bridge/src/components/layout/index.ts b/examples/02-evm-simple-bridge/src/components/layout/index.ts index cef7d95..c3ecc83 100644 --- a/examples/02-evm-simple-bridge/src/components/layout/index.ts +++ b/examples/02-evm-simple-bridge/src/components/layout/index.ts @@ -1,6 +1,6 @@ /** * Layout components barrel export. - * Header is from @ccip-examples/shared-components. + * Header is from @chainlink/ccip-examples-shared-components. */ export { Footer } from "./Footer"; diff --git a/examples/02-evm-simple-bridge/src/config/index.ts b/examples/02-evm-simple-bridge/src/config/index.ts index 4ec33be..2b4d5d1 100644 --- a/examples/02-evm-simple-bridge/src/config/index.ts +++ b/examples/02-evm-simple-bridge/src/config/index.ts @@ -6,4 +6,4 @@ export { CHAIN_ID_TO_NETWORK, NETWORK_TO_CHAIN_ID, getWagmiChain, -} from "@ccip-examples/shared-config/wagmi"; +} from "@chainlink/ccip-examples-shared-config/wagmi"; diff --git a/examples/02-evm-simple-bridge/src/hooks/index.ts b/examples/02-evm-simple-bridge/src/hooks/index.ts index 39bbf87..0789564 100644 --- a/examples/02-evm-simple-bridge/src/hooks/index.ts +++ b/examples/02-evm-simple-bridge/src/hooks/index.ts @@ -11,12 +11,15 @@ * @see https://wagmi.sh/react/api/hooks */ export { useTransfer } from "./useTransfer.js"; -export type { TransferStatusStatus, TransferState } from "@ccip-examples/shared-utils"; -export { useMessageStatus, type MessageStatusResult } from "@ccip-examples/shared-utils/hooks"; +export type { TransferStatusStatus, TransferState } from "@chainlink/ccip-examples-shared-utils"; +export { + useMessageStatus, + type MessageStatusResult, +} from "@chainlink/ccip-examples-shared-utils/hooks"; export { useGetChain } from "./useGetChain.js"; export { useTokenInfo, type TokenInfo, type UseTokenInfoResult, -} from "@ccip-examples/shared-utils/hooks"; -export type { WalletBalances, BalanceData } from "@ccip-examples/shared-utils/hooks"; +} from "@chainlink/ccip-examples-shared-utils/hooks"; +export type { WalletBalances, BalanceData } from "@chainlink/ccip-examples-shared-utils/hooks"; diff --git a/examples/02-evm-simple-bridge/src/hooks/useGetChain.ts b/examples/02-evm-simple-bridge/src/hooks/useGetChain.ts index 6884c38..10452cc 100644 --- a/examples/02-evm-simple-bridge/src/hooks/useGetChain.ts +++ b/examples/02-evm-simple-bridge/src/hooks/useGetChain.ts @@ -8,8 +8,8 @@ import { useCallback, useRef } from "react"; import { fromViemClient } from "@chainlink/ccip-sdk/viem"; import type { Chain } from "@chainlink/ccip-sdk"; import { getPublicClient } from "wagmi/actions"; -import { toGenericPublicClient } from "@ccip-examples/shared-utils"; -import { wagmiConfig, NETWORK_TO_CHAIN_ID } from "@ccip-examples/shared-config/wagmi"; +import { toGenericPublicClient } from "@chainlink/ccip-examples-shared-utils"; +import { wagmiConfig, NETWORK_TO_CHAIN_ID } from "@chainlink/ccip-examples-shared-config/wagmi"; export function useGetChain(): (networkId: string) => Promise { const chainCacheRef = useRef>(new Map()); diff --git a/examples/02-evm-simple-bridge/src/hooks/useTransfer.ts b/examples/02-evm-simple-bridge/src/hooks/useTransfer.ts index 62de19a..69052ee 100644 --- a/examples/02-evm-simple-bridge/src/hooks/useTransfer.ts +++ b/examples/02-evm-simple-bridge/src/hooks/useTransfer.ts @@ -18,7 +18,11 @@ import { fromViemClient, viemWallet } from "@chainlink/ccip-sdk/viem"; import { networkInfo } from "@chainlink/ccip-sdk"; import type { Chain } from "@chainlink/ccip-sdk"; import { getPublicClient } from "wagmi/actions"; -import { NETWORKS, getTokenAddress, type FeeTokenOptionItem } from "@ccip-examples/shared-config"; +import { + NETWORKS, + getTokenAddress, + type FeeTokenOptionItem, +} from "@chainlink/ccip-examples-shared-config"; import { parseAmount, formatAmount, @@ -27,8 +31,8 @@ import { categorizeError, buildTokenTransferMessage, type TransferState, -} from "@ccip-examples/shared-utils"; -import { wagmiConfig, NETWORK_TO_CHAIN_ID } from "@ccip-examples/shared-config/wagmi"; +} from "@chainlink/ccip-examples-shared-utils"; +import { wagmiConfig, NETWORK_TO_CHAIN_ID } from "@chainlink/ccip-examples-shared-config/wagmi"; const initialState: TransferState = { status: "idle", diff --git a/examples/03-multichain-bridge-dapp/README.md b/examples/03-multichain-bridge-dapp/README.md index c3633b1..0d47a1d 100644 --- a/examples/03-multichain-bridge-dapp/README.md +++ b/examples/03-multichain-bridge-dapp/README.md @@ -25,10 +25,10 @@ Optional: copy `.env.example` to `.env`. Set `RPC_` (e.g. `RPC_ETHER ## Architecture -- **Chains:** `ChainContext` exposes `getChain(networkId)`. Chains are created on demand via the shared `createChain(networkId, rpcUrl)` factory from `@ccip-examples/shared-utils`, which maps chain family to the appropriate SDK constructor (`EVMChain.fromUrl`, `SolanaChain.fromUrl`, `AptosChain.fromUrl`). RPC URLs come from `NETWORKS[networkId].rpcUrl` in shared-config (env override or fallback). +- **Chains:** `ChainContext` exposes `getChain(networkId)`. Chains are created on demand via the shared `createChain(networkId, rpcUrl)` factory from `@chainlink/ccip-examples-shared-utils`, which maps chain family to the appropriate SDK constructor (`EVMChain.fromUrl`, `SolanaChain.fromUrl`, `AptosChain.fromUrl`). RPC URLs come from `NETWORKS[networkId].rpcUrl` in shared-config (env override or fallback). - **Chain family:** `networkInfo(networkId).family` (SDK); no custom chain-type strings. - **Provider order:** ErrorBoundary → QueryClientProvider → WagmiProvider → RainbowKitProvider → ConnectionProvider (Solana) → WalletProvider (Solana) → WalletModalProvider → AptosWalletAdapterProvider → ChainContextProvider → TransactionHistoryProvider → App. -- **Config:** `@ccip-examples/shared-config` (NETWORKS, tokens, wagmi); SDK network IDs only (e.g. `ethereum-testnet-sepolia`, `solana-devnet`, `aptos-testnet`). +- **Config:** `@chainlink/ccip-examples-shared-config` (NETWORKS, tokens, wagmi); SDK network IDs only (e.g. `ethereum-testnet-sepolia`, `solana-devnet`, `aptos-testnet`). ## Data flow diff --git a/examples/03-multichain-bridge-dapp/package.json b/examples/03-multichain-bridge-dapp/package.json index 194a195..097252f 100644 --- a/examples/03-multichain-bridge-dapp/package.json +++ b/examples/03-multichain-bridge-dapp/package.json @@ -1,5 +1,6 @@ { - "name": "@ccip-examples/03-multichain-bridge-dapp", + "name": "@chainlink/ccip-examples-03-multichain-bridge-dapp", + "private": true, "version": "1.0.0", "engines": { "node": ">=22.0.0" @@ -19,10 +20,10 @@ "@aptos-labs/ts-sdk": "^5.2.1", "@aptos-labs/wallet-adapter-react": "^3.7.2", "@chainlink/ccip-sdk": "1.3.1", - "@ccip-examples/shared-brand": "workspace:*", - "@ccip-examples/shared-config": "workspace:*", - "@ccip-examples/shared-components": "workspace:*", - "@ccip-examples/shared-utils": "workspace:*", + "@chainlink/ccip-examples-shared-brand": "workspace:*", + "@chainlink/ccip-examples-shared-config": "workspace:*", + "@chainlink/ccip-examples-shared-components": "workspace:*", + "@chainlink/ccip-examples-shared-utils": "workspace:*", "@rainbow-me/rainbowkit": "^2.2.10", "@solana/wallet-adapter-base": "0.9.23", "@solana/wallet-adapter-react": "0.15.39", diff --git a/examples/03-multichain-bridge-dapp/src/App.tsx b/examples/03-multichain-bridge-dapp/src/App.tsx index a564f4c..73e96f0 100644 --- a/examples/03-multichain-bridge-dapp/src/App.tsx +++ b/examples/03-multichain-bridge-dapp/src/App.tsx @@ -19,15 +19,15 @@ import { useWallet as useAptosWallet } from "@aptos-labs/wallet-adapter-react"; import { Network } from "@aptos-labs/ts-sdk"; import { useAccount, useSwitchChain } from "wagmi"; -import { BRAND_COLORS } from "@ccip-examples/shared-brand"; -import { wagmiConfig } from "@ccip-examples/shared-config/wagmi"; -import { createDefaultQueryClient } from "@ccip-examples/shared-config/queryClient"; -import { NETWORKS, type FeeTokenOptionItem } from "@ccip-examples/shared-config"; +import { BRAND_COLORS } from "@chainlink/ccip-examples-shared-brand"; +import { wagmiConfig } from "@chainlink/ccip-examples-shared-config/wagmi"; +import { createDefaultQueryClient } from "@chainlink/ccip-examples-shared-config/queryClient"; +import { NETWORKS, type FeeTokenOptionItem } from "@chainlink/ccip-examples-shared-config"; import { networkInfo, NetworkType } from "@chainlink/ccip-sdk"; -import { getWalletAddress, type WalletAddresses } from "@ccip-examples/shared-utils"; -import { ErrorBoundary, Header } from "@ccip-examples/shared-components"; -import { SDKInspectorToggle } from "@ccip-examples/shared-components/inspector"; -import { useSDKInspector } from "@ccip-examples/shared-utils/inspector"; +import { getWalletAddress, type WalletAddresses } from "@chainlink/ccip-examples-shared-utils"; +import { ErrorBoundary, Header } from "@chainlink/ccip-examples-shared-components"; +import { SDKInspectorToggle } from "@chainlink/ccip-examples-shared-components/inspector"; +import { useSDKInspector } from "@chainlink/ccip-examples-shared-utils/inspector"; import { ChainContextProvider } from "./hooks/ChainContext.jsx"; import { TransactionHistoryContext } from "./hooks/transactionHistoryTypes.js"; import { TransactionHistoryProvider } from "./hooks/TransactionHistoryContext.jsx"; @@ -36,14 +36,14 @@ import { TransactionStatusView } from "./components/transaction/TransactionStatu import { WalletConnect, BridgeForm } from "./components/bridge/index.js"; import { TransactionHistory } from "./components/transaction/TransactionHistory.js"; import { useTransfer } from "./hooks/useTransfer.js"; -import "@ccip-examples/shared-components/styles/globals.css"; -import styles from "@ccip-examples/shared-components/layout/AppLayout.module.css"; +import "@chainlink/ccip-examples-shared-components/styles/globals.css"; +import styles from "@chainlink/ccip-examples-shared-components/layout/AppLayout.module.css"; import appStyles from "./App.module.css"; import "@rainbow-me/rainbowkit/styles.css"; // Lazy load the inspector panel — zero cost when inspector is disabled const SDKInspectorPanel = lazy(() => - import("@ccip-examples/shared-components/inspector").then((m) => ({ + import("@chainlink/ccip-examples-shared-components/inspector").then((m) => ({ default: m.SDKInspectorPanel, })) ); diff --git a/examples/03-multichain-bridge-dapp/src/components/bridge/BridgeForm.tsx b/examples/03-multichain-bridge-dapp/src/components/bridge/BridgeForm.tsx index 5c6f7ae..a2091dd 100644 --- a/examples/03-multichain-bridge-dapp/src/components/bridge/BridgeForm.tsx +++ b/examples/03-multichain-bridge-dapp/src/components/bridge/BridgeForm.tsx @@ -10,7 +10,7 @@ import { getTokenAddress, CHAIN_FAMILY_LABELS, type FeeTokenOptionItem, -} from "@ccip-examples/shared-config"; +} from "@chainlink/ccip-examples-shared-config"; import { isValidAddress, isValidAmount, @@ -20,7 +20,7 @@ import { getAddressPlaceholder, COPIED_FEEDBACK_MS, type WalletAddresses, -} from "@ccip-examples/shared-utils"; +} from "@chainlink/ccip-examples-shared-utils"; import { Select, Input, @@ -32,15 +32,15 @@ import { CopyIcon, CheckIcon, type BalanceItem, -} from "@ccip-examples/shared-components"; -import { useWalletBalances, useFeeTokens } from "@ccip-examples/shared-utils/hooks"; +} from "@chainlink/ccip-examples-shared-components"; +import { useWalletBalances, useFeeTokens } from "@chainlink/ccip-examples-shared-utils/hooks"; import { inspectorStore } from "../../inspector/index.js"; import { getAnnotation } from "../../inspector/annotations.js"; -import { serializeForDisplay } from "@ccip-examples/shared-utils/inspector"; +import { serializeForDisplay } from "@chainlink/ccip-examples-shared-utils/inspector"; import { PoolInfo } from "./PoolInfo.js"; import { useChains } from "../../hooks/useChains.js"; -import { NETWORK_TO_CHAIN_ID } from "@ccip-examples/shared-config/wagmi"; -import styles from "@ccip-examples/shared-components/bridge/BridgeForm.module.css"; +import { NETWORK_TO_CHAIN_ID } from "@chainlink/ccip-examples-shared-config/wagmi"; +import styles from "@chainlink/ccip-examples-shared-components/bridge/BridgeForm.module.css"; const TOKEN_SYMBOL = "CCIP-BnM"; diff --git a/examples/03-multichain-bridge-dapp/src/components/bridge/PoolInfo.tsx b/examples/03-multichain-bridge-dapp/src/components/bridge/PoolInfo.tsx index 6b2d934..04f0df7 100644 --- a/examples/03-multichain-bridge-dapp/src/components/bridge/PoolInfo.tsx +++ b/examples/03-multichain-bridge-dapp/src/components/bridge/PoolInfo.tsx @@ -6,7 +6,7 @@ import { useState, useEffect } from "react"; import { useTokenPoolInfo, type TokenPoolInfo } from "../../hooks/useTokenPoolInfo.js"; import { RateLimitDisplay } from "./RateLimitDisplay.js"; -import { truncateAddress, copyToClipboard } from "@ccip-examples/shared-utils"; +import { truncateAddress, copyToClipboard } from "@chainlink/ccip-examples-shared-utils"; import styles from "./PoolInfo.module.css"; export type { TokenPoolInfo }; diff --git a/examples/03-multichain-bridge-dapp/src/components/bridge/RateLimitDisplay.tsx b/examples/03-multichain-bridge-dapp/src/components/bridge/RateLimitDisplay.tsx index fab8c1a..ab0d75b 100644 --- a/examples/03-multichain-bridge-dapp/src/components/bridge/RateLimitDisplay.tsx +++ b/examples/03-multichain-bridge-dapp/src/components/bridge/RateLimitDisplay.tsx @@ -2,7 +2,7 @@ * Rate limit visualization (capacity bar + refill rate). */ -import { type RateLimitBucket, formatRateLimitBucket } from "@ccip-examples/shared-utils"; +import { type RateLimitBucket, formatRateLimitBucket } from "@chainlink/ccip-examples-shared-utils"; import styles from "./RateLimitDisplay.module.css"; interface RateLimitDisplayProps { diff --git a/examples/03-multichain-bridge-dapp/src/components/bridge/WalletConnect.tsx b/examples/03-multichain-bridge-dapp/src/components/bridge/WalletConnect.tsx index b912055..6bda3f3 100644 --- a/examples/03-multichain-bridge-dapp/src/components/bridge/WalletConnect.tsx +++ b/examples/03-multichain-bridge-dapp/src/components/bridge/WalletConnect.tsx @@ -10,8 +10,8 @@ import { ConnectButton } from "@rainbow-me/rainbowkit"; import { useWallet as useSolanaWallet } from "@solana/wallet-adapter-react"; import { useWalletModal } from "@solana/wallet-adapter-react-ui"; import { useWallet as useAptosWallet } from "@aptos-labs/wallet-adapter-react"; -import { truncateAddress } from "@ccip-examples/shared-utils"; -import styles from "@ccip-examples/shared-components/bridge/WalletConnect.module.css"; +import { truncateAddress } from "@chainlink/ccip-examples-shared-utils"; +import styles from "@chainlink/ccip-examples-shared-components/bridge/WalletConnect.module.css"; // ── EVM ────────────────────────────────────────────────────────────────────── diff --git a/examples/03-multichain-bridge-dapp/src/components/transaction/TransactionHistoryItem.tsx b/examples/03-multichain-bridge-dapp/src/components/transaction/TransactionHistoryItem.tsx index df50a5d..58e4add 100644 --- a/examples/03-multichain-bridge-dapp/src/components/transaction/TransactionHistoryItem.tsx +++ b/examples/03-multichain-bridge-dapp/src/components/transaction/TransactionHistoryItem.tsx @@ -4,11 +4,11 @@ import type { ReactNode } from "react"; import { getCCIPExplorerUrl } from "@chainlink/ccip-sdk"; -import { getExplorerTxUrl } from "@ccip-examples/shared-config"; -import { truncateAddress } from "@ccip-examples/shared-utils"; -import { formatRelativeTime } from "@ccip-examples/shared-utils"; +import { getExplorerTxUrl } from "@chainlink/ccip-examples-shared-config"; +import { truncateAddress } from "@chainlink/ccip-examples-shared-utils"; +import { formatRelativeTime } from "@chainlink/ccip-examples-shared-utils"; import type { StoredTransaction } from "../../utils/localStorage.js"; -import { NETWORKS } from "@ccip-examples/shared-config"; +import { NETWORKS } from "@chainlink/ccip-examples-shared-config"; import styles from "./TransactionHistoryItem.module.css"; interface TransactionHistoryItemProps { diff --git a/examples/03-multichain-bridge-dapp/src/components/transaction/TransactionStatusView.tsx b/examples/03-multichain-bridge-dapp/src/components/transaction/TransactionStatusView.tsx index 0bcecbb..2ccb2e6 100644 --- a/examples/03-multichain-bridge-dapp/src/components/transaction/TransactionStatusView.tsx +++ b/examples/03-multichain-bridge-dapp/src/components/transaction/TransactionStatusView.tsx @@ -4,14 +4,18 @@ */ import { useCallback } from "react"; -import { getExplorerTxUrl } from "@ccip-examples/shared-config"; -import type { CategorizedError, LastTransferContext } from "@ccip-examples/shared-utils"; -import type { TransferStatusStatus } from "@ccip-examples/shared-utils"; -import { useMessageStatus } from "@ccip-examples/shared-utils/hooks"; -import { TransferStatus, MessageProgress, ErrorMessage } from "@ccip-examples/shared-components"; +import { getExplorerTxUrl } from "@chainlink/ccip-examples-shared-config"; +import type { CategorizedError, LastTransferContext } from "@chainlink/ccip-examples-shared-utils"; +import type { TransferStatusStatus } from "@chainlink/ccip-examples-shared-utils"; +import { useMessageStatus } from "@chainlink/ccip-examples-shared-utils/hooks"; +import { + TransferStatus, + MessageProgress, + ErrorMessage, +} from "@chainlink/ccip-examples-shared-components"; import { inspectorStore } from "../../inspector/index.js"; import { getAnnotation } from "../../inspector/annotations.js"; -import { serializeForDisplay } from "@ccip-examples/shared-utils/inspector"; +import { serializeForDisplay } from "@chainlink/ccip-examples-shared-utils/inspector"; import { TransferBalances } from "./TransferBalances.js"; import { TransferRateLimits } from "./TransferRateLimits.js"; import styles from "./TransactionStatusView.module.css"; diff --git a/examples/03-multichain-bridge-dapp/src/components/transaction/TransferBalances.tsx b/examples/03-multichain-bridge-dapp/src/components/transaction/TransferBalances.tsx index b488751..e90bcc9 100644 --- a/examples/03-multichain-bridge-dapp/src/components/transaction/TransferBalances.tsx +++ b/examples/03-multichain-bridge-dapp/src/components/transaction/TransferBalances.tsx @@ -3,8 +3,8 @@ * Two cards; uses useTransferBalances and shared formatAmount / NETWORKS. */ -import { getNetwork } from "@ccip-examples/shared-config"; -import { formatAmount } from "@ccip-examples/shared-utils"; +import { getNetwork } from "@chainlink/ccip-examples-shared-config"; +import { formatAmount } from "@chainlink/ccip-examples-shared-utils"; import { useTransferBalances } from "../../hooks/useTransferBalances.js"; import styles from "./TransferBalances.module.css"; diff --git a/examples/03-multichain-bridge-dapp/src/components/transaction/TransferRateLimits.tsx b/examples/03-multichain-bridge-dapp/src/components/transaction/TransferRateLimits.tsx index 4b24bef..6a95c6e 100644 --- a/examples/03-multichain-bridge-dapp/src/components/transaction/TransferRateLimits.tsx +++ b/examples/03-multichain-bridge-dapp/src/components/transaction/TransferRateLimits.tsx @@ -3,7 +3,7 @@ * Two cards (source / destination), each with Outbound and Inbound via RateLimitDisplay. */ -import { getNetwork } from "@ccip-examples/shared-config"; +import { getNetwork } from "@chainlink/ccip-examples-shared-config"; import { RateLimitDisplay } from "../bridge/RateLimitDisplay.js"; import { useTransferRateLimits } from "../../hooks/useTransferRateLimits.js"; import styles from "./TransferRateLimits.module.css"; diff --git a/examples/03-multichain-bridge-dapp/src/hooks/ChainContext.tsx b/examples/03-multichain-bridge-dapp/src/hooks/ChainContext.tsx index d53ac5e..790b270 100644 --- a/examples/03-multichain-bridge-dapp/src/hooks/ChainContext.tsx +++ b/examples/03-multichain-bridge-dapp/src/hooks/ChainContext.tsx @@ -6,9 +6,13 @@ import { createContext, useCallback, useMemo, useRef, type ReactNode } from "react"; import { networkInfo, ChainFamily } from "@chainlink/ccip-sdk"; -import type { SDKCallPhase } from "@ccip-examples/shared-utils/inspector"; -import { NETWORKS, CHAIN_FAMILY_LABELS } from "@ccip-examples/shared-config"; -import { createChain, obfuscateRpcUrl, type ChainInstance } from "@ccip-examples/shared-utils"; +import type { SDKCallPhase } from "@chainlink/ccip-examples-shared-utils/inspector"; +import { NETWORKS, CHAIN_FAMILY_LABELS } from "@chainlink/ccip-examples-shared-config"; +import { + createChain, + obfuscateRpcUrl, + type ChainInstance, +} from "@chainlink/ccip-examples-shared-utils"; import { logSDKCall } from "../inspector/index.js"; import { getAnnotation } from "../inspector/annotations.js"; diff --git a/examples/03-multichain-bridge-dapp/src/hooks/index.ts b/examples/03-multichain-bridge-dapp/src/hooks/index.ts index a96a511..3703c14 100644 --- a/examples/03-multichain-bridge-dapp/src/hooks/index.ts +++ b/examples/03-multichain-bridge-dapp/src/hooks/index.ts @@ -1,19 +1,22 @@ export { useChains } from "./useChains.js"; export { ChainContext, ChainContextProvider } from "./ChainContext.js"; export type { ChainContextValue } from "./ChainContext.js"; -export type { ChainInstance } from "@ccip-examples/shared-utils"; +export type { ChainInstance } from "@chainlink/ccip-examples-shared-utils"; export { useTransfer } from "./useTransfer.js"; -export type { TransferStatusStatus, TransferState } from "@ccip-examples/shared-utils"; -export { useMessageStatus, type MessageStatusResult } from "@ccip-examples/shared-utils/hooks"; +export type { TransferStatusStatus, TransferState } from "@chainlink/ccip-examples-shared-utils"; +export { + useMessageStatus, + type MessageStatusResult, +} from "@chainlink/ccip-examples-shared-utils/hooks"; export { useTokenInfo, type UseTokenInfoResult, type TokenInfo, -} from "@ccip-examples/shared-utils/hooks"; -export type { WalletBalances, BalanceData } from "@ccip-examples/shared-utils/hooks"; +} from "@chainlink/ccip-examples-shared-utils/hooks"; +export type { WalletBalances, BalanceData } from "@chainlink/ccip-examples-shared-utils/hooks"; export { useTokenPoolInfo } from "./useTokenPoolInfo.js"; export type { TokenPoolInfo, RateLimitBucket, UseTokenPoolInfoResult } from "./useTokenPoolInfo.js"; -export { formatRateLimitBucket } from "@ccip-examples/shared-utils"; +export { formatRateLimitBucket } from "@chainlink/ccip-examples-shared-utils"; export { useDestinationBalance, type UseDestinationBalanceResult, diff --git a/examples/03-multichain-bridge-dapp/src/hooks/useAptosTransfer.ts b/examples/03-multichain-bridge-dapp/src/hooks/useAptosTransfer.ts index 3caa9b3..4867a02 100644 --- a/examples/03-multichain-bridge-dapp/src/hooks/useAptosTransfer.ts +++ b/examples/03-multichain-bridge-dapp/src/hooks/useAptosTransfer.ts @@ -9,7 +9,7 @@ import { useWallet } from "@aptos-labs/wallet-adapter-react"; import { Deserializer, SimpleTransaction } from "@aptos-labs/ts-sdk"; import type { AptosChain } from "@chainlink/ccip-sdk"; import { networkInfo } from "@chainlink/ccip-sdk"; -import { NETWORKS } from "@ccip-examples/shared-config"; +import { NETWORKS } from "@chainlink/ccip-examples-shared-config"; import { logSDKCall } from "../inspector/index.js"; import { getAnnotation } from "../inspector/annotations.js"; import type { TransactionResult, TransferMessage } from "./transferTypes.js"; diff --git a/examples/03-multichain-bridge-dapp/src/hooks/useDestinationBalance.ts b/examples/03-multichain-bridge-dapp/src/hooks/useDestinationBalance.ts index 39a8085..8719239 100644 --- a/examples/03-multichain-bridge-dapp/src/hooks/useDestinationBalance.ts +++ b/examples/03-multichain-bridge-dapp/src/hooks/useDestinationBalance.ts @@ -5,7 +5,7 @@ import { useState, useEffect, useCallback, useRef } from "react"; import { networkInfo, ChainFamily } from "@chainlink/ccip-sdk"; -import { formatAmount, isValidAddress } from "@ccip-examples/shared-utils"; +import { formatAmount, isValidAddress } from "@chainlink/ccip-examples-shared-utils"; import { useChains } from "./useChains.js"; import { useTokenPoolInfo } from "./useTokenPoolInfo.js"; import { logSDKCall } from "../inspector/index.js"; diff --git a/examples/03-multichain-bridge-dapp/src/hooks/useEVMTransfer.ts b/examples/03-multichain-bridge-dapp/src/hooks/useEVMTransfer.ts index ea790ca..2a75647 100644 --- a/examples/03-multichain-bridge-dapp/src/hooks/useEVMTransfer.ts +++ b/examples/03-multichain-bridge-dapp/src/hooks/useEVMTransfer.ts @@ -6,8 +6,8 @@ import { useCallback } from "react"; import { useAccount, useWalletClient, usePublicClient } from "wagmi"; import { networkInfo, type EVMChain } from "@chainlink/ccip-sdk"; -import { NETWORKS } from "@ccip-examples/shared-config"; -import { parseEVMError } from "@ccip-examples/shared-utils"; +import { NETWORKS } from "@chainlink/ccip-examples-shared-config"; +import { parseEVMError } from "@chainlink/ccip-examples-shared-utils"; import { logSDKCall } from "../inspector/index.js"; import { getAnnotation } from "../inspector/annotations.js"; import type { TransactionResult, TransferMessage } from "./transferTypes.js"; diff --git a/examples/03-multichain-bridge-dapp/src/hooks/useSolanaTransfer.ts b/examples/03-multichain-bridge-dapp/src/hooks/useSolanaTransfer.ts index 5e07241..a0ffb0a 100644 --- a/examples/03-multichain-bridge-dapp/src/hooks/useSolanaTransfer.ts +++ b/examples/03-multichain-bridge-dapp/src/hooks/useSolanaTransfer.ts @@ -8,8 +8,8 @@ import { useWallet, useConnection } from "@solana/wallet-adapter-react"; import { TransactionMessage, VersionedTransaction } from "@solana/web3.js"; import type { SolanaChain } from "@chainlink/ccip-sdk"; import { networkInfo } from "@chainlink/ccip-sdk"; -import { NETWORKS } from "@ccip-examples/shared-config"; -import { parseSolanaError, confirmTransaction } from "@ccip-examples/shared-utils"; +import { NETWORKS } from "@chainlink/ccip-examples-shared-config"; +import { parseSolanaError, confirmTransaction } from "@chainlink/ccip-examples-shared-utils"; import { logSDKCall } from "../inspector/index.js"; import { getAnnotation } from "../inspector/annotations.js"; import type { TransactionResult, TransferMessage } from "./transferTypes.js"; diff --git a/examples/03-multichain-bridge-dapp/src/hooks/useTokenPoolInfo.ts b/examples/03-multichain-bridge-dapp/src/hooks/useTokenPoolInfo.ts index e0744ec..dce797f 100644 --- a/examples/03-multichain-bridge-dapp/src/hooks/useTokenPoolInfo.ts +++ b/examples/03-multichain-bridge-dapp/src/hooks/useTokenPoolInfo.ts @@ -6,8 +6,8 @@ import { useState, useEffect, useCallback } from "react"; import { networkInfo } from "@chainlink/ccip-sdk"; import type { RateLimiterState } from "@chainlink/ccip-sdk"; -import { NETWORKS } from "@ccip-examples/shared-config"; -import type { RateLimitBucket } from "@ccip-examples/shared-utils"; +import { NETWORKS } from "@chainlink/ccip-examples-shared-config"; +import type { RateLimitBucket } from "@chainlink/ccip-examples-shared-utils"; import { useChains } from "./useChains.js"; import { logSDKCall } from "../inspector/index.js"; import { getAnnotation } from "../inspector/annotations.js"; diff --git a/examples/03-multichain-bridge-dapp/src/hooks/useTransactionExecution.ts b/examples/03-multichain-bridge-dapp/src/hooks/useTransactionExecution.ts index a1699bb..04e2659 100644 --- a/examples/03-multichain-bridge-dapp/src/hooks/useTransactionExecution.ts +++ b/examples/03-multichain-bridge-dapp/src/hooks/useTransactionExecution.ts @@ -8,7 +8,7 @@ import { isSolanaChain, isAptosChain, type ChainInstance, -} from "@ccip-examples/shared-utils"; +} from "@chainlink/ccip-examples-shared-utils"; import { useEVMTransfer } from "./useEVMTransfer.js"; import { useSolanaTransfer } from "./useSolanaTransfer.js"; import { useAptosTransfer } from "./useAptosTransfer.js"; diff --git a/examples/03-multichain-bridge-dapp/src/hooks/useTransfer.ts b/examples/03-multichain-bridge-dapp/src/hooks/useTransfer.ts index bcba9b5..898eade 100644 --- a/examples/03-multichain-bridge-dapp/src/hooks/useTransfer.ts +++ b/examples/03-multichain-bridge-dapp/src/hooks/useTransfer.ts @@ -8,7 +8,11 @@ import { useAccount } from "wagmi"; import { useWallet as useSolanaWallet } from "@solana/wallet-adapter-react"; import { useWallet as useAptosWallet } from "@aptos-labs/wallet-adapter-react"; import { networkInfo } from "@chainlink/ccip-sdk"; -import { NETWORKS, getTokenAddress, type FeeTokenOptionItem } from "@ccip-examples/shared-config"; +import { + NETWORKS, + getTokenAddress, + type FeeTokenOptionItem, +} from "@chainlink/ccip-examples-shared-config"; import { parseAmount, formatAmount, @@ -19,7 +23,7 @@ import { type WalletAddresses, type LastTransferContext, type TransferState, -} from "@ccip-examples/shared-utils"; +} from "@chainlink/ccip-examples-shared-utils"; import { useChains } from "./useChains.js"; import { useTransactionExecution } from "./useTransactionExecution.js"; import type { TransferMessage } from "./transferTypes.js"; diff --git a/examples/03-multichain-bridge-dapp/src/hooks/useTransferBalances.ts b/examples/03-multichain-bridge-dapp/src/hooks/useTransferBalances.ts index b1bbc1a..24cd471 100644 --- a/examples/03-multichain-bridge-dapp/src/hooks/useTransferBalances.ts +++ b/examples/03-multichain-bridge-dapp/src/hooks/useTransferBalances.ts @@ -7,7 +7,7 @@ */ import { useState, useEffect, useCallback, useRef } from "react"; -import { BALANCE_POLLING_INTERVAL_MS } from "@ccip-examples/shared-config"; +import { BALANCE_POLLING_INTERVAL_MS } from "@chainlink/ccip-examples-shared-config"; import { useChains } from "./useChains.js"; import { useDestinationBalance } from "./useDestinationBalance.js"; import { logSDKCall } from "../inspector/index.js"; diff --git a/examples/03-multichain-bridge-dapp/src/hooks/useTransferRateLimits.ts b/examples/03-multichain-bridge-dapp/src/hooks/useTransferRateLimits.ts index ef74c2c..5beacae 100644 --- a/examples/03-multichain-bridge-dapp/src/hooks/useTransferRateLimits.ts +++ b/examples/03-multichain-bridge-dapp/src/hooks/useTransferRateLimits.ts @@ -6,10 +6,10 @@ import { useState, useEffect, useCallback, useRef } from "react"; import { networkInfo } from "@chainlink/ccip-sdk"; import type { RateLimiterState } from "@chainlink/ccip-sdk"; -import { RATE_LIMIT_POLLING_INTERVAL_MS } from "@ccip-examples/shared-config"; -import { NETWORKS } from "@ccip-examples/shared-config"; +import { RATE_LIMIT_POLLING_INTERVAL_MS } from "@chainlink/ccip-examples-shared-config"; +import { NETWORKS } from "@chainlink/ccip-examples-shared-config"; import { useChains } from "./useChains.js"; -import type { RateLimitBucket } from "@ccip-examples/shared-utils"; +import type { RateLimitBucket } from "@chainlink/ccip-examples-shared-utils"; import { logSDKCall } from "../inspector/index.js"; import { getAnnotation } from "../inspector/annotations.js"; diff --git a/examples/03-multichain-bridge-dapp/src/inspector/annotations.ts b/examples/03-multichain-bridge-dapp/src/inspector/annotations.ts index ba41fff..6a0240d 100644 --- a/examples/03-multichain-bridge-dapp/src/inspector/annotations.ts +++ b/examples/03-multichain-bridge-dapp/src/inspector/annotations.ts @@ -10,7 +10,7 @@ * of the inspector UI via `displayArgs`. */ -import type { LogSDKCallOptions } from "@ccip-examples/shared-utils/inspector"; +import type { LogSDKCallOptions } from "@chainlink/ccip-examples-shared-utils/inspector"; type Annotation = Pick; diff --git a/examples/03-multichain-bridge-dapp/src/inspector/index.ts b/examples/03-multichain-bridge-dapp/src/inspector/index.ts index 3df53e7..a75e89f 100644 --- a/examples/03-multichain-bridge-dapp/src/inspector/index.ts +++ b/examples/03-multichain-bridge-dapp/src/inspector/index.ts @@ -1,2 +1,6 @@ export { getAnnotation } from "./annotations.js"; -export { logSDKCall, logSDKCallSync, inspectorStore } from "@ccip-examples/shared-utils/inspector"; +export { + logSDKCall, + logSDKCallSync, + inspectorStore, +} from "@chainlink/ccip-examples-shared-utils/inspector"; diff --git a/examples/04-hardhat-ccip/hardhat.config.ts b/examples/04-hardhat-ccip/hardhat.config.ts index 959f41a..9d0bb52 100644 --- a/examples/04-hardhat-ccip/hardhat.config.ts +++ b/examples/04-hardhat-ccip/hardhat.config.ts @@ -2,7 +2,7 @@ import "dotenv/config"; import { defineConfig, configVariable, task } from "hardhat/config"; import hardhatViemPlugin from "@nomicfoundation/hardhat-viem"; import hardhatNodeTestRunnerPlugin from "@nomicfoundation/hardhat-node-test-runner"; -import { NETWORKS, getChainIdForNetwork } from "@ccip-examples/shared-config"; +import { NETWORKS, getChainIdForNetwork } from "@chainlink/ccip-examples-shared-config"; // Build Hardhat network entries from shared-config NETWORKS (EVM only) // Network names === CCIP SDK canonical networkIds — no mapping needed diff --git a/examples/04-hardhat-ccip/helpers/sdk.ts b/examples/04-hardhat-ccip/helpers/sdk.ts index bb5ea94..e1a1730 100644 --- a/examples/04-hardhat-ccip/helpers/sdk.ts +++ b/examples/04-hardhat-ccip/helpers/sdk.ts @@ -8,7 +8,7 @@ import { createPublicClient, createWalletClient, http, defineChain } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { networkInfo } from "@chainlink/ccip-sdk"; -import { NETWORKS, getChainIdForNetwork } from "@ccip-examples/shared-config"; +import { NETWORKS, getChainIdForNetwork } from "@chainlink/ccip-examples-shared-config"; /** * Create viem clients for a given network diff --git a/examples/04-hardhat-ccip/package.json b/examples/04-hardhat-ccip/package.json index 49b5336..b9a1c7e 100644 --- a/examples/04-hardhat-ccip/package.json +++ b/examples/04-hardhat-ccip/package.json @@ -1,5 +1,6 @@ { - "name": "@ccip-examples/04-hardhat-ccip", + "name": "@chainlink/ccip-examples-04-hardhat-ccip", + "private": true, "version": "1.0.0", "engines": { "node": ">=22.0.0" @@ -15,8 +16,8 @@ "clean": "hardhat clean && rm -rf dist" }, "dependencies": { - "@ccip-examples/shared-config": "workspace:*", - "@ccip-examples/shared-utils": "workspace:*", + "@chainlink/ccip-examples-shared-config": "workspace:*", + "@chainlink/ccip-examples-shared-utils": "workspace:*", "@chainlink/ccip-sdk": "1.3.1", "@chainlink/contracts-ccip": "1.6.4", "@openzeppelin/contracts": "5.1.0", diff --git a/examples/04-hardhat-ccip/tasks/check-status.ts b/examples/04-hardhat-ccip/tasks/check-status.ts index 3a9cfb0..a4678f4 100644 --- a/examples/04-hardhat-ccip/tasks/check-status.ts +++ b/examples/04-hardhat-ccip/tasks/check-status.ts @@ -16,7 +16,7 @@ import { CCIPError, withRetry, } from "@chainlink/ccip-sdk"; -import { getStatusDescription, POLLING_CONFIG } from "@ccip-examples/shared-config"; +import { getStatusDescription, POLLING_CONFIG } from "@chainlink/ccip-examples-shared-config"; interface CheckStatusArgs { messageId: string; diff --git a/examples/04-hardhat-ccip/tasks/deploy-receiver.ts b/examples/04-hardhat-ccip/tasks/deploy-receiver.ts index dced5c3..73aac08 100644 --- a/examples/04-hardhat-ccip/tasks/deploy-receiver.ts +++ b/examples/04-hardhat-ccip/tasks/deploy-receiver.ts @@ -10,7 +10,7 @@ import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; import { networkInfo } from "@chainlink/ccip-sdk"; -import { getExplorerTxUrl } from "@ccip-examples/shared-config"; +import { getExplorerTxUrl } from "@chainlink/ccip-examples-shared-config"; import { createClients, getRouterAddress } from "../helpers/sdk.js"; interface DeployReceiverArgs { diff --git a/examples/04-hardhat-ccip/tasks/deploy-sender.ts b/examples/04-hardhat-ccip/tasks/deploy-sender.ts index 71b4826..66dc39d 100644 --- a/examples/04-hardhat-ccip/tasks/deploy-sender.ts +++ b/examples/04-hardhat-ccip/tasks/deploy-sender.ts @@ -10,7 +10,7 @@ import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; import { networkInfo } from "@chainlink/ccip-sdk"; -import { getExplorerTxUrl } from "@ccip-examples/shared-config"; +import { getExplorerTxUrl } from "@chainlink/ccip-examples-shared-config"; import { createClients, getRouterAddress } from "../helpers/sdk.js"; interface DeploySenderArgs { diff --git a/examples/04-hardhat-ccip/tasks/list-messages.ts b/examples/04-hardhat-ccip/tasks/list-messages.ts index 05e4cce..27e9895 100644 --- a/examples/04-hardhat-ccip/tasks/list-messages.ts +++ b/examples/04-hardhat-ccip/tasks/list-messages.ts @@ -33,7 +33,7 @@ import { getCCIPExplorerUrl, networkInfo, } from "@chainlink/ccip-sdk"; -import { formatRelativeTime } from "@ccip-examples/shared-utils"; +import { formatRelativeTime } from "@chainlink/ccip-examples-shared-utils"; interface ListMessagesArgs { sender: string; diff --git a/examples/04-hardhat-ccip/tasks/manage-allowlist.ts b/examples/04-hardhat-ccip/tasks/manage-allowlist.ts index 0747f00..9332d2e 100644 --- a/examples/04-hardhat-ccip/tasks/manage-allowlist.ts +++ b/examples/04-hardhat-ccip/tasks/manage-allowlist.ts @@ -30,7 +30,7 @@ import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; import { networkInfo } from "@chainlink/ccip-sdk"; -import { getExplorerTxUrl } from "@ccip-examples/shared-config"; +import { getExplorerTxUrl } from "@chainlink/ccip-examples-shared-config"; import { createClients } from "../helpers/sdk.js"; interface ManageAllowlistArgs { diff --git a/examples/04-hardhat-ccip/tasks/manual-execute.ts b/examples/04-hardhat-ccip/tasks/manual-execute.ts index 0c9fd4a..b7004e6 100644 --- a/examples/04-hardhat-ccip/tasks/manual-execute.ts +++ b/examples/04-hardhat-ccip/tasks/manual-execute.ts @@ -29,7 +29,7 @@ import { withRetry, } from "@chainlink/ccip-sdk"; import { fromViemClient, viemWallet } from "@chainlink/ccip-sdk/viem"; -import { getExplorerTxUrl } from "@ccip-examples/shared-config"; +import { getExplorerTxUrl } from "@chainlink/ccip-examples-shared-config"; import { createClients } from "../helpers/sdk.js"; interface ManualExecuteArgs { diff --git a/examples/04-hardhat-ccip/tasks/pause-contract.ts b/examples/04-hardhat-ccip/tasks/pause-contract.ts index ec6c63b..448d3d4 100644 --- a/examples/04-hardhat-ccip/tasks/pause-contract.ts +++ b/examples/04-hardhat-ccip/tasks/pause-contract.ts @@ -17,7 +17,7 @@ */ import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; -import { getExplorerTxUrl } from "@ccip-examples/shared-config"; +import { getExplorerTxUrl } from "@chainlink/ccip-examples-shared-config"; import { createClients } from "../helpers/sdk.js"; interface PauseContractArgs { diff --git a/examples/04-hardhat-ccip/tasks/send-via-router.ts b/examples/04-hardhat-ccip/tasks/send-via-router.ts index 915a7ff..20fb433 100644 --- a/examples/04-hardhat-ccip/tasks/send-via-router.ts +++ b/examples/04-hardhat-ccip/tasks/send-via-router.ts @@ -42,12 +42,12 @@ import { getExplorerTxUrl, getTokenAddress, resolveFeeTokenAddress, -} from "@ccip-examples/shared-config"; +} from "@chainlink/ccip-examples-shared-config"; import { buildTokenTransferMessage, formatAmount, formatLatency, -} from "@ccip-examples/shared-utils"; +} from "@chainlink/ccip-examples-shared-utils"; import { createClients, getRouterAddress, getDestChainSelector } from "../helpers/sdk.js"; interface SendViaRouterArgs { diff --git a/examples/04-hardhat-ccip/tasks/send-via-sender.ts b/examples/04-hardhat-ccip/tasks/send-via-sender.ts index ed69cfd..6c17adc 100644 --- a/examples/04-hardhat-ccip/tasks/send-via-sender.ts +++ b/examples/04-hardhat-ccip/tasks/send-via-sender.ts @@ -45,8 +45,8 @@ import { getExplorerTxUrl, getTokenAddress, resolveFeeTokenAddress, -} from "@ccip-examples/shared-config"; -import { formatAmount, formatLatency } from "@ccip-examples/shared-utils"; +} from "@chainlink/ccip-examples-shared-config"; +import { formatAmount, formatLatency } from "@chainlink/ccip-examples-shared-utils"; import { createClients, getRouterAddress, getDestChainSelector } from "../helpers/sdk.js"; interface SendViaSenderArgs { diff --git a/examples/04-hardhat-ccip/tasks/withdraw-funds.ts b/examples/04-hardhat-ccip/tasks/withdraw-funds.ts index 3977525..110d85e 100644 --- a/examples/04-hardhat-ccip/tasks/withdraw-funds.ts +++ b/examples/04-hardhat-ccip/tasks/withdraw-funds.ts @@ -22,7 +22,7 @@ import type { HardhatRuntimeEnvironment } from "hardhat/types/hre"; import { erc20Abi, formatUnits } from "viem"; -import { getExplorerTxUrl } from "@ccip-examples/shared-config"; +import { getExplorerTxUrl } from "@chainlink/ccip-examples-shared-config"; import { createClients } from "../helpers/sdk.js"; interface WithdrawFundsArgs { diff --git a/packages/shared-brand/README.md b/packages/shared-brand/README.md index 27475ce..256e991 100644 --- a/packages/shared-brand/README.md +++ b/packages/shared-brand/README.md @@ -1,4 +1,4 @@ -# @ccip-examples/shared-brand +# @chainlink/ccip-examples-shared-brand Shared design tokens and brand assets for CCIP SDK examples. @@ -30,7 +30,7 @@ Already included in the monorepo workspace. # Examples automatically have access via workspace:* { "dependencies": { - "@ccip-examples/shared-brand": "workspace:*" + "@chainlink/ccip-examples-shared-brand": "workspace:*" } } ``` @@ -45,7 +45,7 @@ In your example's main entry point (`main.tsx` or `index.tsx`): ```typescript // Import shared design tokens -import "@ccip-examples/shared-brand/design-tokens.css"; +import "@chainlink/ccip-examples-shared-brand/design-tokens.css"; // Then your app's styles import "./styles/globals.css"; @@ -58,7 +58,7 @@ import "./styles/globals.css"; ### 2. Use Logo ```tsx -import { BRAND_ASSETS } from "@ccip-examples/shared-brand"; +import { BRAND_ASSETS } from "@chainlink/ccip-examples-shared-brand"; function Header() { return ( @@ -73,7 +73,7 @@ function Header() { **Or directly in your build process:** ```bash -# Vite will copy from node_modules/@ccip-examples/shared-brand/assets/ +# Vite will copy from node_modules/@chainlink/ccip-examples-shared-brand/assets/ # Access as: /chainlink-logo.svg ``` @@ -82,7 +82,7 @@ function Header() { ### 3. Use Brand Colors Programmatically ```typescript -import { CHAINLINK_COLORS } from "@ccip-examples/shared-brand"; +import { CHAINLINK_COLORS } from "@chainlink/ccip-examples-shared-brand"; // Use in JavaScript/TypeScript const chartColor = CHAINLINK_COLORS.primary; // "#0847F7" @@ -103,7 +103,7 @@ canvas.fillStyle = CHAINLINK_COLORS.success; // "#217B71" ### 4. Use Design Tokens ```typescript -import { DESIGN_TOKENS } from "@ccip-examples/shared-brand"; +import { DESIGN_TOKENS } from "@chainlink/ccip-examples-shared-brand"; // Access any design token programmatically const buttonPadding = DESIGN_TOKENS.spacing[4]; // "1rem" @@ -169,7 +169,7 @@ packages/shared-brand/ │ │ │ │ ▼ │ │ ┌─────────────────────────────┐ │ -│ │ @ccip-examples/shared-brand │ │ +│ │ @chainlink/ccip-examples-shared-brand │ │ │ ├─────────────────────────────┤ │ │ │ • Consistent color palette │ │ │ │ • Logo SVG │ │ @@ -188,7 +188,7 @@ packages/shared-brand/ ```typescript // examples/my-example/src/main.tsx -import "@ccip-examples/shared-brand/design-tokens.css"; +import "@chainlink/ccip-examples-shared-brand/design-tokens.css"; import "./styles/globals.css"; // Your app-specific styles ``` @@ -257,7 +257,7 @@ body { 3. **Use in examples:** ```tsx - import { BRAND_ASSETS } from "@ccip-examples/shared-brand"; + import { BRAND_ASSETS } from "@chainlink/ccip-examples-shared-brand"; ; ``` @@ -267,7 +267,7 @@ body { When creating a new frontend example: -1. ✅ Add `@ccip-examples/shared-brand` to dependencies +1. ✅ Add `@chainlink/ccip-examples-shared-brand` to dependencies 2. ✅ Import `design-tokens.css` in main entry 3. ✅ Use `BRAND_ASSETS` for logos/icons 4. ✅ Use CSS variables for all colors/spacing diff --git a/packages/shared-brand/package.json b/packages/shared-brand/package.json index a88c771..c983f4f 100644 --- a/packages/shared-brand/package.json +++ b/packages/shared-brand/package.json @@ -1,5 +1,6 @@ { - "name": "@ccip-examples/shared-brand", + "name": "@chainlink/ccip-examples-shared-brand", + "private": true, "version": "1.0.0", "engines": { "node": ">=22.0.0" diff --git a/packages/shared-brand/src/design-tokens.css b/packages/shared-brand/src/design-tokens.css index c85586b..a4f764d 100644 --- a/packages/shared-brand/src/design-tokens.css +++ b/packages/shared-brand/src/design-tokens.css @@ -6,12 +6,12 @@ * * Usage: * ```css - * @import '@ccip-examples/shared-brand/design-tokens.css'; + * @import '@chainlink/ccip-examples-shared-brand/design-tokens.css'; * ``` * * Or in your main.tsx/index.tsx: * ```typescript - * import '@ccip-examples/shared-brand/design-tokens.css'; + * import '@chainlink/ccip-examples-shared-brand/design-tokens.css'; * ``` */ diff --git a/packages/shared-brand/src/index.ts b/packages/shared-brand/src/index.ts index d5610c1..4a441a4 100644 --- a/packages/shared-brand/src/index.ts +++ b/packages/shared-brand/src/index.ts @@ -1,5 +1,5 @@ /** - * @ccip-examples/shared-brand + * @chainlink/ccip-examples-shared-brand * * Shared design tokens and brand assets for CCIP SDK examples. * diff --git a/packages/shared-components/package.json b/packages/shared-components/package.json index 48ea8fc..ffec7ba 100644 --- a/packages/shared-components/package.json +++ b/packages/shared-components/package.json @@ -1,5 +1,6 @@ { - "name": "@ccip-examples/shared-components", + "name": "@chainlink/ccip-examples-shared-components", + "private": true, "version": "1.0.0", "engines": { "node": ">=22.0.0" @@ -63,9 +64,9 @@ "ui" ], "dependencies": { - "@ccip-examples/shared-brand": "workspace:*", - "@ccip-examples/shared-config": "workspace:*", - "@ccip-examples/shared-utils": "workspace:*" + "@chainlink/ccip-examples-shared-brand": "workspace:*", + "@chainlink/ccip-examples-shared-config": "workspace:*", + "@chainlink/ccip-examples-shared-utils": "workspace:*" }, "sideEffects": [ "*.css", diff --git a/packages/shared-components/src/FeeEstimateDisplay.tsx b/packages/shared-components/src/FeeEstimateDisplay.tsx index da34f44..16c1ac3 100644 --- a/packages/shared-components/src/FeeEstimateDisplay.tsx +++ b/packages/shared-components/src/FeeEstimateDisplay.tsx @@ -2,8 +2,8 @@ * Fee estimate block: estimated fee (with symbol), delivery, "Your balance after" with checkmark. */ -import type { FeeTokenOptionItem } from "@ccip-examples/shared-config"; -import { formatAmount } from "@ccip-examples/shared-utils"; +import type { FeeTokenOptionItem } from "@chainlink/ccip-examples-shared-config"; +import { formatAmount } from "@chainlink/ccip-examples-shared-utils"; import styles from "./FeeEstimateDisplay.module.css"; export interface FeeEstimateDisplayProps { diff --git a/packages/shared-components/src/FeeTokenOptions.tsx b/packages/shared-components/src/FeeTokenOptions.tsx index d173878..4e34743 100644 --- a/packages/shared-components/src/FeeTokenOptions.tsx +++ b/packages/shared-components/src/FeeTokenOptions.tsx @@ -3,7 +3,7 @@ * Radio list: symbol + formatted balance per token; chain-agnostic (address = native vs token). */ -import type { FeeTokenOptionItem } from "@ccip-examples/shared-config"; +import type { FeeTokenOptionItem } from "@chainlink/ccip-examples-shared-config"; import styles from "./FeeTokenOptions.module.css"; export interface FeeTokenOptionsProps { diff --git a/packages/shared-components/src/bridge/MessageProgress.tsx b/packages/shared-components/src/bridge/MessageProgress.tsx index 90025c3..54a3d1c 100644 --- a/packages/shared-components/src/bridge/MessageProgress.tsx +++ b/packages/shared-components/src/bridge/MessageProgress.tsx @@ -3,8 +3,8 @@ */ import { MessageStatus, getCCIPExplorerUrl } from "@chainlink/ccip-sdk"; -import { useMessageStatus } from "@ccip-examples/shared-utils/hooks"; -import { MESSAGE_STAGES } from "@ccip-examples/shared-config"; +import { useMessageStatus } from "@chainlink/ccip-examples-shared-utils/hooks"; +import { MESSAGE_STAGES } from "@chainlink/ccip-examples-shared-config"; import { CheckIcon, XIcon } from "../icons/index.js"; import styles from "./MessageProgress.module.css"; diff --git a/packages/shared-components/src/bridge/TransferStatus.tsx b/packages/shared-components/src/bridge/TransferStatus.tsx index afcb4da..0ed65a6 100644 --- a/packages/shared-components/src/bridge/TransferStatus.tsx +++ b/packages/shared-components/src/bridge/TransferStatus.tsx @@ -3,7 +3,7 @@ */ import { getCCIPExplorerUrl } from "@chainlink/ccip-sdk"; -import type { TransferStatusStatus } from "@ccip-examples/shared-utils"; +import type { TransferStatusStatus } from "@chainlink/ccip-examples-shared-utils"; import { Button } from "../primitives/Button.js"; import styles from "./TransferStatus.module.css"; diff --git a/packages/shared-components/src/bridge/index.ts b/packages/shared-components/src/bridge/index.ts index d16e60a..82f4884 100644 --- a/packages/shared-components/src/bridge/index.ts +++ b/packages/shared-components/src/bridge/index.ts @@ -1,3 +1,3 @@ export { MessageProgress, type MessageProgressProps } from "./MessageProgress.js"; export { TransferStatus, type TransferStatusProps } from "./TransferStatus.js"; -export type { TransferStatusStatus } from "@ccip-examples/shared-utils"; +export type { TransferStatusStatus } from "@chainlink/ccip-examples-shared-utils"; diff --git a/packages/shared-components/src/inspector/CallEntry.tsx b/packages/shared-components/src/inspector/CallEntry.tsx index aa62a2b..01f52a6 100644 --- a/packages/shared-components/src/inspector/CallEntry.tsx +++ b/packages/shared-components/src/inspector/CallEntry.tsx @@ -3,7 +3,7 @@ */ import { useState } from "react"; -import type { SDKCallEntry } from "@ccip-examples/shared-utils/inspector"; +import type { SDKCallEntry } from "@chainlink/ccip-examples-shared-utils/inspector"; import { CodeSnippet } from "./CodeSnippet.js"; import { PollingIndicator } from "./PollingIndicator.js"; import styles from "./CallEntry.module.css"; diff --git a/packages/shared-components/src/inspector/CodeSnippet.tsx b/packages/shared-components/src/inspector/CodeSnippet.tsx index d2df483..1771063 100644 --- a/packages/shared-components/src/inspector/CodeSnippet.tsx +++ b/packages/shared-components/src/inspector/CodeSnippet.tsx @@ -4,7 +4,7 @@ */ import { useMemo } from "react"; -import { useCopyToClipboard } from "@ccip-examples/shared-utils/hooks"; +import { useCopyToClipboard } from "@chainlink/ccip-examples-shared-utils/hooks"; import styles from "./CodeSnippet.module.css"; interface CodeSnippetProps { diff --git a/packages/shared-components/src/inspector/PhaseGroup.tsx b/packages/shared-components/src/inspector/PhaseGroup.tsx index 56be949..abea67b 100644 --- a/packages/shared-components/src/inspector/PhaseGroup.tsx +++ b/packages/shared-components/src/inspector/PhaseGroup.tsx @@ -3,7 +3,7 @@ */ import { useState, useEffect } from "react"; -import type { SDKCallEntry, SDKCallPhase } from "@ccip-examples/shared-utils/inspector"; +import type { SDKCallEntry, SDKCallPhase } from "@chainlink/ccip-examples-shared-utils/inspector"; import { CallEntry } from "./CallEntry.js"; import styles from "./PhaseGroup.module.css"; diff --git a/packages/shared-components/src/inspector/SDKInspectorPanel.tsx b/packages/shared-components/src/inspector/SDKInspectorPanel.tsx index 33ed159..758231e 100644 --- a/packages/shared-components/src/inspector/SDKInspectorPanel.tsx +++ b/packages/shared-components/src/inspector/SDKInspectorPanel.tsx @@ -8,7 +8,7 @@ import { useSDKInspector, useSDKInspectorActions, type SDKCallPhase, -} from "@ccip-examples/shared-utils/inspector"; +} from "@chainlink/ccip-examples-shared-utils/inspector"; import { PhaseGroup } from "./PhaseGroup.js"; import { InspectorEmptyState } from "./InspectorEmptyState.js"; import styles from "./SDKInspectorPanel.module.css"; diff --git a/packages/shared-components/src/inspector/SDKInspectorToggle.tsx b/packages/shared-components/src/inspector/SDKInspectorToggle.tsx index e842727..f659b58 100644 --- a/packages/shared-components/src/inspector/SDKInspectorToggle.tsx +++ b/packages/shared-components/src/inspector/SDKInspectorToggle.tsx @@ -3,7 +3,10 @@ * Designed to be placed in Header's children slot. */ -import { useSDKInspector, useSDKInspectorActions } from "@ccip-examples/shared-utils/inspector"; +import { + useSDKInspector, + useSDKInspectorActions, +} from "@chainlink/ccip-examples-shared-utils/inspector"; import styles from "./SDKInspectorToggle.module.css"; export function SDKInspectorToggle() { diff --git a/packages/shared-components/src/primitives/ErrorMessage.tsx b/packages/shared-components/src/primitives/ErrorMessage.tsx index d5da4d4..bbc2c34 100644 --- a/packages/shared-components/src/primitives/ErrorMessage.tsx +++ b/packages/shared-components/src/primitives/ErrorMessage.tsx @@ -3,8 +3,8 @@ */ import { useState, useCallback } from "react"; -import type { CategorizedError as CategorizedErrorType } from "@ccip-examples/shared-utils"; -import { copyToClipboard, COPIED_FEEDBACK_MS } from "@ccip-examples/shared-utils"; +import type { CategorizedError as CategorizedErrorType } from "@chainlink/ccip-examples-shared-utils"; +import { copyToClipboard, COPIED_FEEDBACK_MS } from "@chainlink/ccip-examples-shared-utils"; import { Button } from "./Button.js"; import styles from "./ErrorMessage.module.css"; diff --git a/packages/shared-components/src/styles/globals.css b/packages/shared-components/src/styles/globals.css index 8221e1a..fd2dadd 100644 --- a/packages/shared-components/src/styles/globals.css +++ b/packages/shared-components/src/styles/globals.css @@ -2,7 +2,7 @@ * Global styles for CCIP example frontends. * Import design tokens from shared-brand (single source of truth). */ -@import "@ccip-examples/shared-brand/design-tokens.css"; +@import "@chainlink/ccip-examples-shared-brand/design-tokens.css"; :root { --color-metamask: #f6851b; diff --git a/packages/shared-config/package.json b/packages/shared-config/package.json index d38afdf..6880141 100644 --- a/packages/shared-config/package.json +++ b/packages/shared-config/package.json @@ -1,5 +1,6 @@ { - "name": "@ccip-examples/shared-config", + "name": "@chainlink/ccip-examples-shared-config", + "private": true, "version": "1.0.0", "engines": { "node": ">=22.0.0" diff --git a/packages/shared-config/src/index.ts b/packages/shared-config/src/index.ts index 5467d96..84d3f74 100644 --- a/packages/shared-config/src/index.ts +++ b/packages/shared-config/src/index.ts @@ -1,5 +1,5 @@ /** - * @ccip-examples/shared-config + * @chainlink/ccip-examples-shared-config * * Shared network and token configuration for CCIP SDK examples. * diff --git a/packages/shared-config/src/queryClient.ts b/packages/shared-config/src/queryClient.ts index 01b5c24..5509bd6 100644 --- a/packages/shared-config/src/queryClient.ts +++ b/packages/shared-config/src/queryClient.ts @@ -1,6 +1,6 @@ /** * Default React Query client options for CCIP examples. - * Import from "@ccip-examples/shared-config/queryClient" to keep main entry tanstack-free. + * Import from "@chainlink/ccip-examples-shared-config/queryClient" to keep main entry tanstack-free. */ import { QueryClient } from "@tanstack/react-query"; diff --git a/packages/shared-config/src/wagmi.ts b/packages/shared-config/src/wagmi.ts index eeca5ca..c3ff6a6 100644 --- a/packages/shared-config/src/wagmi.ts +++ b/packages/shared-config/src/wagmi.ts @@ -1,6 +1,6 @@ /** * Wagmi & RainbowKit configuration for EVM examples. - * Import from "@ccip-examples/shared-config/wagmi" so the main entry stays wagmi-free (e.g. for Node/CLI). + * Import from "@chainlink/ccip-examples-shared-config/wagmi" so the main entry stays wagmi-free (e.g. for Node/CLI). */ import { getDefaultConfig } from "@rainbow-me/rainbowkit"; diff --git a/packages/shared-utils/package.json b/packages/shared-utils/package.json index de5cea3..1bc1e10 100644 --- a/packages/shared-utils/package.json +++ b/packages/shared-utils/package.json @@ -1,5 +1,6 @@ { - "name": "@ccip-examples/shared-utils", + "name": "@chainlink/ccip-examples-shared-utils", + "private": true, "version": "1.0.0", "engines": { "node": ">=22.0.0" @@ -73,7 +74,7 @@ "bs58": "^6.0.0", "ethers": "^6.16.0", "viem": "^2.21.0", - "@ccip-examples/shared-config": "workspace:*" + "@chainlink/ccip-examples-shared-config": "workspace:*" }, "devDependencies": { "typescript": "^5.9.3", diff --git a/packages/shared-utils/src/ccipErrors.ts b/packages/shared-utils/src/ccipErrors.ts index 5e81a3c..66d9c0d 100644 --- a/packages/shared-utils/src/ccipErrors.ts +++ b/packages/shared-utils/src/ccipErrors.ts @@ -1,5 +1,5 @@ /** - * @ccip-examples/shared-utils — CCIP error parsing + * @chainlink/ccip-examples-shared-utils — CCIP error parsing * * Parses CCIP-specific errors using @chainlink/ccip-sdk chain parse methods. * - EVMChain.parse(error) — decodes hex error selectors via CCIP contract ABIs diff --git a/packages/shared-utils/src/hooks/index.ts b/packages/shared-utils/src/hooks/index.ts index 9849c82..57ded3a 100644 --- a/packages/shared-utils/src/hooks/index.ts +++ b/packages/shared-utils/src/hooks/index.ts @@ -1,6 +1,6 @@ /** * React hooks for CCIP examples (EVM/Solana frontends). - * Import from "@ccip-examples/shared-utils/hooks" to avoid pulling React into Node CLI (example 01). + * Import from "@chainlink/ccip-examples-shared-utils/hooks" to avoid pulling React into Node CLI (example 01). */ export { useMessageStatus, type MessageStatusResult } from "./useMessageStatus.js"; diff --git a/packages/shared-utils/src/hooks/useFeeTokens.ts b/packages/shared-utils/src/hooks/useFeeTokens.ts index 023b097..fb547c7 100644 --- a/packages/shared-utils/src/hooks/useFeeTokens.ts +++ b/packages/shared-utils/src/hooks/useFeeTokens.ts @@ -7,7 +7,7 @@ import { useState, useEffect, useCallback, useRef } from "react"; import type { Chain } from "@chainlink/ccip-sdk"; -import { NETWORKS, type FeeTokenOptionItem } from "@ccip-examples/shared-config"; +import { NETWORKS, type FeeTokenOptionItem } from "@chainlink/ccip-examples-shared-config"; import { formatAmount } from "../validation.js"; import type { SDKCallReporter } from "../inspector/types.js"; diff --git a/packages/shared-utils/src/hooks/useMessageStatus.ts b/packages/shared-utils/src/hooks/useMessageStatus.ts index a16d2b3..e97966a 100644 --- a/packages/shared-utils/src/hooks/useMessageStatus.ts +++ b/packages/shared-utils/src/hooks/useMessageStatus.ts @@ -12,7 +12,7 @@ import { MessageStatus, CCIPAPIClient } from "@chainlink/ccip-sdk"; import { POLLING_CONFIG, getStatusDescription as getSharedStatusDescription, -} from "@ccip-examples/shared-config"; +} from "@chainlink/ccip-examples-shared-config"; import { formatElapsedTime } from "../formatting.js"; import type { SDKCallReporter } from "../inspector/types.js"; diff --git a/packages/shared-utils/src/hooks/useWalletBalances.ts b/packages/shared-utils/src/hooks/useWalletBalances.ts index 3ad50de..1bfada4 100644 --- a/packages/shared-utils/src/hooks/useWalletBalances.ts +++ b/packages/shared-utils/src/hooks/useWalletBalances.ts @@ -21,7 +21,7 @@ import { useState, useEffect, useCallback, useRef } from "react"; import type { Chain } from "@chainlink/ccip-sdk"; -import { NETWORKS, getTokenAddress } from "@ccip-examples/shared-config"; +import { NETWORKS, getTokenAddress } from "@chainlink/ccip-examples-shared-config"; import { formatAmount } from "../validation.js"; import type { SDKCallReporter } from "../inspector/types.js"; diff --git a/packages/shared-utils/src/index.ts b/packages/shared-utils/src/index.ts index 31560c3..97c4c38 100644 --- a/packages/shared-utils/src/index.ts +++ b/packages/shared-utils/src/index.ts @@ -1,5 +1,5 @@ /** - * @ccip-examples/shared-utils + * @chainlink/ccip-examples-shared-utils * * Shared utilities for CCIP SDK examples. */ @@ -90,4 +90,4 @@ export { // NOTE: Wallet utilities (createWallet, createSolanaWallet, etc.) use Node.js // built-ins (fs, os, path) and are NOT re-exported here to keep the main -// entry point browser-safe. Import them from "@ccip-examples/shared-utils/wallet". +// entry point browser-safe. Import them from "@chainlink/ccip-examples-shared-utils/wallet". diff --git a/packages/shared-utils/src/viem.ts b/packages/shared-utils/src/viem.ts index 5f4d7c3..c6f1f81 100644 --- a/packages/shared-utils/src/viem.ts +++ b/packages/shared-utils/src/viem.ts @@ -8,7 +8,7 @@ * ```typescript * import { getPublicClient } from "wagmi/actions"; * import { fromViemClient } from "@chainlink/ccip-sdk/viem"; - * import { toGenericPublicClient } from "@ccip-examples/shared-utils"; + * import { toGenericPublicClient } from "@chainlink/ccip-examples-shared-utils"; * * const client = getPublicClient(wagmiConfig, { chainId }); * const chain = await fromViemClient(toGenericPublicClient(client)); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 01ae6bb..853aa23 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,10 +43,10 @@ importers: examples/01-getting-started: dependencies: - "@ccip-examples/shared-config": + "@chainlink/ccip-examples-shared-config": specifier: workspace:* version: link:../../packages/shared-config - "@ccip-examples/shared-utils": + "@chainlink/ccip-examples-shared-utils": specifier: workspace:* version: link:../../packages/shared-utils "@chainlink/ccip-sdk": @@ -83,16 +83,16 @@ importers: examples/02-evm-simple-bridge: dependencies: - "@ccip-examples/shared-brand": + "@chainlink/ccip-examples-shared-brand": specifier: workspace:* version: link:../../packages/shared-brand - "@ccip-examples/shared-components": + "@chainlink/ccip-examples-shared-components": specifier: workspace:* version: link:../../packages/shared-components - "@ccip-examples/shared-config": + "@chainlink/ccip-examples-shared-config": specifier: workspace:* version: link:../../packages/shared-config - "@ccip-examples/shared-utils": + "@chainlink/ccip-examples-shared-utils": specifier: workspace:* version: link:../../packages/shared-utils "@chainlink/ccip-sdk": @@ -150,16 +150,16 @@ importers: "@aptos-labs/wallet-adapter-react": specifier: ^3.7.2 version: 3.8.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/core@1.4.0(@aptos-labs/ts-sdk@5.2.1(got@12.6.1))(@mizuwallet-sdk/protocol@0.0.6)(graphql-request@7.4.0(graphql@16.12.0)))(@mizuwallet-sdk/protocol@0.0.6)(@telegram-apps/bridge@1.9.2)(@types/react@18.3.28)(@wallet-standard/core@1.1.1)(aptos@1.22.1(got@12.6.1))(axios@1.13.5)(got@12.6.1)(react@18.3.1) - "@ccip-examples/shared-brand": + "@chainlink/ccip-examples-shared-brand": specifier: workspace:* version: link:../../packages/shared-brand - "@ccip-examples/shared-components": + "@chainlink/ccip-examples-shared-components": specifier: workspace:* version: link:../../packages/shared-components - "@ccip-examples/shared-config": + "@chainlink/ccip-examples-shared-config": specifier: workspace:* version: link:../../packages/shared-config - "@ccip-examples/shared-utils": + "@chainlink/ccip-examples-shared-utils": specifier: workspace:* version: link:../../packages/shared-utils "@chainlink/ccip-sdk": @@ -179,7 +179,7 @@ importers: version: 0.9.35(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bs58@5.0.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(typescript@5.9.3) "@solana/wallet-adapter-wallets": specifier: 0.19.32 - version: 0.19.32(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bs58@5.0.0)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.76) + version: 0.19.32(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bs58@5.0.0)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.76) "@solana/web3.js": specifier: 1.98.0 version: 1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) @@ -226,10 +226,10 @@ importers: examples/04-hardhat-ccip: dependencies: - "@ccip-examples/shared-config": + "@chainlink/ccip-examples-shared-config": specifier: workspace:* version: link:../../packages/shared-config - "@ccip-examples/shared-utils": + "@chainlink/ccip-examples-shared-utils": specifier: workspace:* version: link:../../packages/shared-utils "@chainlink/ccip-sdk": @@ -278,13 +278,13 @@ importers: packages/shared-components: dependencies: - "@ccip-examples/shared-brand": + "@chainlink/ccip-examples-shared-brand": specifier: workspace:* version: link:../shared-brand - "@ccip-examples/shared-config": + "@chainlink/ccip-examples-shared-config": specifier: workspace:* version: link:../shared-config - "@ccip-examples/shared-utils": + "@chainlink/ccip-examples-shared-utils": specifier: workspace:* version: link:../shared-utils devDependencies: @@ -333,7 +333,7 @@ importers: "@aptos-labs/ts-sdk": specifier: ^5.2.1 version: 5.2.1(got@12.6.1) - "@ccip-examples/shared-config": + "@chainlink/ccip-examples-shared-config": specifier: workspace:* version: link:../shared-config "@coral-xyz/anchor": @@ -16126,30 +16126,30 @@ snapshots: - react-native - typescript - "@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": + "@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - "@solana-program/stake@0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": + "@solana-program/stake@0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana-program/system@0.10.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10))": dependencies: "@solana/kit": 5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) - "@solana-program/system@0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": + "@solana-program/system@0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - "@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))": + "@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/sysvars": 5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": + "@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana-program/token@0.9.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10))": dependencies: @@ -16454,7 +16454,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - "@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/accounts": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/addresses": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -16467,11 +16467,11 @@ snapshots: "@solana/rpc": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/rpc-parsed-types": 2.3.0(typescript@5.9.3) "@solana/rpc-spec-types": 2.3.0(typescript@5.9.3) - "@solana/rpc-subscriptions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/rpc-subscriptions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/rpc-types": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/signers": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/sysvars": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana/transaction-confirmation": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/transaction-confirmation": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/transaction-messages": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/transactions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) typescript: 5.9.3 @@ -16687,14 +16687,14 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - "@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/errors": 2.3.0(typescript@5.9.3) "@solana/functional": 2.3.0(typescript@5.9.3) "@solana/rpc-subscriptions-spec": 2.3.0(typescript@5.9.3) "@solana/subscribable": 2.3.0(typescript@5.9.3) typescript: 5.9.3 - ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) "@solana/rpc-subscriptions-channel-websocket@5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)": dependencies: @@ -16726,7 +16726,7 @@ snapshots: optionalDependencies: typescript: 5.9.3 - "@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/errors": 2.3.0(typescript@5.9.3) "@solana/fast-stable-stringify": 2.3.0(typescript@5.9.3) @@ -16734,7 +16734,7 @@ snapshots: "@solana/promises": 2.3.0(typescript@5.9.3) "@solana/rpc-spec-types": 2.3.0(typescript@5.9.3) "@solana/rpc-subscriptions-api": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana/rpc-subscriptions-channel-websocket": 2.3.0(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/rpc-subscriptions-channel-websocket": 2.3.0(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/rpc-subscriptions-spec": 2.3.0(typescript@5.9.3) "@solana/rpc-transformers": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/rpc-types": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -16953,7 +16953,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - "@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/addresses": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/codecs-strings": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -16961,7 +16961,7 @@ snapshots: "@solana/keys": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/promises": 2.3.0(typescript@5.9.3) "@solana/rpc": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana/rpc-subscriptions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/rpc-subscriptions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/rpc-types": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/transaction-messages": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/transactions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -17304,11 +17304,11 @@ snapshots: - supports-color - utf-8-validate - "@solana/wallet-adapter-trezor@0.1.6(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/wallet-adapter-trezor@0.1.6(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/wallet-adapter-base": 0.9.27(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/web3.js": 1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) - "@trezor/connect-web": 9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@trezor/connect-web": 9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) buffer: 6.0.3 transitivePeerDependencies: - "@solana/sysvars" @@ -17371,7 +17371,7 @@ snapshots: - utf-8-validate - zod - "@solana/wallet-adapter-wallets@0.19.32(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bs58@5.0.0)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.76)": + "@solana/wallet-adapter-wallets@0.19.32(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bs58@5.0.0)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.76)": dependencies: "@solana/wallet-adapter-alpha": 0.1.14(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-avana": 0.1.17(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) @@ -17404,7 +17404,7 @@ snapshots: "@solana/wallet-adapter-tokenary": 0.1.16(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-tokenpocket": 0.4.23(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-torus": 0.11.32(@babel/runtime@7.28.6)(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(utf-8-validate@5.0.10) - "@solana/wallet-adapter-trezor": 0.1.6(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/wallet-adapter-trezor": 0.1.6(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-trust": 0.1.17(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-unsafe-burner": 0.1.11(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-walletconnect": 0.1.21(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -17814,13 +17814,13 @@ snapshots: - react-native - utf-8-validate - "@trezor/blockchain-link@2.6.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@trezor/blockchain-link@2.6.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: - "@solana-program/compute-budget": 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/stake": 0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/token": 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/token-2022": 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana-program/compute-budget": 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/stake": 0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/token": 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/token-2022": 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/rpc-types": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@stellar/stellar-sdk": 14.2.0 "@trezor/blockchain-link-types": 1.5.0(tslib@2.8.1) @@ -17868,9 +17868,9 @@ snapshots: - expo-localization - react-native - "@trezor/connect-web@9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@trezor/connect-web@9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: - "@trezor/connect": 9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@trezor/connect": 9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@trezor/connect-common": 0.5.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1) "@trezor/utils": 9.5.0(tslib@2.8.1) "@trezor/websocket-client": 1.3.0(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@5.0.10) @@ -17889,7 +17889,7 @@ snapshots: - utf-8-validate - ws - "@trezor/connect@9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@trezor/connect@9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@ethereumjs/common": 10.1.1 "@ethereumjs/tx": 10.1.1 @@ -17897,12 +17897,12 @@ snapshots: "@mobily/ts-belt": 3.13.1 "@noble/hashes": 1.8.0 "@scure/bip39": 1.6.0 - "@solana-program/compute-budget": 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/system": 0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/token": 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/token-2022": 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - "@trezor/blockchain-link": 2.6.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana-program/compute-budget": 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/system": 0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/token": 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/token-2022": 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@trezor/blockchain-link": 2.6.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@trezor/blockchain-link-types": 1.5.0(tslib@2.8.1) "@trezor/blockchain-link-utils": 1.5.1(bufferutil@4.1.0)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(utf-8-validate@5.0.10) "@trezor/connect-analytics": 1.4.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1) From 6737c60461981762061010414e217aa50a86a63a Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Tue, 24 Mar 2026 23:26:35 +0100 Subject: [PATCH 4/6] Add pnpm overrides for @openzeppelin/contracts@4.7.3 --- package.json | 4 +++- pnpm-lock.yaml | 18 ++++++------------ 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 0c8d001..c717251 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,9 @@ ], "pnpm": { "overrides": { - "minimatch@<3.1.6": ">=3.1.6" + "minimatch@<3.1.6": ">=3.1.6", + "@openzeppelin/contracts@4.7.3": "4.9.6", + "@openzeppelin/contracts-upgradeable@4.7.3": "4.9.6" } }, "author": "Chainlink", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 853aa23..96978eb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,6 +6,8 @@ settings: overrides: minimatch@<3.1.6: ">=3.1.6" + "@openzeppelin/contracts@4.7.3": 4.9.6 + "@openzeppelin/contracts-upgradeable@4.7.3": 4.9.6 importers: .: @@ -2720,12 +2722,6 @@ packages: integrity: sha512-mpn6PHjH/KDDjNX0pXHEKdyv8m6DVGQiI2nGzQn0JbM1nOSHJpWx6fvfjtH7YxHJ6zBZTcsKkqGkFKDtCfoSLw==, } - "@openzeppelin/contracts-upgradeable@4.7.3": - resolution: - { - integrity: sha512-+wuegAMaLcZnLCJIvrVUDzA9z/Wp93f0Dla/4jJvIhijRrPabjQbZe6fWiECLaJyfn5ci9fqf9vTw3xpQOad2A==, - } - "@openzeppelin/contracts-upgradeable@4.9.6": resolution: { @@ -13028,8 +13024,8 @@ snapshots: "@arbitrum/nitro-contracts@3.0.0": dependencies: "@offchainlabs/upgrade-executor": 1.1.0-beta.0 - "@openzeppelin/contracts": 4.7.3 - "@openzeppelin/contracts-upgradeable": 4.7.3 + "@openzeppelin/contracts": 4.9.6 + "@openzeppelin/contracts-upgradeable": 4.9.6 patch-package: 6.5.1 solady: 0.0.182 @@ -14920,10 +14916,8 @@ snapshots: "@offchainlabs/upgrade-executor@1.1.0-beta.0": dependencies: - "@openzeppelin/contracts": 4.7.3 - "@openzeppelin/contracts-upgradeable": 4.7.3 - - "@openzeppelin/contracts-upgradeable@4.7.3": {} + "@openzeppelin/contracts": 4.9.6 + "@openzeppelin/contracts-upgradeable": 4.9.6 "@openzeppelin/contracts-upgradeable@4.9.6": {} From 66f50e8af9b9c42295261aa383c02f29bb11edce Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Tue, 24 Mar 2026 23:42:03 +0100 Subject: [PATCH 5/6] Override @openzeppelin/contracts-4.7.3 alias to resolve to 4.9.6 --- package.json | 3 +- pnpm-lock.yaml | 89 +++++++++++++++++++++++--------------------------- 2 files changed, 43 insertions(+), 49 deletions(-) diff --git a/package.json b/package.json index c717251..f6ed600 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,8 @@ "overrides": { "minimatch@<3.1.6": ">=3.1.6", "@openzeppelin/contracts@4.7.3": "4.9.6", - "@openzeppelin/contracts-upgradeable@4.7.3": "4.9.6" + "@openzeppelin/contracts-upgradeable@4.7.3": "4.9.6", + "@openzeppelin/contracts-4.7.3": "npm:@openzeppelin/contracts@4.9.6" } }, "author": "Chainlink", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 96978eb..d6fc5c0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,7 @@ overrides: minimatch@<3.1.6: ">=3.1.6" "@openzeppelin/contracts@4.7.3": 4.9.6 "@openzeppelin/contracts-upgradeable@4.7.3": 4.9.6 + "@openzeppelin/contracts-4.7.3": npm:@openzeppelin/contracts@4.9.6 importers: .: @@ -181,7 +182,7 @@ importers: version: 0.9.35(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bs58@5.0.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(typescript@5.9.3) "@solana/wallet-adapter-wallets": specifier: 0.19.32 - version: 0.19.32(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bs58@5.0.0)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.76) + version: 0.19.32(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bs58@5.0.0)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.76) "@solana/web3.js": specifier: 1.98.0 version: 1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) @@ -2728,12 +2729,6 @@ packages: integrity: sha512-m4iHazOsOCv1DgM7eD7GupTJ+NFVujRZt1wzddDPSVGpWdKq1SKkla5htKG7+IS4d2XOCtzkUNwRZ7Vq5aEUMA==, } - "@openzeppelin/contracts@4.7.3": - resolution: - { - integrity: sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw==, - } - "@openzeppelin/contracts@4.8.3": resolution: { @@ -13401,7 +13396,7 @@ snapshots: "@changesets/get-github-info": 0.6.0 "@eslint/eslintrc": 3.3.5 "@eth-optimism/contracts": 0.6.0(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - "@openzeppelin/contracts-4.7.3": "@openzeppelin/contracts@4.7.3" + "@openzeppelin/contracts-4.7.3": "@openzeppelin/contracts@4.9.6" "@openzeppelin/contracts-4.8.3": "@openzeppelin/contracts@4.8.3" "@openzeppelin/contracts-4.9.6": "@openzeppelin/contracts@4.9.6" "@openzeppelin/contracts-5.0.2": "@openzeppelin/contracts@5.0.2" @@ -14921,8 +14916,6 @@ snapshots: "@openzeppelin/contracts-upgradeable@4.9.6": {} - "@openzeppelin/contracts@4.7.3": {} - "@openzeppelin/contracts@4.8.3": {} "@openzeppelin/contracts@4.9.6": {} @@ -16120,30 +16113,30 @@ snapshots: - react-native - typescript - "@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": + "@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - "@solana-program/stake@0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": + "@solana-program/stake@0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana-program/system@0.10.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10))": dependencies: "@solana/kit": 5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) - "@solana-program/system@0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": + "@solana-program/system@0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - "@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))": + "@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/sysvars": 5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": + "@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana-program/token@0.9.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10))": dependencies: @@ -16448,7 +16441,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - "@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/accounts": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/addresses": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -16461,11 +16454,11 @@ snapshots: "@solana/rpc": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/rpc-parsed-types": 2.3.0(typescript@5.9.3) "@solana/rpc-spec-types": 2.3.0(typescript@5.9.3) - "@solana/rpc-subscriptions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/rpc-subscriptions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/rpc-types": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/signers": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/sysvars": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana/transaction-confirmation": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/transaction-confirmation": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/transaction-messages": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/transactions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) typescript: 5.9.3 @@ -16681,14 +16674,14 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - "@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/errors": 2.3.0(typescript@5.9.3) "@solana/functional": 2.3.0(typescript@5.9.3) "@solana/rpc-subscriptions-spec": 2.3.0(typescript@5.9.3) "@solana/subscribable": 2.3.0(typescript@5.9.3) typescript: 5.9.3 - ws: 8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) "@solana/rpc-subscriptions-channel-websocket@5.5.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)": dependencies: @@ -16720,7 +16713,7 @@ snapshots: optionalDependencies: typescript: 5.9.3 - "@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/errors": 2.3.0(typescript@5.9.3) "@solana/fast-stable-stringify": 2.3.0(typescript@5.9.3) @@ -16728,7 +16721,7 @@ snapshots: "@solana/promises": 2.3.0(typescript@5.9.3) "@solana/rpc-spec-types": 2.3.0(typescript@5.9.3) "@solana/rpc-subscriptions-api": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana/rpc-subscriptions-channel-websocket": 2.3.0(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/rpc-subscriptions-channel-websocket": 2.3.0(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/rpc-subscriptions-spec": 2.3.0(typescript@5.9.3) "@solana/rpc-transformers": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/rpc-types": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -16947,7 +16940,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - "@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/addresses": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/codecs-strings": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -16955,7 +16948,7 @@ snapshots: "@solana/keys": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/promises": 2.3.0(typescript@5.9.3) "@solana/rpc": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana/rpc-subscriptions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/rpc-subscriptions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/rpc-types": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/transaction-messages": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/transactions": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -17298,11 +17291,11 @@ snapshots: - supports-color - utf-8-validate - "@solana/wallet-adapter-trezor@0.1.6(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@solana/wallet-adapter-trezor@0.1.6(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@solana/wallet-adapter-base": 0.9.27(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/web3.js": 1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) - "@trezor/connect-web": 9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@trezor/connect-web": 9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) buffer: 6.0.3 transitivePeerDependencies: - "@solana/sysvars" @@ -17365,7 +17358,7 @@ snapshots: - utf-8-validate - zod - "@solana/wallet-adapter-wallets@0.19.32(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bs58@5.0.0)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.76)": + "@solana/wallet-adapter-wallets@0.19.32(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bs58@5.0.0)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@18.3.1(react@18.3.1))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(react@18.3.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@3.25.76)": dependencies: "@solana/wallet-adapter-alpha": 0.1.14(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-avana": 0.1.17(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) @@ -17398,7 +17391,7 @@ snapshots: "@solana/wallet-adapter-tokenary": 0.1.16(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-tokenpocket": 0.4.23(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-torus": 0.11.32(@babel/runtime@7.28.6)(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(utf-8-validate@5.0.10) - "@solana/wallet-adapter-trezor": 0.1.6(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana/wallet-adapter-trezor": 0.1.6(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-trust": 0.1.17(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-unsafe-burner": 0.1.11(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/wallet-adapter-walletconnect": 0.1.21(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -17808,13 +17801,13 @@ snapshots: - react-native - utf-8-validate - "@trezor/blockchain-link@2.6.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@trezor/blockchain-link@2.6.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: - "@solana-program/compute-budget": 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/stake": 0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/token": 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/token-2022": 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana-program/compute-budget": 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/stake": 0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/token": 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/token-2022": 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@solana/rpc-types": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@stellar/stellar-sdk": 14.2.0 "@trezor/blockchain-link-types": 1.5.0(tslib@2.8.1) @@ -17862,9 +17855,9 @@ snapshots: - expo-localization - react-native - "@trezor/connect-web@9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@trezor/connect-web@9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: - "@trezor/connect": 9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@trezor/connect": 9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@trezor/connect-common": 0.5.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1) "@trezor/utils": 9.5.0(tslib@2.8.1) "@trezor/websocket-client": 1.3.0(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@5.0.10) @@ -17883,7 +17876,7 @@ snapshots: - utf-8-validate - ws - "@trezor/connect@9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": + "@trezor/connect@9.7.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))": dependencies: "@ethereumjs/common": 10.1.1 "@ethereumjs/tx": 10.1.1 @@ -17891,12 +17884,12 @@ snapshots: "@mobily/ts-belt": 3.13.1 "@noble/hashes": 1.8.0 "@scure/bip39": 1.6.0 - "@solana-program/compute-budget": 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/system": 0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/token": 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - "@solana-program/token-2022": 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) - "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - "@trezor/blockchain-link": 2.6.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@solana-program/compute-budget": 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/system": 0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/token": 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) + "@solana-program/token-2022": 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) + "@solana/kit": 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + "@trezor/blockchain-link": 2.6.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) "@trezor/blockchain-link-types": 1.5.0(tslib@2.8.1) "@trezor/blockchain-link-utils": 1.5.1(bufferutil@4.1.0)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(utf-8-validate@5.0.10) "@trezor/connect-analytics": 1.4.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(utf-8-validate@5.0.10))(tslib@2.8.1) From 653c4f3d832e731908a809ceba707a040550513e Mon Sep 17 00:00:00 2001 From: aelmanaa Date: Tue, 24 Mar 2026 23:50:33 +0100 Subject: [PATCH 6/6] Add pnpm override for vulnerable undici@5.29.0 --- package.json | 3 ++- pnpm-lock.yaml | 23 ++--------------------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index f6ed600..60bab1a 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,8 @@ "minimatch@<3.1.6": ">=3.1.6", "@openzeppelin/contracts@4.7.3": "4.9.6", "@openzeppelin/contracts-upgradeable@4.7.3": "4.9.6", - "@openzeppelin/contracts-4.7.3": "npm:@openzeppelin/contracts@4.9.6" + "@openzeppelin/contracts-4.7.3": "npm:@openzeppelin/contracts@4.9.6", + "undici@<6.22.0": ">=6.22.0" } }, "author": "Chainlink", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d6fc5c0..cc6d274 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,6 +9,7 @@ overrides: "@openzeppelin/contracts@4.7.3": 4.9.6 "@openzeppelin/contracts-upgradeable@4.7.3": 4.9.6 "@openzeppelin/contracts-4.7.3": npm:@openzeppelin/contracts@4.9.6 + undici@<6.22.0: ">=6.22.0" importers: .: @@ -1860,13 +1861,6 @@ packages: integrity: sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==, } - "@fastify/busboy@2.1.1": - resolution: - { - integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==, - } - engines: { node: ">=14" } - "@fivebinaries/coin-selection@3.0.0": resolution: { @@ -12080,13 +12074,6 @@ packages: integrity: sha512-w9IMgQrz4O0YN1LtB7K5P63vhlIOvC7opSmouCJ+ZywlPAlO9gIkJ+otk6LvGpAs2wg4econaCz3TvQ9xPoyuQ==, } - undici@5.29.0: - resolution: - { - integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==, - } - engines: { node: ">=14.0" } - undici@6.24.0: resolution: { @@ -12847,7 +12834,7 @@ snapshots: "@actions/http-client@2.2.3": dependencies: tunnel: 0.0.6 - undici: 5.29.0 + undici: 6.24.0 "@actions/io@1.1.3": {} @@ -14184,8 +14171,6 @@ snapshots: "@ethersproject/properties": 5.8.0 "@ethersproject/strings": 5.8.0 - "@fastify/busboy@2.1.1": {} - "@fivebinaries/coin-selection@3.0.0": dependencies: "@emurgo/cardano-serialization-lib-browser": 13.2.1 @@ -23649,10 +23634,6 @@ snapshots: undici-types@7.21.0: {} - undici@5.29.0: - dependencies: - "@fastify/busboy": 2.1.1 - undici@6.24.0: {} unidragger@3.0.1: