Explore docs & resources

Start your Chainlink journey
Learn & Explore
Explore Cross-Chain Interoperability with CCIP
Learn cross-chain concepts, workflows, and real-world use cases.
Understand How Data Feeds Power dApps
See how oracle data feeds deliver price feeds and reference data.
Learn How Data Streams Deliver Real-Time Data
Understand how low-latency streams support time-sensitive applications.
Discover Off-Chain Compute with Functions
Learn how Functions connect smart contracts to APIs and custom logic.
Build & Integrate
Build Cross-Chain Apps with CCIP Tutorials
Follow step-by-step guides with language switching (EVM, Rust, Move, etc.).
Integrate Data Feeds into Smart Contracts
Plug feeds into your apps with examples and addresses.
Implement Real-Time Use Cases with Data Streams
Use low-latency data in trading, gaming, and other live applications.
Connect Contracts to APIs with Functions
Add external data and custom logic to your dApps.
Operate & Scale
Monitor CCIP Transactions in Real Time
Track the progress and status of cross-chain transactions.
Stay Up to Date with Data Feeds
Rely on changelogs and schema updates for accuracy.
Deliver Reliable Low-Latency Data with Streams
Operate Data Streams at scale for critical, time-sensitive use cases.
Scale and Optimize Functions
Debug, manage workloads, and grow your applications.
Try it out
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {FunctionsClient} from "@chainlink/contracts/src/v0.8/functions/v1_0_0/FunctionsClient.sol";
import {FunctionsRequest} from "@chainlink/contracts/src/v0.8/functions/v1_0_0/libraries/FunctionsRequest.sol";
import {ConfirmedOwner} from "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
/**
* THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY.
* THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
* DO NOT USE THIS CODE IN PRODUCTION.
*/
contract FunctionsConsumerDecoder is FunctionsClient, ConfirmedOwner {
using FunctionsRequest for FunctionsRequest.Request;
bytes32 public s_lastRequestId;
bytes public s_lastResponse;
bytes public s_lastError;
uint256 public s_answer;
uint256 public s_updatedAt;
uint8 public s_decimals;
string public s_description;
error UnexpectedRequestID(bytes32 requestId);
event Response(bytes32 indexed requestId, bytes response, bytes err);
event DecodedResponse(
bytes32 indexed requestId, uint256 answer, uint256 updatedAt, uint8 decimals, string description
);
constructor(
address router
) FunctionsClient(router) ConfirmedOwner(msg.sender) {}
/**
* @notice Send a simple request
* @param source JavaScript source code
* @param encryptedSecretsUrls Encrypted URLs where to fetch user secrets
* @param donHostedSecretsSlotID Don hosted secrets slotId
* @param donHostedSecretsVersion Don hosted secrets version
* @param args List of arguments accessible from within the source code
* @param bytesArgs Array of bytes arguments, represented as hex strings
* @param subscriptionId Billing ID
*/
function sendRequest(
string memory source,
bytes memory encryptedSecretsUrls,
uint8 donHostedSecretsSlotID,
uint64 donHostedSecretsVersion,
string[] memory args,
bytes[] memory bytesArgs,
uint64 subscriptionId,
uint32 gasLimit,
bytes32 donID
) external onlyOwner returns (bytes32 requestId) {
FunctionsRequest.Request memory req;
req.initializeRequestForInlineJavaScript(source);
if (encryptedSecretsUrls.length > 0) {
req.addSecretsReference(encryptedSecretsUrls);
} else if (donHostedSecretsVersion > 0) {
req.addDONHostedSecrets(donHostedSecretsSlotID, donHostedSecretsVersion);
}
if (args.length > 0) req.setArgs(args);
if (bytesArgs.length > 0) req.setBytesArgs(bytesArgs);
s_lastRequestId = _sendRequest(req.encodeCBOR(), subscriptionId, gasLimit, donID);
return s_lastRequestId;
}
/**
* @notice Send a pre-encoded CBOR request
* @param request CBOR-encoded request data
* @param subscriptionId Billing ID
* @param gasLimit The maximum amount of gas the request can consume
* @param donID ID of the job to be invoked
* @return requestId The ID of the sent request
*/
function sendRequestCBOR(
bytes memory request,
uint64 subscriptionId,
uint32 gasLimit,
bytes32 donID
) external onlyOwner returns (bytes32 requestId) {
s_lastRequestId = _sendRequest(request, subscriptionId, gasLimit, donID);
return s_lastRequestId;
}
/**
* @dev Internal function to process the outcome of a data request. It stores the latest response or error and updates
* the contract state accordingly. This function is designed to handle only one of `response` or `err` at a time, not
* both. It decodes the response if present and emits events to log both raw and decoded data.
*
* @param requestId The unique identifier of the request, originally returned by `sendRequest`. Used to match
* responses with requests.
* @param response The raw aggregated response data from the external source. This data is ABI-encoded and is expected
* to contain specific information (e.g., answer, updatedAt) if no error occurred. The function attempts to decode
* this data if `response` is not empty.
* @param err The raw aggregated error information, indicating an issue either from the user's code or within the
* execution of the user Chainlink Function.
*
* Emits a `DecodedResponse` event if the `response` is successfully decoded, providing detailed information about the
* data received.
* Emits a `Response` event for every call to log the raw response and error data.
*
* Requirements:
* - The `requestId` must match the last stored request ID to ensure the response corresponds to the latest request
* sent.
* - Only one of `response` or `err` should contain data for a given call; the other should be empty.
*/
function fulfillRequest(
bytes32 requestId,
bytes memory response,
bytes memory err
) internal override {
if (s_lastRequestId != requestId) {
revert UnexpectedRequestID(requestId);
}
s_lastError = err;
s_lastResponse = response;
if (response.length > 0) {
(uint256 answer, uint256 updatedAt, uint8 decimals, string memory description) =
abi.decode(response, (uint256, uint256, uint8, string));
s_answer = answer;
s_updatedAt = updatedAt;
s_decimals = decimals;
s_description = description;
emit DecodedResponse(requestId, answer, updatedAt, decimals, description);
}
emit Response(requestId, response, err);
}
}
Demos
Custom Data Feed
See how you can bring your financial data onchain in a variety of different ways by creating a Net Asset Value feed, Proof of Reserve feed, or other custom data feed.
Delivery vs. Payment (DvP)
Learn how to sell a variety of assets via a Delivery vs. Payment transaction using the Chainlink Runtime Environment (CRE).
Digital Transfer Agent (DTA)
Learn how to invest in a variety of funds via a Digital Transfer Agent (DTA) transaction using the Chainlink Runtime Environment (CRE).
Explore Chainlink
Explore how the Chainlink standard powers tokenization and onchain finance through
Community Events