@show-karma/karma-gap-sdk 0.4.16 → 0.4.18
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/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.d.ts +1114 -0
- package/core/abi/index.js +26 -0
- package/core/class/AllGapSchemas.d.ts +9 -0
- package/core/class/AllGapSchemas.js +19 -0
- package/core/class/Attestation.d.ts +173 -0
- package/core/class/Attestation.js +333 -0
- package/core/class/Fetcher.d.ts +175 -0
- package/core/class/Fetcher.js +13 -0
- package/core/class/GAP.d.ts +254 -0
- package/core/class/GAP.js +289 -0
- package/core/class/GapSchema.d.ts +34 -0
- package/core/class/GapSchema.js +62 -0
- package/core/class/Gelato/{Gelato.ts → Gelato.js} +0 -23
- package/core/class/GrantProgramRegistry/Allo.d.ts +17 -0
- package/core/class/GrantProgramRegistry/Allo.js +137 -0
- package/core/class/GrantProgramRegistry/AlloRegistry.d.ts +15 -0
- package/core/class/GrantProgramRegistry/AlloRegistry.js +70 -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/GapEasClient.d.ts +71 -0
- package/core/class/GraphQL/GapEasClient.js +451 -0
- package/core/class/GraphQL/index.js +19 -0
- package/core/class/Schema.d.ts +233 -0
- package/core/class/Schema.js +490 -0
- package/core/class/SchemaError.d.ts +30 -0
- package/core/class/SchemaError.js +39 -0
- package/core/class/contract/GapContract.d.ts +102 -0
- package/core/class/contract/GapContract.js +285 -0
- package/core/class/entities/Community.d.ts +34 -0
- package/core/class/entities/Community.js +109 -0
- package/core/class/entities/ContributorProfile.d.ts +41 -0
- package/core/class/entities/ContributorProfile.js +69 -0
- package/core/class/entities/Grant.d.ts +54 -0
- package/core/class/entities/Grant.js +223 -0
- package/core/class/entities/GrantUpdate.d.ts +62 -0
- package/core/class/entities/GrantUpdate.js +114 -0
- package/core/class/entities/MemberOf.d.ts +11 -0
- package/core/class/entities/MemberOf.js +33 -0
- package/core/class/entities/Milestone.d.ts +168 -0
- package/core/class/entities/Milestone.js +657 -0
- package/core/class/entities/Project.d.ts +92 -0
- package/core/class/entities/Project.js +418 -0
- package/core/class/entities/ProjectImpact.d.ts +50 -0
- package/core/class/entities/ProjectImpact.js +112 -0
- package/core/class/entities/ProjectMilestone.d.ts +60 -0
- package/core/class/entities/ProjectMilestone.js +174 -0
- package/core/class/entities/ProjectPointer.d.ts +12 -0
- package/core/class/entities/ProjectPointer.js +22 -0
- package/core/class/entities/ProjectUpdate.d.ts +50 -0
- package/core/class/entities/ProjectUpdate.js +110 -0
- package/core/class/entities/Track.d.ts +16 -0
- package/core/class/entities/Track.js +21 -0
- package/core/class/entities/index.js +26 -0
- package/core/class/index.js +26 -0
- package/core/class/karma-indexer/GapIndexerClient.d.ts +66 -0
- package/core/class/karma-indexer/GapIndexerClient.js +207 -0
- package/core/class/karma-indexer/api/GapIndexerApi.d.ts +73 -0
- package/core/class/karma-indexer/api/GapIndexerApi.js +256 -0
- package/core/class/karma-indexer/api/types.d.ts +309 -0
- package/core/class/karma-indexer/api/types.js +2 -0
- package/core/class/remote-storage/IpfsStorage.d.ts +23 -0
- package/core/class/remote-storage/IpfsStorage.js +56 -0
- package/core/class/remote-storage/RemoteStorage.d.ts +41 -0
- package/core/class/remote-storage/RemoteStorage.js +38 -0
- package/core/class/types/allo.d.ts +78 -0
- package/core/class/types/allo.js +2 -0
- package/core/class/types/attestations.d.ts +173 -0
- package/core/class/types/attestations.js +66 -0
- package/core/consts.d.ts +50 -0
- package/core/consts.js +699 -0
- package/core/index.js +24 -0
- package/core/shared/types.d.ts +13 -0
- package/core/shared/types.js +2 -0
- package/core/types.d.ts +131 -0
- package/core/types.js +13 -0
- package/core/utils/gelato/index.js +19 -0
- package/core/utils/gelato/send-gelato-txn.d.ts +55 -0
- package/core/utils/gelato/send-gelato-txn.js +100 -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 +63 -0
- package/core/utils/get-date.d.ts +1 -0
- package/core/utils/get-date.js +7 -0
- package/core/utils/get-ipfs-data.d.ts +1 -0
- package/core/utils/get-ipfs-data.js +20 -0
- package/core/utils/get-web3-provider.d.ts +2 -0
- package/core/utils/get-web3-provider.js +18 -0
- package/core/utils/gql-queries.d.ts +12 -0
- package/core/utils/gql-queries.js +90 -0
- package/core/utils/index.js +23 -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.js +17 -0
- package/package.json +45 -45
- package/.cursorrules +0 -43
- package/core/abi/index.ts +0 -21
- package/core/class/AllGapSchemas.ts +0 -21
- package/core/class/Attestation.ts +0 -429
- package/core/class/Fetcher.ts +0 -224
- package/core/class/GAP.ts +0 -481
- package/core/class/GapSchema.ts +0 -93
- package/core/class/GrantProgramRegistry/Allo.ts +0 -188
- package/core/class/GrantProgramRegistry/AlloRegistry.ts +0 -101
- package/core/class/GraphQL/AxiosGQL.ts +0 -29
- package/core/class/GraphQL/EASClient.ts +0 -34
- package/core/class/GraphQL/GapEasClient.ts +0 -869
- package/core/class/Schema.ts +0 -659
- package/core/class/SchemaError.ts +0 -42
- package/core/class/contract/GapContract.ts +0 -457
- package/core/class/entities/Community.ts +0 -148
- package/core/class/entities/ContributorProfile.ts +0 -108
- package/core/class/entities/Grant.ts +0 -321
- package/core/class/entities/GrantUpdate.ts +0 -187
- package/core/class/entities/MemberOf.ts +0 -52
- package/core/class/entities/Milestone.ts +0 -898
- package/core/class/entities/Project.ts +0 -672
- package/core/class/entities/ProjectImpact.ts +0 -170
- package/core/class/entities/ProjectMilestone.ts +0 -254
- package/core/class/entities/ProjectPointer.ts +0 -39
- package/core/class/entities/ProjectUpdate.ts +0 -176
- package/core/class/entities/Track.ts +0 -32
- package/core/class/karma-indexer/GapIndexerClient.ts +0 -383
- package/core/class/karma-indexer/api/GapIndexerApi.ts +0 -446
- package/core/class/karma-indexer/api/types.ts +0 -313
- package/core/class/remote-storage/IpfsStorage.ts +0 -76
- package/core/class/remote-storage/RemoteStorage.ts +0 -65
- package/core/class/types/allo.ts +0 -93
- package/core/class/types/attestations.ts +0 -223
- package/core/consts.ts +0 -775
- package/core/scripts/create-grant.ts +0 -102
- package/core/scripts/create-program.ts +0 -43
- package/core/scripts/create-schemas.ts +0 -65
- package/core/scripts/deploy.ts +0 -65
- package/core/scripts/index.ts +0 -1
- package/core/scripts/milestone-multi-grants.ts +0 -125
- package/core/shared/types.ts +0 -13
- package/core/types.ts +0 -224
- package/core/utils/gelato/send-gelato-txn.ts +0 -114
- package/core/utils/gelato/sponsor-handler.ts +0 -77
- package/core/utils/gelato/watch-gelato-txn.ts +0 -67
- package/core/utils/get-date.ts +0 -3
- package/core/utils/get-ipfs-data.ts +0 -13
- package/core/utils/get-web3-provider.ts +0 -18
- package/core/utils/gql-queries.ts +0 -133
- package/core/utils/map-filter.ts +0 -21
- package/core/utils/serialize-bigint.ts +0 -7
- package/core/utils/to-unix.ts +0 -18
- package/create-community-example.ts +0 -119
- package/csv-upload/README.md +0 -74
- package/csv-upload/config.ts +0 -41
- package/csv-upload/example.csv +0 -2
- package/csv-upload/keys.example.json +0 -8
- package/csv-upload/scripts/run.ts +0 -417
- package/csv-upload/types.ts +0 -39
- 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 +0 -155
- package/milestone-workflow-example.ts +0 -353
- package/readme.md +0 -872
- package/schemas/.gitkeep +0 -0
- package/schemas/GAP-schemas-1692135812877.json +0 -33
- package/test-file-indexer-api.ts +0 -25
- package/tsconfig.json +0 -26
- /package/{csv-upload/.gitkeep → core/class/Gelato/Gelato.d.ts} +0 -0
- /package/core/class/GraphQL/{index.ts → index.d.ts} +0 -0
- /package/core/class/entities/{index.ts → index.d.ts} +0 -0
- /package/core/class/{index.ts → index.d.ts} +0 -0
- /package/core/{index.ts → index.d.ts} +0 -0
- /package/core/utils/gelato/{index.ts → index.d.ts} +0 -0
- /package/core/utils/{index.ts → index.d.ts} +0 -0
- /package/{index.ts → index.d.ts} +0 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.GAP = void 0;
|
|
7
|
+
const CommunityResolverABI_json_1 = __importDefault(require("../abi/CommunityResolverABI.json"));
|
|
8
|
+
const MultiAttester_json_1 = __importDefault(require("../abi/MultiAttester.json"));
|
|
9
|
+
const ProjectResolver_json_1 = __importDefault(require("../abi/ProjectResolver.json"));
|
|
10
|
+
const eas_sdk_1 = require("@ethereum-attestation-service/eas-sdk");
|
|
11
|
+
const ethers_1 = require("ethers");
|
|
12
|
+
const package_json_1 = require("../../package.json");
|
|
13
|
+
const consts_1 = require("../consts");
|
|
14
|
+
const types_1 = require("../types");
|
|
15
|
+
const get_web3_provider_1 = require("../utils/get-web3-provider");
|
|
16
|
+
const GapSchema_1 = require("./GapSchema");
|
|
17
|
+
const GraphQL_1 = require("./GraphQL");
|
|
18
|
+
const Schema_1 = require("./Schema");
|
|
19
|
+
/**
|
|
20
|
+
* GAP SDK Facade.
|
|
21
|
+
*
|
|
22
|
+
* This is the main class that is used to interact with the GAP SDK.
|
|
23
|
+
*
|
|
24
|
+
* This class implements the singleton pattern to ensure only one instance exists
|
|
25
|
+
* throughout the application lifecycle.
|
|
26
|
+
*
|
|
27
|
+
* Using this class, the user will be able to:
|
|
28
|
+
*
|
|
29
|
+
* - Create and manage attestations
|
|
30
|
+
* - Create and manage schemas
|
|
31
|
+
* - Fetch data from the EAS
|
|
32
|
+
*
|
|
33
|
+
* #### Features
|
|
34
|
+
* - EAS Client: used to interact with EAS contracts
|
|
35
|
+
* - EAS Fetcher: used to fetch data from the EAS GraphQL API, providing methods for:
|
|
36
|
+
* - Get projects
|
|
37
|
+
* - Get grants with its details
|
|
38
|
+
* - Get grantees
|
|
39
|
+
* - Get members
|
|
40
|
+
* - Get tags
|
|
41
|
+
* - Get external links
|
|
42
|
+
* - Get schemas
|
|
43
|
+
* - Get attestations by pair, attester, recipient, schema, or UID
|
|
44
|
+
* - Get dependent attestations
|
|
45
|
+
* - Schema: used to create and manage schemas
|
|
46
|
+
* - Attestation: used to create and manage attestations
|
|
47
|
+
* - Replace schemas: used to replace the schema list with a new list
|
|
48
|
+
* - Replace single schema: used to replace a single schema from the schema list
|
|
49
|
+
*
|
|
50
|
+
* ---
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* import { GAP } from "./core/class/GAP";
|
|
54
|
+
* import { GapSchema } from "./core/class/GapSchema";
|
|
55
|
+
* import { Schema } from "./core/class/Schema";
|
|
56
|
+
* import { MountEntities, Networks } from "./core/consts";
|
|
57
|
+
*
|
|
58
|
+
* const schemas = MountEntities(Networks.sepolia);
|
|
59
|
+
*
|
|
60
|
+
* // Initialize the singleton instance
|
|
61
|
+
* const gap = GAP.getInstance({
|
|
62
|
+
* network: "sepolia",
|
|
63
|
+
* owner: "0xd7d1DB401EA825b0325141Cd5e6cd7C2d01825f2",
|
|
64
|
+
* schemas: Object.values(schemas),
|
|
65
|
+
* });
|
|
66
|
+
*
|
|
67
|
+
* // Later in the code, get the same instance
|
|
68
|
+
* const sameGap = GAP.getInstance();
|
|
69
|
+
*
|
|
70
|
+
* gap.fetcher
|
|
71
|
+
* .fetchProjects()
|
|
72
|
+
* .then((res) => {
|
|
73
|
+
* console.log(JSON.stringify(res, null, 2));
|
|
74
|
+
* })
|
|
75
|
+
*
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
class GAP extends types_1.Facade {
|
|
79
|
+
/**
|
|
80
|
+
* Get the singleton instance of GAP for a specific network.
|
|
81
|
+
* If no instance exists for the network, creates one with the provided args.
|
|
82
|
+
* @param args Optional initialization arguments
|
|
83
|
+
* @returns The singleton instance of GAP for the specified network
|
|
84
|
+
*/
|
|
85
|
+
static getInstance(args) {
|
|
86
|
+
if (!args) {
|
|
87
|
+
throw new Error("Network must be specified when getting GAP instance");
|
|
88
|
+
}
|
|
89
|
+
const existingInstance = GAP.instances.get(args.network);
|
|
90
|
+
if (existingInstance) {
|
|
91
|
+
return existingInstance;
|
|
92
|
+
}
|
|
93
|
+
if (!args) {
|
|
94
|
+
throw new Error("Initialization arguments required for first instance");
|
|
95
|
+
}
|
|
96
|
+
const newInstance = new GAP(args);
|
|
97
|
+
GAP.instances.set(args.network, newInstance);
|
|
98
|
+
return newInstance;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Creates a new instance of GAP.
|
|
102
|
+
* You can either use this constructor directly or use the singleton pattern via getInstance().
|
|
103
|
+
* @param args Initialization arguments
|
|
104
|
+
*/
|
|
105
|
+
constructor(args) {
|
|
106
|
+
super();
|
|
107
|
+
/**
|
|
108
|
+
* Generates a slug from a text.
|
|
109
|
+
* @param text
|
|
110
|
+
* @returns
|
|
111
|
+
*/
|
|
112
|
+
this.generateSlug = async (text) => {
|
|
113
|
+
let slug = text
|
|
114
|
+
.toLowerCase()
|
|
115
|
+
// Remove emojis
|
|
116
|
+
.replace(/([\uE000-\uF8FF]|\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDDFF])/g, "")
|
|
117
|
+
// Remove basic text emoticons
|
|
118
|
+
.replace(/[:;=][()DP]/g, "")
|
|
119
|
+
.replace(/ /g, "-")
|
|
120
|
+
.replace(/[^\w-]+/g, "")
|
|
121
|
+
.trim()
|
|
122
|
+
.replace(/^-+|-+$/g, ""); // Remove leading and trailing hyphens
|
|
123
|
+
const checkSlug = async (currentSlug, counter = 0) => {
|
|
124
|
+
const slugToCheck = counter === 0 ? currentSlug : `${currentSlug}-${counter}`;
|
|
125
|
+
const slugExists = await this.fetch.slugExists(slugToCheck);
|
|
126
|
+
if (slugExists) {
|
|
127
|
+
return checkSlug(currentSlug, counter + 1);
|
|
128
|
+
}
|
|
129
|
+
return slugToCheck.toLowerCase();
|
|
130
|
+
};
|
|
131
|
+
return checkSlug(slug);
|
|
132
|
+
};
|
|
133
|
+
const schemas = args.schemas || Object.values((0, consts_1.MountEntities)(consts_1.Networks[args.network]));
|
|
134
|
+
this.network = args.network;
|
|
135
|
+
this._eas = new eas_sdk_1.EAS(consts_1.Networks[args.network].contracts.eas);
|
|
136
|
+
this.fetch =
|
|
137
|
+
args.apiClient ||
|
|
138
|
+
new GraphQL_1.GapEasClient({
|
|
139
|
+
network: args.network,
|
|
140
|
+
});
|
|
141
|
+
this.fetch.gapInstance = this;
|
|
142
|
+
this.assertGelatoOpts(args);
|
|
143
|
+
GAP._gelatoOpts = args.gelatoOpts;
|
|
144
|
+
GAP.remoteStorage = args.remoteStorage;
|
|
145
|
+
this._schemas = schemas.map((schema) => new GapSchema_1.GapSchema(schema, this, false, args.globalSchemas ? !args.globalSchemas : false));
|
|
146
|
+
Schema_1.Schema.validate(this.network);
|
|
147
|
+
console.info(`Loaded GAP SDK v${package_json_1.version} for network ${this.network}`);
|
|
148
|
+
GAP.instances.set(this.network, this);
|
|
149
|
+
}
|
|
150
|
+
assertGelatoOpts(args) {
|
|
151
|
+
if (args.gelatoOpts &&
|
|
152
|
+
!(args.gelatoOpts.sponsorUrl || args.gelatoOpts.apiKey)) {
|
|
153
|
+
throw new Error("You must provide a `sponsorUrl` or an `apiKey`.");
|
|
154
|
+
}
|
|
155
|
+
if (args.gelatoOpts?.sponsorUrl &&
|
|
156
|
+
args.gelatoOpts?.contained &&
|
|
157
|
+
!args.gelatoOpts.env_gelatoApiKey) {
|
|
158
|
+
throw new Error("You must provide `env_gelatoApiKey` to be able to use it in a backend handler.");
|
|
159
|
+
}
|
|
160
|
+
if ((args.gelatoOpts?.env_gelatoApiKey ||
|
|
161
|
+
args.gelatoOpts?.apiKey ||
|
|
162
|
+
args.gelatoOpts?.sponsorUrl) &&
|
|
163
|
+
!args.gelatoOpts?.useGasless) {
|
|
164
|
+
console.warn("GAP::You are using gelatoOpts but not setting useGasless to true. This will send transactions through the normal provider.");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Creates the attestation payload using a specific schema.
|
|
169
|
+
* @param from
|
|
170
|
+
* @param to
|
|
171
|
+
* @param data
|
|
172
|
+
* @param schema
|
|
173
|
+
*/
|
|
174
|
+
async attest(attestation) {
|
|
175
|
+
const schema = GapSchema_1.GapSchema.find(attestation.schemaName, this.network);
|
|
176
|
+
return schema.attest(attestation);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Replaces the schema list with a new list.
|
|
180
|
+
* @param schemas
|
|
181
|
+
*/
|
|
182
|
+
replaceSchemas(schemas) {
|
|
183
|
+
Schema_1.Schema.replaceAll(schemas, this.network);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Replaces a schema from the schema list.
|
|
187
|
+
* @throws {SchemaError} if desired schema name does not exist.
|
|
188
|
+
*/
|
|
189
|
+
replaceSingleSchema(schema) {
|
|
190
|
+
Schema_1.Schema.replaceOne(schema, this.network);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Returns a copy of the original schema with no pointers.
|
|
194
|
+
* @param name
|
|
195
|
+
* @returns
|
|
196
|
+
*/
|
|
197
|
+
findSchema(name) {
|
|
198
|
+
const found = Schema_1.Schema.get(name, this.network);
|
|
199
|
+
return GapSchema_1.GapSchema.clone(found);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Find many schemas by name and return their copies as an array in the same order.
|
|
203
|
+
* @param names
|
|
204
|
+
* @returns
|
|
205
|
+
*/
|
|
206
|
+
findManySchemas(names) {
|
|
207
|
+
const schemas = Schema_1.Schema.getMany(names, this.network);
|
|
208
|
+
return schemas.map((s) => GapSchema_1.GapSchema.clone(s));
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Get the multicall contract
|
|
212
|
+
* @param signer
|
|
213
|
+
*/
|
|
214
|
+
static async getMulticall(signer) {
|
|
215
|
+
const chain = (await signer.provider.getNetwork()) || signer.provider.network;
|
|
216
|
+
const network = Object.values(consts_1.Networks).find((n) => +n.chainId === Number(chain.chainId));
|
|
217
|
+
if (!network)
|
|
218
|
+
throw new Error(`Network ${chain.name || chain.chainId} not supported.`);
|
|
219
|
+
const address = network.contracts.multicall;
|
|
220
|
+
return new ethers_1.ethers.Contract(address, MultiAttester_json_1.default, signer);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Get the multicall contract
|
|
224
|
+
* @param signer
|
|
225
|
+
*/
|
|
226
|
+
static async getProjectResolver(signer, chainId) {
|
|
227
|
+
const currentChainId = chainId ||
|
|
228
|
+
Number((await signer.provider.getNetwork())?.chainId ||
|
|
229
|
+
(await signer.getChainId()));
|
|
230
|
+
const provider = chainId ? (0, get_web3_provider_1.getWeb3Provider)(chainId) : signer;
|
|
231
|
+
const network = Object.values(consts_1.Networks).find((n) => +n.chainId === Number(currentChainId));
|
|
232
|
+
const address = network.contracts.projectResolver;
|
|
233
|
+
return new ethers_1.ethers.Contract(address, ProjectResolver_json_1.default, provider);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Get the multicall contract
|
|
237
|
+
* @param signer
|
|
238
|
+
*/
|
|
239
|
+
static async getCommunityResolver(signer, chainId) {
|
|
240
|
+
const currentChainId = chainId ||
|
|
241
|
+
Number((await signer.provider.getNetwork())?.chainId ||
|
|
242
|
+
(await signer.getChainId()));
|
|
243
|
+
const provider = chainId ? (0, get_web3_provider_1.getWeb3Provider)(chainId) : signer;
|
|
244
|
+
const network = Object.values(consts_1.Networks).find((n) => +n.chainId === Number(currentChainId));
|
|
245
|
+
const address = network.contracts.communityResolver;
|
|
246
|
+
return new ethers_1.ethers.Contract(address, CommunityResolverABI_json_1.default, provider);
|
|
247
|
+
}
|
|
248
|
+
get schemas() {
|
|
249
|
+
return this._schemas;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Defined if the transactions will be gasless or not.
|
|
253
|
+
*
|
|
254
|
+
* In case of true, the transactions will be sent through [Gelato](https://gelato.network)
|
|
255
|
+
* and an API key is needed.
|
|
256
|
+
*/
|
|
257
|
+
static set gelatoOpts(gelatoOpts) {
|
|
258
|
+
if (typeof this._gelatoOpts === "undefined") {
|
|
259
|
+
this._gelatoOpts = gelatoOpts;
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
throw new Error("Cannot change a readonly value gelatoOpts.");
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Defined if the transactions will be gasless or not.
|
|
267
|
+
*
|
|
268
|
+
* In case of true, the transactions will be sent through [Gelato](https://gelato.network)
|
|
269
|
+
* and an API key is needed.
|
|
270
|
+
*/
|
|
271
|
+
static get gelatoOpts() {
|
|
272
|
+
return this._gelatoOpts;
|
|
273
|
+
}
|
|
274
|
+
static set useGasLess(useGasLess) {
|
|
275
|
+
if (useGasLess &&
|
|
276
|
+
!this._gelatoOpts?.apiKey &&
|
|
277
|
+
!this._gelatoOpts?.sponsorUrl &&
|
|
278
|
+
!this._gelatoOpts?.env_gelatoApiKey) {
|
|
279
|
+
throw new Error("You must provide a `sponsorUrl` or an `apiKey` before using gasless transactions.");
|
|
280
|
+
}
|
|
281
|
+
this._gelatoOpts.useGasless = useGasLess;
|
|
282
|
+
}
|
|
283
|
+
static get remoteClient() {
|
|
284
|
+
return this.remoteStorage;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
exports.GAP = GAP;
|
|
288
|
+
GAP.instances = new Map();
|
|
289
|
+
GAP._gelatoOpts = null;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { IGapSchema, SchemaInterface, TNetwork, TSchemaName } from '../types';
|
|
2
|
+
import { Schema } from './Schema';
|
|
3
|
+
import { GAP } from './GAP';
|
|
4
|
+
/**
|
|
5
|
+
* Represents the GapSchema
|
|
6
|
+
* @extends Schema
|
|
7
|
+
*/
|
|
8
|
+
export declare class GapSchema extends Schema implements IGapSchema {
|
|
9
|
+
readonly name: TSchemaName;
|
|
10
|
+
readonly references: TSchemaName;
|
|
11
|
+
constructor(args: SchemaInterface<TSchemaName>, gap: GAP, strict?: boolean, ignoreSchema?: boolean);
|
|
12
|
+
/**
|
|
13
|
+
* Clones a schema without references to the original.
|
|
14
|
+
* @param schema
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
static clone(schema: GapSchema): GapSchema;
|
|
18
|
+
/**
|
|
19
|
+
* Returns a copy of the original schema with no pointers.
|
|
20
|
+
* @param name
|
|
21
|
+
* @returns
|
|
22
|
+
*/
|
|
23
|
+
static find(name: TSchemaName, network: TNetwork): GapSchema;
|
|
24
|
+
/**
|
|
25
|
+
* Find many schemas by name and return their copies as an array in the same order.
|
|
26
|
+
* @param names
|
|
27
|
+
* @returns
|
|
28
|
+
*/
|
|
29
|
+
static findMany(names: TSchemaName[], network: TNetwork): GapSchema[];
|
|
30
|
+
/**
|
|
31
|
+
* Get all schemas that references this schema.
|
|
32
|
+
*/
|
|
33
|
+
get children(): GapSchema[];
|
|
34
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GapSchema = void 0;
|
|
4
|
+
const utils_1 = require("../utils");
|
|
5
|
+
const Schema_1 = require("./Schema");
|
|
6
|
+
/**
|
|
7
|
+
* Represents the GapSchema
|
|
8
|
+
* @extends Schema
|
|
9
|
+
*/
|
|
10
|
+
class GapSchema extends Schema_1.Schema {
|
|
11
|
+
constructor(args, gap, strict = false, ignoreSchema = false) {
|
|
12
|
+
super(args, gap, strict, ignoreSchema);
|
|
13
|
+
if (!ignoreSchema)
|
|
14
|
+
Schema_1.Schema.add(gap.network, new GapSchema({
|
|
15
|
+
name: args.name,
|
|
16
|
+
schema: args.schema.map((s) => ({ ...s })),
|
|
17
|
+
uid: args.uid,
|
|
18
|
+
references: args.references,
|
|
19
|
+
revocable: args.revocable,
|
|
20
|
+
oldSchemas: args.oldSchemas,
|
|
21
|
+
}, gap, strict, true));
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Clones a schema without references to the original.
|
|
25
|
+
* @param schema
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
28
|
+
static clone(schema) {
|
|
29
|
+
return new GapSchema({
|
|
30
|
+
name: schema.name,
|
|
31
|
+
schema: schema.schema.map((s) => ({ ...s })),
|
|
32
|
+
uid: schema.uid,
|
|
33
|
+
references: schema.references,
|
|
34
|
+
revocable: schema.revocable,
|
|
35
|
+
}, schema.gap, false, true);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Returns a copy of the original schema with no pointers.
|
|
39
|
+
* @param name
|
|
40
|
+
* @returns
|
|
41
|
+
*/
|
|
42
|
+
static find(name, network) {
|
|
43
|
+
const found = Schema_1.Schema.get(name, network);
|
|
44
|
+
return this.clone(found);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Find many schemas by name and return their copies as an array in the same order.
|
|
48
|
+
* @param names
|
|
49
|
+
* @returns
|
|
50
|
+
*/
|
|
51
|
+
static findMany(names, network) {
|
|
52
|
+
const schemas = Schema_1.Schema.getMany(names, network);
|
|
53
|
+
return schemas.map((s) => this.clone(s));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get all schemas that references this schema.
|
|
57
|
+
*/
|
|
58
|
+
get children() {
|
|
59
|
+
return (0, utils_1.mapFilter)(GapSchema.schemas[this.gap.network], (s) => s.references === this.name || s.references === this.uid, (s) => new GapSchema(s, s.gap, false, true));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.GapSchema = GapSchema;
|
|
@@ -5,13 +5,11 @@
|
|
|
5
5
|
// /* eslint-disable class-methods-use-this */
|
|
6
6
|
// /* eslint-disable no-useless-constructor */
|
|
7
7
|
// /* eslint-disable import/no-extraneous-dependencies */
|
|
8
|
-
|
|
9
8
|
// import { GelatoRelay } from "@gelatonetwork/relay-sdk";
|
|
10
9
|
// import { ethers } from "ethers";
|
|
11
10
|
// import axios from "axios";
|
|
12
11
|
// import ABI from "./";
|
|
13
12
|
// import { Hex } from "core/types";
|
|
14
|
-
|
|
15
13
|
// enum TaskState {
|
|
16
14
|
// CheckPending = "CheckPending",
|
|
17
15
|
// ExecPending = "ExecPending",
|
|
@@ -22,15 +20,12 @@
|
|
|
22
20
|
// Cancelled = "Cancelled",
|
|
23
21
|
// NotFound = "NotFound",
|
|
24
22
|
// }
|
|
25
|
-
|
|
26
23
|
// export class DelegateRegistryContract extends GelatoRelay {
|
|
27
24
|
// contract: ethers.Contract;
|
|
28
|
-
|
|
29
25
|
// constructor(readonly contractAddress: Hex) {
|
|
30
26
|
// super();
|
|
31
27
|
// this.contract = new ethers.Contract(contractAddress, ABI);
|
|
32
28
|
// }
|
|
33
|
-
|
|
34
29
|
// /**
|
|
35
30
|
// * Returns the r, s, v values of a signature
|
|
36
31
|
// * @param signature
|
|
@@ -42,7 +37,6 @@
|
|
|
42
37
|
// const v = `0x${signature.slice(130, 132)}`;
|
|
43
38
|
// return { r, s, v };
|
|
44
39
|
// }
|
|
45
|
-
|
|
46
40
|
// /**
|
|
47
41
|
// * Returns the nonce of a delegate
|
|
48
42
|
// * @param address
|
|
@@ -56,13 +50,11 @@
|
|
|
56
50
|
// args: [address],
|
|
57
51
|
// chainId: 10,
|
|
58
52
|
// });
|
|
59
|
-
|
|
60
53
|
// return {
|
|
61
54
|
// nonce: Number(nonce),
|
|
62
55
|
// next: Number(nonce + 1n),
|
|
63
56
|
// };
|
|
64
57
|
// }
|
|
65
|
-
|
|
66
58
|
// /**
|
|
67
59
|
// * Waits for a transaction to be mined at Gelato Network
|
|
68
60
|
// * @param taskId
|
|
@@ -100,14 +92,12 @@
|
|
|
100
92
|
// );
|
|
101
93
|
// break;
|
|
102
94
|
// }
|
|
103
|
-
|
|
104
95
|
// await new Promise((r) => setTimeout(r, 500));
|
|
105
96
|
// }
|
|
106
97
|
// };
|
|
107
98
|
// loop();
|
|
108
99
|
// });
|
|
109
100
|
// }
|
|
110
|
-
|
|
111
101
|
// /**
|
|
112
102
|
// * Executes a transaction on the DelegateRegistry contract
|
|
113
103
|
// * @param fn the function to call
|
|
@@ -127,7 +117,6 @@
|
|
|
127
117
|
// wait: () => waitForTransaction({ hash }),
|
|
128
118
|
// };
|
|
129
119
|
// }
|
|
130
|
-
|
|
131
120
|
// public async registerDelegate(data: DelegateWithProfile) {
|
|
132
121
|
// return this.transaction("registerDelegate", [
|
|
133
122
|
// data.tokenAddress,
|
|
@@ -135,7 +124,6 @@
|
|
|
135
124
|
// JSON.stringify(data.profile),
|
|
136
125
|
// ]);
|
|
137
126
|
// }
|
|
138
|
-
|
|
139
127
|
// /**
|
|
140
128
|
// * Creates the payload for register delegate by signature
|
|
141
129
|
// * returning the payload
|
|
@@ -149,9 +137,7 @@
|
|
|
149
137
|
// const { nonce } = await this.getNonce(address);
|
|
150
138
|
// // 2 minutes expiry
|
|
151
139
|
// const expiry = ((Date.now() + 1000 * 120) / 1000).toFixed(0);
|
|
152
|
-
|
|
153
140
|
// const metadata = JSON.stringify(data.profile);
|
|
154
|
-
|
|
155
141
|
// const types = {
|
|
156
142
|
// RegisterDelegate: [
|
|
157
143
|
// { name: "tokenAddress", type: "address" },
|
|
@@ -178,9 +164,7 @@
|
|
|
178
164
|
// primaryType: "RegisterDelegate",
|
|
179
165
|
// types,
|
|
180
166
|
// });
|
|
181
|
-
|
|
182
167
|
// const { r, s, v } = this.getRSV(signature);
|
|
183
|
-
|
|
184
168
|
// const { data: payload } =
|
|
185
169
|
// await this.contract.populateTransaction.registerDelegateBySig(
|
|
186
170
|
// address,
|
|
@@ -193,7 +177,6 @@
|
|
|
193
177
|
// r,
|
|
194
178
|
// s
|
|
195
179
|
// );
|
|
196
|
-
|
|
197
180
|
// // eslint-disable-next-line no-console
|
|
198
181
|
// console.log({ payload, signature, r, s, v });
|
|
199
182
|
// if (!payload) throw new Error("Payload is undefined");
|
|
@@ -209,7 +192,6 @@
|
|
|
209
192
|
// },
|
|
210
193
|
// ];
|
|
211
194
|
// }
|
|
212
|
-
|
|
213
195
|
// /**
|
|
214
196
|
// * Sends a sponsored call to the DelegateRegistry contract using GelatoRelay
|
|
215
197
|
// * @param payload
|
|
@@ -218,13 +200,11 @@
|
|
|
218
200
|
// static async sendGelato(...params: Parameters<GelatoRelay["sponsoredCall"]>) {
|
|
219
201
|
// const client = new this(params[0].target as Hex);
|
|
220
202
|
// const relayResponse = await client.sponsoredCall(...params);
|
|
221
|
-
|
|
222
203
|
// return {
|
|
223
204
|
// taskId: relayResponse.taskId,
|
|
224
205
|
// wait: () => client.wait(relayResponse.taskId),
|
|
225
206
|
// };
|
|
226
207
|
// }
|
|
227
|
-
|
|
228
208
|
// /**
|
|
229
209
|
// * Deregisters a delegate on the DelegateRegistry contract
|
|
230
210
|
// * @param tokenAddress
|
|
@@ -234,7 +214,6 @@
|
|
|
234
214
|
// public deregisterDelegate(tokenAddress: string, tokenChainId: number) {
|
|
235
215
|
// return this.transaction("deregisterDelegate", [tokenAddress, tokenChainId]);
|
|
236
216
|
// }
|
|
237
|
-
|
|
238
217
|
// /**
|
|
239
218
|
// * Returns a delegate from the DelegateRegistry contract
|
|
240
219
|
// * @param delegateAddress
|
|
@@ -265,7 +244,6 @@
|
|
|
265
244
|
// interests
|
|
266
245
|
// }
|
|
267
246
|
// }`;
|
|
268
|
-
|
|
269
247
|
// const {
|
|
270
248
|
// data: {
|
|
271
249
|
// data: { delegates },
|
|
@@ -273,7 +251,6 @@
|
|
|
273
251
|
// } = await axios.post<{ data: DelegateStatementRes }>(this.subgraphUrl, {
|
|
274
252
|
// query,
|
|
275
253
|
// });
|
|
276
|
-
|
|
277
254
|
// return delegates.map((item) => {
|
|
278
255
|
// if (Array.isArray(item?.interests))
|
|
279
256
|
// return item as DelegateRegistryWithInterests;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ethers } from "ethers";
|
|
2
|
+
export declare class AlloBase {
|
|
3
|
+
private signer;
|
|
4
|
+
private contract;
|
|
5
|
+
private allo;
|
|
6
|
+
private pinataJWTToken;
|
|
7
|
+
constructor(signer: ethers.Signer, pinataJWTToken: string, chainId: number);
|
|
8
|
+
saveAndGetCID(data: any, pinataMetadata?: {
|
|
9
|
+
name: string;
|
|
10
|
+
}): Promise<any>;
|
|
11
|
+
encodeStrategyInitData(applicationStart: number, applicationEnd: number, roundStart: number, roundEnd: number, payoutToken: string): Promise<string>;
|
|
12
|
+
createGrant(args: any, callback?: Function): Promise<{
|
|
13
|
+
poolId: string;
|
|
14
|
+
txHash: string;
|
|
15
|
+
}>;
|
|
16
|
+
updatePoolMetadata(poolId: string, poolMetadata: any, callback?: Function): Promise<any>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AlloBase = void 0;
|
|
7
|
+
const ethers_1 = require("ethers");
|
|
8
|
+
const Allo_json_1 = __importDefault(require("../../abi/Allo.json"));
|
|
9
|
+
const consts_1 = require("../../consts");
|
|
10
|
+
const ethers_2 = require("ethers");
|
|
11
|
+
const allo_v2_sdk_1 = require("@allo-team/allo-v2-sdk/");
|
|
12
|
+
const axios_1 = __importDefault(require("axios"));
|
|
13
|
+
// ABI fragment for the Initialized event
|
|
14
|
+
const INITIALIZED_EVENT = ["event Initialized(uint256 poolId, bytes data)"];
|
|
15
|
+
class AlloBase {
|
|
16
|
+
constructor(signer, pinataJWTToken, chainId) {
|
|
17
|
+
this.signer = signer;
|
|
18
|
+
this.contract = new ethers_1.ethers.Contract(consts_1.AlloContracts.alloProxy, Allo_json_1.default, signer);
|
|
19
|
+
this.allo = new allo_v2_sdk_1.Allo({ chain: chainId });
|
|
20
|
+
this.pinataJWTToken = pinataJWTToken;
|
|
21
|
+
}
|
|
22
|
+
async saveAndGetCID(data, pinataMetadata = { name: "via karma-gap-sdk" }) {
|
|
23
|
+
try {
|
|
24
|
+
const res = await axios_1.default.post("https://api.pinata.cloud/pinning/pinJSONToIPFS", {
|
|
25
|
+
pinataContent: data,
|
|
26
|
+
pinataMetadata: pinataMetadata,
|
|
27
|
+
}, {
|
|
28
|
+
headers: {
|
|
29
|
+
"Content-Type": "application/json",
|
|
30
|
+
Authorization: `Bearer ${this.pinataJWTToken}`,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
return res.data.IpfsHash;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.log(error);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async encodeStrategyInitData(applicationStart, applicationEnd, roundStart, roundEnd, payoutToken) {
|
|
40
|
+
const encoder = new ethers_2.AbiCoder();
|
|
41
|
+
const initStrategyData = encoder.encode(["bool", "bool", "uint256", "uint256", "uint256", "uint256", "address[]"], [
|
|
42
|
+
false,
|
|
43
|
+
true,
|
|
44
|
+
applicationStart,
|
|
45
|
+
applicationEnd,
|
|
46
|
+
roundStart,
|
|
47
|
+
roundEnd,
|
|
48
|
+
[payoutToken],
|
|
49
|
+
]);
|
|
50
|
+
return initStrategyData;
|
|
51
|
+
}
|
|
52
|
+
async createGrant(args, callback) {
|
|
53
|
+
console.log("Creating grant...");
|
|
54
|
+
const walletBalance = await this.signer.provider.getBalance(await this.signer.getAddress());
|
|
55
|
+
console.log("Wallet balance:", (0, ethers_1.formatEther)(walletBalance.toString()), " ETH");
|
|
56
|
+
try {
|
|
57
|
+
const metadata_cid = await this.saveAndGetCID({
|
|
58
|
+
round: args.roundMetadata,
|
|
59
|
+
application: args.applicationMetadata,
|
|
60
|
+
});
|
|
61
|
+
const metadata = {
|
|
62
|
+
protocol: BigInt(1),
|
|
63
|
+
pointer: metadata_cid,
|
|
64
|
+
};
|
|
65
|
+
const initStrategyData = (await this.encodeStrategyInitData(args.applicationStart, args.applicationEnd, args.roundStart, args.roundEnd, args.payoutToken));
|
|
66
|
+
const createPoolArgs = {
|
|
67
|
+
profileId: args.profileId,
|
|
68
|
+
strategy: args.strategy,
|
|
69
|
+
initStrategyData: initStrategyData,
|
|
70
|
+
token: args.payoutToken,
|
|
71
|
+
amount: BigInt(args.matchingFundAmt),
|
|
72
|
+
metadata: metadata,
|
|
73
|
+
managers: args.managers,
|
|
74
|
+
};
|
|
75
|
+
callback?.("preparing");
|
|
76
|
+
const txData = this.allo.createPool(createPoolArgs);
|
|
77
|
+
const tx = await this.signer.sendTransaction({
|
|
78
|
+
data: txData.data,
|
|
79
|
+
to: txData.to,
|
|
80
|
+
value: BigInt(txData.value),
|
|
81
|
+
});
|
|
82
|
+
callback?.("pending");
|
|
83
|
+
const receipt = await tx.wait();
|
|
84
|
+
callback?.("confirmed");
|
|
85
|
+
// Create interface to parse the logs
|
|
86
|
+
const iface = new ethers_1.ethers.Interface(INITIALIZED_EVENT);
|
|
87
|
+
let poolId;
|
|
88
|
+
// Find the Initialized event in the logs
|
|
89
|
+
const initializedLog = receipt.logs.find((log) => {
|
|
90
|
+
try {
|
|
91
|
+
const parsed = iface.parseLog(log);
|
|
92
|
+
return parsed.name === "Initialized";
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
if (initializedLog) {
|
|
99
|
+
const parsedLog = iface.parseLog(initializedLog);
|
|
100
|
+
poolId = parsedLog.args.poolId.toString();
|
|
101
|
+
console.log(`Transaction ${tx.hash} - Found poolId: ${poolId}`);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
poolId = receipt.logs[receipt.logs.length - 1].topics[1]; // Fallback to Initialized order logic
|
|
105
|
+
console.log(`No Initialized event found in tx ${tx.hash}`);
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
poolId: BigInt(poolId).toString(),
|
|
109
|
+
txHash: tx.hash,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.error(`Failed to create pool: ${error}`);
|
|
114
|
+
throw new Error(`Failed to create pool metadata: ${error}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async updatePoolMetadata(poolId, poolMetadata, callback) {
|
|
118
|
+
try {
|
|
119
|
+
callback?.("preparing");
|
|
120
|
+
const metadata_cid = await this.saveAndGetCID(poolMetadata);
|
|
121
|
+
const metadata = {
|
|
122
|
+
protocol: 1,
|
|
123
|
+
pointer: metadata_cid,
|
|
124
|
+
};
|
|
125
|
+
const tx = await this.contract.updatePoolMetadata(poolId, metadata);
|
|
126
|
+
callback?.("pending");
|
|
127
|
+
const receipt = await tx.wait();
|
|
128
|
+
callback?.("confirmed");
|
|
129
|
+
return receipt;
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
console.error(`Failed to update pool metadata: ${error}`);
|
|
133
|
+
throw new Error(`Failed to update pool metadata: ${error}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
exports.AlloBase = AlloBase;
|