@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,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encoding Utilities
|
|
3
|
+
* Direct port of frontend encoding.js for byte-identical behavior.
|
|
4
|
+
* Uses ethers v5 + bs58 v6 to match frontend exactly.
|
|
5
|
+
*/
|
|
6
|
+
export declare function stringToBytes(str: string): Uint8Array;
|
|
7
|
+
export declare function bytesToString(bytes: Uint8Array): string;
|
|
8
|
+
export declare function stringToBytes32(str: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Encode IPFS CIDv0 (Qm...) to bytes32.
|
|
11
|
+
* CIDv0 = base58(0x1220 + 32-byte-sha256-hash)
|
|
12
|
+
* We store just the 32-byte hash portion.
|
|
13
|
+
*/
|
|
14
|
+
export declare function ipfsCidToBytes32(cid: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Decode bytes32 back to IPFS CIDv0.
|
|
17
|
+
*/
|
|
18
|
+
export declare function bytes32ToIpfsCid(bytes32Hash: string): string | null;
|
|
19
|
+
/**
|
|
20
|
+
* Parse a task ID from subgraph format.
|
|
21
|
+
* Subgraph returns IDs like "contractAddress-taskId", contract expects numeric taskId.
|
|
22
|
+
*/
|
|
23
|
+
export declare function parseTaskId(taskId: string | number): string;
|
|
24
|
+
export declare function parseModuleId(moduleId: string | number): string;
|
|
25
|
+
/**
|
|
26
|
+
* Parse a project ID from subgraph format.
|
|
27
|
+
* Subgraph: "{contractAddress}-{projectId}" where projectId is bytes32 hex.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseProjectId(projectId: string): string;
|
|
30
|
+
export declare function formatAddress(address: string, chars?: number): string;
|
|
31
|
+
export declare function isValidAddress(address: string): boolean;
|
|
32
|
+
export declare function toChecksumAddress(address: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Parse a deadline expression into unix seconds.
|
|
35
|
+
*
|
|
36
|
+
* Accepted forms:
|
|
37
|
+
* - ''or '0' → 0 (no deadline)
|
|
38
|
+
* - relative → '7d', '48h', '90m', '3600s' (added to `now`)
|
|
39
|
+
* - unix seconds → bare digits >= 10^9, e.g. '1790000000'
|
|
40
|
+
* - ISO date → '2026-08-01' (treated as UTC midnight)
|
|
41
|
+
* - ISO datetime → '2026-08-01T12:30:00' or '...Z' / '...+02:00'
|
|
42
|
+
* (no timezone suffix → treated as UTC)
|
|
43
|
+
*
|
|
44
|
+
* Throws CliError when the input is unparseable, exceeds the uint48
|
|
45
|
+
* range, or resolves to a timestamp at/before `now`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function parseDeadline(input: string, now?: number): number;
|
|
48
|
+
/**
|
|
49
|
+
* Parse a duration expression into seconds.
|
|
50
|
+
* Accepts bare seconds ('3600') or s/m/h/d suffixes ('48h', '7d').
|
|
51
|
+
* '0' → 0. Throws CliError when unparseable or above the uint32 max.
|
|
52
|
+
*/
|
|
53
|
+
export declare function parseDurationSeconds(input: string): number;
|
|
54
|
+
/**
|
|
55
|
+
* Format a unix-second deadline as 'YYYY-MM-DD HH:mm UTC'.
|
|
56
|
+
* 0 (no deadline) → 'none'.
|
|
57
|
+
*/
|
|
58
|
+
export declare function formatDeadline(unixSecs: number): string;
|
package/dist/encoding.js
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Encoding Utilities
|
|
4
|
+
* Direct port of frontend encoding.js for byte-identical behavior.
|
|
5
|
+
* Uses ethers v5 + bs58 v6 to match frontend exactly.
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.stringToBytes = stringToBytes;
|
|
12
|
+
exports.bytesToString = bytesToString;
|
|
13
|
+
exports.stringToBytes32 = stringToBytes32;
|
|
14
|
+
exports.ipfsCidToBytes32 = ipfsCidToBytes32;
|
|
15
|
+
exports.bytes32ToIpfsCid = bytes32ToIpfsCid;
|
|
16
|
+
exports.parseTaskId = parseTaskId;
|
|
17
|
+
exports.parseModuleId = parseModuleId;
|
|
18
|
+
exports.parseProjectId = parseProjectId;
|
|
19
|
+
exports.formatAddress = formatAddress;
|
|
20
|
+
exports.isValidAddress = isValidAddress;
|
|
21
|
+
exports.toChecksumAddress = toChecksumAddress;
|
|
22
|
+
exports.parseDeadline = parseDeadline;
|
|
23
|
+
exports.parseDurationSeconds = parseDurationSeconds;
|
|
24
|
+
exports.formatDeadline = formatDeadline;
|
|
25
|
+
const ethers_1 = require("ethers");
|
|
26
|
+
const bs58_1 = __importDefault(require("bs58"));
|
|
27
|
+
const errors_1 = require("./errors");
|
|
28
|
+
function stringToBytes(str) {
|
|
29
|
+
return ethers_1.ethers.utils.toUtf8Bytes(str);
|
|
30
|
+
}
|
|
31
|
+
function bytesToString(bytes) {
|
|
32
|
+
return ethers_1.ethers.utils.toUtf8String(bytes);
|
|
33
|
+
}
|
|
34
|
+
function stringToBytes32(str) {
|
|
35
|
+
if (!str)
|
|
36
|
+
return ethers_1.ethers.constants.HashZero;
|
|
37
|
+
return ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.toUtf8Bytes(str));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Encode IPFS CIDv0 (Qm...) to bytes32.
|
|
41
|
+
* CIDv0 = base58(0x1220 + 32-byte-sha256-hash)
|
|
42
|
+
* We store just the 32-byte hash portion.
|
|
43
|
+
*/
|
|
44
|
+
function ipfsCidToBytes32(cid) {
|
|
45
|
+
if (!cid || cid === '') {
|
|
46
|
+
return ethers_1.ethers.constants.HashZero;
|
|
47
|
+
}
|
|
48
|
+
if (!cid.startsWith('Qm')) {
|
|
49
|
+
if (cid.startsWith('0x') && cid.length === 66) {
|
|
50
|
+
return cid;
|
|
51
|
+
}
|
|
52
|
+
return stringToBytes32(cid);
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const decoded = bs58_1.default.decode(cid);
|
|
56
|
+
if (decoded.length !== 34) {
|
|
57
|
+
console.error(`Invalid CIDv0 length: expected 34 bytes, got ${decoded.length}`);
|
|
58
|
+
return ethers_1.ethers.constants.HashZero;
|
|
59
|
+
}
|
|
60
|
+
const hashBytes = decoded.slice(2);
|
|
61
|
+
return ethers_1.ethers.utils.hexlify(hashBytes);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error('Failed to encode IPFS CID to bytes32:', error);
|
|
65
|
+
return ethers_1.ethers.constants.HashZero;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Decode bytes32 back to IPFS CIDv0.
|
|
70
|
+
*/
|
|
71
|
+
function bytes32ToIpfsCid(bytes32Hash) {
|
|
72
|
+
if (!bytes32Hash || bytes32Hash === ethers_1.ethers.constants.HashZero)
|
|
73
|
+
return null;
|
|
74
|
+
try {
|
|
75
|
+
const hashBytes = ethers_1.ethers.utils.arrayify(bytes32Hash);
|
|
76
|
+
const withPrefix = new Uint8Array([0x12, 0x20, ...hashBytes]);
|
|
77
|
+
return bs58_1.default.encode(withPrefix);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.warn('Failed to decode bytes32 to IPFS CID:', error);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Parse a task ID from subgraph format.
|
|
86
|
+
* Subgraph returns IDs like "contractAddress-taskId", contract expects numeric taskId.
|
|
87
|
+
*/
|
|
88
|
+
function parseTaskId(taskId) {
|
|
89
|
+
const taskIdStr = taskId.toString();
|
|
90
|
+
const result = taskIdStr.includes('-') ? taskIdStr.split('-')[1] : taskIdStr;
|
|
91
|
+
if (!result) {
|
|
92
|
+
throw new Error(`Invalid task ID format: "${taskId}"`);
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
function parseModuleId(moduleId) {
|
|
97
|
+
const moduleIdStr = moduleId.toString();
|
|
98
|
+
const result = moduleIdStr.includes('-') ? moduleIdStr.split('-')[1] : moduleIdStr;
|
|
99
|
+
if (!result) {
|
|
100
|
+
throw new Error(`Invalid module ID format: "${moduleId}"`);
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Parse a project ID from subgraph format.
|
|
106
|
+
* Subgraph: "{contractAddress}-{projectId}" where projectId is bytes32 hex.
|
|
107
|
+
*/
|
|
108
|
+
function parseProjectId(projectId) {
|
|
109
|
+
if (!projectId) {
|
|
110
|
+
return ethers_1.ethers.constants.HashZero;
|
|
111
|
+
}
|
|
112
|
+
if (projectId.startsWith('0x') && projectId.length === 66) {
|
|
113
|
+
return projectId;
|
|
114
|
+
}
|
|
115
|
+
const subgraphPattern = /^0x[a-fA-F0-9]{40}-(.+)$/;
|
|
116
|
+
const match = projectId.match(subgraphPattern);
|
|
117
|
+
if (match) {
|
|
118
|
+
const extractedId = match[1];
|
|
119
|
+
if (extractedId.startsWith('0x') && extractedId.length === 66) {
|
|
120
|
+
return extractedId;
|
|
121
|
+
}
|
|
122
|
+
if (/^[a-fA-F0-9]+$/.test(extractedId)) {
|
|
123
|
+
return ethers_1.ethers.utils.hexZeroPad('0x' + extractedId, 32);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return stringToBytes32(projectId);
|
|
127
|
+
}
|
|
128
|
+
function formatAddress(address, chars = 4) {
|
|
129
|
+
if (!address)
|
|
130
|
+
return '';
|
|
131
|
+
return `${address.slice(0, chars + 2)}...${address.slice(-chars)}`;
|
|
132
|
+
}
|
|
133
|
+
function isValidAddress(address) {
|
|
134
|
+
return ethers_1.ethers.utils.isAddress(address);
|
|
135
|
+
}
|
|
136
|
+
function toChecksumAddress(address) {
|
|
137
|
+
return ethers_1.ethers.utils.getAddress(address);
|
|
138
|
+
}
|
|
139
|
+
/** Contracts store deadlines as uint48. */
|
|
140
|
+
const UINT48_MAX = 2 ** 48 - 1;
|
|
141
|
+
/** Contracts store durations as uint32. */
|
|
142
|
+
const UINT32_MAX = 2 ** 32 - 1;
|
|
143
|
+
const DURATION_MULTIPLIERS = {
|
|
144
|
+
s: 1,
|
|
145
|
+
m: 60,
|
|
146
|
+
h: 3600,
|
|
147
|
+
d: 86400,
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Parse a deadline expression into unix seconds.
|
|
151
|
+
*
|
|
152
|
+
* Accepted forms:
|
|
153
|
+
* - ''or '0' → 0 (no deadline)
|
|
154
|
+
* - relative → '7d', '48h', '90m', '3600s' (added to `now`)
|
|
155
|
+
* - unix seconds → bare digits >= 10^9, e.g. '1790000000'
|
|
156
|
+
* - ISO date → '2026-08-01' (treated as UTC midnight)
|
|
157
|
+
* - ISO datetime → '2026-08-01T12:30:00' or '...Z' / '...+02:00'
|
|
158
|
+
* (no timezone suffix → treated as UTC)
|
|
159
|
+
*
|
|
160
|
+
* Throws CliError when the input is unparseable, exceeds the uint48
|
|
161
|
+
* range, or resolves to a timestamp at/before `now`.
|
|
162
|
+
*/
|
|
163
|
+
function parseDeadline(input, now) {
|
|
164
|
+
const nowSecs = now ?? Math.floor(Date.now() / 1000);
|
|
165
|
+
const trimmed = (input || '').trim();
|
|
166
|
+
if (trimmed === '' || trimmed === '0')
|
|
167
|
+
return 0;
|
|
168
|
+
let result;
|
|
169
|
+
const relative = trimmed.match(/^(\d+)([smhd])$/i);
|
|
170
|
+
if (relative) {
|
|
171
|
+
result = nowSecs + parseInt(relative[1], 10) * DURATION_MULTIPLIERS[relative[2].toLowerCase()];
|
|
172
|
+
}
|
|
173
|
+
else if (/^\d+$/.test(trimmed)) {
|
|
174
|
+
const num = parseInt(trimmed, 10);
|
|
175
|
+
if (num < 1e9) {
|
|
176
|
+
throw new errors_1.CliError(`Ambiguous deadline "${input}": bare numbers must be unix-second timestamps (>= 1000000000).`, 1, 'Use a relative deadline like "7d" or "48h", an ISO date like "2026-08-01", or a full unix timestamp.');
|
|
177
|
+
}
|
|
178
|
+
result = num;
|
|
179
|
+
}
|
|
180
|
+
else if (/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) {
|
|
181
|
+
const ms = Date.parse(`${trimmed}T00:00:00Z`);
|
|
182
|
+
if (Number.isNaN(ms)) {
|
|
183
|
+
throw new errors_1.CliError(`Invalid date "${input}".`, 1, 'Use an ISO date like "2026-08-01".');
|
|
184
|
+
}
|
|
185
|
+
result = Math.floor(ms / 1000);
|
|
186
|
+
}
|
|
187
|
+
else if (/^\d{4}-\d{2}-\d{2}[T ]/.test(trimmed)) {
|
|
188
|
+
const normalized = trimmed.replace(' ', 'T');
|
|
189
|
+
// No timezone suffix → treat as UTC for deterministic behavior
|
|
190
|
+
const hasTz = /(?:Z|[+-]\d{2}:?\d{2})$/i.test(normalized);
|
|
191
|
+
const ms = Date.parse(hasTz ? normalized : `${normalized}Z`);
|
|
192
|
+
if (Number.isNaN(ms)) {
|
|
193
|
+
throw new errors_1.CliError(`Invalid datetime "${input}".`, 1, 'Use ISO format like "2026-08-01T12:30:00Z".');
|
|
194
|
+
}
|
|
195
|
+
result = Math.floor(ms / 1000);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
throw new errors_1.CliError(`Unparseable deadline "${input}".`, 1, 'Use a relative deadline ("7d", "48h", "90m", "3600s"), an ISO date ("2026-08-01"), a unix timestamp, or "0" for no deadline.');
|
|
199
|
+
}
|
|
200
|
+
if (result > UINT48_MAX) {
|
|
201
|
+
throw new errors_1.CliError(`Deadline "${input}" exceeds the uint48 range (max ${UINT48_MAX}).`);
|
|
202
|
+
}
|
|
203
|
+
if (result <= nowSecs) {
|
|
204
|
+
throw new errors_1.CliError(`Deadline "${input}" is in the past (resolved to ${formatDeadline(result)}).`, 1, 'Pick a future date, or pass "0" for no deadline.');
|
|
205
|
+
}
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Parse a duration expression into seconds.
|
|
210
|
+
* Accepts bare seconds ('3600') or s/m/h/d suffixes ('48h', '7d').
|
|
211
|
+
* '0' → 0. Throws CliError when unparseable or above the uint32 max.
|
|
212
|
+
*/
|
|
213
|
+
function parseDurationSeconds(input) {
|
|
214
|
+
const trimmed = (input || '').trim();
|
|
215
|
+
if (trimmed === '0')
|
|
216
|
+
return 0;
|
|
217
|
+
let seconds;
|
|
218
|
+
const relative = trimmed.match(/^(\d+)([smhd])$/i);
|
|
219
|
+
if (relative) {
|
|
220
|
+
seconds = parseInt(relative[1], 10) * DURATION_MULTIPLIERS[relative[2].toLowerCase()];
|
|
221
|
+
}
|
|
222
|
+
else if (/^\d+$/.test(trimmed)) {
|
|
223
|
+
seconds = parseInt(trimmed, 10);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
throw new errors_1.CliError(`Unparseable duration "${input}".`, 1, 'Use bare seconds ("3600") or a suffix: "3600s", "90m", "48h", "7d".');
|
|
227
|
+
}
|
|
228
|
+
if (seconds > UINT32_MAX) {
|
|
229
|
+
throw new errors_1.CliError(`Duration "${input}" exceeds the uint32 range (max ${UINT32_MAX} seconds).`);
|
|
230
|
+
}
|
|
231
|
+
return seconds;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Format a unix-second deadline as 'YYYY-MM-DD HH:mm UTC'.
|
|
235
|
+
* 0 (no deadline) → 'none'.
|
|
236
|
+
*/
|
|
237
|
+
function formatDeadline(unixSecs) {
|
|
238
|
+
if (!unixSecs)
|
|
239
|
+
return 'none';
|
|
240
|
+
const d = new Date(unixSecs * 1000);
|
|
241
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
242
|
+
return `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())} ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())} UTC`;
|
|
243
|
+
}
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment injection seam.
|
|
3
|
+
*
|
|
4
|
+
* @poa-box/core never reads process.env. Hosts pass an EnvSource where env-derived
|
|
5
|
+
* behavior is wanted: the CLI passes process.env, a Next.js frontend passes an
|
|
6
|
+
* object built from NEXT_PUBLIC_* values, tests pass literals, and integrators
|
|
7
|
+
* who want pure defaults pass nothing.
|
|
8
|
+
*/
|
|
9
|
+
export type EnvSource = Record<string, string | undefined>;
|
|
10
|
+
export declare const EMPTY_ENV: EnvSource;
|
package/dist/env.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract Error Catalog
|
|
3
|
+
* Decodes custom contract errors (4-byte selector + ABI-encoded args) from
|
|
4
|
+
* revert data into human-readable messages with actionable suggestions.
|
|
5
|
+
* Covers every custom error declared across the generated abis/ registry
|
|
6
|
+
* via a lazily-built selector registry. test/lib/error-catalog.test.ts
|
|
7
|
+
* enforces that ERROR_MESSAGES stays in sync with the ABIs.
|
|
8
|
+
*/
|
|
9
|
+
import { ethers } from 'ethers';
|
|
10
|
+
export interface DecodedContractError {
|
|
11
|
+
name: string;
|
|
12
|
+
args: any[];
|
|
13
|
+
human: string;
|
|
14
|
+
suggestion?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Decode custom-error revert data from an ethers v5 error object.
|
|
18
|
+
* Tries the caller-supplied interface first (most specific), then the global
|
|
19
|
+
* registry built from all generated ABI error fragments.
|
|
20
|
+
*
|
|
21
|
+
* Returns null when no revert data is present, or for plain Error(string) /
|
|
22
|
+
* Panic(uint256) reverts — those already surface via error.reason. Unknown
|
|
23
|
+
* selectors return a generic UnknownCustomError(<selector>) result.
|
|
24
|
+
*/
|
|
25
|
+
export declare function decodeContractError(error: any, iface?: ethers.utils.Interface): DecodedContractError | null;
|
|
26
|
+
/**
|
|
27
|
+
* Human messages + suggestions for every distinct custom error name across
|
|
28
|
+
* all generated ABIs. The drift guard in test/lib/error-catalog.test.ts
|
|
29
|
+
* fails if an ABI regeneration introduces a name without an entry here.
|
|
30
|
+
*/
|
|
31
|
+
export declare const ERROR_MESSAGES: Record<string, {
|
|
32
|
+
human: string;
|
|
33
|
+
suggestion?: string;
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Look up the human message + suggestion for a custom error name.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getErrorHint(name: string): {
|
|
39
|
+
human: string;
|
|
40
|
+
suggestion?: string;
|
|
41
|
+
} | undefined;
|