From 2df46e1952675d1946564552a37bb6065db83741 Mon Sep 17 00:00:00 2001 From: Alain Nicolas Date: Wed, 11 Oct 2023 00:07:42 +0200 Subject: [PATCH] feat: As a user, I want to create an attestation using the SDK --- .github/workflows/sdk.yml | 2 +- pnpm-lock.yaml | 8 +- sdk/.env.example | 1 + sdk/examples/portal/portalExamples.ts | 32 +- sdk/package.json | 17 +- sdk/src/VeraxSdk.ts | 44 +- sdk/src/abi/DefaultPortal.ts | 403 ++++++++++++++++++ sdk/src/dataMapper/BaseDataMapper.ts | 25 +- sdk/src/dataMapper/PortalDataMapper.ts | 45 +- sdk/src/types/index.d.ts | 25 +- sdk/src/utils/constants.ts | 5 + .../dataMapper/AttestationDataMapper.test.ts | 21 +- 12 files changed, 584 insertions(+), 44 deletions(-) create mode 100644 sdk/.env.example create mode 100644 sdk/src/abi/DefaultPortal.ts diff --git a/.github/workflows/sdk.yml b/.github/workflows/sdk.yml index 9e1e1172..784c3d71 100644 --- a/.github/workflows/sdk.yml +++ b/.github/workflows/sdk.yml @@ -53,7 +53,7 @@ jobs: run: pnpm install --frozen-lockfile - name: Run the unit tests - run: pnpm run test + run: pnpm run test:ci - name: Add test summary run: | diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3e500158..09856b34 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -69,6 +69,9 @@ importers: '@apollo/client': specifier: ^3.8.4 version: 3.8.4(graphql@16.8.1) + dotenv: + specifier: ^16.3.1 + version: 16.3.1 graphql: specifier: ^16.8.1 version: 16.8.1 @@ -4187,7 +4190,6 @@ packages: /dotenv@16.3.1: resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} engines: {node: '>=12'} - dev: true /ecc-jsbn@0.1.2: resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} @@ -5154,7 +5156,7 @@ packages: dependencies: inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 8.0.4 once: 1.4.0 path-is-absolute: 1.0.1 dev: true @@ -5165,7 +5167,7 @@ packages: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 8.0.4 once: 1.4.0 path-is-absolute: 1.0.1 dev: true diff --git a/sdk/.env.example b/sdk/.env.example new file mode 100644 index 00000000..40104188 --- /dev/null +++ b/sdk/.env.example @@ -0,0 +1 @@ +PRIVATE_KEY=0x0000000000000000000000000000000000000000000000000000000000000001 diff --git a/sdk/examples/portal/portalExamples.ts b/sdk/examples/portal/portalExamples.ts index a0067f39..ec0cc9db 100644 --- a/sdk/examples/portal/portalExamples.ts +++ b/sdk/examples/portal/portalExamples.ts @@ -2,9 +2,11 @@ import VeraxSdk from "../../src/VeraxSdk"; export default class PortalExamples { private veraxSdk: VeraxSdk; + constructor(_veraxSdk: VeraxSdk) { this.veraxSdk = _veraxSdk; } + async run(methodName: string = "") { if (methodName.toLowerCase() == "findOneById".toLowerCase() || methodName == "") console.log(await this.veraxSdk.portal.findOneById("0x1495341ab1019798dd08976f4a3e5ab0e095510b")); @@ -12,7 +14,35 @@ export default class PortalExamples { if (methodName.toLowerCase() == "findBy".toLowerCase() || methodName == "") console.log(await this.veraxSdk.portal.findBy({ ownerName: "Clique" })); - if (methodName.toLowerCase() == "attest" || methodName == "") console.log(await this.veraxSdk.portal.attest()); + if (methodName.toLowerCase() == "simulateAttest".toLowerCase() || methodName == "") { + console.log( + await this.veraxSdk.portal.simulateAttest( + "0xeea25bc2ec56cae601df33b8fc676673285e12cc", + { + schemaId: "0x9ba590dd7fbd5bd1a7d06cdcb4744e20a49b3520560575cd63de17734a408738", + expirationDate: 1693583329, + subject: "0x828c9f04D1a07E3b0aBE12A9F8238a3Ff7E57b47", + attestationData: [{ isBuidler: true }], + }, + [], + ), + ); + } + + if (methodName.toLowerCase() == "attest" || methodName == "") { + console.log( + await this.veraxSdk.portal.attest( + "0xeea25bc2ec56cae601df33b8fc676673285e12cc", + { + schemaId: "0x9ba590dd7fbd5bd1a7d06cdcb4744e20a49b3520560575cd63de17734a408738", + expirationDate: 1693583329, + subject: "0x828c9f04D1a07E3b0aBE12A9F8238a3Ff7E57b47", + attestationData: [{ isBuidler: true }], + }, + [], + ), + ); + } if (methodName.toLowerCase() == "bulkAttest".toLowerCase() || methodName == "") console.log(await this.veraxSdk.portal.bulkAttest()); diff --git a/sdk/package.json b/sdk/package.json index e7b130ab..f450cb54 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -20,25 +20,12 @@ "module": "ts-node examples/module/index.ts", "portal": "ts-node examples/portal/index.ts", "schema": "ts-node examples/schema/index.ts", - "attestation:all": "ts-node examples/attestation/findBy.ts", - "attestation:one": "ts-node examples/attestation/findOneById.ts", - "module:all": "ts-node examples/module/findBy.ts", - "module:one": "ts-node examples/module/findOneById.ts", - "portal:all": "ts-node examples/portal/findBy.ts", - "portal:one": "ts-node examples/portal/findOneById.ts", - "schema:all": "ts-node examples/schema/findBy.ts", - "schema:one": "ts-node examples/schema/findOneById.ts", "test": "jest", - "utils:attestation:counter": "ts-node examples/utils/getAttestationIdCounter.ts", - "utils:attestation:version": "ts-node examples/utils/getVersionNumber.ts", - "utils:decode": "ts-node examples/utils/decode.ts", - "utils:encode": "ts-node examples/utils/encode.ts", - "utils:module:counter": "ts-node examples/utils/getModulesNumber.ts", - "utils:portal:counter": "ts-node examples/utils/getPortalsCount.ts", - "utils:schema:counter": "ts-node examples/utils/getSchemasNumber.ts" + "test:ci": "cp .env.example .env && jest" }, "dependencies": { "@apollo/client": "^3.8.4", + "dotenv": "^16.3.1", "graphql": "^16.8.1", "viem": "^1.14.0" }, diff --git a/sdk/src/VeraxSdk.ts b/sdk/src/VeraxSdk.ts index c7397ba6..d937bea1 100644 --- a/sdk/src/VeraxSdk.ts +++ b/sdk/src/VeraxSdk.ts @@ -3,14 +3,20 @@ import AttestationDataMapper from "./dataMapper/AttestationDataMapper"; import SchemaDataMapper from "./dataMapper/SchemaDataMapper"; import ModuleDataMapper from "./dataMapper/ModuleDataMapper"; import PortalDataMapper from "./dataMapper/PortalDataMapper"; -import { createPublicClient, http, PublicClient } from "viem"; +import { createPublicClient, createWalletClient, custom, Hex, http, PublicClient, WalletClient } from "viem"; import { ApolloClient, InMemoryCache } from "@apollo/client/core"; -import { Conf } from "./types"; import UtilsDataMapper from "./dataMapper/UtilsDataMapper"; +import { privateKeyToAccount } from "viem/accounts"; +import dotenv from "dotenv"; +import { Conf } from "./types"; +import { SDKMode } from "./utils/constants"; + +dotenv.config({ path: "./.env" }); export default class VeraxSdk { static DEFAULT_LINEA_MAINNET: Conf = { chain: linea, + mode: SDKMode.BACKEND, subgraphUrl: "https://graph-query.linea.build/subgraphs/name/Consensys/linea-attestation-registry", portalRegistryAddress: "0xd5d61e4ECDf6d46A63BfdC262af92544DFc19083", moduleRegistryAddress: "0xf851513A732996F22542226341748f3C9978438f", @@ -18,8 +24,14 @@ export default class VeraxSdk { attestationRegistryAddress: "0x3de3893aa4Cdea029e84e75223a152FD08315138", }; + static DEFAULT_LINEA_MAINNET_FRONTEND: Conf = { + ...VeraxSdk.DEFAULT_LINEA_MAINNET, + mode: SDKMode.BACKEND, + }; + static DEFAULT_LINEA_TESTNET: Conf = { chain: lineaTestnet, + mode: SDKMode.BACKEND, subgraphUrl: "https://graph-query.goerli.linea.build/subgraphs/name/Consensys/linea-attestation-registry", portalRegistryAddress: "0x506f88a5Ca8D5F001f2909b029738A40042e42a6", moduleRegistryAddress: "0x1a20b2CFA134686306436D2c9f778D7eC6c43A43", @@ -27,7 +39,13 @@ export default class VeraxSdk { attestationRegistryAddress: "0xC765F28096F6121C2F2b82D35A4346280164428b", }; + static DEFAULT_LINEA_TESTNET_FRONTEND: Conf = { + ...VeraxSdk.DEFAULT_LINEA_TESTNET, + mode: SDKMode.BACKEND, + }; + private readonly web3Client: PublicClient; + private readonly walletClient: WalletClient; private readonly apolloClient: ApolloClient; public attestation: AttestationDataMapper; @@ -42,15 +60,27 @@ export default class VeraxSdk { transport: http(), }); + this.walletClient = + conf.mode === SDKMode.BACKEND + ? createWalletClient({ + chain: conf.chain, + account: privateKeyToAccount(process.env.PRIVATE_KEY as Hex), + transport: http(), + }) + : createWalletClient({ + chain: conf.chain, + transport: custom(window.ethereum), + }); + this.apolloClient = new ApolloClient({ uri: conf.subgraphUrl, cache: new InMemoryCache(), }); - this.attestation = new AttestationDataMapper(conf, this.web3Client, this.apolloClient); - this.schema = new SchemaDataMapper(conf, this.web3Client, this.apolloClient); - this.module = new ModuleDataMapper(conf, this.web3Client, this.apolloClient); - this.portal = new PortalDataMapper(conf, this.web3Client, this.apolloClient); - this.utils = new UtilsDataMapper(conf, this.web3Client, this.apolloClient); + this.attestation = new AttestationDataMapper(conf, this.web3Client, this.walletClient, this.apolloClient, this); + this.schema = new SchemaDataMapper(conf, this.web3Client, this.walletClient, this.apolloClient, this); + this.module = new ModuleDataMapper(conf, this.web3Client, this.walletClient, this.apolloClient, this); + this.portal = new PortalDataMapper(conf, this.web3Client, this.walletClient, this.apolloClient, this); + this.utils = new UtilsDataMapper(conf, this.web3Client, this.walletClient, this.apolloClient, this); } } diff --git a/sdk/src/abi/DefaultPortal.ts b/sdk/src/abi/DefaultPortal.ts new file mode 100644 index 00000000..04fe0715 --- /dev/null +++ b/sdk/src/abi/DefaultPortal.ts @@ -0,0 +1,403 @@ +export const abiDefaultPortal = [ + { + inputs: [ + { + internalType: "address[]", + name: "modules", + type: "address[]", + }, + { + internalType: "address", + name: "router", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [], + name: "OnlyPortalOwner", + type: "error", + }, + { + inputs: [], + name: "AlreadyRevoked", + type: "error", + }, + { + inputs: [], + name: "ArrayLengthMismatch", + type: "error", + }, + { + inputs: [], + name: "AttestationDataFieldEmpty", + type: "error", + }, + { + inputs: [], + name: "AttestationNotAttested", + type: "error", + }, + { + inputs: [], + name: "AttestationNotRevocable", + type: "error", + }, + { + inputs: [], + name: "AttestationSubjectFieldEmpty", + type: "error", + }, + { + inputs: [], + name: "OnlyAttestingPortal", + type: "error", + }, + { + inputs: [], + name: "OnlyPortal", + type: "error", + }, + { + inputs: [], + name: "RouterInvalid", + type: "error", + }, + { + inputs: [], + name: "SchemaNotRegistered", + type: "error", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes32", + name: "schemaId", + type: "bytes32", + }, + { + internalType: "uint64", + name: "expirationDate", + type: "uint64", + }, + { + internalType: "bytes", + name: "subject", + type: "bytes", + }, + { + internalType: "bytes", + name: "attestationData", + type: "bytes", + }, + ], + internalType: "struct AttestationPayload", + name: "attestationPayload", + type: "tuple", + }, + { + internalType: "bytes[]", + name: "validationPayloads", + type: "bytes[]", + }, + ], + name: "attest", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [], + name: "attestationRegistry", + outputs: [ + { + internalType: "contract AttestationRegistry", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes32", + name: "schemaId", + type: "bytes32", + }, + { + internalType: "uint64", + name: "expirationDate", + type: "uint64", + }, + { + internalType: "bytes", + name: "subject", + type: "bytes", + }, + { + internalType: "bytes", + name: "attestationData", + type: "bytes", + }, + ], + internalType: "struct AttestationPayload[]", + name: "attestationsPayloads", + type: "tuple[]", + }, + { + internalType: "bytes[][]", + name: "validationPayloads", + type: "bytes[][]", + }, + ], + name: "bulkAttest", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32[]", + name: "attestationIds", + type: "bytes32[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "schemaId", + type: "bytes32", + }, + { + internalType: "uint64", + name: "expirationDate", + type: "uint64", + }, + { + internalType: "bytes", + name: "subject", + type: "bytes", + }, + { + internalType: "bytes", + name: "attestationData", + type: "bytes", + }, + ], + internalType: "struct AttestationPayload[]", + name: "attestationsPayloads", + type: "tuple[]", + }, + { + internalType: "bytes[][]", + name: "validationPayloads", + type: "bytes[][]", + }, + ], + name: "bulkReplace", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32[]", + name: "attestationIds", + type: "bytes32[]", + }, + ], + name: "bulkRevoke", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "getAttester", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getModules", + outputs: [ + { + internalType: "address[]", + name: "", + type: "address[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "moduleRegistry", + outputs: [ + { + internalType: "contract ModuleRegistry", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + name: "modules", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "portalRegistry", + outputs: [ + { + internalType: "contract PortalRegistry", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "attestationId", + type: "bytes32", + }, + { + components: [ + { + internalType: "bytes32", + name: "schemaId", + type: "bytes32", + }, + { + internalType: "uint64", + name: "expirationDate", + type: "uint64", + }, + { + internalType: "bytes", + name: "subject", + type: "bytes", + }, + { + internalType: "bytes", + name: "attestationData", + type: "bytes", + }, + ], + internalType: "struct AttestationPayload", + name: "attestationPayload", + type: "tuple", + }, + { + internalType: "bytes[]", + name: "validationPayloads", + type: "bytes[]", + }, + ], + name: "replace", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "attestationId", + type: "bytes32", + }, + ], + name: "revoke", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "router", + outputs: [ + { + internalType: "contract IRouter", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes4", + name: "interfaceID", + type: "bytes4", + }, + ], + name: "supportsInterface", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "address payable", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "withdraw", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +]; diff --git a/sdk/src/dataMapper/BaseDataMapper.ts b/sdk/src/dataMapper/BaseDataMapper.ts index d679612b..d708b6f7 100644 --- a/sdk/src/dataMapper/BaseDataMapper.ts +++ b/sdk/src/dataMapper/BaseDataMapper.ts @@ -1,35 +1,46 @@ -import { PublicClient } from "viem"; +import { PublicClient, WalletClient } from "viem"; import { ApolloClient, gql } from "@apollo/client/core"; -import { Conf, FilterMap } from "../types"; +import { Conf, FilterMap, QueryResult } from "../types"; import { stringifyWhereClause } from "../utils/apolloClientHelper"; +import VeraxSdk from "../VeraxSdk"; export default abstract class BaseDataMapper { protected readonly conf: Conf; protected readonly web3Client: PublicClient; + protected readonly walletClient: WalletClient; protected readonly apolloClient: ApolloClient; + protected readonly veraxSdk: VeraxSdk; protected abstract typeName: string; protected abstract gqlInterface: string; - constructor(_conf: Conf, _web3Client: PublicClient, _apolloClient: ApolloClient) { + constructor( + _conf: Conf, + _web3Client: PublicClient, + _walletClient: WalletClient, + _apolloClient: ApolloClient, + _veraxSdk: VeraxSdk, + ) { this.conf = _conf; this.web3Client = _web3Client; + this.walletClient = _walletClient; this.apolloClient = _apolloClient; + this.veraxSdk = _veraxSdk; } async findOneById(id: string): Promise { - const queryResult = await this.apolloClient.query({ + const queryResult = await this.apolloClient.query>({ query: gql(`query GetOne($id: ID!) { ${this.typeName}(id: $id) ${this.gqlInterface} }`), variables: { id }, }); - return queryResult.data; + return queryResult.data[this.typeName]; } async findBy(whereClause: Partial) { - const queryResult = await this.apolloClient.query>({ + const queryResult = await this.apolloClient.query, typeof this.typeName>>({ query: gql(`query GetBy { ${this.typeName}s(where: ${stringifyWhereClause(whereClause)}) ${this.gqlInterface} }`), }); - return queryResult.data; + return queryResult.data[`${this.typeName}s`]; } } diff --git a/sdk/src/dataMapper/PortalDataMapper.ts b/sdk/src/dataMapper/PortalDataMapper.ts index d76cd7da..998f907e 100644 --- a/sdk/src/dataMapper/PortalDataMapper.ts +++ b/sdk/src/dataMapper/PortalDataMapper.ts @@ -1,5 +1,8 @@ -import { Portal } from "../types"; +import { AttestationPayload, Portal } from "../types"; import BaseDataMapper from "./BaseDataMapper"; +import { abiDefaultPortal } from "../abi/DefaultPortal"; +import { Address, BaseError, ContractFunctionRevertedError, Hash } from "viem"; +import { encode } from "../utils/abiCoder"; export default class PortalDataMapper extends BaseDataMapper { typeName = "portal"; @@ -13,8 +16,44 @@ export default class PortalDataMapper extends BaseDataMapper { ownerName }`; - async attest() { - throw new Error("Not implemented"); + async simulateAttest(portalAddress: Address, attestationPayload: AttestationPayload, validationPayloads: string[]) { + const matchingSchema = await this.veraxSdk.schema.findOneById(attestationPayload.schemaId); + const attestationData = encode(matchingSchema.schema, attestationPayload.attestationData); + + try { + const { request } = await this.web3Client.simulateContract({ + address: portalAddress, + abi: abiDefaultPortal, + functionName: "attest", + account: this.walletClient.account, + args: [ + [attestationPayload.schemaId, attestationPayload.expirationDate, attestationPayload.subject, attestationData], + validationPayloads, + ], + }); + + return request; + } catch (err) { + if (err instanceof BaseError) { + const revertError = err.walk((err) => err instanceof ContractFunctionRevertedError); + if (revertError instanceof ContractFunctionRevertedError) { + const errorName = revertError.data?.errorName ?? ""; + console.error(`Failing with ${errorName}`); + } + } + console.error(err); + + throw new Error("Simulation failed"); + } + } + + async attest(portalAddress: Address, attestationPayload: AttestationPayload, validationPayloads: string[]) { + const request = await this.simulateAttest(portalAddress, attestationPayload, validationPayloads); + const hash: Hash = await this.walletClient.writeContract(request); + + console.log(`Transaction sent with hash ${hash}`); + + return hash; } async bulkAttest() { diff --git a/sdk/src/types/index.d.ts b/sdk/src/types/index.d.ts index a2201f0c..a39652b4 100644 --- a/sdk/src/types/index.d.ts +++ b/sdk/src/types/index.d.ts @@ -1,7 +1,8 @@ -import { Address, Chain } from "viem"; +import { Address, Chain, EthereumProvider } from "viem"; export interface Conf { chain: Chain; + mode: SDKMode; subgraphUrl: string; portalRegistryAddress: Address; moduleRegistryAddress: Address; @@ -9,12 +10,19 @@ export interface Conf { attestationRegistryAddress: Address; } +export type AttestationPayload = { + schemaId: string; // The identifier of the schema this attestation adheres to. + expirationDate: number; // The expiration date of the attestation. + subject: string; // The ID of the attestee, EVM address, DID, URL etc. + attestationData: object[]; // The attestation data. +}; + export type Attestation = { attestationId: string; // The unique identifier of the attestation. schemaId: string; // The identifier of the schema this attestation adheres to. replacedBy: string | null; // Whether the attestation was replaced by a new one. - Address: string; // The address issuing the attestation to the subject. - Address: string; // The id of the portal that created the attestation. + attester: Address; // The address issuing the attestation to the subject. + portal: Address; // The id of the portal that created the attestation. attestedDate: number; // The date the attestation is issued. expirationDate: number; // The expiration date of the attestation. revocationDate: number | null; // The date when the attestation was revoked. @@ -25,6 +33,7 @@ export type Attestation = { }; export type Schema = { + id: string; // The ID of the schema. name: string; // The name of the schema. description: string; // A description of the schema. context: string; // The context of the schema. @@ -61,3 +70,13 @@ export type FilterModule = Module; export type FilterSchema = Schema; export type FilterPortal = Portal; + +export type QueryResult = { + [P in K]: T; +}; + +declare global { + interface Window { + ethereum: EthereumProvider; + } +} diff --git a/sdk/src/utils/constants.ts b/sdk/src/utils/constants.ts index f7ea3773..925834bb 100644 --- a/sdk/src/utils/constants.ts +++ b/sdk/src/utils/constants.ts @@ -3,3 +3,8 @@ export class Constants { static readonly NAMED_GRAPH_RELATIONSHIP_SCHEMA_ID = "0x5003a7832fa2734780a5bf6a1f3940b84c0c66a398e62dd4e7f183fdbc7da6ee"; } + +export enum SDKMode { + BACKEND = "BACKEND", + FRONTEND = "FRONTEND", +} diff --git a/sdk/test/dataMapper/AttestationDataMapper.test.ts b/sdk/test/dataMapper/AttestationDataMapper.test.ts index 602f18c5..0ed5ac8b 100644 --- a/sdk/test/dataMapper/AttestationDataMapper.test.ts +++ b/sdk/test/dataMapper/AttestationDataMapper.test.ts @@ -1,12 +1,13 @@ import AttestationDataMapper from "../../src/dataMapper/AttestationDataMapper"; import VeraxSdk from "../../src/VeraxSdk"; -import { createPublicClient, http, PublicClient } from "viem"; +import { createPublicClient, createWalletClient, http, PublicClient, WalletClient } from "viem"; import { ApolloClient, ApolloQueryResult, gql, InMemoryCache } from "@apollo/client/core"; import { Constants } from "../../src/utils/constants"; describe("AttestationDataMapper", () => { let mockApolloClient: ApolloClient; let web3Client: PublicClient; + let walletClient: WalletClient; let attestationDataMapper: AttestationDataMapper; const typeName: string = "attestation"; const gqlInterface: string = `{ @@ -33,12 +34,24 @@ describe("AttestationDataMapper", () => { transport: http(), }); + // Create walletClient + walletClient = createWalletClient({ + chain: VeraxSdk.DEFAULT_LINEA_TESTNET.chain, + transport: http(), + }); + // Create a mock Apollo Client with an in-memory cache mockApolloClient = new ApolloClient({ cache: new InMemoryCache(), }); - attestationDataMapper = new AttestationDataMapper(VeraxSdk.DEFAULT_LINEA_TESTNET, web3Client, mockApolloClient); + attestationDataMapper = new AttestationDataMapper( + VeraxSdk.DEFAULT_LINEA_TESTNET, + web3Client, + walletClient, + mockApolloClient, + new VeraxSdk(VeraxSdk.DEFAULT_LINEA_TESTNET), + ); }); afterEach(() => { @@ -60,7 +73,7 @@ describe("AttestationDataMapper", () => { const result = await attestationDataMapper.findOneById(attestationId); // Assert - expect(result).toMatchObject({ attestation: { result: "success" } }); + expect(result).toMatchObject({ result: "success" }); expect(mockApolloClient.query).toHaveBeenCalledWith({ query: gql(`query GetOne($id: ID!) { ${typeName}(id: $id) ${gqlInterface} }`), variables: { id: attestationId }, @@ -82,7 +95,7 @@ describe("AttestationDataMapper", () => { const result = await attestationDataMapper.getRelatedAttestations(attestationId); // Assert - expect(result).toMatchObject({ attestations: { result: "success" } }); + expect(result).toMatchObject({ result: "success" }); expect(mockApolloClient.query).toHaveBeenCalledWith({ query: gql( `query GetBy { ${typeName}s(where: {attestationData_contains:"${attestationId}",schemaId_in:["${Constants.RELATIONSHIP_SCHEMA_ID}","${Constants.NAMED_GRAPH_RELATIONSHIP_SCHEMA_ID}"]}) ${gqlInterface} }`,