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

feat: permits are generated from the calculation results and redirect to the permit claim page #8

Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
29a55ee
Create main.yml
gentlementlegen Apr 2, 2024
108e55f
Create local-test.yml
gentlementlegen Apr 2, 2024
08e7028
Merge branch 'ubiquibot:development' into development
gentlementlegen Apr 7, 2024
50b396b
feat: permit generation module
gentlementlegen Apr 11, 2024
0534c62
chore: fix workflow test
gentlementlegen Apr 11, 2024
7cf32ac
chore: bump permit-generation package
gentlementlegen Apr 11, 2024
09c564c
chore: bump main action package
gentlementlegen Apr 11, 2024
48db80c
chore: updated env vars for actions
gentlementlegen Apr 11, 2024
6caf3fb
chore: updated env vars for actions
gentlementlegen Apr 11, 2024
c9a68de
chore: changed aggregation total to be after each step
gentlementlegen Apr 11, 2024
fbb551a
chore: changed evmNetworkId type to number
gentlementlegen Apr 11, 2024
b8e81cf
chore: changed arguments to be inside the CLI
gentlementlegen Apr 11, 2024
15671d9
chore: pushed yarn.lock again
gentlementlegen Apr 11, 2024
392c334
chore: removed unused env.d.ts definitions
gentlementlegen Apr 11, 2024
02b9c96
chore: fixed env definition
gentlementlegen Apr 11, 2024
4c16c7b
Create main.yml
gentlementlegen Apr 2, 2024
09b61cc
Create local-test.yml
gentlementlegen Apr 2, 2024
925243f
feat: permit generation module
gentlementlegen Apr 11, 2024
11c5809
Merge branch 'development' into feat/permit-generation
gentlementlegen Apr 15, 2024
f1f8f23
chore: fixed yarn conflict
gentlementlegen Apr 15, 2024
bd9a217
chore: fix knip unused file
gentlementlegen Apr 15, 2024
6f96775
chore: fix knip unused export
gentlementlegen Apr 15, 2024
3c58a1a
chore: relinked ubiquibot package
gentlementlegen Apr 15, 2024
2e02ddc
chore: change supabase key variable name and upgraded package
gentlementlegen Apr 15, 2024
23a65d9
chore: fixed payload duplicated code
gentlementlegen Apr 15, 2024
1eb86bd
chore: deleted local tests action file
gentlementlegen Apr 15, 2024
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
3 changes: 3 additions & 0 deletions .github/workflows/jest-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
gentlementlegen marked this conversation as resolved.
Show resolved Hide resolved
X25519_PRIVATE_KEY: ${{ secrets.X25519_PRIVATE_KEY }}

steps:
- name: Checkout code
Expand Down
40 changes: 40 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Run Local Tests

on:
workflow_dispatch:
inputs:
issueUrl:
description: "The URL the the issue needing to be parsed"
required: true
evmNetworkId:
description: "The EVM network ID to use"
required: true
type: number
evmPrivateEncrypted:
description: "The encrypted EVM private key"
required: true

jobs:
test-local:
name: Run Local Tests
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
X25519_PRIVATE_KEY: ${{ secrets.X25519_PRIVATE_KEY }}

steps:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20.10.0"

- name: Action Test
# Replace with whatever package version you want to test
uses: gentlementlegen/conversation-rewards@feat/permit-generation
with:
issueUrl: ${{ inputs.issueUrl }}
evmNetworkId: ${{ inputs.evmNetworkId }}
evmPrivateEncrypted: ${{ inputs.evmPrivateEncrypted }}
16 changes: 16 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Release Please

on:
workflow_dispatch:
push:
branches:
- main
gentlementlegen marked this conversation as resolved.
Show resolved Hide resolved

jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: google-github-actions/release-please-action@v4
gentlementlegen marked this conversation as resolved.
Show resolved Hide resolved
with:
release-type: simple
default-branch: main
10 changes: 8 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
name: "Conversation Rewards"
description: "Compute rewards for contributors' discussion on issues that are closed as complete."
inputs:
issue_url:
issueUrl:
description: "The URL the the issue needing to be parsed"
required: true
evmNetworkId:
description: "The EVM network ID to use"
required: true
evmPrivateEncrypted:
description: "The encrypted EVM private key"
required: true
outputs:
result:
description: "The result containing all the rewards of the users"
Expand All @@ -13,7 +19,7 @@ runs:
steps:
- run: |
yarn --cwd ${{ github.action_path }} --production=true
yarn --cwd ${{ github.action_path }} start --issue "${{ inputs.issue_url }}" --file "${{ github.action_path }}/results.json"
yarn --cwd ${{ github.action_path }} start --issue "${{ inputs.issueUrl }}" --evmNetworkId "${{ inputs.evmNetworkId }}" --evmPrivateEncrypted "${{ inputs.evmPrivateEncrypted }}" --file "${{ github.action_path }}/results.json"
output=$(cat ${{ github.action_path }}/results.json | tr -s ' ' | tr -d '\n')
echo "Output of calculations:"
echo "$output"
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@
"open-source"
],
"dependencies": {
"@actions/github": "6.0.0",
"@commander-js/extra-typings": "12.0.1",
"@octokit/rest": "20.0.2",
"@octokit/rest": "20.1.0",
"@sinclair/typebox": "0.32.20",
"@supabase/supabase-js": "2.42.0",
"@ubiquibot/permit-generation": "1.0.2",
"commander": "12.0.0",
"decimal.js": "10.4.3",
"dotenv": "16.4.5",
Expand Down
2 changes: 2 additions & 0 deletions rewards-configuration.default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ formattingEvaluator:
- type: [REVIEW, CONTRIBUTOR]:
formattingMultiplier: 0.25
wordValue: 0.1
permitGeneration:
enabled: true
9 changes: 9 additions & 0 deletions src/configuration/permit-generation-configuration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Static, Type } from "@sinclair/typebox";

const permitGenerationConfigurationType = Type.Object({
enabled: Type.Boolean(),
});

export type PermitGenerationConfiguration = Static<typeof permitGenerationConfigurationType>;

export default permitGenerationConfigurationType;
6 changes: 6 additions & 0 deletions src/parser/command-line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@ if (process.env.NODE_ENV === "test") {
process.argv.splice(2);
process.argv.push("-i");
process.argv.push(`${process.env.TEST_ISSUE_URL}`);
process.argv.push("-n");
process.argv.push("100");
process.argv.push("-e");
process.argv.push("privateKey");
}

const program = new Command()
.requiredOption("-i, --issue <url>", "The url of the issue to parse")
.requiredOption("-n, --evmNetworkId <number>", "The network ID", parseInt)
.requiredOption("-e, --evmPrivateEncrypted <key>", "The EVM private encrypted key")
.option("-c, --config <path>", "The path to the desired configuration to use", "rewards-configuration.default.yml")
.option("-f, --file <file>", "The target file to store the results in")
.version(packageJson.version)
Expand Down
120 changes: 120 additions & 0 deletions src/parser/permit-generation-module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { context } from "@actions/github";
import { Value } from "@sinclair/typebox/value";
import { createClient } from "@supabase/supabase-js";
import {
Context,
createAdapters,
Database,
encodePermits,
generatePayoutPermit,
SupportedEvents,
TokenType,
} from "@ubiquibot/permit-generation";
import configuration from "../configuration/config-reader";
import contentEvaluatorConfig from "../configuration/content-evaluator-config";
import { getOctokitInstance } from "../get-authentication-token";
import { IssueActivity } from "../issue-activity";
import { Module, Result } from "./processor";
import program from "./command-line";

interface Payload {
evmNetworkId: number;
issueUrl: string;
evmPrivateEncrypted: string;
issue: { id: number };
}

