@poa-box/core 0.1.0 → 1.0.0
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/README.md +2 -0
- package/dist/abis/AuthorityRouter.d.ts +448 -0
- package/dist/abis/AuthorityRouter.js +584 -0
- package/dist/abis/CutoverVerifier.d.ts +194 -0
- package/dist/abis/CutoverVerifier.js +259 -0
- package/dist/abis/DirectDemocracyVotingNew.d.ts +168 -30
- package/dist/abis/DirectDemocracyVotingNew.js +214 -35
- package/dist/abis/EducationHubNew.d.ts +32 -75
- package/dist/abis/EducationHubNew.js +38 -94
- package/dist/abis/Executor.d.ts +56 -86
- package/dist/abis/Executor.js +68 -104
- package/dist/abis/HybridVotingNew.d.ts +279 -35
- package/dist/abis/HybridVotingNew.js +357 -40
- package/dist/abis/{EligibilityModuleNew.d.ts → MembershipAuthority.d.ts} +1437 -718
- package/dist/abis/{EligibilityModuleNew.js → MembershipAuthority.js} +1821 -899
- package/dist/abis/OrgDeployerNew.d.ts +193 -127
- package/dist/abis/OrgDeployerNew.js +244 -160
- package/dist/abis/OrgRegistry.d.ts +40 -0
- package/dist/abis/OrgRegistry.js +51 -0
- package/dist/abis/ParticipationToken.d.ts +32 -75
- package/dist/abis/ParticipationToken.js +38 -94
- package/dist/abis/PasskeyAccount.d.ts +28 -0
- package/dist/abis/PasskeyAccount.js +35 -0
- package/dist/abis/PaymasterHub.d.ts +527 -47
- package/dist/abis/PaymasterHub.js +750 -135
- package/dist/abis/QuickJoinNew.d.ts +59 -170
- package/dist/abis/QuickJoinNew.js +71 -215
- package/dist/abis/TaskManagerNew.d.ts +27 -44
- package/dist/abis/TaskManagerNew.js +31 -52
- package/dist/abis/UniversalAccountRegistry.d.ts +24 -0
- package/dist/abis/UniversalAccountRegistry.js +30 -0
- package/dist/abis/ZkEmailInvites.d.ts +44 -0
- package/dist/abis/ZkEmailInvites.js +55 -0
- package/dist/abis/index.d.ts +6 -4
- package/dist/abis/index.js +10 -7
- package/dist/chains.js +3 -3
- package/dist/error-catalog.js +125 -7
- package/dist/graph/documents/activity.d.ts +3 -1
- package/dist/graph/documents/activity.js +19 -14
- package/dist/graph/documents/org.d.ts +4 -4
- package/dist/graph/documents/org.js +10 -4
- package/dist/graph/documents/task.d.ts +10 -1
- package/dist/graph/documents/task.js +157 -3
- package/dist/graph/documents/user.d.ts +5 -30
- package/dist/graph/documents/user.js +2 -42
- package/dist/graph/documents/voting-classes.d.ts +23 -2
- package/dist/graph/documents/voting-classes.js +119 -10
- package/dist/metadata/index.d.ts +0 -1
- package/dist/metadata/index.js +1 -2
- package/dist/perms.d.ts +0 -15
- package/dist/perms.js +1 -21
- package/dist/preflight.d.ts +2 -2
- package/dist/preflight.js +14 -22
- package/dist/reads/authority.d.ts +33 -0
- package/dist/reads/authority.js +196 -0
- package/dist/reads/index.d.ts +1 -1
- package/dist/reads/index.js +2 -2
- package/dist/reads/org.d.ts +20 -20
- package/dist/reads/org.js +94 -28
- package/dist/reads/project.js +3 -3
- package/dist/reads/resolve.d.ts +1 -1
- package/dist/reads/resolve.js +12 -3
- package/dist/reads/task.d.ts +44 -22
- package/dist/reads/task.js +126 -67
- package/dist/reads/user.d.ts +8 -43
- package/dist/reads/user.js +27 -44
- package/dist/reads/vote.d.ts +26 -2
- package/dist/reads/vote.js +104 -23
- package/dist/tx/authority.d.ts +33 -0
- package/dist/tx/authority.js +62 -0
- package/dist/tx/governance.d.ts +6 -0
- package/dist/tx/governance.js +20 -2
- package/dist/tx/index.d.ts +1 -1
- package/dist/tx/index.js +2 -2
- package/dist/tx/org.d.ts +23 -18
- package/dist/tx/org.js +203 -67
- package/dist/tx/project.d.ts +3 -2
- package/dist/tx/project.js +28 -10
- package/dist/tx/task.d.ts +13 -24
- package/dist/tx/task.js +45 -85
- package/dist/tx/user.d.ts +2 -40
- package/dist/tx/user.js +2 -76
- package/dist/tx/vote.d.ts +5 -0
- package/dist/tx/vote.js +54 -43
- package/dist/version.d.ts +0 -5
- package/dist/version.js +1 -13
- package/package.json +1 -1
- package/dist/abis/ToggleModule.d.ts +0 -193
- package/dist/abis/ToggleModule.js +0 -255
- package/dist/metadata/role.d.ts +0 -38
- package/dist/metadata/role.js +0 -35
- package/dist/reads/eligibility.d.ts +0 -377
- package/dist/reads/eligibility.js +0 -687
- package/dist/tx/eligibility.d.ts +0 -511
- package/dist/tx/eligibility.js +0 -818
package/dist/tx/eligibility.js
DELETED
|
@@ -1,818 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* EligibilityModuleNew transaction builders — the vouch/* and role/* write
|
|
4
|
-
* surface (both CLI domains write to the same module).
|
|
5
|
-
*
|
|
6
|
-
* Level 1 (`build*`): pure, synchronous — resolved module address + prepared
|
|
7
|
-
* values in, TxIntent out. ALL argument encoding lives here and matches the
|
|
8
|
-
* CLI's executeTx calls byte-for-byte.
|
|
9
|
-
*
|
|
10
|
-
* Level 2 (`*Intent`): async — resolve the org's eligibility module via the
|
|
11
|
-
* subgraph, replicate the CLI's derivations (role-name→hatId, single-vs-batch
|
|
12
|
-
* method choice, metadata pinning for role applications, the audit-M-03
|
|
13
|
-
* vouch/default-eligibility conflict guard), then delegate to Level 1.
|
|
14
|
-
*
|
|
15
|
-
* NOT ported into builders (host concerns, run them via reads/eligibility +
|
|
16
|
-
* preflight.ts exactly as the CLI does): requireSuperAdmin, the vouch-for /
|
|
17
|
-
* claim / revoke revert-prediction gates, gas-balance checks, idempotency,
|
|
18
|
-
* and confirmation prompts. The ONE preflight that IS ported is the M-03
|
|
19
|
-
* conflict guard in configureVouchingIntent / setDefaultEligibilityIntent,
|
|
20
|
-
* because its state check + callStatic simulation is the only version-proof
|
|
21
|
-
* predictor of the DefaultEligibilityConflictsWithVouch revert and the CLI
|
|
22
|
-
* enforces it inline (src/commands/vouch/config.ts,
|
|
23
|
-
* src/commands/role/eligibility.ts).
|
|
24
|
-
*/
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.buildVouchFor = buildVouchFor;
|
|
27
|
-
exports.buildClaimVouchedHat = buildClaimVouchedHat;
|
|
28
|
-
exports.buildRevokeVouch = buildRevokeVouch;
|
|
29
|
-
exports.buildResetVouches = buildResetVouches;
|
|
30
|
-
exports.buildClearWearerVouches = buildClearWearerVouches;
|
|
31
|
-
exports.buildConfigureVouching = buildConfigureVouching;
|
|
32
|
-
exports.buildApplyForRole = buildApplyForRole;
|
|
33
|
-
exports.buildWithdrawApplication = buildWithdrawApplication;
|
|
34
|
-
exports.buildCreateHatWithEligibility = buildCreateHatWithEligibility;
|
|
35
|
-
exports.buildSetWearerEligibility = buildSetWearerEligibility;
|
|
36
|
-
exports.buildBatchSetWearerEligibility = buildBatchSetWearerEligibility;
|
|
37
|
-
exports.buildClearWearerEligibility = buildClearWearerEligibility;
|
|
38
|
-
exports.buildSetDefaultEligibility = buildSetDefaultEligibility;
|
|
39
|
-
exports.buildTransferSuperAdmin = buildTransferSuperAdmin;
|
|
40
|
-
exports.buildMintHatToAddress = buildMintHatToAddress;
|
|
41
|
-
exports.buildBatchMintHats = buildBatchMintHats;
|
|
42
|
-
exports.buildPause = buildPause;
|
|
43
|
-
exports.buildUnpause = buildUnpause;
|
|
44
|
-
exports.buildSetUserJoinTime = buildSetUserJoinTime;
|
|
45
|
-
exports.buildSetUserJoinTimeNow = buildSetUserJoinTimeNow;
|
|
46
|
-
exports.vouchForIntent = vouchForIntent;
|
|
47
|
-
exports.claimVouchedHatIntent = claimVouchedHatIntent;
|
|
48
|
-
exports.revokeVouchIntent = revokeVouchIntent;
|
|
49
|
-
exports.resetVouchesIntent = resetVouchesIntent;
|
|
50
|
-
exports.configureVouchingIntent = configureVouchingIntent;
|
|
51
|
-
exports.applyForRoleIntent = applyForRoleIntent;
|
|
52
|
-
exports.withdrawApplicationIntent = withdrawApplicationIntent;
|
|
53
|
-
exports.parseMintTo = parseMintTo;
|
|
54
|
-
exports.createHatWithEligibilityIntent = createHatWithEligibilityIntent;
|
|
55
|
-
exports.setWearerEligibilityIntent = setWearerEligibilityIntent;
|
|
56
|
-
exports.batchSetWearerEligibilityIntent = batchSetWearerEligibilityIntent;
|
|
57
|
-
exports.clearWearerEligibilityIntent = clearWearerEligibilityIntent;
|
|
58
|
-
exports.setDefaultEligibilityIntent = setDefaultEligibilityIntent;
|
|
59
|
-
exports.transferSuperAdminIntent = transferSuperAdminIntent;
|
|
60
|
-
exports.mintHatsIntent = mintHatsIntent;
|
|
61
|
-
exports.pauseIntent = pauseIntent;
|
|
62
|
-
exports.unpauseIntent = unpauseIntent;
|
|
63
|
-
exports.setUserJoinTimeIntent = setUserJoinTimeIntent;
|
|
64
|
-
const contracts_1 = require("../contracts");
|
|
65
|
-
const errors_1 = require("../errors");
|
|
66
|
-
const exit_codes_1 = require("../exit-codes");
|
|
67
|
-
const ipfs_1 = require("../ipfs");
|
|
68
|
-
const encoding_1 = require("../encoding");
|
|
69
|
-
const validation_1 = require("../validation");
|
|
70
|
-
const perms_1 = require("../perms");
|
|
71
|
-
const role_1 = require("../metadata/role");
|
|
72
|
-
const eligibility_1 = require("../reads/eligibility");
|
|
73
|
-
const ABI_NAME = 'EligibilityModuleNew';
|
|
74
|
-
/** Port of `pop vouch for` — src/commands/vouch/for.ts: vouchFor(wearer, hatId). */
|
|
75
|
-
function buildVouchFor(a) {
|
|
76
|
-
return {
|
|
77
|
-
to: a.eligibilityModuleAddress,
|
|
78
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
79
|
-
method: 'vouchFor',
|
|
80
|
-
args: [a.wearer, a.hatId],
|
|
81
|
-
meta: {
|
|
82
|
-
domain: 'vouch',
|
|
83
|
-
action: 'for',
|
|
84
|
-
orgId: a.orgId,
|
|
85
|
-
summary: { wearer: a.wearer, hat: String(a.hatId) },
|
|
86
|
-
},
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Port of `pop vouch claim` — src/commands/vouch/claim.ts:
|
|
91
|
-
* claimVouchedHat(hatId). Claim-based pattern — quorum never auto-mints.
|
|
92
|
-
*/
|
|
93
|
-
function buildClaimVouchedHat(a) {
|
|
94
|
-
return {
|
|
95
|
-
to: a.eligibilityModuleAddress,
|
|
96
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
97
|
-
method: 'claimVouchedHat',
|
|
98
|
-
args: [a.hatId],
|
|
99
|
-
meta: {
|
|
100
|
-
domain: 'vouch',
|
|
101
|
-
action: 'claim',
|
|
102
|
-
orgId: a.orgId,
|
|
103
|
-
summary: { hat: String(a.hatId) },
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
/** Port of `pop vouch revoke` — src/commands/vouch/revoke.ts: revokeVouch(wearer, hatId). */
|
|
108
|
-
function buildRevokeVouch(a) {
|
|
109
|
-
return {
|
|
110
|
-
to: a.eligibilityModuleAddress,
|
|
111
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
112
|
-
method: 'revokeVouch',
|
|
113
|
-
args: [a.wearer, a.hatId],
|
|
114
|
-
meta: {
|
|
115
|
-
domain: 'vouch',
|
|
116
|
-
action: 'revoke',
|
|
117
|
-
orgId: a.orgId,
|
|
118
|
-
summary: { wearer: a.wearer, hat: String(a.hatId) },
|
|
119
|
-
},
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Port of `pop vouch reset` (no --wearer) — src/commands/vouch/reset.ts:
|
|
124
|
-
* resetVouches(hatId). DESTRUCTIVE, superAdmin-only: DELETES the hat's
|
|
125
|
-
* VouchConfig (vouching becomes disabled) and bumps the vouch epoch so every
|
|
126
|
-
* existing vouch for the hat is invalidated.
|
|
127
|
-
*/
|
|
128
|
-
function buildResetVouches(a) {
|
|
129
|
-
return {
|
|
130
|
-
to: a.eligibilityModuleAddress,
|
|
131
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
132
|
-
method: 'resetVouches',
|
|
133
|
-
args: [a.hatId],
|
|
134
|
-
meta: {
|
|
135
|
-
domain: 'vouch',
|
|
136
|
-
action: 'reset',
|
|
137
|
-
orgId: a.orgId,
|
|
138
|
-
summary: { hat: String(a.hatId), scope: 'whole-hat' },
|
|
139
|
-
},
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Port of `pop vouch reset --wearer` — src/commands/vouch/reset.ts:
|
|
144
|
-
* clearWearerVouches(wearer, hatId). Surgical per-wearer invalidation
|
|
145
|
-
* (sentinel epoch + count wipe); other wearers' vouches and the hat's config
|
|
146
|
-
* are untouched. superAdmin-only.
|
|
147
|
-
*/
|
|
148
|
-
function buildClearWearerVouches(a) {
|
|
149
|
-
return {
|
|
150
|
-
to: a.eligibilityModuleAddress,
|
|
151
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
152
|
-
method: 'clearWearerVouches',
|
|
153
|
-
args: [a.wearer, a.hatId],
|
|
154
|
-
meta: {
|
|
155
|
-
domain: 'vouch',
|
|
156
|
-
action: 'clear-wearer',
|
|
157
|
-
orgId: a.orgId,
|
|
158
|
-
summary: { hat: String(a.hatId), wearer: a.wearer, scope: 'single-wearer' },
|
|
159
|
-
},
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Port of `pop vouch config set` — src/commands/vouch/config.ts:
|
|
164
|
-
* configureVouching(hatId, quorum, membershipHatId, combineWithHierarchy).
|
|
165
|
-
* superAdmin-only; configuring bumps the hat's vouch epoch, invalidating all
|
|
166
|
-
* existing vouches.
|
|
167
|
-
*/
|
|
168
|
-
function buildConfigureVouching(a) {
|
|
169
|
-
return {
|
|
170
|
-
to: a.eligibilityModuleAddress,
|
|
171
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
172
|
-
method: 'configureVouching',
|
|
173
|
-
args: [a.hatId, a.quorum, a.membershipHatId, a.combineWithHierarchy],
|
|
174
|
-
meta: {
|
|
175
|
-
domain: 'vouch',
|
|
176
|
-
action: 'config-set',
|
|
177
|
-
orgId: a.orgId,
|
|
178
|
-
summary: {
|
|
179
|
-
hat: String(a.hatId),
|
|
180
|
-
quorum: a.quorum,
|
|
181
|
-
membershipHat: String(a.membershipHatId),
|
|
182
|
-
combineWithHierarchy: a.combineWithHierarchy,
|
|
183
|
-
},
|
|
184
|
-
},
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Port of `pop role apply` — src/commands/role/apply.ts:
|
|
189
|
-
* applyForRole(hatId, applicationHash). Signaling only — grants no
|
|
190
|
-
* eligibility.
|
|
191
|
-
*/
|
|
192
|
-
function buildApplyForRole(a) {
|
|
193
|
-
return {
|
|
194
|
-
to: a.eligibilityModuleAddress,
|
|
195
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
196
|
-
method: 'applyForRole',
|
|
197
|
-
args: [a.hatId, a.applicationHash],
|
|
198
|
-
meta: {
|
|
199
|
-
domain: 'role',
|
|
200
|
-
action: 'apply',
|
|
201
|
-
orgId: a.orgId,
|
|
202
|
-
summary: { hat: String(a.hatId) },
|
|
203
|
-
},
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Port of `pop role withdraw-application` —
|
|
208
|
-
* src/commands/role/withdraw-application.ts: withdrawApplication(hatId).
|
|
209
|
-
*/
|
|
210
|
-
function buildWithdrawApplication(a) {
|
|
211
|
-
return {
|
|
212
|
-
to: a.eligibilityModuleAddress,
|
|
213
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
214
|
-
method: 'withdrawApplication',
|
|
215
|
-
args: [a.hatId],
|
|
216
|
-
meta: {
|
|
217
|
-
domain: 'role',
|
|
218
|
-
action: 'withdraw-application',
|
|
219
|
-
orgId: a.orgId,
|
|
220
|
-
summary: { hat: String(a.hatId) },
|
|
221
|
-
},
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Port of `pop role create` — src/commands/role/create.ts:
|
|
226
|
-
* createHatWithEligibility(CreateHatParams). The tuple is built in EXACT ABI
|
|
227
|
-
* order (verified in abi CreateHatParams components):
|
|
228
|
-
* (uint256 parentHatId, string details, uint32 maxSupply, bool _mutable,
|
|
229
|
-
* string imageURI, bool defaultEligible, bool defaultStanding,
|
|
230
|
-
* address[] mintToAddresses, bool[] wearerEligibleFlags,
|
|
231
|
-
* bool[] wearerStandingFlags)
|
|
232
|
-
* superAdmin-only.
|
|
233
|
-
*/
|
|
234
|
-
function buildCreateHatWithEligibility(a) {
|
|
235
|
-
const mintTo = a.mintTo ?? [];
|
|
236
|
-
const eligibleFlags = a.wearerEligibleFlags ?? mintTo.map(() => true);
|
|
237
|
-
const standingFlags = a.wearerStandingFlags ?? mintTo.map(() => true);
|
|
238
|
-
if (eligibleFlags.length !== mintTo.length || standingFlags.length !== mintTo.length) {
|
|
239
|
-
throw new errors_1.CliError('wearerEligibleFlags/wearerStandingFlags must match mintTo length.', exit_codes_1.EXIT.USAGE);
|
|
240
|
-
}
|
|
241
|
-
// CreateHatParams tuple — MUST match ABI component order (see doc comment).
|
|
242
|
-
const params = [
|
|
243
|
-
a.parentHatId, // parentHatId (uint256)
|
|
244
|
-
a.details, // details (string)
|
|
245
|
-
a.maxSupply, // maxSupply (uint32)
|
|
246
|
-
a.mutable, // _mutable (bool)
|
|
247
|
-
a.imageURI ?? '', // imageURI (string)
|
|
248
|
-
a.defaultEligible, // defaultEligible (bool)
|
|
249
|
-
a.defaultStanding, // defaultStanding (bool)
|
|
250
|
-
mintTo, // mintToAddresses (address[])
|
|
251
|
-
eligibleFlags, // wearerEligibleFlags (bool[])
|
|
252
|
-
standingFlags, // wearerStandingFlags (bool[])
|
|
253
|
-
];
|
|
254
|
-
return {
|
|
255
|
-
to: a.eligibilityModuleAddress,
|
|
256
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
257
|
-
method: 'createHatWithEligibility',
|
|
258
|
-
args: [params],
|
|
259
|
-
meta: {
|
|
260
|
-
domain: 'role',
|
|
261
|
-
action: 'create',
|
|
262
|
-
orgId: a.orgId,
|
|
263
|
-
summary: {
|
|
264
|
-
name: a.details,
|
|
265
|
-
parentHat: String(a.parentHatId),
|
|
266
|
-
maxSupply: a.maxSupply,
|
|
267
|
-
mintTo: mintTo.length,
|
|
268
|
-
},
|
|
269
|
-
},
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Port of `pop role eligibility set` (single-wearer) —
|
|
274
|
-
* src/commands/role/eligibility.ts:
|
|
275
|
-
* setWearerEligibility(wearer, hatId, eligible, standing). superAdmin-only.
|
|
276
|
-
*/
|
|
277
|
-
function buildSetWearerEligibility(a) {
|
|
278
|
-
return {
|
|
279
|
-
to: a.eligibilityModuleAddress,
|
|
280
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
281
|
-
method: 'setWearerEligibility',
|
|
282
|
-
args: [a.wearer, a.hatId, a.eligible, a.standing],
|
|
283
|
-
meta: {
|
|
284
|
-
domain: 'role',
|
|
285
|
-
action: 'eligibility-set',
|
|
286
|
-
orgId: a.orgId,
|
|
287
|
-
summary: { hat: String(a.hatId), wearer: a.wearer, eligible: a.eligible, standing: a.standing },
|
|
288
|
-
},
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Port of `pop role eligibility set --file` (batch) —
|
|
293
|
-
* src/commands/role/eligibility.ts:
|
|
294
|
-
* batchSetWearerEligibility(hatId, wearers[], eligibleFlags[], standingFlags[]).
|
|
295
|
-
* superAdmin-only.
|
|
296
|
-
*/
|
|
297
|
-
function buildBatchSetWearerEligibility(a) {
|
|
298
|
-
if (a.eligibleFlags.length !== a.wearers.length || a.standingFlags.length !== a.wearers.length) {
|
|
299
|
-
throw new errors_1.CliError('eligibleFlags/standingFlags must match wearers length.', exit_codes_1.EXIT.USAGE);
|
|
300
|
-
}
|
|
301
|
-
return {
|
|
302
|
-
to: a.eligibilityModuleAddress,
|
|
303
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
304
|
-
method: 'batchSetWearerEligibility',
|
|
305
|
-
args: [a.hatId, a.wearers, a.eligibleFlags, a.standingFlags],
|
|
306
|
-
meta: {
|
|
307
|
-
domain: 'role',
|
|
308
|
-
action: 'eligibility-set-batch',
|
|
309
|
-
orgId: a.orgId,
|
|
310
|
-
summary: { hat: String(a.hatId), count: a.wearers.length },
|
|
311
|
-
},
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Port of `pop role eligibility clear` — src/commands/role/eligibility.ts:
|
|
316
|
-
* clearWearerEligibility(wearer, hatId) — removes the wearer-specific rule so
|
|
317
|
-
* the hat DEFAULTS apply again. superAdmin-only.
|
|
318
|
-
*/
|
|
319
|
-
function buildClearWearerEligibility(a) {
|
|
320
|
-
return {
|
|
321
|
-
to: a.eligibilityModuleAddress,
|
|
322
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
323
|
-
method: 'clearWearerEligibility',
|
|
324
|
-
args: [a.wearer, a.hatId],
|
|
325
|
-
meta: {
|
|
326
|
-
domain: 'role',
|
|
327
|
-
action: 'eligibility-clear',
|
|
328
|
-
orgId: a.orgId,
|
|
329
|
-
summary: { hat: String(a.hatId), wearer: a.wearer },
|
|
330
|
-
},
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
|
-
/**
|
|
334
|
-
* Port of `pop role eligibility set-default` —
|
|
335
|
-
* src/commands/role/eligibility.ts:
|
|
336
|
-
* setDefaultEligibility(hatId, eligible, standing). superAdmin-only. See
|
|
337
|
-
* setDefaultEligibilityIntent for the audit-M-03 conflict guard the CLI runs
|
|
338
|
-
* before this write.
|
|
339
|
-
*/
|
|
340
|
-
function buildSetDefaultEligibility(a) {
|
|
341
|
-
return {
|
|
342
|
-
to: a.eligibilityModuleAddress,
|
|
343
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
344
|
-
method: 'setDefaultEligibility',
|
|
345
|
-
args: [a.hatId, a.eligible, a.standing],
|
|
346
|
-
meta: {
|
|
347
|
-
domain: 'role',
|
|
348
|
-
action: 'eligibility-set-default',
|
|
349
|
-
orgId: a.orgId,
|
|
350
|
-
summary: { hat: String(a.hatId), eligible: a.eligible, standing: a.standing },
|
|
351
|
-
},
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Port of `pop role admin transfer` — src/commands/role/admin.ts:
|
|
356
|
-
* transferSuperAdmin(newSuperAdmin). DESTRUCTIVE — hands over the ENTIRE
|
|
357
|
-
* module (roles, eligibility, vouching, pause). superAdmin-only.
|
|
358
|
-
*/
|
|
359
|
-
function buildTransferSuperAdmin(a) {
|
|
360
|
-
return {
|
|
361
|
-
to: a.eligibilityModuleAddress,
|
|
362
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
363
|
-
method: 'transferSuperAdmin',
|
|
364
|
-
args: [a.newSuperAdmin],
|
|
365
|
-
meta: {
|
|
366
|
-
domain: 'role',
|
|
367
|
-
action: 'admin-transfer',
|
|
368
|
-
orgId: a.orgId,
|
|
369
|
-
summary: { newSuperAdmin: a.newSuperAdmin },
|
|
370
|
-
},
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
/**
|
|
374
|
-
* Port of `pop role admin mint` (single wearer) — src/commands/role/admin.ts:
|
|
375
|
-
* mintHatToAddress(hatId, wearer). superAdmin-only.
|
|
376
|
-
*/
|
|
377
|
-
function buildMintHatToAddress(a) {
|
|
378
|
-
return {
|
|
379
|
-
to: a.eligibilityModuleAddress,
|
|
380
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
381
|
-
method: 'mintHatToAddress',
|
|
382
|
-
args: [a.hatId, a.wearer],
|
|
383
|
-
meta: {
|
|
384
|
-
domain: 'role',
|
|
385
|
-
action: 'admin-mint',
|
|
386
|
-
orgId: a.orgId,
|
|
387
|
-
summary: { hat: String(a.hatId), wearer: a.wearer },
|
|
388
|
-
},
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Port of `pop role admin mint` (comma-separated wearers) —
|
|
393
|
-
* src/commands/role/admin.ts: batchMintHats(hatIds[], wearers[]). The CLI
|
|
394
|
-
* replicates ONE hat per wearer (`wearers.map(() => hatId)`); mintHatsIntent
|
|
395
|
-
* derives that. superAdmin-only.
|
|
396
|
-
*/
|
|
397
|
-
function buildBatchMintHats(a) {
|
|
398
|
-
if (a.hatIds.length !== a.wearers.length) {
|
|
399
|
-
throw new errors_1.CliError('hatIds must match wearers length.', exit_codes_1.EXIT.USAGE);
|
|
400
|
-
}
|
|
401
|
-
return {
|
|
402
|
-
to: a.eligibilityModuleAddress,
|
|
403
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
404
|
-
method: 'batchMintHats',
|
|
405
|
-
args: [a.hatIds, a.wearers],
|
|
406
|
-
meta: {
|
|
407
|
-
domain: 'role',
|
|
408
|
-
action: 'admin-mint-batch',
|
|
409
|
-
orgId: a.orgId,
|
|
410
|
-
summary: { count: a.wearers.length },
|
|
411
|
-
},
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
/** Port of `pop role admin pause` — src/commands/role/admin.ts: pause(). superAdmin-only. */
|
|
415
|
-
function buildPause(a) {
|
|
416
|
-
return {
|
|
417
|
-
to: a.eligibilityModuleAddress,
|
|
418
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
419
|
-
method: 'pause',
|
|
420
|
-
args: [],
|
|
421
|
-
meta: {
|
|
422
|
-
domain: 'role',
|
|
423
|
-
action: 'admin-pause',
|
|
424
|
-
orgId: a.orgId,
|
|
425
|
-
summary: { module: a.eligibilityModuleAddress },
|
|
426
|
-
},
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
/** Port of `pop role admin unpause` — src/commands/role/admin.ts: unpause(). superAdmin-only. */
|
|
430
|
-
function buildUnpause(a) {
|
|
431
|
-
return {
|
|
432
|
-
to: a.eligibilityModuleAddress,
|
|
433
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
434
|
-
method: 'unpause',
|
|
435
|
-
args: [],
|
|
436
|
-
meta: {
|
|
437
|
-
domain: 'role',
|
|
438
|
-
action: 'admin-unpause',
|
|
439
|
-
orgId: a.orgId,
|
|
440
|
-
summary: { module: a.eligibilityModuleAddress },
|
|
441
|
-
},
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Port of `pop role admin set-join-time --timestamp` —
|
|
446
|
-
* src/commands/role/admin.ts: setUserJoinTime(user, joinTime). Governs the
|
|
447
|
-
* new-account vouching grace. superAdmin-only.
|
|
448
|
-
*/
|
|
449
|
-
function buildSetUserJoinTime(a) {
|
|
450
|
-
return {
|
|
451
|
-
to: a.eligibilityModuleAddress,
|
|
452
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
453
|
-
method: 'setUserJoinTime',
|
|
454
|
-
args: [a.user, a.joinTime],
|
|
455
|
-
meta: {
|
|
456
|
-
domain: 'role',
|
|
457
|
-
action: 'admin-set-join-time',
|
|
458
|
-
orgId: a.orgId,
|
|
459
|
-
summary: { user: a.user, timestamp: String(a.joinTime) },
|
|
460
|
-
},
|
|
461
|
-
};
|
|
462
|
-
}
|
|
463
|
-
/**
|
|
464
|
-
* Port of `pop role admin set-join-time` (no --timestamp) —
|
|
465
|
-
* src/commands/role/admin.ts: setUserJoinTimeNow(user) — uses the current
|
|
466
|
-
* block time. superAdmin-only.
|
|
467
|
-
*/
|
|
468
|
-
function buildSetUserJoinTimeNow(a) {
|
|
469
|
-
return {
|
|
470
|
-
to: a.eligibilityModuleAddress,
|
|
471
|
-
abi: (0, contracts_1.getAbi)(ABI_NAME),
|
|
472
|
-
method: 'setUserJoinTimeNow',
|
|
473
|
-
args: [a.user],
|
|
474
|
-
meta: {
|
|
475
|
-
domain: 'role',
|
|
476
|
-
action: 'admin-set-join-time',
|
|
477
|
-
orgId: a.orgId,
|
|
478
|
-
summary: { user: a.user, timestamp: 'now' },
|
|
479
|
-
},
|
|
480
|
-
};
|
|
481
|
-
}
|
|
482
|
-
/** Port of `pop vouch for` — src/commands/vouch/for.ts (org + role-name resolution). */
|
|
483
|
-
async function vouchForIntent(ctx, params) {
|
|
484
|
-
const wearer = (0, validation_1.requireAddress)(params.wearer, 'address');
|
|
485
|
-
let hatId = params.hat !== undefined ? String(params.hat) : undefined;
|
|
486
|
-
if (!hatId && params.role) {
|
|
487
|
-
hatId = await (0, eligibility_1.resolveRoleNameToHatId)(ctx.client, params.org, params.role, ctx.chainId);
|
|
488
|
-
}
|
|
489
|
-
if (!hatId) {
|
|
490
|
-
throw new errors_1.CliError('Either --hat or --role is required', exit_codes_1.EXIT.USAGE);
|
|
491
|
-
}
|
|
492
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
493
|
-
if (params.voucher && wearer.toLowerCase() === params.voucher.toLowerCase()) {
|
|
494
|
-
throw new errors_1.PreconditionError('You cannot vouch for yourself.', 'Ask another member holding the membership hat to vouch for you.');
|
|
495
|
-
}
|
|
496
|
-
return buildVouchFor({ eligibilityModuleAddress, wearer, hatId, orgId });
|
|
497
|
-
}
|
|
498
|
-
/** Port of `pop vouch claim` — src/commands/vouch/claim.ts (org resolution). */
|
|
499
|
-
async function claimVouchedHatIntent(ctx, params) {
|
|
500
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
501
|
-
return buildClaimVouchedHat({ eligibilityModuleAddress, hatId: String(params.hat), orgId });
|
|
502
|
-
}
|
|
503
|
-
/** Port of `pop vouch revoke` — src/commands/vouch/revoke.ts (org resolution). */
|
|
504
|
-
async function revokeVouchIntent(ctx, params) {
|
|
505
|
-
const wearer = (0, validation_1.requireAddress)(params.wearer, 'address');
|
|
506
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
507
|
-
return buildRevokeVouch({ eligibilityModuleAddress, wearer, hatId: String(params.hat), orgId });
|
|
508
|
-
}
|
|
509
|
-
/**
|
|
510
|
-
* Port of `pop vouch reset` — src/commands/vouch/reset.ts. Derives the method
|
|
511
|
-
* exactly as the CLI does: --wearer → clearWearerVouches (surgical), no
|
|
512
|
-
* --wearer → resetVouches (deletes the VouchConfig + bumps the epoch).
|
|
513
|
-
* DESTRUCTIVE, superAdmin-only.
|
|
514
|
-
*/
|
|
515
|
-
async function resetVouchesIntent(ctx, params) {
|
|
516
|
-
const hatId = (0, eligibility_1.parseHatId)(params.hat);
|
|
517
|
-
const wearer = params.wearer ? (0, validation_1.requireAddress)(params.wearer, 'wearer') : undefined;
|
|
518
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
519
|
-
return wearer
|
|
520
|
-
? buildClearWearerVouches({ eligibilityModuleAddress, wearer, hatId, orgId })
|
|
521
|
-
: buildResetVouches({ eligibilityModuleAddress, hatId, orgId });
|
|
522
|
-
}
|
|
523
|
-
/**
|
|
524
|
-
* Port of `pop vouch config set` — src/commands/vouch/config.ts, including the
|
|
525
|
-
* audit-M-03 reverse-direction guard: enabling vouching WITH combine-hierarchy
|
|
526
|
-
* on a hat that is already default-eligible reverts
|
|
527
|
-
* DefaultEligibilityConflictsWithVouch on modules that implement the check —
|
|
528
|
-
* everyone is eligible anyway, so the quorum would be a no-op. The state is
|
|
529
|
-
* detected via getDefaultRules, then the exact call is simulated from `from`
|
|
530
|
-
* (state alone is version-ambiguous — deployed v6 modules accept it). Only a
|
|
531
|
-
* contract revert blocks; transport failures degrade and let gas estimation be
|
|
532
|
-
* the real gate. Requires ctx.provider + params.from to run.
|
|
533
|
-
*/
|
|
534
|
-
async function configureVouchingIntent(ctx, params) {
|
|
535
|
-
const hatId = (0, eligibility_1.parseHatId)(params.hat);
|
|
536
|
-
const membershipHatId = (0, eligibility_1.parseHatId)(params.membershipHat);
|
|
537
|
-
const quorum = params.quorum;
|
|
538
|
-
if (!Number.isInteger(quorum) || quorum < 0 || quorum > 0xffffffff) {
|
|
539
|
-
throw new errors_1.CliError(`Invalid --quorum ${quorum}.`, exit_codes_1.EXIT.USAGE, 'Pass a non-negative integer (uint32).');
|
|
540
|
-
}
|
|
541
|
-
const combine = Boolean(params.combineHierarchy);
|
|
542
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
543
|
-
const needsDefaultRules = combine && quorum > 0;
|
|
544
|
-
if (params.preflight !== false && needsDefaultRules && ctx.provider && params.from) {
|
|
545
|
-
const [rulesResult] = await (0, eligibility_1.batchEligibilityReadsSettled)(ctx.provider, eligibilityModuleAddress, [
|
|
546
|
-
{ fn: 'getDefaultRules', args: [hatId] },
|
|
547
|
-
]);
|
|
548
|
-
// A failed read (older module without the getter) downgrades to a skipped
|
|
549
|
-
// soft check rather than blocking the write — same as the CLI.
|
|
550
|
-
const rules = rulesResult.status === 'fulfilled' ? rulesResult.value : null;
|
|
551
|
-
if (rules !== null && Boolean(rules.eligible ?? rules[0])) {
|
|
552
|
-
// The STATE conflicts, but only a module implementing the M-03 revert rejects the
|
|
553
|
-
// write — the deployed v6 modules do NOT. Simulate the exact call instead — the
|
|
554
|
-
// only version-proof revert predictor.
|
|
555
|
-
const sim = (0, contracts_1.createReadContract)(eligibilityModuleAddress, ABI_NAME, ctx.provider);
|
|
556
|
-
try {
|
|
557
|
-
await sim.callStatic.configureVouching(hatId, quorum, membershipHatId, combine, { from: params.from });
|
|
558
|
-
// Module accepts the write anyway (the CLI warns and proceeds).
|
|
559
|
-
}
|
|
560
|
-
catch (simErr) {
|
|
561
|
-
// Only a CONTRACT revert proves the module enforces M-03; a transport
|
|
562
|
-
// failure proves nothing and must not block a valid write.
|
|
563
|
-
if (simErr?.code === 'CALL_EXCEPTION' || simErr?.code === 'UNPREDICTABLE_GAS_LIMIT') {
|
|
564
|
-
throw new errors_1.PreconditionError(`Hat ${hatId} is default-eligible — everyone already qualifies — so a vouch quorum `
|
|
565
|
-
+ 'combined with the hat hierarchy would have no effect, and the module rejects it.', `Close the hat first: pop role eligibility set-default --hat ${hatId} --no-eligible, `
|
|
566
|
-
+ 'or re-run without --combine-hierarchy.');
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
return buildConfigureVouching({
|
|
572
|
-
eligibilityModuleAddress,
|
|
573
|
-
hatId,
|
|
574
|
-
quorum,
|
|
575
|
-
membershipHatId,
|
|
576
|
-
combineWithHierarchy: combine,
|
|
577
|
-
orgId,
|
|
578
|
-
});
|
|
579
|
-
}
|
|
580
|
-
/**
|
|
581
|
-
* Port of `pop role apply` — src/commands/role/apply.ts. Pins the
|
|
582
|
-
* {notes, experience, appliedAt} application metadata (metadata/role.ts —
|
|
583
|
-
* key order preserved for frontend/subgraph parity), converts the CID to
|
|
584
|
-
* bytes32, then delegates to buildApplyForRole. The pinned document rides in
|
|
585
|
-
* meta.ipfs.
|
|
586
|
-
*/
|
|
587
|
-
async function applyForRoleIntent(ctx, params) {
|
|
588
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
589
|
-
const metadata = (0, role_1.buildRoleApplicationMetadata)({
|
|
590
|
-
notes: params.notes,
|
|
591
|
-
experience: params.experience,
|
|
592
|
-
appliedAt: params.appliedAt,
|
|
593
|
-
});
|
|
594
|
-
const cid = await (0, ipfs_1.pinJson)((0, role_1.serializeRoleApplicationMetadata)(metadata), ctx.ipfs);
|
|
595
|
-
const applicationHash = (0, encoding_1.ipfsCidToBytes32)(cid);
|
|
596
|
-
const intent = buildApplyForRole({
|
|
597
|
-
eligibilityModuleAddress,
|
|
598
|
-
hatId: String(params.hat),
|
|
599
|
-
applicationHash,
|
|
600
|
-
orgId,
|
|
601
|
-
});
|
|
602
|
-
intent.meta.ipfs = { cid, metadata };
|
|
603
|
-
return intent;
|
|
604
|
-
}
|
|
605
|
-
/**
|
|
606
|
-
* Port of `pop role withdraw-application` —
|
|
607
|
-
* src/commands/role/withdraw-application.ts (org resolution).
|
|
608
|
-
*/
|
|
609
|
-
async function withdrawApplicationIntent(ctx, params) {
|
|
610
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
611
|
-
return buildWithdrawApplication({ eligibilityModuleAddress, hatId: String(params.hat), orgId });
|
|
612
|
-
}
|
|
613
|
-
/** Parse "--mint-to a,b,c" into checksummed addresses (empty when omitted). */
|
|
614
|
-
function parseMintTo(input) {
|
|
615
|
-
if (!input)
|
|
616
|
-
return [];
|
|
617
|
-
return input
|
|
618
|
-
.split(',')
|
|
619
|
-
.map(s => s.trim())
|
|
620
|
-
.filter(s => s.length > 0)
|
|
621
|
-
.map(addr => (0, validation_1.requireAddress)(addr, 'mint-to'));
|
|
622
|
-
}
|
|
623
|
-
/**
|
|
624
|
-
* Port of `pop role create` — src/commands/role/create.ts: validates
|
|
625
|
-
* max-supply (uint32), parses/checksums --mint-to, forces the per-mint-to
|
|
626
|
-
* eligible/standing flags TRUE, then delegates to
|
|
627
|
-
* buildCreateHatWithEligibility. superAdmin-only.
|
|
628
|
-
*/
|
|
629
|
-
async function createHatWithEligibilityIntent(ctx, params) {
|
|
630
|
-
const parentHatId = (0, eligibility_1.parseHatId)(params.parentHat);
|
|
631
|
-
const maxSupply = params.maxSupply ?? 1000;
|
|
632
|
-
if (!Number.isInteger(maxSupply) || maxSupply <= 0 || maxSupply > 0xffffffff) {
|
|
633
|
-
throw new errors_1.CliError(`Invalid --max-supply ${maxSupply}.`, exit_codes_1.EXIT.USAGE, 'Pass a positive integer that fits uint32.');
|
|
634
|
-
}
|
|
635
|
-
const mintTo = Array.isArray(params.mintTo)
|
|
636
|
-
? params.mintTo.map(addr => (0, validation_1.requireAddress)(addr, 'mint-to'))
|
|
637
|
-
: parseMintTo(params.mintTo);
|
|
638
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
639
|
-
return buildCreateHatWithEligibility({
|
|
640
|
-
eligibilityModuleAddress,
|
|
641
|
-
parentHatId,
|
|
642
|
-
details: params.name,
|
|
643
|
-
maxSupply,
|
|
644
|
-
mutable: Boolean(params.mutable),
|
|
645
|
-
imageURI: params.image ?? '',
|
|
646
|
-
defaultEligible: Boolean(params.defaultEligible),
|
|
647
|
-
defaultStanding: Boolean(params.defaultStanding),
|
|
648
|
-
mintTo,
|
|
649
|
-
orgId,
|
|
650
|
-
});
|
|
651
|
-
}
|
|
652
|
-
/**
|
|
653
|
-
* Port of `pop role eligibility set` (single wearer) —
|
|
654
|
-
* src/commands/role/eligibility.ts. superAdmin-only.
|
|
655
|
-
*/
|
|
656
|
-
async function setWearerEligibilityIntent(ctx, params) {
|
|
657
|
-
const hatId = (0, eligibility_1.parseHatId)(params.hat);
|
|
658
|
-
const wearer = (0, validation_1.requireAddress)(params.wearer, 'wearer');
|
|
659
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
660
|
-
return buildSetWearerEligibility({
|
|
661
|
-
eligibilityModuleAddress,
|
|
662
|
-
wearer,
|
|
663
|
-
hatId,
|
|
664
|
-
eligible: params.eligible !== false,
|
|
665
|
-
standing: params.standing !== false,
|
|
666
|
-
orgId,
|
|
667
|
-
});
|
|
668
|
-
}
|
|
669
|
-
/**
|
|
670
|
-
* Port of `pop role eligibility set --file` —
|
|
671
|
-
* src/commands/role/eligibility.ts: validates the entries (the CLI's batch
|
|
672
|
-
* JSON shape, minus the fs read — the host loads the file), defaults
|
|
673
|
-
* eligible/standing to true, and encodes
|
|
674
|
-
* batchSetWearerEligibility(hatId, wearers[], eligibles[], standings[]).
|
|
675
|
-
* superAdmin-only.
|
|
676
|
-
*/
|
|
677
|
-
async function batchSetWearerEligibilityIntent(ctx, params) {
|
|
678
|
-
const hatId = (0, eligibility_1.parseHatId)(params.hat);
|
|
679
|
-
if (!Array.isArray(params.entries) || params.entries.length === 0) {
|
|
680
|
-
throw new errors_1.CliError('Batch file must be a non-empty JSON array.', exit_codes_1.EXIT.USAGE, 'Expected: [{"wearer": "0x…", "eligible": true, "standing": true}, …]');
|
|
681
|
-
}
|
|
682
|
-
const batch = params.entries.map((entry, i) => {
|
|
683
|
-
if (!entry || typeof entry !== 'object' || !entry.wearer) {
|
|
684
|
-
throw new errors_1.CliError(`Batch entry ${i} is missing "wearer".`, exit_codes_1.EXIT.USAGE);
|
|
685
|
-
}
|
|
686
|
-
return {
|
|
687
|
-
wearer: (0, validation_1.requireAddress)(String(entry.wearer), `file entry ${i} wearer`),
|
|
688
|
-
eligible: entry.eligible === undefined ? true : Boolean(entry.eligible),
|
|
689
|
-
standing: entry.standing === undefined ? true : Boolean(entry.standing),
|
|
690
|
-
};
|
|
691
|
-
});
|
|
692
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
693
|
-
return buildBatchSetWearerEligibility({
|
|
694
|
-
eligibilityModuleAddress,
|
|
695
|
-
hatId,
|
|
696
|
-
wearers: batch.map(b => b.wearer),
|
|
697
|
-
eligibleFlags: batch.map(b => b.eligible),
|
|
698
|
-
standingFlags: batch.map(b => b.standing),
|
|
699
|
-
orgId,
|
|
700
|
-
});
|
|
701
|
-
}
|
|
702
|
-
/**
|
|
703
|
-
* Port of `pop role eligibility clear` — src/commands/role/eligibility.ts.
|
|
704
|
-
* superAdmin-only.
|
|
705
|
-
*/
|
|
706
|
-
async function clearWearerEligibilityIntent(ctx, params) {
|
|
707
|
-
const hatId = (0, eligibility_1.parseHatId)(params.hat);
|
|
708
|
-
const wearer = (0, validation_1.requireAddress)(params.wearer, 'wearer');
|
|
709
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
710
|
-
return buildClearWearerEligibility({ eligibilityModuleAddress, wearer, hatId, orgId });
|
|
711
|
-
}
|
|
712
|
-
/**
|
|
713
|
-
* Port of `pop role eligibility set-default` —
|
|
714
|
-
* src/commands/role/eligibility.ts, including the audit-M-03 guard: making a
|
|
715
|
-
* hat default-eligible while it uses vouching WITH combineWithHierarchy
|
|
716
|
-
* reverts DefaultEligibilityConflictsWithVouch — an open hat makes the vouch
|
|
717
|
-
* quorum meaningless. The state is detected via getVouchConfig +
|
|
718
|
-
* vouchConflictsWithDefaultEligibility (../perms — the browser-pure rule the
|
|
719
|
-
* CLI uses), then the exact call is simulated from `from`, because the state
|
|
720
|
-
* check alone is version-ambiguous: the deployed v6 modules ACCEPT the write
|
|
721
|
-
* (verified live — 17/19 live VouchConfig rows are in the "conflicting"
|
|
722
|
-
* state, so blocking on state alone would refuse a valid write on nearly
|
|
723
|
-
* every hat). Only a contract revert blocks; transport failures degrade and
|
|
724
|
-
* let gas estimation be the real gate. Requires ctx.provider + params.from.
|
|
725
|
-
* superAdmin-only.
|
|
726
|
-
*/
|
|
727
|
-
async function setDefaultEligibilityIntent(ctx, params) {
|
|
728
|
-
const hatId = (0, eligibility_1.parseHatId)(params.hat);
|
|
729
|
-
const eligible = params.eligible !== false;
|
|
730
|
-
const standing = params.standing !== false;
|
|
731
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
732
|
-
if (params.preflight !== false && eligible && ctx.provider && params.from) {
|
|
733
|
-
const [configResult] = await (0, eligibility_1.batchEligibilityReadsSettled)(ctx.provider, eligibilityModuleAddress, [
|
|
734
|
-
{ fn: 'getVouchConfig', args: [hatId] },
|
|
735
|
-
]);
|
|
736
|
-
// A failed read downgrades to a skipped soft check rather than blocking
|
|
737
|
-
// the write — same as the CLI.
|
|
738
|
-
const vc = configResult.status === 'fulfilled' ? configResult.value : null;
|
|
739
|
-
if (vc !== null && (0, perms_1.vouchConflictsWithDefaultEligibility)(Number(vc.flags), Number(vc.quorum), true)) {
|
|
740
|
-
// The STATE conflicts, but only a module that implements the M-03 revert
|
|
741
|
-
// actually rejects the write. Simulate the exact call instead — the only
|
|
742
|
-
// version-proof revert predictor.
|
|
743
|
-
const sim = (0, contracts_1.createReadContract)(eligibilityModuleAddress, ABI_NAME, ctx.provider);
|
|
744
|
-
try {
|
|
745
|
-
await sim.callStatic.setDefaultEligibility(hatId, eligible, standing, { from: params.from });
|
|
746
|
-
// Module accepts the write anyway (the CLI warns and proceeds).
|
|
747
|
-
}
|
|
748
|
-
catch (simErr) {
|
|
749
|
-
// Only a CONTRACT revert proves the module enforces M-03; a transport
|
|
750
|
-
// failure proves nothing and must not block a valid write.
|
|
751
|
-
if (simErr?.code === 'CALL_EXCEPTION' || simErr?.code === 'UNPREDICTABLE_GAS_LIMIT') {
|
|
752
|
-
throw new errors_1.PreconditionError(`Hat ${hatId} uses vouching with combine-hierarchy (quorum ${vc.quorum}). Making it `
|
|
753
|
-
+ 'default-eligible would make that quorum a no-op, so the module rejects it.', 'Drop combine-hierarchy or disable vouching first: '
|
|
754
|
-
+ `pop vouch config set --hat ${hatId} --quorum 0`);
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
return buildSetDefaultEligibility({ eligibilityModuleAddress, hatId, eligible, standing, orgId });
|
|
760
|
-
}
|
|
761
|
-
/**
|
|
762
|
-
* Port of `pop role admin transfer` — src/commands/role/admin.ts.
|
|
763
|
-
* DESTRUCTIVE, superAdmin-only.
|
|
764
|
-
*/
|
|
765
|
-
async function transferSuperAdminIntent(ctx, params) {
|
|
766
|
-
const to = (0, validation_1.requireAddress)(params.to, 'to');
|
|
767
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
768
|
-
if (params.from && to.toLowerCase() === params.from.toLowerCase()) {
|
|
769
|
-
throw new errors_1.PreconditionError('The target is already the superAdmin (you).', 'Pass a different --to address.');
|
|
770
|
-
}
|
|
771
|
-
return buildTransferSuperAdmin({ eligibilityModuleAddress, newSuperAdmin: to, orgId });
|
|
772
|
-
}
|
|
773
|
-
/**
|
|
774
|
-
* Port of `pop role admin mint` — src/commands/role/admin.ts. Derives the
|
|
775
|
-
* method exactly as the CLI does: one wearer → mintHatToAddress(hat, wearer);
|
|
776
|
-
* several → batchMintHats(hat replicated per wearer, wearers).
|
|
777
|
-
* superAdmin-only.
|
|
778
|
-
*/
|
|
779
|
-
async function mintHatsIntent(ctx, params) {
|
|
780
|
-
const hatId = (0, eligibility_1.parseHatId)(params.hat);
|
|
781
|
-
const wearers = (Array.isArray(params.wearer) ? params.wearer : String(params.wearer).split(','))
|
|
782
|
-
.map(s => s.trim())
|
|
783
|
-
.filter(s => s.length > 0)
|
|
784
|
-
.map(addr => (0, validation_1.requireAddress)(addr, 'wearer'));
|
|
785
|
-
if (wearers.length === 0) {
|
|
786
|
-
throw new errors_1.CliError('No valid --wearer addresses provided.', exit_codes_1.EXIT.USAGE);
|
|
787
|
-
}
|
|
788
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
789
|
-
return wearers.length === 1
|
|
790
|
-
? buildMintHatToAddress({ eligibilityModuleAddress, hatId, wearer: wearers[0], orgId })
|
|
791
|
-
: buildBatchMintHats({ eligibilityModuleAddress, hatIds: wearers.map(() => hatId), wearers, orgId });
|
|
792
|
-
}
|
|
793
|
-
/** Port of `pop role admin pause` — src/commands/role/admin.ts. superAdmin-only. */
|
|
794
|
-
async function pauseIntent(ctx, params) {
|
|
795
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
796
|
-
return buildPause({ eligibilityModuleAddress, orgId });
|
|
797
|
-
}
|
|
798
|
-
/** Port of `pop role admin unpause` — src/commands/role/admin.ts. superAdmin-only. */
|
|
799
|
-
async function unpauseIntent(ctx, params) {
|
|
800
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
801
|
-
return buildUnpause({ eligibilityModuleAddress, orgId });
|
|
802
|
-
}
|
|
803
|
-
/**
|
|
804
|
-
* Port of `pop role admin set-join-time` — src/commands/role/admin.ts.
|
|
805
|
-
* Derives the method exactly as the CLI does: --timestamp →
|
|
806
|
-
* setUserJoinTime(user, ts); omitted → setUserJoinTimeNow(user).
|
|
807
|
-
* superAdmin-only.
|
|
808
|
-
*/
|
|
809
|
-
async function setUserJoinTimeIntent(ctx, params) {
|
|
810
|
-
const user = (0, validation_1.requireAddress)(params.user, 'user');
|
|
811
|
-
if (params.timestamp !== undefined && (!Number.isInteger(params.timestamp) || params.timestamp < 0)) {
|
|
812
|
-
throw new errors_1.CliError(`Invalid --timestamp ${params.timestamp}.`, exit_codes_1.EXIT.USAGE, 'Pass unix seconds, or omit to use the current block time.');
|
|
813
|
-
}
|
|
814
|
-
const { orgId, eligibilityModuleAddress } = await (0, eligibility_1.resolveEligibilityModule)(ctx.client, params.org, ctx.chainId);
|
|
815
|
-
return params.timestamp !== undefined
|
|
816
|
-
? buildSetUserJoinTime({ eligibilityModuleAddress, user, joinTime: params.timestamp, orgId })
|
|
817
|
-
: buildSetUserJoinTimeNow({ eligibilityModuleAddress, user, orgId });
|
|
818
|
-
}
|