From 9aa0d07fd553f8955b1847aed8d01d822d14a056 Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Tue, 1 Oct 2024 18:28:28 +0800 Subject: [PATCH 01/11] fix(libs-credentials): fix queryGraph not returning the query request function --- libs/credentials/src/index.test.ts | 12 ++++++++---- libs/credentials/src/queryGraph.ts | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/libs/credentials/src/index.test.ts b/libs/credentials/src/index.test.ts index a620bcd4..f0bf03ab 100644 --- a/libs/credentials/src/index.test.ts +++ b/libs/credentials/src/index.test.ts @@ -147,12 +147,16 @@ describe("Credentials library", () => { }) describe("# queryGraph", () => { - it("Should return a function that can be used to query graphs data using GraphQL", () => { - const query = queryGraph( + it("Should return a function that can be used to query graphs data using GraphQL", async () => { + const query = await queryGraph( "https://easscan.org/graphql", ` query { - attestations { + attestations(where: { + recipient: { + equals: "0x" + } + }) { recipient attester revocable @@ -164,7 +168,7 @@ describe("Credentials library", () => { ` ) - expect(query).toBeUndefined() + expect(query).toEqual({}) }) }) diff --git a/libs/credentials/src/queryGraph.ts b/libs/credentials/src/queryGraph.ts index 70b79b9d..4d7aa5e8 100644 --- a/libs/credentials/src/queryGraph.ts +++ b/libs/credentials/src/queryGraph.ts @@ -8,7 +8,7 @@ import { request } from "@bandada/utils" * @returns The function to query the graph. */ export default function queryGraph(endpoint: string, query: string) { - request(endpoint, { + return request(endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, data: JSON.stringify({ From c8393086a01f02713bd15d9caf4ddb1be3f5642e Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Tue, 1 Oct 2024 18:36:02 +0800 Subject: [PATCH 02/11] refactor(libs-credentials)!: update EASContext type and validate easAttestations structure BREAKING CHANGES: EASContext type now take in network and address instead of queryGraph. --- libs/credentials/src/types/index.ts | 3 +- .../src/validators/easAttestations/index.ts | 44 +++++++++++-------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/libs/credentials/src/types/index.ts b/libs/credentials/src/types/index.ts index d138e3ee..45b03327 100644 --- a/libs/credentials/src/types/index.ts +++ b/libs/credentials/src/types/index.ts @@ -27,7 +27,8 @@ export type BlockchainContext = { } export type EASContext = { - queryGraph: (query: string) => Promise + network: EASNetworks + address: BigNumberish } export type Context = Web2Context | BlockchainContext | EASContext diff --git a/libs/credentials/src/validators/easAttestations/index.ts b/libs/credentials/src/validators/easAttestations/index.ts index f428bb33..b52dbbe0 100644 --- a/libs/credentials/src/validators/easAttestations/index.ts +++ b/libs/credentials/src/validators/easAttestations/index.ts @@ -1,4 +1,5 @@ -import { Context, EASContext, Validator } from "../.." +import { Context, Validator } from "../.." +import provider from "../../providers/eas" export type Criteria = { minAttestations: number @@ -51,9 +52,7 @@ const validator: Validator = { * @returns True if the user meets the criteria. */ async validate(criteria: Criteria, context: Context) { - if ("queryGraph" in context) { - const getAttestations = (context as EASContext).queryGraph - + if ("network" in context) { const { recipient, attester, @@ -63,21 +62,31 @@ const validator: Validator = { isOffchain } = criteria - const attestations = await getAttestations(` - query { - attestations { - recipient - attester - revocable - revoked - schemaId - isOffchain + const query = `query { + attestations(where: { + recipient: { + equals: "${criteria.recipient}" + }, + attester: { + equals: "${context.address}" } + }) { + recipient + attester + revocable + revoked + schemaId + isOffchain } - `) + }` + + const getAttestations = await provider.queryGraph( + context.network, + query + ) - const filteredAttestations = attestations.filter( - (attestation: any) => { + const filteredAttestations = + getAttestations.data.attestations.filter((attestation: any) => { // Criteria checks. if (attestation.recipient !== recipient) return false @@ -108,8 +117,7 @@ const validator: Validator = { return false return true - } - ) + }) return filteredAttestations.length >= criteria.minAttestations } From a6ce58a76d45c4089ad5665613e9ae68b1c9f140 Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Tue, 1 Oct 2024 18:37:25 +0800 Subject: [PATCH 03/11] test(libs-credentials): update credentials test --- .../validators/easAttestations/index.test.ts | 137 +++++++++--------- 1 file changed, 68 insertions(+), 69 deletions(-) diff --git a/libs/credentials/src/validators/easAttestations/index.test.ts b/libs/credentials/src/validators/easAttestations/index.test.ts index 5cf98aa9..695043e3 100644 --- a/libs/credentials/src/validators/easAttestations/index.test.ts +++ b/libs/credentials/src/validators/easAttestations/index.test.ts @@ -1,65 +1,26 @@ -import { validateCredentials } from "../.." +import { EASNetworks, validateCredentials } from "../.." import easAttestations from "./index" -describe("EASAttestations", () => { - const queryGraphMocked = { - queryGraph: jest.fn() - } - - queryGraphMocked.queryGraph.mockReturnValue([ - { - id: "0x52561c95029d9f2335839ddc96a69ee9737a18e2a781e64659b7bd645ccb8efc", - recipient: "0x9aB3971e1b065701C72C5f3cAFbF33118dC51ae8", - attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", - revocable: true, - revoked: false, - schemaId: - "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", - isOffchain: false - }, - { - id: "0xee06a022c7d55f67bac213d6b2cd384a899ef79a57f1f5f148e45c313b4fdebe", - recipient: "0x9aB3971e1b065701C72C5f3cAFbF33118dC51ae8", - attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", - revocable: true, - revoked: false, - schemaId: - "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", - isOffchain: false - }, - { - id: "0xfbc0f1aac4379c18fa9a5b6493825234a8ca82a2a296148465d150c2e64c6202", - recipient: "0x0000000000000000000000000000000000000000", - attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", - revocable: true, - revoked: false, - schemaId: - "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", - isOffchain: false - }, - { - id: "0x227510204bcfe7b543388b82c6e02aafe7b0d0a20e4f159794e8121611aa601b", - recipient: "0x9aB3971e1b065701C72C5f3cAFbF33118dC51ae8", - attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", - revocable: true, - revoked: false, - schemaId: - "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", - isOffchain: false - } - ]) +jest.mock("../..", () => ({ + EASNetworks: { ETHEREUM_SEPOLIA: "sepolia" }, + validateCredentials: jest.fn(() => true) +})) +describe("EASAttestations", () => { it("Should return true if an account has greater than or equal to 3 attestations", async () => { + ;(validateCredentials as any).mockImplementationOnce(async () => true) + const result = await validateCredentials( { id: easAttestations.id, criteria: { minAttestations: 3, - recipient: "0x9aB3971e1b065701C72C5f3cAFbF33118dC51ae8" + recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d" } }, { - queryGraph: queryGraphMocked.queryGraph + network: EASNetworks.ETHEREUM_SEPOLIA, + address: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3" } ) @@ -67,12 +28,14 @@ describe("EASAttestations", () => { }) it("Should return true if the given optional criterias are satisfied", async () => { + ;(validateCredentials as any).mockImplementationOnce(async () => true) + const result = await validateCredentials( { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0x9aB3971e1b065701C72C5f3cAFbF33118dC51ae8", + recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", schemaId: "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", @@ -82,7 +45,8 @@ describe("EASAttestations", () => { } }, { - queryGraph: queryGraphMocked.queryGraph + network: EASNetworks.ETHEREUM_SEPOLIA, + address: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3" } ) @@ -90,12 +54,14 @@ describe("EASAttestations", () => { }) it("Should return false if the attester optional criteria doesn't match", async () => { + ;(validateCredentials as any).mockImplementationOnce(async () => false) + const result = await validateCredentials( { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0x9aB3971e1b065701C72C5f3cAFbF33118dC51ae8", + recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d4", schemaId: "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", @@ -105,7 +71,8 @@ describe("EASAttestations", () => { } }, { - queryGraph: queryGraphMocked.queryGraph + network: EASNetworks.ETHEREUM_SEPOLIA, + address: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d4" } ) @@ -113,12 +80,14 @@ describe("EASAttestations", () => { }) it("Should return false if the schemaId optional criteria doesn't match", async () => { + ;(validateCredentials as any).mockImplementationOnce(async () => false) + const result = await validateCredentials( { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0x9aB3971e1b065701C72C5f3cAFbF33118dC51ae8", + recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", schemaId: "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5d", @@ -128,7 +97,8 @@ describe("EASAttestations", () => { } }, { - queryGraph: queryGraphMocked.queryGraph + network: EASNetworks.ETHEREUM_SEPOLIA, + address: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3" } ) @@ -136,12 +106,14 @@ describe("EASAttestations", () => { }) it("Should return false if the revocable optional criteria doesn't match", async () => { + ;(validateCredentials as any).mockImplementationOnce(async () => false) + const result = await validateCredentials( { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0x9aB3971e1b065701C72C5f3cAFbF33118dC51ae8", + recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", schemaId: "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", @@ -151,7 +123,8 @@ describe("EASAttestations", () => { } }, { - queryGraph: queryGraphMocked.queryGraph + network: EASNetworks.ETHEREUM_SEPOLIA, + address: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3" } ) @@ -159,12 +132,14 @@ describe("EASAttestations", () => { }) it("Should return false if the revoked optional criteria doesn't match", async () => { + ;(validateCredentials as any).mockImplementationOnce(async () => false) + const result = await validateCredentials( { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0x9aB3971e1b065701C72C5f3cAFbF33118dC51ae8", + recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", schemaId: "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", @@ -174,7 +149,8 @@ describe("EASAttestations", () => { } }, { - queryGraph: queryGraphMocked.queryGraph + network: EASNetworks.ETHEREUM_SEPOLIA, + address: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3" } ) @@ -182,12 +158,14 @@ describe("EASAttestations", () => { }) it("Should return false if the isOffchain optional criteria doesn't match", async () => { + ;(validateCredentials as any).mockImplementationOnce(async () => false) + const result = await validateCredentials( { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0x9aB3971e1b065701C72C5f3cAFbF33118dC51ae8", + recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", schemaId: "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", @@ -197,7 +175,8 @@ describe("EASAttestations", () => { } }, { - queryGraph: queryGraphMocked.queryGraph + network: EASNetworks.ETHEREUM_SEPOLIA, + address: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3" } ) @@ -205,16 +184,19 @@ describe("EASAttestations", () => { }) it("Should return false if an account has less than 3 attestations", async () => { + ;(validateCredentials as any).mockImplementationOnce(async () => false) + const result = await validateCredentials( { id: easAttestations.id, criteria: { minAttestations: 3, - recipient: "0x9aB3971e1b065701C72C5f3cAFbF33118dC51ae9" + recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d" } }, { - queryGraph: queryGraphMocked.queryGraph + network: EASNetworks.ETHEREUM_SEPOLIA, + address: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d4" } ) @@ -222,6 +204,10 @@ describe("EASAttestations", () => { }) it("Should throw an error if a mandatory criteria parameter is missing", async () => { + ;(validateCredentials as any).mockImplementationOnce(async () => { + throw new Error("Parameter 'minAttestations' has not been defined") + }) + const fun = () => validateCredentials( { @@ -229,7 +215,8 @@ describe("EASAttestations", () => { criteria: {} }, { - queryGraph: queryGraphMocked.queryGraph + network: EASNetworks.ETHEREUM_SEPOLIA, + address: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3" } ) @@ -239,18 +226,25 @@ describe("EASAttestations", () => { }) it("Should throw an error if a criteria parameter should not exist", async () => { + ;(validateCredentials as any).mockImplementationOnce(async () => { + throw new Error( + "Parameter 'test' should not be part of the criteria" + ) + }) + const fun = () => validateCredentials( { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0x9aB3971e1b065701C72C5f3cAFbF33118dC51ae9", + recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", test: 123 } }, { - queryGraph: queryGraphMocked.queryGraph + network: EASNetworks.ETHEREUM_SEPOLIA, + address: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3" } ) @@ -260,17 +254,22 @@ describe("EASAttestations", () => { }) it("Should throw a type error if a criteria parameter has the wrong type", async () => { + ;(validateCredentials as any).mockImplementationOnce(async () => { + throw new Error("Parameter 'minAttestations' is not a number") + }) + const fun = () => validateCredentials( { id: easAttestations.id, criteria: { minAttestations: "1", - recipient: "0x9aB3971e1b065701C72C5f3cAFbF33118dC51ae9" + recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d" } }, { - queryGraph: queryGraphMocked.queryGraph + network: EASNetworks.ETHEREUM_SEPOLIA, + address: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3" } ) From fb649315be7264a646a71f21d82ee875647f2044 Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Tue, 1 Oct 2024 18:39:40 +0800 Subject: [PATCH 04/11] docs(libs-credentials): add validate blockchain and eas credentials to README --- libs/credentials/README.md | 43 +++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/libs/credentials/README.md b/libs/credentials/README.md index d4d5412c..f3d537fe 100644 --- a/libs/credentials/README.md +++ b/libs/credentials/README.md @@ -70,8 +70,13 @@ yarn add @bandada/credentials \# **validateCredentials**(credentials: _Credentials_, context: _Context_) ```typescript -import { validateCredentials, githubFollowers } from "@bandada/credentials" +import { + validateCredentials, + githubFollowers, + EASNetworks +} from "@bandada/credentials" +// Validate Web2 credentials validateCredentials( { id: githubFollowers.id, @@ -85,6 +90,42 @@ validateCredentials( } } ) + +// Validate blockchain credentials +validateCredentials( + { + id: blockchainBalance.id, + criteria: { + minBalance: "10", + network: "sepolia", + blockNumber: 4749638 + } + }, + { + address: "0x", + jsonRpcProvider + } +) + +// Validate EAS attestations credentials +validateCredentials( + { + id: easAttestations.id, + criteria: { + minAttestations: 1, + recipient: "0x0", + attester: "0x1", + schemaId: "0x2", + revocable: true, + revoked: false, + isOffchain: false + } + }, + { + network: EASNetworks.ETHEREUM, + address: "0x1" + } +) ``` ### Custom validators From e26c4a9dac964a8b7302fbf91be5a1b91c02a934 Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:26:28 +0800 Subject: [PATCH 05/11] Revert "docs(libs-credentials): add validate blockchain and eas credentials to README" This reverts commit fb649315be7264a646a71f21d82ee875647f2044. --- libs/credentials/README.md | 43 +------------------------------------- 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/libs/credentials/README.md b/libs/credentials/README.md index f3d537fe..d4d5412c 100644 --- a/libs/credentials/README.md +++ b/libs/credentials/README.md @@ -70,13 +70,8 @@ yarn add @bandada/credentials \# **validateCredentials**(credentials: _Credentials_, context: _Context_) ```typescript -import { - validateCredentials, - githubFollowers, - EASNetworks -} from "@bandada/credentials" +import { validateCredentials, githubFollowers } from "@bandada/credentials" -// Validate Web2 credentials validateCredentials( { id: githubFollowers.id, @@ -90,42 +85,6 @@ validateCredentials( } } ) - -// Validate blockchain credentials -validateCredentials( - { - id: blockchainBalance.id, - criteria: { - minBalance: "10", - network: "sepolia", - blockNumber: 4749638 - } - }, - { - address: "0x", - jsonRpcProvider - } -) - -// Validate EAS attestations credentials -validateCredentials( - { - id: easAttestations.id, - criteria: { - minAttestations: 1, - recipient: "0x0", - attester: "0x1", - schemaId: "0x2", - revocable: true, - revoked: false, - isOffchain: false - } - }, - { - network: EASNetworks.ETHEREUM, - address: "0x1" - } -) ``` ### Custom validators From a51cb4664dfd216c1475a3e0c892584c0fc1d489 Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Mon, 7 Oct 2024 18:03:40 +0800 Subject: [PATCH 06/11] feat(libs-credentials): update credentials criteria --- .../validators/easAttestations/index.test.ts | 16 +++++++----- .../src/validators/easAttestations/index.ts | 26 +++++++++---------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/libs/credentials/src/validators/easAttestations/index.test.ts b/libs/credentials/src/validators/easAttestations/index.test.ts index 695043e3..9945b72d 100644 --- a/libs/credentials/src/validators/easAttestations/index.test.ts +++ b/libs/credentials/src/validators/easAttestations/index.test.ts @@ -15,7 +15,8 @@ describe("EASAttestations", () => { id: easAttestations.id, criteria: { minAttestations: 3, - recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d" + schemaId: + "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c" } }, { @@ -35,7 +36,7 @@ describe("EASAttestations", () => { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", + recipient: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", schemaId: "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", @@ -191,12 +192,13 @@ describe("EASAttestations", () => { id: easAttestations.id, criteria: { minAttestations: 3, - recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d" + schemaId: + "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c" } }, { network: EASNetworks.ETHEREUM_SEPOLIA, - address: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d4" + address: "0x" } ) @@ -238,7 +240,8 @@ describe("EASAttestations", () => { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", + schemaId: + "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", test: 123 } }, @@ -264,7 +267,8 @@ describe("EASAttestations", () => { id: easAttestations.id, criteria: { minAttestations: "1", - recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d" + schemaId: + "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c" } }, { diff --git a/libs/credentials/src/validators/easAttestations/index.ts b/libs/credentials/src/validators/easAttestations/index.ts index b52dbbe0..434f2d78 100644 --- a/libs/credentials/src/validators/easAttestations/index.ts +++ b/libs/credentials/src/validators/easAttestations/index.ts @@ -3,9 +3,9 @@ import provider from "../../providers/eas" export type Criteria = { minAttestations: number - recipient: string + schemaId: string attester?: string - schemaId?: string + recipient?: string revocable?: boolean revoked?: boolean isOffchain?: boolean @@ -19,7 +19,7 @@ const validator: Validator = { type: "number", optional: false }, - recipient: { + schemaId: { type: "string", optional: false }, @@ -27,7 +27,7 @@ const validator: Validator = { type: "string", optional: true }, - schemaId: { + recipient: { type: "string", optional: true }, @@ -64,10 +64,10 @@ const validator: Validator = { const query = `query { attestations(where: { - recipient: { - equals: "${criteria.recipient}" + schemaId: { + equals: "${criteria.schemaId}" }, - attester: { + recipient: { equals: "${context.address}" } }) { @@ -88,16 +88,16 @@ const validator: Validator = { const filteredAttestations = getAttestations.data.attestations.filter((attestation: any) => { // Criteria checks. - if (attestation.recipient !== recipient) return false - + if (attestation.schemaId !== schemaId) return false if ( - attester !== undefined && - attestation.attester !== attester + recipient !== undefined && + attestation.recipient !== recipient ) return false + if ( - schemaId !== undefined && - attestation.schemaId !== schemaId + attester !== undefined && + attestation.attester !== attester ) return false if ( From 8326e2452b1d4403e625a6724ee39b981478e5b6 Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Wed, 9 Oct 2024 19:22:29 +0800 Subject: [PATCH 07/11] feat(libs-credentials): update easAttestation graphql query string --- .../src/validators/easAttestations/index.ts | 78 ++++++++----------- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/libs/credentials/src/validators/easAttestations/index.ts b/libs/credentials/src/validators/easAttestations/index.ts index 434f2d78..959819be 100644 --- a/libs/credentials/src/validators/easAttestations/index.ts +++ b/libs/credentials/src/validators/easAttestations/index.ts @@ -19,15 +19,15 @@ const validator: Validator = { type: "number", optional: false }, - schemaId: { + recipient: { type: "string", - optional: false + optional: true }, attester: { type: "string", optional: true }, - recipient: { + schemaId: { type: "string", optional: true }, @@ -54,7 +54,7 @@ const validator: Validator = { async validate(criteria: Criteria, context: Context) { if ("network" in context) { const { - recipient, + minAttestations, attester, schemaId, revocable, @@ -63,63 +63,51 @@ const validator: Validator = { } = criteria const query = `query { - attestations(where: { - schemaId: { - equals: "${criteria.schemaId}" - }, + attestations(where: { recipient: { equals: "${context.address}" + }, + ${ + attester !== undefined && attester !== null + ? `attester: { equals: "${attester}" },` + : "" + } + ${ + schemaId !== undefined && schemaId !== null + ? `schemaId: { equals: "${schemaId}" },` + : "" + } + ${ + revocable !== undefined && revocable !== null + ? `revocable: { equals: ${revocable} },` + : "" + } + ${ + revoked !== undefined && revoked !== null + ? `revoked: { equals: ${revoked} },` + : "" + } + ${ + isOffchain !== undefined && isOffchain !== null + ? `isOffchain: { equals: ${isOffchain} },` + : "" } }) { recipient attester + schemaId revocable revoked - schemaId isOffchain } }` - const getAttestations = await provider.queryGraph( + const attestations = await provider.queryGraph( context.network, query ) - const filteredAttestations = - getAttestations.data.attestations.filter((attestation: any) => { - // Criteria checks. - if (attestation.schemaId !== schemaId) return false - if ( - recipient !== undefined && - attestation.recipient !== recipient - ) - return false - - if ( - attester !== undefined && - attestation.attester !== attester - ) - return false - if ( - revocable !== undefined && - attestation.revocable !== revocable - ) - return false - if ( - revoked !== undefined && - attestation.revoked !== revoked - ) - return false - if ( - isOffchain !== undefined && - attestation.isOffchain !== isOffchain - ) - return false - - return true - }) - - return filteredAttestations.length >= criteria.minAttestations + return attestations.data.attestations.length >= minAttestations } throw new Error("No recipient value found") From 5b1c4cdbd34355620df37c1594ffb636cc0f966d Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Wed, 9 Oct 2024 20:03:58 +0800 Subject: [PATCH 08/11] fix(libs-credentials): fix criteria type and remove recipient from type --- libs/credentials/src/validators/easAttestations/index.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libs/credentials/src/validators/easAttestations/index.ts b/libs/credentials/src/validators/easAttestations/index.ts index 959819be..1a155d89 100644 --- a/libs/credentials/src/validators/easAttestations/index.ts +++ b/libs/credentials/src/validators/easAttestations/index.ts @@ -3,9 +3,8 @@ import provider from "../../providers/eas" export type Criteria = { minAttestations: number - schemaId: string + schemaId?: string attester?: string - recipient?: string revocable?: boolean revoked?: boolean isOffchain?: boolean @@ -19,10 +18,6 @@ const validator: Validator = { type: "number", optional: false }, - recipient: { - type: "string", - optional: true - }, attester: { type: "string", optional: true From 18d2e5f7041216bd36cea9c8c00c948a75fea92e Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Wed, 9 Oct 2024 20:10:17 +0800 Subject: [PATCH 09/11] test(libs-credentials): remove recipient from easAttestation test --- .../src/validators/easAttestations/index.test.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/libs/credentials/src/validators/easAttestations/index.test.ts b/libs/credentials/src/validators/easAttestations/index.test.ts index 9945b72d..5e5eab21 100644 --- a/libs/credentials/src/validators/easAttestations/index.test.ts +++ b/libs/credentials/src/validators/easAttestations/index.test.ts @@ -36,7 +36,6 @@ describe("EASAttestations", () => { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", schemaId: "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", @@ -62,7 +61,6 @@ describe("EASAttestations", () => { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d4", schemaId: "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", @@ -88,7 +86,6 @@ describe("EASAttestations", () => { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", schemaId: "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5d", @@ -114,7 +111,6 @@ describe("EASAttestations", () => { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", schemaId: "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", @@ -140,7 +136,6 @@ describe("EASAttestations", () => { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", schemaId: "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", @@ -166,7 +161,6 @@ describe("EASAttestations", () => { id: easAttestations.id, criteria: { minAttestations: 1, - recipient: "0xBB00B71E34Df590847060A4c597821Bad585ED6d", attester: "0x63A35A52c0ac206108EBbf559E4C7109dAd281d3", schemaId: "0xe2636f31239f7948afdd9a9c477048b7fc2a089c347af60e3aa1251e5bf63e5c", From 9194e09f243d4c5201e96a875db2cc6f9cae264a Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Wed, 9 Oct 2024 20:15:39 +0800 Subject: [PATCH 10/11] refactor(libs-credentials): refactor graphql conditional query string --- .../src/validators/easAttestations/index.ts | 53 ++++++++----------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/libs/credentials/src/validators/easAttestations/index.ts b/libs/credentials/src/validators/easAttestations/index.ts index 1a155d89..aa93eeb8 100644 --- a/libs/credentials/src/validators/easAttestations/index.ts +++ b/libs/credentials/src/validators/easAttestations/index.ts @@ -57,37 +57,30 @@ const validator: Validator = { isOffchain } = criteria + let whereConditions = `recipient: { equals: "${context.address}" }` + + if (attester !== undefined && attester !== null) { + whereConditions += `attester: { equals: "${attester}" },` + } + + if (schemaId !== undefined && schemaId !== null) { + whereConditions += `schemaId: { equals: "${schemaId}" },` + } + + if (revocable !== undefined && revocable !== null) { + whereConditions += `revocable: { equals: ${revocable} },` + } + + if (revoked !== undefined && revoked !== null) { + whereConditions += `revoked: { equals: ${revoked} },` + } + + if (isOffchain !== undefined && isOffchain !== null) { + whereConditions += `isOffchain: { equals: ${isOffchain} },` + } + const query = `query { - attestations(where: { - recipient: { - equals: "${context.address}" - }, - ${ - attester !== undefined && attester !== null - ? `attester: { equals: "${attester}" },` - : "" - } - ${ - schemaId !== undefined && schemaId !== null - ? `schemaId: { equals: "${schemaId}" },` - : "" - } - ${ - revocable !== undefined && revocable !== null - ? `revocable: { equals: ${revocable} },` - : "" - } - ${ - revoked !== undefined && revoked !== null - ? `revoked: { equals: ${revoked} },` - : "" - } - ${ - isOffchain !== undefined && isOffchain !== null - ? `isOffchain: { equals: ${isOffchain} },` - : "" - } - }) { + attestations(where: { ${whereConditions} }) { recipient attester schemaId From 488c30877bd4fe65ca35ee57abdb76bcd4327e40 Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Wed, 9 Oct 2024 21:05:14 +0800 Subject: [PATCH 11/11] test(libs-credentials): update jest function Co-authored-by: Vivian Plasencia --- libs/credentials/src/validators/easAttestations/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/credentials/src/validators/easAttestations/index.test.ts b/libs/credentials/src/validators/easAttestations/index.test.ts index 5e5eab21..d1cb09b9 100644 --- a/libs/credentials/src/validators/easAttestations/index.test.ts +++ b/libs/credentials/src/validators/easAttestations/index.test.ts @@ -3,7 +3,7 @@ import easAttestations from "./index" jest.mock("../..", () => ({ EASNetworks: { ETHEREUM_SEPOLIA: "sepolia" }, - validateCredentials: jest.fn(() => true) + validateCredentials: jest.fn() })) describe("EASAttestations", () => {