@show-karma/karma-gap-sdk 0.4.15 → 0.4.16

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 (188) hide show
  1. package/.cursorrules +43 -0
  2. package/core/abi/AirdropNFT.json +1 -1
  3. package/core/abi/Allo.json +860 -860
  4. package/core/abi/AlloRegistry.json +578 -578
  5. package/core/abi/CommunityResolverABI.json +506 -506
  6. package/core/abi/Donations.json +251 -251
  7. package/core/abi/EAS.json +1 -1
  8. package/core/abi/MultiAttester.json +746 -746
  9. package/core/abi/ProjectResolver.json +574 -574
  10. package/core/abi/SchemaRegistry.json +1 -1
  11. package/core/abi/index.ts +21 -0
  12. package/core/class/AllGapSchemas.ts +21 -0
  13. package/core/class/Attestation.ts +429 -0
  14. package/core/class/Fetcher.ts +224 -0
  15. package/core/class/GAP.ts +481 -0
  16. package/core/class/GapSchema.ts +93 -0
  17. package/core/class/Gelato/{Gelato.js → Gelato.ts} +23 -0
  18. package/core/class/GrantProgramRegistry/Allo.ts +188 -0
  19. package/core/class/GrantProgramRegistry/AlloRegistry.ts +101 -0
  20. package/core/class/GraphQL/AxiosGQL.ts +29 -0
  21. package/core/class/GraphQL/EASClient.ts +34 -0
  22. package/core/class/GraphQL/GapEasClient.ts +869 -0
  23. package/core/class/Schema.ts +659 -0
  24. package/core/class/SchemaError.ts +42 -0
  25. package/core/class/contract/GapContract.ts +457 -0
  26. package/core/class/entities/Community.ts +148 -0
  27. package/core/class/entities/ContributorProfile.ts +108 -0
  28. package/core/class/entities/Grant.ts +321 -0
  29. package/core/class/entities/GrantUpdate.ts +187 -0
  30. package/core/class/entities/MemberOf.ts +52 -0
  31. package/core/class/entities/Milestone.ts +898 -0
  32. package/core/class/entities/Project.ts +672 -0
  33. package/core/class/entities/ProjectImpact.ts +170 -0
  34. package/core/class/entities/ProjectMilestone.ts +254 -0
  35. package/core/class/entities/ProjectPointer.ts +39 -0
  36. package/core/class/entities/ProjectUpdate.ts +176 -0
  37. package/core/class/entities/Track.ts +32 -0
  38. package/core/class/karma-indexer/GapIndexerClient.ts +383 -0
  39. package/core/class/karma-indexer/api/GapIndexerApi.ts +446 -0
  40. package/core/class/karma-indexer/api/types.ts +313 -0
  41. package/core/class/remote-storage/IpfsStorage.ts +76 -0
  42. package/core/class/remote-storage/RemoteStorage.ts +65 -0
  43. package/core/class/types/allo.ts +93 -0
  44. package/core/class/types/attestations.ts +223 -0
  45. package/core/consts.ts +775 -0
  46. package/core/scripts/create-grant.ts +102 -0
  47. package/core/scripts/create-program.ts +43 -0
  48. package/core/scripts/create-schemas.ts +65 -0
  49. package/core/scripts/deploy.ts +65 -0
  50. package/core/scripts/index.ts +1 -0
  51. package/core/scripts/milestone-multi-grants.ts +125 -0
  52. package/core/shared/types.ts +13 -0
  53. package/core/types.ts +224 -0
  54. package/core/utils/gelato/send-gelato-txn.ts +114 -0
  55. package/core/utils/gelato/sponsor-handler.ts +77 -0
  56. package/core/utils/gelato/watch-gelato-txn.ts +67 -0
  57. package/core/utils/get-date.ts +3 -0
  58. package/core/utils/get-ipfs-data.ts +13 -0
  59. package/core/utils/get-web3-provider.ts +18 -0
  60. package/core/utils/gql-queries.ts +133 -0
  61. package/core/utils/map-filter.ts +21 -0
  62. package/core/utils/serialize-bigint.ts +7 -0
  63. package/core/utils/to-unix.ts +18 -0
  64. package/create-community-example.ts +119 -0
  65. package/csv-upload/README.md +74 -0
  66. package/csv-upload/config.ts +41 -0
  67. package/csv-upload/example.csv +2 -0
  68. package/csv-upload/keys.example.json +8 -0
  69. package/csv-upload/scripts/run.ts +417 -0
  70. package/csv-upload/types.ts +39 -0
  71. package/docs/.gitkeep +0 -0
  72. package/docs/images/attestation-architecture.png +0 -0
  73. package/docs/images/dfd-get-projects.png +0 -0
  74. package/gap-schema.yaml +155 -0
  75. package/milestone-workflow-example.ts +353 -0
  76. package/package.json +45 -39
  77. package/readme.md +872 -0
  78. package/schemas/.gitkeep +0 -0
  79. package/schemas/GAP-schemas-1692135812877.json +33 -0
  80. package/test-file-indexer-api.ts +25 -0
  81. package/tsconfig.json +26 -0
  82. package/core/abi/index.d.ts +0 -1114
  83. package/core/abi/index.js +0 -26
  84. package/core/class/AllGapSchemas.d.ts +0 -9
  85. package/core/class/AllGapSchemas.js +0 -19
  86. package/core/class/Attestation.d.ts +0 -173
  87. package/core/class/Attestation.js +0 -333
  88. package/core/class/Fetcher.d.ts +0 -175
  89. package/core/class/Fetcher.js +0 -13
  90. package/core/class/GAP.d.ts +0 -254
  91. package/core/class/GAP.js +0 -289
  92. package/core/class/GapSchema.d.ts +0 -34
  93. package/core/class/GapSchema.js +0 -62
  94. package/core/class/GrantProgramRegistry/Allo.d.ts +0 -17
  95. package/core/class/GrantProgramRegistry/Allo.js +0 -137
  96. package/core/class/GrantProgramRegistry/AlloRegistry.d.ts +0 -15
  97. package/core/class/GrantProgramRegistry/AlloRegistry.js +0 -70
  98. package/core/class/GraphQL/AxiosGQL.d.ts +0 -6
  99. package/core/class/GraphQL/AxiosGQL.js +0 -25
  100. package/core/class/GraphQL/EASClient.d.ts +0 -16
  101. package/core/class/GraphQL/EASClient.js +0 -26
  102. package/core/class/GraphQL/GapEasClient.d.ts +0 -71
  103. package/core/class/GraphQL/GapEasClient.js +0 -451
  104. package/core/class/GraphQL/index.js +0 -19
  105. package/core/class/Schema.d.ts +0 -233
  106. package/core/class/Schema.js +0 -488
  107. package/core/class/SchemaError.d.ts +0 -30
  108. package/core/class/SchemaError.js +0 -39
  109. package/core/class/contract/GapContract.d.ts +0 -102
  110. package/core/class/contract/GapContract.js +0 -285
  111. package/core/class/entities/Community.d.ts +0 -34
  112. package/core/class/entities/Community.js +0 -109
  113. package/core/class/entities/ContributorProfile.d.ts +0 -41
  114. package/core/class/entities/ContributorProfile.js +0 -69
  115. package/core/class/entities/Grant.d.ts +0 -54
  116. package/core/class/entities/Grant.js +0 -223
  117. package/core/class/entities/GrantUpdate.d.ts +0 -40
  118. package/core/class/entities/GrantUpdate.js +0 -114
  119. package/core/class/entities/MemberOf.d.ts +0 -11
  120. package/core/class/entities/MemberOf.js +0 -33
  121. package/core/class/entities/Milestone.d.ts +0 -168
  122. package/core/class/entities/Milestone.js +0 -657
  123. package/core/class/entities/Project.d.ts +0 -92
  124. package/core/class/entities/Project.js +0 -418
  125. package/core/class/entities/ProjectImpact.d.ts +0 -50
  126. package/core/class/entities/ProjectImpact.js +0 -112
  127. package/core/class/entities/ProjectMilestone.d.ts +0 -60
  128. package/core/class/entities/ProjectMilestone.js +0 -174
  129. package/core/class/entities/ProjectPointer.d.ts +0 -12
  130. package/core/class/entities/ProjectPointer.js +0 -22
  131. package/core/class/entities/ProjectUpdate.d.ts +0 -50
  132. package/core/class/entities/ProjectUpdate.js +0 -110
  133. package/core/class/entities/Track.d.ts +0 -16
  134. package/core/class/entities/Track.js +0 -21
  135. package/core/class/entities/index.js +0 -26
  136. package/core/class/index.js +0 -26
  137. package/core/class/karma-indexer/GapIndexerClient.d.ts +0 -66
  138. package/core/class/karma-indexer/GapIndexerClient.js +0 -207
  139. package/core/class/karma-indexer/api/GapIndexerApi.d.ts +0 -73
  140. package/core/class/karma-indexer/api/GapIndexerApi.js +0 -256
  141. package/core/class/karma-indexer/api/types.d.ts +0 -295
  142. package/core/class/karma-indexer/api/types.js +0 -2
  143. package/core/class/remote-storage/IpfsStorage.d.ts +0 -23
  144. package/core/class/remote-storage/IpfsStorage.js +0 -56
  145. package/core/class/remote-storage/RemoteStorage.d.ts +0 -41
  146. package/core/class/remote-storage/RemoteStorage.js +0 -38
  147. package/core/class/types/allo.d.ts +0 -78
  148. package/core/class/types/allo.js +0 -2
  149. package/core/class/types/attestations.d.ts +0 -168
  150. package/core/class/types/attestations.js +0 -66
  151. package/core/consts.d.ts +0 -48
  152. package/core/consts.js +0 -641
  153. package/core/index.js +0 -24
  154. package/core/shared/types.d.ts +0 -6
  155. package/core/shared/types.js +0 -2
  156. package/core/types.d.ts +0 -131
  157. package/core/types.js +0 -13
  158. package/core/utils/gelato/index.js +0 -19
  159. package/core/utils/gelato/send-gelato-txn.d.ts +0 -55
  160. package/core/utils/gelato/send-gelato-txn.js +0 -100
  161. package/core/utils/gelato/sponsor-handler.d.ts +0 -9
  162. package/core/utils/gelato/sponsor-handler.js +0 -60
  163. package/core/utils/gelato/watch-gelato-txn.d.ts +0 -7
  164. package/core/utils/gelato/watch-gelato-txn.js +0 -63
  165. package/core/utils/get-date.d.ts +0 -1
  166. package/core/utils/get-date.js +0 -7
  167. package/core/utils/get-ipfs-data.d.ts +0 -1
  168. package/core/utils/get-ipfs-data.js +0 -20
  169. package/core/utils/get-web3-provider.d.ts +0 -2
  170. package/core/utils/get-web3-provider.js +0 -18
  171. package/core/utils/gql-queries.d.ts +0 -12
  172. package/core/utils/gql-queries.js +0 -90
  173. package/core/utils/index.js +0 -23
  174. package/core/utils/map-filter.d.ts +0 -8
  175. package/core/utils/map-filter.js +0 -20
  176. package/core/utils/serialize-bigint.d.ts +0 -1
  177. package/core/utils/serialize-bigint.js +0 -8
  178. package/core/utils/to-unix.d.ts +0 -1
  179. package/core/utils/to-unix.js +0 -25
  180. package/index.js +0 -17
  181. /package/core/class/GraphQL/{index.d.ts → index.ts} +0 -0
  182. /package/core/class/entities/{index.d.ts → index.ts} +0 -0
  183. /package/core/class/{index.d.ts → index.ts} +0 -0
  184. /package/core/{index.d.ts → index.ts} +0 -0
  185. /package/core/utils/gelato/{index.d.ts → index.ts} +0 -0
  186. /package/core/utils/{index.d.ts → index.ts} +0 -0
  187. /package/{core/class/Gelato/Gelato.d.ts → csv-upload/.gitkeep} +0 -0
  188. /package/{index.d.ts → index.ts} +0 -0
