@show-karma/karma-gap-sdk 0.3.4 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/core/abi/CommunityResolverABI.json +508 -0
  2. package/core/class/AttestationIPFS.d.ts +7 -0
  3. package/core/class/AttestationIPFS.js +10 -0
  4. package/core/class/GAP.d.ts +7 -0
  5. package/core/class/GAP.js +14 -0
  6. package/core/class/GraphQL/Fetcher.d.ts +132 -0
  7. package/core/class/GraphQL/Fetcher.js +7 -0
  8. package/core/class/GraphQL/GAPFetcher.d.ts +160 -0
  9. package/core/class/GraphQL/GAPFetcher.js +516 -0
  10. package/core/class/IPFS/IPFS.d.ts +13 -0
  11. package/core/class/IPFS/IPFS.js +24 -0
  12. package/core/class/contract/MultiAttest.d.ts +10 -0
  13. package/core/class/contract/MultiAttest.js +19 -0
  14. package/core/consts.js +4 -34
  15. package/core/types.d.ts +1 -0
  16. package/package.json +1 -1
  17. package/readme.md +34 -39
  18. package/config/keys.example.json +0 -6
  19. package/core/abi/EAS.json +0 -1
  20. package/core/abi/SchemaRegistry.json +0 -1
  21. package/core/class/Attestation.ts +0 -402
  22. package/core/class/Fetcher.ts +0 -202
  23. package/core/class/GAP.ts +0 -398
  24. package/core/class/GapSchema.ts +0 -90
  25. package/core/class/Gelato/Gelato.ts +0 -286
  26. package/core/class/GraphQL/AxiosGQL.ts +0 -29
  27. package/core/class/GraphQL/EASClient.ts +0 -34
  28. package/core/class/GraphQL/GapEasClient.ts +0 -845
  29. package/core/class/GraphQL/index.ts +0 -3
  30. package/core/class/Schema.ts +0 -609
  31. package/core/class/SchemaError.ts +0 -36
  32. package/core/class/contract/GapContract.ts +0 -353
  33. package/core/class/entities/Community.ts +0 -115
  34. package/core/class/entities/Grant.ts +0 -309
  35. package/core/class/entities/MemberOf.ts +0 -42
  36. package/core/class/entities/Milestone.ts +0 -269
  37. package/core/class/entities/Project.ts +0 -370
  38. package/core/class/entities/index.ts +0 -5
  39. package/core/class/index.ts +0 -10
  40. package/core/class/karma-indexer/GapIndexerClient.ts +0 -245
  41. package/core/class/remote-storage/IpfsStorage.ts +0 -51
  42. package/core/class/remote-storage/RemoteStorage.ts +0 -65
  43. package/core/class/types/attestations.ts +0 -158
  44. package/core/consts.ts +0 -282
  45. package/core/index.ts +0 -7
  46. package/core/scripts/deploy.ts +0 -67
  47. package/core/scripts/index.ts +0 -1
  48. package/core/types.ts +0 -186
  49. package/core/utils/gelato/index.ts +0 -3
  50. package/core/utils/gelato/send-gelato-txn.ts +0 -114
  51. package/core/utils/gelato/sponsor-handler.ts +0 -77
  52. package/core/utils/gelato/watch-gelato-txn.ts +0 -67
  53. package/core/utils/get-date.ts +0 -3
  54. package/core/utils/get-ipfs-data.ts +0 -13
  55. package/core/utils/get-web3-provider.ts +0 -20
  56. package/core/utils/gql-queries.ts +0 -133
  57. package/core/utils/index.ts +0 -7
  58. package/core/utils/map-filter.ts +0 -21
  59. package/core/utils/serialize-bigint.ts +0 -7
  60. package/core/utils/to-unix.ts +0 -18
  61. package/csv-upload/.gitkeep +0 -0
  62. package/csv-upload/example.csv +0 -2
  63. package/csv-upload/scripts/run.ts +0 -193
  64. package/docs/.gitkeep +0 -0
  65. package/docs/images/attestation-architecture.png +0 -0
  66. package/docs/images/dfd-get-projects.png +0 -0
  67. package/index.ts +0 -1
  68. package/schemas/.gitkeep +0 -0
  69. package/schemas/GAP-schemas-1692135812877.json +0 -33
  70. package/test-file.ts +0 -92
  71. package/tsconfig.json +0 -26
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Fetcher = void 0;
4
+ const AxiosGQL_1 = require("./AxiosGQL");
5
+ class Fetcher extends AxiosGQL_1.AxiosGQL {
6
+ }
7
+ exports.Fetcher = Fetcher;
@@ -0,0 +1,160 @@
1
+ import { Attestation } from "../Attestation";
2
+ import { Hex, IAttestation, TSchemaName } from "../../types";
3
+ import { Grantee } from "../types/attestations";
4
+ import { GapSchema } from "../GapSchema";
5
+ import { EASClient } from "./EASClient";
6
+ import { Grant, Milestone, Project, MemberOf } from "../entities";
7
+ import { Community } from "../entities/Community";
8
+ export declare class GAPFetcher extends EASClient {
9
+ /**
10
+ * Fetches all the schemas deployed by an owner
11
+ * @param owner
12
+ */
13
+ schemas(owner: Hex): Promise<GapSchema[]>;
14
+ /**
15
+ * Fetch a single attestation by its UID.
16
+ * @param uid
17
+ */
18
+ attestation<T = unknown>(uid: Hex): Promise<Attestation<T, GapSchema>>;
19
+ /**
20
+ * Fetch attestations of a schema.
21
+ * @param schemaName
22
+ * @param search if set, will search decodedDataJson by the value.
23
+ * @returns
24
+ */
25
+ attestations(schemaName: TSchemaName, search?: string): Promise<IAttestation[]>;
26
+ /**
27
+ * Fetch attestations of a schema.
28
+ * @param schemaName
29
+ * @param recipient
30
+ * @returns
31
+ */
32
+ attestationsOf(schemaName: TSchemaName, recipient: Hex): Promise<IAttestation[]>;
33
+ /**
34
+ * Fetch attestations of a schema for a specific recipient.
35
+ * @param schemaName
36
+ * @param recipient
37
+ * @returns
38
+ */
39
+ attestationsTo(schemaName: TSchemaName, recipient: Hex): Promise<IAttestation[]>;
40
+ /**
41
+ * Fetch all dependent attestations of a parent schema.
42
+ * @param parentSchema the schema name to get dependents of.
43
+ * @param parentUid the parent uid to get dependents of.
44
+ */
45
+ dependentsOf(parentSchema: TSchemaName, parentUid: Hex): Promise<Attestation[]>;
46
+ /**
47
+ * Fetch all available communities with details and grantees uids.
48
+ *
49
+ * If search is defined, will try to find communities by the search string.
50
+ * @param search
51
+ * @returns
52
+ */
53
+ communities(search?: string): Promise<Community[]>;
54
+ /**
55
+ * Fetch a set of communities by their ids.
56
+ * @param uids
57
+ * @returns
58
+ */
59
+ communitiesByIds(uids: Hex[]): Promise<Community[]>;
60
+ /**
61
+ * Get details for a set of communities and returns the updated array.
62
+ * @param communities
63
+ * @returns
64
+ */
65
+ communitiesDetails(communities: Community[]): Promise<Community[]>;
66
+ /**
67
+ * Fetch a community by its name with details, grants and milestones.
68
+ *
69
+ * It is possible that the resulted community is not the one you are looking for.
70
+ * @param name
71
+ * @returns
72
+ */
73
+ communityBySlug(slug: string): Promise<Community>;
74
+ /**
75
+ * Fetch a community by its id. This method will also return the
76
+ * community details and projects.
77
+ */
78
+ communityById(uid: Hex): Promise<Community>;
79
+ /**
80
+ * Fetch the details for a set of
81
+ * projects with project grants,
82
+ * members, milestones, and tags.
83
+ * @param projects
84
+ */
85
+ projectsDetails(projects: Project[]): Promise<Project[]>;
86
+ /**
87
+ * Fetch a project by its id.
88
+ * @param uid
89
+ * @returns
90
+ */
91
+ projectById(uid: Hex): Promise<Project>;
92
+ /**
93
+ * Fetch a project by its id.
94
+ * @param uid
95
+ * @returns
96
+ */
97
+ projectBySlug(slug: string): Promise<Project>;
98
+ /**
99
+ * Check if a name is already in use.
100
+ * @param slug
101
+ * @returns
102
+ */
103
+ slugExists(slug: string): Promise<boolean>;
104
+ /**
105
+ * Fetch projects with details and members.
106
+ * @param name if set, will search by the name.
107
+ * @returns
108
+ */
109
+ projects(name?: string): Promise<Project[]>;
110
+ /**
111
+ * Fetch projects with details and members.
112
+ * @param grantee the public address of the grantee
113
+ * @returns
114
+ */
115
+ projectsOf(grantee: Hex): Promise<Project[]>;
116
+ /**
117
+ * Fetch Grantee with details and projects.
118
+ * @param address
119
+ * @param withProjects if true, will get grantee project details.
120
+ * @returns
121
+ */
122
+ grantee(address: Hex): Promise<Grantee>;
123
+ /**
124
+ * Fetch all Grantees with details.
125
+ * @returns
126
+ */
127
+ grantees(): Promise<Grantee[]>;
128
+ /**
129
+ * Fetches the grantes related to a grantee address (recipient).
130
+ * @param grantee
131
+ * @returns
132
+ */
133
+ grantsOf(grantee: Hex, withCommunity?: boolean): Promise<Grant[]>;
134
+ grantsUpdates(grants: Grant[]): Promise<Grant[]>;
135
+ grantsByCommunity(uid: Hex): Promise<Grant[]>;
136
+ /**
137
+ * Fetch grants for an array of projects with milestones.
138
+ * @param projects
139
+ * @returns
140
+ */
141
+ grantsFor(projects: Project[], withCommunity?: boolean): Promise<Grant[]>;
142
+ /**
143
+ * Fetch all milestones related to an array of Grants.
144
+ * @param grants
145
+ * @returns
146
+ */
147
+ milestonesOf(grants: Grant[]): Promise<Milestone[]>;
148
+ /**
149
+ * Bulk fetch members with details of an array of Projects.
150
+ * @param projects
151
+ * @returns
152
+ */
153
+ membersOf(projects: Project[]): Promise<MemberOf[]>;
154
+ /**
155
+ * Returns a string to be used to search by a value in `decodedDataJson`.
156
+ * @param field
157
+ * @param value
158
+ */
159
+ private getSearchFieldString;
160
+ }
@@ -0,0 +1,516 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GAPFetcher = void 0;
4
+ const Attestation_1 = require("../Attestation");
5
+ const gql_queries_1 = require("../../utils/gql-queries");
6
+ const to_unix_1 = require("../../utils/to-unix");
7
+ const attestations_1 = require("../types/attestations");
8
+ const GapSchema_1 = require("../GapSchema");
9
+ const Schema_1 = require("../Schema");
10
+ const EASClient_1 = require("./EASClient");
11
+ const SchemaError_1 = require("../SchemaError");
12
+ const entities_1 = require("../entities");
13
+ const Community_1 = require("../entities/Community");
14
+ const utils_1 = require("../../utils");
15
+ // TODO: Split this class into small ones
16
+ class GAPFetcher extends EASClient_1.EASClient {
17
+ /**
18
+ * Fetches all the schemas deployed by an owner
19
+ * @param owner
20
+ */
21
+ async schemas(owner) {
22
+ const query = gql_queries_1.gqlQueries.schemata(owner);
23
+ const { schemata } = await this.query(query);
24
+ return schemata.map((schema) => new GapSchema_1.GapSchema({
25
+ name: "",
26
+ schema: Schema_1.Schema.rawToObject(schema.schema),
27
+ uid: schema.uid,
28
+ }));
29
+ }
30
+ /**
31
+ * Fetch a single attestation by its UID.
32
+ * @param uid
33
+ */
34
+ async attestation(uid) {
35
+ const query = gql_queries_1.gqlQueries.attestation(uid);
36
+ const { attestation } = await this.query(query);
37
+ return Attestation_1.Attestation.fromInterface([attestation])[0];
38
+ }
39
+ /**
40
+ * Fetch attestations of a schema.
41
+ * @param schemaName
42
+ * @param search if set, will search decodedDataJson by the value.
43
+ * @returns
44
+ */
45
+ async attestations(schemaName, search) {
46
+ const schema = GapSchema_1.GapSchema.find(schemaName);
47
+ const query = gql_queries_1.gqlQueries.attestationsOf(schema.uid, search);
48
+ const { schema: { attestations }, } = await this.query(query);
49
+ return attestations;
50
+ }
51
+ /**
52
+ * Fetch attestations of a schema.
53
+ * @param schemaName
54
+ * @param recipient
55
+ * @returns
56
+ */
57
+ async attestationsOf(schemaName, recipient) {
58
+ const schema = GapSchema_1.GapSchema.find(schemaName);
59
+ const query = gql_queries_1.gqlQueries.attestationsOf(schema.uid, recipient);
60
+ const { schema: { attestations }, } = await this.query(query);
61
+ return attestations;
62
+ }
63
+ /**
64
+ * Fetch attestations of a schema for a specific recipient.
65
+ * @param schemaName
66
+ * @param recipient
67
+ * @returns
68
+ */
69
+ async attestationsTo(schemaName, recipient) {
70
+ const schema = GapSchema_1.GapSchema.find(schemaName);
71
+ const query = gql_queries_1.gqlQueries.attestationsTo(schema.uid, recipient);
72
+ const { schema: { attestations }, } = await this.query(query);
73
+ return attestations;
74
+ }
75
+ /**
76
+ * Fetch all dependent attestations of a parent schema.
77
+ * @param parentSchema the schema name to get dependents of.
78
+ * @param parentUid the parent uid to get dependents of.
79
+ */
80
+ async dependentsOf(parentSchema, parentUid) {
81
+ const parent = GapSchema_1.GapSchema.find(parentSchema);
82
+ const children = parent.children.map((c) => c.uid);
83
+ if (!children.length)
84
+ throw new SchemaError_1.SchemaError("INVALID_REFERENCE", `Schema ${parentSchema} has no children.`);
85
+ const query = gql_queries_1.gqlQueries.dependentsOf(parentUid, children);
86
+ const { attestations } = await this.query(query);
87
+ return Attestation_1.Attestation.fromInterface(attestations);
88
+ }
89
+ /**
90
+ * Fetch all available communities with details and grantees uids.
91
+ *
92
+ * If search is defined, will try to find communities by the search string.
93
+ * @param search
94
+ * @returns
95
+ */
96
+ async communities(search) {
97
+ const [community, communityDetails] = GapSchema_1.GapSchema.findMany([
98
+ "Community",
99
+ "CommunityDetails",
100
+ ]);
101
+ const query = gql_queries_1.gqlQueries.attestationsOf(community.uid, search);
102
+ const { schema: { attestations }, } = await this.query(query);
103
+ const communities = Attestation_1.Attestation.fromInterface(attestations);
104
+ if (!communities.length)
105
+ return [];
106
+ return this.communitiesDetails(communities);
107
+ }
108
+ /**
109
+ * Fetch a set of communities by their ids.
110
+ * @param uids
111
+ * @returns
112
+ */
113
+ async communitiesByIds(uids) {
114
+ if (!uids.length)
115
+ return [];
116
+ const communityDetails = GapSchema_1.GapSchema.find("CommunityDetails");
117
+ const communityQuery = gql_queries_1.gqlQueries.attestationsIn(uids);
118
+ const detailsQuery = gql_queries_1.gqlQueries.dependentsOf(uids, [communityDetails.uid]);
119
+ try {
120
+ const [communities, details] = await Promise.all([
121
+ this.query(communityQuery),
122
+ this.query(detailsQuery),
123
+ ]);
124
+ const communitiesAttestations = Attestation_1.Attestation.fromInterface(communities.attestations || []);
125
+ const detailsAttestations = Attestation_1.Attestation.fromInterface(details.attestations || []);
126
+ communitiesAttestations.forEach((community) => {
127
+ community.details = detailsAttestations.find((d) => d.refUID === community.uid);
128
+ });
129
+ return communitiesAttestations;
130
+ }
131
+ catch (error) {
132
+ throw error;
133
+ }
134
+ }
135
+ /**
136
+ * Get details for a set of communities and returns the updated array.
137
+ * @param communities
138
+ * @returns
139
+ */
140
+ async communitiesDetails(communities) {
141
+ const [project, communityDetails] = GapSchema_1.GapSchema.findMany([
142
+ "Project",
143
+ "CommunityDetails",
144
+ ]);
145
+ const ref = gql_queries_1.gqlQueries.dependentsOf(communities.map((c) => c.uid), [communityDetails.uid]);
146
+ const results = await this.query(ref);
147
+ const deps = Attestation_1.Attestation.fromInterface(results.attestations || []);
148
+ return communities.map((community) => {
149
+ community.projects = (deps.filter((ref) => ref.schema.uid === project.uid && ref.refUID === community.uid));
150
+ community.details = (deps.find((ref) => ref.schema.uid === communityDetails.uid &&
151
+ ref.refUID === community.uid));
152
+ return community;
153
+ });
154
+ }
155
+ /**
156
+ * Fetch a community by its name with details, grants and milestones.
157
+ *
158
+ * It is possible that the resulted community is not the one you are looking for.
159
+ * @param name
160
+ * @returns
161
+ */
162
+ async communityBySlug(slug) {
163
+ const communitySchema = GapSchema_1.GapSchema.find("CommunityDetails");
164
+ const query = gql_queries_1.gqlQueries.attestationsOf(communitySchema.uid, this.getSearchFieldString("slug", slug));
165
+ try {
166
+ const { schema: { attestations }, } = await this.query(query);
167
+ if (!attestations.length)
168
+ throw new Error("Community not found.");
169
+ const communities = (0, utils_1.mapFilter)(Attestation_1.Attestation.fromInterface(attestations), (details) => !!details.name, (details) => {
170
+ const community = new Community_1.Community({
171
+ data: { community: true },
172
+ uid: details.refUID,
173
+ schema: communitySchema,
174
+ recipient: details.recipient,
175
+ });
176
+ community.details = details;
177
+ return community;
178
+ });
179
+ const [withDetails] = await this.communitiesDetails(communities);
180
+ if (!withDetails)
181
+ throw new Error("Community not found.");
182
+ const grants = await this.grantsByCommunity(withDetails.uid);
183
+ withDetails.grants = grants;
184
+ return withDetails;
185
+ }
186
+ catch (error) {
187
+ throw error;
188
+ }
189
+ }
190
+ /**
191
+ * Fetch a community by its id. This method will also return the
192
+ * community details and projects.
193
+ */
194
+ async communityById(uid) {
195
+ const query = gql_queries_1.gqlQueries.attestation(uid);
196
+ const { attestation } = await this.query(query);
197
+ if (!attestation)
198
+ throw new Error("Community not found.");
199
+ const communities = Attestation_1.Attestation.fromInterface([attestation]).map((c) => new Community_1.Community(c));
200
+ const [withDetails] = await this.communitiesDetails(communities);
201
+ if (!withDetails)
202
+ throw new Error("Community not found.");
203
+ const grants = await this.grantsByCommunity(uid);
204
+ withDetails.grants = grants;
205
+ return withDetails;
206
+ }
207
+ /**
208
+ * Fetch the details for a set of
209
+ * projects with project grants,
210
+ * members, milestones, and tags.
211
+ * @param projects
212
+ */
213
+ async projectsDetails(projects) {
214
+ // Get projects array and fetch details, members, grants, etc then append to the project and return the array.
215
+ const [projectDetails] = GapSchema_1.GapSchema.findMany(["ProjectDetails"]);
216
+ const refQuery = gql_queries_1.gqlQueries.dependentsOf(projects.map((p) => p.uid), [projectDetails.uid]);
217
+ const [result, members, grants] = await Promise.all([
218
+ this.query(refQuery),
219
+ this.membersOf(projects),
220
+ this.grantsFor(projects, true),
221
+ ]);
222
+ const deps = Attestation_1.Attestation.fromInterface(result.attestations || []);
223
+ return projects.map((project) => {
224
+ project.details = (deps.find((ref) => ref.schema.uid === projectDetails.uid && ref.refUID === project.uid));
225
+ project.members = members.filter((m) => m.refUID === project.uid);
226
+ project.grants = grants.filter((g) => g.refUID === project.uid);
227
+ return project;
228
+ });
229
+ }
230
+ /**
231
+ * Fetch a project by its id.
232
+ * @param uid
233
+ * @returns
234
+ */
235
+ async projectById(uid) {
236
+ const query = gql_queries_1.gqlQueries.attestation(uid);
237
+ const { attestation } = await this.query(query);
238
+ if (!attestation)
239
+ throw new Error("Project not found.");
240
+ const projectAttestation = Attestation_1.Attestation.fromInterface([
241
+ attestation,
242
+ ])[0];
243
+ const [result] = await this.projectsDetails([
244
+ new entities_1.Project(projectAttestation),
245
+ ]);
246
+ return result;
247
+ }
248
+ /**
249
+ * Fetch a project by its id.
250
+ * @param uid
251
+ * @returns
252
+ */
253
+ async projectBySlug(slug) {
254
+ const projectDetails = GapSchema_1.GapSchema.find("ProjectDetails");
255
+ const query = gql_queries_1.gqlQueries.attestationsOf(projectDetails.uid, this.getSearchFieldString("slug", slug));
256
+ const { schema: { attestations }, } = await this.query(query);
257
+ const projectAttestations = Attestation_1.Attestation.fromInterface(attestations).filter((p) => p.title);
258
+ if (!projectAttestations.length)
259
+ throw new Error("Project not found.");
260
+ const project = new entities_1.Project({
261
+ data: { project: true },
262
+ uid: projectAttestations[0].refUID,
263
+ schema: GapSchema_1.GapSchema.find("Project"),
264
+ recipient: projectAttestations[0].recipient,
265
+ });
266
+ const [withDetails] = await this.projectsDetails([project]);
267
+ if (!withDetails)
268
+ throw new Error("Project not found.");
269
+ return withDetails;
270
+ }
271
+ /**
272
+ * Check if a name is already in use.
273
+ * @param slug
274
+ * @returns
275
+ */
276
+ async slugExists(slug) {
277
+ const details = GapSchema_1.GapSchema.find("ProjectDetails");
278
+ const query = gql_queries_1.gqlQueries.attestationsOf(details.uid, "slug");
279
+ const { schema: { attestations }, } = await this.query(query);
280
+ return attestations.some((a) => a.decodedDataJson.includes(slug));
281
+ }
282
+ /**
283
+ * Fetch projects with details and members.
284
+ * @param name if set, will search by the name.
285
+ * @returns
286
+ */
287
+ async projects(name) {
288
+ const result = await this.attestations("Project", name);
289
+ if (!result.length)
290
+ return [];
291
+ const projects = Attestation_1.Attestation.fromInterface(result);
292
+ return this.projectsDetails(projects);
293
+ }
294
+ /**
295
+ * Fetch projects with details and members.
296
+ * @param grantee the public address of the grantee
297
+ * @returns
298
+ */
299
+ async projectsOf(grantee) {
300
+ const result = await this.attestationsTo("Project", grantee);
301
+ if (!result.length)
302
+ return [];
303
+ const projects = Attestation_1.Attestation.fromInterface(result);
304
+ return this.projectsDetails(projects);
305
+ }
306
+ /**
307
+ * Fetch Grantee with details and projects.
308
+ * @param address
309
+ * @param withProjects if true, will get grantee project details.
310
+ * @returns
311
+ */
312
+ async grantee(address) {
313
+ const projects = await this.projectsOf(address);
314
+ return new attestations_1.Grantee(address, projects);
315
+ }
316
+ /**
317
+ * Fetch all Grantees with details.
318
+ * @returns
319
+ */
320
+ async grantees() {
321
+ const projects = await this.projects();
322
+ return projects.reduce((acc, item) => {
323
+ const hasGrantee = acc.find((g) => g.address === item.recipient);
324
+ if (hasGrantee)
325
+ hasGrantee.projects.push(item);
326
+ else
327
+ acc.push(new attestations_1.Grantee(item.recipient, [item]));
328
+ return acc;
329
+ }, []);
330
+ }
331
+ /**
332
+ * Fetches the grantes related to a grantee address (recipient).
333
+ * @param grantee
334
+ * @returns
335
+ */
336
+ async grantsOf(grantee, withCommunity) {
337
+ const [grant, grantDetails, grantVerified] = GapSchema_1.GapSchema.findMany([
338
+ "Grant",
339
+ "GrantDetails",
340
+ "GrantVerified",
341
+ ]);
342
+ const query = gql_queries_1.gqlQueries.attestationsTo(grant.uid, grantee);
343
+ const { schema: { attestations }, } = await this.query(query);
344
+ const grants = Attestation_1.Attestation.fromInterface(attestations);
345
+ if (!grants.length)
346
+ return [];
347
+ const ref = gql_queries_1.gqlQueries.dependentsOf(grants.map((g) => g.uid), [grantDetails.uid, grantVerified.uid], grants.map((g) => g.recipient));
348
+ const results = await this.query(ref);
349
+ const deps = Attestation_1.Attestation.fromInterface(results.attestations || []);
350
+ const milestones = await this.milestonesOf(grants);
351
+ const communities = withCommunity
352
+ ? await this.communitiesByIds((0, utils_1.mapFilter)(grants, (g) => !!g.communityUID, (g) => g.communityUID))
353
+ : [];
354
+ const withDetails = grants.map((grant) => {
355
+ const refs = deps.filter((ref) => ref.refUID === grant.uid);
356
+ grant.verified = !!refs.find((ref) => ref.schema.uid === grantVerified.uid && ref.refUID === grant.uid);
357
+ grant.details = (refs.find((ref) => ref.schema.uid === grantDetails.uid &&
358
+ ref.refUID === grant.uid &&
359
+ typeof ref.endsAt === "undefined"));
360
+ grant.milestones = milestones.filter((m) => m.refUID === grant.uid && typeof m.endsAt !== "undefined");
361
+ grant.community = communities.find((c) => c.uid === grant.communityUID);
362
+ return grant;
363
+ });
364
+ return this.grantsUpdates(withDetails);
365
+ }
366
+ async grantsUpdates(grants) {
367
+ const details = GapSchema_1.GapSchema.find("GrantDetails");
368
+ const query = gql_queries_1.gqlQueries.attestationsOf(details.uid, this.getSearchFieldString("type", "grant-update"), grants.map((g) => g.uid));
369
+ const { schema: { attestations }, } = await this.query(query);
370
+ const updates = Attestation_1.Attestation.fromInterface(attestations);
371
+ return grants.map((grant) => {
372
+ grant.updates = updates.filter((u) => u.refUID === grant.uid);
373
+ return grant;
374
+ });
375
+ }
376
+ async grantsByCommunity(uid) {
377
+ const [grant, grantDetails, project, projectDetails] = GapSchema_1.GapSchema.findMany([
378
+ "Grant",
379
+ "GrantDetails",
380
+ "Project",
381
+ "ProjectDetails",
382
+ ]);
383
+ const query = gql_queries_1.gqlQueries.attestations(grant.uid, uid);
384
+ const { schema: { attestations }, } = await this.query(query);
385
+ const grants = Attestation_1.Attestation.fromInterface(attestations).map((g) => new entities_1.Grant(g));
386
+ if (!grants.length)
387
+ return [];
388
+ const refs = gql_queries_1.gqlQueries.dependentsOf(grants.map((g) => [g.uid, g.refUID]).flat(), [grantDetails.uid, project.uid]);
389
+ const results = await this.query(refs);
390
+ const deps = Attestation_1.Attestation.fromInterface(results.attestations || []);
391
+ const projectsDetailsQuery = gql_queries_1.gqlQueries.attestationsOf(projectDetails.uid);
392
+ const { schema: { attestations: projectsDetailsAttestations }, } = await this.query(projectsDetailsQuery);
393
+ const projectsDetails = Attestation_1.Attestation.fromInterface(projectsDetailsAttestations);
394
+ const milestones = await this.milestonesOf(grants);
395
+ return grants.map((grant) => {
396
+ grant.project = (projectsDetails.find((p) => p.refUID === grant.refUID));
397
+ grant.details = (deps.find((d) => d.refUID === grant.uid &&
398
+ d.schema.uid === grantDetails.uid &&
399
+ typeof d.amount !== undefined &&
400
+ typeof d.endsAt === "undefined" &&
401
+ typeof d.data.type === "undefined"));
402
+ grant.milestones = milestones
403
+ .filter((m) => m.refUID === grant.uid && typeof m.endsAt !== "undefined")
404
+ .sort((a, b) => a.endsAt - b.endsAt);
405
+ grant.updates = deps.filter((d) => d.data.type && d.refUID === grant.uid);
406
+ return grant;
407
+ });
408
+ }
409
+ /**
410
+ * Fetch grants for an array of projects with milestones.
411
+ * @param projects
412
+ * @returns
413
+ */
414
+ async grantsFor(projects, withCommunity) {
415
+ const [grant, grantDetails] = GapSchema_1.GapSchema.findMany([
416
+ "Grant",
417
+ "GrantDetails",
418
+ "Milestone",
419
+ "MilestoneApproved",
420
+ "MilestoneCompleted",
421
+ ]);
422
+ const query = gql_queries_1.gqlQueries.dependentsOf(projects.map((p) => p.uid), [grant.uid]);
423
+ const { attestations: grants } = await this.query(query);
424
+ const grantsWithDetails = Attestation_1.Attestation.fromInterface(grants).map((g) => new entities_1.Grant(g));
425
+ const ref = gql_queries_1.gqlQueries.dependentsOf(grants.map((g) => g.uid), [grantDetails.uid]);
426
+ const { attestations } = await this.query(ref);
427
+ const milestones = await this.milestonesOf(grantsWithDetails);
428
+ const deps = Attestation_1.Attestation.fromInterface(attestations);
429
+ grantsWithDetails.forEach((grant) => {
430
+ grant.details = (deps.find((d) => d.refUID === grant.uid &&
431
+ d.schema.uid === grantDetails.uid &&
432
+ typeof d.amount !== undefined &&
433
+ typeof d.endsAt === "undefined" &&
434
+ typeof d.data.type === "undefined"));
435
+ grant.milestones = milestones
436
+ .filter((m) => m.refUID === grant.uid && typeof m.endsAt !== "undefined")
437
+ .sort((a, b) => a.endsAt - b.endsAt);
438
+ });
439
+ const communities = withCommunity
440
+ ? await this.communitiesByIds((0, utils_1.mapFilter)(grantsWithDetails, (g) => !!g.communityUID, (g) => g.communityUID))
441
+ : [];
442
+ grantsWithDetails.forEach((grant) => {
443
+ grant.community = communities.find((c) => c.uid === grant.communityUID);
444
+ });
445
+ const grantsWithUpdates = await this.grantsUpdates(grantsWithDetails);
446
+ return grantsWithUpdates.sort((a, b) => a.milestones?.at(-1)?.endsAt - b.milestones?.at(-1)?.endsAt ||
447
+ a.createdAt.getTime() - b.createdAt.getTime());
448
+ }
449
+ /**
450
+ * Fetch all milestones related to an array of Grants.
451
+ * @param grants
452
+ * @returns
453
+ */
454
+ async milestonesOf(grants) {
455
+ const [milestone, milestoneApproved, milestoneCompleted] = GapSchema_1.GapSchema.findMany([
456
+ "Milestone",
457
+ "MilestoneApproved",
458
+ "MilestoneCompleted",
459
+ ]);
460
+ const query = gql_queries_1.gqlQueries.dependentsOf(grants.map((g) => g.uid), [milestone.uid]);
461
+ const { attestations } = await this.query(query);
462
+ const milestones = Attestation_1.Attestation.fromInterface(attestations)
463
+ .map((milestone) => new entities_1.Milestone(milestone))
464
+ .filter((m) => typeof m.endsAt !== "undefined");
465
+ if (!milestones.length)
466
+ return [];
467
+ const ref = gql_queries_1.gqlQueries.dependentsOf(milestones.map((m) => m.uid), [milestoneApproved.uid, milestoneCompleted.uid]);
468
+ const results = await this.query(ref);
469
+ const deps = Attestation_1.Attestation.fromInterface(results.attestations || []);
470
+ return milestones.map((milestone) => {
471
+ const refs = deps.filter((ref) => ref.refUID === milestone.uid);
472
+ milestone.endsAt = (0, to_unix_1.toUnix)(milestone.endsAt);
473
+ milestone.completed = refs.find((dep) => dep.type === "completed" && dep.refUID === milestone.uid);
474
+ milestone.approved = refs.find((dep) => dep.type === "approved" && dep.refUID === milestone.uid);
475
+ milestone.rejected = refs.find((dep) => dep.type === "rejected" && dep.refUID === milestone.uid);
476
+ return milestone;
477
+ });
478
+ }
479
+ /**
480
+ * Bulk fetch members with details of an array of Projects.
481
+ * @param projects
482
+ * @returns
483
+ */
484
+ async membersOf(projects) {
485
+ const [member, memberDetails] = GapSchema_1.GapSchema.findMany([
486
+ "MemberOf",
487
+ "MemberDetails",
488
+ ]);
489
+ if (!projects.length)
490
+ return [];
491
+ const query = gql_queries_1.gqlQueries.dependentsOf(projects.map((p) => p.uid), [member.uid], projects.map((p) => p.attester));
492
+ const results = await this.query(query);
493
+ const members = Attestation_1.Attestation.fromInterface(results.attestations || []);
494
+ if (members.length) {
495
+ const ref = gql_queries_1.gqlQueries.dependentsOf(members.map((a) => a.uid), [memberDetails.uid], members.map((a) => a.attester));
496
+ const detailsResult = await this.query(ref);
497
+ const detailsRef = Attestation_1.Attestation.fromInterface(detailsResult.attestations || []);
498
+ members.forEach((member) => {
499
+ member.details = detailsRef.find((d) => d.refUID === member.uid);
500
+ });
501
+ }
502
+ return members;
503
+ }
504
+ /**
505
+ * Returns a string to be used to search by a value in `decodedDataJson`.
506
+ * @param field
507
+ * @param value
508
+ */
509
+ getSearchFieldString(field, value) {
510
+ return [
511
+ String.raw `\\\\\"${field}\\\\\":\\\\\"${value}\\\\\"`,
512
+ String.raw `\\\\\"${field}\\\\\": \\\\\"${value}\\\\\"`,
513
+ ];
514
+ }
515
+ }
516
+ exports.GAPFetcher = GAPFetcher;