Skip to content

Commit 2d6c73a

Browse files
committed
Adds oracle reader contract
1 parent 1f61ca4 commit 2d6c73a

File tree

5 files changed

+251
-3
lines changed

5 files changed

+251
-3
lines changed

packages/hardhat/.env.example

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
# If not set, we provide default values (check `hardhat.config.ts`) so developers can start prototyping out of the box,
66
# but we recommend getting your own API Keys for Production Apps.
77

8+
# The Chronicle ETH/USD oracle on Sepolia.
9+
CHRONICLE_ORACLE=0xdd6D76262Fd7BdDe428dcfCd94386EbAe0151603
10+
# The Chronicle SelfKisser contract on Sepolia.
11+
SELF_KISSER=0x0Dcc19657007713483A5cA76e6A7bbe5f56EA37d
12+
813
# To access the values stored in this .env file you can use: process.env.VARIABLENAME
914
ALCHEMY_API_KEY=
1015
DEPLOYER_PRIVATE_KEY=
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.16;
3+
4+
/**
5+
* @title OracleReader
6+
*
7+
* @notice A simple contract to read from Chronicle oracles
8+
*
9+
* @dev Addresses in this contract are hardcoded for the Sepolia testnet.
10+
* For other supported networks, see https://docs.chroniclelabs.org/.
11+
*/
12+
contract OracleReader {
13+
/// @notice The Chronicle ETH/USD oracle.
14+
IChronicle public immutable chronicle;
15+
16+
/// @notice The SelfKisser granting access to Chronicle oracles.
17+
ISelfKisser public immutable selfKisser;
18+
19+
constructor(address chronicle_, address selfKisser_) {
20+
chronicle = IChronicle(chronicle_);
21+
selfKisser = ISelfKisser(selfKisser_);
22+
23+
// Note to add address(this) to chronicle oracle's whitelist.
24+
// This allows the contract to read from the chronicle oracle.
25+
selfKisser.selfKiss(address(chronicle));
26+
}
27+
28+
/// @notice Function to read the latest data from the Chronicle oracle.
29+
/// @return val The current value returned by the oracle.
30+
function read() external view returns (uint256 val) {
31+
return chronicle.read();
32+
}
33+
}
34+
35+
// Copied from [chronicle-std](https://github.com/chronicleprotocol/chronicle-std/blob/main/src/IChronicle.sol).
36+
interface IChronicle {
37+
/// @notice Returns the oracle's current value.
38+
/// @dev Reverts if no value set.
39+
/// @return value The oracle's current value.
40+
function read() external view returns (uint256 value);
41+
}
42+
43+
// Copied from [self-kisser](https://github.com/chronicleprotocol/self-kisser/blob/main/src/ISelfKisser.sol).
44+
interface ISelfKisser {
45+
/// @notice Kisses caller on oracle `oracle`.
46+
function selfKiss(address oracle) external;
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import * as dotenv from "dotenv";
2+
dotenv.config();
3+
import { HardhatRuntimeEnvironment } from "hardhat/types";
4+
import { DeployFunction } from "hardhat-deploy/types";
5+
import { Contract, getAddress } from "ethers";
6+
7+
/**
8+
* Deploys a contract named "OracleReader" using the deployer account and
9+
* constructor arguments set to the deployer address
10+
*
11+
* @param hre HardhatRuntimeEnvironment object.
12+
*/
13+
const deployOracleReader: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
14+
/*
15+
On localhost, the deployer account is the one that comes with Hardhat, which is already funded.
16+
17+
When deploying to live networks (e.g `yarn deploy --network goerli`), the deployer account
18+
should have sufficient balance to pay for the gas fees for contract creation.
19+
20+
You can generate a random account with `yarn generate` which will fill DEPLOYER_PRIVATE_KEY
21+
with a random private key in the .env file (then used on hardhat.config.ts)
22+
You can run the `yarn account` command to check your balance in every network.
23+
*/
24+
const { deployer } = await hre.getNamedAccounts();
25+
const { deploy } = hre.deployments;
26+
27+
// Read oracle and self-kisser addresses from .env file.
28+
const oracle = getAddress(process.env.CHRONICLE_ORACLE || "");
29+
const selfKisser = getAddress(process.env.SELF_KISSER || "");
30+
31+
await deploy("OracleReader", {
32+
from: deployer,
33+
// Contract constructor arguments
34+
args: [oracle, selfKisser],
35+
log: true,
36+
// autoMine: can be passed to the deploy function to make the deployment process faster on local networks by
37+
// automatically mining the contract deployment transaction. There is no effect on live networks.
38+
autoMine: true,
39+
});
40+
41+
// Get the deployed contract to interact with it after deploying.
42+
const oracleReader = await hre.ethers.getContract<Contract>("OracleReader", deployer);
43+
console.log("👋 The current oracle's value is:", await oracleReader.read());
44+
};
45+
46+
export default deployOracleReader;
47+
48+
// Tags are useful if you have multiple deploy files and only want to run one of them.
49+
// e.g. yarn deploy --tags OracleReader
50+
deployOracleReader.tags = ["OracleReader"];