@@ -0,0 +1,672 @@
1
+ import {
2
+ Hex,
3
+ MultiAttestPayload,
4
+ SignerOrProvider,
5
+ TNetwork,
6
+ } from "core/types";
7
+ import { chainIdToNetwork, nullRef } from "../../consts";
8
+ import { mapFilter } from "../../utils";
9
+ import { AllGapSchemas } from "../AllGapSchemas";
10
+ import { Attestation } from "../Attestation";
11
+ import { GapContract } from "../contract/GapContract";
12
+ import {
13
+ IProjectMilestoneResponse,
14
+ IProjectResponse,
15
+ } from "../karma-indexer/api/types";
16
+ import { AttestationError } from "../SchemaError";
17
+ import {
18
+ AttestationWithTx,
19
+ Grantee,
20
+ MemberDetails,
21
+ ProjectDetails,
22
+ ProjectEndorsement,
23
+ } from "../types/attestations";
24
+ import { Grant } from "./Grant";
25
+ import { MemberOf } from "./MemberOf";
26
+ import { IProjectImpact, ProjectImpact } from "./ProjectImpact";
27
+ import { ProjectMilestone } from "./ProjectMilestone";
28
+ import { ProjectPointer } from "./ProjectPointer";
29
+ import { ProjectUpdate } from "./ProjectUpdate";
30
+
31
+ interface _Project extends Project {}
32
+
33
+ export interface IProject {
34
+ project: true;
35
+ }
36
+
37
+ export class Project extends Attestation<IProject> {
38
+ details?: ProjectDetails;
39
+ members: MemberOf[] = [];
40
+ grants: Grant[] = [];
41
+ grantee: Grantee;
42
+ impacts: ProjectImpact[] = [];
43
+ endorsements: ProjectEndorsement[] = [];
44
+ updates: ProjectUpdate[] = [];
45
+ pointers: ProjectPointer[] = [];
46
+ milestones: ProjectMilestone[] = [];
47
+
48
+ /**
49
+ * Creates the payload for a multi-attestation.
50
+ *
51
+ * > if Current payload is set, it'll be used as the base payload
52
+ * and the project should refer to an index of the current payload,
53
+ * usually the community position.
54
+ *
55
+ * @param payload
56
+ * @param communityIdx
57
+ */
58
+ async multiAttestPayload(
59
+ currentPayload: MultiAttestPayload = [],
60
+ communityIdx = 0
61
+ ): Promise<MultiAttestPayload> {
62
+ const payload = [...currentPayload];
63
+ const projectIdx =
64
+ payload.push([this, await this.payloadFor(communityIdx)]) - 1;
65
+
66
+ if (this.details) {
67
+ payload.push([this.details, await this.details.payloadFor(projectIdx)]);
68
+ }
69
+
70
+ if (this.members?.length) {
71
+ await Promise.all(
72
+ this.members.map(async (m) =>
73
+ payload.push(...(await m.multiAttestPayload(payload, projectIdx)))
74
+ )
75
+ );
76
+ }
77
+
78
+ if (this.grants?.length) {
79
+ await Promise.all(
80
+ this.grants.map(async (g) =>
81
+ payload.push(...(await g.multiAttestPayload(payload, projectIdx)))
82
+ )
83
+ );
84
+ }
85
+
86
+ return payload.slice(currentPayload.length, payload.length);
87
+ }
88
+
89
+ async attest(
90
+ signer: SignerOrProvider,
91
+ callback?: Function
92
+ ): Promise<AttestationWithTx> {
93
+ const payload = await this.multiAttestPayload();
94
+ const { tx, uids } = await GapContract.multiAttest(
95
+ signer,
96
+ payload.map((p) => p[1]),
97
+ callback
98
+ );
99
+
100
+ if (Array.isArray(uids)) {
101
+ uids.forEach((uid, index) => {
102
+ payload[index][0].uid = uid;
103
+ });
104
+ }
105
+ return { tx, uids };
106
+ }
107
+
108
+ async transferOwnership(
109
+ signer: SignerOrProvider,
110
+ newOwner: Hex,
111
+ callback?: Function
112
+ ): Promise<AttestationWithTx> {
113
+ callback?.("preparing");
114
+ const tx = await GapContract.transferProjectOwnership(
115
+ signer,
116
+ this.uid,
117
+ newOwner
118
+ );
119
+ callback?.("confirmed");
120
+ const txArray = [tx].flat();
121
+ return { tx: txArray, uids: [this.uid] };
122
+ }
123
+
124
+ isOwner(signer: SignerOrProvider, publicAddress?: string): Promise<boolean> {
125
+ return GapContract.isProjectOwner(
126
+ signer,
127
+ this.uid,
128
+ this.chainID,
129
+ publicAddress
130
+ );
131
+ }
132
+
133
+ isAdmin(signer: SignerOrProvider, publicAddress?: string): Promise<boolean> {
134
+ return GapContract.isProjectAdmin(
135
+ signer,
136
+ this.uid,
137
+ this.chainID,
138
+ publicAddress
139
+ );
140
+ }
141
+
142
+ /**
143
+ * Add new members to the project.
144
+ * If any member in the array already exists in the project
145
+ * it'll be ignored.
146
+ * @param members
147
+ */
148
+ pushMembers(...members: Hex[]) {
149
+ this.members.push(
150
+ ...mapFilter(
151
+ members,
152
+ (member) => !!this.members.find((m) => m.recipient === member),
153
+ (member) =>
154
+ new MemberOf({
155
+ data: { memberOf: true },
156
+ refUID: this.uid,
157
+ schema: this.schema.gap.findSchema("MemberOf"),
158
+ recipient: member,
159
+ uid: nullRef,
160
+ })
161
+ )
162
+ );
163
+ }
164
+
165
+ /**
166
+ * Add new members to the project.
167
+ * If any member in the array already exists in the project
168
+ * it'll be ignored.
169
+ *
170
+ * __To modify member details, use `addMemberDetails(signer, MemberDetails[])` instead.__
171
+ * @param signer
172
+ * @param members
173
+ */
174
+ async attestMembers(
175
+ signer: SignerOrProvider,
176
+ members: MemberDetails[],
177
+ callback?: Function
178
+ ) {
179
+ const newMembers = mapFilter(
180
+ members,
181
+ (member) => !this.members.find((m) => m.recipient === member.recipient),
182
+ // (member) => !!member,
183
+ (details) => {
184
+ const member = new MemberOf({
185
+ data: { memberOf: true },
186
+ refUID: this.uid,
187
+ schema: this.schema.gap.findSchema("MemberOf"),
188
+ createdAt: Date.now(),
189
+ recipient: details.recipient,
190
+ uid: nullRef,
191
+ });
192
+ return { member, details };
193
+ }
194
+ );
195
+
196
+ if (!newMembers.length) {
197
+ throw new AttestationError("ATTEST_ERROR", "No new members to add.");
198
+ }
199
+
200
+ console.log(`Creating ${newMembers.length} new members`);
201
+
202
+ const { uids: attestedMembers } = await this.schema.multiAttest(
203
+ signer,
204
+ newMembers.map((m) => m.member),
205
+ callback
206
+ );
207
+
208
+ console.log("attested-members", attestedMembers);
209
+
210
+ newMembers.forEach(({ member, details }, idx) => {
211
+ Object.assign(member, { uid: attestedMembers[idx] });
212
+
213
+ if (!details) return;
214
+ Object.assign(details, { refUID: attestedMembers[idx] });
215
+ });
216
+
217
+ this.members.push(...newMembers.map((m) => m.member));
218
+
219
+ await this.addMemberDetails(
220
+ signer,
221
+ newMembers.map((m) => m.details)
222
+ );
223
+ }
224
+
225
+ /**
226
+ * Add new details to the members of a project. Note that it will overwrite
227
+ * any existing details.
228
+ *
229
+ * @param signer
230
+ * @param entities
231
+ */
232
+ private async addMemberDetails(
233
+ signer: SignerOrProvider,
234
+ entities: MemberDetails[],
235
+ callback?: Function
236
+ ) {
237
+ // Check if any of members should be revoked (details modified)
238
+ const toRevoke = mapFilter(
239
+ this.members,
240
+ (member) =>
241
+ !!entities.find(
242
+ (entity) =>
243
+ member.uid === entity.refUID &&
244
+ member.details &&
245
+ member.details?.refUID !== entity.refUID
246
+ ),
247
+ (member) => member.uid
248
+ );
249
+
250
+ if (toRevoke.length) {
251
+ console.log("Revoking details");
252
+ await this.cleanDetails(signer, toRevoke);
253
+ }
254
+
255
+ console.log(`Creating ${entities.length} new member details`);
256
+
257
+ const { uids: attestedEntities } = await this.schema.multiAttest(
258
+ signer,
259
+ entities,
260
+ callback
261
+ );
262
+ console.log("attested-entities", attestedEntities);
263
+
264
+ entities.forEach((entity, idx) => {
265
+ const member = this.members.find(
266
+ (member) => member.uid === entity.refUID
267
+ );
268
+ if (!member) return;
269
+
270
+ Object.assign(entity, { uid: attestedEntities[idx] });
271
+ member.details = entity;
272
+ });
273
+ }
274
+
275
+ /**
276
+ * Clean member details.
277
+ * @param signer
278
+ * @param uids
279
+ */
280
+ async cleanDetails(signer: SignerOrProvider, uids: Hex[]) {
281
+ if (!uids.length) {
282
+ throw new AttestationError("ATTEST_ERROR", "No details to clean.");
283
+ }
284
+ const memberDetails = this.schema.gap.findSchema("MemberDetails");
285
+
286
+ await this.schema.multiRevoke(
287
+ signer,
288
+ uids.map((uid) => ({ schemaId: memberDetails.uid, uid }))
289
+ );
290
+
291
+ this.members.forEach((member) => {
292
+ if (!member.details) return;
293
+ if (uids.includes(member.details.uid)) {
294
+ member.details = undefined;
295
+ }
296
+ });
297
+ }
298
+
299
+ /**
300
+ * Remove members from the project.
301
+ * @param signer
302
+ * @param uids
303
+ * @returns
304
+ */
305
+ async removeMembers(signer: SignerOrProvider, uids: Hex[]) {
306
+ if (!uids.length) {
307
+ throw new AttestationError("ATTEST_ERROR", "No members to remove.");
308
+ }
309
+ const memberOf = this.schema.gap.findSchema("MemberOf");
310
+
311
+ const details = mapFilter(
312
+ this.members,
313
+ (m) => uids.includes(m.uid) && !!m.details,
314
+ (m) => m.details?.uid
315
+ );
316
+
317
+ if (details.length) {
318
+ await this.cleanDetails(signer, details);
319
+ }
320
+
321
+ await this.schema.multiRevoke(
322
+ signer,
323
+ uids.map((uid) => ({ schemaId: memberOf.uid, uid }))
324
+ );
325
+
326
+ this.members = this.members.filter((m) => !uids.includes(m.uid));
327
+ }
328
+
329
+ /**
330
+ * Remove all members from the project.
331
+ * @param signer
332
+ */
333
+ async removeAllMembers(signer: SignerOrProvider) {
334
+ const members = mapFilter(
335
+ this.members,
336
+ (m) => !!m.uid,
337
+ (m) => m.uid
338
+ );
339
+
340
+ if (!members.length) {
341
+ throw new AttestationError("REVOKATION_ERROR", "No members to revoke.");
342
+ }
343
+
344
+ const details = mapFilter(
345
+ this.members,
346
+ (m) => !!m.details,
347
+ (m) => m.details?.uid
348
+ );
349
+ if (details.length) {
350
+ await this.cleanDetails(signer, details);
351
+ }
352
+
353
+ await this.removeMembers(signer, members);
354
+ this.members.splice(0, this.members.length);
355
+ }
356
+
357
+ static from(attestations: IProjectResponse[], network: TNetwork): Project[] {
358
+ const allSchemas = new AllGapSchemas();
359
+ return attestations.map((attestation) => {
360
+ const project = new Project({
361
+ ...attestation,
362
+ data: {
363
+ project: true,
364
+ },
365
+ schema: allSchemas.findSchema(
366
+ "Project",
367
+ chainIdToNetwork[attestation.chainID] as TNetwork
368
+ ),
369
+ chainID: attestation.chainID,
370
+ });
371
+
372
+ if (attestation.details) {
373
+ const { details } = attestation;
374
+ project.details = new ProjectDetails({
375
+ ...details,
376
+ data: {
377
+ ...details.data,
378
+ },
379
+ schema: allSchemas.findSchema(
380
+ "ProjectDetails",
381
+ chainIdToNetwork[attestation.chainID] as TNetwork
382
+ ),
383
+ chainID: attestation.chainID,
384
+ });
385
+
386
+ project.details.links = details.data.links || [];
387
+ project.details.tags = details.data.tags || [];
388
+
389
+ if ((attestation.data as any).links) {
390
+ project.details.links = (attestation.data as any).links;
391
+ }
392
+
393
+ if ((attestation.data as any).tags) {
394
+ project.details.tags = (attestation as any).tags;
395
+ }
396
+ }
397
+
398
+ if (attestation.members) {
399
+ project.members = attestation.members.map((m) => {
400
+ const member = new MemberOf({
401
+ ...m,
402
+ data: {
403
+ memberOf: true,
404
+ },
405
+ schema: allSchemas.findSchema(
406
+ "MemberOf",
407
+ chainIdToNetwork[attestation.chainID] as TNetwork
408
+ ),
409
+ chainID: attestation.chainID,
410
+ });
411
+
412
+ if (m.details) {
413
+ const { details } = m;
414
+ member.details = new MemberDetails({
415
+ ...details,
416
+ data: {
417
+ ...details.data,
418
+ },
419
+ schema: allSchemas.findSchema(
420
+ "MemberDetails",
421
+ chainIdToNetwork[attestation.chainID] as TNetwork
422
+ ),
423
+ chainID: attestation.chainID,
424
+ });
425
+ }
426
+
427
+ return member;
428
+ });
429
+ }
430
+
431
+ if (attestation.grants) {
432
+ project.grants = Grant.from(attestation.grants, network);
433
+ }
434
+
435
+ if (attestation.impacts) {
436
+ project.impacts = ProjectImpact.from(
437
+ attestation.impacts as unknown as ProjectImpact[],
438
+ network
439
+ );
440
+ }
441
+
442
+ if (attestation.pointers) {
443
+ project.pointers = ProjectPointer.from(
444
+ attestation.pointers as unknown as ProjectPointer[],
445
+ network
446
+ );
447
+ }
448
+
449
+ if (attestation.updates) {
450
+ project.updates = ProjectUpdate.from(
451
+ attestation.updates as unknown as ProjectUpdate[],
452
+ network
453
+ );
454
+ }
455
+
456
+ if (attestation.milestones) {
457
+ project.milestones = ProjectMilestone.from(
458
+ attestation.milestones as unknown as IProjectMilestoneResponse[],
459
+ network
460
+ );
461
+ }
462
+
463
+ if (attestation.endorsements) {
464
+ project.endorsements = attestation.endorsements.map((pi) => {
465
+ const endorsement = new ProjectEndorsement({
466
+ ...pi,
467
+ data: {
468
+ ...pi.data,
469
+ },
470
+ schema: allSchemas.findSchema(
471
+ "ProjectDetails",
472
+ chainIdToNetwork[attestation.chainID] as TNetwork
473
+ ),
474
+ chainID: attestation.chainID,
475
+ });
476
+
477
+ return endorsement;
478
+ });
479
+ }
480
+
481
+ return project;
482
+ });
483
+ }
484
+
485
+ async attestUpdate(
486
+ signer: SignerOrProvider,
487
+ data: ProjectUpdate,
488
+ callback?: Function
489
+ ) {
490
+ const projectUpdate = new ProjectUpdate({
491
+ data: {
492
+ ...data,
493
+ type: "project-update",
494
+ },
495
+ recipient: this.recipient,
496
+ refUID: this.uid,
497
+ schema: this.schema.gap.findSchema("ProjectUpdate"),
498
+ });
499
+
500
+ await projectUpdate.attest(signer, callback);
501
+ this.updates.push(projectUpdate);
502
+ }
503
+
504
+ async attestMilestone(
505
+ signer: SignerOrProvider,
506
+ data: ProjectUpdate,
507
+ callback?: Function
508
+ ) {
509
+ const projectMilestone = new ProjectMilestone({
510
+ data: {
511
+ ...data,
512
+ type: "project-milestone",
513
+ },
514
+ recipient: this.recipient,
515
+ refUID: this.uid,
516
+ schema: this.schema.gap.findSchema("ProjectMilestone"),
517
+ });
518
+
519
+ await projectMilestone.attest(signer, callback);
520
+ this.milestones.push(projectMilestone);
521
+ }
522
+
523
+ async attestPointer(
524
+ signer: SignerOrProvider,
525
+ data: ProjectPointer,
526
+ callback?: Function
527
+ ) {
528
+ const projectPointer = new ProjectPointer({
529
+ data: {
530
+ ...data,
531
+ type: "project-pointer",
532
+ },
533
+ recipient: this.recipient,
534
+ refUID: this.uid,
535
+ schema: this.schema.gap.findSchema("ProjectPointer"),
536
+ });
537
+
538
+ await projectPointer.attest(signer, callback);
539
+ this.pointers.push(projectPointer);
540
+ }
541
+
542
+ async attestImpact(
543
+ signer: SignerOrProvider,
544
+ data: IProjectImpact,
545
+ targetChainId?: number,
546
+ callback?: Function
547
+ ): Promise<AttestationWithTx> {
548
+ if (targetChainId && targetChainId !== this.chainID) {
549
+ return this.attestGhostProjectImpact(
550
+ signer,
551
+ data,
552
+ targetChainId,
553
+ callback
554
+ );
555
+ }
556
+
557
+ const projectImpact = new ProjectImpact({
558
+ data: {
559
+ ...data,
560
+ type: "project-impact",
561
+ },
562
+ recipient: this.recipient,
563
+ refUID: this.uid,
564
+ schema: this.schema.gap.findSchema("ProjectDetails"),
565
+ });
566
+
567
+ const { tx, uids } = await projectImpact.attest(signer, callback);
568
+ this.impacts.push(projectImpact);
569
+ return { tx, uids };
570
+ }
571
+
572
+ private async attestGhostProjectImpact(
573
+ signer: SignerOrProvider,
574
+ data: IProjectImpact,
575
+ targetChainId: number,
576
+ callback?: Function
577
+ ): Promise<AttestationWithTx> {
578
+ const { tx, uids } = await this.attestGhostProject(signer, targetChainId);
579
+ const ghostProjectUid = uids[0];
580
+
581
+ const allGapSchemas = new AllGapSchemas();
582
+ const projectImpact = new ProjectImpact({
583
+ data: {
584
+ ...data,
585
+ type: "project-impact",
586
+ },
587
+ recipient: this.recipient,
588
+ refUID: ghostProjectUid,
589
+ schema: allGapSchemas.findSchema(
590
+ "ProjectDetails",
591
+ chainIdToNetwork[targetChainId]
592
+ ),
593
+ chainID: targetChainId,
594
+ });
595
+
596
+ const impactAttestation = await projectImpact.attest(signer, callback);
597
+ this.impacts.push(projectImpact);
598
+
599
+ return {
600
+ tx: impactAttestation.tx,
601
+ uids: [...uids, impactAttestation.uids[0]],
602
+ };
603
+ }
604
+
605
+ async attestEndorsement(signer: SignerOrProvider, data?: ProjectEndorsement) {
606
+ const projectEndorsement = new ProjectEndorsement({
607
+ data: {
608
+ ...data,
609
+ type: "project-endorsement",
610
+ },
611
+ recipient: this.recipient,
612
+ refUID: this.uid,
613
+ schema: this.schema.gap.findSchema("ProjectDetails"),
614
+ });
615
+
616
+ await projectEndorsement.attest(signer);
617
+ this.endorsements.push(projectEndorsement);
618
+ }
619
+
620
+ async attestGhostProject(signer: SignerOrProvider, targetChainId: number) {
621
+ const allGapSchemas = new AllGapSchemas();
622
+ const project = new Project({
623
+ data: { project: true },
624
+ schema: allGapSchemas.findSchema(
625
+ "Project",
626
+ chainIdToNetwork[targetChainId]
627
+ ),
628
+ recipient: this.recipient,
629
+ chainID: targetChainId,
630
+ });
631
+
632
+ (project.details as Attestation) = new Attestation({
633
+ data: {
634
+ originalProjectChainId: this.chainID,
635
+ uid: this.uid,
636
+ },
637
+ chainID: targetChainId,
638
+ recipient: this.recipient,
639
+ schema: allGapSchemas.findSchema(
640
+ "ProjectDetails",
641
+ chainIdToNetwork[targetChainId]
642
+ ),
643
+ });
644
+
645
+ const attestation = await project.attest(signer);
646
+ return attestation;
647
+ }
648
+
649
+ async addAdmin(
650
+ signer: SignerOrProvider,
651
+ newAdmin: Hex,
652
+ callback?: Function
653
+ ): Promise<AttestationWithTx> {
654
+ callback?.("preparing");
655
+ const tx = await GapContract.addProjectAdmin(signer, this.uid, newAdmin);
656
+ callback?.("confirmed");
657
+ const txArray = [tx].flat();
658
+ return { tx: txArray, uids: [this.uid] };
659
+ }
660
+
661
+ async removeAdmin(
662
+ signer: SignerOrProvider,
663
+ oldAdmin: Hex,
664
+ callback?: Function
665
+ ): Promise<AttestationWithTx> {
666
+ callback?.("preparing");
667
+ const tx = await GapContract.removeProjectAdmin(signer, this.uid, oldAdmin);
668
+ callback?.("confirmed");
669
+ const txArray = [tx].flat();
670
+ return { tx: txArray, uids: [this.uid] };
671
+ }
672
+ }