Skip to content
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

add update files #1

Closed
wants to merge 1 commit into from
Closed
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
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Ian Hecker

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
5 changes: 5 additions & 0 deletions basic-feed/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.env
artifacts/
bun.lockb
cache/
node_modules
62 changes: 62 additions & 0 deletions basic-feed/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Basic Feed

To run a basic data feed:

1. Navigate into the folder

```bash
cd basic-feed
```

2. Install dependencies

```bash
bun install
```

3. Setup the `.env` file inside of the `basic-feed` directory, and add your
private key

```bash
cat << EOF > .env
AGGREGATOR_ID = 0x755c0da00f939b04266f3ba3619ad6498fb936a8bfbfac27c9ecd4ab4c5d4878
CHAIN_ID = 421614
DEPLOYED_CONTRACT_ADDRESS = 0x42E12a6945ab87C3AEeE1601cE9c40da5D43D92A
PRIVATE_KEY = 0x!...YOUR_KEY_HERE...!
RPC_URL = "https://arb-sepolia.g.alchemy.com/v2/!...API_KEY_HERE...!"
SWITCHBOARD_CONTRACT_ADDRESS = 0xa2a0425fa3c5669d384f4e6c8068dfcf64485b3b
EOF
```

Alternate RPC URLs to Alchemy:
- https://sepolia-rollup.arbitrum.io/rpc
- https://mainnet-rollup.arbitrum.io/rpc

You can use the existing configuration - but if you wish to deploy a contract,
be sure to update `DEPLOYED_CONTRACT_ADDRESS` with the new address you receive

4. Contract Deployment (OPTIONAL)

* Hardhat is already configured, and a contract is deployed. To deploy a new
contract, first, compile the contract

```bash
npx hardhat compile
```

* To deploy a contract

```bash
npx hardhat ignition deploy ./ignition/modules/BasicFeed.js --network arbitrumSepolia
```
> Hardhat is finicky after you deploy a contract. You will need to remove
the artifact files Hardhat created for a deployment if you wish to deploy
a second time

* Add your new contract address to the `.env` file

6. To run

```bash
bun run index.ts
```
67 changes: 67 additions & 0 deletions basic-feed/contracts/BasicFeed.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import {ISwitchboard} from "@switchboard-xyz/on-demand-solidity/ISwitchboard.sol";

contract Example {
ISwitchboard switchboard;

// Every Switchboard Feed has a unique aggregatorId.
bytes32 public aggregatorId;

// The latest price from the feed
int256 public latestPrice;

// If the transaction fee is not paid, the update will fail.
error InsufficientFee(uint256 expected, uint256 received);

// If the feed result is invalid, this error will be emitted.
error InvalidResult(int128 result);

// If the Switchboard update succeeds, this event will be emitted with the latest price.
event FeedData(int128 price);

/**
* @param _switchboard The address of the Switchboard contract
* @param _aggregatorId The feed ID for the feed you want to query
*/
constructor(address _switchboard, bytes32 _aggregatorId) {
// Initialize the target _switchboard
// Get the existing Switchboard contract address on your preferred network from the Switchboard Docs
switchboard = ISwitchboard(_switchboard);
aggregatorId = _aggregatorId;
}

/**
* getFeedData is a function that uses an encoded Switchboard update
* If the update is successful, it will read the latest price from the feed
* See below for fetching encoded updates (e.g., using the Switchboard Typescript SDK)
* @param updates Encoded feed updates to update the contract with the latest result
*/
function getFeedData(bytes[] calldata updates) public payable {
// Get the fee for updating the feeds. If the transaction fee is not paid, the update will fail.
uint256 fee = switchboard.getFee(updates);
if (msg.value < fee) {
revert InsufficientFee(fee, msg.value);
}

// Submit the updates to the Switchboard contract
switchboard.updateFeeds{value: fee}(updates);

// Read the current value from a Switchboard feed.
// This will fail if the feed doesn't have fresh updates ready (e.g. if the feed update failed)
// Get the latest feed result
// This is encoded as decimal * 10^18 to avoid floating point issues
int128 result = switchboard.latestUpdate(aggregatorId).result;

// In this example, we revert if the result is negative
if (result < 0) {
revert InvalidResult(result);
}

latestPrice = result;

// Emit the latest result from the feed
emit FeedData(result);
}
}
6 changes: 6 additions & 0 deletions basic-feed/hardhat.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require("@nomicfoundation/hardhat-toolbox");

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.24",
};
17 changes: 17 additions & 0 deletions basic-feed/ignition/modules/BasicFeed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";

