-
Notifications
You must be signed in to change notification settings - Fork 440
Hardhat Getting Started Guide #1824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
c56b6d8
init
khadni b46623b
link fix
khadni 32d5764
sidebar update
khadni 0bcb2c3
nit
khadni e10193a
links fix
khadni 2ea9a22
links fix
khadni a36a38c
Refactor deployment scripts into Hardhat tasks + clarifications
khadni 5116c48
Apply suggestions from code review
khadni 55b8447
Merge branch 'main' into streams/getting-started-hardhat
khadni b1a831f
nit
khadni 05924e9
nit
khadni acaa6c7
nit
khadni 3b83d7a
Merge branch 'main' into streams/getting-started-hardhat
khadni d96413c
Update links to Hardhat repo
khadni 06f8eff
Update links to Hardhat repo
khadni fdef233
Clarifications
khadni 88ab8ae
Merge branch 'main' into streams/getting-started-hardhat
khadni e835bda
Apply suggestions from code review
khadni bb75708
Links fix
khadni File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.16; | ||
|
||
import {Common} from "@chainlink/contracts/src/v0.8/libraries/Common.sol"; | ||
import {StreamsLookupCompatibleInterface} from "@chainlink/contracts/src/v0.8/automation/interfaces/StreamsLookupCompatibleInterface.sol"; | ||
import {ILogAutomation, Log} from "@chainlink/contracts/src/v0.8/automation/interfaces/ILogAutomation.sol"; | ||
import {IRewardManager} from "@chainlink/contracts/src/v0.8/llo-feeds/interfaces/IRewardManager.sol"; | ||
import {IVerifierFeeManager} from "@chainlink/contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol"; | ||
import {IERC20} from "@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC20.sol"; | ||
import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol"; | ||
|
||
/** | ||
* THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE FOR DEMONSTRATION PURPOSES. | ||
* DO NOT USE THIS CODE IN PRODUCTION. | ||
*/ | ||
|
||
/** | ||
* @dev Defines the parameters required to register a new upkeep. | ||
* @param name The name of the upkeep to be registered. | ||
* @param encryptedEmail An encrypted email address associated with the upkeep (optional). | ||
* @param upkeepContract The address of the contract that requires upkeep. | ||
* @param gasLimit The maximum amount of gas to be used for the upkeep execution. | ||
* @param adminAddress The address that will have administrative privileges over the upkeep. | ||
* @param triggerType An identifier for the type of trigger that initiates the upkeep (`1` for event-based). | ||
* @param checkData Data passed to the checkUpkeep function to simulate conditions for triggering upkeep. | ||
* @param triggerConfig Configuration parameters specific to the trigger type. | ||
* @param offchainConfig Off-chain configuration data, if applicable. | ||
* @param amount The amount of LINK tokens to fund the upkeep registration. | ||
*/ | ||
struct RegistrationParams { | ||
string name; | ||
bytes encryptedEmail; | ||
address upkeepContract; | ||
uint32 gasLimit; | ||
address adminAddress; | ||
uint8 triggerType; | ||
bytes checkData; | ||
bytes triggerConfig; | ||
bytes offchainConfig; | ||
uint96 amount; | ||
} | ||
|
||
/** | ||
* @dev Interface for the Automation Registrar contract. | ||
*/ | ||
interface AutomationRegistrarInterface { | ||
/** | ||
* @dev Registers a new upkeep contract with Chainlink Automation. | ||
* @param requestParams The parameters required for the upkeep registration, encapsulated in `RegistrationParams`. | ||
* @return upkeepID The unique identifier for the registered upkeep, used for future interactions. | ||
*/ | ||
function registerUpkeep( | ||
RegistrationParams calldata requestParams | ||
) external returns (uint256); | ||
} | ||
|
||
// Custom interfaces for Data Streams: IVerifierProxy and IFeeManager | ||
interface IVerifierProxy { | ||
function verify( | ||
bytes calldata payload, | ||
bytes calldata parameterPayload | ||
) external payable returns (bytes memory verifierResponse); | ||
|
||
function s_feeManager() external view returns (IVerifierFeeManager); | ||
} | ||
|
||
interface IFeeManager { | ||
function getFeeAndReward( | ||
address subscriber, | ||
bytes memory unverifiedReport, | ||
address quoteAddress | ||
) external returns (Common.Asset memory, Common.Asset memory, uint256); | ||
|
||
function i_linkAddress() external view returns (address); | ||
|
||
function i_nativeAddress() external view returns (address); | ||
|
||
function i_rewardManager() external view returns (address); | ||
} | ||
|
||
contract StreamsUpkeepRegistrar is | ||
ILogAutomation, | ||
StreamsLookupCompatibleInterface | ||
{ | ||
LinkTokenInterface public immutable i_link; | ||
AutomationRegistrarInterface public immutable i_registrar; | ||
|
||
struct BasicReport { | ||
bytes32 feedId; // The feed ID the report has data for | ||
uint32 validFromTimestamp; // Earliest timestamp for which price is applicable | ||
uint32 observationsTimestamp; // Latest timestamp for which price is applicable | ||
uint192 nativeFee; // Base cost to validate a transaction using the report, denominated in the chain’s native token (WETH/ETH) | ||
uint192 linkFee; // Base cost to validate a transaction using the report, denominated in LINK | ||
uint32 expiresAt; // Latest timestamp where the report can be verified onchain | ||
int192 price; // DON consensus median price, carried to 8 decimal places | ||
} | ||
|
||
struct PremiumReport { | ||
bytes32 feedId; // The feed ID the report has data for | ||
uint32 validFromTimestamp; // Earliest timestamp for which price is applicable | ||
uint32 observationsTimestamp; // Latest timestamp for which price is applicable | ||
uint192 nativeFee; // Base cost to validate a transaction using the report, denominated in the chain’s native token (WETH/ETH) | ||
uint192 linkFee; // Base cost to validate a transaction using the report, denominated in LINK | ||
uint32 expiresAt; // Latest timestamp where the report can be verified onchain | ||
int192 price; // DON consensus median price, carried to 8 decimal places | ||
int192 bid; // Simulated price impact of a buy order up to the X% depth of liquidity utilisation | ||
int192 ask; // Simulated price impact of a sell order up to the X% depth of liquidity utilisation | ||
} | ||
|
||
struct Quote { | ||
address quoteAddress; | ||
} | ||
|
||
event PriceUpdate(int192 indexed price); | ||
|
||
IVerifierProxy public verifier; | ||
|
||
address public FEE_ADDRESS; | ||
string public constant DATASTREAMS_FEEDLABEL = "feedIDs"; | ||
string public constant DATASTREAMS_QUERYLABEL = "timestamp"; | ||
int192 public s_last_retrieved_price; | ||
uint256 s_upkeepID; | ||
bytes public s_LogTriggerConfig; | ||
|
||
// Find a complete list of IDs at https://docs.chain.link/data-streams/stream-ids | ||
string[] public feedIds; | ||
|
||
constructor( | ||
address _verifier, | ||
LinkTokenInterface link, | ||
AutomationRegistrarInterface registrar, | ||
string[] memory _feedIds | ||
) { | ||
verifier = IVerifierProxy(_verifier); | ||
i_link = link; | ||
i_registrar = registrar; | ||
feedIds = _feedIds; | ||
} | ||
|
||
/** | ||
* @notice Registers a new upkeep using the specified parameters and predicts its ID. | ||
* @dev This function first approves the transfer of LINK tokens specified in `params.amount` to the Automation Registrar contract. | ||
* It then registers the upkeep and stores its ID if registration is successful. | ||
* Reverts if auto-approve is disabled or registration fails. | ||
* @param params The registration parameters, including name, upkeep contract address, gas limit, admin address, trigger type, and funding amount. | ||
*/ | ||
function registerAndPredictID(RegistrationParams memory params) public { | ||
i_link.approve(address(i_registrar), params.amount); | ||
uint256 upkeepID = i_registrar.registerUpkeep(params); | ||
if (upkeepID != 0) { | ||
s_upkeepID = upkeepID; // DEV - Use the upkeepID however you see fit | ||
} else { | ||
revert("auto-approve disabled"); | ||
} | ||
} | ||
|
||
// This function uses revert to convey call information. | ||
// See https://eips.ethereum.org/EIPS/eip-3668#rationale for details. | ||
function checkLog( | ||
Log calldata log, | ||
bytes memory | ||
) external returns (bool upkeepNeeded, bytes memory performData) { | ||
revert StreamsLookup( | ||
DATASTREAMS_FEEDLABEL, | ||
feedIds, | ||
DATASTREAMS_QUERYLABEL, | ||
log.timestamp, | ||
"" | ||
); | ||
} | ||
|
||
// The Data Streams report bytes is passed here. | ||
// extraData is context data from feed lookup process. | ||
// Your contract may include logic to further process this data. | ||
// This method is intended only to be simulated offchain by Automation. | ||
// The data returned will then be passed by Automation into performUpkeep | ||
function checkCallback( | ||
bytes[] calldata values, | ||
bytes calldata extraData | ||
) external pure returns (bool, bytes memory) { | ||
return (true, abi.encode(values, extraData)); | ||
} | ||
|
||
// function will be performed onchain | ||
function performUpkeep(bytes calldata performData) external { | ||
// Decode the performData bytes passed in by CL Automation. | ||
// This contains the data returned by your implementation in checkCallback(). | ||
(bytes[] memory signedReports, bytes memory extraData) = abi.decode( | ||
performData, | ||
(bytes[], bytes) | ||
); | ||
|
||
bytes memory unverifiedReport = signedReports[0]; | ||
|
||
(, /* bytes32[3] reportContextData */ bytes memory reportData) = abi | ||
.decode(unverifiedReport, (bytes32[3], bytes)); | ||
|
||
// Report verification fees | ||
IFeeManager feeManager = IFeeManager(address(verifier.s_feeManager())); | ||
IRewardManager rewardManager = IRewardManager( | ||
address(feeManager.i_rewardManager()) | ||
); | ||
|
||
address feeTokenAddress = feeManager.i_linkAddress(); | ||
(Common.Asset memory fee, , ) = feeManager.getFeeAndReward( | ||
address(this), | ||
reportData, | ||
feeTokenAddress | ||
); | ||
|
||
// Approve rewardManager to spend this contract's balance in fees | ||
IERC20(feeTokenAddress).approve(address(rewardManager), fee.amount); | ||
|
||
// Verify the report | ||
bytes memory verifiedReportData = verifier.verify( | ||
unverifiedReport, | ||
abi.encode(feeTokenAddress) | ||
); | ||
|
||
// Decode verified report data into BasicReport struct | ||
BasicReport memory verifiedReport = abi.decode( | ||
verifiedReportData, | ||
(BasicReport) | ||
); | ||
|
||
// Log price from report | ||
emit PriceUpdate(verifiedReport.price); | ||
|
||
// Store the price from the report | ||
s_last_retrieved_price = verifiedReport.price; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
--- | ||
section: dataStreams | ||
date: Last Modified | ||
title: "Getting Started with Chainlink Data Streams using the Hardhat CLI" | ||
metadata: | ||
linkToWallet: true | ||
excerpt: "Learn the basics for how to get data from Chainlink Data Streams." | ||
whatsnext: { | ||
"Find the list of available stream IDs.": "/data-streams/stream-ids", | ||
"Find the schema of data to expect from Data Streams reports.": "/data-streams/reference/report-schema", | ||
"Learn more about Log Trigger upkeeps": "/chainlink-automation/guides/log-trigger/", | ||
} | ||
--- | ||
|
||
import { Aside } from "@components" | ||
import DataStreams from "@features/data-streams/common/DataStreams.astro" | ||
|
||
<Aside type="note" title="Mainnet Access"> | ||
Chainlink Data Streams is available on Arbitrum Mainnet and Arbitrum Sepolia. | ||
</Aside> | ||
|
||
<Aside type="note" title="Talk to an expert"> | ||
<a href="https://chainlinkcommunity.typeform.com/datastreams?#ref_id=docs">Contact us</a> to talk to an expert about | ||
integrating Chainlink Data Streams with your applications. | ||
</Aside> | ||
|
||
<DataStreams section="gettingStartedHardhat" /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,14 @@ | ||
--- | ||
const GettingStarted = await Astro.glob("./gettingStarted.mdx") | ||
const GettingStartedComponent = GettingStarted[0].Content | ||
const GettingStartedHardhat = await Astro.glob("./gettingStartedHardhat.mdx") | ||
const GettingStartedHardhatComponent = GettingStartedHardhat[0].Content | ||
|
||
export type Props = { | ||
section?: "gettingStarted" | ||
section?: "gettingStarted" | "gettingStartedHardhat" | ||
} | ||
const { section } = Astro.props as Props | ||
--- | ||
|
||
{section === "gettingStarted" && <GettingStartedComponent />} | ||
{section === "gettingStartedHardhat" && <GettingStartedHardhatComponent />} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.