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

PRO-2265-Arka_Housekeeping #86

Merged
merged 2 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ The structure should be as follows
"137": "https://api.polygonscan.com/api?module=gastracker&action=gasoracle&apikey=YourApiKeyToken", // Note that you need to replace YourApiKeyToken to actual API key from etherscan
"1": "https://api.etherscan.io/api?module=gastracker&action=gasoracle&apikey=YourApiKeyToken"
} which then needs to be converted into `base64` value
- DEFAULT_API_KEY - this is used for checking token paymaster deposits. Please use an apiKey which has the list of token paymasters that needs to be monitored. Please note that it only tracks the token paymasters in `ERC20_PAYMASTERS` and `MULTI_TOKEN_PAYMASTERS` variable specified inside the apiKey.
- WEBHOOK_URL - this is used to notify if the token paymaster deposit comes below 'thresholdValue' specified in backend/config.json and please note that each chain has configured threshold as approx. 50 USD worth of native tokens

## API KEY VALIDATION
- In ARKA Admin Frontend, create an API_KEY with the following format -
Expand Down
4 changes: 2 additions & 2 deletions admin_frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion admin_frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "admin_frontend",
"version": "1.2.0",
"version": "1.2.1",
"private": true,
"dependencies": {
"@emotion/react": "11.11.3",
Expand Down
80 changes: 56 additions & 24 deletions backend/config.json.default
Original file line number Diff line number Diff line change
Expand Up @@ -4,167 +4,199 @@
"bundler": "https://ethereum-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0x7F690e93CecFca5A31E6e1dF50A33F6d3059048c"
}
},
"thresholdValue": "0.016"
},
{
"chainId": 5,
"bundler": "https://goerli-bundler.etherspot.io",
"contracts": {
"etherspotPaymasterAddress": "0xcaDBADcFeD5530A49762DFc9d1d712CcD6b09b25"
}
},
"thresholdValue": "0.016"
},
{
"chainId": 10,
"bundler": "https://optimism-bundler.etherspot.io",
"contracts": {
"etherspotPaymasterAddress": "0x805650ce74561C85baA44a8Bd13E19633Fd0F79d"
}
},
"thresholdValue": "21.8"
},
{
"chainId": 14,
"bundler": "https://flare-bundler.etherspot.io",
"contracts": {
"etherspotPaymasterAddress": "0x8A41594e5c6Fe492e437414c24eA6f401186b8d2"
}
},
"thresholdValue": "1556"
},
{
"chainId": 56,
"bundler": "https://bnb-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0xEA5ecE95D3A28f9faB161779d20128b449F9EC9C"
}
},
"thresholdValue": "0.09"
},
{
"chainId": 97,
"bundler": "https://bnbtestnet-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0x153e26707DF3787183945B88121E4Eb188FDCAAA"
}
},
"thresholdValue": "0.09"
},
{
"chainId": 100,
"bundler": "https://gnosis-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0x373aBcF1EA9e5802778E32870e7f72C8A6a90349"
}
},
"thresholdValue": "50"
},
{
"chainId": 114,
"bundler": "https://flaretestnet-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0x2a18C360b525824B3e5656B5a705554f2a5036Be"
}
},
"thresholdValue": "1556"
},
{
"chainId": 122,
"bundler": "https://fuse-bundler.etherspot.io",
"contracts": {
"etherspotPaymasterAddress": "0xEC2EE24E79C73DB13Dd9bC782856a5296626b7eb"
}
},
"thresholdValue": "669"
},
{
"chainId": 137,
"bundler": "https://polygon-bundler.etherspot.io",
"contracts": {
"etherspotPaymasterAddress": "0x26FeC24b0D467C9de105217B483931e8f944ff50"
}
},
"thresholdValue": "69.85"
},
{
"chainId": 420,
"bundler": "https://optimismgoerli-bundler.etherspot.io",
"contracts": {
"etherspotPaymasterAddress": "0x898c530A5fA37720DcF1843AeCC34b6B0cBaEB8a"
}
},
"thresholdValue": "21.8"
},
{
"chainId": 1001,
"bundler": "https://klaytntestnet-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0x810FA4C915015b703db0878CF2B9344bEB254a40"
}
},
"thresholdValue": "275.2"
},
{
"chainId": 5000,
"bundler": "https://mantle-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0x8A41594e5c6Fe492e437414c24eA6f401186b8d2"
}
},
"thresholdValue": "44.24"
},
{
"chainId": 5001,
"bundler": "https://mantletestnet-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0xb56eC212C60C47fb7385f13b7247886FFa5E9D5C"
}
},
"thresholdValue": "44.24"
},
{
"chainId": 8217,
"bundler": "https://klaytn-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0x4ebd86AAF89151b5303DB072e0205C668e31E5E7"
}
},
"thresholdValue": "275.2"
},
{
"chainId": 8453,
"bundler": "https://base-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0x810FA4C915015b703db0878CF2B9344bEB254a40"
}
},
"thresholdValue": "15.19"
},
{
"chainId": 42161,
"bundler": "https://arbitrum-bundler.etherspot.io",
"contracts": {
"etherspotPaymasterAddress": "0xEC2EE24E79C73DB13Dd9bC782856a5296626b7eb"
}
},
"thresholdValue": "43.10"
},
{
"chainId": 43114,
"bundler": "https://avalanche-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0x527569794781671319f20374A050BDbef4181aB3"
}
},
"thresholdValue": "1.4"
},
{
"chainId": 59144,
"bundler": "https://linea-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0xB3AD9B9B06c6016f81404ee8FcCD0526F018Cf0C"
}
},
"thresholdValue": "0.016"
},
{
"chainId": 80001,
"bundler": "https://mumbai-bundler.etherspot.io",
"contracts": {
"etherspotPaymasterAddress": "0x8350355c08aDAC387b443782124A30A8942BeC2e"
}
},
"thresholdValue": "69.85"
},
{
"chainId": 84531,
"bundler": "https://basegoerli-bundler.etherspot.io",
"contracts": {
"etherspotPaymasterAddress": "0x898c530A5fA37720DcF1843AeCC34b6B0cBaEB8a"
}
},
"thresholdValue": "15.19"
},
{
"chainId": 421613,
"bundler": "https://arbitrumgoerli-bundler.etherspot.io",
"contracts": {
"etherspotPaymasterAddress": "0x898c530A5fA37720DcF1843AeCC34b6B0cBaEB8a"
}
},
"thresholdValue": "43.18"
},
{
"chainId": 534351,
"bundler": "https://scrollsepolia-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0xe893A26DD53b325BffAacDfA224692EfF4C448c4"
}
},
"thresholdValue": "0.016"
},
{
"chainId": 11155111,
"bundler": "https://sepolia-bundler.etherspot.io",
"contracts": {
"etherspotPaymasterAddress": "0xcaDBADcFeD5530A49762DFc9d1d712CcD6b09b25"
}
},
"thresholdValue": "0.016"
},
{
"chainId": 28122024,
"bundler": "https://ancient8testnet-bundler.etherspot.io/",
"contracts": {
"etherspotPaymasterAddress": "0xe893A26DD53b325BffAacDfA224692EfF4C448c4"
},
"thresholdValue": "0.016"
}
]
2 changes: 2 additions & 0 deletions backend/demo.env
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ ADMIN_WALLET_ADDRESS=
DEFAULT_INDEXER_ENDPOINT=http://localhost:3003
FEE_MARKUP=
ETHERSCAN_GAS_ORACLES=
DEFAULT_API_KEY=
WEBHOOK_URL=
2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "arka",
"version": "1.2.0",
"version": "1.2.1",
"description": "ARKA - (Albanian for Cashier's case) is the first open source Paymaster as a service software",
"type": "module",
"directories": {
Expand Down
58 changes: 57 additions & 1 deletion backend/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import fastify, { FastifyInstance } from 'fastify';
import cors from '@fastify/cors';
import fastifyCron from 'fastify-cron';
import { providers, ethers } from 'ethers';
import { GetSecretValueCommand, SecretsManagerClient } from '@aws-sdk/client-secrets-manager';
import fetch from 'node-fetch';
import database from './plugins/db.js';
import config from './plugins/config.js';
Expand All @@ -12,7 +13,8 @@ import metadataRoutes from './routes/metadata.js';
import EtherspotChainlinkOracleAbi from './abi/EtherspotChainlinkOracleAbi.js';
import PimlicoAbi from './abi/PimlicoAbi.js';
import PythOracleAbi from './abi/PythOracleAbi.js';
import { getNetworkConfig } from './utils/common.js';
import { getNetworkConfig, getSQLdata } from './utils/common.js';
import { checkDeposit } from './utils/monitorTokenPaymaster.js';

let server: FastifyInstance;

Expand Down Expand Up @@ -148,6 +150,60 @@ const initializeServer = async (): Promise<void> => {
server.log.info('no private key found in env')
}
}
},
{
// Only these two properties are required,
// the rest is from the node-cron API:
// https://github.com/kelektiv/node-cron#api
cronTime: '0 * * * *', // Every Hour,
name: 'checkTokenPaymasterDeposit',

// Note: the callbacks (onTick & onComplete) take the server
// as an argument, as opposed to nothing in the node-cron API:
onTick: async () => {
if (process.env.DEFAULT_API_KEY && process.env.WEBHOOK_URL) {
const prefixSecretId = 'arka_';
let client: SecretsManagerClient;
const unsafeMode: boolean = process.env.UNSAFE_MODE == "true" ? true : false;
const api_key = process.env.DEFAULT_API_KEY;
let customPaymasters = [], multiTokenPaymasters = [];
if (!unsafeMode) {
client = new SecretsManagerClient();
const AWSresponse = await client.send(
new GetSecretValueCommand({
SecretId: prefixSecretId + api_key,
})
);
client.destroy();
const secrets = JSON.parse(AWSresponse.SecretString ?? '{}');
if (secrets['ERC20_PAYMASTERS']) {
const buffer = Buffer.from(secrets['ERC20_PAYMASTERS'], 'base64');
customPaymasters = JSON.parse(buffer.toString());
}
if (secrets['MULTI_TOKEN_PAYMASTERS']) {
const buffer = Buffer.from(secrets['MULTI_TOKEN_PAYMASTERS'], 'base64');
multiTokenPaymasters = JSON.parse(buffer.toString());
}
} else {
const record: any = await getSQLdata(api_key, server.sqlite.db, server.log);
if (record['ERC20_PAYMASTERS']) {
const buffer = Buffer.from(record['ERC20_PAYMASTERS'], 'base64');
customPaymasters = JSON.parse(buffer.toString());
}
if (record['MULTI_TOKEN_PAYMASTERS']) {
const buffer = Buffer.from(record['MULTI_TOKEN_PAYMASTERS'], 'base64');
multiTokenPaymasters = JSON.parse(buffer.toString());
}
}
customPaymasters = {...customPaymasters, ...multiTokenPaymasters};
for (const chainId in customPaymasters) {
const networkConfig = getNetworkConfig(chainId, '');
for (const symbol in customPaymasters[chainId]) {
checkDeposit(customPaymasters[chainId][symbol], networkConfig.bundler, process.env.WEBHOOK_URL, networkConfig.thresholdValue ?? '0.001', Number(chainId), server.log)
}
}
}
}
}
]
});
Expand Down
22 changes: 22 additions & 0 deletions backend/src/utils/monitorTokenPaymaster.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { FastifyBaseLogger } from "fastify";
import { ethers, providers } from "ethers";
import fetch from 'node-fetch';
import EtherspotAbi from "../abi/EtherspotAbi.js";