packages/hardhat/hardhat.config.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ const config: HardhatUserConfig = {
4242
// If the network you are looking for is not here you can add new network settings
4343
hardhat: {
4444
forking: {
45-
url: `https://eth-mainnet.alchemyapi.io/v2/${providerApiKey}`,
46-
enabled: process.env.MAINNET_FORKING_ENABLED === "true",
45+
url: `https://eth-sepolia.g.alchemy.com/v2/${providerApiKey}`,
46+
enabled: process.env.SEPOLIA_FORKING_ENABLED === "true",
4747
},
4848
},
4949
mainnet: {

packages/nextjs/contracts/deployedContracts.ts

+147-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,152 @@
44
*/
55
import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract";
66

7-
const deployedContracts = {} as const;
7+
const deployedContracts = {
8+
31337: {
9+
YourContract: {
10+
address: "0x5FbDB2315678afecb367f032d93F642f64180aa3",
11+
abi: [
12+
{
13+
inputs: [
14+
{
15+
internalType: "address",
16+
name: "_owner",
17+
type: "address",
18+
},
19+
],
20+
stateMutability: "nonpayable",
21+
type: "constructor",
22+
},
23+
{
24+
anonymous: false,
25+
inputs: [
26+
{
27+
indexed: true,
28+
internalType: "address",
29+
name: "greetingSetter",
30+
type: "address",
31+
},
32+
{
33+
indexed: false,
34+
internalType: "string",
35+
name: "newGreeting",
36+
type: "string",
37+
},
38+
{
39+
indexed: false,
40+
internalType: "bool",
41+
name: "premium",
42+
type: "bool",
43+
},
44+
{
45+
indexed: false,
46+
internalType: "uint256",
47+
name: "value",
48+
type: "uint256",
49+
},
50+
],
51+
name: "GreetingChange",
52+
type: "event",
53+
},
54+
{
55+
inputs: [],
56+
name: "greeting",
57+
outputs: [
58+
{
59+
internalType: "string",
60+
name: "",
61+
type: "string",
62+
},
63+
],
64+
stateMutability: "view",
65+
type: "function",
66+
},
67+
{
68+
inputs: [],
69+
name: "owner",
70+
outputs: [
71+
{
72+
internalType: "address",
73+
name: "",
74+
type: "address",
75+
},
76+
],
77+
stateMutability: "view",
78+
type: "function",
79+
},
80+
{
81+
inputs: [],
82+
name: "premium",
83+
outputs: [
84+
{
85+
internalType: "bool",
86+
name: "",
87+
type: "bool",
88+
},
89+
],
90+
stateMutability: "view",
91+
type: "function",
92+
},
93+
{
94+
inputs: [
95+
{
96+
internalType: "string",
97+
name: "_newGreeting",
98+
type: "string",
99+
},
100+
],
101+
name: "setGreeting",
102+
outputs: [],
103+
stateMutability: "payable",
104+
type: "function",
105+
},
106+
{
107+
inputs: [],
108+
name: "totalCounter",
109+
outputs: [
110+
{
111+
internalType: "uint256",
112+
name: "",
113+
type: "uint256",
114+
},
115+
],
116+
stateMutability: "view",
117+
type: "function",
118+
},
119+
{
120+
inputs: [
121+
{
122+
internalType: "address",
123+
name: "",
124+
type: "address",
125+
},
126+
],
127+
name: "userGreetingCounter",
128+
outputs: [
129+
{
130+
internalType: "uint256",
131+
name: "",
132+
type: "uint256",
133+
},
134+
],
135+
stateMutability: "view",
136+
type: "function",
137+
},
138+
{
139+
inputs: [],
140+
name: "withdraw",
141+
outputs: [],
142+
stateMutability: "nonpayable",
143+
type: "function",
144+
},
145+
{
146+
stateMutability: "payable",
147+
type: "receive",
148+
},
149+
],
150+
inheritedFunctions: {},
151+
},
152+
},
153+
} as const;
8154

9155
export default deployedContracts satisfies GenericContractsDeclaration;

0 commit comments

Comments
 (0)