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

Html comments #545

Merged
merged 20 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from 19 commits
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
11 changes: 11 additions & 0 deletions .github/ubiquibot-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,16 @@ payment-permit-max-price: 1000
comment-incentives: true
max-concurrent-bounties: 2
promotion-comment: "\n<h6>If you enjoy the DevPool experience, please follow <a href='https://github.com/ubiquity'>Ubiquity on GitHub</a> and star <a href='https://github.com/ubiquity/devpool-directory'>this repo</a> to show your support. It helps a lot!</h6>"
incentives:
comment:
elements:
code: 5
img: 5
h1: 1
li: 0.5
a: 0.5
blockquote: 0
totals:
word: 0.1
register-wallet-with-verification: false
assistive-pricing: true
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,12 @@ To test the bot, you can:

`issue-creator-multiplier` is a number that defines a base multiplier for calculating incentive reward for the creator of the issue.

`comment-element-pricing` defines how much is a part of the comment worth. For example `text: 0.1` means that any text in the comment will be multiplied by 0.1
`incentives` defines incentive rewards:

- `comment` defines comment rewards:
- `elements` defines reward value for HTML elements such as `p`, `img`, `a`.
- `totals`:
- `word` defines reward for each word in the comment

`max-concurrent-bounties` is the maximum number of bounties that can be assigned to a bounty hunter at once. This excludes bounties with pending pull request reviews.

Expand Down
6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
"@probot/adapter-github-actions": "^3.1.3",
"@sinclair/typebox": "^0.25.9",
"@supabase/supabase-js": "^2.4.0",
"@types/mdast": "^3.0.11",
"@types/ms": "^0.7.31",
"@typescript-eslint/eslint-plugin": "^5.59.11",
"@typescript-eslint/parser": "^5.59.11",
Expand All @@ -44,20 +43,19 @@
"ajv": "^8.11.2",
"ajv-formats": "^2.1.1",
"axios": "^1.3.2",
"decimal.js": "^10.4.3",
"copyfiles": "^2.4.1",
"ethers": "^5.7.2",
"husky": "^8.0.2",
"jimp": "^0.22.4",
"js-yaml": "^4.1.0",
"libsodium-wrappers": "^0.7.11",
"lint-staged": "^13.1.0",
"mdast-util-from-markdown": "^1.3.0",
"mdast-util-gfm": "^2.0.2",
"micromark-extension-gfm": "^2.0.3",
"ms": "^2.1.3",
"node-html-parser": "^6.1.5",
"node-html-to-image": "^3.3.0",
"nodemon": "^2.0.19",
"parse5": "^7.1.2",
"prettier": "^2.7.1",
"probot": "^12.2.4",
"telegraf": "^4.11.2",
Expand Down
23 changes: 18 additions & 5 deletions src/adapters/supabase/helpers/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,22 +160,35 @@ export const upsertWalletAddress = async (username: string, address: string): Pr
const logger = getLogger();
const { supabase } = getAdapters();

