Skip to content

Commit 25d5cc4

Browse files
committed
refactor(contract): restructure contract resolver and related components
Refactored contract-related code to improve organization and maintainability: - Moved ContractResolver from graphql to services directory - Updated import paths in composed resolver - Modified WhereFieldDefinitions for contract fields so that chain_id is bigint not number - Enhanced ContractEntityService with comprehensive documentation - Added detailed JSDoc comments for ContractService and ContractsQueryStrategy - Updated field types and naming conventions for improved type safety
1 parent b4259aa commit 25d5cc4

File tree

9 files changed

+479
-29
lines changed

9 files changed

+479
-29
lines changed

src/graphql/schemas/resolvers/composed.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { HypercertResolver } from "./hypercertResolver.js";
22
import { MetadataResolver } from "./metadataResolver.js";
3-
import { ContractResolver } from "./contractResolver.js";
3+
import { ContractResolver } from "../../../services/graphql/resolvers/contractResolver.js";
44
import { FractionResolver } from "./fractionResolver.js";
55
import { AttestationResolver } from "../../../services/graphql/resolvers/attestationResolver.js";
66
import { AttestationSchemaResolver } from "../../../services/graphql/resolvers/attestationSchemaResolver.js";

src/graphql/schemas/resolvers/contractResolver.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/lib/graphql/whereFieldDefinitions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ export const WhereFieldDefinitions = {
7777
Contract: {
7878
fields: {
7979
id: "string",
80-
address: "string",
81-
chain_id: "number",
80+
contract_address: "string",
81+
chain_id: "bigint",
8282
},
8383
},
8484
Fraction: {

src/services/database/entities/ContractEntityService.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,36 @@ import {
88
type EntityService,
99
} from "./EntityServiceFactory.js";
1010

11+
/** Type representing a selected contract record from the database */
1112
export type ContractSelect = Selectable<CachingDatabase["contracts"]>;
1213

14+
/**
15+
* Service class for managing contract entities in the database.
16+
* Handles CRUD operations for contracts deployed on various chains.
17+
*
18+
* This service provides methods to:
19+
* - Retrieve multiple contracts with filtering and pagination
20+
* - Retrieve a single contract by its criteria
21+
*
22+
* Each contract represents a smart contract deployed on a blockchain,
23+
* containing information such as:
24+
* - Chain ID
25+
* - Contract address
26+
* - Deployment block number
27+
*
28+
* @injectable Marks the class as injectable for dependency injection with tsyringe
29+
*/
1330
@injectable()
1431
export class ContractService {
1532
private entityService: EntityService<
1633
CachingDatabase["contracts"],
1734
GetContractsArgs
1835
>;
1936

37+
/**
38+
* Creates a new instance of ContractService.
39+
* Initializes the underlying entity service for database operations.
40+
*/
2041
constructor() {
2142
this.entityService = createEntityService<
2243
CachingDatabase,
@@ -25,10 +46,53 @@ export class ContractService {
2546
>("contracts", "ContractEntityService", kyselyCaching);
2647
}
2748

49+
/**
50+
* Retrieves multiple contracts based on provided arguments.
51+
*
52+
* @param args - Query arguments for filtering and pagination
53+
* @returns A promise that resolves to an object containing:
54+
* - data: Array of contracts matching the query
55+
* - count: Total number of matching contracts
56+
* @throws {Error} If the database query fails
57+
*
58+
* @example
59+
* ```typescript
60+
* const result = await service.getContracts({
61+
* where: {
62+
* chain_id: { eq: "1" },
63+
* contract_address: { eq: "0x..." }
64+
* }
65+
* });
66+
* console.log(result.data); // Array of matching contracts
67+
* console.log(result.count); // Total count
68+
* ```
69+
*/
2870
async getContracts(args: GetContractsArgs) {
2971
return this.entityService.getMany(args);
3072
}
3173

74+
/**
75+
* Retrieves a single contract based on provided arguments.
76+
*
77+
* @param args - Query arguments for filtering
78+
* @returns A promise that resolves to:
79+
* - The matching contract if found
80+
* - undefined if no contract matches the criteria
81+
* @throws {Error} If the database query fails
82+
*
83+
* @example
84+
* ```typescript
85+
* const contract = await service.getContract({
86+
* where: {
87+
* chain_id: { eq: "1" },
88+
* contract_address: { eq: "0x..." }
89+
* }
90+
* });
91+
* if (contract) {
92+
* console.log("Found contract:", contract);
93+
* }
94+
* ```
95+
*/
3296
async getContract(args: GetContractsArgs) {
3397
return this.entityService.getSingle(args);
3498
}

src/services/database/strategies/ContractsQueryStrategy.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,52 @@ import { CachingDatabase } from "../../../types/kyselySupabaseCaching.js";
33
import { QueryStrategy } from "./QueryStrategy.js";
44

55
/**
6-
* Strategy for querying contracts
7-
* Handles joins with claims table
6+
* Strategy for building database queries for contracts.
7+
* Implements query logic for contract retrieval and counting.
8+
*
9+
* This strategy extends the base QueryStrategy to provide contract-specific query building.
10+
* It handles basic data retrieval and counting operations for contracts deployed on various chains.
11+
*
12+
* @template CachingDatabase - The database type containing the contracts table
813
*/
914
export class ContractsQueryStrategy extends QueryStrategy<
1015
CachingDatabase,
1116
"contracts"
1217
> {
1318
protected readonly tableName = "contracts" as const;
1419

20+
/**
21+
* Builds a query to retrieve contract data.
22+
* Returns a simple SELECT query that retrieves all columns from the contracts table.
23+
*
24+
* @param db - Kysely database instance
25+
* @returns A query builder for retrieving contract data
26+
*
27+
* @example
28+
* ```typescript
29+
* // Basic query to select all contracts
30+
* buildDataQuery(db);
31+
* // SELECT * FROM contracts
32+
* ```
33+
*/
1534
buildDataQuery(db: Kysely<CachingDatabase>) {
1635
return db.selectFrom(this.tableName).selectAll(this.tableName);
1736
}
1837

38+
/**
39+
* Builds a query to count contracts.
40+
* Returns a simple COUNT query for the contracts table.
41+
*
42+
* @param db - Kysely database instance
43+
* @returns A query builder for counting contracts
44+
*
45+
* @example
46+
* ```typescript
47+
* // Count all contracts
48+
* buildCountQuery(db);
49+
* // SELECT COUNT(*) as count FROM contracts
50+
* ```
51+
*/
1952
buildCountQuery(db: Kysely<CachingDatabase>) {
2053
return db.selectFrom(this.tableName).select((eb) => {
2154
return eb.fn.countAll().as("count");
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { inject, injectable } from "tsyringe";
2+
import { Args, Query, Resolver } from "type-graphql";
3+
import { ContractService } from "../../database/entities/ContractEntityService.js";
4+
import { GetContractsArgs } from "../../../graphql/schemas/args/contractArgs.js";
5+
import {
6+
Contract,
7+
GetContractsResponse,
8+
} from "../../../graphql/schemas/typeDefs/contractTypeDefs.js";
9+
10+
/**
11+
* GraphQL resolver for Contract operations.
12+
* Handles queries for contracts deployed on various chains.
13+
*
14+
* This resolver provides:
15+
* - Query for fetching contracts with optional filtering
16+
* - Support for pagination and sorting
17+
*
18+
* Each contract represents a smart contract deployed on a blockchain,
19+
* containing information such as:
20+
* - Chain ID
21+
* - Contract address
22+
* - Deployment block number
23+
*
24+
* @injectable Marks the class as injectable for dependency injection with tsyringe
25+
* @resolver Marks the class as a GraphQL resolver for the Contract type
26+
*/
27+
@injectable()
28+
@Resolver(() => Contract)
29+
class ContractResolver {
30+
/**
31+
* Creates a new instance of ContractResolver.
32+
*
33+
* @param contractService - Service for handling contract operations
34+
*/
35+
constructor(
36+
@inject(ContractService)
37+
private contractService: ContractService,
38+
) {}
39+
40+
/**
41+
* Queries contracts based on provided arguments.
42+
* Returns both the matching contracts and a total count.
43+
*
44+
* @param args - Query arguments for filtering contracts
45+
* @returns A promise that resolves to an object containing:
46+
* - data: Array of contracts matching the query
47+
* - count: Total number of matching contracts
48+
* @throws {Error} If the contract service query fails
49+
*
50+
* @example
51+
* Query with filtering:
52+
* ```graphql
53+
* query {
54+
* contracts(
55+
* where: {
56+
* chain_id: { eq: "1" },
57+
* contract_address: { eq: "0x..." }
58+
* }
59+
* ) {
60+
* data {
61+
* id
62+
* chain_id
63+
* contract_address
64+
* start_block
65+
* }
66+
* count
67+
* }
68+
* }
69+
* ```
70+
*/
71+
@Query(() => GetContractsResponse)
72+
async contracts(@Args() args: GetContractsArgs) {
73+
return this.contractService.getContracts(args);
74+
}
75+
}
76+
77+
export { ContractResolver };

0 commit comments

Comments
 (0)