@poa-box/core 0.1.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 (220) hide show
  1. package/README.md +201 -0
  2. package/dist/abis/DirectDemocracyVotingNew.d.ts +749 -0
  3. package/dist/abis/DirectDemocracyVotingNew.js +961 -0
  4. package/dist/abis/ERC20.d.ts +90 -0
  5. package/dist/abis/ERC20.js +125 -0
  6. package/dist/abis/EducationHubNew.d.ts +590 -0
  7. package/dist/abis/EducationHubNew.js +762 -0
  8. package/dist/abis/EligibilityModuleNew.d.ts +1615 -0
  9. package/dist/abis/EligibilityModuleNew.js +2082 -0
  10. package/dist/abis/Executor.d.ts +619 -0
  11. package/dist/abis/Executor.js +796 -0
  12. package/dist/abis/HybridVotingNew.d.ts +898 -0
  13. package/dist/abis/HybridVotingNew.js +1149 -0
  14. package/dist/abis/ImplementationRegistry.d.ts +270 -0
  15. package/dist/abis/ImplementationRegistry.js +355 -0
  16. package/dist/abis/OrgDeployerNew.d.ts +1275 -0
  17. package/dist/abis/OrgDeployerNew.js +1630 -0
  18. package/dist/abis/OrgRegistry.d.ts +670 -0
  19. package/dist/abis/OrgRegistry.js +868 -0
  20. package/dist/abis/ParticipationToken.d.ts +1086 -0
  21. package/dist/abis/ParticipationToken.js +1415 -0
  22. package/dist/abis/PasskeyAccount.d.ts +788 -0
  23. package/dist/abis/PasskeyAccount.js +1019 -0
  24. package/dist/abis/PasskeyAccountFactory.d.ts +344 -0
  25. package/dist/abis/PasskeyAccountFactory.js +449 -0
  26. package/dist/abis/PaymasterHub.d.ts +1603 -0
  27. package/dist/abis/PaymasterHub.js +2048 -0
  28. package/dist/abis/PaymentManager.d.ts +520 -0
  29. package/dist/abis/PaymentManager.js +671 -0
  30. package/dist/abis/PoaManager.d.ts +344 -0
  31. package/dist/abis/PoaManager.js +449 -0
  32. package/dist/abis/QuickJoinNew.d.ts +855 -0
  33. package/dist/abis/QuickJoinNew.js +1098 -0
  34. package/dist/abis/TaskManagerNew.d.ts +1236 -0
  35. package/dist/abis/TaskManagerNew.js +1573 -0
  36. package/dist/abis/ToggleModule.d.ts +193 -0
  37. package/dist/abis/ToggleModule.js +255 -0
  38. package/dist/abis/UniversalAccountRegistry.d.ts +577 -0
  39. package/dist/abis/UniversalAccountRegistry.js +750 -0
  40. package/dist/abis/ZkEmailInvites.d.ts +823 -0
  41. package/dist/abis/ZkEmailInvites.js +1060 -0
  42. package/dist/abis/external/AaveGovernanceV2.d.ts +128 -0
  43. package/dist/abis/external/AaveGovernanceV2.js +177 -0
  44. package/dist/abis/external/AaveGovernanceV3.d.ts +160 -0
  45. package/dist/abis/external/AaveGovernanceV3.js +220 -0
  46. package/dist/abis/external/AragonVoting.d.ts +107 -0
  47. package/dist/abis/external/AragonVoting.js +150 -0
  48. package/dist/abis/external/CurveGaugeController.d.ts +95 -0
  49. package/dist/abis/external/CurveGaugeController.js +130 -0
  50. package/dist/abis/external/CurveVotingEscrow.d.ts +86 -0
  51. package/dist/abis/external/CurveVotingEscrow.js +116 -0
  52. package/dist/abis/external/GovernorAlpha.d.ts +172 -0
  53. package/dist/abis/external/GovernorAlpha.js +228 -0
  54. package/dist/abis/external/MakerDAOChief.d.ts +92 -0
  55. package/dist/abis/external/MakerDAOChief.js +129 -0
  56. package/dist/abis/external/OZGovernor.d.ts +227 -0
  57. package/dist/abis/external/OZGovernor.js +317 -0
  58. package/dist/abis/external/SolidlyVotingEscrow.d.ts +196 -0
  59. package/dist/abis/external/SolidlyVotingEscrow.js +260 -0
  60. package/dist/abis/index.d.ts +62 -0
  61. package/dist/abis/index.js +98 -0
  62. package/dist/chains.d.ts +150 -0
  63. package/dist/chains.js +320 -0
  64. package/dist/context.d.ts +48 -0
  65. package/dist/context.js +38 -0
  66. package/dist/contracts.d.ts +24 -0
  67. package/dist/contracts.js +41 -0
  68. package/dist/encoding.d.ts +58 -0
  69. package/dist/encoding.js +243 -0
  70. package/dist/env.d.ts +10 -0
  71. package/dist/env.js +4 -0
  72. package/dist/error-catalog.d.ts +41 -0
  73. package/dist/error-catalog.js +941 -0
  74. package/dist/errors.d.ts +27 -0
  75. package/dist/errors.js +60 -0
  76. package/dist/execute/ethers.d.ts +93 -0
  77. package/dist/execute/ethers.js +323 -0
  78. package/dist/execute/index.d.ts +7 -0
  79. package/dist/execute/index.js +23 -0
  80. package/dist/execute/sponsored.d.ts +68 -0
  81. package/dist/execute/sponsored.js +277 -0
  82. package/dist/exit-codes.d.ts +18 -0
  83. package/dist/exit-codes.js +21 -0
  84. package/dist/format.d.ts +21 -0
  85. package/dist/format.js +89 -0
  86. package/dist/graph/client.d.ts +298 -0
  87. package/dist/graph/client.js +702 -0
  88. package/dist/graph/documents/activity.d.ts +9 -0
  89. package/dist/graph/documents/activity.js +164 -0
  90. package/dist/graph/documents/beacons.d.ts +172 -0
  91. package/dist/graph/documents/beacons.js +345 -0
  92. package/dist/graph/documents/index.d.ts +21 -0
  93. package/dist/graph/documents/index.js +57 -0
  94. package/dist/graph/documents/infrastructure.d.ts +30 -0
  95. package/dist/graph/documents/infrastructure.js +34 -0
  96. package/dist/graph/documents/org.d.ts +15 -0
  97. package/dist/graph/documents/org.js +249 -0
  98. package/dist/graph/documents/paymaster.d.ts +95 -0
  99. package/dist/graph/documents/paymaster.js +101 -0
  100. package/dist/graph/documents/role.d.ts +6 -0
  101. package/dist/graph/documents/role.js +41 -0
  102. package/dist/graph/documents/roles.d.ts +50 -0
  103. package/dist/graph/documents/roles.js +112 -0
  104. package/dist/graph/documents/task.d.ts +84 -0
  105. package/dist/graph/documents/task.js +236 -0
  106. package/dist/graph/documents/token.d.ts +13 -0
  107. package/dist/graph/documents/token.js +126 -0
  108. package/dist/graph/documents/treasury.d.ts +39 -0
  109. package/dist/graph/documents/treasury.js +136 -0
  110. package/dist/graph/documents/user.d.ts +120 -0
  111. package/dist/graph/documents/user.js +302 -0
  112. package/dist/graph/documents/voting-classes.d.ts +69 -0
  113. package/dist/graph/documents/voting-classes.js +149 -0
  114. package/dist/graph/documents/voting.d.ts +28 -0
  115. package/dist/graph/documents/voting.js +163 -0
  116. package/dist/graph/documents/vouch.d.ts +79 -0
  117. package/dist/graph/documents/vouch.js +171 -0
  118. package/dist/graph/documents/zkemail.d.ts +63 -0
  119. package/dist/graph/documents/zkemail.js +188 -0
  120. package/dist/graph/index.d.ts +2 -0
  121. package/dist/graph/index.js +41 -0
  122. package/dist/index.d.ts +49 -0
  123. package/dist/index.js +92 -0
  124. package/dist/ipfs.d.ts +39 -0
  125. package/dist/ipfs.js +214 -0
  126. package/dist/label-aliases.d.ts +31 -0
  127. package/dist/label-aliases.js +70 -0
  128. package/dist/metadata/education.d.ts +30 -0
  129. package/dist/metadata/education.js +31 -0
  130. package/dist/metadata/index.d.ts +12 -0
  131. package/dist/metadata/index.js +48 -0
  132. package/dist/metadata/org.d.ts +92 -0
  133. package/dist/metadata/org.js +93 -0
  134. package/dist/metadata/proposal.d.ts +44 -0
  135. package/dist/metadata/proposal.js +45 -0
  136. package/dist/metadata/role.d.ts +38 -0
  137. package/dist/metadata/role.js +35 -0
  138. package/dist/metadata/task.d.ts +108 -0
  139. package/dist/metadata/task.js +81 -0
  140. package/dist/metadata/token.d.ts +32 -0
  141. package/dist/metadata/token.js +36 -0
  142. package/dist/metadata/user.d.ts +63 -0
  143. package/dist/metadata/user.js +70 -0
  144. package/dist/multicall.d.ts +32 -0
  145. package/dist/multicall.js +96 -0
  146. package/dist/payout.d.ts +59 -0
  147. package/dist/payout.js +96 -0
  148. package/dist/perms.d.ts +47 -0
  149. package/dist/perms.js +120 -0
  150. package/dist/preflight.d.ts +72 -0
  151. package/dist/preflight.js +269 -0
  152. package/dist/reads/education.d.ts +79 -0
  153. package/dist/reads/education.js +122 -0
  154. package/dist/reads/eligibility.d.ts +377 -0
  155. package/dist/reads/eligibility.js +687 -0
  156. package/dist/reads/index.d.ts +16 -0
  157. package/dist/reads/index.js +55 -0
  158. package/dist/reads/org.d.ts +258 -0
  159. package/dist/reads/org.js +220 -0
  160. package/dist/reads/paymaster.d.ts +147 -0
  161. package/dist/reads/paymaster.js +235 -0
  162. package/dist/reads/project.d.ts +33 -0
  163. package/dist/reads/project.js +62 -0
  164. package/dist/reads/resolve.d.ts +34 -0
  165. package/dist/reads/resolve.js +64 -0
  166. package/dist/reads/task.d.ts +286 -0
  167. package/dist/reads/task.js +280 -0
  168. package/dist/reads/token.d.ts +94 -0
  169. package/dist/reads/token.js +75 -0
  170. package/dist/reads/treasury.d.ts +222 -0
  171. package/dist/reads/treasury.js +241 -0
  172. package/dist/reads/user.d.ts +229 -0
  173. package/dist/reads/user.js +155 -0
  174. package/dist/reads/vote.d.ts +296 -0
  175. package/dist/reads/vote.js +392 -0
  176. package/dist/reads/zkemail.d.ts +117 -0
  177. package/dist/reads/zkemail.js +217 -0
  178. package/dist/similarity.d.ts +36 -0
  179. package/dist/similarity.js +67 -0
  180. package/dist/sponsorship-config.d.ts +47 -0
  181. package/dist/sponsorship-config.js +41 -0
  182. package/dist/stats.d.ts +11 -0
  183. package/dist/stats.js +27 -0
  184. package/dist/task-lens.d.ts +113 -0
  185. package/dist/task-lens.js +210 -0
  186. package/dist/tx/education.d.ts +169 -0
  187. package/dist/tx/education.js +344 -0
  188. package/dist/tx/eligibility.d.ts +511 -0
  189. package/dist/tx/eligibility.js +818 -0
  190. package/dist/tx/governance.d.ts +85 -0
  191. package/dist/tx/governance.js +87 -0
  192. package/dist/tx/index.d.ts +17 -0
  193. package/dist/tx/index.js +56 -0
  194. package/dist/tx/intent.d.ts +67 -0
  195. package/dist/tx/intent.js +48 -0
  196. package/dist/tx/org.d.ts +321 -0
  197. package/dist/tx/org.js +544 -0
  198. package/dist/tx/paymaster.d.ts +140 -0
  199. package/dist/tx/paymaster.js +251 -0
  200. package/dist/tx/project.d.ts +146 -0
  201. package/dist/tx/project.js +217 -0
  202. package/dist/tx/task.d.ts +480 -0
  203. package/dist/tx/task.js +1149 -0
  204. package/dist/tx/token.d.ts +96 -0
  205. package/dist/tx/token.js +165 -0
  206. package/dist/tx/treasury.d.ts +474 -0
  207. package/dist/tx/treasury.js +911 -0
  208. package/dist/tx/user.d.ts +177 -0
  209. package/dist/tx/user.js +292 -0
  210. package/dist/tx/vote.d.ts +332 -0
  211. package/dist/tx/vote.js +762 -0
  212. package/dist/tx/zkemail.d.ts +90 -0
  213. package/dist/tx/zkemail.js +210 -0
  214. package/dist/validation.d.ts +8 -0
  215. package/dist/validation.js +39 -0
  216. package/dist/version.d.ts +142 -0
  217. package/dist/version.js +257 -0
  218. package/dist/zkemail.d.ts +161 -0
  219. package/dist/zkemail.js +299 -0
  220. package/package.json +130 -0
