@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,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Participation-token reads — typed wrappers over graph/documents/token.
|
|
4
|
+
*
|
|
5
|
+
* Serves the read paths of `pop token balance` (src/commands/token/balance.ts)
|
|
6
|
+
* and `pop token requests` (src/commands/token/requests.ts), plus the
|
|
7
|
+
* subgraph half of the token-address resolution in
|
|
8
|
+
* src/commands/token/helpers.ts.
|
|
9
|
+
*
|
|
10
|
+
* NOT ported here (deliberately — see the header of
|
|
11
|
+
* src/commands/token/helpers.ts): readTokenGates / checkWearsAnyHat /
|
|
12
|
+
* readTokenRequest. Those are provider-bound revert predictors that MUST stay
|
|
13
|
+
* on RPC: ParticipationTokenContract.executor/.hatsContract are the zero
|
|
14
|
+
* address on all live subgraph rows, memberHatIds/approverHatIds are not
|
|
15
|
+
* indexed at all, and requests(id) is the existence/state gate evaluated
|
|
16
|
+
* immediately before a write — subgraph lag there means knowingly
|
|
17
|
+
* broadcasting a doomed transaction.
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.resolveParticipationToken = resolveParticipationToken;
|
|
21
|
+
exports.getTokenBalance = getTokenBalance;
|
|
22
|
+
exports.listTokenRequests = listTokenRequests;
|
|
23
|
+
exports.listUserTokenRequests = listUserTokenRequests;
|
|
24
|
+
const token_1 = require("../graph/documents/token");
|
|
25
|
+
const resolve_1 = require("./resolve");
|
|
26
|
+
/**
|
|
27
|
+
* Resolve an org (name or hex ID) to its ParticipationToken address.
|
|
28
|
+
* Port of resolveTokenAddress in src/commands/token/helpers.ts — the
|
|
29
|
+
* subgraph-only half of that file (the hat-gate readers stay in the CLI).
|
|
30
|
+
*/
|
|
31
|
+
async function resolveParticipationToken(client, orgIdOrName, chainId) {
|
|
32
|
+
const modules = await (0, resolve_1.resolveOrgModules)(client, orgIdOrName, chainId);
|
|
33
|
+
return {
|
|
34
|
+
orgId: modules.orgId,
|
|
35
|
+
tokenAddress: (0, resolve_1.requireModule)(modules, 'participationTokenAddress'),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Subgraph read behind `pop token balance` — src/commands/token/balance.ts.
|
|
40
|
+
* TokenBalance mirrors ERC20 balanceOf exactly (verified live: the sum of a
|
|
41
|
+
* token's TokenBalance rows equals its indexed totalSupply).
|
|
42
|
+
*/
|
|
43
|
+
async function getTokenBalance(client, tokenAddress, holder, chainId) {
|
|
44
|
+
const data = await client.query(token_1.FETCH_TOKEN_BALANCE, { token: tokenAddress.toLowerCase(), balanceId: (0, token_1.tokenBalanceId)(tokenAddress, holder) }, chainId);
|
|
45
|
+
const symbol = data?.participationTokenContract?.symbol
|
|
46
|
+
? String(data.participationTokenContract.symbol)
|
|
47
|
+
: null;
|
|
48
|
+
const balanceWei = data?.tokenBalance?.balance !== null && data?.tokenBalance?.balance !== undefined
|
|
49
|
+
? String(data.tokenBalance.balance)
|
|
50
|
+
: null;
|
|
51
|
+
const updatedAt = data?.tokenBalance?.updatedAt !== undefined && data?.tokenBalance?.updatedAt !== null
|
|
52
|
+
? String(data.tokenBalance.updatedAt)
|
|
53
|
+
: null;
|
|
54
|
+
return { tokenAddress, symbol, balanceWei, updatedAt };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* List token requests for a ParticipationToken.
|
|
58
|
+
* Subgraph read behind `pop token requests` — src/commands/token/requests.ts
|
|
59
|
+
* (`status: 'pending'` ⇒ FETCH_PENDING_TOKEN_REQUESTS, `'all'` ⇒
|
|
60
|
+
* FETCH_ALL_TOKEN_REQUESTS; pending is the CLI default).
|
|
61
|
+
*/
|
|
62
|
+
async function listTokenRequests(client, tokenAddress, opts) {
|
|
63
|
+
const gqlQuery = opts?.status === 'all' ? token_1.FETCH_ALL_TOKEN_REQUESTS : token_1.FETCH_PENDING_TOKEN_REQUESTS;
|
|
64
|
+
const result = await client.query(gqlQuery, { tokenAddress }, opts?.chainId);
|
|
65
|
+
return result.tokenRequests || [];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* One requester's token-request history (newest first, max 50) —
|
|
69
|
+
* FETCH_USER_TOKEN_REQUESTS from graph/documents/token. Rows omit
|
|
70
|
+
* `requester` (it is the filter variable).
|
|
71
|
+
*/
|
|
72
|
+
async function listUserTokenRequests(client, tokenAddress, userAddress, chainId) {
|
|
73
|
+
const result = await client.query(token_1.FETCH_USER_TOKEN_REQUESTS, { tokenAddress, userAddress: userAddress.toLowerCase() }, chainId);
|
|
74
|
+
return result.tokenRequests || [];
|
|
75
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Treasury reads — typed wrappers over graph/documents/treasury.
|
|
3
|
+
*
|
|
4
|
+
* Serves the read paths of `pop treasury view` (src/commands/treasury/view.ts),
|
|
5
|
+
* `pop treasury distributions` (src/commands/treasury/distributions.ts), the
|
|
6
|
+
* distribution lookups of `pop treasury claim` / `claim-mine`, and the member
|
|
7
|
+
* snapshots that `compute-merkle` / `claim-mine` build merkle trees from.
|
|
8
|
+
*
|
|
9
|
+
* Read-sourcing policy (inherited from the CLI, comments load-bearing):
|
|
10
|
+
* - display reads (view / distributions) are pure subgraph
|
|
11
|
+
* - `distribution(id:)` answers null — NOT an error — for an id it has not
|
|
12
|
+
* indexed, and a brand-new distribution is exactly the case where someone
|
|
13
|
+
* claims early. Callers MUST treat null as "not indexed yet" and fall back
|
|
14
|
+
* to PaymentManager.getDistribution, never render it as DistributionNotFound.
|
|
15
|
+
* - the write-gating twins (hasClaimed / isOptedOut / getDistribution as a
|
|
16
|
+
* revert predictor) stay on RPC in the host. isOptedOut in particular has
|
|
17
|
+
* no trustworthy indexed twin: the OptOutToggle table has ZERO rows on all
|
|
18
|
+
* nine live Gnosis PaymentManagers (verified 2026-07) because zero
|
|
19
|
+
* OptOutToggled events have ever been emitted, so the mapping is
|
|
20
|
+
* unexercised and no live row proves it indexes correctly.
|
|
21
|
+
*/
|
|
22
|
+
import { ethers } from 'ethers';
|
|
23
|
+
import type { GraphClient } from '../graph/client';
|
|
24
|
+
import { distributionEntityId } from '../graph/documents/treasury';
|
|
25
|
+
export { distributionEntityId };
|
|
26
|
+
export interface DistributionClaimRow {
|
|
27
|
+
id: string;
|
|
28
|
+
claimer: string;
|
|
29
|
+
claimerUsername: string | null;
|
|
30
|
+
amount: string;
|
|
31
|
+
claimedAt: string;
|
|
32
|
+
transactionHash: string;
|
|
33
|
+
}
|
|
34
|
+
export interface DistributionRow {
|
|
35
|
+
id: string;
|
|
36
|
+
distributionId: string;
|
|
37
|
+
payoutToken: string;
|
|
38
|
+
totalAmount: string;
|
|
39
|
+
totalClaimed: string;
|
|
40
|
+
checkpointBlock: string;
|
|
41
|
+
createdAtBlock: string | null;
|
|
42
|
+
merkleRoot: string;
|
|
43
|
+
/** Enum is exactly Active | Finalized. */
|
|
44
|
+
status: 'Active' | 'Finalized' | string;
|
|
45
|
+
createdAt: string | null;
|
|
46
|
+
finalizedAt: string | null;
|
|
47
|
+
unclaimedAmount: string | null;
|
|
48
|
+
claims: DistributionClaimRow[];
|
|
49
|
+
}
|
|
50
|
+
export interface PaymentRow {
|
|
51
|
+
id: string;
|
|
52
|
+
payer: string;
|
|
53
|
+
payerUsername: string | null;
|
|
54
|
+
amount: string;
|
|
55
|
+
token: string;
|
|
56
|
+
receivedAt: string;
|
|
57
|
+
transactionHash: string;
|
|
58
|
+
}
|
|
59
|
+
export interface TreasuryData {
|
|
60
|
+
id: string;
|
|
61
|
+
executorContract: {
|
|
62
|
+
id: string;
|
|
63
|
+
isPaused: boolean;
|
|
64
|
+
owner: string | null;
|
|
65
|
+
allowedCaller: string | null;
|
|
66
|
+
sweeps: Array<{
|
|
67
|
+
id: string;
|
|
68
|
+
to: string;
|
|
69
|
+
amount: string;
|
|
70
|
+
sweptAt: string;
|
|
71
|
+
transactionHash: string;
|
|
72
|
+
}>;
|
|
73
|
+
} | null;
|
|
74
|
+
participationToken: {
|
|
75
|
+
id: string;
|
|
76
|
+
name: string;
|
|
77
|
+
symbol: string;
|
|
78
|
+
totalSupply: string;
|
|
79
|
+
} | null;
|
|
80
|
+
paymentManager: {
|
|
81
|
+
id: string;
|
|
82
|
+
owner: string | null;
|
|
83
|
+
revenueShareToken: string | null;
|
|
84
|
+
distributionCounter: string;
|
|
85
|
+
distributions: DistributionRow[];
|
|
86
|
+
payments: PaymentRow[];
|
|
87
|
+
} | null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Full treasury overview — subgraph read behind `pop treasury view`
|
|
91
|
+
* (src/commands/treasury/view.ts) and `pop treasury distributions`
|
|
92
|
+
* (src/commands/treasury/distributions.ts). Returns the raw organization
|
|
93
|
+
* entity; null when the org is unknown on this chain.
|
|
94
|
+
*/
|
|
95
|
+
export declare function fetchTreasuryData(client: GraphClient, orgIdOrName: string | undefined, chainId?: number): Promise<TreasuryData | null>;
|
|
96
|
+
/**
|
|
97
|
+
* Distribution list, optionally filtered by status — the selection behind
|
|
98
|
+
* `pop treasury distributions --status ...`.
|
|
99
|
+
*/
|
|
100
|
+
export declare function listDistributions(client: GraphClient, orgIdOrName: string | undefined, chainId?: number, status?: 'Active' | 'Finalized'): Promise<DistributionRow[]>;
|
|
101
|
+
export interface IndexedDistribution {
|
|
102
|
+
id: string;
|
|
103
|
+
distributionId: string;
|
|
104
|
+
/** Re-checksummed at the boundary (the subgraph stores addresses lowercased,
|
|
105
|
+
* while the ABI-decoded getDistribution() path yields EIP-55 — without this
|
|
106
|
+
* the value silently changes case depending on whether the distribution
|
|
107
|
+
* happens to be indexed). */
|
|
108
|
+
payoutToken: string;
|
|
109
|
+
totalAmount: string;
|
|
110
|
+
totalClaimed: string;
|
|
111
|
+
checkpointBlock: string;
|
|
112
|
+
/** The contract has NO getter for this — subgraph-only field. */
|
|
113
|
+
createdAtBlock: string | null;
|
|
114
|
+
merkleRoot: string;
|
|
115
|
+
status: 'Active' | 'Finalized' | string;
|
|
116
|
+
/** Derived exactly like `pop treasury claim` does: status === 'Finalized'.
|
|
117
|
+
* The enum only becomes Finalized once DistributionFinalized is indexed, so
|
|
118
|
+
* a false positive is impossible; a stale Active is caught at gas estimation. */
|
|
119
|
+
finalized: boolean;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* One distribution by (paymentManager, distributionId) — the indexed twin of
|
|
123
|
+
* PaymentManager.getDistribution(), read behind `pop treasury claim`
|
|
124
|
+
* (src/commands/treasury/claim.ts).
|
|
125
|
+
*
|
|
126
|
+
* Returns null when the subgraph has not indexed the id — callers MUST fall
|
|
127
|
+
* back to getDistribution() on-chain, never treat null as DistributionNotFound.
|
|
128
|
+
*/
|
|
129
|
+
export declare function fetchDistributionById(client: GraphClient, paymentManagerAddress: string, distributionId: number | string, chainId?: number): Promise<IndexedDistribution | null>;
|
|
130
|
+
export interface ActiveDistributionRow {
|
|
131
|
+
distributionId: string;
|
|
132
|
+
totalAmount: string;
|
|
133
|
+
merkleRoot: string;
|
|
134
|
+
checkpointBlock: string;
|
|
135
|
+
payoutToken: string;
|
|
136
|
+
claims: Array<{
|
|
137
|
+
claimer: string;
|
|
138
|
+
}>;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Every still-claimable distribution with its claim log — the read behind
|
|
142
|
+
* `pop treasury claim-mine` (src/commands/treasury/claim-mine.ts).
|
|
143
|
+
*/
|
|
144
|
+
export declare function fetchActiveDistributions(client: GraphClient, orgIdOrName: string | undefined, chainId?: number): Promise<ActiveDistributionRow[]>;
|
|
145
|
+
/**
|
|
146
|
+
* Members + PT balances at the CURRENT head — the builder snapshot used by
|
|
147
|
+
* `pop treasury compute-merkle` (src/commands/treasury/compute-merkle.ts).
|
|
148
|
+
* Ordered by PT balance desc: the dust-to-largest-holder rule depends on
|
|
149
|
+
* allocations[0] being the largest holder.
|
|
150
|
+
*/
|
|
151
|
+
export declare const FETCH_MEMBERS_PT = "\n query FetchMembersPT($orgId: Bytes!) {\n organization(id: $orgId) {\n users(\n orderBy: participationTokenBalance,\n orderDirection: desc,\n first: 1000\n ) {\n address\n participationTokenBalance\n membershipStatus\n account {\n username\n }\n }\n participationToken {\n totalSupply\n }\n }\n }\n";
|
|
152
|
+
/**
|
|
153
|
+
* Members AND opt-out state as of a distribution's checkpoint block — the
|
|
154
|
+
* reconstruction snapshot used by `pop treasury claim-mine`
|
|
155
|
+
* (src/commands/treasury/claim-mine.ts).
|
|
156
|
+
*
|
|
157
|
+
* Both halves are block-scoped on purpose. `pop treasury compute-merkle`
|
|
158
|
+
* excludes opted-out members when it BUILDS the tree (the only place opt-out
|
|
159
|
+
* is enforced since audit L-19), so reconstructing that tree has to reproduce
|
|
160
|
+
* the opt-out set as it was AT BUILD TIME. Using current opt-out state instead
|
|
161
|
+
* would rebuild a different tree the moment anyone toggles after a
|
|
162
|
+
* distribution is created, and every member would get "Root mismatch" for a
|
|
163
|
+
* valid distribution. compute-merkle sets checkpointBlock to the build block,
|
|
164
|
+
* so this is that state.
|
|
165
|
+
*
|
|
166
|
+
* optOutToggles is a TOP-LEVEL entity, so it MUST be scoped to this org's
|
|
167
|
+
* PaymentManager. Unfiltered it returns toggles from every PaymentManager the
|
|
168
|
+
* subgraph indexes (nine on Gnosis today), and any address that opted out of a
|
|
169
|
+
* DIFFERENT org would be dropped from this org's tree — producing a spurious
|
|
170
|
+
* "Root mismatch" that tells every member they cannot claim.
|
|
171
|
+
*/
|
|
172
|
+
export declare const FETCH_MEMBERS_AT_BLOCK = "\n query FetchMembersAtBlock($orgId: Bytes!, $block: Int!, $paymentManager: String!) {\n organization(id: $orgId, block: { number: $block }) {\n participationToken { totalSupply }\n users(orderBy: participationTokenBalance, orderDirection: desc, first: 1000) {\n address\n participationTokenBalance\n membershipStatus\n }\n }\n optOutToggles(\n block: { number: $block }\n where: { paymentManager: $paymentManager }\n first: 1000\n orderBy: toggledAtBlock\n orderDirection: asc\n ) {\n user\n optedOut\n toggledAtBlock\n }\n }\n";
|
|
173
|
+
export interface MemberPtRow {
|
|
174
|
+
address: string;
|
|
175
|
+
participationTokenBalance: string;
|
|
176
|
+
membershipStatus: string;
|
|
177
|
+
account?: {
|
|
178
|
+
username: string | null;
|
|
179
|
+
} | null;
|
|
180
|
+
}
|
|
181
|
+
export interface OptOutToggleRow {
|
|
182
|
+
user: string;
|
|
183
|
+
optedOut: boolean;
|
|
184
|
+
toggledAtBlock: string;
|
|
185
|
+
}
|
|
186
|
+
/** Current-head member snapshot (compute-merkle builder input). */
|
|
187
|
+
export declare function fetchMembersPT(client: GraphClient, orgId: string, chainId?: number): Promise<{
|
|
188
|
+
users: MemberPtRow[];
|
|
189
|
+
totalSupply: string;
|
|
190
|
+
} | null>;
|
|
191
|
+
/** Block-pinned member + opt-out snapshot (claim-mine reconstruction input). */
|
|
192
|
+
export declare function fetchMembersAtBlock(client: GraphClient, orgId: string, block: number, paymentManagerAddress: string, chainId?: number): Promise<{
|
|
193
|
+
users: MemberPtRow[];
|
|
194
|
+
totalSupply: string;
|
|
195
|
+
optOutToggles: OptOutToggleRow[];
|
|
196
|
+
} | null>;
|
|
197
|
+
/**
|
|
198
|
+
* Latest toggle per user wins — the log is ascending, so the last write for an
|
|
199
|
+
* address is its state at the pinned block. Pure port of the fold in
|
|
200
|
+
* `pop treasury claim-mine`.
|
|
201
|
+
*/
|
|
202
|
+
export declare function optedOutSetFromToggles(toggles: OptOutToggleRow[]): Set<string>;
|
|
203
|
+
export interface PayoutTokenInfo {
|
|
204
|
+
address: string;
|
|
205
|
+
symbol: string;
|
|
206
|
+
decimals: number;
|
|
207
|
+
isNative: boolean;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Resolve a distribution payout token to human units — port of
|
|
211
|
+
* resolvePayoutTokenInfo in src/commands/treasury/helpers.ts (shared by claim,
|
|
212
|
+
* claim-mine, propose-distribution and propose-finalize so amounts render
|
|
213
|
+
* identically).
|
|
214
|
+
*
|
|
215
|
+
* PaymentManager uses address(0) for the chain's native token (verified:
|
|
216
|
+
* claimDistribution transfers raw value when payoutToken == address(0));
|
|
217
|
+
* ERC20s are resolved via a live decimals()/symbol() read with the known-token
|
|
218
|
+
* table then an 18-decimals default as fallbacks. RPC on purpose: the subgraph
|
|
219
|
+
* does not index arbitrary ERC20s. When no provider is supplied the live read
|
|
220
|
+
* is skipped and the table/default fallback applies directly.
|
|
221
|
+
*/
|
|
222
|
+
export declare function resolvePayoutTokenInfo(provider: ethers.providers.Provider | undefined, tokenAddress: string, chainId?: number): Promise<PayoutTokenInfo>;
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Treasury reads — typed wrappers over graph/documents/treasury.
|
|
4
|
+
*
|
|
5
|
+
* Serves the read paths of `pop treasury view` (src/commands/treasury/view.ts),
|
|
6
|
+
* `pop treasury distributions` (src/commands/treasury/distributions.ts), the
|
|
7
|
+
* distribution lookups of `pop treasury claim` / `claim-mine`, and the member
|
|
8
|
+
* snapshots that `compute-merkle` / `claim-mine` build merkle trees from.
|
|
9
|
+
*
|
|
10
|
+
* Read-sourcing policy (inherited from the CLI, comments load-bearing):
|
|
11
|
+
* - display reads (view / distributions) are pure subgraph
|
|
12
|
+
* - `distribution(id:)` answers null — NOT an error — for an id it has not
|
|
13
|
+
* indexed, and a brand-new distribution is exactly the case where someone
|
|
14
|
+
* claims early. Callers MUST treat null as "not indexed yet" and fall back
|
|
15
|
+
* to PaymentManager.getDistribution, never render it as DistributionNotFound.
|
|
16
|
+
* - the write-gating twins (hasClaimed / isOptedOut / getDistribution as a
|
|
17
|
+
* revert predictor) stay on RPC in the host. isOptedOut in particular has
|
|
18
|
+
* no trustworthy indexed twin: the OptOutToggle table has ZERO rows on all
|
|
19
|
+
* nine live Gnosis PaymentManagers (verified 2026-07) because zero
|
|
20
|
+
* OptOutToggled events have ever been emitted, so the mapping is
|
|
21
|
+
* unexercised and no live row proves it indexes correctly.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.FETCH_MEMBERS_AT_BLOCK = exports.FETCH_MEMBERS_PT = exports.distributionEntityId = void 0;
|
|
25
|
+
exports.fetchTreasuryData = fetchTreasuryData;
|
|
26
|
+
exports.listDistributions = listDistributions;
|
|
27
|
+
exports.fetchDistributionById = fetchDistributionById;
|
|
28
|
+
exports.fetchActiveDistributions = fetchActiveDistributions;
|
|
29
|
+
exports.fetchMembersPT = fetchMembersPT;
|
|
30
|
+
exports.fetchMembersAtBlock = fetchMembersAtBlock;
|
|
31
|
+
exports.optedOutSetFromToggles = optedOutSetFromToggles;
|
|
32
|
+
exports.resolvePayoutTokenInfo = resolvePayoutTokenInfo;
|
|
33
|
+
const ethers_1 = require("ethers");
|
|
34
|
+
const treasury_1 = require("../graph/documents/treasury");
|
|
35
|
+
Object.defineProperty(exports, "distributionEntityId", { enumerable: true, get: function () { return treasury_1.distributionEntityId; } });
|
|
36
|
+
const resolve_1 = require("./resolve");
|
|
37
|
+
const contracts_1 = require("../contracts");
|
|
38
|
+
const chains_1 = require("../chains");
|
|
39
|
+
/**
|
|
40
|
+
* Full treasury overview — subgraph read behind `pop treasury view`
|
|
41
|
+
* (src/commands/treasury/view.ts) and `pop treasury distributions`
|
|
42
|
+
* (src/commands/treasury/distributions.ts). Returns the raw organization
|
|
43
|
+
* entity; null when the org is unknown on this chain.
|
|
44
|
+
*/
|
|
45
|
+
async function fetchTreasuryData(client, orgIdOrName, chainId) {
|
|
46
|
+
const orgId = await (0, resolve_1.resolveOrgId)(client, orgIdOrName, chainId);
|
|
47
|
+
const result = await client.query(treasury_1.FETCH_TREASURY_DATA, { orgId }, chainId);
|
|
48
|
+
return result.organization ?? null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Distribution list, optionally filtered by status — the selection behind
|
|
52
|
+
* `pop treasury distributions --status ...`.
|
|
53
|
+
*/
|
|
54
|
+
async function listDistributions(client, orgIdOrName, chainId, status) {
|
|
55
|
+
const org = await fetchTreasuryData(client, orgIdOrName, chainId);
|
|
56
|
+
let distributions = org?.paymentManager?.distributions ?? [];
|
|
57
|
+
if (status)
|
|
58
|
+
distributions = distributions.filter((d) => d.status === status);
|
|
59
|
+
return distributions;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* One distribution by (paymentManager, distributionId) — the indexed twin of
|
|
63
|
+
* PaymentManager.getDistribution(), read behind `pop treasury claim`
|
|
64
|
+
* (src/commands/treasury/claim.ts).
|
|
65
|
+
*
|
|
66
|
+
* Returns null when the subgraph has not indexed the id — callers MUST fall
|
|
67
|
+
* back to getDistribution() on-chain, never treat null as DistributionNotFound.
|
|
68
|
+
*/
|
|
69
|
+
async function fetchDistributionById(client, paymentManagerAddress, distributionId, chainId) {
|
|
70
|
+
const result = await client
|
|
71
|
+
.query(treasury_1.FETCH_DISTRIBUTION_BY_ID, { id: (0, treasury_1.distributionEntityId)(paymentManagerAddress, distributionId) }, chainId)
|
|
72
|
+
.catch(() => ({ distribution: null }));
|
|
73
|
+
const indexed = result.distribution;
|
|
74
|
+
if (!indexed)
|
|
75
|
+
return null;
|
|
76
|
+
return {
|
|
77
|
+
...indexed,
|
|
78
|
+
payoutToken: ethers_1.ethers.utils.getAddress(indexed.payoutToken),
|
|
79
|
+
finalized: indexed.status === 'Finalized',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Every still-claimable distribution with its claim log — the read behind
|
|
84
|
+
* `pop treasury claim-mine` (src/commands/treasury/claim-mine.ts).
|
|
85
|
+
*/
|
|
86
|
+
async function fetchActiveDistributions(client, orgIdOrName, chainId) {
|
|
87
|
+
const orgId = await (0, resolve_1.resolveOrgId)(client, orgIdOrName, chainId);
|
|
88
|
+
const result = await client.query(treasury_1.FETCH_ACTIVE_DISTRIBUTIONS, { orgId }, chainId);
|
|
89
|
+
return result.organization?.paymentManager?.distributions ?? [];
|
|
90
|
+
}
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Member snapshots for merkle building / reconstruction
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
/**
|
|
95
|
+
* Members + PT balances at the CURRENT head — the builder snapshot used by
|
|
96
|
+
* `pop treasury compute-merkle` (src/commands/treasury/compute-merkle.ts).
|
|
97
|
+
* Ordered by PT balance desc: the dust-to-largest-holder rule depends on
|
|
98
|
+
* allocations[0] being the largest holder.
|
|
99
|
+
*/
|
|
100
|
+
exports.FETCH_MEMBERS_PT = `
|
|
101
|
+
query FetchMembersPT($orgId: Bytes!) {
|
|
102
|
+
organization(id: $orgId) {
|
|
103
|
+
users(
|
|
104
|
+
orderBy: participationTokenBalance,
|
|
105
|
+
orderDirection: desc,
|
|
106
|
+
first: 1000
|
|
107
|
+
) {
|
|
108
|
+
address
|
|
109
|
+
participationTokenBalance
|
|
110
|
+
membershipStatus
|
|
111
|
+
account {
|
|
112
|
+
username
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
participationToken {
|
|
116
|
+
totalSupply
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
`;
|
|
121
|
+
/**
|
|
122
|
+
* Members AND opt-out state as of a distribution's checkpoint block — the
|
|
123
|
+
* reconstruction snapshot used by `pop treasury claim-mine`
|
|
124
|
+
* (src/commands/treasury/claim-mine.ts).
|
|
125
|
+
*
|
|
126
|
+
* Both halves are block-scoped on purpose. `pop treasury compute-merkle`
|
|
127
|
+
* excludes opted-out members when it BUILDS the tree (the only place opt-out
|
|
128
|
+
* is enforced since audit L-19), so reconstructing that tree has to reproduce
|
|
129
|
+
* the opt-out set as it was AT BUILD TIME. Using current opt-out state instead
|
|
130
|
+
* would rebuild a different tree the moment anyone toggles after a
|
|
131
|
+
* distribution is created, and every member would get "Root mismatch" for a
|
|
132
|
+
* valid distribution. compute-merkle sets checkpointBlock to the build block,
|
|
133
|
+
* so this is that state.
|
|
134
|
+
*
|
|
135
|
+
* optOutToggles is a TOP-LEVEL entity, so it MUST be scoped to this org's
|
|
136
|
+
* PaymentManager. Unfiltered it returns toggles from every PaymentManager the
|
|
137
|
+
* subgraph indexes (nine on Gnosis today), and any address that opted out of a
|
|
138
|
+
* DIFFERENT org would be dropped from this org's tree — producing a spurious
|
|
139
|
+
* "Root mismatch" that tells every member they cannot claim.
|
|
140
|
+
*/
|
|
141
|
+
exports.FETCH_MEMBERS_AT_BLOCK = `
|
|
142
|
+
query FetchMembersAtBlock($orgId: Bytes!, $block: Int!, $paymentManager: String!) {
|
|
143
|
+
organization(id: $orgId, block: { number: $block }) {
|
|
144
|
+
participationToken { totalSupply }
|
|
145
|
+
users(orderBy: participationTokenBalance, orderDirection: desc, first: 1000) {
|
|
146
|
+
address
|
|
147
|
+
participationTokenBalance
|
|
148
|
+
membershipStatus
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
optOutToggles(
|
|
152
|
+
block: { number: $block }
|
|
153
|
+
where: { paymentManager: $paymentManager }
|
|
154
|
+
first: 1000
|
|
155
|
+
orderBy: toggledAtBlock
|
|
156
|
+
orderDirection: asc
|
|
157
|
+
) {
|
|
158
|
+
user
|
|
159
|
+
optedOut
|
|
160
|
+
toggledAtBlock
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
`;
|
|
164
|
+
/** Current-head member snapshot (compute-merkle builder input). */
|
|
165
|
+
async function fetchMembersPT(client, orgId, chainId) {
|
|
166
|
+
const result = await client.query(exports.FETCH_MEMBERS_PT, { orgId }, chainId);
|
|
167
|
+
const org = result.organization;
|
|
168
|
+
if (!org)
|
|
169
|
+
return null;
|
|
170
|
+
return { users: org.users ?? [], totalSupply: org.participationToken?.totalSupply ?? '0' };
|
|
171
|
+
}
|
|
172
|
+
/** Block-pinned member + opt-out snapshot (claim-mine reconstruction input). */
|
|
173
|
+
async function fetchMembersAtBlock(client, orgId, block, paymentManagerAddress, chainId) {
|
|
174
|
+
const result = await client.query(exports.FETCH_MEMBERS_AT_BLOCK, { orgId, block, paymentManager: paymentManagerAddress.toLowerCase() }, chainId);
|
|
175
|
+
const org = result.organization;
|
|
176
|
+
if (!org)
|
|
177
|
+
return null;
|
|
178
|
+
return {
|
|
179
|
+
users: org.users ?? [],
|
|
180
|
+
totalSupply: org.participationToken?.totalSupply ?? '0',
|
|
181
|
+
optOutToggles: result.optOutToggles ?? [],
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Latest toggle per user wins — the log is ascending, so the last write for an
|
|
186
|
+
* address is its state at the pinned block. Pure port of the fold in
|
|
187
|
+
* `pop treasury claim-mine`.
|
|
188
|
+
*/
|
|
189
|
+
function optedOutSetFromToggles(toggles) {
|
|
190
|
+
const optedOut = new Set();
|
|
191
|
+
for (const t of toggles ?? []) {
|
|
192
|
+
const addr = String(t.user).toLowerCase();
|
|
193
|
+
if (t.optedOut)
|
|
194
|
+
optedOut.add(addr);
|
|
195
|
+
else
|
|
196
|
+
optedOut.delete(addr);
|
|
197
|
+
}
|
|
198
|
+
return optedOut;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Resolve a distribution payout token to human units — port of
|
|
202
|
+
* resolvePayoutTokenInfo in src/commands/treasury/helpers.ts (shared by claim,
|
|
203
|
+
* claim-mine, propose-distribution and propose-finalize so amounts render
|
|
204
|
+
* identically).
|
|
205
|
+
*
|
|
206
|
+
* PaymentManager uses address(0) for the chain's native token (verified:
|
|
207
|
+
* claimDistribution transfers raw value when payoutToken == address(0));
|
|
208
|
+
* ERC20s are resolved via a live decimals()/symbol() read with the known-token
|
|
209
|
+
* table then an 18-decimals default as fallbacks. RPC on purpose: the subgraph
|
|
210
|
+
* does not index arbitrary ERC20s. When no provider is supplied the live read
|
|
211
|
+
* is skipped and the table/default fallback applies directly.
|
|
212
|
+
*/
|
|
213
|
+
async function resolvePayoutTokenInfo(provider, tokenAddress, chainId) {
|
|
214
|
+
if (!tokenAddress || tokenAddress === ethers_1.ethers.constants.AddressZero) {
|
|
215
|
+
const native = (0, chains_1.getNetworkByChainId)(chainId ?? 0)?.nativeCurrency?.symbol ?? 'native';
|
|
216
|
+
return { address: ethers_1.ethers.constants.AddressZero, symbol: native, decimals: 18, isNative: true };
|
|
217
|
+
}
|
|
218
|
+
const known = (0, chains_1.getTokenByAddress)(tokenAddress);
|
|
219
|
+
let decimals = known?.decimals;
|
|
220
|
+
let symbol = known?.symbol;
|
|
221
|
+
if (provider) {
|
|
222
|
+
try {
|
|
223
|
+
const erc20 = (0, contracts_1.createReadContract)(tokenAddress, 'ERC20', provider);
|
|
224
|
+
const [liveDecimals, liveSymbol] = await Promise.all([
|
|
225
|
+
erc20.decimals(),
|
|
226
|
+
erc20.symbol().catch(() => undefined),
|
|
227
|
+
]);
|
|
228
|
+
decimals = Number(liveDecimals);
|
|
229
|
+
symbol = liveSymbol ?? symbol;
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
// Live read failed — fall back to the known-token table / 18.
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
address: tokenAddress,
|
|
237
|
+
symbol: symbol ?? 'tokens',
|
|
238
|
+
decimals: decimals ?? 18,
|
|
239
|
+
isNative: false,
|
|
240
|
+
};
|
|
241
|
+
}
|