Skip to content

Commit

Permalink
gg22 features branch (#3670)
Browse files Browse the repository at this point in the history
* feat: add bridging widget to checkout (#3645)

---------

Co-authored-by: 0xKurt <[email protected]>

* chore: redo donation history page (#3666)


Co-authored-by: Aditya Anand M C <[email protected]>

* feat: add mint attestation to thank you page (#3662)

* added mint attestation workflow in donation history page and code ref… (#3671)

* added mint attestation workflow in donation history page and code refactoring

* workflow improvements

* refactored attestation mint modal

* chore: check transaction minting in history page (#3676)

* feat: implemented data-layer attestationService

* chore: implemented useMintingAttestations

* chore: renamed useContributionHistory to useContributionsByDonor

* refactor: useContributionsByDonor now uses useQuery

* chore: useMintingAttestations export type and add default parameter

* chore: changed MintDonationButtonProps

* chore: check if transaction is minted - propDrilling

* fix: data-layer attestation types

* chore: moved ImageWithLoading to common feature

* fix: DonationsTransactions - missing key in rendering map

* chore: AttestationService - added metadata and timestamp to query

* chore: useMintingAttestations sort response by timestamp desc

* fix: MintingAttestationIdsData - metadata is array

* chore: remove MintDonationButton from MintDonationImapactAction

* chore: implemented modal and used it to display MintingImage

* Update packages/builder/src/components/grants/rounds/LinkManager.tsx

* bump : squid widget (#3677)

* bump : squid widget

* fix

* remove unused coe

* Gg22 thank you page improvs (#3679)

* seperated checkoutStore with attestation store

* getting round names for attestation frame for thank you page

* allow minting below 20 attestation has no fee (#3678)

* add zero fee attestation

* free mint when totalAttestation < threshold

* chore: view attestation modal design (#3681)

* chore: added close icon

* chore: added responsiveness to TransactionHeader

* chore: implemented RainbowBorderButton

* chore: implemented ViewTransactionButton

* refactor: MindDonationButton renders RainbowBorderButton

* chore: implemented ViewAttestationModal

* chore: refactored Modal

* chore: use ViewAttestationModal in MintingActionButtons

* chore: added go to attestation transaction page functionality

* improved attestation frame made it more dynamic-minimal (#3682)

* improved attestation frame made it more dynamic-minimal

* make sure the frame projects images are fetched

* dynamic handling of fees and proxy attestations implementation (#3687)

* adds twitter sharable urls

* fix: update encoding and format for farcaster share URLs

* chore: make bridge button more prominent

close PAR-530

* - revese ui on thank you page mobile screen
- add border to twitter button

close PAR-531
close PAR-528

* fix title

---------

Co-authored-by: 0xKurt <[email protected]>
Co-authored-by: Huss Martinez <[email protected]>
Co-authored-by: Nick Lionis <[email protected]>
Co-authored-by: Nick Lionis <[email protected]>
Co-authored-by: veganbeef <[email protected]>
  • Loading branch information
6 people authored Oct 16, 2024
1 parent dddff65 commit 828a7d0
Show file tree
Hide file tree
Showing 202 changed files with 14,582 additions and 7,951 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default function LinkManager({ linkProps }: { linkProps: LinkProps }) {
</Button>
) : null}
{/* Applications link is todo: Andrea PR */}
{linkProps.displayType === RoundDisplayType.Current ?? null}
{/* {linkProps.displayType === RoundDisplayType.Current ?? null} */}
{linkProps.displayType === RoundDisplayType.Past ? (
<Button
disabled={!linkProps.enableStats}
Expand Down
52 changes: 39 additions & 13 deletions packages/data-layer/src/data-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
ExpandedApplicationRef,
RoundApplicationPayout,
ProjectApplicationWithRoundAndProgram,
BaseDonorValues,
DirectDonationValues,
} from "./data.types";
import {
Expand Down Expand Up @@ -61,6 +60,10 @@ import {
getDirectDonationsByProjectId,
} from "./queries";
import { mergeCanonicalAndLinkedProjects } from "./utils";
import {
AttestationService,
type MintingAttestationIdsData,
} from "./services/AttestationService";

/**
* DataLayer is a class that provides a unified interface to the various data sources.
Expand All @@ -85,6 +88,8 @@ export class DataLayer {
private collectionsSource: collections.CollectionsSource;
private gsIndexerEndpoint: string;

private attestationService: AttestationService;

constructor({
fetch,
search,
Expand Down Expand Up @@ -121,6 +126,8 @@ export class DataLayer {
? { type: "hardcoded" }
: { type: "google-sheet", url: collections.googleSheetsUrl };
this.gsIndexerEndpoint = indexer.baseUrl;

this.attestationService = new AttestationService(this.gsIndexerEndpoint);
}

/**
Expand Down Expand Up @@ -501,7 +508,7 @@ export class DataLayer {
return [];
}

const applicationToFilter = (r: ExpandedApplicationRef) => {
const applicationToFilter = (r: ExpandedApplicationRef): string => {
return `{
and: {
chainId: { equalTo: ${r.chainId} }
Expand Down Expand Up @@ -570,8 +577,8 @@ export class DataLayer {
projectId: a.project.id,
name: a.project?.metadata?.title,
websiteUrl: a.project?.metadata?.website,
logoImageCid: a.project?.metadata?.logoImg!,
bannerImageCid: a.project?.metadata?.bannerImg!,
logoImageCid: a.project?.metadata?.logoImg ?? null,
bannerImageCid: a.project?.metadata?.bannerImg ?? null,
summaryText: a.project?.metadata?.description,
payoutWalletAddress: a.metadata?.application?.recipient,
createdAtBlock: 123,
Expand Down Expand Up @@ -709,6 +716,7 @@ export class DataLayer {

const projects: Project[] = round.applications.flatMap((application) => {
if (application.project === null) {
// eslint-disable-next-line no-console
console.error(`Project not found for application ${application.id}`);
return [];
}
Expand Down Expand Up @@ -978,15 +986,33 @@ export class DataLayer {
projectId: string;
chainIds: number[];
}): Promise<DirectDonationValues[]> {
const response: { rounds: { donations: DirectDonationValues[] }[] } = await request(
this.gsIndexerEndpoint,
getDirectDonationsByProjectId,
{ projectId, chainIds }
);
const response: { rounds: { donations: DirectDonationValues[] }[] } =
await request(this.gsIndexerEndpoint, getDirectDonationsByProjectId, {
projectId,
chainIds,
});

// Flatten the donations from all rounds into a single array
const allDonations = response.rounds.flatMap(round => round.donations);
const allDonations = response.rounds.flatMap((round) => round.donations);

return allDonations;
}
}

async getMintingAttestationIdsByTransactionHash({
transactionHashes,
}: {
transactionHashes: string[];
}): Promise<MintingAttestationIdsData[]> {
return this.attestationService.getMintingAttestationIdsByTransactionHash({
transactionHashes,
});
}

async getAttestationCount({
attestationChainIds,
}: {
attestationChainIds: number[]
}): Promise<number> {
return this.attestationService.getAttestationCount({attestationChainIds});
}
}
1 change: 1 addition & 0 deletions packages/data-layer/src/data.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,7 @@ export type Contribution = {
application: {
project: {
name: string;
metadata?: ProjectMetadata;
};
};
timestamp: string;
Expand Down
3 changes: 2 additions & 1 deletion packages/data-layer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export { useDataLayer, DataLayerContext, DataLayerProvider } from "./react";
export * from "./openapi-search-client/models/index";
export * from "./data.types";
export * from "./roundApplication.types";
export * from "./utils";
export * from "./services/AttestationService/types";
export * from "./utils";
15 changes: 8 additions & 7 deletions packages/data-layer/src/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ export const getProjectsBySearchTerm = gql`
searchProjects(
searchTerm: $searchTerm
filter: {
metadata: {isNull: false }
metadata: { isNull: false }
tags: { equalTo: "allo-v2" }
not: { tags: { contains: "program" } }
chainId: {
Expand Down Expand Up @@ -609,9 +609,9 @@ export const getRoundByIdAndChainId = gql`
query getRoundByIdAndChainId($roundId: String!, $chainId: Int!) {
rounds(
first: 1
filter: {
id: { equalTo: $roundId },
chainId: { equalTo: $chainId },
filter: {
id: { equalTo: $roundId }
chainId: { equalTo: $chainId }
roundMetadata: { isNull: false }
}
) {
Expand Down Expand Up @@ -736,9 +736,9 @@ export const getRoundForExplorer = gql`
query getRoundForExplorer($roundId: String!, $chainId: Int!) {
rounds(
first: 1
filter: {
id: { equalTo: $roundId },
chainId: { equalTo: $chainId },
filter: {
id: { equalTo: $roundId }
chainId: { equalTo: $chainId }
roundMetadata: { isNull: false }
}
) {
Expand Down Expand Up @@ -806,6 +806,7 @@ export const getDonationsByDonorAddress = gql`
application {
project: canonicalProject {
name
metadata
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { gql, request } from "graphql-request";
import { MintingAttestationIdsData } from "./types";

export class AttestationService {
private gsIndexerEndpoint: string;

constructor(gsIndexerEndpoint: string) {
this.gsIndexerEndpoint = gsIndexerEndpoint;
}

async getMintingAttestationIdsByTransactionHash({
transactionHashes,
}: {
transactionHashes: string[];
}): Promise<MintingAttestationIdsData[]> {
const query = gql`
query getMintingAttestationIdsByTransactionHash(
$transactionHashes: [String!]!
) {
attestationTxns(filter: { txnHash: { in: $transactionHashes } }) {
txnHash
attestationUid
attestationChainId
attestation {
metadata
timestamp
}
}
}
`;

const response: { attestationTxns: MintingAttestationIdsData[] } =
await request(this.gsIndexerEndpoint, query, {
transactionHashes,
});

return response.attestationTxns;
}

async getAttestationCount({
attestationChainIds
}: {
attestationChainIds: number[];
}) : Promise<number> {
const query = gql`
query getAttestationCount(
$attestationChainIds: [Int!]!
) {
attestations(filter: {
chainId: { in: $attestationChainIds }
}) {
uid
}
}
`;

const response: { attestations: any[] } =
await request(this.gsIndexerEndpoint, query, {
attestationChainIds,
});

return response.attestations.length;
}
}
2 changes: 2 additions & 0 deletions packages/data-layer/src/services/AttestationService/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { AttestationService } from "./AttestationService";
export * from "./types";
11 changes: 11 additions & 0 deletions packages/data-layer/src/services/AttestationService/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export type MintingAttestationIdsData = {
txnHash: string;
attestationUid: string;
attestationChainId: string;
attestation: {
metadata: {
impactImageCid: string;
}[];
timestamp: string;
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { describe, it, expect, vi } from "vitest";
import { request } from "graphql-request";
import { AttestationService } from "../AttestationService/AttestationService";
import {
mockEmptyResponse,
mockEmptyTransactionHashes,
mockResponse,
mockTransactionHashes,
} from "./mocks";

// Mock the request function from graphql-request
vi.mock("graphql-request", async () => {
const actual = await vi.importActual("graphql-request");
return {
...(actual ?? {}),
request: vi.fn(), // Mock the request function
};
});

describe("AttestationService", () => {
const gsIndexerEndpoint = "http://mock-endpoint.com/graphql";
const service = new AttestationService(gsIndexerEndpoint);

it("should fetch and return minting attestation IDs", async () => {
// Mock the request function to return the mock response
(request as ReturnType<typeof vi.fn>).mockResolvedValue(mockResponse);

const result = await service.getMintingAttestationIdsByTransactionHash({
transactionHashes: mockTransactionHashes,
});

expect(request).toHaveBeenCalledWith(
gsIndexerEndpoint,
expect.any(String),
{
transactionHashes: mockTransactionHashes,
},
);
expect(result).toEqual(mockResponse.attestationTxns);
});

it("should fetch and return an empty array if transactionHashes is an empty array", async () => {
// Mock the request function to return the mock response
(request as ReturnType<typeof vi.fn>).mockResolvedValue(mockEmptyResponse);

const result = await service.getMintingAttestationIdsByTransactionHash({
transactionHashes: mockEmptyTransactionHashes,
});

expect(request).toHaveBeenCalledWith(
gsIndexerEndpoint,
expect.any(String),
{
transactionHashes: mockEmptyTransactionHashes,
},
);
expect(result).toEqual(mockEmptyResponse.attestationTxns);
});
});
25 changes: 25 additions & 0 deletions packages/data-layer/src/services/__tests__/mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export const mockTransactionHashes = ["hash1", "hash2"];
export const mockResponse = {
attestationTxns: [
{
txnHash: "hash1",
attestationUid: "uid1",
attestationChainId: "chain1",
},
{
txnHash: "hash1",
attestationUid: "uid2",
attestationChainId: "chain1",
},
{
txnHash: "hash2",
attestationUid: "uid3",
attestationChainId: "chain2",
},
],
};

export const mockEmptyTransactionHashes = [];
export const mockEmptyResponse = {
attestationTxns: [],
};
4 changes: 4 additions & 0 deletions packages/grant-explorer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@
]
},
"dependencies": {
"@0xsquid/widget": "^1.7.17",
"@chakra-ui/react": "^2.1.2",
"@craco/craco": "^7.1.0",
"@datadog/browser-logs": "^4.19.0",
"@datadog/browser-rum": "^4.19.0",
"@emotion/react": "^11",
"@emotion/styled": "^11",
"@ethereum-attestation-service/eas-contracts": "1.7.1",
"@ethersproject/abstract-signer": "^5.7.0",
"@ethersproject/providers": "^5.7.2",
"@headlessui/react": "^1.7.4",
Expand Down Expand Up @@ -81,6 +83,7 @@
"graphql-request": "^6.1.0",
"history": "^5.3.0",
"html-react-parser": "^3.0.7",
"html2canvas-pro": "1.5.8",
"https-browserify": "^1.0.0",
"ipfs-core": "^0.14.3",
"ipfs-core-types": "^0.14.0",
Expand All @@ -102,6 +105,7 @@
"react-router": "^6",
"react-router-dom": "6",
"react-tooltip": "^4.5.0",
"react-use": "^17.5.1",
"sleep-promise": "^9.1.0",
"stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
Expand Down
Empty file modified packages/grant-explorer/src/assets/404.svg
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified packages/grant-explorer/src/assets/404.tsx
100644 → 100755
Empty file.
Empty file modified packages/grant-explorer/src/assets/DonationHistoryBanner.tsx
100644 → 100755
Empty file.
Loading

0 comments on commit 828a7d0

Please sign in to comment.