package/dist/tx/org.js ADDED
@@ -0,0 +1,544 @@
1
+ "use strict";
2
+ /**
3
+ * Org write builders.
4
+ *
5
+ * Ports:
6
+ * - `pop org deploy` — src/commands/org/deploy.ts
7
+ * - `pop org update-metadata` — src/commands/org/update-metadata.ts
8
+ * - `pop org set-metadata-admin` — src/commands/org/set-metadata-admin.ts
9
+ *
10
+ * Level-1 builders are pure (sync, zero I/O) and own ALL argument encoding.
11
+ * Level-2 `<action>Intent(ctx, params)` builders resolve addresses via the
12
+ * subgraph, pin metadata to IPFS, and delegate to Level 1.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DEPLOY_FULL_ORG_GAS_LIMIT = exports.REGISTER_ACCOUNT_TYPES = void 0;
16
+ exports.indicesToBitmap = indicesToBitmap;
17
+ exports.assertRoleIndices = assertRoleIndices;
18
+ exports.deriveOrgId = deriveOrgId;
19
+ exports.registerAccountDomain = registerAccountDomain;
20
+ exports.signRegisterAccount = signRegisterAccount;
21
+ exports.buildDeploymentParams = buildDeploymentParams;
22
+ exports.buildDeployFullOrg = buildDeployFullOrg;
23
+ exports.deployFullOrgIntent = deployFullOrgIntent;
24
+ exports.buildUpdateOrgMetaAsAdmin = buildUpdateOrgMetaAsAdmin;
25
+ exports.updateOrgMetaIntent = updateOrgMetaIntent;
26
+ exports.setMetadataAdminTitle = setMetadataAdminTitle;
27
+ exports.buildSetMetadataAdminProposal = buildSetMetadataAdminProposal;
28
+ exports.setMetadataAdminIntent = setMetadataAdminIntent;
29
+ const ethers_1 = require("ethers");
30
+ const contracts_1 = require("../contracts");
31
+ const encoding_1 = require("../encoding");
32
+ const ipfs_1 = require("../ipfs");
33
+ const errors_1 = require("../errors");
34
+ const exit_codes_1 = require("../exit-codes");
35
+ const resolve_1 = require("../reads/resolve");
36
+ const infrastructure_1 = require("../graph/documents/infrastructure");
37
+ const org_1 = require("../graph/documents/org");
38
+ const org_2 = require("../metadata/org");
39
+ const proposal_1 = require("../metadata/proposal");
40
+ const governance_1 = require("./governance");
41
+ // ---------------------------------------------------------------------------
42
+ // Shared infra resolution
43
+ // ---------------------------------------------------------------------------
44
+ /**
45
+ * OrgRegistry proxy address — global infrastructure, not an org module.
46
+ * Same lookup + error as `pop org update-metadata` / `pop org set-metadata-admin`.
47
+ */
48
+ async function resolveOrgRegistryAddress(ctx) {
49
+ const infra = await ctx.client.query(infrastructure_1.FETCH_INFRASTRUCTURE_ADDRESSES, {}, ctx.chainId);
50
+ const orgRegistryAddr = infra.poaManagerContracts?.[0]?.orgRegistryProxy;
51
+ if (!orgRegistryAddr) {
52
+ throw new errors_1.CliError('Could not resolve OrgRegistry address from subgraph', exit_codes_1.EXIT.INFRA);
53
+ }
54
+ return orgRegistryAddr;
55
+ }
56
+ /** Port of indicesToBitmap in src/commands/org/deploy.ts. */
57
+ function indicesToBitmap(indices) {
58
+ let bitmap = ethers_1.ethers.BigNumber.from(0);
59
+ for (const i of indices) {
60
+ bitmap = bitmap.or(ethers_1.ethers.BigNumber.from(1).shl(i));
61
+ }
62
+ return bitmap;
63
+ }
64
+ /**
65
+ * Reject role indices that do not name a role in the config.
66
+ *
67
+ * RoleResolver reverts UnregisteredRole(roleIdx) when a bitmap bit has no registered hat
68
+ * (audit M-09) — previously hat 0 was silently stored as an "authorized" hat and the deploy
69
+ * succeeded with a broken allowlist. Either way the config is wrong, and we know roles.length
70
+ * here, so name the offending field instead of surfacing a bare index from gas estimation
71
+ * (older deployers) or an aborted deploy (upgraded ones).
72
+ */
73
+ function assertRoleIndices(field, indices, roleCount) {
74
+ for (const i of indices ?? []) {
75
+ if (!Number.isInteger(i) || i < 0 || i >= roleCount) {
76
+ throw new errors_1.CliError(`${field} references role index ${i}, but the config defines ${roleCount} role(s) (valid: 0-${roleCount - 1}).`, exit_codes_1.EXIT.USAGE, 'Role indices are positions in the config\'s `roles` array — renumber them after adding '
77
+ + 'or removing a role.');
78
+ }
79
+ }
80
+ }
81
+ /**
82
+ * Derive the deterministic orgId + normalized name the deployer uses:
83
+ * orgId = keccak256(orgName.toLowerCase().replace(/\s+/g, '-')).
84
+ * The normalized name is also the default deployer username.
85
+ */
86
+ function deriveOrgId(orgName) {
87
+ const normalizedName = orgName.toLowerCase().replace(/\s+/g, '-');
88
+ return {
89
+ orgId: ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.toUtf8Bytes(normalizedName)),
90
+ normalizedName,
91
+ };
92
+ }
93
+ /** EIP-712 type set for UniversalAccountRegistry registration. */
94
+ exports.REGISTER_ACCOUNT_TYPES = {
95
+ RegisterAccount: [
96
+ { name: 'user', type: 'address' },
97
+ { name: 'username', type: 'string' },
98
+ { name: 'nonce', type: 'uint256' },
99
+ { name: 'deadline', type: 'uint256' },
100
+ ],
101
+ };
102
+ /** EIP-712 domain for UniversalAccountRegistry registration. */
103
+ function registerAccountDomain(chainId, registryAddress) {
104
+ return {
105
+ name: 'UniversalAccountRegistry',
106
+ version: '1',
107
+ chainId,
108
+ verifyingContract: registryAddress,
109
+ };
110
+ }
111
+ /**
112
+ * Port of the EIP-712 RegisterAccount signature step in `pop org deploy`
113
+ * (src/commands/org/deploy.ts): registration happens INSIDE deployFullOrg via
114
+ * this signature — it is not a separate tx. Kept as a separate function taking
115
+ * a Signer so hosts control key custody; everything else here is pure data.
116
+ */
117
+ async function signRegisterAccount(signer, params) {
118
+ const domain = registerAccountDomain(params.chainId, params.registryAddress);
119
+ const message = {
120
+ user: params.user,
121
+ username: params.username,
122
+ nonce: ethers_1.ethers.BigNumber.from(params.nonce).toString(),
123
+ deadline: params.deadline,
124
+ };
125
+ return signer._signTypedData(domain, exports.REGISTER_ACCOUNT_TYPES, message);
126
+ }
127
+ /** Recommended gasLimit for deployFullOrg — the CLI always sends 15,000,000. */
128
+ exports.DEPLOY_FULL_ORG_GAS_LIMIT = 15000000;
129
+ /**
130
+ * Pure assembly of the DeploymentParams struct — port of the param build in
131
+ * `pop org deploy` (src/commands/org/deploy.ts:257-403), byte-for-byte the
132
+ * same encoding. Validates taskManagerPerms lengths and every roleAssignments
133
+ * index exactly like the CLI (both gate the broadcast).
134
+ *
135
+ * ABI field order (verified against src/abi/OrgDeployerNew.json +
136
+ * contracts origin/main src/OrgDeployer.sol DeploymentParams):
137
+ * orgId, orgName, metadataHash, registryAddr, deployerAddress,
138
+ * deployerUsername, regDeadline, regNonce, regSignature, autoUpgrade,
139
+ * hybridThresholdPct, ddThresholdPct, hybridClasses, ddInitialTargets,
140
+ * roles, roleAssignments, metadataAdminRoleIndex, passkeyEnabled,
141
+ * educationHubConfig, bootstrap, paymasterConfig, taskManagerPerms
142
+ */
143
+ function buildDeploymentParams(config, resolved) {
144
+ // Build hybrid voting classes
145
+ // ABI: strategy(uint8), slicePct(uint8), quadratic(bool), minBalance(uint256), asset(address), hatIds(uint256[])
146
+ const hybridClasses = config.hybridVoting.classes.map((c) => [
147
+ c.strategy === 'DIRECT' ? 0 : 1, // uint8
148
+ c.slicePct, // uint8 (0-100)
149
+ c.quadratic || false, // bool
150
+ c.minBalance ? ethers_1.ethers.utils.parseUnits(c.minBalance, 18) : 0, // uint256
151
+ c.asset || ethers_1.ethers.constants.AddressZero, // address
152
+ c.hatIds || [], // uint256[]
153
+ ]);
154
+ // Build role configs
155
+ // ABI: name(string), image(string), metadataCID(bytes32), canVote(bool),
156
+ // vouching(tuple), defaults(tuple), hierarchy(tuple), distribution(tuple), hatConfig(tuple)
157
+ const MAX_UINT32 = 4294967295; // 2^32 - 1
158
+ const roles = config.roles.map((r) => [
159
+ r.name, // string
160
+ r.image || '', // string
161
+ ethers_1.ethers.constants.HashZero, // bytes32 metadataCID
162
+ r.canVote, // bool
163
+ [
164
+ r.vouching?.enabled || false,
165
+ r.vouching?.quorum || 0,
166
+ r.vouching?.voucherRoleIndex ?? ethers_1.ethers.constants.MaxUint256,
167
+ r.vouching?.combineWithHierarchy || false,
168
+ ],
169
+ [
170
+ r.defaults?.eligible ?? true,
171
+ r.defaults?.standing ?? true,
172
+ ],
173
+ [
174
+ r.hierarchy?.adminRoleIndex ?? ethers_1.ethers.constants.MaxUint256,
175
+ ],
176
+ [
177
+ r.distribution?.mintToDeployer ?? true,
178
+ r.distribution?.additionalWearers || [],
179
+ ],
180
+ [
181
+ r.hatConfig?.maxSupply ?? MAX_UINT32, // uint32, NOT uint256
182
+ r.hatConfig?.mutableHat ?? true,
183
+ ],
184
+ ]);
185
+ // Build role assignment bitmaps
186
+ const ra = config.roleAssignments;
187
+ // Every index must name a real role BEFORE anything is broadcast — a stale index is
188
+ // trivially produced by editing `roles` without renumbering `roleAssignments`.
189
+ const roleCount = config.roles.length;
190
+ assertRoleIndices('roleAssignments.quickJoinRoles', ra.quickJoinRoles, roleCount);
191
+ assertRoleIndices('roleAssignments.tokenMemberRoles', ra.tokenMemberRoles, roleCount);
192
+ assertRoleIndices('roleAssignments.tokenApproverRoles', ra.tokenApproverRoles, roleCount);
193
+ assertRoleIndices('roleAssignments.taskCreatorRoles', ra.taskCreatorRoles, roleCount);
194
+ assertRoleIndices('roleAssignments.educationCreatorRoles', ra.educationCreatorRoles, roleCount);
195
+ assertRoleIndices('roleAssignments.educationMemberRoles', ra.educationMemberRoles, roleCount);
196
+ assertRoleIndices('roleAssignments.hybridProposalCreatorRoles', ra.hybridProposalCreatorRoles, roleCount);
197
+ assertRoleIndices('roleAssignments.ddVotingRoles', ra.ddVotingRoles, roleCount);
198
+ assertRoleIndices('roleAssignments.ddCreatorRoles', ra.ddCreatorRoles, roleCount);
199
+ const roleAssignments = [
200
+ indicesToBitmap(ra.quickJoinRoles),
201
+ indicesToBitmap(ra.tokenMemberRoles),
202
+ indicesToBitmap(ra.tokenApproverRoles),
203
+ indicesToBitmap(ra.taskCreatorRoles),
204
+ indicesToBitmap(ra.educationCreatorRoles || []),
205
+ indicesToBitmap(ra.educationMemberRoles || []),
206
+ indicesToBitmap(ra.hybridProposalCreatorRoles),
207
+ indicesToBitmap(ra.ddVotingRoles),
208
+ indicesToBitmap(ra.ddCreatorRoles),
209
+ ];
210
+ // Build paymaster config
211
+ // ABI: operatorRoleIndex(uint256), autoWhitelistContracts(bool),
212
+ // maxFeePerGas(uint256), maxPriorityFeePerGas(uint256),
213
+ // maxCallGas(uint32), maxVerificationGas(uint32), maxPreVerificationGas(uint32),
214
+ // defaultBudgetCapPerEpoch(uint128), defaultBudgetEpochLen(uint32)
215
+ const pm = config.paymaster;
216
+ const paymasterConfig = pm ? [
217
+ pm.operatorRoleIndex, // uint256
218
+ true, // bool
219
+ ethers_1.ethers.utils.parseUnits(pm.maxFeePerGas, 'gwei'), // uint256
220
+ ethers_1.ethers.utils.parseUnits(pm.maxPriorityFeePerGas, 'gwei'), // uint256
221
+ 500000, // uint32 maxCallGas
222
+ 500000, // uint32 maxVerificationGas
223
+ 100000, // uint32 maxPreVerificationGas
224
+ ethers_1.ethers.utils.parseEther(pm.defaultBudgetCapPerEpoch), // uint128
225
+ pm.defaultBudgetEpochLen, // uint32
226
+ ] : [
227
+ ethers_1.ethers.constants.MaxUint256, // operatorRoleIndex = MaxUint256 disables paymaster
228
+ false, // autoWhitelistContracts
229
+ 0, // maxFeePerGas
230
+ 0, // maxPriorityFeePerGas
231
+ 0, // maxCallGas
232
+ 0, // maxVerificationGas
233
+ 0, // maxPreVerificationGas
234
+ 0, // defaultBudgetCapPerEpoch
235
+ 0, // defaultBudgetEpochLen
236
+ ];
237
+ // Optional org-wide TaskManager ROLE_PERM grants
238
+ // (OrgDeployer.TaskManagerPermConfig: roleIndices[] + masks[] — empty
239
+ // arrays skip the bootstrapGlobalPerms step entirely; verified against
240
+ // contracts origin/main src/OrgDeployer.sol).
241
+ const tmPerms = config.taskManagerPerms;
242
+ if (tmPerms && (tmPerms.roleIndices?.length || 0) !== (tmPerms.masks?.length || 0)) {
243
+ throw new errors_1.CliError('Config invalid: taskManagerPerms.roleIndices and taskManagerPerms.masks must be the same length.', exit_codes_1.EXIT.USAGE);
244
+ }
245
+ const taskManagerPerms = [
246
+ tmPerms?.roleIndices || [], // uint256[] roleIndices
247
+ tmPerms?.masks || [], // uint8[] masks
248
+ ];
249
+ return [
250
+ resolved.orgId, // bytes32
251
+ config.orgName, // string
252
+ resolved.metadataHash, // bytes32
253
+ resolved.registryAddr, // address
254
+ resolved.deployerAddress, // address deployerAddress
255
+ resolved.deployerUsername, // string deployerUsername
256
+ resolved.regDeadline, // uint256
257
+ resolved.regNonce, // uint256
258
+ resolved.regSignature, // bytes
259
+ config.autoUpgrade ?? true, // bool
260
+ config.hybridVoting.thresholdPct, // uint8
261
+ config.directDemocracy?.thresholdPct || 51, // uint8
262
+ hybridClasses, // ClassConfig[]
263
+ [], // address[] ddInitialTargets
264
+ roles, // RoleConfig[]
265
+ roleAssignments, // RoleAssignments struct
266
+ config.metadataAdminRoleIndex ?? ethers_1.ethers.constants.MaxUint256, // uint256
267
+ true, // bool passkeyEnabled
268
+ [config.educationHub?.enabled ?? true], // EducationHubConfig struct
269
+ [[], []], // BootstrapConfig struct (projects, tasks)
270
+ paymasterConfig, // PaymasterConfig struct
271
+ taskManagerPerms, // TaskManagerPermConfig struct (roleIndices, masks)
272
+ ];
273
+ }
274
+ /**
275
+ * Port of `pop org deploy` — src/commands/org/deploy.ts.
276
+ * OrgDeployer.deployFullOrg([DeploymentParams]) — the single on-chain write,
277
+ * which internally deploys every org module (registration happens inside it
278
+ * via the EIP-712 signature carried in the params).
279
+ *
280
+ * NOTE: the CLI always sends this with gasLimit 15,000,000
281
+ * (DEPLOY_FULL_ORG_GAS_LIMIT) — pass it in the executor's options; TxIntent
282
+ * carries no gas policy.
283
+ */
284
+ function buildDeployFullOrg(a) {
285
+ return {
286
+ to: a.orgDeployerAddress,
287
+ abi: (0, contracts_1.getAbi)('OrgDeployerNew'),
288
+ method: 'deployFullOrg',
289
+ args: [a.deployParams],
290
+ value: a.value,
291
+ meta: {
292
+ domain: 'org',
293
+ action: 'deploy',
294
+ orgId: a.orgId,
295
+ summary: {
296
+ orgId: a.orgId,
297
+ orgName: a.orgName,
298
+ gasLimit: exports.DEPLOY_FULL_ORG_GAS_LIMIT,
299
+ },
300
+ },
301
+ };
302
+ }
303
+ /**
304
+ * Resolved builder for `pop org deploy` — src/commands/org/deploy.ts.
305
+ *
306
+ * Performs the CLI's pre-steps in the same order: config validation,
307
+ * infrastructure address resolution (orgDeployerProxy +
308
+ * globalAccountRegistryProxy), org metadata pin, on-chain
309
+ * UniversalAccountRegistry.nonces() read (requires ctx.provider), and the
310
+ * EIP-712 RegisterAccount signature — then delegates to buildDeployFullOrg.
311
+ */
312
+ async function deployFullOrgIntent(ctx, params) {
313
+ const config = params.config;
314
+ // ── Fail fast on config problems before any network work ───────────
315
+ if (!config.orgName)
316
+ throw new errors_1.CliError('Config missing: orgName', exit_codes_1.EXIT.USAGE);
317
+ if (!config.roles?.length)
318
+ throw new errors_1.CliError('Config missing: roles', exit_codes_1.EXIT.USAGE);
319
+ if (!config.hybridVoting)
320
+ throw new errors_1.CliError('Config missing: hybridVoting', exit_codes_1.EXIT.USAGE);
321
+ if (!ctx.provider) {
322
+ throw new errors_1.CliError('deployFullOrgIntent requires ctx.provider (UniversalAccountRegistry.nonces read)', exit_codes_1.EXIT.USAGE);
323
+ }
324
+ if (ctx.chainId === undefined) {
325
+ throw new errors_1.CliError('deployFullOrgIntent requires ctx.chainId (EIP-712 domain)', exit_codes_1.EXIT.USAGE);
326
+ }
327
+ // Resolve infrastructure addresses
328
+ const infra = await ctx.client.query(infrastructure_1.FETCH_INFRASTRUCTURE_ADDRESSES, {}, ctx.chainId);
329
+ const orgDeployerAddr = infra.poaManagerContracts?.[0]?.orgDeployerProxy;
330
+ const registryAddr = infra.poaManagerContracts?.[0]?.globalAccountRegistryProxy;
331
+ if (!orgDeployerAddr)
332
+ throw new errors_1.CliError('Could not resolve OrgDeployer address', exit_codes_1.EXIT.INFRA);
333
+ if (!registryAddr)
334
+ throw new errors_1.CliError('Could not resolve UniversalAccountRegistry address', exit_codes_1.EXIT.INFRA);
335
+ // Generate orgId: keccak256(orgName.toLowerCase().replace(/\s+/g, '-'))
336
+ const { orgId, normalizedName } = deriveOrgId(config.orgName);
337
+ const deployerUsername = config.deployerUsername || normalizedName;
338
+ // Upload org metadata to IPFS
339
+ const metadata = (0, org_2.buildOrgDeployMetadata)({
340
+ description: config.description,
341
+ links: config.links,
342
+ });
343
+ const metaCid = await (0, ipfs_1.pinJson)((0, org_2.serializeOrgMetadata)(metadata), ctx.ipfs);
344
+ const metadataHash = (0, encoding_1.ipfsCidToBytes32)(metaCid);
345
+ // Get registration nonce for deployer
346
+ const registryContract = (0, contracts_1.createReadContract)(registryAddr, 'UniversalAccountRegistry', ctx.provider);
347
+ const regNonce = await registryContract.nonces(params.deployerAddress);
348
+ // 15 min validity by default — see DeployFullOrgParams.regDeadline.
349
+ const regDeadline = params.regDeadline ?? Math.floor(Date.now() / 1000) + 900;
350
+ // Sign EIP-712 registration message
351
+ const regSignature = await signRegisterAccount(params.signer, {
352
+ registryAddress: registryAddr,
353
+ chainId: ctx.chainId,
354
+ user: params.deployerAddress,
355
+ username: deployerUsername,
356
+ nonce: regNonce,
357
+ deadline: regDeadline,
358
+ });
359
+ const deployParams = buildDeploymentParams(config, {
360
+ orgId,
361
+ metadataHash,
362
+ registryAddr,
363
+ deployerAddress: params.deployerAddress,
364
+ deployerUsername,
365
+ regDeadline,
366
+ regNonce,
367
+ regSignature,
368
+ });
369
+ const txValue = config.paymaster?.funding
370
+ ? ethers_1.ethers.utils.parseEther(config.paymaster.funding)
371
+ : undefined;
372
+ const intent = buildDeployFullOrg({
373
+ orgDeployerAddress: orgDeployerAddr,
374
+ deployParams,
375
+ value: txValue,
376
+ orgId,
377
+ orgName: config.orgName,
378
+ });
379
+ intent.meta.ipfs = { cid: metaCid, metadata };
380
+ return intent;
381
+ }
382
+ /**
383
+ * Port of `pop org update-metadata` — src/commands/org/update-metadata.ts.
384
+ * OrgRegistry.updateOrgMetaAsAdmin(orgId, stringToBytes(name), metadataHash).
385
+ * Caller must wear the org's metadata-admin hat (topHat fallback) — revert
386
+ * NotOrgMetadataAdmin otherwise. FULL OVERWRITE of name + metadata hash.
387
+ */
388
+ function buildUpdateOrgMetaAsAdmin(a) {
389
+ return {
390
+ to: a.orgRegistryAddress,
391
+ abi: (0, contracts_1.getAbi)('OrgRegistry'),
392
+ method: 'updateOrgMetaAsAdmin',
393
+ args: [a.orgId, (0, encoding_1.stringToBytes)(a.name), a.metadataHash],
394
+ meta: {
395
+ domain: 'org',
396
+ action: 'update-metadata',
397
+ orgId: a.orgId,
398
+ summary: { name: a.name, metadataHash: a.metadataHash },
399
+ },
400
+ };
401
+ }
402
+ /**
403
+ * Resolved builder for `pop org update-metadata` — src/commands/org/update-metadata.ts.
404
+ *
405
+ * Merge base is the RAW IPFS doc (fetchJson of the current metadataHash),
406
+ * spread FIRST so unknown keys (e.g. zkEmailAllowlist) and frontend key order
407
+ * survive; refuses (INFRA) when IPFS is unreachable but the subgraph shows
408
+ * metadata exists — proceeding would drop any key the CLI does not model.
409
+ */
410
+ async function updateOrgMetaIntent(ctx, params) {
411
+ if (!params.name && !params.description && !params.logo && !params.logoCid && !params.links
412
+ && params.backgroundColor === undefined && params.hideTreasury === undefined) {
413
+ throw new errors_1.CliError('At least one metadata field must be provided.', exit_codes_1.EXIT.USAGE, 'Available: --name, --description, --logo, --links, --background-color, --hide-treasury');
414
+ }
415
+ const orgId = await (0, resolve_1.resolveOrgId)(ctx.client, params.org, ctx.chainId);
416
+ // Resolve OrgRegistry address (global infrastructure, not an org module)
417
+ const orgRegistryAddr = await resolveOrgRegistryAddress(ctx);
418
+ // Fetch existing metadata to preserve fields not being updated.
419
+ const existing = await ctx.client.query(org_1.FETCH_ORG_FULL_DATA, { orgId }, ctx.chainId);
420
+ if (!existing.organization) {
421
+ throw new errors_1.CliError(`Organization ${orgId} is not indexed on this chain.`, exit_codes_1.EXIT.INFRA, 'This write overwrites the org name and metadata wholesale; refusing to send it against '
422
+ + 'an unknown org would otherwise blank both. Check --chain, or retry once indexed.');
423
+ }
424
+ const subgraphMeta = existing.organization.metadata || {};
425
+ const currentName = existing.organization.name || '';
426
+ const currentMetadataHash = existing.organization.metadataHash;
427
+ // The RAW IPFS doc — not the subgraph's typed projection — is the merge base
428
+ // (see mergeOrgMetadata for why).
429
+ let rawMeta = null;
430
+ if (currentMetadataHash && currentMetadataHash !== ethers_1.ethers.constants.HashZero) {
431
+ try {
432
+ rawMeta = await (0, ipfs_1.fetchJson)(currentMetadataHash, ctx.ipfs);
433
+ }
434
+ catch { /* handled below */ }
435
+ }
436
+ if (!rawMeta && Object.keys(subgraphMeta).length > 0) {
437
+ throw new errors_1.CliError('Could not fetch the org\'s current metadata from IPFS, so unknown fields cannot be preserved.', exit_codes_1.EXIT.INFRA, 'This write is a full overwrite — proceeding would drop any metadata key the CLI does not '
438
+ + 'model. Retry once IPFS responds.');
439
+ }
440
+ const currentMeta = rawMeta ?? subgraphMeta;
441
+ // Upload logo to IPFS if provided
442
+ let logoCid = params.logoCid ?? null;
443
+ if (params.logo) {
444
+ logoCid = await (0, ipfs_1.pinFile)(params.logo, ctx.ipfs);
445
+ }
446
+ const metadata = (0, org_2.mergeOrgMetadata)(currentMeta, {
447
+ description: params.description,
448
+ links: params.links,
449
+ logoCid,
450
+ backgroundColor: params.backgroundColor,
451
+ hideTreasury: params.hideTreasury,
452
+ });
453
+ // If name not provided, keep the current name (full-overwrite write).
454
+ const nameToSend = params.name || currentName;
455
+ const metaCid = await (0, ipfs_1.pinJson)((0, org_2.serializeOrgMetadata)(metadata), ctx.ipfs);
456
+ const metadataHash = (0, encoding_1.ipfsCidToBytes32)(metaCid);
457
+ const intent = buildUpdateOrgMetaAsAdmin({
458
+ orgRegistryAddress: orgRegistryAddr,
459
+ orgId,
460
+ name: nameToSend,
461
+ metadataHash,
462
+ });
463
+ intent.meta.ipfs = { cid: metaCid, metadata };
464
+ if (logoCid)
465
+ intent.meta.summary.logoCid = logoCid;
466
+ return intent;
467
+ }
468
+ /** The exact proposal title `pop org set-metadata-admin` uses. */
469
+ function setMetadataAdminTitle(hatId) {
470
+ return `Set org metadata-admin hat to ${ethers_1.ethers.BigNumber.from(hatId).toString()}`;
471
+ }
472
+ /**
473
+ * Port of `pop org set-metadata-admin` — src/commands/org/set-metadata-admin.ts.
474
+ *
475
+ * setOrgMetadataAdminHat(bytes32 orgId, uint256 hatId) is executor-only after
476
+ * bootstrap (revert NotOrgExecutor), so it ships as a HybridVoting proposal
477
+ * whose option-0 execution batch calls the OrgRegistry via the executor.
478
+ * Option 1 is "keep current" (empty batch). hatId 0 is meaningful: it clears
479
+ * the override so updateOrgMetaAsAdmin falls back to the org topHat.
480
+ */
481
+ function buildSetMetadataAdminProposal(a) {
482
+ const hatId = ethers_1.ethers.BigNumber.from(a.hatId);
483
+ // Same inline fragment the CLI encodes with — identical selector + calldata
484
+ // to the full OrgRegistry ABI.
485
+ const registryIface = new ethers_1.ethers.utils.Interface([
486
+ 'function setOrgMetadataAdminHat(bytes32 orgId, uint256 hatId)',
487
+ ]);
488
+ const setHatCall = registryIface.encodeFunctionData('setOrgMetadataAdminHat', [a.orgId, hatId]);
489
+ return (0, governance_1.buildGovernanceProposal)({
490
+ votingAddress: a.hybridVotingAddress,
491
+ votingAbiName: 'HybridVotingNew',
492
+ title: a.title ?? setMetadataAdminTitle(hatId),
493
+ descriptionHash: a.descriptionHash,
494
+ durationMinutes: a.durationMinutes,
495
+ numOptions: 2,
496
+ batches: [
497
+ [{ target: a.orgRegistryAddress, value: ethers_1.ethers.BigNumber.from(0), calldata: setHatCall }], // option 0: apply
498
+ [], // option 1: keep current
499
+ ],
500
+ hatIds: [],
501
+ orgId: a.orgId,
502
+ domain: 'org',
503
+ action: 'set-metadata-admin',
504
+ summary: { hatId: hatId.toString(), orgRegistry: a.orgRegistryAddress },
505
+ });
506
+ }
507
+ /**
508
+ * Resolved builder for `pop org set-metadata-admin` — src/commands/org/set-metadata-admin.ts.
509
+ * Resolves the org's HybridVoting module + the global OrgRegistry, pins the
510
+ * proposal metadata ({description, optionNames, createdAt} — key order is
511
+ * load-bearing), and delegates to buildSetMetadataAdminProposal.
512
+ */
513
+ async function setMetadataAdminIntent(ctx, params) {
514
+ const hatId = ethers_1.ethers.BigNumber.from(params.hatId);
515
+ const durationMinutes = params.durationMinutes ?? 60;
516
+ const modules = await (0, resolve_1.resolveOrgModules)(ctx.client, params.org, ctx.chainId);
517
+ const hybridVotingAddress = modules.hybridVotingAddress;
518
+ if (!hybridVotingAddress) {
519
+ throw new errors_1.CliError('HybridVoting not deployed for this org — cannot create a governance proposal.', exit_codes_1.EXIT.PRECONDITION);
520
+ }
521
+ // OrgRegistry is global infrastructure (not an org module).
522
+ const orgRegistryAddr = await resolveOrgRegistryAddress(ctx);
523
+ const hatLabel = hatId.isZero() ? '0 (clear — topHat fallback)' : hatId.toString();
524
+ const title = setMetadataAdminTitle(hatId);
525
+ // Proposal metadata — key order (description, optionNames, createdAt) is a
526
+ // protocol contract (metadata/proposal.ts); text matches the CLI exactly.
527
+ const metadata = (0, proposal_1.buildProposalMetadata)({
528
+ description: `Set the org's metadata-admin hat to ${hatLabel} via OrgRegistry.setOrgMetadataAdminHat. Wearers of this hat can update the org name/metadata directly (pop org update-metadata) without a vote.${hatId.isZero() ? ' A value of 0 clears the override so the org topHat is required instead.' : ''}`,
529
+ optionNames: [title, 'Keep current metadata admin'],
530
+ });
531
+ const cid = await (0, ipfs_1.pinJson)((0, proposal_1.serializeProposalMetadata)(metadata), ctx.ipfs);
532
+ const descriptionHash = (0, encoding_1.ipfsCidToBytes32)(cid);
533
+ const intent = buildSetMetadataAdminProposal({
534
+ hybridVotingAddress,
535
+ orgRegistryAddress: orgRegistryAddr,
536
+ orgId: modules.orgId,
537
+ hatId,
538
+ durationMinutes,
539
+ title,
540
+ descriptionHash,
541
+ });
542
+ intent.meta.ipfs = { cid, metadata };
543
+ return intent;
544
+ }
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Paymaster transaction builders — ports of `pop paymaster *` write paths
3
+ * (src/commands/paymaster/).
4
+ *
5
+ * buildDepositForOrg / depositForOrgIntent — pop paymaster deposit
6
+ * (PaymasterHub.depositForOrg(bytes32) payable — permissionless)
7
+ * buildRegisterCalldata / buildAdminCallRegister / registerOrgIntent —
8
+ * pop paymaster register (PoaManager.adminCall wrapping the
9
+ * registrar-gated registerOrg / registerAndConfigureOrg)
10
+ *
11
+ * Registration gate — VERIFIED against contracts origin/main
12
+ * src/PaymasterHub.sol: registerOrg / registerAndConfigureOrg are
13
+ * registrar-gated (_onlyRegistrar: msg.sender must be the PoaManager CONTRACT
14
+ * or the orgRegistrar, i.e. the OrgDeployer). No EOA can ever call them
15
+ * directly — the after-the-fact path is the PoaManager OWNER routing the call
16
+ * through PoaManager.adminCall(target, data). adminCall is NOT payable, so an
17
+ * initial deposit is always its own, separate depositForOrg transaction.
18
+ */
19
+ import { ethers } from 'ethers';
20
+ import type { TxIntent } from './intent';
21
+ import type { PopContext } from '../context';
22
+ /** DeployConfig struct shape — verified against PaymasterHub.sol origin/main. */
23
+ export declare const DEPLOY_CONFIG_TUPLE: string;
24
+ /**
25
+ * Optional --config JSON for registerAndConfigureOrg. Fee caps are GWEI and
26
+ * budget caps are ETHER units, matching the `pop org deploy` paymaster block
27
+ * conventions.
28
+ */
29
+ export interface PaymasterRegisterConfig {
30
+ operatorHatId?: string | number;
31
+ maxFeePerGas?: string | number;
32
+ maxPriorityFeePerGas?: string | number;
33
+ maxCallGas?: number;
34
+ maxVerificationGas?: number;
35
+ maxPreVerificationGas?: number;
36
+ rules?: Array<{
37
+ target: string;
38
+ selector: string;
39
+ allowed: boolean;
40
+ maxCallGasHint?: number;
41
+ }>;
42
+ budgets?: Array<{
43
+ subjectKey?: string;
44
+ hatId?: string | number;
45
+ capPerEpoch: string | number;
46
+ epochLen: number;
47
+ }>;
48
+ }
49
+ /** Parse a hat ID flag — BigNumber, never parseInt (Hats IDs exceed 2^53). */
50
+ export declare function parsePaymasterHatId(input: string | number, flag: string): ethers.BigNumber;
51
+ /** Parse an amount in ether units of the native gas token — port of parseDepositAmount in src/commands/paymaster/deposit.ts. */
52
+ export declare function parseDepositAmount(input: string | number): ethers.BigNumber;
53
+ /**
54
+ * Build the registerOrg / registerAndConfigureOrg calldata from the hat IDs +
55
+ * the optional config (gwei fee caps + ether budget caps). Pure port of
56
+ * buildRegisterCalldata in src/commands/paymaster/register.ts — byte-for-byte
57
+ * identical encoding.
58
+ */
59
+ export declare function buildRegisterCalldata(orgId: string, adminHatId: ethers.BigNumber, operatorHatId: ethers.BigNumber, config?: PaymasterRegisterConfig): {
60
+ method: string;
61
+ data: string;
62
+ };
63
+ export interface DepositForOrgArgs {
64
+ paymasterHubAddress: string;
65
+ /** bytes32 org id. */
66
+ orgId: string;
67
+ /** Native value in wei (the function is payable; reverts ZeroAmount on 0). */
68
+ amountWei: ethers.BigNumberish;
69
+ }
70
+ /**
71
+ * Port of `pop paymaster deposit` — src/commands/paymaster/deposit.ts:
72
+ * PaymasterHub.depositForOrg(bytes32 orgId) payable. PERMISSIONLESS ("anyone
73
+ * can deposit to any org"); reverts ZeroAmount on msg.value == 0 and
74
+ * OrgNotRegistered when the org has no paymaster config (adminHatId == 0).
75
+ * ONE-WAY on the deployed hub: no withdraw exists (PR #185 / audit M-04 not
76
+ * shipped) — funds draw down only as sponsored UserOperations consume them.
77
+ */
78
+ export declare function buildDepositForOrg(a: DepositForOrgArgs): TxIntent;
79
+ export interface AdminCallRegisterArgs {
80
+ poaManagerAddress: string;
81
+ paymasterHubAddress: string;
82
+ /** bytes32 org id. */
83
+ orgId: string;
84
+ adminHatId: ethers.BigNumber;
85
+ /** 0 = none. */
86
+ operatorHatId: ethers.BigNumber;
87
+ /** Present → registerAndConfigureOrg; absent → registerOrg. */
88
+ config?: PaymasterRegisterConfig;
89
+ }
90
+ /**
91
+ * Port of the owner path of `pop paymaster register` —
92
+ * src/commands/paymaster/register.ts: PoaManager.adminCall(paymasterHub,
93
+ * registerCalldata). Only the PoaManager OWNER can send this (adminCall is
94
+ * onlyOwner); any other signer's transaction must revert — the CLI prints the
95
+ * calldata for the owner instead of broadcasting, which hosts can reproduce
96
+ * with buildRegisterCalldata + encodeIntent.
97
+ */
98
+ export declare function buildAdminCallRegister(a: AdminCallRegisterArgs): TxIntent;
99
+ export interface DepositForOrgParams {
100
+ org: string;
101
+ /** Ether units of the native gas token (e.g. 0.05 = 0.05 xDAI on Gnosis). */
102
+ amount: string | number;
103
+ }
104
+ /**
105
+ * Resolved port of `pop paymaster deposit` — src/commands/paymaster/deposit.ts.
106
+ * Resolves the org id and the chain's singleton PaymasterHub proxy from the
107
+ * infrastructure subgraph (the hub is NOT in the org's module list). When
108
+ * ctx.provider is present, replicates the CLI's authoritative
109
+ * OrgNotRegistered gate (an eth_call on purpose — subgraph lag in a
110
+ * revert-predicting read means knowingly broadcasting a doomed tx).
111
+ */
112
+ export declare function depositForOrgIntent(ctx: PopContext, params: DepositForOrgParams): Promise<TxIntent>;
113
+ export interface RegisterOrgParams {
114
+ org: string;
115
+ /** Hat ID that will administer the org's paymaster config (usually the org top hat). */
116
+ adminHat: string | number;
117
+ /** Optional hat ID allowed to manage budgets/rules (0 = none). */
118
+ operatorHat?: string | number;
119
+ /** Initial fee caps (gwei), rules, and budgets (ether caps) — uses registerAndConfigureOrg. */
120
+ config?: PaymasterRegisterConfig;
121
+ }
122
+ /**
123
+ * Resolved port of `pop paymaster register` —
124
+ * src/commands/paymaster/register.ts (the adminCall route). Resolves the org
125
+ * id + PaymasterHub + PoaManager from the infrastructure subgraph and returns
126
+ * the PoaManager.adminCall intent.
127
+ *
128
+ * Registration check is asymmetric like the CLI: a POSITIVE indexed
129
+ * "registered" answer is trusted; a negative is re-confirmed on chain when
130
+ * ctx.provider is available. An already-registered org throws
131
+ * PreconditionError (the CLI reports it as a no-op success — builder callers
132
+ * need the hard stop, since the intent would be a doomed re-registration).
133
+ *
134
+ * NOTE the on-chain gate the builder cannot check for you: adminCall is
135
+ * onlyOwner on the PoaManager, and PoaManager.owner() has no subgraph field
136
+ * in either live deployment — the CLI reads it via eth_call and prints the
137
+ * calldata instead of broadcasting when the signer is not the owner. Hosts
138
+ * should do the same before executing this intent.
139
+ */
140
+ export declare function registerOrgIntent(ctx: PopContext, params: RegisterOrgParams): Promise<TxIntent>;