@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.
- package/README.md +201 -0
- package/dist/abis/DirectDemocracyVotingNew.d.ts +749 -0
- package/dist/abis/DirectDemocracyVotingNew.js +961 -0
- package/dist/abis/ERC20.d.ts +90 -0
- package/dist/abis/ERC20.js +125 -0
- package/dist/abis/EducationHubNew.d.ts +590 -0
- package/dist/abis/EducationHubNew.js +762 -0
- package/dist/abis/EligibilityModuleNew.d.ts +1615 -0
- package/dist/abis/EligibilityModuleNew.js +2082 -0
- package/dist/abis/Executor.d.ts +619 -0
- package/dist/abis/Executor.js +796 -0
- package/dist/abis/HybridVotingNew.d.ts +898 -0
- package/dist/abis/HybridVotingNew.js +1149 -0
- package/dist/abis/ImplementationRegistry.d.ts +270 -0
- package/dist/abis/ImplementationRegistry.js +355 -0
- package/dist/abis/OrgDeployerNew.d.ts +1275 -0
- package/dist/abis/OrgDeployerNew.js +1630 -0
- package/dist/abis/OrgRegistry.d.ts +670 -0
- package/dist/abis/OrgRegistry.js +868 -0
- package/dist/abis/ParticipationToken.d.ts +1086 -0
- package/dist/abis/ParticipationToken.js +1415 -0
- package/dist/abis/PasskeyAccount.d.ts +788 -0
- package/dist/abis/PasskeyAccount.js +1019 -0
- package/dist/abis/PasskeyAccountFactory.d.ts +344 -0
- package/dist/abis/PasskeyAccountFactory.js +449 -0
- package/dist/abis/PaymasterHub.d.ts +1603 -0
- package/dist/abis/PaymasterHub.js +2048 -0
- package/dist/abis/PaymentManager.d.ts +520 -0
- package/dist/abis/PaymentManager.js +671 -0
- package/dist/abis/PoaManager.d.ts +344 -0
- package/dist/abis/PoaManager.js +449 -0
- package/dist/abis/QuickJoinNew.d.ts +855 -0
- package/dist/abis/QuickJoinNew.js +1098 -0
- package/dist/abis/TaskManagerNew.d.ts +1236 -0
- package/dist/abis/TaskManagerNew.js +1573 -0
- package/dist/abis/ToggleModule.d.ts +193 -0
- package/dist/abis/ToggleModule.js +255 -0
- package/dist/abis/UniversalAccountRegistry.d.ts +577 -0
- package/dist/abis/UniversalAccountRegistry.js +750 -0
- package/dist/abis/ZkEmailInvites.d.ts +823 -0
- package/dist/abis/ZkEmailInvites.js +1060 -0
- package/dist/abis/external/AaveGovernanceV2.d.ts +128 -0
- package/dist/abis/external/AaveGovernanceV2.js +177 -0
- package/dist/abis/external/AaveGovernanceV3.d.ts +160 -0
- package/dist/abis/external/AaveGovernanceV3.js +220 -0
- package/dist/abis/external/AragonVoting.d.ts +107 -0
- package/dist/abis/external/AragonVoting.js +150 -0
- package/dist/abis/external/CurveGaugeController.d.ts +95 -0
- package/dist/abis/external/CurveGaugeController.js +130 -0
- package/dist/abis/external/CurveVotingEscrow.d.ts +86 -0
- package/dist/abis/external/CurveVotingEscrow.js +116 -0
- package/dist/abis/external/GovernorAlpha.d.ts +172 -0
- package/dist/abis/external/GovernorAlpha.js +228 -0
- package/dist/abis/external/MakerDAOChief.d.ts +92 -0
- package/dist/abis/external/MakerDAOChief.js +129 -0
- package/dist/abis/external/OZGovernor.d.ts +227 -0
- package/dist/abis/external/OZGovernor.js +317 -0
- package/dist/abis/external/SolidlyVotingEscrow.d.ts +196 -0
- package/dist/abis/external/SolidlyVotingEscrow.js +260 -0
- package/dist/abis/index.d.ts +62 -0
- package/dist/abis/index.js +98 -0
- package/dist/chains.d.ts +150 -0
- package/dist/chains.js +320 -0
- package/dist/context.d.ts +48 -0
- package/dist/context.js +38 -0
- package/dist/contracts.d.ts +24 -0
- package/dist/contracts.js +41 -0
- package/dist/encoding.d.ts +58 -0
- package/dist/encoding.js +243 -0
- package/dist/env.d.ts +10 -0
- package/dist/env.js +4 -0
- package/dist/error-catalog.d.ts +41 -0
- package/dist/error-catalog.js +941 -0
- package/dist/errors.d.ts +27 -0
- package/dist/errors.js +60 -0
- package/dist/execute/ethers.d.ts +93 -0
- package/dist/execute/ethers.js +323 -0
- package/dist/execute/index.d.ts +7 -0
- package/dist/execute/index.js +23 -0
- package/dist/execute/sponsored.d.ts +68 -0
- package/dist/execute/sponsored.js +277 -0
- package/dist/exit-codes.d.ts +18 -0
- package/dist/exit-codes.js +21 -0
- package/dist/format.d.ts +21 -0
- package/dist/format.js +89 -0
- package/dist/graph/client.d.ts +298 -0
- package/dist/graph/client.js +702 -0
- package/dist/graph/documents/activity.d.ts +9 -0
- package/dist/graph/documents/activity.js +164 -0
- package/dist/graph/documents/beacons.d.ts +172 -0
- package/dist/graph/documents/beacons.js +345 -0
- package/dist/graph/documents/index.d.ts +21 -0
- package/dist/graph/documents/index.js +57 -0
- package/dist/graph/documents/infrastructure.d.ts +30 -0
- package/dist/graph/documents/infrastructure.js +34 -0
- package/dist/graph/documents/org.d.ts +15 -0
- package/dist/graph/documents/org.js +249 -0
- package/dist/graph/documents/paymaster.d.ts +95 -0
- package/dist/graph/documents/paymaster.js +101 -0
- package/dist/graph/documents/role.d.ts +6 -0
- package/dist/graph/documents/role.js +41 -0
- package/dist/graph/documents/roles.d.ts +50 -0
- package/dist/graph/documents/roles.js +112 -0
- package/dist/graph/documents/task.d.ts +84 -0
- package/dist/graph/documents/task.js +236 -0
- package/dist/graph/documents/token.d.ts +13 -0
- package/dist/graph/documents/token.js +126 -0
- package/dist/graph/documents/treasury.d.ts +39 -0
- package/dist/graph/documents/treasury.js +136 -0
- package/dist/graph/documents/user.d.ts +120 -0
- package/dist/graph/documents/user.js +302 -0
- package/dist/graph/documents/voting-classes.d.ts +69 -0
- package/dist/graph/documents/voting-classes.js +149 -0
- package/dist/graph/documents/voting.d.ts +28 -0
- package/dist/graph/documents/voting.js +163 -0
- package/dist/graph/documents/vouch.d.ts +79 -0
- package/dist/graph/documents/vouch.js +171 -0
- package/dist/graph/documents/zkemail.d.ts +63 -0
- package/dist/graph/documents/zkemail.js +188 -0
- package/dist/graph/index.d.ts +2 -0
- package/dist/graph/index.js +41 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.js +92 -0
- package/dist/ipfs.d.ts +39 -0
- package/dist/ipfs.js +214 -0
- package/dist/label-aliases.d.ts +31 -0
- package/dist/label-aliases.js +70 -0
- package/dist/metadata/education.d.ts +30 -0
- package/dist/metadata/education.js +31 -0
- package/dist/metadata/index.d.ts +12 -0
- package/dist/metadata/index.js +48 -0
- package/dist/metadata/org.d.ts +92 -0
- package/dist/metadata/org.js +93 -0
- package/dist/metadata/proposal.d.ts +44 -0
- package/dist/metadata/proposal.js +45 -0
- package/dist/metadata/role.d.ts +38 -0
- package/dist/metadata/role.js +35 -0
- package/dist/metadata/task.d.ts +108 -0
- package/dist/metadata/task.js +81 -0
- package/dist/metadata/token.d.ts +32 -0
- package/dist/metadata/token.js +36 -0
- package/dist/metadata/user.d.ts +63 -0
- package/dist/metadata/user.js +70 -0
- package/dist/multicall.d.ts +32 -0
- package/dist/multicall.js +96 -0
- package/dist/payout.d.ts +59 -0
- package/dist/payout.js +96 -0
- package/dist/perms.d.ts +47 -0
- package/dist/perms.js +120 -0
- package/dist/preflight.d.ts +72 -0
- package/dist/preflight.js +269 -0
- package/dist/reads/education.d.ts +79 -0
- package/dist/reads/education.js +122 -0
- package/dist/reads/eligibility.d.ts +377 -0
- package/dist/reads/eligibility.js +687 -0
- package/dist/reads/index.d.ts +16 -0
- package/dist/reads/index.js +55 -0
- package/dist/reads/org.d.ts +258 -0
- package/dist/reads/org.js +220 -0
- package/dist/reads/paymaster.d.ts +147 -0
- package/dist/reads/paymaster.js +235 -0
- package/dist/reads/project.d.ts +33 -0
- package/dist/reads/project.js +62 -0
- package/dist/reads/resolve.d.ts +34 -0
- package/dist/reads/resolve.js +64 -0
- package/dist/reads/task.d.ts +286 -0
- package/dist/reads/task.js +280 -0
- package/dist/reads/token.d.ts +94 -0
- package/dist/reads/token.js +75 -0
- package/dist/reads/treasury.d.ts +222 -0
- package/dist/reads/treasury.js +241 -0
- package/dist/reads/user.d.ts +229 -0
- package/dist/reads/user.js +155 -0
- package/dist/reads/vote.d.ts +296 -0
- package/dist/reads/vote.js +392 -0
- package/dist/reads/zkemail.d.ts +117 -0
- package/dist/reads/zkemail.js +217 -0
- package/dist/similarity.d.ts +36 -0
- package/dist/similarity.js +67 -0
- package/dist/sponsorship-config.d.ts +47 -0
- package/dist/sponsorship-config.js +41 -0
- package/dist/stats.d.ts +11 -0
- package/dist/stats.js +27 -0
- package/dist/task-lens.d.ts +113 -0
- package/dist/task-lens.js +210 -0
- package/dist/tx/education.d.ts +169 -0
- package/dist/tx/education.js +344 -0
- package/dist/tx/eligibility.d.ts +511 -0
- package/dist/tx/eligibility.js +818 -0
- package/dist/tx/governance.d.ts +85 -0
- package/dist/tx/governance.js +87 -0
- package/dist/tx/index.d.ts +17 -0
- package/dist/tx/index.js +56 -0
- package/dist/tx/intent.d.ts +67 -0
- package/dist/tx/intent.js +48 -0
- package/dist/tx/org.d.ts +321 -0
- package/dist/tx/org.js +544 -0
- package/dist/tx/paymaster.d.ts +140 -0
- package/dist/tx/paymaster.js +251 -0
- package/dist/tx/project.d.ts +146 -0
- package/dist/tx/project.js +217 -0
- package/dist/tx/task.d.ts +480 -0
- package/dist/tx/task.js +1149 -0
- package/dist/tx/token.d.ts +96 -0
- package/dist/tx/token.js +165 -0
- package/dist/tx/treasury.d.ts +474 -0
- package/dist/tx/treasury.js +911 -0
- package/dist/tx/user.d.ts +177 -0
- package/dist/tx/user.js +292 -0
- package/dist/tx/vote.d.ts +332 -0
- package/dist/tx/vote.js +762 -0
- package/dist/tx/zkemail.d.ts +90 -0
- package/dist/tx/zkemail.js +210 -0
- package/dist/validation.d.ts +8 -0
- package/dist/validation.js +39 -0
- package/dist/version.d.ts +142 -0
- package/dist/version.js +257 -0
- package/dist/zkemail.d.ts +161 -0
- package/dist/zkemail.js +299 -0
- package/package.json +130 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* User-profile metadata — the document `pop user update-profile` pins to IPFS
|
|
4
|
+
* before calling UniversalAccountRegistry.setProfileMetadata.
|
|
5
|
+
*
|
|
6
|
+
* Port of the merge logic in src/commands/user/update-profile.ts.
|
|
7
|
+
*
|
|
8
|
+
* KEY ORDER IS A PROTOCOL CONTRACT: keys are CONDITIONALLY PRESENT but appear
|
|
9
|
+
* in the fixed order {bio, avatar, github, twitter, website} — a key is
|
|
10
|
+
* included when the caller supplies a new value (even an empty string) OR the
|
|
11
|
+
* existing indexed metadata carries a truthy value for it. The subgraph's
|
|
12
|
+
* AccountMetadata mapping and the frontend both consume this document; do not
|
|
13
|
+
* reorder or unconditionally include keys.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.USER_PROFILE_FIELDS = void 0;
|
|
17
|
+
exports.buildUserProfileMetadata = buildUserProfileMetadata;
|
|
18
|
+
exports.serializeUserProfileMetadata = serializeUserProfileMetadata;
|
|
19
|
+
const errors_1 = require("../errors");
|
|
20
|
+
const exit_codes_1 = require("../exit-codes");
|
|
21
|
+
/** The five profile fields, in canonical document order. */
|
|
22
|
+
exports.USER_PROFILE_FIELDS = ['bio', 'avatar', 'github', 'twitter', 'website'];
|
|
23
|
+
/**
|
|
24
|
+
* Read-then-merge profile metadata builder.
|
|
25
|
+
* Port of `pop user update-profile` — src/commands/user/update-profile.ts.
|
|
26
|
+
*
|
|
27
|
+
* Replicates the CLI's inclusion + precedence rules EXACTLY:
|
|
28
|
+
* - a key is included when `updates.<k> !== undefined` OR `existing.<k>` is
|
|
29
|
+
* truthy (so single-flag edits preserve the other fields, and an explicit
|
|
30
|
+
* empty string clears a field while keeping the key);
|
|
31
|
+
* - value precedence: updates.<k> ?? existing.<k> ?? '';
|
|
32
|
+
* - bio is capped at 280 chars (same error message and exit code).
|
|
33
|
+
*/
|
|
34
|
+
function buildUserProfileMetadata(updates, existing) {
|
|
35
|
+
const prev = existing || {};
|
|
36
|
+
const metadata = {};
|
|
37
|
+
// Conditional keys, fixed order — order is load-bearing.
|
|
38
|
+
if (updates.bio !== undefined || prev.bio)
|
|
39
|
+
metadata.bio = updates.bio ?? prev.bio ?? '';
|
|
40
|
+
if (updates.avatar !== undefined || prev.avatar)
|
|
41
|
+
metadata.avatar = updates.avatar ?? prev.avatar ?? '';
|
|
42
|
+
if (updates.github !== undefined || prev.github)
|
|
43
|
+
metadata.github = updates.github ?? prev.github ?? '';
|
|
44
|
+
if (updates.twitter !== undefined || prev.twitter)
|
|
45
|
+
metadata.twitter = updates.twitter ?? prev.twitter ?? '';
|
|
46
|
+
if (updates.website !== undefined || prev.website)
|
|
47
|
+
metadata.website = updates.website ?? prev.website ?? '';
|
|
48
|
+
if (metadata.bio && metadata.bio.length > 280) {
|
|
49
|
+
throw new errors_1.CliError(`Bio too long: ${metadata.bio.length}/280 chars`, exit_codes_1.EXIT.USAGE);
|
|
50
|
+
}
|
|
51
|
+
return metadata;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Serialize with the exact conditional key order the CLI pins. Rebuilt with
|
|
55
|
+
* explicit ordering so callers cannot accidentally pin a reordered document.
|
|
56
|
+
*/
|
|
57
|
+
function serializeUserProfileMetadata(metadata) {
|
|
58
|
+
const ordered = {};
|
|
59
|
+
if (metadata.bio !== undefined)
|
|
60
|
+
ordered.bio = metadata.bio;
|
|
61
|
+
if (metadata.avatar !== undefined)
|
|
62
|
+
ordered.avatar = metadata.avatar;
|
|
63
|
+
if (metadata.github !== undefined)
|
|
64
|
+
ordered.github = metadata.github;
|
|
65
|
+
if (metadata.twitter !== undefined)
|
|
66
|
+
ordered.twitter = metadata.twitter;
|
|
67
|
+
if (metadata.website !== undefined)
|
|
68
|
+
ordered.website = metadata.website;
|
|
69
|
+
return JSON.stringify(ordered);
|
|
70
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multicall3 Batching
|
|
3
|
+
* Batch read-only eth_calls through the canonical Multicall3 deployment
|
|
4
|
+
* (same address on every chain, https://www.multicall3.com). When Multicall3
|
|
5
|
+
* is not deployed on the target chain, degrades to parallel provider.call
|
|
6
|
+
* with per-call error trapping so callers always get one result per call.
|
|
7
|
+
*/
|
|
8
|
+
import { ethers } from 'ethers';
|
|
9
|
+
/** Canonical Multicall3 address (identical across all supported chains). */
|
|
10
|
+
export declare const MULTICALL3 = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
11
|
+
export interface Call {
|
|
12
|
+
to: string;
|
|
13
|
+
data: string;
|
|
14
|
+
}
|
|
15
|
+
export interface CallResult {
|
|
16
|
+
success: boolean;
|
|
17
|
+
returnData: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Batch read-only calls through Multicall3.tryAggregate(requireSuccess=false),
|
|
21
|
+
* one RPC round-trip for the whole batch. Per-call reverts surface as
|
|
22
|
+
* { success: false } instead of throwing. When Multicall3 is unavailable
|
|
23
|
+
* (or the aggregate call itself fails), falls back to parallel provider.call
|
|
24
|
+
* with the same per-call error mapping.
|
|
25
|
+
*/
|
|
26
|
+
export declare function tryAggregate(provider: ethers.providers.Provider, calls: Call[], opts?: {
|
|
27
|
+
blockTag?: number;
|
|
28
|
+
}): Promise<CallResult[]>;
|
|
29
|
+
/** Calldata for Multicall3.getEthBalance(address), for batching native-balance reads. */
|
|
30
|
+
export declare function getEthBalanceCall(address: string): Call;
|
|
31
|
+
/** Decode the uint256 balance from a getEthBalance return payload. */
|
|
32
|
+
export declare function decodeEthBalance(returnData: string): ethers.BigNumber;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Multicall3 Batching
|
|
4
|
+
* Batch read-only eth_calls through the canonical Multicall3 deployment
|
|
5
|
+
* (same address on every chain, https://www.multicall3.com). When Multicall3
|
|
6
|
+
* is not deployed on the target chain, degrades to parallel provider.call
|
|
7
|
+
* with per-call error trapping so callers always get one result per call.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.MULTICALL3 = void 0;
|
|
11
|
+
exports.tryAggregate = tryAggregate;
|
|
12
|
+
exports.getEthBalanceCall = getEthBalanceCall;
|
|
13
|
+
exports.decodeEthBalance = decodeEthBalance;
|
|
14
|
+
const ethers_1 = require("ethers");
|
|
15
|
+
/** Canonical Multicall3 address (identical across all supported chains). */
|
|
16
|
+
exports.MULTICALL3 = '0xcA11bde05977b3631167028862bE2a173976CA11';
|
|
17
|
+
const MULTICALL3_IFACE = new ethers_1.ethers.utils.Interface([
|
|
18
|
+
'function tryAggregate(bool requireSuccess, tuple(address target, bytes callData)[] calls) returns (tuple(bool success, bytes returnData)[] returnData)',
|
|
19
|
+
'function getEthBalance(address addr) view returns (uint256 balance)',
|
|
20
|
+
]);
|
|
21
|
+
/**
|
|
22
|
+
* Multicall3 availability, cached per provider instance (a provider is bound
|
|
23
|
+
* to one chain, so this is effectively per provider/chain).
|
|
24
|
+
*/
|
|
25
|
+
const availabilityCache = new WeakMap();
|
|
26
|
+
function isMulticallAvailable(provider) {
|
|
27
|
+
let available = availabilityCache.get(provider);
|
|
28
|
+
if (!available) {
|
|
29
|
+
available = provider
|
|
30
|
+
.getCode(exports.MULTICALL3)
|
|
31
|
+
.then((code) => typeof code === 'string' && code.length > 2 && code !== '0x0')
|
|
32
|
+
.catch(() => false);
|
|
33
|
+
availabilityCache.set(provider, available);
|
|
34
|
+
}
|
|
35
|
+
return available;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Fallback for chains without Multicall3: issue the call directly.
|
|
39
|
+
* getEthBalance calls target Multicall3 itself, so without the deployment
|
|
40
|
+
* they are answered from eth_getBalance instead of eth_call.
|
|
41
|
+
*/
|
|
42
|
+
async function fallbackCall(provider, call, blockTag) {
|
|
43
|
+
try {
|
|
44
|
+
if (call.to.toLowerCase() === exports.MULTICALL3.toLowerCase() &&
|
|
45
|
+
call.data.slice(0, 10).toLowerCase() === MULTICALL3_IFACE.getSighash('getEthBalance').toLowerCase()) {
|
|
46
|
+
const [addr] = MULTICALL3_IFACE.decodeFunctionData('getEthBalance', call.data);
|
|
47
|
+
const balance = await provider.getBalance(addr, blockTag);
|
|
48
|
+
return { success: true, returnData: ethers_1.ethers.utils.defaultAbiCoder.encode(['uint256'], [balance]) };
|
|
49
|
+
}
|
|
50
|
+
const returnData = await provider.call({ to: call.to, data: call.data }, blockTag);
|
|
51
|
+
return { success: true, returnData };
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return { success: false, returnData: '0x' };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Batch read-only calls through Multicall3.tryAggregate(requireSuccess=false),
|
|
59
|
+
* one RPC round-trip for the whole batch. Per-call reverts surface as
|
|
60
|
+
* { success: false } instead of throwing. When Multicall3 is unavailable
|
|
61
|
+
* (or the aggregate call itself fails), falls back to parallel provider.call
|
|
62
|
+
* with the same per-call error mapping.
|
|
63
|
+
*/
|
|
64
|
+
async function tryAggregate(provider, calls, opts) {
|
|
65
|
+
if (calls.length === 0)
|
|
66
|
+
return [];
|
|
67
|
+
if (await isMulticallAvailable(provider)) {
|
|
68
|
+
try {
|
|
69
|
+
const data = MULTICALL3_IFACE.encodeFunctionData('tryAggregate', [
|
|
70
|
+
false,
|
|
71
|
+
calls.map((c) => [c.to, c.data]),
|
|
72
|
+
]);
|
|
73
|
+
const raw = await provider.call({ to: exports.MULTICALL3, data }, opts?.blockTag);
|
|
74
|
+
const [results] = MULTICALL3_IFACE.decodeFunctionResult('tryAggregate', raw);
|
|
75
|
+
return results.map((r) => ({
|
|
76
|
+
success: r.success,
|
|
77
|
+
returnData: r.returnData,
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// Aggregate call failed — degrade to the parallel fallback below.
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return Promise.all(calls.map((call) => fallbackCall(provider, call, opts?.blockTag)));
|
|
85
|
+
}
|
|
86
|
+
/** Calldata for Multicall3.getEthBalance(address), for batching native-balance reads. */
|
|
87
|
+
function getEthBalanceCall(address) {
|
|
88
|
+
return {
|
|
89
|
+
to: exports.MULTICALL3,
|
|
90
|
+
data: MULTICALL3_IFACE.encodeFunctionData('getEthBalance', [address]),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/** Decode the uint256 balance from a getEthBalance return payload. */
|
|
94
|
+
function decodeEthBalance(returnData) {
|
|
95
|
+
return MULTICALL3_IFACE.decodeFunctionResult('getEthBalance', returnData)[0];
|
|
96
|
+
}
|
package/dist/payout.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task payout + token-label conventions.
|
|
3
|
+
*
|
|
4
|
+
* Port of the frontend's `poa-app/src/util/taskUtils.js` (payout math, 15-minute time helpers)
|
|
5
|
+
* and `src/util/tokenLabel.js` (token label). None of this is enforced on-chain — TaskManager
|
|
6
|
+
* stores whatever payout it is handed — so it is a shared CONVENTION between the UI and the
|
|
7
|
+
* CLI. Diverging here produces tasks that look mispriced in the app next to identical ones
|
|
8
|
+
* created in the browser, which is why the numbers are copied rather than re-derived.
|
|
9
|
+
*
|
|
10
|
+
* Two payout modes:
|
|
11
|
+
* - default: difficulty-weighted, base + multiplier x estimated hours
|
|
12
|
+
* - hours-only: the org sets `taskPayoutHoursOnly` in its metadata; difficulty is ignored
|
|
13
|
+
* and payout is simply rate x estimated hours
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Difficulty configuration for payout calculation.
|
|
17
|
+
* base payout + (multiplier * estimated hours) = total payout.
|
|
18
|
+
*/
|
|
19
|
+
export declare const DIFFICULTY_CONFIG: Record<string, {
|
|
20
|
+
base: number;
|
|
21
|
+
multiplier: number;
|
|
22
|
+
}>;
|
|
23
|
+
/** Tokens-per-hour default for orgs that opt into hours-only payouts. */
|
|
24
|
+
export declare const DEFAULT_HOURLY_RATE = 10;
|
|
25
|
+
/** Orgs default to "Shares" unless they opt into the token's on-chain symbol. */
|
|
26
|
+
export declare const DEFAULT_TOKEN_LABEL = "Shares";
|
|
27
|
+
export declare const MINUTES_STEP = 15;
|
|
28
|
+
export interface PayoutConfig {
|
|
29
|
+
hoursOnly?: boolean;
|
|
30
|
+
hourlyRate?: number | string | null;
|
|
31
|
+
}
|
|
32
|
+
/** Normalize a configured hourly rate to a positive finite number. */
|
|
33
|
+
export declare function normalizeHourlyRate(value: unknown): number;
|
|
34
|
+
/**
|
|
35
|
+
* Calculate a task payout the same way the web app does.
|
|
36
|
+
*
|
|
37
|
+
* An unknown difficulty falls back to `medium` rather than throwing, matching the frontend —
|
|
38
|
+
* the CLI accepts free-text --difficulty and older tasks carry values no longer in the config.
|
|
39
|
+
*/
|
|
40
|
+
export declare function calculatePayout(difficulty: string | undefined, estimatedHours: number, payoutConfig?: PayoutConfig): number;
|
|
41
|
+
/**
|
|
42
|
+
* Resolve the user-facing label for an org's participation token.
|
|
43
|
+
* `useTokenSymbol` is an OrgMetadata flag; without it every amount reads as "Shares".
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveTokenLabel(args?: {
|
|
46
|
+
useTokenSymbol?: boolean;
|
|
47
|
+
symbol?: string | null;
|
|
48
|
+
}): string;
|
|
49
|
+
/**
|
|
50
|
+
* Format decimal hours as a compact "1h 30m" / "45m" / "2h" label.
|
|
51
|
+
*
|
|
52
|
+
* Durations are stored as decimal hours (0.25 = 15 min); hours-only orgs enter and read them
|
|
53
|
+
* in 15-minute steps, so "0.25 hrs" is the wrong unit to show those members.
|
|
54
|
+
*/
|
|
55
|
+
export declare function formatEstTime(hours: number | string): string;
|
|
56
|
+
/** Read an org's payout convention out of its OrgMetadata (subgraph entity or raw IPFS doc). */
|
|
57
|
+
export declare function payoutConfigFromMetadata(metadata: any): PayoutConfig & {
|
|
58
|
+
useTokenSymbol: boolean;
|
|
59
|
+
};
|
package/dist/payout.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Task payout + token-label conventions.
|
|
4
|
+
*
|
|
5
|
+
* Port of the frontend's `poa-app/src/util/taskUtils.js` (payout math, 15-minute time helpers)
|
|
6
|
+
* and `src/util/tokenLabel.js` (token label). None of this is enforced on-chain — TaskManager
|
|
7
|
+
* stores whatever payout it is handed — so it is a shared CONVENTION between the UI and the
|
|
8
|
+
* CLI. Diverging here produces tasks that look mispriced in the app next to identical ones
|
|
9
|
+
* created in the browser, which is why the numbers are copied rather than re-derived.
|
|
10
|
+
*
|
|
11
|
+
* Two payout modes:
|
|
12
|
+
* - default: difficulty-weighted, base + multiplier x estimated hours
|
|
13
|
+
* - hours-only: the org sets `taskPayoutHoursOnly` in its metadata; difficulty is ignored
|
|
14
|
+
* and payout is simply rate x estimated hours
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.MINUTES_STEP = exports.DEFAULT_TOKEN_LABEL = exports.DEFAULT_HOURLY_RATE = exports.DIFFICULTY_CONFIG = void 0;
|
|
18
|
+
exports.normalizeHourlyRate = normalizeHourlyRate;
|
|
19
|
+
exports.calculatePayout = calculatePayout;
|
|
20
|
+
exports.resolveTokenLabel = resolveTokenLabel;
|
|
21
|
+
exports.formatEstTime = formatEstTime;
|
|
22
|
+
exports.payoutConfigFromMetadata = payoutConfigFromMetadata;
|
|
23
|
+
/**
|
|
24
|
+
* Difficulty configuration for payout calculation.
|
|
25
|
+
* base payout + (multiplier * estimated hours) = total payout.
|
|
26
|
+
*/
|
|
27
|
+
exports.DIFFICULTY_CONFIG = {
|
|
28
|
+
easy: { base: 1, multiplier: 16.5 },
|
|
29
|
+
medium: { base: 4, multiplier: 24 },
|
|
30
|
+
hard: { base: 10, multiplier: 30 },
|
|
31
|
+
veryHard: { base: 25, multiplier: 37.5 },
|
|
32
|
+
};
|
|
33
|
+
/** Tokens-per-hour default for orgs that opt into hours-only payouts. */
|
|
34
|
+
exports.DEFAULT_HOURLY_RATE = 10;
|
|
35
|
+
/** Orgs default to "Shares" unless they opt into the token's on-chain symbol. */
|
|
36
|
+
exports.DEFAULT_TOKEN_LABEL = 'Shares';
|
|
37
|
+
exports.MINUTES_STEP = 15;
|
|
38
|
+
/** Normalize a configured hourly rate to a positive finite number. */
|
|
39
|
+
function normalizeHourlyRate(value) {
|
|
40
|
+
const rate = Number(value);
|
|
41
|
+
return Number.isFinite(rate) && rate > 0 ? rate : exports.DEFAULT_HOURLY_RATE;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Calculate a task payout the same way the web app does.
|
|
45
|
+
*
|
|
46
|
+
* An unknown difficulty falls back to `medium` rather than throwing, matching the frontend —
|
|
47
|
+
* the CLI accepts free-text --difficulty and older tasks carry values no longer in the config.
|
|
48
|
+
*/
|
|
49
|
+
function calculatePayout(difficulty, estimatedHours, payoutConfig) {
|
|
50
|
+
const hours = Number(estimatedHours) || 0;
|
|
51
|
+
if (payoutConfig?.hoursOnly) {
|
|
52
|
+
return Math.round(normalizeHourlyRate(payoutConfig.hourlyRate) * hours);
|
|
53
|
+
}
|
|
54
|
+
const config = exports.DIFFICULTY_CONFIG[difficulty];
|
|
55
|
+
if (!config)
|
|
56
|
+
return calculatePayout('medium', hours);
|
|
57
|
+
return Math.round(config.base + config.multiplier * hours);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Resolve the user-facing label for an org's participation token.
|
|
61
|
+
* `useTokenSymbol` is an OrgMetadata flag; without it every amount reads as "Shares".
|
|
62
|
+
*/
|
|
63
|
+
function resolveTokenLabel(args) {
|
|
64
|
+
const { useTokenSymbol, symbol } = args || {};
|
|
65
|
+
if (useTokenSymbol === true && symbol && typeof symbol === 'string' && symbol.trim()) {
|
|
66
|
+
return symbol.trim();
|
|
67
|
+
}
|
|
68
|
+
return exports.DEFAULT_TOKEN_LABEL;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Format decimal hours as a compact "1h 30m" / "45m" / "2h" label.
|
|
72
|
+
*
|
|
73
|
+
* Durations are stored as decimal hours (0.25 = 15 min); hours-only orgs enter and read them
|
|
74
|
+
* in 15-minute steps, so "0.25 hrs" is the wrong unit to show those members.
|
|
75
|
+
*/
|
|
76
|
+
function formatEstTime(hours) {
|
|
77
|
+
const totalMin = Math.round(Number(hours) * 60);
|
|
78
|
+
if (!Number.isFinite(totalMin) || totalMin <= 0)
|
|
79
|
+
return '0m';
|
|
80
|
+
const h = Math.floor(totalMin / 60);
|
|
81
|
+
const m = totalMin % 60;
|
|
82
|
+
if (h && m)
|
|
83
|
+
return `${h}h ${m}m`;
|
|
84
|
+
if (h)
|
|
85
|
+
return `${h}h`;
|
|
86
|
+
return `${m}m`;
|
|
87
|
+
}
|
|
88
|
+
/** Read an org's payout convention out of its OrgMetadata (subgraph entity or raw IPFS doc). */
|
|
89
|
+
function payoutConfigFromMetadata(metadata) {
|
|
90
|
+
return {
|
|
91
|
+
hoursOnly: metadata?.taskPayoutHoursOnly === true,
|
|
92
|
+
// BigDecimal arrives from the subgraph as a string; normalizeHourlyRate coerces it.
|
|
93
|
+
hourlyRate: metadata?.taskPayoutHourlyRate ?? null,
|
|
94
|
+
useTokenSymbol: metadata?.useTokenSymbol === true,
|
|
95
|
+
};
|
|
96
|
+
}
|
package/dist/perms.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TaskManager Permission Bitmask Utilities
|
|
3
|
+
* Parse, format, and describe TaskPerm bitmasks used by the
|
|
4
|
+
* TaskManager contract's per-member permission system.
|
|
5
|
+
*/
|
|
6
|
+
export declare const PERM_BITS: {
|
|
7
|
+
readonly create: 1;
|
|
8
|
+
readonly claim: 2;
|
|
9
|
+
readonly review: 4;
|
|
10
|
+
readonly assign: 8;
|
|
11
|
+
readonly 'self-review': 16;
|
|
12
|
+
readonly budget: 32;
|
|
13
|
+
readonly 'edit-meta': 64;
|
|
14
|
+
readonly 'edit-full': 128;
|
|
15
|
+
};
|
|
16
|
+
export type PermName = keyof typeof PERM_BITS;
|
|
17
|
+
/**
|
|
18
|
+
* Parse a comma-separated list of permission names into a bitmask.
|
|
19
|
+
* Case-insensitive, whitespace-tolerant. Empty string or 'none' → 0.
|
|
20
|
+
* Throws CliError listing valid names on an unknown permission.
|
|
21
|
+
*/
|
|
22
|
+
export declare function parsePermList(input: string): number;
|
|
23
|
+
/**
|
|
24
|
+
* Format a bitmask as a comma-separated list of permission names.
|
|
25
|
+
* 0 → 'none'. Unrecognized high bits render as 'bitN' (N = bit index).
|
|
26
|
+
*/
|
|
27
|
+
export declare function formatMask(mask: number): string;
|
|
28
|
+
/**
|
|
29
|
+
* Describe each set bit of a bitmask as a human-readable sentence.
|
|
30
|
+
* Unknown bits render as 'unknown permission (bitN)'.
|
|
31
|
+
*/
|
|
32
|
+
export declare function describeMask(mask: number): string[];
|
|
33
|
+
/**
|
|
34
|
+
* EligibilityModule vouch-config flag bits (EligibilityModule.sol:156-157).
|
|
35
|
+
* Packed into the `flags` byte of the VouchConfig tuple returned by getVouchConfig.
|
|
36
|
+
*/
|
|
37
|
+
export declare const VOUCH_FLAG_ENABLED = 1;
|
|
38
|
+
export declare const VOUCH_FLAG_COMBINE_HIERARCHY = 2;
|
|
39
|
+
/**
|
|
40
|
+
* Would enabling vouching and default-eligibility on the same hat conflict?
|
|
41
|
+
*
|
|
42
|
+
* Audit M-03 made these mutually exclusive in BOTH directions: a hat that everyone is eligible
|
|
43
|
+
* for by default makes a vouch quorum a no-op, so the contract reverts
|
|
44
|
+
* DefaultEligibilityConflictsWithVouch. The guard only fires when vouching is enabled AND
|
|
45
|
+
* combineWithHierarchy is set — vouching alone, or without combine, is fine.
|
|
46
|
+
*/
|
|
47
|
+
export declare function vouchConflictsWithDefaultEligibility(vouchFlags: number, vouchQuorum: number, defaultEligible: boolean): boolean;
|
package/dist/perms.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TaskManager Permission Bitmask Utilities
|
|
4
|
+
* Parse, format, and describe TaskPerm bitmasks used by the
|
|
5
|
+
* TaskManager contract's per-member permission system.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.VOUCH_FLAG_COMBINE_HIERARCHY = exports.VOUCH_FLAG_ENABLED = exports.PERM_BITS = void 0;
|
|
9
|
+
exports.parsePermList = parsePermList;
|
|
10
|
+
exports.formatMask = formatMask;
|
|
11
|
+
exports.describeMask = describeMask;
|
|
12
|
+
exports.vouchConflictsWithDefaultEligibility = vouchConflictsWithDefaultEligibility;
|
|
13
|
+
const errors_1 = require("./errors");
|
|
14
|
+
exports.PERM_BITS = {
|
|
15
|
+
create: 1,
|
|
16
|
+
claim: 2,
|
|
17
|
+
review: 4,
|
|
18
|
+
assign: 8,
|
|
19
|
+
'self-review': 16,
|
|
20
|
+
budget: 32,
|
|
21
|
+
'edit-meta': 64,
|
|
22
|
+
'edit-full': 128,
|
|
23
|
+
};
|
|
24
|
+
const PERM_DESCRIPTIONS = {
|
|
25
|
+
create: 'create tasks',
|
|
26
|
+
claim: 'claim tasks',
|
|
27
|
+
review: 'review submissions',
|
|
28
|
+
assign: 'assign tasks to others',
|
|
29
|
+
'self-review': 'review own submissions',
|
|
30
|
+
budget: 'edit project budgets',
|
|
31
|
+
'edit-meta': 'edit task metadata post-claim',
|
|
32
|
+
'edit-full': 'edit all task fields post-claim',
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Parse a comma-separated list of permission names into a bitmask.
|
|
36
|
+
* Case-insensitive, whitespace-tolerant. Empty string or 'none' → 0.
|
|
37
|
+
* Throws CliError listing valid names on an unknown permission.
|
|
38
|
+
*/
|
|
39
|
+
function parsePermList(input) {
|
|
40
|
+
const trimmed = (input || '').trim();
|
|
41
|
+
if (trimmed === '' || trimmed.toLowerCase() === 'none')
|
|
42
|
+
return 0;
|
|
43
|
+
let mask = 0;
|
|
44
|
+
for (const part of trimmed.split(',')) {
|
|
45
|
+
const name = part.trim().toLowerCase();
|
|
46
|
+
if (name === '')
|
|
47
|
+
continue;
|
|
48
|
+
const bit = exports.PERM_BITS[name];
|
|
49
|
+
if (bit === undefined) {
|
|
50
|
+
throw new errors_1.CliError(`Unknown permission "${name}". Valid permissions: ${Object.keys(exports.PERM_BITS).join(', ')}`);
|
|
51
|
+
}
|
|
52
|
+
mask |= bit;
|
|
53
|
+
}
|
|
54
|
+
return mask;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Format a bitmask as a comma-separated list of permission names.
|
|
58
|
+
* 0 → 'none'. Unrecognized high bits render as 'bitN' (N = bit index).
|
|
59
|
+
*/
|
|
60
|
+
function formatMask(mask) {
|
|
61
|
+
if (mask === 0)
|
|
62
|
+
return 'none';
|
|
63
|
+
const names = [];
|
|
64
|
+
let known = 0;
|
|
65
|
+
for (const [name, bit] of Object.entries(exports.PERM_BITS)) {
|
|
66
|
+
if (mask & bit) {
|
|
67
|
+
names.push(name);
|
|
68
|
+
known |= bit;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
let remaining = mask & ~known;
|
|
72
|
+
for (let i = 0; remaining !== 0 && i < 32; i++) {
|
|
73
|
+
if (remaining & (1 << i)) {
|
|
74
|
+
names.push(`bit${i}`);
|
|
75
|
+
remaining &= ~(1 << i);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return names.join(',');
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Describe each set bit of a bitmask as a human-readable sentence.
|
|
82
|
+
* Unknown bits render as 'unknown permission (bitN)'.
|
|
83
|
+
*/
|
|
84
|
+
function describeMask(mask) {
|
|
85
|
+
const sentences = [];
|
|
86
|
+
let known = 0;
|
|
87
|
+
for (const [name, bit] of Object.entries(exports.PERM_BITS)) {
|
|
88
|
+
if (mask & bit) {
|
|
89
|
+
sentences.push(PERM_DESCRIPTIONS[name]);
|
|
90
|
+
known |= bit;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
let remaining = mask & ~known;
|
|
94
|
+
for (let i = 0; remaining !== 0 && i < 32; i++) {
|
|
95
|
+
if (remaining & (1 << i)) {
|
|
96
|
+
sentences.push(`unknown permission (bit${i})`);
|
|
97
|
+
remaining &= ~(1 << i);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return sentences;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* EligibilityModule vouch-config flag bits (EligibilityModule.sol:156-157).
|
|
104
|
+
* Packed into the `flags` byte of the VouchConfig tuple returned by getVouchConfig.
|
|
105
|
+
*/
|
|
106
|
+
exports.VOUCH_FLAG_ENABLED = 0x01;
|
|
107
|
+
exports.VOUCH_FLAG_COMBINE_HIERARCHY = 0x02;
|
|
108
|
+
/**
|
|
109
|
+
* Would enabling vouching and default-eligibility on the same hat conflict?
|
|
110
|
+
*
|
|
111
|
+
* Audit M-03 made these mutually exclusive in BOTH directions: a hat that everyone is eligible
|
|
112
|
+
* for by default makes a vouch quorum a no-op, so the contract reverts
|
|
113
|
+
* DefaultEligibilityConflictsWithVouch. The guard only fires when vouching is enabled AND
|
|
114
|
+
* combineWithHierarchy is set — vouching alone, or without combine, is fine.
|
|
115
|
+
*/
|
|
116
|
+
function vouchConflictsWithDefaultEligibility(vouchFlags, vouchQuorum, defaultEligible) {
|
|
117
|
+
const enabled = (vouchFlags & exports.VOUCH_FLAG_ENABLED) !== 0 && vouchQuorum > 0;
|
|
118
|
+
const combine = (vouchFlags & exports.VOUCH_FLAG_COMBINE_HIERARCHY) !== 0;
|
|
119
|
+
return enabled && combine && defaultEligible;
|
|
120
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-flight Checks
|
|
3
|
+
* Read-only validations that run before a write command sends its
|
|
4
|
+
* transaction, so predictable failures surface as one actionable message
|
|
5
|
+
* instead of an on-chain revert (or a silent wrong-state write). Contract
|
|
6
|
+
* reads batch through Multicall3 in a single RPC round-trip; local checks
|
|
7
|
+
* run concurrently. ALL failures are collected before throwing.
|
|
8
|
+
*/
|
|
9
|
+
import { ethers } from 'ethers';
|
|
10
|
+
import type { SponsoredConfig } from './sponsorship-config';
|
|
11
|
+
export interface CheckResult {
|
|
12
|
+
ok: boolean;
|
|
13
|
+
detail?: string;
|
|
14
|
+
suggestion?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface PreflightCheck {
|
|
17
|
+
/** Short human label, e.g. 'gas balance' or 'task 12 status'. */
|
|
18
|
+
label: string;
|
|
19
|
+
/** Read-only eth_call, batched through Multicall3 with the other checks. */
|
|
20
|
+
call?: {
|
|
21
|
+
to: string;
|
|
22
|
+
data: string;
|
|
23
|
+
};
|
|
24
|
+
/** Local/off-chain check; runs concurrently with the batched calls. */
|
|
25
|
+
local?: () => Promise<CheckResult> | CheckResult;
|
|
26
|
+
/** Interpret the batched call's result. Used only when `call` is set. */
|
|
27
|
+
interpret?: (returnData: string, success: boolean) => CheckResult;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Run all checks (batched calls + concurrent locals), collect every failure,
|
|
31
|
+
* and throw a single PreconditionError listing them. `opts.skip` (from a
|
|
32
|
+
* --skip-checks flag) bypasses everything.
|
|
33
|
+
*/
|
|
34
|
+
export declare function runPreflight(provider: ethers.providers.Provider, checks: PreflightCheck[], opts?: {
|
|
35
|
+
skip?: boolean;
|
|
36
|
+
}): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Wallet holds at least `minWei` (default 0.0001 ether) of the chain's
|
|
39
|
+
* native gas token, read via Multicall3.getEthBalance. Pass the resolved
|
|
40
|
+
* sponsorship config as `sponsored` to skip the check for sponsored wallets
|
|
41
|
+
* (the CLI resolves it from env via resolveSponsoredConfig).
|
|
42
|
+
*/
|
|
43
|
+
export declare function checkGasBalance(address: string, minWei?: ethers.BigNumber, sponsored?: SponsoredConfig): PreflightCheck;
|
|
44
|
+
/** Wearer holds the given hat (IHats balanceOf(wearer, hatId) > 0). */
|
|
45
|
+
export declare function checkHasHat(hatsAddress: string, wearer: string, hatId: ethers.BigNumberish): PreflightCheck;
|
|
46
|
+
/** Username is unregistered (UAR getAddressOfUsername returns the zero address). */
|
|
47
|
+
export declare function checkUsernameFree(registryAddr: string, username: string): PreflightCheck;
|
|
48
|
+
/**
|
|
49
|
+
* Task is in one of `allowedStatuses` (authoritative on-chain read via
|
|
50
|
+
* TaskManager.getLensData). Options:
|
|
51
|
+
* - claimerMustBe: task.claimer must equal this address (case-insensitive)
|
|
52
|
+
* - allowExpiredTakeover: a CLAIMED task outside allowedStatuses still passes
|
|
53
|
+
* when its claim deadline has lapsed (deriveClaimState === 'expired-claimable')
|
|
54
|
+
* - now: injectable unix timestamp for deadline math (tests)
|
|
55
|
+
*/
|
|
56
|
+
export declare function checkTaskStatus(taskManagerAddr: string, taskId: ethers.BigNumberish, allowedStatuses: number[], opts?: {
|
|
57
|
+
claimerMustBe?: string;
|
|
58
|
+
allowExpiredTakeover?: boolean;
|
|
59
|
+
now?: number;
|
|
60
|
+
}): PreflightCheck;
|
|
61
|
+
/**
|
|
62
|
+
* Proposal ID exists on the voting contract (proposalsCount() > id).
|
|
63
|
+
*
|
|
64
|
+
* Kept on RPC on purpose. Counting Proposal/DDVProposal rows in the subgraph
|
|
65
|
+
* would be semantically equivalent, but it saves nothing and costs something:
|
|
66
|
+
* this check's `call` rides inside the SAME Multicall3 batch as the gas-balance
|
|
67
|
+
* check that every write already performs, so dropping it removes zero RPC
|
|
68
|
+
* round-trips while adding a subgraph round-trip. Worse, the propose→cast
|
|
69
|
+
* sequence agents run means the proposal is frequently seconds old, and an
|
|
70
|
+
* un-indexed row would block a perfectly legitimate vote. Net: strictly worse.
|
|
71
|
+
*/
|
|
72
|
+
export declare function checkProposalActive(votingAddr: string, proposalId: number): PreflightCheck;
|