Skip to content
This repository has been archived by the owner on Sep 19, 2024. It is now read-only.

Commit

Permalink
Merge branch 'development' into link-pr-to-issue
Browse files Browse the repository at this point in the history
  • Loading branch information
seprintour authored Apr 28, 2023
2 parents 8de6773 + 1fdbc9c commit dfae2ab
Show file tree
Hide file tree
Showing 8 changed files with 1,117 additions and 11 deletions.
2 changes: 2 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
nodeLinker: node-modules

yarnPath: yarn/releases/yarn-3.5.0.cjs
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,20 @@
"husky": "^8.0.2",
"jimp": "^0.22.4",
"js-yaml": "^4.1.0",
"libsodium-wrappers": "^0.7.11",
"lint-staged": "^13.1.0",
"ms": "^2.1.3",
"node-html-parser": "^6.1.5",
"node-html-to-image": "^3.3.0",
"nodemon": "^2.0.19",
"prettier": "^2.7.1",
"probot": "^12.2.4",
"telegraf": "^4.11.2"
"telegraf": "^4.11.2",
"yaml": "^2.2.2"
},
"devDependencies": {
"@types/jest": "^28.1.0",
"@types/libsodium-wrappers": "^0.7.10",
"@types/node": "^14.18.37",
"@types/source-map-support": "^0.5.6",
"jest": "^26.6.3",
Expand All @@ -69,5 +72,6 @@
"*.{ts,json}": [
"prettier --write"
]
}
},
"packageManager": "yarn@3.5.0"
}
22 changes: 13 additions & 9 deletions src/bindings/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import ms from "ms";

