Skip to content

Commit

Permalink
Release Oct 2024 - decentralized verification (#1843)
Browse files Browse the repository at this point in the history
* fix: remove memo for project verification managing funds

* fix: remove memo for project verification managing funds

* add projectId and qfRoundId to qf data export

* fix: getDraftDonationById bug (toWalletMemo can be null)

* fix: add memo for stellar project address uniqueness

* fix: add memo for manage address validation

* fix: add duplicate address error message for stellar

* fix: linter error

* add index for project stellar address

* eslint error

* fix: case when owner donate to his own peoject (Stellar chain)

* fix: add calculateGivbackFactor to Stellar cron job

* onlyEndaement option added to donationResolvers to get only endaoment projects

* chore: implementing coderabbitai suggestion to remove string literal

* feat: register secondary donation

* running migration to set project banners appropriately for endaoment … (#1778)

* running migration to set project banners appropriately for endaoment projects

* chore: correcting tab spaces for syntax

* fix: linter errors

* Modify add banner to endaoment projects migration (#1791)

related to #1600

* Fix lint errors

* Fix running tests

* Fix projectResolver test cases

* Fix donationResolver test cases

* skip should renew the expiration date of the draft donation test case

---------

Co-authored-by: Hrithik Sampson <[email protected]>
Co-authored-by: mohammadranjbarz <[email protected]>

* improve adminjs to import qfround matching and better filters

* fix eslint

* fix: remove adding secondary donation logic

* fix minor form issues

* order middleware in bootstrap file

* test: add test cases to fetch only Endaoment projects

* chore: change the second Project to first Project

* chore: change the second Project to first Project

* chore: change the second Project to first Project

* chore: change the second user to new user since it is interfering with the pre-existing test cases

* delete previous_round_rank when deleting a project (#1809)

* Implement  allocatedGivbacks function (#1808)

* WIP Implement  allocatedGivbacks function

related to Giveth/giveth-dapps-v2#4678 Giveth/giveth-dapps-v2#4679

* allocatedGivbacks() endpoint implemented and works

related to Giveth/giveth-dapps-v2#4678 Giveth/giveth-dapps-v2#4679

* Fix allocatedGivbacksQuery test cases

* migration: project banners for endaoment projects need to have the correct banners

* chore: underscore before unused variable in add_endaoment_project_banners

* Use Gnosis giv token for getting price of GIV

* Use superfluid mock adapter for test cases

* Use superfluid adapter on test env again

* Feat/separate givback verfied (#1770)

* add isGivbackEligible field

* add AddIsGivbackEligibleColumnToProject1637168932304

* add UpdateIsGivbackEligibleForVerifiedProjects1637168932305 migration

* add migration to rename isProjectVerified to isProjectGivbackEligible

* change isProjectVerified tp isProjectGivbackEligible

* update octant donation

* add approve project

* treat project.verified and project.isGivbackEligible equally on sorting

* remove reset verification status on verify

* check isGivbackEligible on create ProjectVerificationForm

* add ProjectInstantPowerViewV3 migration

* use verifiedOrIsGivbackEligibleCondition

* Use different materialized view for givback factor

related to #1770

* Fix build error

* Fix build error

* Fix project query for isGivbackEligible and verified

* Fix add base token migration

* Fix eslint errors

* Fix add base token migration

* Fix add base token migration

* Fix add base token migration

* Fix donation test cases related to isGivbackEligible

* Fix build error

---------

Co-authored-by: Mohammad Ranjbar Z <[email protected]>

* Fix test cases related to isProjectVerified

* add isImported And categories to project tab

* fix isProjectGivbackEligible Migration in wrong folder

* add chaintype and solana networks to tokenTab

* update branch

* add environment and energy image mapping

* add categories to show and edit forms in adminjs for projects

* fix eslint

* add best match sort option

* update addSearchQuery to prioritize the title

* Add Stellar to QFRound

* run linter

* remove eager from project categories in entity

* Add isGivbackEligible filter

* Hotfix automatic model score sync (#1849)

* add user mbdscore sync workers and cronjob

* add active env var for syncing score

* add tests to the user sync worker and cronjob

* prevent duplicate tokens being added in adminJS

* Ensure correct emails are sent for project status changes related to decentralized verification

* fix test

* fix test cases

* fix test cases

---------

Co-authored-by: Meriem-BM <[email protected]>
Co-authored-by: Carlos <[email protected]>
Co-authored-by: HrithikSampson <[email protected]>
Co-authored-by: HrithikSampson <[email protected]>
Co-authored-by: Hrithik Sampson <[email protected]>
Co-authored-by: CarlosQ96 <[email protected]>
Co-authored-by: Cherik <[email protected]>
Co-authored-by: Ramin <[email protected]>
  • Loading branch information
9 people authored Oct 3, 2024
1 parent d0eefa4 commit dd4a672
Show file tree
Hide file tree
Showing 69 changed files with 2,841 additions and 265 deletions.
Binary file modified .DS_Store
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class RenameIsProjectVerifiedToIsGivbackEligibleInDonation1637168932306
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE donation
RENAME COLUMN "isProjectVerified" TO "isProjectGivbackEligible";
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE donation
RENAME COLUMN "isProjectGivbackEligible" TO "isProjectVerified";
`);
}
}
1 change: 1 addition & 0 deletions migration/1646295724658-createTokensTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export class createTokensTable1646295724658 implements MigrationInterface {
name text COLLATE pg_catalog."default" NOT NULL,
symbol text COLLATE pg_catalog."default" NOT NULL,
address text COLLATE pg_catalog."default" NOT NULL,
"isQR" BOOLEAN DEFAULT FALSE NOT NUL,
"networkId" integer NOT NULL,
decimals integer NOT NULL,
"order" integer,
Expand Down
2 changes: 1 addition & 1 deletion migration/1696918830123-add_octant_donations_to_db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const transactions: Partial<Donation>[] = [
transactionId:
'0x30954cb441cb7b2184e6cd1afc6acbd1318f86a68b669f6bfb2786dd459e2d6c',
currency: 'ETH',
isProjectVerified: true,
isProjectGivbackEligible: true,
isTokenEligibleForGivback: true,
amount: 5,
valueUsd: 9_458.4,
Expand Down
4 changes: 4 additions & 0 deletions migration/1716367359560-add_base_chain_tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { NETWORK_IDS } from '../src/provider';

export class AddBaseChainTokens1716367359560 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE token ADD COLUMN IF NOT EXISTS "isQR" BOOLEAN DEFAULT FALSE NOT NULL`,
);

const environment = config.get('ENVIRONMENT') as string;

const networkId =
Expand Down
23 changes: 23 additions & 0 deletions migration/1724060343213-AddIsGivbackEligibleColumnToProject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm';

export class AddIsGivbackEligibleColumnToProject1637168932304
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
// Add the new column
await queryRunner.addColumn(
'project',
new TableColumn({
name: 'isGivbackEligible',
type: 'boolean',
isNullable: false,
default: false,
}),
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
// Drop the isGivbackEligible column
await queryRunner.dropColumn('project', 'isGivbackEligible');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class UpdateIsGivbackEligibleForVerifiedProjects1637168932305
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
// Update isGivbackEligible to true for verified projects
await queryRunner.query(`
UPDATE project
SET "isGivbackEligible" = true
WHERE "verified" = true;
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
// Revert the update (optional)
await queryRunner.query(`
UPDATE project
SET "isGivbackEligible" = false
WHERE "verified" = true;
`);
}
}
66 changes: 66 additions & 0 deletions migration/1724223781248-ProjectInstantPowerViewV3.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class ProjectInstantPowerViewV31724223781248
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
DROP MATERIALIZED VIEW IF EXISTS public.project_instant_power_view;
CREATE MATERIALIZED VIEW IF NOT EXISTS public.project_instant_power_view AS
SELECT
innerview."projectId",
ROUND(CAST(innerview."totalPower" as NUMERIC), 2) as "totalPower",
rank() OVER (
ORDER BY
innerview."totalPower" DESC
) AS "powerRank"
FROM
(
SELECT
project.id AS "projectId",
CASE
WHEN (project.verified = true OR project."isGivbackEligible" = true) AND project."statusId" = 5 THEN COALESCE(sum(pp."boostedPower"), 0 :: double precision)
ELSE 0 :: double precision
END AS "totalPower"
FROM
project
LEFT JOIN (
SELECT
"powerBoosting"."projectId",
sum("instantPowerBalance".balance * "powerBoosting".percentage :: double precision / 100 :: double precision) AS "boostedPower",
now() AS "updateTime"
FROM
instant_power_balance "instantPowerBalance"
JOIN power_boosting "powerBoosting" ON "powerBoosting"."userId" = "instantPowerBalance"."userId"
GROUP BY
"powerBoosting"."projectId"
) pp ON pp."projectId" = project.id
GROUP BY
project.id
) innerview
ORDER BY
innerview."totalPower" DESC WITH DATA;
`);

await queryRunner.query(`
CREATE UNIQUE INDEX idx_project_instant_power_view_unique ON public.project_instant_power_view ("projectId");
`);

await queryRunner.query(`
CREATE INDEX project_instant_power_view_project_id ON public.project_instant_power_view USING hash ("projectId") TABLESPACE pg_default;
`);

await queryRunner.query(`
CREATE INDEX project_instant_power_view_total_power ON public.project_instant_power_view USING btree ("totalPower" DESC) TABLESPACE pg_default;
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
DROP MATERIALIZED VIEW IF EXISTS public.project_instant_power_view;
DROP INDEX IF EXISTS public.idx_project_instant_power_view_unique;
DROP INDEX IF EXISTS public.project_instant_power_view_project_id;
DROP INDEX IF EXISTS public.project_instant_power_view_total_power;
`);
}
}
66 changes: 66 additions & 0 deletions migration/1725260193333-projectGivbackRankView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class ProjectGivbackRankViewV31725260193333
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`
DROP
MATERIALIZED VIEW IF EXISTS public.project_givback_rank_view;
CREATE MATERIALIZED VIEW IF NOT EXISTS public.project_givback_rank_view AS
SELECT
innerview."projectId",
ROUND(CAST(innerview."totalPower" as NUMERIC), 2) as "totalPower",
rank() OVER (
ORDER BY
innerview."totalPower" DESC
) AS "powerRank",
"powerRound".round
FROM
(
SELECT
project.id AS "projectId",
CASE project."isGivbackEligible" and project."statusId" = 5 WHEN false THEN 0 :: double precision ELSE COALESCE(
sum(pp."boostedPower"),
0 :: double precision
) END AS "totalPower"
FROM
project project
LEFT JOIN (
SELECT
"powerRound".round,
"powerBoostingSnapshot"."projectId",
"powerBoostingSnapshot"."userId",
avg(
"powerBalanceSnapshot".balance * "powerBoostingSnapshot".percentage :: double precision / 100 :: double precision
) AS "boostedPower",
now() AS "updateTime"
FROM
power_round "powerRound"
JOIN power_snapshot "powerSnapshot" ON "powerSnapshot"."roundNumber" = "powerRound".round
JOIN power_balance_snapshot "powerBalanceSnapshot" ON "powerBalanceSnapshot"."powerSnapshotId" = "powerSnapshot".id
JOIN power_boosting_snapshot "powerBoostingSnapshot" ON "powerBoostingSnapshot"."powerSnapshotId" = "powerSnapshot".id
AND "powerBoostingSnapshot"."userId" = "powerBalanceSnapshot"."userId"
GROUP BY
"powerRound".round,
"powerBoostingSnapshot"."projectId",
"powerBoostingSnapshot"."userId"
) pp ON pp."projectId" = project.id
GROUP BY
project.id
) innerview,
power_round "powerRound"
ORDER BY
innerview."totalPower" DESC WITH DATA;
CREATE UNIQUE INDEX project_givback_rank_view_project_id_round_unique ON public.project_givback_rank_view ("projectId", "round");
CREATE INDEX project_givback_rank_view_project_id ON public.project_givback_rank_view USING hash ("projectId") TABLESPACE pg_default;
CREATE INDEX project_givback_rank_view_total_power ON public.project_givback_rank_view USING btree ("totalPower" DESC) TABLESPACE pg_default;
`,
);
}

public async down(_queryRunner: QueryRunner): Promise<void> {
//
}
}
86 changes: 86 additions & 0 deletions migration/1726069430594-add_endaoment_project_banners.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { endaomentProjects } from './data/importedEndaomentProjects';
import { endaomentProjectCategoryMapping } from './data/endaomentProjectCategoryMapping';
import { NETWORK_IDS } from '../src/provider';
export class AddEndaomentProjectBanners1726069430594
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
const mainCategorySlugToBannerMapping = {
'environment-and-energy': 'environment-energy',
'health-and-wellness': 'health-wellness',
'art-and-culture': 'art-culture',
nature: 'nature',
community: 'community',
finance: 'finance',
education: 'education',
equality: 'equality',
other: '1',
'economic-and-infrastructure': 'economic-infrastructure',
ngo: 'non-profit',
technology: 'technology',
};
const subCategoryToCategory = await queryRunner.query(
'SELECT category.value, main_category.slug from category LEFT JOIN main_category on category."mainCategoryId" = main_category.id;',
);

const imageCategoryMapping = subCategoryToCategory.reduce(function (
categoryImageKeyPair,
category: { value: string; slug: string },
) {
const bannerLink = mainCategorySlugToBannerMapping[category.slug] || '1';
categoryImageKeyPair[category.value] = bannerLink;
return categoryImageKeyPair;
}, {});

for (const project of endaomentProjects) {
const mainnetAddress = project.mainnetAddress;
const projectAddresses = await queryRunner.query(
`SELECT * FROM project_address WHERE LOWER(address) = $1 AND "networkId" = $2 LIMIT 1`,
[mainnetAddress!.toLowerCase(), NETWORK_IDS.MAIN_NET],
);

const projectAddress = await projectAddresses?.[0];

if (!projectAddress) {
// eslint-disable-next-line no-console
console.log(`Could not find project address for ${mainnetAddress}`);
continue;
}

// Insert the project-category relationship in a single query
const getCategoryNames = (nteeCode: string): string[] => {
const mapping = endaomentProjectCategoryMapping.find(
category => category.nteeCode === nteeCode,
);
return mapping
? [
mapping.category1,
mapping.category2,
mapping.category3 || '',
mapping.category4 || '',
].filter(Boolean)
: [];
};
if (!project.nteeCode) {
// eslint-disable-next-line no-console
console.log(`Could not find nteeCode for ${mainnetAddress}`);
continue;
}
const categoryNames = getCategoryNames(String(project.nteeCode));
const bannerImage = `/images/defaultProjectImages/${imageCategoryMapping[categoryNames[1]] || '1'}.png`;
await queryRunner.query(`UPDATE project SET image = $1 WHERE id = $2`, [
bannerImage,
projectAddress.projectId,
]);
// eslint-disable-next-line no-console
console.log(
`Updated project ${projectAddress.projectId} with image ${bannerImage}`,
);
}
}

public async down(_queryRunner: QueryRunner): Promise<void> {
// No down migration
}
}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@
"test:qfRoundHistoryRepository": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/repositories/qfRoundHistoryRepository.test.ts",
"test:qfRoundService": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/services/qfRoundService.test.ts",
"test:project": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/entities/project.test.ts",
"test:projectsTab": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/server/adminJs/tabs/projectsTab.test.ts",
"test:syncUsersModelScore": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/services/cronJobs/syncUsersModelScore.test.ts",
"test:notifyDonationsWithSegment": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/services/cronJobs/notifyDonationsWithSegment.test.ts",
"test:checkProjectVerificationStatus": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/services/cronJobs/checkProjectVerificationStatus.test.ts",
"test:statusReasonResolver": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/resolvers/statusReasonResolver.test.ts",
Expand Down Expand Up @@ -166,6 +168,7 @@
"test:anchorContractAddressRepository": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/repositories/anchorContractAddressRepository.test.ts",
"test:recurringDonationRepository": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/repositories/recurringDonationRepository.test.ts",
"test:userPassportScoreRepository": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/repositories/userPassportScoreRepository.test.ts",
"test:projectGivbackRepository": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/repositories/projectGivbackViewRepository.test.ts",
"test:recurringDonationService": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/services/recurringDonationService.test.ts",
"test:dbCronRepository": "NODE_ENV=test mocha -t 90000 ./test/pre-test-scripts.ts ./src/repositories/dbCronRepository.test.ts",
"test:powerBoostingResolver": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/resolvers/powerBoostingResolver.test.ts",
Expand Down
15 changes: 13 additions & 2 deletions src/adapters/superFluid/superFluidMockAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
FlowUpdatedEvent,
SuperFluidAdapterInterface,
} from './superFluidAdapterInterface';
import { generateRandomString } from '../../utils/utils';

export class SuperFluidMockAdapter implements SuperFluidAdapterInterface {
async streamPeriods() {
Expand Down Expand Up @@ -88,12 +89,22 @@ export class SuperFluidMockAdapter implements SuperFluidAdapterInterface {
return Promise.resolve(undefined);
}

getFlowByTxHash(_params: {
getFlowByTxHash(params: {
receiver: string;
sender: string;
flowRate: string;
transactionHash: string;
}): Promise<FlowUpdatedEvent | undefined> {
return Promise.resolve(undefined);
const { receiver, sender, flowRate, transactionHash } = params;
return Promise.resolve({
id: generateRandomString(20),
flowOperator: 'flowOperator',
flowRate,
transactionHash,
receiver,
sender,
token: '',
timestamp: String(new Date().getTime()),
});
}
}
Loading

0 comments on commit dd4a672

Please sign in to comment.