const { data, error } = await supabase.from("wallets").select("user_name").eq("user_name", username).single();
if (data) {
await supabase.from("wallets").upsert({
const { data, error } = await supabase.from("wallets").select("user_name").eq("user_name", username);
if (error) {
logger.error(`Checking wallet address failed, error: ${JSON.stringify(error)}`);
throw new Error(`Checking wallet address failed, error: ${JSON.stringify(error)}`);
}

if (data && data.length > 0) {
const { data: _data, error: _error } = await supabase.from("wallets").upsert({
user_name: username,
wallet_address: address,
updated_at: new Date().toUTCString(),
});
logger.info(`Upserting a wallet address done, { data: ${data}, error: ${error} }`);
if (_error) {
logger.error(`Upserting a wallet address failed, error: ${JSON.stringify(_error)}`);
throw new Error(`Upserting a wallet address failed, error: ${JSON.stringify(_error)}`);
}
logger.info(`Upserting a wallet address done, { data: ${JSON.stringify(_data)} }`);
} else {
const { data: _data, error: _error } = await supabase.from("wallets").insert({
user_name: username,
wallet_address: address,
created_at: new Date().toUTCString(),
updated_at: new Date().toUTCString(),
});
logger.info(`Creating a new wallet_table record done, { error: ${_error?.message} }`);
if (_error) {
logger.error(`Creating a new wallet_table record failed, error: ${JSON.stringify(_error)}`);
throw new Error(`Creating a new wallet_table record failed, error: ${JSON.stringify(_error)}`);
}
logger.info(`Creating a new wallet_table record done, { data: ${JSON.stringify(_data)} }`);
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/bindings/config.ts
0x4007 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const loadConfig = async (context: Context): Promise<BotConfig> => {
timeLabels,
privateKey,
priorityLabels,
commentElementPricing,
incentives,
paymentPermitMaxPrice,
disableAnalytics,
bountyHunterMax,
Expand All @@ -40,7 +40,7 @@ export const loadConfig = async (context: Context): Promise<BotConfig> => {
issueCreatorMultiplier,
timeLabels,
priorityLabels,
commentElementPricing,
incentives,
defaultLabels,
},
comments: {
Expand Down
28 changes: 15 additions & 13 deletions src/handlers/payout/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ import {
clearAllPriceLabelsOnIssue,
deleteLabel,
generatePermit2Signature,
getAllIssueAssignEvents,
getAllIssueComments,
getTokenSymbol,
savePermitToDB,
wasIssueReopened,
getAllIssueAssignEvents,
} from "../../helpers";
import { UserType, Payload, StateReason } from "../../types";
import { shortenEthAddress } from "../../utils";
import { bountyInfo } from "../wildcard";
import Decimal from "decimal.js";
import { GLOBAL_STRINGS } from "../../configs";
import { isParentIssue } from "../pricing";

Expand Down Expand Up @@ -142,45 +143,46 @@ export const handleIssueClosed = async () => {
}

const recipient = await getWalletAddress(assignee.login);
const { value } = await getWalletMultiplier(assignee.login, id?.toString());
if (!recipient || recipient?.trim() === "") {
logger.info(`Recipient address is missing`);
return;
}

if (value === 0) {
const { value: multiplier } = await getWalletMultiplier(assignee.login, id?.toString());

if (multiplier === 0) {
const errMsg = "Refusing to generate the payment permit because " + `@${assignee.login}` + "'s payment `multiplier` is `0`";
logger.info(errMsg);
return errMsg;
}

// TODO: add multiplier to the priceInEth
let priceInEth = (+issueDetailed.priceLabel.substring(7, issueDetailed.priceLabel.length - 4) * value).toString();
if (parseInt(priceInEth) > paymentPermitMaxPrice) {
let priceInEth = new Decimal(issueDetailed.priceLabel.substring(7, issueDetailed.priceLabel.length - 4)).mul(multiplier);
if (priceInEth.gt(paymentPermitMaxPrice)) {
logger.info("Skipping to proceed the payment because bounty payout is higher than paymentPermitMaxPrice");
return `Permit generation skipped since issue's bounty is higher than ${paymentPermitMaxPrice}`;
}
if (!recipient || recipient?.trim() === "") {
logger.info(`Recipient address is missing`);
return;
}

// if bounty hunter has any penalty then deduct it from the bounty
const penaltyAmount = await getPenalty(assignee.login, payload.repository.full_name, paymentToken, networkId.toString());
if (penaltyAmount.gt(0)) {
logger.info(`Deducting penalty from bounty`);
const bountyAmount = ethers.utils.parseUnits(priceInEth, 18);
const bountyAmount = ethers.utils.parseUnits(priceInEth.toString(), 18);
const bountyAmountAfterPenalty = bountyAmount.sub(penaltyAmount);
if (bountyAmountAfterPenalty.lte(0)) {
await removePenalty(assignee.login, payload.repository.full_name, paymentToken, networkId.toString(), bountyAmount);
const msg = `Permit generation skipped because bounty amount after penalty is 0`;
logger.info(msg);
return msg;
}
priceInEth = ethers.utils.formatUnits(bountyAmountAfterPenalty, 18);
priceInEth = new Decimal(ethers.utils.formatUnits(bountyAmountAfterPenalty, 18));
}

const { txData, payoutUrl } = await generatePermit2Signature(recipient, priceInEth, issue.node_id);
const tokenSymbol = await getTokenSymbol(paymentToken, rpc);
const shortenRecipient = shortenEthAddress(recipient, `[ CLAIM ${priceInEth} ${tokenSymbol.toUpperCase()} ]`.length);
logger.info(`Posting a payout url to the issue, url: ${payoutUrl}`);
const comment = `### [ **[ CLAIM ${priceInEth} ${tokenSymbol.toUpperCase()} ]** ](${payoutUrl})\n` + "```" + shortenRecipient + "```";
const comment =
`#### Task Assignee Reward\n### [ **[ CLAIM ${priceInEth} ${tokenSymbol.toUpperCase()} ]** ](${payoutUrl})\n` + "```" + shortenRecipient + "```";
const permitComments = comments.filter((content) => content.body.includes("https://pay.ubq.fi?claim=") && content.user.type == UserType.Bot);
if (permitComments.length > 0) {
logger.info(`Skip to generate a permit url because it has been already posted`);
Expand Down
Loading