feat(cloud-functions): initial simple cloud functions for calculating UMA TVL and fetching KPI options recipients (#2697)

* Added cloud functions package

Signed-off-by: Christopher Maree <christopher.maree@gmail.com>

* Added serverless functions

Signed-off-by: Christopher Maree <christopher.maree@gmail.com>

* Added yarn lock

Signed-off-by: Christopher Maree <christopher.maree@gmail.com>

* removed lock files

Signed-off-by: Christopher Maree <christopher.maree@gmail.com>

* Added readme file

Signed-off-by: Christopher Maree <christopher.maree@gmail.com>

* Added cashing solution to tvl

Signed-off-by: Christopher Maree <christopher.maree@gmail.com>

* Updated README.md

Signed-off-by: Christopher Maree <christopher.maree@gmail.com>

* Updated

Signed-off-by: Christopher Maree <christopher.maree@gmail.com>

* Updated for cors

Signed-off-by: Christopher Maree <christopher.maree@gmail.com>

* Updated cors logig

Signed-off-by: Christopher Maree <christopher.maree@gmail.com>

* Added private

Signed-off-by: Christopher Maree <christopher.maree@gmail.com>
This commit is contained in:
Chris Maree
2021-03-22 08:35:57 +02:00
committed by GitHub
parent 2c4ddb3060
commit 18f874bbe4
9 changed files with 112 additions and 2 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
{
"packages": ["packages/*"],
"packages": ["packages/**"],
"npmClient": "yarn",
"useWorkspaces": true,
"version": "independent"
+1 -1
View File
@@ -67,6 +67,6 @@
"*.{js,ts,tsx}": "eslint --cache --fix"
},
"workspaces": [
"packages/*"
"packages/**"
]
}
+13
View File
@@ -0,0 +1,13 @@
# @uma/merkle-distributor
This package contains a number of serverless functions used to wrap core UMA logic in a serverless consumable format.
## Key packages included:
1. `uma-tvl-calculator` wraps the `merkle-distributor-helper` package's `calculateCurrentTvl` method to create a simple interface for computing the current UMA TVL. Once the TVL is calculated, this method will store it within GCP data store with the Key being the computation timestamp. This should be run by a cron job to ensure the data store always has the most up to data information.
2. `uma-tvl-fetcher` pulls data from GCP data store to quickly return the most recent TVL.
3. `Merkle-distributor-helper` wraps the the `merkle-distributor-helper` package's `getClaimsForAddress` method to create a simple interface to fetch claims for a particular address.
## Using these functions
These serverless functions are designed to work in any serverless framework. They are used by UMA within GCP cloud functions but they should work equally well within Vercel's serverless, AWS Lambda or any other serverless framework of your choosing.
@@ -0,0 +1,25 @@
const { getClaimsForAddress } = require("@uma/merkle-distributor");
exports.getClaimsForAddress = async (req, res) => {
try {
res.set("Access-Control-Allow-Origin", "*");
if (req.method === "OPTIONS") {
res.set("Access-Control-Allow-Methods", "GET, PUT, POST, OPTIONS");
res.set("Access-Control-Allow-Headers", "Content-Type");
res.status(204).send("");
} else {
const body = req.body;
["merkleDistributorAddress", "claimerAddress", "chainId"].forEach(requiredKey => {
if (!Object.keys(body).includes(requiredKey))
throw "Missing key in req body! required: merkleDistributorAddress, claimerAddress, chainId";
});
const claims = await getClaimsForAddress(body.merkleDistributorAddress, body.claimerAddress, body.chainId);
console.log(`Fetched claims for ${JSON.stringify(body)}. Claims: ${JSON.stringify(claims)}`);
res.status(200).send(claims);
}
} catch (e) {
console.error(e);
res.status(500).send({ message: "Error in fetching claims", error: e instanceof Error ? e.message : e });
}
};
@@ -0,0 +1,8 @@
{
"name": "merkle-distributor-helper",
"version": "0.0.1",
"dependencies": {
"@uma/merkle-distributor": "npm:@uma/merkle-distributor@1.0.4"
},
"private": true
}
@@ -0,0 +1,27 @@
const { Datastore } = require("@google-cloud/datastore");
const datastore = new Datastore();
const { calculateCurrentTvl } = require("@uma/merkle-distributor");
exports.calculateCurrentTvl = async (req, res) => {
try {
const tvl = await calculateCurrentTvl();
const currentTime = Math.round(new Date().getTime() / 1000);
const key = datastore.key(["UmaTvl", currentTime]);
const dataBlob = {
key: key,
data: {
tvl: tvl.currentTvl,
created: currentTime
}
};
await datastore.save(dataBlob);
console.log(`Fetched and saved current TVL: ${JSON.stringify(tvl)}`);
res.status(200).send(tvl);
} catch (e) {
console.error(e);
res.status(500).send({ message: "Error in fetching and saving TVL", error: e instanceof Error ? e.message : e });
}
};
@@ -0,0 +1,9 @@
{
"name": "uma-tvl-calculator",
"version": "0.0.1",
"dependencies": {
"@uma/merkle-distributor": "npm:@uma/merkle-distributor@1.0.3",
"@google-cloud/datastore": "^6.3.1"
},
"private": true
}
@@ -0,0 +1,20 @@
const { Datastore } = require("@google-cloud/datastore");
const datastore = new Datastore();
exports.fetchLatestTvl = async (req, res) => {
try {
res.set("Access-Control-Allow-Origin", "*");
const [result] = await datastore.runQuery(
datastore
.createQuery("UmaTvl")
.order("created", { descending: true })
.limit(1)
);
const responseObject = { currentTvl: result[0].tvl, currentTime: result[0].created };
console.log(`Fetched TVL from data store: ${JSON.stringify(responseObject)}`);
res.status(200).send(responseObject);
} catch (e) {
console.error(e);
res.status(500).send({ message: "Error in fetching TVL", error: e instanceof Error ? e.message : e });
}
};
@@ -0,0 +1,8 @@
{
"name": "uma-tvl-fetcher",
"version": "0.0.1",
"dependencies": {
"@google-cloud/datastore": "^6.3.1"
},
"private": true
}