protocols/chainlink-integration

Chainlink Integration Guide

ethereumguide🏛️ Officialconfidence highhealth -2%
v1.0.0·Updated 3/20/2026

Installation

npm install @chainlink/contracts

Price Feeds (Most Commonly Used)

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

contract PriceConsumer {
  AggregatorV3Interface internal priceFeed;
  
  // ETH/USD on Ethereum: 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
  constructor() { priceFeed = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419); }
  
  function getLatestPrice() public view returns (int) {
    (, int price,,,) = priceFeed.latestRoundData();
    return price; // 8 decimals: 200000000000 = $2000
  }
}

Main Price Feed Addresses (Mainnet)

PairAddress
ETH/USD0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
BTC/USD0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c
USDC/USD0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6
LINK/USD0x2c1d072e956AFFC0D435Cb7AC38EF18d24d9127c

Complete list: https://docs.chain.link/data-feeds/price-feeds/addresses

VRF V2.5 (On-chain Randomness)

import "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2Plus.sol";

contract RandomGame is VRFConsumerBaseV2Plus {
  uint256 public s_subscriptionId; // Create and fund with LINK at vrf.chain.link
  
  function requestRandom() external returns (uint256 requestId) {
    return s_vrfCoordinator.requestRandomWords(
      VRFV2PlusClient.RandomWordsRequest({
        keyHash: 0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae, // 500 gwei key hash
        subId: s_subscriptionId,
        requestConfirmations: 3,
        callbackGasLimit: 100000,
        numWords: 1,
        extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: false}))
      })
    );
  }
  
  function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal override {
    uint256 result = randomWords[0] % 100; // Random number from 0-99
  }
}

CCIP (Cross-Chain Messaging)

import "@chainlink/contracts-ccip/src/v0.8/CCIPReceiver.sol";
import "@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol";

// Send cross-chain message
IRouterClient router = IRouterClient(0xE561d5E02641c58De07aCE84dDF4D9F3abDed3c1); // Ethereum Sepolia
Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({
  receiver: abi.encode(destinationAddress),
  data: abi.encode(payload),
  tokenAmounts: new Client.EVMTokenAmount[](0),
  feeToken: address(linkToken),
  extraArgs: ""
});
uint256 fee = router.getFee(destinationChainSelector, message);
IERC20(linkToken).approve(address(router), fee);
router.ccipSend(destinationChainSelector, message);

Automation (Scheduled Contract Execution)

import "@chainlink/contracts/src/v0.8/automation/AutomationCompatible.sol";

contract AutoTask is AutomationCompatibleInterface {
  function checkUpkeep(bytes calldata) external view override returns (bool upkeepNeeded, bytes memory) {
    upkeepNeeded = (block.timestamp - lastTimeStamp) > interval;
  }
  
  function performUpkeep(bytes calldata) external override {
    // Logic to execute on schedule
  }
}

Common Pitfalls

  • Price feeds have heartbeat intervals (ETH/USD is 1 hour), need to check if updatedAt is stale
  • VRF subscription requires sufficient LINK, insufficient balance will cause callback failures
  • CCIP cross-chain fees are paid in LINK or native token, query getFee in advance