export async function checkDeposit(paymasterAddress: string, bundlerUrl: string, webhookUrl: string, thresholdValue: string, chainId: number, log: FastifyBaseLogger) {
try {
const provider = new providers.JsonRpcProvider(bundlerUrl);
const contract = new ethers.Contract(paymasterAddress, EtherspotAbi, provider);
const currentDeposit = await contract.getDeposit();
if (ethers.utils.parseEther(thresholdValue).gte(currentDeposit)) {
const body = { message: `Balance below threshold. Please deposit on tokenPaymasterAddress: ${paymasterAddress} chainId: ${chainId}`, currentDeposit: ethers.utils.formatEther(currentDeposit) }
await fetch(webhookUrl, {
method: 'POST',
body: JSON.stringify(body)
});
}
} catch (err) {
log.error(`Error on chainId ${chainId} address: ${paymasterAddress} webhookUrl: ${webhookUrl} bunderUrl: ${bundlerUrl}`)
log.error(err);
}
}
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ services:
- DEFAULT_INDEXER_ENDPOINT=http://localhost:3003
- FEE_MARKUP=
- ETHERSCAN_GAS_ORACLES=
- DEFAULT_API_KEY=
- WEBHOOK_URL=
build:
context: ./backend
dockerfile: Dockerfile
Expand Down
4 changes: 2 additions & 2 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading