Skip to content

Update Streams for beta.1 contracts #1829

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 1 commit into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
2 changes: 1 addition & 1 deletion public/samples/DataStreams/StreamsUpkeep.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
pragma solidity 0.8.19;

import {Common} from "@chainlink/contracts/src/v0.8/llo-feeds/libraries/Common.sol";
import {StreamsLookupCompatibleInterface} from "@chainlink/contracts/src/v0.8/automation/interfaces/StreamsLookupCompatibleInterface.sol";
Expand Down
22 changes: 19 additions & 3 deletions public/samples/DataStreams/StreamsUpkeepRegistrar.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
pragma solidity 0.8.19;

import {Common} from "@chainlink/contracts/src/v0.8/libraries/Common.sol";
import {Common} from "@chainlink/contracts/src/v0.8/llo-feeds/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 {IERC20} from "@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC20.sol";
import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol";

/**
Expand Down Expand Up @@ -154,6 +154,22 @@ contract StreamsUpkeepRegistrar is
}
}

/**
* @notice this is a new, optional function in streams lookup. It is meant to surface streams lookup errors.
* @return upkeepNeeded boolean to indicate whether the keeper should call performUpkeep or not.
* @return performData bytes that the keeper should call performUpkeep with, if
* upkeep is needed. If you would like to encode data to decode later, try `abi.encode`.
*/
function checkErrorHandler(
uint256 /*errCode*/,
bytes memory /*extraData*/
) external pure returns (bool upkeepNeeded, bytes memory performData) {
return (true, "0");
// Hardcoded to always perform upkeep.
// Read the StreamsLookup error handler guide for more information.
// https://docs.chain.link/chainlink-automation/guides/streams-lookup-error-handler
}