const SWITCHBOARD_CONTRACT_ADDRESS = process.env.SWITCHBOARD_CONTRACT_ADDRESS;
if (!SWITCHBOARD_CONTRACT_ADDRESS) {
throw new Error("Missing SWITCHBOARD_CONTRACT_ADDRESS");
}

const AGGREGATOR_ID = process.env.AGGREGATOR_ID;
if (!AGGREGATOR_ID) {
throw new Error("Missing AGGREGATOR_ID");
}

export default buildModule("BasicFeedModule", (m) => {
const basicFeed = m.contract("BasicFeed", [SWITCHBOARD_CONTRACT_ADDRESS, AGGREGATOR_ID]);

return { basicFeed };
});
50 changes: 50 additions & 0 deletions basic-feed/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { CrossbarClient } from "@switchboard-xyz/on-demand";
import * as ethers from "ethers";
import * as fs from "fs";

const chainId = process.env.CHAIN_ID as string;
if (!chainId) {
throw new Error("Missing CHAIN_ID");
}

const address = process.env.DEPLOYED_CONTRACT_ADDRESS as string;
if (!address) {
throw new Error("Missing DEPLOYED_CONTRACT_ADDRESS");
}

const privateKey = process.env.PRIVATE_KEY as string;
if (!privateKey) {
throw new Error("Missing PRIVATE_KEY");
}

const rpcURL = process.env.RPC_URL as string;
if (!rpcURL) {
throw new Error("Missing RPC_URL");
}

const provider = new ethers.JsonRpcProvider(rpcURL);

const signerWithProvider = new ethers.Wallet(privateKey, provider);

const ABI = [
"function getFeedData(bytes[] calldata updates) public payable",
"function aggregatorId() public view returns (bytes32)",
"function latestPrice() public view returns (int256)",
];

const crossbar = new CrossbarClient(`https://crossbar.switchboard.xyz`);

const exampleContract = new ethers.Contract(address, ABI, signerWithProvider);

const { encoded } = await crossbar.fetchEVMResults({
chainId: chainId,
aggregatorIds: [await exampleContract.aggregatorId()],
});

const tx = await exampleContract.getFeedData(encoded);

console.log(tx);

console.log("Transaction completed!");

console.log("Value stored in contract: ", await exampleContract.latestPrice());
18 changes: 18 additions & 0 deletions basic-feed/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "example",
"module": "index.ts",
"type": "module",
"devDependencies": {
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
"@types/bun": "latest",
"hardhat": "^2.22.6"
},
"peerDependencies": {
"typescript": "^5.0.0"
},
"dependencies": {
"@switchboard-xyz/on-demand": "^1.2.10",
"@switchboard-xyz/on-demand-solidity": "^0.0.4",
"ethers": "^6.13.1"
}
}
27 changes: 27 additions & 0 deletions basic-feed/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"compilerOptions": {
// Enable latest features
"lib": ["ESNext", "DOM"],
"target": "ESNext",
"module": "ES2022",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,

// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,

// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,

// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false
}
}
3 changes: 3 additions & 0 deletions measure/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.env
bun.lockb
node_modules/
41 changes: 41 additions & 0 deletions measure/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Measure

To run a measurement:

1. Navigate into the folder

```bash
cd measure
```

2. Install dependencies

```bash
bun install
```

3. Setup the `.env` file inside of the `measure` directory, and add your
private key

```bash
cat << EOF > .env
CHAIN_ID = 421614
COINMARKETCAP_API_KEY = "!...API_KEY_HERE...!"
DEPLOYED_CONTRACT_ADDRESS = 0x42E12a6945ab87C3AEeE1601cE9c40da5D43D92A
PRIVATE_KEY = 0x!...YOUR_KEY_HERE...!
RPC_URL = "https://arb-sepolia.g.alchemy.com/v2/!...API_KEY_HERE...!"
EOF
```

Alternate RPC URLs to Alchemy:
- https://sepolia-rollup.arbitrum.io/rpc
- https://mainnet-rollup.arbitrum.io/rpc

You can use the existing configuration - but if you wish to deploy a contract,
be sure to update `BASIC_FEED_CONTRACT_ADDRESS` with the new address you receive

4. To run

```bash
bun run index.ts
```
Loading