@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.
Files changed (95) hide show
  1. package/README.md +2 -0
  2. package/dist/abis/AuthorityRouter.d.ts +448 -0
  3. package/dist/abis/AuthorityRouter.js +584 -0
  4. package/dist/abis/CutoverVerifier.d.ts +194 -0
  5. package/dist/abis/CutoverVerifier.js +259 -0
  6. package/dist/abis/DirectDemocracyVotingNew.d.ts +168 -30
  7. package/dist/abis/DirectDemocracyVotingNew.js +214 -35
  8. package/dist/abis/EducationHubNew.d.ts +32 -75
  9. package/dist/abis/EducationHubNew.js +38 -94
  10. package/dist/abis/Executor.d.ts +56 -86
  11. package/dist/abis/Executor.js +68 -104
  12. package/dist/abis/HybridVotingNew.d.ts +279 -35
  13. package/dist/abis/HybridVotingNew.js +357 -40
  14. package/dist/abis/{EligibilityModuleNew.d.ts → MembershipAuthority.d.ts} +1437 -718
  15. package/dist/abis/{EligibilityModuleNew.js → MembershipAuthority.js} +1821 -899
  16. package/dist/abis/OrgDeployerNew.d.ts +193 -127
  17. package/dist/abis/OrgDeployerNew.js +244 -160
  18. package/dist/abis/OrgRegistry.d.ts +40 -0
  19. package/dist/abis/OrgRegistry.js +51 -0
  20. package/dist/abis/ParticipationToken.d.ts +32 -75
  21. package/dist/abis/ParticipationToken.js +38 -94
  22. package/dist/abis/PasskeyAccount.d.ts +28 -0
  23. package/dist/abis/PasskeyAccount.js +35 -0
  24. package/dist/abis/PaymasterHub.d.ts +527 -47
  25. package/dist/abis/PaymasterHub.js +750 -135
  26. package/dist/abis/QuickJoinNew.d.ts +59 -170
  27. package/dist/abis/QuickJoinNew.js +71 -215
  28. package/dist/abis/TaskManagerNew.d.ts +27 -44
  29. package/dist/abis/TaskManagerNew.js +31 -52
  30. package/dist/abis/UniversalAccountRegistry.d.ts +24 -0
  31. package/dist/abis/UniversalAccountRegistry.js +30 -0
  32. package/dist/abis/ZkEmailInvites.d.ts +44 -0
  33. package/dist/abis/ZkEmailInvites.js +55 -0
  34. package/dist/abis/index.d.ts +6 -4
  35. package/dist/abis/index.js +10 -7
  36. package/dist/chains.js +3 -3
  37. package/dist/error-catalog.js +125 -7
  38. package/dist/graph/documents/activity.d.ts +3 -1
  39. package/dist/graph/documents/activity.js +19 -14
  40. package/dist/graph/documents/org.d.ts +4 -4
  41. package/dist/graph/documents/org.js +10 -4
  42. package/dist/graph/documents/task.d.ts +10 -1
  43. package/dist/graph/documents/task.js +157 -3
  44. package/dist/graph/documents/user.d.ts +5 -30
  45. package/dist/graph/documents/user.js +2 -42
  46. package/dist/graph/documents/voting-classes.d.ts +23 -2
  47. package/dist/graph/documents/voting-classes.js +119 -10
  48. package/dist/metadata/index.d.ts +0 -1
  49. package/dist/metadata/index.js +1 -2
  50. package/dist/perms.d.ts +0 -15
  51. package/dist/perms.js +1 -21
  52. package/dist/preflight.d.ts +2 -2
  53. package/dist/preflight.js +14 -22
  54. package/dist/reads/authority.d.ts +33 -0
  55. package/dist/reads/authority.js +196 -0
  56. package/dist/reads/index.d.ts +1 -1
  57. package/dist/reads/index.js +2 -2
  58. package/dist/reads/org.d.ts +20 -20
  59. package/dist/reads/org.js +94 -28
  60. package/dist/reads/project.js +3 -3
  61. package/dist/reads/resolve.d.ts +1 -1
  62. package/dist/reads/resolve.js +12 -3
  63. package/dist/reads/task.d.ts +44 -22
  64. package/dist/reads/task.js +126 -67
  65. package/dist/reads/user.d.ts +8 -43
  66. package/dist/reads/user.js +27 -44
  67. package/dist/reads/vote.d.ts +26 -2
  68. package/dist/reads/vote.js +104 -23
  69. package/dist/tx/authority.d.ts +33 -0
  70. package/dist/tx/authority.js +62 -0
  71. package/dist/tx/governance.d.ts +6 -0
  72. package/dist/tx/governance.js +20 -2
  73. package/dist/tx/index.d.ts +1 -1
  74. package/dist/tx/index.js +2 -2
  75. package/dist/tx/org.d.ts +23 -18
  76. package/dist/tx/org.js +203 -67
  77. package/dist/tx/project.d.ts +3 -2
  78. package/dist/tx/project.js +28 -10
  79. package/dist/tx/task.d.ts +13 -24
  80. package/dist/tx/task.js +45 -85
  81. package/dist/tx/user.d.ts +2 -40
  82. package/dist/tx/user.js +2 -76
  83. package/dist/tx/vote.d.ts +5 -0
  84. package/dist/tx/vote.js +54 -43
  85. package/dist/version.d.ts +0 -5
  86. package/dist/version.js +1 -13
  87. package/package.json +1 -1
  88. package/dist/abis/ToggleModule.d.ts +0 -193
  89. package/dist/abis/ToggleModule.js +0 -255
  90. package/dist/metadata/role.d.ts +0 -38
  91. package/dist/metadata/role.js +0 -35
  92. package/dist/reads/eligibility.d.ts +0 -377
  93. package/dist/reads/eligibility.js +0 -687
  94. package/dist/tx/eligibility.d.ts +0 -511
  95. package/dist/tx/eligibility.js +0 -818
@@ -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
- }