@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.
- package/.cursorrules +43 -0
- package/core/abi/AirdropNFT.json +1 -1
- package/core/abi/Allo.json +860 -860
- package/core/abi/AlloRegistry.json +578 -578
- package/core/abi/CommunityResolverABI.json +506 -506
- package/core/abi/Donations.json +251 -251
- package/core/abi/EAS.json +1 -1
- package/core/abi/MultiAttester.json +746 -746
- package/core/abi/ProjectResolver.json +574 -574
- package/core/abi/SchemaRegistry.json +1 -1
- package/core/abi/index.ts +21 -0
- package/core/class/AllGapSchemas.ts +21 -0
- package/core/class/Attestation.ts +429 -0
- package/core/class/Fetcher.ts +224 -0
- package/core/class/GAP.ts +481 -0
- package/core/class/GapSchema.ts +93 -0
- package/core/class/Gelato/{Gelato.js → Gelato.ts} +23 -0
- package/core/class/GrantProgramRegistry/Allo.ts +188 -0
- package/core/class/GrantProgramRegistry/AlloRegistry.ts +101 -0
- package/core/class/GraphQL/AxiosGQL.ts +29 -0
- package/core/class/GraphQL/EASClient.ts +34 -0
- package/core/class/GraphQL/GapEasClient.ts +869 -0
- package/core/class/Schema.ts +659 -0
- package/core/class/SchemaError.ts +42 -0
- package/core/class/contract/GapContract.ts +457 -0
- package/core/class/entities/Community.ts +148 -0
- package/core/class/entities/ContributorProfile.ts +108 -0
- package/core/class/entities/Grant.ts +321 -0
- package/core/class/entities/GrantUpdate.ts +187 -0
- package/core/class/entities/MemberOf.ts +52 -0
- package/core/class/entities/Milestone.ts +898 -0
- package/core/class/entities/Project.ts +672 -0
- package/core/class/entities/ProjectImpact.ts +170 -0
- package/core/class/entities/ProjectMilestone.ts +254 -0
- package/core/class/entities/ProjectPointer.ts +39 -0
- package/core/class/entities/ProjectUpdate.ts +176 -0
- package/core/class/entities/Track.ts +32 -0
- package/core/class/karma-indexer/GapIndexerClient.ts +383 -0
- package/core/class/karma-indexer/api/GapIndexerApi.ts +446 -0
- package/core/class/karma-indexer/api/types.ts +313 -0
- package/core/class/remote-storage/IpfsStorage.ts +76 -0
- package/core/class/remote-storage/RemoteStorage.ts +65 -0
- package/core/class/types/allo.ts +93 -0
- package/core/class/types/attestations.ts +223 -0
- package/core/consts.ts +775 -0
- package/core/scripts/create-grant.ts +102 -0
- package/core/scripts/create-program.ts +43 -0
- package/core/scripts/create-schemas.ts +65 -0
- package/core/scripts/deploy.ts +65 -0
- package/core/scripts/index.ts +1 -0
- package/core/scripts/milestone-multi-grants.ts +125 -0
- package/core/shared/types.ts +13 -0
- package/core/types.ts +224 -0
- package/core/utils/gelato/send-gelato-txn.ts +114 -0
- package/core/utils/gelato/sponsor-handler.ts +77 -0
- package/core/utils/gelato/watch-gelato-txn.ts +67 -0
- package/core/utils/get-date.ts +3 -0
- package/core/utils/get-ipfs-data.ts +13 -0
- package/core/utils/get-web3-provider.ts +18 -0
- package/core/utils/gql-queries.ts +133 -0
- package/core/utils/map-filter.ts +21 -0
- package/core/utils/serialize-bigint.ts +7 -0
- package/core/utils/to-unix.ts +18 -0
- package/create-community-example.ts +119 -0
- package/csv-upload/README.md +74 -0
- package/csv-upload/config.ts +41 -0
- package/csv-upload/example.csv +2 -0
- package/csv-upload/keys.example.json +8 -0
- package/csv-upload/scripts/run.ts +417 -0
- package/csv-upload/types.ts +39 -0
- package/docs/.gitkeep +0 -0
- package/docs/images/attestation-architecture.png +0 -0
- package/docs/images/dfd-get-projects.png +0 -0
- package/gap-schema.yaml +155 -0
- package/milestone-workflow-example.ts +353 -0
- package/package.json +45 -39
- package/readme.md +872 -0
- package/schemas/.gitkeep +0 -0
- package/schemas/GAP-schemas-1692135812877.json +33 -0
- package/test-file-indexer-api.ts +25 -0
- package/tsconfig.json +26 -0
- package/core/abi/index.d.ts +0 -1114
- package/core/abi/index.js +0 -26
- package/core/class/AllGapSchemas.d.ts +0 -9
- package/core/class/AllGapSchemas.js +0 -19
- package/core/class/Attestation.d.ts +0 -173
- package/core/class/Attestation.js +0 -333
- package/core/class/Fetcher.d.ts +0 -175
- package/core/class/Fetcher.js +0 -13
- package/core/class/GAP.d.ts +0 -254
- package/core/class/GAP.js +0 -289
- package/core/class/GapSchema.d.ts +0 -34
- package/core/class/GapSchema.js +0 -62
- package/core/class/GrantProgramRegistry/Allo.d.ts +0 -17
- package/core/class/GrantProgramRegistry/Allo.js +0 -137
- package/core/class/GrantProgramRegistry/AlloRegistry.d.ts +0 -15
- package/core/class/GrantProgramRegistry/AlloRegistry.js +0 -70
- package/core/class/GraphQL/AxiosGQL.d.ts +0 -6
- package/core/class/GraphQL/AxiosGQL.js +0 -25
- package/core/class/GraphQL/EASClient.d.ts +0 -16
- package/core/class/GraphQL/EASClient.js +0 -26
- package/core/class/GraphQL/GapEasClient.d.ts +0 -71
- package/core/class/GraphQL/GapEasClient.js +0 -451
- package/core/class/GraphQL/index.js +0 -19
- package/core/class/Schema.d.ts +0 -233
- package/core/class/Schema.js +0 -488
- package/core/class/SchemaError.d.ts +0 -30
- package/core/class/SchemaError.js +0 -39
- package/core/class/contract/GapContract.d.ts +0 -102
- package/core/class/contract/GapContract.js +0 -285
- package/core/class/entities/Community.d.ts +0 -34
- package/core/class/entities/Community.js +0 -109
- package/core/class/entities/ContributorProfile.d.ts +0 -41
- package/core/class/entities/ContributorProfile.js +0 -69
- package/core/class/entities/Grant.d.ts +0 -54
- package/core/class/entities/Grant.js +0 -223
- package/core/class/entities/GrantUpdate.d.ts +0 -40
- package/core/class/entities/GrantUpdate.js +0 -114
- package/core/class/entities/MemberOf.d.ts +0 -11
- package/core/class/entities/MemberOf.js +0 -33
- package/core/class/entities/Milestone.d.ts +0 -168
- package/core/class/entities/Milestone.js +0 -657
- package/core/class/entities/Project.d.ts +0 -92
- package/core/class/entities/Project.js +0 -418
- package/core/class/entities/ProjectImpact.d.ts +0 -50
- package/core/class/entities/ProjectImpact.js +0 -112
- package/core/class/entities/ProjectMilestone.d.ts +0 -60
- package/core/class/entities/ProjectMilestone.js +0 -174
- package/core/class/entities/ProjectPointer.d.ts +0 -12
- package/core/class/entities/ProjectPointer.js +0 -22
- package/core/class/entities/ProjectUpdate.d.ts +0 -50
- package/core/class/entities/ProjectUpdate.js +0 -110
- package/core/class/entities/Track.d.ts +0 -16
- package/core/class/entities/Track.js +0 -21
- package/core/class/entities/index.js +0 -26
- package/core/class/index.js +0 -26
- package/core/class/karma-indexer/GapIndexerClient.d.ts +0 -66
- package/core/class/karma-indexer/GapIndexerClient.js +0 -207
- package/core/class/karma-indexer/api/GapIndexerApi.d.ts +0 -73
- package/core/class/karma-indexer/api/GapIndexerApi.js +0 -256
- package/core/class/karma-indexer/api/types.d.ts +0 -295
- package/core/class/karma-indexer/api/types.js +0 -2
- package/core/class/remote-storage/IpfsStorage.d.ts +0 -23
- package/core/class/remote-storage/IpfsStorage.js +0 -56
- package/core/class/remote-storage/RemoteStorage.d.ts +0 -41
- package/core/class/remote-storage/RemoteStorage.js +0 -38
- package/core/class/types/allo.d.ts +0 -78
- package/core/class/types/allo.js +0 -2
- package/core/class/types/attestations.d.ts +0 -168
- package/core/class/types/attestations.js +0 -66
- package/core/consts.d.ts +0 -48
- package/core/consts.js +0 -641
- package/core/index.js +0 -24
- package/core/shared/types.d.ts +0 -6
- package/core/shared/types.js +0 -2
- package/core/types.d.ts +0 -131
- package/core/types.js +0 -13
- package/core/utils/gelato/index.js +0 -19
- package/core/utils/gelato/send-gelato-txn.d.ts +0 -55
- package/core/utils/gelato/send-gelato-txn.js +0 -100
- package/core/utils/gelato/sponsor-handler.d.ts +0 -9
- package/core/utils/gelato/sponsor-handler.js +0 -60
- package/core/utils/gelato/watch-gelato-txn.d.ts +0 -7
- package/core/utils/gelato/watch-gelato-txn.js +0 -63
- package/core/utils/get-date.d.ts +0 -1
- package/core/utils/get-date.js +0 -7
- package/core/utils/get-ipfs-data.d.ts +0 -1
- package/core/utils/get-ipfs-data.js +0 -20
- package/core/utils/get-web3-provider.d.ts +0 -2
- package/core/utils/get-web3-provider.js +0 -18
- package/core/utils/gql-queries.d.ts +0 -12
- package/core/utils/gql-queries.js +0 -90
- package/core/utils/index.js +0 -23
- package/core/utils/map-filter.d.ts +0 -8
- package/core/utils/map-filter.js +0 -20
- package/core/utils/serialize-bigint.d.ts +0 -1
- package/core/utils/serialize-bigint.js +0 -8
- package/core/utils/to-unix.d.ts +0 -1
- package/core/utils/to-unix.js +0 -25
- package/index.js +0 -17
- /package/core/class/GraphQL/{index.d.ts → index.ts} +0 -0
- /package/core/class/entities/{index.d.ts → index.ts} +0 -0
- /package/core/class/{index.d.ts → index.ts} +0 -0
- /package/core/{index.d.ts → index.ts} +0 -0
- /package/core/utils/gelato/{index.d.ts → index.ts} +0 -0
- /package/core/utils/{index.d.ts → index.ts} +0 -0
- /package/{core/class/Gelato/Gelato.d.ts → csv-upload/.gitkeep} +0 -0
- /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
|
+
}
|