// This function uses revert to convey call information.
// See https://eips.ethereum.org/EIPS/eip-3668#rationale for details.
function checkLog(
Expand Down
46 changes: 36 additions & 10 deletions src/features/data-streams/common/gettingStarted.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,17 @@ This example uses a [Chainlink Automation Log Trigger](/chainlink-automation/gui
- Testnet LINK is available for Arbitrum Sepolia at [faucets.chain.link](https://faucets.chain.link/arbitrum-sepolia).
- Learn how to [Fund your contract with LINK](/resources/fund-your-contract).

## Deploy the Chainlink Automation upkeep contract
## Tutorial

### Deploy the Chainlink Automation upkeep contract

Deploy an upkeep contract that is enabled to retrieve data from Data Streams. For this example, you will read from the ETH/USD stream with ID `0x00027bbaff688c906a3e20a34fe951715d1018d262a5b66e38eda027a674cd1b` on Arbitrum Sepolia. See the [Stream Identifiers](/data-streams/stream-ids) page for a complete list of available assets, IDs, and verifier proxy addresses.

1. [Open the StreamsUpkeep.sol](https://remix.ethereum.org/#url=https://docs.chain.link/samples/DataStreams/StreamsUpkeep.sol) contract in Remix.

<CodeSample src="samples/DataStreams/StreamsUpkeep.sol" showButtonOnly />

1. Select the `0.8.16` Solidity compiler and the `StreamsUpkeep.sol` contract in the **Solidity Compiler** tab.
1. Select the `StreamsUpkeep.sol` contract in the **Solidity Compiler** tab.

<ClickToZoom
src="/images/data-streams/getting-started/solidity-compiler.webp"
Expand Down Expand Up @@ -79,7 +81,7 @@ Deploy an upkeep contract that is enabled to retrieve data from Data Streams. Fo
style="max-width: 70%;"
/>

## Deploy the emitter contract
### Deploy the emitter contract

This contract emits logs that trigger the upkeep. This code can be part of your dApp. For example, you might emit log triggers when your users initiate a trade or other action requiring data retrieval. For this Getting Started guide, use a very simple emitter so you can test the upkeep and data retrieval.

Expand Down Expand Up @@ -121,7 +123,7 @@ This contract emits logs that trigger the upkeep. This code can be part of your
style="max-width: 70%;"
/>

## Register the upkeep
### Register the upkeep

Register a new **Log trigger** upkeep. See [Automation Log Triggers](/chainlink-automation/guides/log-trigger) to learn more about how to register Log Trigger upkeeps.

Expand Down Expand Up @@ -151,7 +153,7 @@ Register a new **Log trigger** upkeep. See [Automation Log Triggers](/chainlink-

1. Leave the **Check data** value and other fields blank for now, and click **Register Upkeep**. MetaMask prompts you to confirm the transaction. Wait for the transaction to complete.

## Fund the upkeep contract
### Fund the upkeep contract

In this example, the upkeep contract pays for onchain verification of reports from Data Streams. The Automation subscription does not cover the cost.

Expand All @@ -163,7 +165,7 @@ Open MetaMask and send 1 testnet LINK on _Arbitrum Sepolia_ to the upkeep contra
style="max-width: 70%;"
/>

## Emit a log
### Emit a log

Now, you can use your emitter contract to emit a log and initiate the upkeep, which retrieves data for the specified Data Streams asset ID.

Expand All @@ -181,7 +183,7 @@ After the transaction is complete, the log is emitted, and the upkeep is trigger

<ClickToZoom src="/images/data-streams/getting-started/request-fulfilled.webp" />

## View the retrieved price
### View the retrieved price

The retrieved price is stored as a variable in the contract and emitted in the logs.

Expand All @@ -199,8 +201,32 @@ Alternatively, you can view the price emitted in the logs for your upkeep transa

## Examine the code

The example code you deployed has all the interfaces and functions required to work with Chainlink Automation as an upkeep contract. It follows a similar flow to the trading flow in the [Architecture](/data-streams#example-trading-flow) documentation but uses a basic log emitter to simulate the client contract that would initiate a `StreamsLookup`. After the contract receives and verifies the report, `performUpkeep` stores the price from the report in the `last_retrieved_price` and emits a `PriceUpdate` log message with the price. You could modify this to use the data in a way that works for your specific use case and application.

The code example uses `revert` with `StreamsLookup` to convey call information about what streams to retrieve. See the [EIP-3668 rationale](https://eips.ethereum.org/EIPS/eip-3668#rationale) for more information about how to use `revert` in this way.
The example code you deployed has all the interfaces and functions required to work with Chainlink Automation as an upkeep contract. It follows a similar flow to the trading flow in the [Architecture](/data-streams#example-trading-flow) documentation but uses a basic log emitter to simulate the client contract that would initiate a `StreamsLookup`. The code example uses `revert` with `StreamsLookup` to convey call information about what streams to retrieve. See the [EIP-3668 rationale](https://eips.ethereum.org/EIPS/eip-3668#rationale) for more information about how to use `revert` in this way.

<CodeSample src="samples/DataStreams/StreamsUpkeep.sol" />

### Initializing the upkeep contract

When deploying the contract, you define the verifier proxy address for the Data Streams feed you want to read from. You can find this address on the [Data Streams Feed IDs](/data-streams/stream-ids) page. The verifier proxy address provides functions that are required for this example:

- The `s_feeManager` function to estimate the verification fees.
- The `verify` function to verify the report onchain.

### Emitting a log, retrieving, and verifying the report

After registering your upkeep contract with Chainlink Automation with a log trigger, you can emit a log with the `emitLog` function from your emitter contract.

1. The emitted log triggers the Chainlink Automation upkeep.
2. Chainlink Automation then uses `StreamsLookup` to retrieve a signed report from the Data Streams Engine, returns the data in a callback (`checkCallback`), and runs the `performUpkeep` function on your registered upkeep contract.
3. The `performUpkeep` function calls the `verify` function on the verifier contract to verify the report onchain.
4. In this example, the `performUpkeep` function also stores the price from the report in the `last_retrieved_price` state variable and emits a `PriceUpdate` log message with the price.

### Viewing the retrieved price

The `last_retrieved_price` getter function of your upkeep contract retrieves the last price stored by the `performUpkeep` function in the `last_retrieved_price` state variable of the `StreamsUpkeep` contract. Additionally, the `performUpkeep` function emits a `PriceUpdate` log message with the retrieved price.

### Optional: Handle Data Streams fetching errors offchain with `checkErrorHandler`

When Automation detects the triggering event, it runs the `checkLog` function of your upkeep contract, which includes a `StreamsLookup` revert custom error. The `StreamsLookup` revert enables your upkeep to fetch a report from Data Streams. If the report is fetched successfully, the `checkCallback` function is evaluated offchain. Otherwise, the `checkErrorHandler` function is evaluated offchain to determine what Automation should do next.

In this example, the `checkErrorHandler` is set to always return `true` for `upkeepNeeded`. This implies that the upkeep is always triggered, even if the report fetching fails. You can modify the `checkErrorHandler` function to handle errors offchain in a way that works for your specific use case. Read more about [using the StreamsLookup error handler](/chainlink-automation/guides/streams-lookup-error-handler).
12 changes: 8 additions & 4 deletions src/features/data-streams/common/gettingStartedHardhat.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,7 @@ You can find the upkeep transaction hash at [Chainlink Automation UI](https://au

## Examine the code

The example code you deployed has all the interfaces and functions required to work with Chainlink Automation as an upkeep contract. It follows a similar flow to the trading flow in the [Architecture](/data-streams#example-trading-flow) documentation but uses a basic log emitter to simulate the client contract that would initiate a `StreamsLookup`. After the contract receives and verifies the report, `performUpkeep` stores the price from the report in the `s_last_retrieved_price` and emits a `PriceUpdate` log message with the price. You could modify this to use the data in a way that works for your specific use case and application.

The code example uses `revert` with `StreamsLookup` to convey call information about what streams to retrieve. See the [EIP-3668 rationale](https://eips.ethereum.org/EIPS/eip-3668#rationale) for more information about how to use `revert` in this way.
The example code you deployed has all the interfaces and functions required to work with Chainlink Automation as an upkeep contract. It follows a similar flow to the trading flow in the [Architecture](/data-streams#example-trading-flow) documentation but uses a basic log emitter to simulate the client contract that would initiate a `StreamsLookup`. The code example uses `revert` with `StreamsLookup` to convey call information about what streams to retrieve. See the [EIP-3668 rationale](https://eips.ethereum.org/EIPS/eip-3668#rationale) for more information about how to use `revert` in this way.

<CodeSample src="samples/DataStreams/StreamsUpkeepRegistrar.sol" />

Expand Down Expand Up @@ -212,4 +210,10 @@ You can use the [`emitLog` task](https://github.com/smartcontractkit/smart-contr

### Viewing the retrieved price

The [`getLastRetrievedPrice`](https://github.com/smartcontractkit/smart-contract-examples/blob/main/data-streams/getting-started/hardhat/tasks/getLastRetrievedPrice.js) Hardhat task retrieves the last price updated by the `performUpkeep` function in the `s_last_retrieved_price` state variable of the `StreamsUpkeep` contract.
The [`getLastRetrievedPrice`](https://github.com/smartcontractkit/smart-contract-examples/blob/main/data-streams/getting-started/hardhat/tasks/getLastRetrievedPrice.js) Hardhat task retrieves the last price updated by the `performUpkeep` function in the `s_last_retrieved_price` state variable of the `StreamsUpkeepRegistrar` contract.

### Optional: Handle Data Streams fetching errors offchain with `checkErrorHandler`

When Automation detects the triggering event, it runs the `checkLog` function of your upkeep contract, which includes a `StreamsLookup` revert custom error. The `StreamsLookup` revert enables your upkeep to fetch a report from Data Streams. If the report is fetched successfully, the `checkCallback` function is evaluated offchain. Otherwise, the `checkErrorHandler` function is evaluated offchain to determine what Automation should do next.

In this example, the `checkErrorHandler` is set to always return `true` for `upkeepNeeded`. This implies that the upkeep is always triggered, even if the report fetching fails. You can modify the `checkErrorHandler` function to handle errors offchain in a way that works for your specific use case. Read more about [using the StreamsLookup error handler](/chainlink-automation/guides/streams-lookup-error-handler).