@show-karma/karma-gap-sdk 0.1.29
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/core/abi/MultiAttester.json +676 -0
- package/core/class/Attestation.d.ts +169 -0
- package/core/class/Attestation.js +311 -0
- package/core/class/Fetcher.d.ts +132 -0
- package/core/class/Fetcher.js +7 -0
- package/core/class/GAP.d.ts +212 -0
- package/core/class/GAP.js +206 -0
- package/core/class/GapSchema.d.ts +33 -0
- package/core/class/GapSchema.js +61 -0
- package/core/class/Gelato/Gelato.d.ts +0 -0
- package/core/class/Gelato/Gelato.js +263 -0
- package/core/class/GraphQL/AxiosGQL.d.ts +6 -0
- package/core/class/GraphQL/AxiosGQL.js +25 -0
- package/core/class/GraphQL/EASClient.d.ts +16 -0
- package/core/class/GraphQL/EASClient.js +26 -0
- package/core/class/GraphQL/Fetcher.d.ts +132 -0
- package/core/class/GraphQL/Fetcher.js +7 -0
- package/core/class/GraphQL/GAPFetcher.d.ts +160 -0
- package/core/class/GraphQL/GAPFetcher.js +516 -0
- package/core/class/GraphQL/GapEasClient.d.ts +63 -0
- package/core/class/GraphQL/GapEasClient.js +420 -0
- package/core/class/GraphQL/index.d.ts +3 -0
- package/core/class/GraphQL/index.js +19 -0
- package/core/class/Schema.d.ts +213 -0
- package/core/class/Schema.js +434 -0
- package/core/class/SchemaError.d.ts +26 -0
- package/core/class/SchemaError.js +34 -0
- package/core/class/contract/GapContract.d.ts +55 -0
- package/core/class/contract/GapContract.js +176 -0
- package/core/class/contract/MultiAttest.d.ts +10 -0
- package/core/class/contract/MultiAttest.js +19 -0
- package/core/class/entities/Community.d.ts +36 -0
- package/core/class/entities/Community.js +88 -0
- package/core/class/entities/Grant.d.ts +53 -0
- package/core/class/entities/Grant.js +194 -0
- package/core/class/entities/MemberOf.d.ts +11 -0
- package/core/class/entities/MemberOf.js +31 -0
- package/core/class/entities/Milestone.d.ts +63 -0
- package/core/class/entities/Milestone.js +171 -0
- package/core/class/entities/Project.d.ts +73 -0
- package/core/class/entities/Project.js +243 -0
- package/core/class/entities/index.d.ts +5 -0
- package/core/class/entities/index.js +21 -0
- package/core/class/index.d.ts +7 -0
- package/core/class/index.js +23 -0
- package/core/class/karma-indexer/GapIndexerClient.d.ts +28 -0
- package/core/class/karma-indexer/GapIndexerClient.js +137 -0
- package/core/class/types/attestations.d.ts +108 -0
- package/core/class/types/attestations.js +55 -0
- package/core/consts.d.ts +19 -0
- package/core/consts.js +228 -0
- package/core/index.d.ts +7 -0
- package/core/index.js +23 -0
- package/core/types.d.ts +107 -0
- package/core/types.js +13 -0
- package/core/utils/gelato/index.d.ts +3 -0
- package/core/utils/gelato/index.js +19 -0
- package/core/utils/gelato/send-gelato-txn.d.ts +54 -0
- package/core/utils/gelato/send-gelato-txn.js +99 -0
- package/core/utils/gelato/sponsor-handler.d.ts +9 -0
- package/core/utils/gelato/sponsor-handler.js +60 -0
- package/core/utils/gelato/watch-gelato-txn.d.ts +7 -0
- package/core/utils/gelato/watch-gelato-txn.js +55 -0
- package/core/utils/get-date.d.ts +1 -0
- package/core/utils/get-date.js +7 -0
- package/core/utils/gql-queries.d.ts +12 -0
- package/core/utils/gql-queries.js +90 -0
- package/core/utils/index.d.ts +6 -0
- package/core/utils/index.js +22 -0
- package/core/utils/map-filter.d.ts +8 -0
- package/core/utils/map-filter.js +20 -0
- package/core/utils/serialize-bigint.d.ts +1 -0
- package/core/utils/serialize-bigint.js +8 -0
- package/core/utils/to-unix.d.ts +1 -0
- package/core/utils/to-unix.js +25 -0
- package/index.d.ts +1 -0
- package/index.js +17 -0
- package/package.json +37 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GapContract = void 0;
|
|
4
|
+
const GAP_1 = require("../GAP");
|
|
5
|
+
const serialize_bigint_1 = require("../../utils/serialize-bigint");
|
|
6
|
+
const send_gelato_txn_1 = require("../../utils/gelato/send-gelato-txn");
|
|
7
|
+
const eas_sdk_1 = require("@ethereum-attestation-service/eas-sdk");
|
|
8
|
+
const AttestationDataTypes = {
|
|
9
|
+
Attest: [
|
|
10
|
+
{ name: 'payloadHash', type: 'string' },
|
|
11
|
+
{ name: 'nonce', type: 'uint256' },
|
|
12
|
+
{ name: 'expiry', type: 'uint256' },
|
|
13
|
+
],
|
|
14
|
+
};
|
|
15
|
+
class GapContract {
|
|
16
|
+
/**
|
|
17
|
+
* Signs a message for the delegated attestation.
|
|
18
|
+
* @param signer
|
|
19
|
+
* @param payload
|
|
20
|
+
* @returns r,s,v signature
|
|
21
|
+
*/
|
|
22
|
+
static async signAttestation(signer, payload, expiry) {
|
|
23
|
+
let { nonce } = await this.getNonce(signer);
|
|
24
|
+
const { chainId } = await signer.provider.getNetwork();
|
|
25
|
+
const domain = {
|
|
26
|
+
chainId,
|
|
27
|
+
name: 'gap-attestation',
|
|
28
|
+
version: '1',
|
|
29
|
+
verifyingContract: GAP_1.GAP.getMulticall(null).address,
|
|
30
|
+
};
|
|
31
|
+
const data = { payloadHash: payload, nonce, expiry };
|
|
32
|
+
console.log({ domain, AttestationDataTypes, data });
|
|
33
|
+
const signature = await signer._signTypedData(domain, AttestationDataTypes, data);
|
|
34
|
+
const { r, s, v } = this.getRSV(signature);
|
|
35
|
+
return { r, s, v, nonce, chainId };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Returns the r, s, v values of a signature
|
|
39
|
+
* @param signature
|
|
40
|
+
* @returns
|
|
41
|
+
*/
|
|
42
|
+
static getRSV(signature) {
|
|
43
|
+
const r = signature.slice(0, 66);
|
|
44
|
+
const s = `0x${signature.slice(66, 130)}`;
|
|
45
|
+
const v = `0x${signature.slice(130, 132)}`;
|
|
46
|
+
return { r, s, v };
|
|
47
|
+
}
|
|
48
|
+
static async getSignerAddress(signer) {
|
|
49
|
+
const address = signer.address || signer._address || (await signer.getAddress());
|
|
50
|
+
if (!address)
|
|
51
|
+
throw new Error('Signer does not provider either address or getAddress().');
|
|
52
|
+
return address;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get nonce for the transaction
|
|
56
|
+
* @param address
|
|
57
|
+
* @returns
|
|
58
|
+
*/
|
|
59
|
+
static async getNonce(signer) {
|
|
60
|
+
const contract = GAP_1.GAP.getMulticall(signer);
|
|
61
|
+
const address = await this.getSignerAddress(signer);
|
|
62
|
+
console.log({ address });
|
|
63
|
+
const nonce = await contract.functions.nonces(address);
|
|
64
|
+
return {
|
|
65
|
+
nonce: Number(nonce),
|
|
66
|
+
next: Number(nonce + 1n),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Send a single attestation
|
|
71
|
+
* @param signer
|
|
72
|
+
* @param payload
|
|
73
|
+
* @returns
|
|
74
|
+
*/
|
|
75
|
+
static async attest(signer, payload) {
|
|
76
|
+
const contract = GAP_1.GAP.getMulticall(signer);
|
|
77
|
+
if (GAP_1.GAP.gelatoOpts?.useGasless) {
|
|
78
|
+
return this.attestBySig(signer, payload);
|
|
79
|
+
}
|
|
80
|
+
const tx = await contract.functions.attest({
|
|
81
|
+
schema: payload.schema,
|
|
82
|
+
data: payload.data.payload,
|
|
83
|
+
});
|
|
84
|
+
const result = await tx.wait?.();
|
|
85
|
+
const attestations = (0, eas_sdk_1.getUIDsFromAttestReceipt)(result)[0];
|
|
86
|
+
return attestations;
|
|
87
|
+
}
|
|
88
|
+
static async attestBySig(signer, payload) {
|
|
89
|
+
const contract = GAP_1.GAP.getMulticall(signer);
|
|
90
|
+
const expiry = BigInt(Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30);
|
|
91
|
+
const address = await this.getSignerAddress(signer);
|
|
92
|
+
const payloadHash = (0, serialize_bigint_1.serializeWithBigint)({
|
|
93
|
+
schema: payload.schema,
|
|
94
|
+
data: payload.data.raw,
|
|
95
|
+
});
|
|
96
|
+
const { r, s, v, nonce, chainId } = await this.signAttestation(signer, payloadHash, expiry);
|
|
97
|
+
const { data: populatedTxn } = await contract.populateTransaction.attestBySig({
|
|
98
|
+
data: payload.data.payload,
|
|
99
|
+
schema: payload.schema,
|
|
100
|
+
}, payloadHash, address, nonce, expiry, v, r, s);
|
|
101
|
+
if (!populatedTxn)
|
|
102
|
+
throw new Error('Transaction data is empty');
|
|
103
|
+
const txn = await (0, send_gelato_txn_1.sendGelatoTxn)(...send_gelato_txn_1.Gelato.buildArgs(populatedTxn, chainId, contract.address));
|
|
104
|
+
const attestations = await this.getTransactionLogs(signer, txn);
|
|
105
|
+
return attestations[0];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Performs a referenced multi attestation.
|
|
109
|
+
*
|
|
110
|
+
* @returns an array with the attestation UIDs.
|
|
111
|
+
*/
|
|
112
|
+
static async multiAttest(signer, payload) {
|
|
113
|
+
const contract = GAP_1.GAP.getMulticall(signer);
|
|
114
|
+
if (GAP_1.GAP.gelatoOpts?.useGasless) {
|
|
115
|
+
return this.multiAttestBySig(signer, payload);
|
|
116
|
+
}
|
|
117
|
+
const tx = await contract.functions.multiSequentialAttest(payload.map((p) => p.payload));
|
|
118
|
+
const result = await tx.wait?.();
|
|
119
|
+
const attestations = (0, eas_sdk_1.getUIDsFromAttestReceipt)(result);
|
|
120
|
+
return attestations;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Performs a referenced multi attestation.
|
|
124
|
+
*
|
|
125
|
+
* @returns an array with the attestation UIDs.
|
|
126
|
+
*/
|
|
127
|
+
static async multiAttestBySig(signer, payload) {
|
|
128
|
+
const contract = GAP_1.GAP.getMulticall(signer);
|
|
129
|
+
const expiry = BigInt(Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30);
|
|
130
|
+
const address = await this.getSignerAddress(signer);
|
|
131
|
+
const payloadHash = (0, serialize_bigint_1.serializeWithBigint)(payload.map((p) => p.raw));
|
|
132
|
+
const { r, s, v, nonce, chainId } = await this.signAttestation(signer, payloadHash, expiry);
|
|
133
|
+
console.info({ r, s, v, nonce, chainId, payloadHash, address });
|
|
134
|
+
const { data: populatedTxn } = await contract.populateTransaction.multiSequentialAttestBySig(payload.map((p) => p.payload), payloadHash, address, nonce, expiry, v, r, s);
|
|
135
|
+
if (!populatedTxn)
|
|
136
|
+
throw new Error('Transaction data is empty');
|
|
137
|
+
const txn = await (0, send_gelato_txn_1.sendGelatoTxn)(...send_gelato_txn_1.Gelato.buildArgs(populatedTxn, chainId, contract.address));
|
|
138
|
+
const attestations = await this.getTransactionLogs(signer, txn);
|
|
139
|
+
return attestations;
|
|
140
|
+
}
|
|
141
|
+
static async multiRevoke(signer, payload) {
|
|
142
|
+
const contract = GAP_1.GAP.getMulticall(signer);
|
|
143
|
+
if (GAP_1.GAP.gelatoOpts?.useGasless) {
|
|
144
|
+
return this.multiRevokeBySig(signer, payload);
|
|
145
|
+
}
|
|
146
|
+
const tx = await contract.functions.multiRevoke(payload);
|
|
147
|
+
return tx.wait?.();
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Performs a referenced multi attestation.
|
|
151
|
+
*
|
|
152
|
+
* @returns an array with the attestation UIDs.
|
|
153
|
+
*/
|
|
154
|
+
static async multiRevokeBySig(signer, payload) {
|
|
155
|
+
const contract = GAP_1.GAP.getMulticall(signer);
|
|
156
|
+
const expiry = BigInt(Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30);
|
|
157
|
+
const address = await this.getSignerAddress(signer);
|
|
158
|
+
const payloadHash = (0, serialize_bigint_1.serializeWithBigint)(payload);
|
|
159
|
+
const { r, s, v, nonce, chainId } = await this.signAttestation(signer, payloadHash, expiry);
|
|
160
|
+
console.info({ r, s, v, nonce, chainId, payloadHash, address });
|
|
161
|
+
const { data: populatedTxn } = await contract.populateTransaction.multiRevokeBySig(payload, payloadHash, address, nonce, expiry, v, r, s);
|
|
162
|
+
if (!populatedTxn)
|
|
163
|
+
throw new Error('Transaction data is empty');
|
|
164
|
+
await (0, send_gelato_txn_1.sendGelatoTxn)(...send_gelato_txn_1.Gelato.buildArgs(populatedTxn, chainId, contract.address));
|
|
165
|
+
}
|
|
166
|
+
static async getTransactionLogs(signer, txnHash) {
|
|
167
|
+
const txn = await signer.provider.getTransactionReceipt(txnHash);
|
|
168
|
+
if (!txn || !txn.logs.length)
|
|
169
|
+
throw new Error('Transaction not found');
|
|
170
|
+
// Returns the txn logs with the attestation results. Tha last two logs are the
|
|
171
|
+
// the ones from the GelatoRelay contract.
|
|
172
|
+
return (0, eas_sdk_1.getUIDsFromAttestReceipt)(txn);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.GapContract = GapContract;
|
|
176
|
+
GapContract.nonces = {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SignerOrProvider } from "@ethereum-attestation-service/eas-sdk/dist/transaction";
|
|
2
|
+
import { Hex, MultiAttestData } from "core/types";
|
|
3
|
+
export declare class MultiAttest {
|
|
4
|
+
/**
|
|
5
|
+
* Performs a referenced multi attestation.
|
|
6
|
+
*
|
|
7
|
+
* @returns an array with the attestation UIDs.
|
|
8
|
+
*/
|
|
9
|
+
static send(signer: SignerOrProvider, payload: MultiAttestData[]): Promise<Hex[]>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MultiAttest = void 0;
|
|
4
|
+
const GAP_1 = require("../GAP");
|
|
5
|
+
class MultiAttest {
|
|
6
|
+
/**
|
|
7
|
+
* Performs a referenced multi attestation.
|
|
8
|
+
*
|
|
9
|
+
* @returns an array with the attestation UIDs.
|
|
10
|
+
*/
|
|
11
|
+
static async send(signer, payload) {
|
|
12
|
+
const contract = GAP_1.GAP.getMulticall(signer);
|
|
13
|
+
const tx = await contract.functions.multiSequentialAttest(payload);
|
|
14
|
+
const result = await tx.wait?.();
|
|
15
|
+
const attestations = result.logs?.map((m) => m.data);
|
|
16
|
+
return attestations;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.MultiAttest = MultiAttest;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Attestation } from "../Attestation";
|
|
2
|
+
import { CommunityDetails, ICommunityDetails } from "../types/attestations";
|
|
3
|
+
import { Project } from "./Project";
|
|
4
|
+
import { MultiAttestPayload, SignerOrProvider } from "core/types";
|
|
5
|
+
import { Grant } from "./Grant";
|
|
6
|
+
interface _Community extends Community {
|
|
7
|
+
}
|
|
8
|
+
export interface ICommunity {
|
|
9
|
+
community: true;
|
|
10
|
+
}
|
|
11
|
+
export declare class Community extends Attestation<ICommunity> {
|
|
12
|
+
projects: Project[];
|
|
13
|
+
grants: Grant[];
|
|
14
|
+
details?: CommunityDetails;
|
|
15
|
+
/**
|
|
16
|
+
* Creates the payload for a multi-attestation.
|
|
17
|
+
*
|
|
18
|
+
* > if Current payload is set, it'll be used as the base payload
|
|
19
|
+
* and the project should refer to an index of the current payload,
|
|
20
|
+
* usually the community position.
|
|
21
|
+
*
|
|
22
|
+
* @param payload
|
|
23
|
+
* @param refIdx
|
|
24
|
+
*/
|
|
25
|
+
multiAttestPayload(): MultiAttestPayload;
|
|
26
|
+
/**
|
|
27
|
+
* Attest a community with its details.
|
|
28
|
+
*
|
|
29
|
+
* If the community exists, it will not be revoked but its details will be updated.
|
|
30
|
+
* @param signer
|
|
31
|
+
* @param details
|
|
32
|
+
*/
|
|
33
|
+
attest(signer: SignerOrProvider, details?: ICommunityDetails): Promise<void>;
|
|
34
|
+
static from(attestations: _Community[]): Community[];
|
|
35
|
+
}
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Community = void 0;
|
|
4
|
+
const Attestation_1 = require("../Attestation");
|
|
5
|
+
const attestations_1 = require("../types/attestations");
|
|
6
|
+
const consts_1 = require("../../consts");
|
|
7
|
+
const SchemaError_1 = require("../SchemaError");
|
|
8
|
+
const GapSchema_1 = require("../GapSchema");
|
|
9
|
+
const Grant_1 = require("./Grant");
|
|
10
|
+
class Community extends Attestation_1.Attestation {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.projects = [];
|
|
14
|
+
this.grants = [];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Creates the payload for a multi-attestation.
|
|
18
|
+
*
|
|
19
|
+
* > if Current payload is set, it'll be used as the base payload
|
|
20
|
+
* and the project should refer to an index of the current payload,
|
|
21
|
+
* usually the community position.
|
|
22
|
+
*
|
|
23
|
+
* @param payload
|
|
24
|
+
* @param refIdx
|
|
25
|
+
*/
|
|
26
|
+
multiAttestPayload() {
|
|
27
|
+
const payload = [[this, this.payloadFor(0)]];
|
|
28
|
+
if (this.details) {
|
|
29
|
+
payload.push([this.details, this.details.payloadFor(0)]);
|
|
30
|
+
}
|
|
31
|
+
if (this.projects?.length) {
|
|
32
|
+
this.projects.forEach((p) => {
|
|
33
|
+
payload.push(...p.multiAttestPayload(payload, 0));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return payload;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Attest a community with its details.
|
|
40
|
+
*
|
|
41
|
+
* If the community exists, it will not be revoked but its details will be updated.
|
|
42
|
+
* @param signer
|
|
43
|
+
* @param details
|
|
44
|
+
*/
|
|
45
|
+
async attest(signer, details) {
|
|
46
|
+
console.log("Attesting community");
|
|
47
|
+
try {
|
|
48
|
+
this._uid = await this.schema.attest({
|
|
49
|
+
signer,
|
|
50
|
+
to: this.recipient,
|
|
51
|
+
refUID: consts_1.nullRef,
|
|
52
|
+
data: this.data,
|
|
53
|
+
});
|
|
54
|
+
console.log(this.uid);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error(error);
|
|
58
|
+
throw new SchemaError_1.AttestationError("ATTEST_ERROR", "Error during attestation.");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
static from(attestations) {
|
|
62
|
+
return attestations.map((attestation) => {
|
|
63
|
+
const community = new Community({
|
|
64
|
+
...attestation,
|
|
65
|
+
data: {
|
|
66
|
+
community: true,
|
|
67
|
+
},
|
|
68
|
+
schema: GapSchema_1.GapSchema.find("Community"),
|
|
69
|
+
});
|
|
70
|
+
if (attestation.details) {
|
|
71
|
+
const { details } = attestation;
|
|
72
|
+
community.details = new attestations_1.CommunityDetails({
|
|
73
|
+
...details,
|
|
74
|
+
data: {
|
|
75
|
+
...details.data,
|
|
76
|
+
},
|
|
77
|
+
schema: GapSchema_1.GapSchema.find("CommunityDetails"),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (attestation.grants) {
|
|
81
|
+
const { grants } = attestation;
|
|
82
|
+
community.grants = Grant_1.Grant.from(grants);
|
|
83
|
+
}
|
|
84
|
+
return community;
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.Community = Community;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Attestation } from '../Attestation';
|
|
2
|
+
import { GrantDetails, GrantRound, GrantUpdate, IGrantUpdate, GrantCompleted } from '../types/attestations';
|
|
3
|
+
import { IMilestone, Milestone } from './Milestone';
|
|
4
|
+
import { GapSchema } from '../GapSchema';
|
|
5
|
+
import { Hex, MultiAttestPayload, SignerOrProvider } from 'core/types';
|
|
6
|
+
import { Community } from './Community';
|
|
7
|
+
import { Project } from './Project';
|
|
8
|
+
interface _Grant extends Grant {
|
|
9
|
+
}
|
|
10
|
+
export interface IGrant {
|
|
11
|
+
communityUID: Hex;
|
|
12
|
+
}
|
|
13
|
+
export declare class Grant extends Attestation<IGrant> {
|
|
14
|
+
details?: GrantDetails;
|
|
15
|
+
communityUID: Hex;
|
|
16
|
+
verified?: boolean;
|
|
17
|
+
round?: GrantRound;
|
|
18
|
+
milestones: Milestone[];
|
|
19
|
+
community: Community;
|
|
20
|
+
updates: GrantUpdate[];
|
|
21
|
+
completed?: GrantCompleted;
|
|
22
|
+
project?: Project;
|
|
23
|
+
verify(signer: SignerOrProvider): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Add milestones to the grant.
|
|
26
|
+
* @param signer
|
|
27
|
+
* @param milestones
|
|
28
|
+
*/
|
|
29
|
+
addMilestones(milestones: IMilestone[]): void;
|
|
30
|
+
/**
|
|
31
|
+
* Creates the payload for a multi-attestation.
|
|
32
|
+
*
|
|
33
|
+
* > if Current payload is set, it'll be used as the base payload
|
|
34
|
+
* and the project should refer to an index of the current payload,
|
|
35
|
+
* usually the community position.
|
|
36
|
+
*
|
|
37
|
+
* @param payload
|
|
38
|
+
* @param projectIdx
|
|
39
|
+
*/
|
|
40
|
+
multiAttestPayload(currentPayload?: MultiAttestPayload, projectIdx?: number): [Attestation<unknown, GapSchema>, import("core/types").RawMultiAttestPayload][];
|
|
41
|
+
/**
|
|
42
|
+
* @inheritdoc
|
|
43
|
+
*/
|
|
44
|
+
attest(signer: SignerOrProvider): Promise<void>;
|
|
45
|
+
attestUpdate(signer: SignerOrProvider, data: IGrantUpdate): Promise<void>;
|
|
46
|
+
complete(signer: SignerOrProvider, data: IGrantUpdate): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Validate if the grant has a valid reference to a community.
|
|
49
|
+
*/
|
|
50
|
+
protected assertPayload(): boolean;
|
|
51
|
+
static from(attestations: _Grant[]): Grant[];
|
|
52
|
+
}
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Grant = void 0;
|
|
4
|
+
const Attestation_1 = require("../Attestation");
|
|
5
|
+
const attestations_1 = require("../types/attestations");
|
|
6
|
+
const Milestone_1 = require("./Milestone");
|
|
7
|
+
const GapSchema_1 = require("../GapSchema");
|
|
8
|
+
const GAP_1 = require("../GAP");
|
|
9
|
+
const SchemaError_1 = require("../SchemaError");
|
|
10
|
+
const consts_1 = require("../../consts");
|
|
11
|
+
const GapContract_1 = require("../contract/GapContract");
|
|
12
|
+
const Community_1 = require("./Community");
|
|
13
|
+
const Project_1 = require("./Project");
|
|
14
|
+
class Grant extends Attestation_1.Attestation {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(...arguments);
|
|
17
|
+
this.verified = false;
|
|
18
|
+
this.milestones = [];
|
|
19
|
+
this.updates = [];
|
|
20
|
+
}
|
|
21
|
+
async verify(signer) {
|
|
22
|
+
const eas = GAP_1.GAP.eas.connect(signer);
|
|
23
|
+
const schema = GapSchema_1.GapSchema.find('MilestoneApproved');
|
|
24
|
+
schema.setValue('approved', true);
|
|
25
|
+
try {
|
|
26
|
+
await eas.attest({
|
|
27
|
+
schema: schema.raw,
|
|
28
|
+
data: {
|
|
29
|
+
recipient: this.recipient,
|
|
30
|
+
data: schema.encode(),
|
|
31
|
+
refUID: this.uid,
|
|
32
|
+
expirationTime: 0n,
|
|
33
|
+
revocable: schema.revocable,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
this.verified = true;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
console.error(error);
|
|
40
|
+
throw new SchemaError_1.AttestationError('ATTEST_ERROR', error.message);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Add milestones to the grant.
|
|
45
|
+
* @param signer
|
|
46
|
+
* @param milestones
|
|
47
|
+
*/
|
|
48
|
+
addMilestones(milestones) {
|
|
49
|
+
const schema = GapSchema_1.GapSchema.find('Milestone');
|
|
50
|
+
const newMilestones = milestones.map((milestone) => {
|
|
51
|
+
const m = new Milestone_1.Milestone({
|
|
52
|
+
data: milestone,
|
|
53
|
+
refUID: this.uid,
|
|
54
|
+
schema,
|
|
55
|
+
createdAt: Date.now(),
|
|
56
|
+
recipient: this.recipient,
|
|
57
|
+
uid: consts_1.nullRef,
|
|
58
|
+
});
|
|
59
|
+
return m;
|
|
60
|
+
});
|
|
61
|
+
this.milestones.push(...newMilestones);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Creates the payload for a multi-attestation.
|
|
65
|
+
*
|
|
66
|
+
* > if Current payload is set, it'll be used as the base payload
|
|
67
|
+
* and the project should refer to an index of the current payload,
|
|
68
|
+
* usually the community position.
|
|
69
|
+
*
|
|
70
|
+
* @param payload
|
|
71
|
+
* @param projectIdx
|
|
72
|
+
*/
|
|
73
|
+
multiAttestPayload(currentPayload = [], projectIdx = 0) {
|
|
74
|
+
this.assertPayload();
|
|
75
|
+
const payload = [...currentPayload];
|
|
76
|
+
const grantIdx = payload.push([this, this.payloadFor(projectIdx)]) - 1;
|
|
77
|
+
if (this.details) {
|
|
78
|
+
payload.push([this.details, this.details.payloadFor(grantIdx)]);
|
|
79
|
+
}
|
|
80
|
+
if (this.milestones.length) {
|
|
81
|
+
this.milestones.forEach((m) => {
|
|
82
|
+
payload.push([m, m.payloadFor(grantIdx)]);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (this.updates.length) {
|
|
86
|
+
this.updates.forEach((u) => {
|
|
87
|
+
payload.push([u, u.payloadFor(grantIdx)]);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return payload.slice(currentPayload.length, payload.length);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* @inheritdoc
|
|
94
|
+
*/
|
|
95
|
+
async attest(signer) {
|
|
96
|
+
this.assertPayload();
|
|
97
|
+
const payload = this.multiAttestPayload();
|
|
98
|
+
const uids = await GapContract_1.GapContract.multiAttest(signer, payload.map((p) => p[1]));
|
|
99
|
+
uids.forEach((uid, index) => {
|
|
100
|
+
payload[index][0].uid = uid;
|
|
101
|
+
});
|
|
102
|
+
console.log(uids);
|
|
103
|
+
}
|
|
104
|
+
async attestUpdate(signer, data) {
|
|
105
|
+
const grantUpdate = new attestations_1.GrantUpdate({
|
|
106
|
+
data: {
|
|
107
|
+
...data,
|
|
108
|
+
type: 'grant-update',
|
|
109
|
+
},
|
|
110
|
+
recipient: this.recipient,
|
|
111
|
+
refUID: this.uid,
|
|
112
|
+
schema: GapSchema_1.GapSchema.find('GrantDetails'),
|
|
113
|
+
});
|
|
114
|
+
await grantUpdate.attest(signer);
|
|
115
|
+
this.updates.push(grantUpdate);
|
|
116
|
+
}
|
|
117
|
+
async complete(signer, data) {
|
|
118
|
+
const completed = new attestations_1.GrantCompleted({
|
|
119
|
+
data: {
|
|
120
|
+
...data,
|
|
121
|
+
type: 'grant-completed',
|
|
122
|
+
},
|
|
123
|
+
recipient: this.recipient,
|
|
124
|
+
refUID: this.uid,
|
|
125
|
+
schema: GapSchema_1.GapSchema.find('GrantDetails'),
|
|
126
|
+
});
|
|
127
|
+
await completed.attest(signer);
|
|
128
|
+
this.completed = completed;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Validate if the grant has a valid reference to a community.
|
|
132
|
+
*/
|
|
133
|
+
assertPayload() {
|
|
134
|
+
if (!this.details || !this.communityUID) {
|
|
135
|
+
throw new SchemaError_1.AttestationError('INVALID_REFERENCE', 'Grant should include a valid reference to a community on its details.');
|
|
136
|
+
}
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
static from(attestations) {
|
|
140
|
+
return attestations.map((attestation) => {
|
|
141
|
+
const grant = new Grant({
|
|
142
|
+
...attestation,
|
|
143
|
+
data: {
|
|
144
|
+
communityUID: attestation.data.communityUID,
|
|
145
|
+
},
|
|
146
|
+
schema: GapSchema_1.GapSchema.find('Grant'),
|
|
147
|
+
});
|
|
148
|
+
if (attestation.details) {
|
|
149
|
+
const { details } = attestation;
|
|
150
|
+
grant.details = new attestations_1.GrantDetails({
|
|
151
|
+
...details,
|
|
152
|
+
data: {
|
|
153
|
+
...details.data,
|
|
154
|
+
},
|
|
155
|
+
schema: GapSchema_1.GapSchema.find('GrantDetails'),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
if (attestation.milestones) {
|
|
159
|
+
const { milestones } = attestation;
|
|
160
|
+
grant.milestones = Milestone_1.Milestone.from(milestones);
|
|
161
|
+
}
|
|
162
|
+
if (attestation.updates) {
|
|
163
|
+
const { updates } = attestation;
|
|
164
|
+
grant.updates = updates.map((u) => new attestations_1.GrantUpdate({
|
|
165
|
+
...u,
|
|
166
|
+
data: {
|
|
167
|
+
...u.data,
|
|
168
|
+
},
|
|
169
|
+
schema: GapSchema_1.GapSchema.find('GrantDetails'),
|
|
170
|
+
}));
|
|
171
|
+
}
|
|
172
|
+
if (attestation.completed) {
|
|
173
|
+
const { completed } = attestation;
|
|
174
|
+
grant.completed = new attestations_1.GrantCompleted({
|
|
175
|
+
...completed,
|
|
176
|
+
data: {
|
|
177
|
+
...completed.data,
|
|
178
|
+
},
|
|
179
|
+
schema: GapSchema_1.GapSchema.find('GrantDetails'),
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
if (attestation.project) {
|
|
183
|
+
const { project } = attestation;
|
|
184
|
+
grant.project = Project_1.Project.from([project])[0];
|
|
185
|
+
}
|
|
186
|
+
if (attestation.community) {
|
|
187
|
+
const { community } = attestation;
|
|
188
|
+
grant.community = Community_1.Community.from([community])[0];
|
|
189
|
+
}
|
|
190
|
+
return grant;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
exports.Grant = Grant;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MultiAttestPayload, SignerOrProvider } from "core/types";
|
|
2
|
+
import { Attestation } from "../Attestation";
|
|
3
|
+
import { MemberDetails } from "../types/attestations";
|
|
4
|
+
export interface IMemberOf {
|
|
5
|
+
memberOf: true;
|
|
6
|
+
}
|
|
7
|
+
export declare class MemberOf extends Attestation<IMemberOf> {
|
|
8
|
+
details?: MemberDetails;
|
|
9
|
+
multiAttestPayload(currentPayload?: MultiAttestPayload, projectIdx?: number): [Attestation<unknown, import("..").GapSchema>, import("core/types").RawMultiAttestPayload][];
|
|
10
|
+
attest(signer: SignerOrProvider): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MemberOf = void 0;
|
|
4
|
+
const Attestation_1 = require("../Attestation");
|
|
5
|
+
const SchemaError_1 = require("../SchemaError");
|
|
6
|
+
const GapContract_1 = require("../contract/GapContract");
|
|
7
|
+
class MemberOf extends Attestation_1.Attestation {
|
|
8
|
+
multiAttestPayload(currentPayload = [], projectIdx = 0) {
|
|
9
|
+
const payload = [...currentPayload];
|
|
10
|
+
const memberIdx = payload.push([this, this.payloadFor(projectIdx)]) - 1;
|
|
11
|
+
if (this.details) {
|
|
12
|
+
payload.push([this.details, this.details.payloadFor(memberIdx)]);
|
|
13
|
+
}
|
|
14
|
+
return payload.slice(currentPayload.length, payload.length);
|
|
15
|
+
}
|
|
16
|
+
async attest(signer) {
|
|
17
|
+
const payload = this.multiAttestPayload();
|
|
18
|
+
try {
|
|
19
|
+
const [memberUID, detailsUID] = await GapContract_1.GapContract.multiAttest(signer, payload.map((p) => p[1]));
|
|
20
|
+
this.uid = memberUID;
|
|
21
|
+
if (this.details && detailsUID) {
|
|
22
|
+
this.details.uid = detailsUID;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
console.error(error);
|
|
27
|
+
throw new SchemaError_1.AttestationError("ATTEST_ERROR", error.message);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.MemberOf = MemberOf;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { SignerOrProvider } from "../../types";
|
|
2
|
+
import { Attestation } from "../Attestation";
|
|
3
|
+
import { MilestoneCompleted } from "../types/attestations";
|
|
4
|
+
interface _Milestone extends Milestone {
|
|
5
|
+
}
|
|
6
|
+
export interface IMilestone {
|
|
7
|
+
title: string;
|
|
8
|
+
endsAt: number;
|
|
9
|
+
description: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class Milestone extends Attestation<IMilestone> implements IMilestone {
|
|
12
|
+
title: string;
|
|
13
|
+
endsAt: number;
|
|
14
|
+
description: string;
|
|
15
|
+
completed: MilestoneCompleted;
|
|
16
|
+
approved: MilestoneCompleted;
|
|
17
|
+
rejected: MilestoneCompleted;
|
|
18
|
+
/**
|
|
19
|
+
* Approves this milestone. If the milestone is not completed or already approved,
|
|
20
|
+
* it will throw an error.
|
|
21
|
+
* @param signer
|
|
22
|
+
* @param reason
|
|
23
|
+
*/
|
|
24
|
+
approve(signer: SignerOrProvider, reason?: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Revokes the approved status of the milestone. If the milestone is not approved,
|
|
27
|
+
* it will throw an error.
|
|
28
|
+
* @param signer
|
|
29
|
+
*/
|
|
30
|
+
revokeApproval(signer: SignerOrProvider): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Reject a completed milestone. If the milestone is not completed or already rejected,
|
|
33
|
+
* it will throw an error.
|
|
34
|
+
* @param signer
|
|
35
|
+
* @param reason
|
|
36
|
+
*/
|
|
37
|
+
reject(signer: SignerOrProvider, reason?: string): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Revokes the rejected status of the milestone. If the milestone is not rejected,
|
|
40
|
+
* it will throw an error.
|
|
41
|
+
* @param signer
|
|
42
|
+
*/
|
|
43
|
+
revokeRejection(signer: SignerOrProvider): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Marks a milestone as completed. If the milestone is already completed,
|
|
46
|
+
* it will throw an error.
|
|
47
|
+
* @param signer
|
|
48
|
+
* @param reason
|
|
49
|
+
*/
|
|
50
|
+
complete(signer: SignerOrProvider, reason?: string): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Revokes the completed status of the milestone. If the milestone is not completed,
|
|
53
|
+
* it will throw an error.
|
|
54
|
+
* @param signer
|
|
55
|
+
*/
|
|
56
|
+
revokeCompletion(signer: SignerOrProvider): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Attest the status of the milestone as approved, rejected or completed.
|
|
59
|
+
*/
|
|
60
|
+
private attestStatus;
|
|
61
|
+
static from(attestations: _Milestone[]): Milestone[];
|
|
62
|
+
}
|
|
63
|
+
export {};
|