import { BotConfig, BotConfigSchema } from "../types";
import {
DefaultPriceConfig,
DEFAULT_BOT_DELAY,
DEFAULT_CHAIN_ID,
DEFAULT_DISQUALIFY_TIME,
Expand All @@ -13,25 +12,26 @@ import {
} from "../configs";
import { ajv } from "../utils";
import { Context } from "probot";
import { getScalarKey, getWideConfig } from "../utils/private";

export const loadConfig = async (context: Context): Promise<BotConfig> => {
let configFile: any = {};
configFile = await context.config("ubiquibot-config.yml");
const { privateKey, baseMultiplier, timeLabels, priorityLabels, autoPayMode, analyticsMode } = await getWideConfig(context);
const publicKey = await getScalarKey(process.env.X25519_PRIVATE_KEY);

const botConfig: BotConfig = {
log: {
level: process.env.LOG_LEVEL || "deubg",
ingestionKey: process.env.LOGDNA_INGESTION_KEY ?? "",
},
price: {
baseMultiplier: process.env.BASE_MULTIPLIER ? Number(process.env.BASE_MULTIPLIER) : configFile?.baseMultiplier ?? DefaultPriceConfig.baseMultiplier,
timeLabels: configFile?.timeLabels ?? DefaultPriceConfig.timeLabels,
priorityLabels: configFile?.priorityLabels ?? DefaultPriceConfig.priorityLabels,
baseMultiplier: baseMultiplier,
timeLabels: timeLabels,
priorityLabels: priorityLabels,
},
payout: {
chainId: process.env.CHAIN_ID ? Number(process.env.CHAIN_ID) : DEFAULT_CHAIN_ID,
rpc: process.env.RPC_PROVIDER_URL || DEFAULT_RPC_ENDPOINT,
privateKey: process.env.UBIQUITY_BOT_EVM_PRIVATE_KEY || "",
privateKey: privateKey,
paymentToken: process.env.PAYMENT_TOKEN || DEFAULT_PAYMENT_TOKEN,
permitBaseUrl: process.env.PERMIT_BASE_URL || DEFAULT_PERMIT_BASE_URL,
},
Expand All @@ -48,8 +48,12 @@ export const loadConfig = async (context: Context): Promise<BotConfig> => {
delay: process.env.TELEGRAM_BOT_DELAY ? Number(process.env.TELEGRAM_BOT_DELAY) : DEFAULT_BOT_DELAY,
},
mode: {
autoPayMode: process.env.AUTO_PAY_MODE === "TRUE" ? true : configFile?.autoPayMode ?? true,
analyticsMode: process.env.ANALYTICS_MODE === "TRUE" ? true : configFile?.analyticsMode ?? false,
autoPayMode: autoPayMode,
analyticsMode: analyticsMode,
},
sodium: {
privateKey: process.env.X25519_PRIVATE_KEY ?? "",
publicKey: publicKey ?? "",
},
};

Expand Down
6 changes: 6 additions & 0 deletions src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ export const LogConfigSchema = Type.Object({
ingestionKey: Type.String(),
});

export const SodiumSchema = Type.Object({
publicKey: Type.String(),
privateKey: Type.String(),
});

export const BotConfigSchema = Type.Object({
log: LogConfigSchema,
price: PriceConfigSchema,
Expand All @@ -55,6 +60,7 @@ export const BotConfigSchema = Type.Object({
supabase: SupabaseConfigSchema,
telegram: TelegramBotConfigSchema,
mode: ModeSchema,
sodium: SodiumSchema,
});

export type BotConfig = Static<typeof BotConfigSchema>;
52 changes: 52 additions & 0 deletions src/utils/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { DefaultPriceConfig } from "../configs";
import { WideLabel, WideOrgConfig, WideRepoConfig } from "./private";

export const getBaseMultiplier = (parsedRepo: WideRepoConfig | undefined, parsedOrg: WideOrgConfig | undefined): number => {
if (parsedRepo && parsedRepo["baseMultiplier"] && !Number.isNaN(Number(parsedRepo["baseMultiplier"]))) {
return Number(parsedRepo["baseMultiplier"]);
} else if (parsedOrg && parsedOrg["baseMultiplier"] && !Number.isNaN(Number(parsedOrg["baseMultiplier"]))) {
return Number(parsedOrg["baseMultiplier"]);
} else {
return Number(DefaultPriceConfig["baseMultiplier"]);
}
};

export const getTimeLabels = (parsedRepo: WideRepoConfig | undefined, parsedOrg: WideOrgConfig | undefined): WideLabel[] => {
if (parsedRepo && parsedRepo["timeLabels"] && Array.isArray(parsedRepo["timeLabels"]) && parsedRepo["timeLabels"].length > 0) {
return parsedRepo["timeLabels"];
} else if (parsedOrg && parsedOrg["timeLabels"] && Array.isArray(parsedOrg["timeLabels"]) && parsedOrg["timeLabels"].length > 0) {
return parsedOrg["timeLabels"];
} else {
return DefaultPriceConfig["timeLabels"];
}
};

export const getPriorityLabels = (parsedRepo: WideRepoConfig | undefined, parsedOrg: WideOrgConfig | undefined): WideLabel[] => {
if (parsedRepo && parsedRepo["priorityLabels"] && Array.isArray(parsedRepo["priorityLabels"]) && parsedRepo["priorityLabels"].length > 0) {
return parsedRepo["priorityLabels"];
} else if (parsedOrg && parsedOrg["priorityLabels"] && Array.isArray(parsedOrg["priorityLabels"]) && parsedOrg["priorityLabels"].length > 0) {
return parsedOrg["priorityLabels"];
} else {
return DefaultPriceConfig["priorityLabels"];
}
};

export const getAutoPayMode = (parsedRepo: WideRepoConfig | undefined, parsedOrg: WideOrgConfig | undefined): boolean => {
if (parsedRepo && parsedRepo["autoPayMode"] && typeof parsedRepo["autoPayMode"] === "boolean") {
return parsedRepo["autoPayMode"];
} else if (parsedOrg && parsedOrg["autoPayMode"] && typeof parsedOrg["autoPayMode"] === "boolean") {
return parsedOrg["autoPayMode"];
} else {
return true;
}
};

export const getAnalyticsMode = (parsedRepo: WideRepoConfig | undefined, parsedOrg: WideOrgConfig | undefined): boolean => {
if (parsedRepo && parsedRepo["analyticsMode"] && typeof parsedRepo["analyticsMode"] === "boolean") {
return parsedRepo["analyticsMode"];
} else if (parsedOrg && parsedOrg["analyticsMode"] && typeof parsedOrg["analyticsMode"] === "boolean") {
return parsedOrg["analyticsMode"];
} else {
return false;
}
};
132 changes: 132 additions & 0 deletions src/utils/private.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import _sodium from "libsodium-wrappers";
import YAML from "yaml";
import { getBotConfig } from "../bindings";
import { Payload } from "../types";
import { Context } from "probot";
import { getAnalyticsMode, getAutoPayMode, getBaseMultiplier, getPriorityLabels, getTimeLabels } from "./helpers";

const CONFIG_REPO = "ubiquibot-config";
const KEY_PATH = ".github/ubiquibot-config.yml";
const KEY_NAME = "PSK";
const KEY_PREFIX = "HSK_";

export const getConfigSuperset = async (context: Context, type: "org" | "repo"): Promise<string | undefined> => {
try {
const payload = context.payload as Payload;
const repo = type === "org" ? CONFIG_REPO : payload.repository.name!;
const { data } = await context.octokit.rest.repos.getContent({
owner: payload.organization?.login!,
repo: repo,
path: KEY_PATH,
mediaType: {
format: "raw",
},
});
return data as unknown as string;
} catch (error: any) {
return undefined;
}
};

export interface WideLabel {
name: string;
weight: number;
value?: number | undefined;
target: string;
}

export interface WideConfig {
baseMultiplier?: number;
timeLabels?: WideLabel[];
priorityLabels?: WideLabel[];
autoPayMode?: boolean;
analyticsMode?: boolean;
}

export interface WideRepoConfig extends WideConfig {}

export interface WideOrgConfig extends WideConfig {
PSK?: string;
}

export interface DataConfig {
privateKey: string;
baseMultiplier: number;
timeLabels: WideLabel[];
priorityLabels: WideLabel[];
autoPayMode: boolean;
analyticsMode: boolean;
}

export const parseYAML = async (data: any): Promise<any | undefined> => {
try {
const parsedData = await YAML.parse(data);
if (parsedData !== null) {
return parsedData;
} else {
return undefined;
}
} catch (error) {
return undefined;
}
};

export const getPrivateKey = async (cipherText: string): Promise<string | undefined> => {
try {
await _sodium.ready;
const sodium = _sodium;
const {
sodium: { publicKey, privateKey },
} = getBotConfig();

if (publicKey === "" || privateKey === "") {
return undefined;
}

const binPub = sodium.from_base64(publicKey, sodium.base64_variants.URLSAFE_NO_PADDING);
const binPriv = sodium.from_base64(privateKey, sodium.base64_variants.URLSAFE_NO_PADDING);
const binCipher = sodium.from_base64(cipherText, sodium.base64_variants.URLSAFE_NO_PADDING);

let walletPrivateKey: string | undefined = sodium.crypto_box_seal_open(binCipher, binPub, binPriv, "text");
walletPrivateKey = walletPrivateKey.startsWith(KEY_PREFIX) ? walletPrivateKey.replace(KEY_PREFIX, "") : undefined;
return walletPrivateKey;
} catch (error: any) {
return undefined;
}
};

export const getScalarKey = async (X25519_PRIVATE_KEY: string | undefined): Promise<string | undefined> => {
try {
if (X25519_PRIVATE_KEY !== undefined) {
await _sodium.ready;
const sodium = _sodium;

const binPriv = sodium.from_base64(X25519_PRIVATE_KEY, sodium.base64_variants.URLSAFE_NO_PADDING);
const scalerPub = sodium.crypto_scalarmult_base(binPriv, "base64");
return scalerPub;
}
return undefined;
} catch (error: any) {
return undefined;
}
};

export const getWideConfig = async (context: Context): Promise<DataConfig> => {
const orgConfig = await getConfigSuperset(context, "org");
const repoConfig = await getConfigSuperset(context, "repo");

const parsedOrg: WideOrgConfig | undefined = await parseYAML(orgConfig);
const parsedRepo: WideRepoConfig | undefined = await parseYAML(repoConfig);
const PSK = parsedOrg && parsedOrg[KEY_NAME] ? await getPrivateKey(parsedOrg[KEY_NAME]) : undefined;

const configData: DataConfig = {
privateKey: PSK ?? process.env.UBIQUITY_BOT_EVM_PRIVATE_KEY ?? "",
baseMultiplier: getBaseMultiplier(parsedRepo, parsedOrg),
timeLabels: getTimeLabels(parsedRepo, parsedOrg),
priorityLabels: getPriorityLabels(parsedRepo, parsedOrg),
autoPayMode: getAutoPayMode(parsedRepo, parsedOrg),
analyticsMode: getAnalyticsMode(parsedRepo, parsedOrg),
};

return configData;
};
33 changes: 33 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2573,6 +2573,13 @@ __metadata:
languageName: node
linkType: hard

"@types/libsodium-wrappers@npm:^0.7.10":
version: 0.7.10
resolution: "@types/libsodium-wrappers@npm:0.7.10"
checksum: 717054ebcb5fa553e378144b8d564bed8b691905c0d4e90b95c64d77ba24ec9fe798cb2c58cd61dad545ceacb1f05ab69b5597217f9829f2da7a23f0688d11d0
languageName: node
linkType: hard

"@types/lru-cache@npm:^5.1.0":
version: 5.1.1
resolution: "@types/lru-cache@npm:5.1.1"
Expand Down Expand Up @@ -7114,6 +7121,22 @@ __metadata:
languageName: node
linkType: hard

"libsodium-wrappers@npm:^0.7.11":
version: 0.7.11
resolution: "libsodium-wrappers@npm:0.7.11"
dependencies:
libsodium: ^0.7.11
checksum: 6a6ef47b2213e3fb4687196c28fee4c9885f70d89547d845e62d96014d3d5ad9f59cb05fadc601debc0031a3cfd0b9b416d7efbeb5bf66db6aa0ed69f55a6293
languageName: node
linkType: hard

"libsodium@npm:^0.7.11":
version: 0.7.11
resolution: "libsodium@npm:0.7.11"
checksum: 0a3493ac1829d1e346178b6984c4eb449dc77157c906876441386c0c653142e3fa56f623ce980bb50e580196578689298c9cd406ce6d514904090e370c6bc0f7
languageName: node
linkType: hard

"lilconfig@npm:2.1.0":
version: 2.1.0
resolution: "lilconfig@npm:2.1.0"
Expand Down Expand Up @@ -10602,6 +10625,7 @@ __metadata:
"@sinclair/typebox": ^0.25.9
"@supabase/supabase-js": ^2.4.0
"@types/jest": ^28.1.0
"@types/libsodium-wrappers": ^0.7.10
"@types/ms": ^0.7.31
"@types/node": ^14.18.37
"@types/source-map-support": ^0.5.6
Expand All @@ -10615,6 +10639,7 @@ __metadata:
jest: ^26.6.3
jimp: ^0.22.4
js-yaml: ^4.1.0
libsodium-wrappers: ^0.7.11
lint-staged: ^13.1.0
ms: ^2.1.3
nock: ^13.0.5
Expand All @@ -10630,6 +10655,7 @@ __metadata:
telegraf: ^4.11.2
ts-jest: ^26.4.4
typescript: ^4.9.5
yaml: ^2.2.2
languageName: unknown
linkType: soft

Expand Down Expand Up @@ -11237,6 +11263,13 @@ __metadata:
languageName: node
linkType: hard

"yaml@npm:^2.2.2":
version: 2.2.2
resolution: "yaml@npm:2.2.2"
checksum: d90c235e099e30094dcff61ba3350437aef53325db4a6bcd04ca96e1bfe7e348b191f6a7a52b5211e2dbc4eeedb22a00b291527da030de7c189728ef3f2b4eb3
languageName: node
linkType: hard

"yargs-parser@npm:20.x, yargs-parser@npm:^20.2.3":
version: 20.2.9
resolution: "yargs-parser@npm:20.2.9"
Expand Down
Loading

0 comments on commit dfae2ab

Please sign in to comment.