Build smarter
applications on the blockchain
Deliver data to your users, FAST
import { ApolloClient, gql, InMemoryCache } from "@apollo/client/core/core.cjs";
const client = new ApolloClient({
uri: "https://api.kenshi.io/index/graphql",
cache: new InMemoryCache(),
});
const query = gql`
{
getEntries(blockchain: "binance-mainnet") {
event {
name
}
}
}
`;
const { data } = client.query({ query });
See more examples on GitHub
import axios from "axios";
const request = {
blockchain: "binance-mainnet",
query: {
"event.name": "Transfer",
"block.number": { $gte: 20740000 },
},
};
const data = await axios.post("https://api.kenshi.io/index/mql", request);
See more examples on GitHub
import express from "express";
import parser from "body-parser";
const app = express();
app.use(parser.json());
app.post("/", (req, res) => {
console.dir(req.body, { depth: null });
res.status(200).end("OK");
});
app.listen(8080);
See more examples on GitHub
Kenshi blockchain IoT SDK
Supports 200+ development boards!
Kenshi blockchain IoT SDK supports more than 200 development boards.
Automate the world, with blockchain
Integrate with the tools you already know
The Kenshi R-API integrations with existing automation and data flow tools.
Connect your smart contract
Get started
Use one of our Oracle blueprints or sample codes to get started in no time.
A very simple blueprint to start from. Extend this to create your custom functionality.
export const handler = async () => {
return {
statusCode: 200,
body: JSON.stringify({
method: "setTime",
args: [new Date().valueOf()],
maxGas: "100000000000000", // 0.0001 ETH
abort: false,
}),
};
};
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Time {
uint256 timestamp;
event TimeRequest();
/**
* Emit and event that will be picked up by the Kenshi
* Oracle Network and sent to your oracle for processing
*/
function requestTime() external {
emit TimeRequest();
}
/**
* This method will be called by the Kenshi Oracle Network
* with the result returned from your oracle
*/
function setTime(uint256 time) external {
timestamp = time;
}
/**
* Public function to display the last retrieved timestamp
*/
function showTime() public view returns (uint256) {
return timestamp;
}
}
The following blueprint shows how to get price data
from
coingecko.com
import { ethers } from "ethers";
import fetch from "node-fetch";
const url =
"https://api.coingecko.com/api/v3/coins/kenshi/market_chart?vs_currency=usd&days=1";
export const handler = async () => {
const resp = await fetch(url);
const { prices } = await resp.json();
const average =
prices
.slice(-6) // last 30 minutes
.map(([_, price]) => price)
.reduce((a, b) => a + b) / 6;
return {
statusCode: 200,
body: JSON.stringify({
method: "setPrice",
args: [ethers.utils.parseUnits(average.toFixed(18)).toString()],
maxGas: "100000000000000", // 0.0001 ETH
abort: false,
}),
};
};
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Price {
event PriceRequest();
event PriceRequestFulfilled(uint256 price);
/**
* Emit and event that will be picked up by the Kenshi
* Oracle Network and sent to your oracle for processing
*/
function requestPrice() external {
emit PriceRequest();
}
/**
* This method will be called by the Kenshi Oracle Network
* with the result returned from your oracle
*/
function setPrice(uint256 price) external {
emit PriceRequestFulfilled(price);
}
}
The following blueprint shows how to check if the user owns a specific amount of tokens or NFTs on another chain.
import { ethers } from "ethers";
const abi = ["function balanceOf(address) view returns (uint)"];
export const handler = async ({ body }) => {
const { entry } = JSON.parse(body);
const provider = new ethers.providers.JsonRpcProvider(process.env.RPC_ADDR);
const contract = new ethers.Contract(entry.event.args.token, abi, provider);
const balance = await contract.balanceOf(entry.event.args.user);
return {
statusCode: 200,
body: JSON.stringify({
method: "setBalance",
args: [entry.event.args.user, entry.event.args.token, balance.toString()],
maxGas: "100000000000000", // 0.0001 ETH
abort: false,
}),
};
};
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Balance {
event BalanceRequest(address user, address token);
event BalanceRequestFulfilled(address user, address token, uint256 balance);
/**
* Emit and event that will be picked up by the Kenshi
* Oracle Network and sent to your oracle for processing
*/
function requestBalance(address user, address token) external {
emit BalanceRequest(user, token);
}
/**
* This method will be called by the Kenshi Oracle Network
* with the result returned from your oracle
*/
function setBalance(
address user,
address token,
uint256 balance
) external {
emit BalanceRequestFulfilled(user, token, balance);
}
}
The following blueprint shows how to get weather data
from
brightsky.dev
import { ethers } from "ethers";
import fetch from "node-fetch";
export const handler = async ({ body }) => {
const now = new Date();
const { entry } = JSON.parse(body);
// Solidity doesn't have floating point numbers;
// We divide lat and long by 100 for 0.01 precision
const lat = ethers.BigNumber.from(entry.event.args.lat).toNumber() / 100;
const long = ethers.BigNumber.from(entry.event.args.long).toNumber() / 100;
const url = `https://api.brightsky.dev/weather?lat=${lat}&lon=${long}&date=${now.toISOString()}`;
const resp = await fetch(url);
const { weather } = await resp.json();
return {
statusCode: 200,
body: JSON.stringify({
method: "setWeather",
args: [
entry.event.args.lat,
entry.event.args.long,
// Solidity doesn't have floating point numbers;
// We multiply the temperature by 100 for 0.01 precision
Math.round(weather[0].temperature * 100),
],
maxGas: "100000000000000", // 0.0001 ETH
abort: false,
}),
};
};
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Weather {
event WeatherRequest(uint256 lat, uint256 long);
event WeatherRequestFulfilled(
uint256 lat,
uint256 long,
uint256 temperature
);
/**
* Emit and event that will be picked up by the Kenshi
* Oracle Network and sent to your oracle for processing
*
* Note: Solidity doesn't have floating point numbers,
* we assume lat and long are multiplied by 100 to elliminate
* the decimal part of them
*/
function requestWeather(uint256 lat, uint256 long) external {
emit WeatherRequest(lat, long);
}
/**
* This method will be called by the Kenshi Oracle Network
* with the result returned from your oracle
*/
function setWeather(
uint256 lat,
uint256 long,
uint256 temperature
) external {
emit WeatherRequestFulfilled(lat, long, temperature);
}
}
The following blueprint shows how to create your own VRF oracle. This example uses the Kenshi VRF libraries, which implement draft 10 of the IETF ECVRF.
import { decode, prove, getFastVerifyComponents } from "@kenshi.io/node-ecvrf";
import { createHash } from "crypto";
import Elliptic from "elliptic";
const EC = new Elliptic.ec("secp256k1");
export const getPublicKey = (privateKey) => {
const key = EC.keyFromPrivate(privateKey);
return {
key: key.getPublic("hex"),
compressed: key.getPublic(true, "hex"),
x: key.getPublic().getX(),
y: key.getPublic().getY(),
};
};
const fromHex = (hex) => Buffer.from(hex.slice(2));
const hash = (...args) => {
const sha256 = createHash("sha256");
for (const arg of args) {
sha256.update(arg);
}
return sha256.digest().toString("hex");
};
export const handler = async ({ body }) => {
const { entry } = JSON.parse(body);
// You can generate a private key using the `keygen` function
// exported by the @kenshi.io/node-ecvrf library
const publicKey = getPublicKey(process.env.VRF_PRIVATE_KEY);
const alpha = hash(
fromHex(entry.transaction.hash),
fromHex(entry.log.index),
fromHex(entry.block.address),
fromHex(entry.event.args.requestId)
);
const proof = prove(process.env.VRF_PRIVATE_KEY, alpha);
const fast = getFastVerifyComponents(publicKey.key, proof, alpha);
const [Gamma, c, s] = decode(proof);
return {
statusCode: 200,
body: JSON.stringify({
method: "setRandomness",
args: [
[Gamma.x.toString(), Gamma.y.toString(), c.toString(), s.toString()],
`0x${alpha}`,
[fast.uX, fast.uY],
[fast.sHX, fast.sHY, fast.cGX, fast.cGY],
entry.event.args.requestId,
],
maxGas: "100000000000000", // 0.0001 ETH
abort: false,
}),
};
};
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
import "@kenshi.io/vrf-consumer/contracts/VRFUtils.sol";
contract VRFOracle {
uint256 _requestId;
mapping(uint256 => bool) alreadyFulfilled;
event RandomnessRequest(uint256 requestId);
event RandomnessRequestFulfilled(uint256 requestId, uint256 randomness);
VRFUtils utils;
constructor(bytes memory publicKey) {
utils = new VRFUtils();
utils.setPublicKey(publicKey);
}
/**
* Emit and event that will be picked up by the Kenshi
* Oracle Network and sent to your oracle for processing
*/
function requestRandomness() external {
emit RandomnessRequest(_requestId++);
}
/**
* This method will be called by the Kenshi Oracle Network
* with the result returned from your oracle
*
* Note: We encourage reading IETF ECVRF drafts to understand
* what's going on: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf
*/
function setRandomness(
uint256[4] memory proof,
bytes memory message,
uint256[2] memory uPoint,
uint256[4] memory vComponents,
uint256 requestId
) external {
require(!alreadyFulfilled[requestId], "Already fulfilled");
bool isValid = utils.fastVerify(proof, message, uPoint, vComponents);
require(isValid, "Cannot verify VRF results");
bytes32 beta = utils.gammaToHash(proof[0], proof[1]);
uint256 randomness = uint256(beta);
alreadyFulfilled[requestId] = true;
emit RandomnessRequestFulfilled(requestId, randomness);
}
}
Developer resources
Together, we drive forward!
Influencers and Content Creators
Partner to amazing businesses
We are on a constant lookout for collaborating with top-notch companies and industry leaders.
Supported blockchains
Reach out to us to launch Kenshi services on your blockchain.