export class PermitGenerationModule implements Module {
readonly _configuration: PermitGenerationModule = configuration.permitGeneration;
readonly _supabase = createClient<Database>(process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY);

async transform(data: Readonly<IssueActivity>, result: Result): Promise<Result> {
const payload: Context["payload"] & Payload = {
...context.payload.inputs,
issueUrl: program.opts().issue,
evmPrivateEncrypted: program.opts().evmPrivateEncrypted,
evmNetworkId: program.opts().evmNetworkId,
};
const issueId = Number(payload.issueUrl.match(/[0-9]+$/)?.[1]);
payload.issue = {
id: issueId,
};
const env = process.env;
gentlementlegen marked this conversation as resolved.
Show resolved Hide resolved
const eventName = context.eventName as SupportedEvents;
const octokit = getOctokitInstance();
const logger = {
debug(message: unknown, optionalParams: unknown) {
console.log(message, optionalParams);
},
error(message: unknown, optionalParams: unknown) {
console.error(message, optionalParams);
},
fatal(message: unknown, optionalParams: unknown) {
console.error(message, optionalParams);
},
info(message: unknown, optionalParams: unknown) {
console.log(message, optionalParams);
},
warn(message: unknown, optionalParams: unknown) {
console.warn(message, optionalParams);
},
};
const adapters = {} as ReturnType<typeof createAdapters>;

for (const [key, value] of Object.entries(result)) {
try {
const config: Context["config"] = {
evmNetworkId: payload.evmNetworkId,
evmPrivateEncrypted: payload.evmPrivateEncrypted,
permitRequests: [
{
amount: value.total,
userId: value.userId,
contributionType: "",
gentlementlegen marked this conversation as resolved.
Show resolved Hide resolved
type: TokenType.ERC20,
},
],
};
const permits = await generatePayoutPermit(
{
env,
eventName,
logger,
payload,
adapters: createAdapters(this._supabase, {
env,
eventName,
octokit,
config,
logger,
payload,
adapters,
}),
octokit,
config,
},
[
{
type: "ERC20",
gentlementlegen marked this conversation as resolved.
Show resolved Hide resolved
userId: value.userId,
amount: value.total,
contributionType: "",
},
]
);
result[key].permitUrl = `https://pay.ubq.fi?claim=${encodePermits(permits)}`;
} catch (e) {
console.error(e);
}
}
return Promise.resolve(result);
}

get enabled(): boolean {
if (!Value.Check(contentEvaluatorConfig, this._configuration)) {
console.warn("Invalid configuration detected for PermitGenerationModule, disabling.");
return false;
}
return this._configuration.enabled;
}
}
14 changes: 9 additions & 5 deletions src/parser/processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import program from "./command-line";
import { ContentEvaluatorModule } from "./content-evaluator-module";
import { DataPurgeModule } from "./data-purge-module";
import { FormattingEvaluatorModule } from "./formatting-evaluator-module";
import { PermitGenerationModule } from "./permit-generation-module";
import { UserExtractorModule } from "./user-extractor-module";

export class Processor {
Expand All @@ -17,7 +18,8 @@ export class Processor {
this.add(new UserExtractorModule())
.add(new DataPurgeModule())
.add(new FormattingEvaluatorModule())
.add(new ContentEvaluatorModule());
.add(new ContentEvaluatorModule())
.add(new PermitGenerationModule());
}

add(transformer: Module) {
Expand All @@ -34,10 +36,10 @@ export class Processor {
if (transformer.enabled) {
this._result = await transformer.transform(data, this._result);
}
}
// Aggregate total result
for (const item of Object.keys(this._result)) {
this._result[item].total = this._sumRewards(this._result[item]);
// Aggregate total result
for (const item of Object.keys(this._result)) {
this._result[item].total = this._sumRewards(this._result[item]);
}
}
return this._result;
}
Expand Down Expand Up @@ -96,6 +98,8 @@ export interface Result {
task?: {
reward: number;
};
permitUrl?: string;
userId: number;
};
}

Expand Down
1 change: 1 addition & 0 deletions src/parser/user-extractor-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export class UserExtractorModule implements Module {
...result[comment.user.login],
total: 0,
task,
userId: comment.user.id,
};
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/types/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
declare global {
namespace NodeJS {
interface ProcessEnv {
GITHUB_TOKEN: string;
OPENAI_API_KEY: string;
X25519_PRIVATE_KEY: string;
SUPABASE_ANON_KEY: string;
gentlementlegen marked this conversation as resolved.
Show resolved Hide resolved
SUPABASE_URL: string;
}
}
}

export {};
Loading
Loading