Add observable web3 addresses to your KPR Cloud config
npm install @kpr-labs/observablesKPR allows you to create custom dashboards and visualization via our api. All supported charts are specified below, with examples. KPR data charts are generic and unopinionated. The graphs will display and fetch any data as long as you honor the API contract.
1. The web app hosted on https://kprlabs.io connects to your local node. For the cloud hosted version of this please reach out to omer@kprlabs.io. I recommend spinning up a node using hardhat. However, any node that supports gRPC and listening on localhost:8545 should work.
2. In your terminal spin up a node with npx hardhat node. You can also spin up a local fork with Alchemy if you have a key. npx --max-old-space-size=8192 hardhat node --fork https://eth-mainnet.alchemyapi.io/v2/
3. We'll want to deploy some contracts to our local chain. We'll later query our contracts and display the data. Let's clone our demo repo with git clone https://github.com/Arieg419/chaos-labs-example-repo.
4. Navigate to your cloned repo. This should look something like cd ~/dev/demo-repo
5. Compile and deploy the contracts in the example repo with npx hardhat run scripts/deploy.js --network localhost
6. View Observable Widgets on https://kprlabs.io
7. Profit 🎉🎉🥳🥳
KPR deployments and chart definitions can be seen in https://github.com/Arieg419/chaos-labs-example-repo/blob/master/scripts/deploy.js and chart specific helper scripts (histogram-deploy.js, stat-card-deploy.js...)
Adding KPR to your project is easy. Let's get started.
1. npm install @kpr-labs/observables
2. Initialize the KPR module with initKPR({ API_URL, API_ENDPOINT: SPECTRAL_ENDPOINT, API_KEY: "
3. Start defining your charts!
Let's walk through examples with all of our charts.
Initialize KPR Config Object
``js
const {
initKPR,
addObservables,
deployObservables,
} = require("@kpr-labs/observables");
const API_URL = "https://kpr-server.herokuapp.com";
const SPECTRAL_ENDPOINT = "/cloud/server/spectral/config";
initKPR({ API_URL, API_ENDPOINT: SPECTRAL_ENDPOINT, API_KEY: "
`
Observables are smart contract accounts or EOA (externally owned account) that you want to keep track of. Every address provided will result in a corresponding dashboard widget.
`js
// Add Observable Data
const observableData = {};
observableData["POOL_ADMIN"] = poolAdminAddress;
observableData["EMERGENCY_ADMIN"] = emergencyAdminAddress;
addObservables(observableData);
// Deploy Observable Data
await deployObservables();
`
Interactables allow you to define contracts or accounts that you'd like to interact with during simulations. Interactables supports the following types:
`js`
// Valid Interactable Types
const INTERACTABLE_TYPES = {
CONTRACT: "CONTRACT",
HISTOGRAM: "HISTOGRAM",
PIE_CHART: "PIE_CHART",
TIME_SERIES: "TIME_SERIES",
};
Defining an interactable as a contract will allow you to view and invoke it's methods through the KPR dashboard. This is similar to what you can do with Etherscan. Let's define an interactable contract together.
`js
import { initKPR, addConfigObject, deployConfig } from "@kpr-labs/observables";
const API_URL = "https://kpr-server.herokuapp.com";
const SPECTRAL_ENDPOINT = "/cloud/server/spectral/config";
// KPR Init
initKPR({ API_URL, API_ENDPOINT: SPECTRAL_ENDPOINT, API_KEY: "
const exampleJson = require("../src/artifacts/contracts/example/Example.sol/Example.json");
addInteractable({
name: exampleJson.contractName,
abi: exampleJson.abi,
address: exampleContract.address,
description:
"Omer - This is a very cool interactable, say hello and Lorem Ipsum, I appreciate the help.",
type: INTERACTABLE_TYPES.CONTRACT,
});
const importantJson = require("../src/artifacts/contracts/important-contract/ImportantContract.sol/ImportantContract.json");
addInteractable({
name: importantJson.contractName,
abi: importantJson.abi,
address: importantContract.address,
description:
"Yonatan - This is a very important interactable, say hello and Lorem Ipsum, I appreciate the help.",
type: INTERACTABLE_TYPES.CONTRACT,
});
await deployInteractables();
`
Defining a histogram (bar chart) requires you to define the histogram name, as well as a payload describing how to fetch the data for each bucket in the histogram.
`js
import { initKPR, addHistogram, deployHistograms } from "@kpr-labs/observables";
// KPR Init
initKPR({ API_URL, API_ENDPOINT: SPECTRAL_ENDPOINT, API_KEY: "
addHistogram({
title: "USERS PER TICK",
legend: [
"Available Liquidity",
"Total Debt",
"Liquidity Rate",
"Variable Liquidity Rate",
],
buckets: [
{
contractAddress: dataProviderContract.address,
abi: dataProviderJson.abi,
method: "getReserveData",
title: "Tick 3",
returnKey: "1",
params: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 3],
},
{
contractAddress: dataProviderContract.address,
abi: dataProviderJson.abi,
method: "getReserveData",
title: "Tick 4",
returnKey: "2",
params: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 4],
},
{
contractAddress: dataProviderContract.address,
abi: dataProviderJson.abi,
method: "getReserveData",
title: "Tick 5",
returnKey: "3",
params: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 5],
},
{
contractAddress: dataProviderContract.address,
abi: dataProviderJson.abi,
method: "getReserveData",
title: "Tick 6",
returnKey: "4",
params: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 6],
},
{
contractAddress: dataProviderContract.address,
abi: dataProviderJson.abi,
method: "getReserveData",
title: "Tick 7",
returnKey: "5",
params: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 7],
},
],
});
await deployHistograms();
`
Stat cards let you display important or top line metrics with ease.
`js`
addStatCard({
mainIcon: "trending_up",
mainIconBg: "bg-light-green",
mainTitle: "Active Users",
mainTextColor: "text-green",
secondaryIcon: "expand_less",
secondaryIconBg: "bg-green",
delta: null, // coming soon
dataFetchers: [
// vals should sum to 100
{
contractAddress: dataProviderContract.address,
abi: dataProviderJson.abi,
dataFetcherMethod: "fakeDataFetcher1",
returnKey: "4",
params: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 6],
},
{
contractAddress: dataProviderContract.address,
abi: dataProviderJson.abi,
dataFetcherMethod: "fakeDataFetcher2",
returnKey: "4",
params: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 6],
},
{
contractAddress: dataProviderContract.address,
abi: dataProviderJson.abi,
dataFetcherMethod: "fakeDataFetcher3",
returnKey: "4",
params: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 6],
},
],
});
Note: We're using the Material Design color pallette and icon set for styling. You can specify mainIcon, background color, text color, secondary icons by selecting a valid option from the material UI Library.
Pie charts let you define a pie chart widget to be displayed on your dashboard.
`js`
addPieChart({
primaryTitle: "Lending Protocols",
secondaryTitle: "Leading interest rates",
theme: "primary",
data: [
{
value: 65,
name: "Aave",
contractAddress: address,
abi,
dataFetcherMethod: "fakeDataFetcher1",
returnKey: null,
params: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 6],
},
{
name: "Compound",
contractAddress: address,
abi,
dataFetcherMethod: "fakeDataFetcher2",
returnKey: null,
params: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 6],
},
{
name: "Others",
},
],
});
Line charts represent a time series. The same data fetcher is used for every data point in time.
`js`
addLineChart({
primaryTitle: "New Users",
secondaryTitle: "Joined Last 7 Days",
delta: null, // coming soon
// deltaIcon: "arrow_drop_up",
theme: "primary",
dataFetchers: [
{
contractAddress: address,
abi,
dataFetcherMethod: "fakeDataFetcher1",
returnKey: null,
params: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", 6],
},
],
xAxis: [
"Block 1",
"Block 2",
"Block 3",
"Block 4",
"Block 5",
"Block 6",
"Block 7",
],
});
Note: We're using the Material Design color pallette and icon set for styling. You can specify mainIcon, background color, text color, secondary icons by selecting a valid option from the material UI Library.
In order to run and view your simulation results on KPRCloud make sure that your hardhat network config is pointing at the correct node. When signing up for KPR you should receive an API key. See the networks payload in the example below.
`js``
const hardhatConfig: HardhatUserConfig = {
solidity: {
version: "0.6.12",
settings: {
optimizer: { enabled: true, runs: 200 },
evmVersion: "istanbul",
},
},
typechain: {
outDir: "types",
target: "ethers-v5",
},
etherscan: {
apiKey: ETHERSCAN_KEY,
},
defaultNetwork: "localhost",
networks: {
hardhat: {
forking: {
url: "https://eth-mainnet.alchemyapi.io/v2/
},
},
},
};
Please reach out to omer@kprlabs.io :)