@ckb-firewall/cli 0.1.1 → 0.2.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 +23 -64
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +23 -15
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/check.d.ts +9 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +84 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/execute.d.ts.map +1 -1
- package/dist/commands/execute.js +112 -17
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/export.d.ts +6 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +41 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/import.d.ts +6 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +148 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/inspect.d.ts.map +1 -1
- package/dist/commands/inspect.js +30 -7
- package/dist/commands/inspect.js.map +1 -1
- package/dist/commands/propose.d.ts.map +1 -1
- package/dist/commands/propose.js +29 -4
- package/dist/commands/propose.js.map +1 -1
- package/dist/commands/remove.d.ts.map +1 -1
- package/dist/commands/remove.js +23 -15
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/sign.d.ts +1 -0
- package/dist/commands/sign.d.ts.map +1 -1
- package/dist/commands/sign.js +16 -22
- package/dist/commands/sign.js.map +1 -1
- package/dist/commands/vote.d.ts +1 -1
- package/dist/commands/vote.d.ts.map +1 -1
- package/dist/commands/vote.js +71 -15
- package/dist/commands/vote.js.map +1 -1
- package/dist/index.js +34 -34
- package/dist/index.js.map +1 -1
- package/dist/lib/blkl.d.ts +11 -1
- package/dist/lib/blkl.d.ts.map +1 -1
- package/dist/lib/blkl.js +95 -5
- package/dist/lib/blkl.js.map +1 -1
- package/dist/lib/defaults.d.ts +13 -2
- package/dist/lib/defaults.d.ts.map +1 -1
- package/dist/lib/defaults.js +29 -7
- package/dist/lib/defaults.js.map +1 -1
- package/dist/lib/placeholder-governance.d.ts +2 -0
- package/dist/lib/placeholder-governance.d.ts.map +1 -0
- package/dist/lib/placeholder-governance.js +8 -0
- package/dist/lib/placeholder-governance.js.map +1 -0
- package/dist/lib/proposals.d.ts +5 -1
- package/dist/lib/proposals.d.ts.map +1 -1
- package/dist/lib/proposals.js +37 -3
- package/dist/lib/proposals.js.map +1 -1
- package/dist/lib/registry.d.ts +5 -0
- package/dist/lib/registry.d.ts.map +1 -0
- package/dist/lib/registry.js +24 -0
- package/dist/lib/registry.js.map +1 -0
- package/dist/lib/rpc.d.ts +2 -2
- package/dist/lib/rpc.d.ts.map +1 -1
- package/dist/lib/rpc.js +60 -15
- package/dist/lib/rpc.js.map +1 -1
- package/dist/lib/validator-set.d.ts +7 -0
- package/dist/lib/validator-set.d.ts.map +1 -0
- package/dist/lib/validator-set.js +78 -0
- package/dist/lib/validator-set.js.map +1 -0
- package/dist/lib/witness.d.ts +6 -6
- package/dist/lib/witness.d.ts.map +1 -1
- package/dist/lib/witness.js +16 -10
- package/dist/lib/witness.js.map +1 -1
- package/package.json +3 -2
package/dist/commands/sign.js
CHANGED
|
@@ -5,19 +5,6 @@ import { secp256k1 } from "@noble/curves/secp256k1.js";
|
|
|
5
5
|
import { loadProposal, saveProposal, listProposals, isReviewWindowPassed, isVoteApproved, signingMessage, SIG_THRESHOLD, } from "../lib/proposals.js";
|
|
6
6
|
import { hexToBytes, bytesToHex } from "../lib/blkl.js";
|
|
7
7
|
import { printHints } from "../lib/hints.js";
|
|
8
|
-
// Deterministic dev key for testnet (NOT for production).
|
|
9
|
-
function devKey(index) {
|
|
10
|
-
// Simple derivation: fixed prefix + index byte, then use it as-is.
|
|
11
|
-
// In practice users should supply real keys; this is a testnet convenience.
|
|
12
|
-
const seed = new Uint8Array(32);
|
|
13
|
-
seed[0] = 0x01; // non-zero
|
|
14
|
-
seed[31] = index;
|
|
15
|
-
// Ensure valid secp256k1 scalar (must be 1 <= key <= n-1).
|
|
16
|
-
seed[1] = 0x11;
|
|
17
|
-
seed[2] = 0x22;
|
|
18
|
-
seed[3] = 0x33;
|
|
19
|
-
return seed;
|
|
20
|
-
}
|
|
21
8
|
function isValidPrivKey(hex) {
|
|
22
9
|
try {
|
|
23
10
|
const bytes = hexToBytes(hex);
|
|
@@ -30,6 +17,11 @@ function isValidPrivKey(hex) {
|
|
|
30
17
|
return false;
|
|
31
18
|
}
|
|
32
19
|
}
|
|
20
|
+
export function parseSignerIndex(value) {
|
|
21
|
+
if (!/^[0-4]$/.test(value.trim()))
|
|
22
|
+
return null;
|
|
23
|
+
return Number.parseInt(value.trim(), 10);
|
|
24
|
+
}
|
|
33
25
|
export async function signCommand(opts) {
|
|
34
26
|
// ── select proposal ──────────────────────────────────────────────────────
|
|
35
27
|
let proposalId = opts.proposal?.trim() ?? "";
|
|
@@ -80,11 +72,12 @@ export async function signCommand(opts) {
|
|
|
80
72
|
// ── signer index ─────────────────────────────────────────────────────────
|
|
81
73
|
let signerIndex;
|
|
82
74
|
if (opts.signerIndex !== undefined) {
|
|
83
|
-
|
|
84
|
-
if (
|
|
75
|
+
const parsed = parseSignerIndex(opts.signerIndex);
|
|
76
|
+
if (parsed === null) {
|
|
85
77
|
console.error(logSymbols.error, chalk.red("--signer-index must be 0–4."));
|
|
86
78
|
process.exit(1);
|
|
87
79
|
}
|
|
80
|
+
signerIndex = parsed;
|
|
88
81
|
}
|
|
89
82
|
else {
|
|
90
83
|
const usedIndices = new Set(proposal.signatures.map((s) => s.signerIndex));
|
|
@@ -119,21 +112,20 @@ export async function signCommand(opts) {
|
|
|
119
112
|
}
|
|
120
113
|
else {
|
|
121
114
|
console.log();
|
|
122
|
-
console.log(chalk.dim("Tip: leave blank to use a deterministic testnet dev key for this signer index."));
|
|
123
115
|
const { keyInput } = await inquirer.prompt([
|
|
124
116
|
{
|
|
125
117
|
type: "password",
|
|
126
118
|
name: "keyInput",
|
|
127
|
-
message: `Private key for signer ${signerIndex} (32-byte hex
|
|
119
|
+
message: `Private key for signer ${signerIndex} (32-byte hex):`,
|
|
128
120
|
mask: "*",
|
|
129
121
|
},
|
|
130
122
|
]);
|
|
131
123
|
if (!keyInput.trim()) {
|
|
132
|
-
|
|
133
|
-
|
|
124
|
+
console.error(logSymbols.error, chalk.red("A private key is required. Pass --key <hex> or enter it at the prompt."));
|
|
125
|
+
process.exit(1);
|
|
134
126
|
}
|
|
135
127
|
else if (!isValidPrivKey(keyInput.trim())) {
|
|
136
|
-
console.error(logSymbols.error, chalk.red("Invalid private key."));
|
|
128
|
+
console.error(logSymbols.error, chalk.red("Invalid private key — must be 32-byte hex."));
|
|
137
129
|
process.exit(1);
|
|
138
130
|
}
|
|
139
131
|
else {
|
|
@@ -141,13 +133,16 @@ export async function signCommand(opts) {
|
|
|
141
133
|
}
|
|
142
134
|
}
|
|
143
135
|
// ── sign ─────────────────────────────────────────────────────────────────
|
|
136
|
+
// Derive pubkey before zeroing key material.
|
|
137
|
+
const pubKey = bytesToHex(new Uint8Array(secp256k1.getPublicKey(privateKeyBytes, true)));
|
|
144
138
|
const msgHash = signingMessage(proposal);
|
|
145
139
|
// @noble/curves v2 'recovered' format: [recovery_bit(1), r(32), s(32)].
|
|
146
140
|
// CKB secp256k1 expects: [r(32), s(32), recovery_bit(1)].
|
|
147
141
|
const recoveredSig = secp256k1.sign(msgHash, privateKeyBytes, { lowS: true, format: "recovered" });
|
|
148
142
|
const sigBytes = new Uint8Array(65);
|
|
149
143
|
sigBytes.set(recoveredSig.slice(1), 0); // r + s at bytes 0-63
|
|
150
|
-
sigBytes[64] = recoveredSig[0] ?? 0; // recovery bit at byte 64
|
|
144
|
+
sigBytes[64] = recoveredSig[0] ?? 0; // recovery bit at byte 64
|
|
145
|
+
privateKeyBytes.fill(0); // zero key material immediately after use
|
|
151
146
|
proposal.signatures.push({
|
|
152
147
|
signerIndex,
|
|
153
148
|
signature: bytesToHex(sigBytes),
|
|
@@ -158,7 +153,6 @@ export async function signCommand(opts) {
|
|
|
158
153
|
proposal.status = "approved";
|
|
159
154
|
}
|
|
160
155
|
saveProposal(proposal);
|
|
161
|
-
const pubKey = bytesToHex(new Uint8Array(secp256k1.getPublicKey(privateKeyBytes, true)));
|
|
162
156
|
console.log();
|
|
163
157
|
console.log(logSymbols.success, chalk.green(`Signed by signer ${signerIndex}`));
|
|
164
158
|
console.log(` Public key: ${chalk.dim(pubKey)}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sign.js","sourceRoot":"","sources":["../../src/commands/sign.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,cAAc,EACd,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAW,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"sign.js","sourceRoot":"","sources":["../../src/commands/sign.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/vote.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vote.d.ts","sourceRoot":"","sources":["../../src/commands/vote.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vote.d.ts","sourceRoot":"","sources":["../../src/commands/vote.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAaD,wBAAsB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgKlE"}
|
package/dist/commands/vote.js
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import logSymbols from "log-symbols";
|
|
3
3
|
import inquirer from "inquirer";
|
|
4
|
-
import {
|
|
4
|
+
import { secp256k1 } from "@noble/curves/secp256k1.js";
|
|
5
|
+
import { loadProposal, saveProposal, listProposals, computeVoteDigestHash, voteSigningMessage, isVoteApproved, countYes, VOTE_THRESHOLD, } from "../lib/proposals.js";
|
|
6
|
+
import { hexToBytes, bytesToHex } from "../lib/blkl.js";
|
|
7
|
+
import { computeMerkleProof } from "../lib/validator-set.js";
|
|
8
|
+
import { TESTNET_GOVERNANCE_PUBKEYS } from "../lib/defaults.js";
|
|
5
9
|
import { printHints } from "../lib/hints.js";
|
|
10
|
+
function isValidPrivKey(hex) {
|
|
11
|
+
try {
|
|
12
|
+
const bytes = hexToBytes(hex);
|
|
13
|
+
if (bytes.length !== 32)
|
|
14
|
+
return false;
|
|
15
|
+
secp256k1.getPublicKey(bytes);
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
6
22
|
export async function voteCommand(opts) {
|
|
7
23
|
// ── select proposal ──────────────────────────────────────────────────────
|
|
8
24
|
let proposalId = opts.proposal?.trim() ?? "";
|
|
@@ -35,22 +51,51 @@ export async function voteCommand(opts) {
|
|
|
35
51
|
console.log(logSymbols.error, chalk.red("Proposal was rejected."));
|
|
36
52
|
process.exit(1);
|
|
37
53
|
}
|
|
38
|
-
// ──
|
|
39
|
-
let
|
|
40
|
-
if (
|
|
41
|
-
|
|
54
|
+
// ── private key → pubkey ─────────────────────────────────────────────────
|
|
55
|
+
let privateKeyBytes;
|
|
56
|
+
if (opts.key) {
|
|
57
|
+
if (!isValidPrivKey(opts.key)) {
|
|
58
|
+
console.error(logSymbols.error, chalk.red("Invalid private key — must be 32-byte hex."));
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
privateKeyBytes = hexToBytes(opts.key);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.log();
|
|
65
|
+
const { keyInput } = await inquirer.prompt([
|
|
42
66
|
{
|
|
43
|
-
type: "
|
|
44
|
-
name: "
|
|
45
|
-
message: "
|
|
46
|
-
|
|
67
|
+
type: "password",
|
|
68
|
+
name: "keyInput",
|
|
69
|
+
message: "Validator private key (32-byte hex):",
|
|
70
|
+
mask: "*",
|
|
47
71
|
},
|
|
48
72
|
]);
|
|
49
|
-
|
|
73
|
+
if (!keyInput.trim()) {
|
|
74
|
+
console.error(logSymbols.error, chalk.red("A private key is required. Pass --key <hex> or enter it at the prompt."));
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
if (!isValidPrivKey(keyInput.trim())) {
|
|
78
|
+
console.error(logSymbols.error, chalk.red("Invalid private key — must be 32-byte hex."));
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
privateKeyBytes = hexToBytes(keyInput.trim());
|
|
82
|
+
}
|
|
83
|
+
const pubkeyBytes = secp256k1.getPublicKey(privateKeyBytes, true); // 33 bytes compressed
|
|
84
|
+
const pubkey = bytesToHex(new Uint8Array(pubkeyBytes));
|
|
85
|
+
// Verify this pubkey is in the authorized validator set.
|
|
86
|
+
const validatorSet = TESTNET_GOVERNANCE_PUBKEYS.map(bytesToHex);
|
|
87
|
+
const merkleResult = computeMerkleProof(validatorSet, pubkey);
|
|
88
|
+
if (merkleResult === null) {
|
|
89
|
+
console.error(logSymbols.error, chalk.red("This key is not an authorized validator."));
|
|
90
|
+
console.error(chalk.dim(` Pubkey: ${pubkey}`));
|
|
91
|
+
privateKeyBytes.fill(0);
|
|
92
|
+
process.exit(1);
|
|
50
93
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
94
|
+
const { proof: merkleProof, leafIndex: merkleLeafIndex } = merkleResult;
|
|
95
|
+
// Duplicate check by pubkey.
|
|
96
|
+
if (proposal.votes.some((v) => v.pubkey.toLowerCase() === pubkey.toLowerCase())) {
|
|
97
|
+
console.log(logSymbols.warning, chalk.yellow(`Validator pubkey ${pubkey.slice(0, 14)}… has already voted on this proposal.`));
|
|
98
|
+
privateKeyBytes.fill(0);
|
|
54
99
|
process.exit(0);
|
|
55
100
|
}
|
|
56
101
|
// ── vote ─────────────────────────────────────────────────────────────────
|
|
@@ -80,8 +125,19 @@ export async function voteCommand(opts) {
|
|
|
80
125
|
]);
|
|
81
126
|
vote = chosen;
|
|
82
127
|
}
|
|
128
|
+
// ── sign vote ────────────────────────────────────────────────────────────
|
|
129
|
+
const timestamp = new Date().toISOString();
|
|
130
|
+
const msgHash = voteSigningMessage(proposal.proposalIdHash, vote, timestamp, pubkey);
|
|
131
|
+
// format:"recovered" returns Uint8Array[recovery_id(1), r(32), s(32)]
|
|
132
|
+
const sigRaw = secp256k1.sign(msgHash, privateKeyBytes, { lowS: true, format: "recovered" });
|
|
133
|
+
// Store as [r(32), s(32), recovery_id(1)] — matches ProposalSignature convention
|
|
134
|
+
const sigBytes = new Uint8Array(65);
|
|
135
|
+
sigBytes.set(sigRaw.slice(1), 0);
|
|
136
|
+
sigBytes[64] = sigRaw[0] ?? 0;
|
|
137
|
+
privateKeyBytes.fill(0); // zero key material immediately after use
|
|
138
|
+
const signature = bytesToHex(sigBytes);
|
|
83
139
|
// ── record vote ──────────────────────────────────────────────────────────
|
|
84
|
-
proposal.votes.push({
|
|
140
|
+
proposal.votes.push({ pubkey, vote, timestamp, signature, merkleLeafIndex, merkleProof });
|
|
85
141
|
proposal.voteDigestHash = computeVoteDigestHash(proposal.votes);
|
|
86
142
|
const yesCount = countYes(proposal.votes);
|
|
87
143
|
const approved = isVoteApproved(proposal);
|
|
@@ -90,7 +146,7 @@ export async function voteCommand(opts) {
|
|
|
90
146
|
}
|
|
91
147
|
saveProposal(proposal);
|
|
92
148
|
console.log();
|
|
93
|
-
console.log(logSymbols.success, `Vote recorded: ${chalk.bold(vote)} by ${
|
|
149
|
+
console.log(logSymbols.success, `Vote recorded: ${chalk.bold(vote)} by ${pubkey.slice(0, 14)}…`);
|
|
94
150
|
console.log(` Yes votes: ${yesCount}/${VOTE_THRESHOLD} required`);
|
|
95
151
|
if (approved) {
|
|
96
152
|
console.log();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vote.js","sourceRoot":"","sources":["../../src/commands/vote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,cAAc,EACd,QAAQ,EACR,cAAc,GAEf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAQ7C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAiB;IACjD,4EAA4E;IAE5E,IAAI,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC7C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC,MAAM,CACjC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,gBAAgB,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,CAC9D,CAAC;QACF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,mCAAmC,CAAC,CAAC,CAAC;YACnF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC,CAAC;YAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAqB;YAC3D;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,6BAA6B;gBACtC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACxB,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,cAAc,OAAO;oBAC/I,KAAK,EAAE,CAAC,CAAC,EAAE;iBACZ,CAAC,CAAC;aACJ;SACF,CAAC,CAAC;QACH,UAAU,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,MAAM,QAAQ,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IAE1C,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,4EAA4E;IAE5E,IAAI,
|
|
1
|
+
{"version":3,"file":"vote.js","sourceRoot":"","sources":["../../src/commands/vote.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
import { program } from "commander";
|
|
3
3
|
import cfonts from "cfonts";
|
|
4
4
|
import { inspectCommand, inspectDefaults } from "./commands/inspect.js";
|
|
5
|
-
import { addCommand, addDefaults } from "./commands/add.js";
|
|
6
|
-
import { removeCommand, removeDefaults } from "./commands/remove.js";
|
|
7
5
|
import { proposeCommand } from "./commands/propose.js";
|
|
8
6
|
import { proposalsCommand } from "./commands/proposals.js";
|
|
9
7
|
import { voteCommand } from "./commands/vote.js";
|
|
10
8
|
import { signCommand } from "./commands/sign.js";
|
|
11
9
|
import { executeCommand, executeDefaults } from "./commands/execute.js";
|
|
10
|
+
import { exportCommand } from "./commands/export.js";
|
|
11
|
+
import { importCommand } from "./commands/import.js";
|
|
12
|
+
import { checkCommand, checkDefaults } from "./commands/check.js";
|
|
12
13
|
function printBanner() {
|
|
13
14
|
cfonts.say("CKB FIREWALL|CLI", {
|
|
14
15
|
font: "block",
|
|
@@ -24,7 +25,7 @@ function printBanner() {
|
|
|
24
25
|
program
|
|
25
26
|
.name("ckb-firewall")
|
|
26
27
|
.description("Manage the CKB Transaction Firewall blacklist registry")
|
|
27
|
-
.version("0.
|
|
28
|
+
.version("0.2.0")
|
|
28
29
|
.addHelpCommand(false);
|
|
29
30
|
// ── inspect ──────────────────────────────────────────────────────────────────
|
|
30
31
|
const inspectDefs = inspectDefaults();
|
|
@@ -37,41 +38,22 @@ program
|
|
|
37
38
|
.action(async (opts) => {
|
|
38
39
|
await inspectCommand(opts);
|
|
39
40
|
});
|
|
40
|
-
// ──
|
|
41
|
-
const
|
|
41
|
+
// ── check ─────────────────────────────────────────────────────────────────────
|
|
42
|
+
const checkDefs = checkDefaults();
|
|
42
43
|
program
|
|
43
|
-
.command("
|
|
44
|
-
.description("
|
|
45
|
-
.
|
|
46
|
-
.option("--
|
|
47
|
-
.option("--
|
|
48
|
-
.option("--registry-
|
|
49
|
-
.option("--registry-index <n>", "Registry cell output index", addDefs.registryIndex)
|
|
50
|
-
.option("--tx-out <file>", "Write unsigned tx JSON to this file", addDefs.txOut)
|
|
51
|
-
.option("--sign", "Sign and submit via ckb-cli after generating the tx file")
|
|
52
|
-
.option("--from-account <address>", "Governance account address for ckb-cli signing", addDefs.fromAccount)
|
|
44
|
+
.command("check")
|
|
45
|
+
.description("Test whether a lock-args identifier is currently blacklisted")
|
|
46
|
+
.requiredOption("--lock-args <hex>", "Lock args to check (0x-prefixed hex)")
|
|
47
|
+
.option("--rpc-url <url>", "CKB node RPC URL", checkDefs.rpcUrl)
|
|
48
|
+
.option("--registry-tx <hash>", "Registry cell tx hash", checkDefs.registryTx)
|
|
49
|
+
.option("--registry-index <n>", "Registry cell output index", checkDefs.registryIndex)
|
|
53
50
|
.action(async (opts) => {
|
|
54
|
-
await
|
|
55
|
-
});
|
|
56
|
-
// ── remove (quick path) ───────────────────────────────────────────────────────
|
|
57
|
-
const removeDefs = removeDefaults();
|
|
58
|
-
program
|
|
59
|
-
.command("remove")
|
|
60
|
-
.description("Quick: remove a lock-args from the blacklist with placeholder governance (testnet/dev)")
|
|
61
|
-
.option("--lock-args <hex>", "Lock args to remove (0x-prefixed hex)")
|
|
62
|
-
.option("--rpc-url <url>", "CKB node RPC URL", removeDefs.rpcUrl)
|
|
63
|
-
.option("--registry-tx <hash>", "Registry cell tx hash", removeDefs.registryTx)
|
|
64
|
-
.option("--registry-index <n>", "Registry cell output index", removeDefs.registryIndex)
|
|
65
|
-
.option("--tx-out <file>", "Write unsigned tx JSON to this file", removeDefs.txOut)
|
|
66
|
-
.option("--sign", "Sign and submit via ckb-cli after generating the tx file")
|
|
67
|
-
.option("--from-account <address>", "Governance account address for ckb-cli signing", removeDefs.fromAccount)
|
|
68
|
-
.action(async (opts) => {
|
|
69
|
-
await removeCommand(opts);
|
|
51
|
+
await checkCommand(opts);
|
|
70
52
|
});
|
|
71
53
|
// ── propose ───────────────────────────────────────────────────────────────────
|
|
72
54
|
program
|
|
73
55
|
.command("propose")
|
|
74
|
-
.description("Create a governance proposal (
|
|
56
|
+
.description("Create a governance proposal (72h review + voting + signing + on-chain execution)")
|
|
75
57
|
.option("--action <add|remove>", "Proposal action")
|
|
76
58
|
.option("--lock-args <hex>", "Lock args to add or remove")
|
|
77
59
|
.option("--expires-at <timestamp>", "Expiry timestamp (add only, 0 = never)")
|
|
@@ -94,10 +76,10 @@ program
|
|
|
94
76
|
// ── vote ──────────────────────────────────────────────────────────────────────
|
|
95
77
|
program
|
|
96
78
|
.command("vote")
|
|
97
|
-
.description("Record a validator vote on a governance proposal")
|
|
79
|
+
.description("Record a cryptographically signed validator vote on a governance proposal")
|
|
98
80
|
.option("--proposal <id>", "Proposal ID or hash")
|
|
99
81
|
.option("--vote <choice>", "Vote: yes|no|abstain")
|
|
100
|
-
.option("--
|
|
82
|
+
.option("--key <hex>", "32-byte validator private key in hex (prompted if omitted)")
|
|
101
83
|
.action(async (opts) => {
|
|
102
84
|
await voteCommand(opts);
|
|
103
85
|
});
|
|
@@ -126,6 +108,24 @@ program
|
|
|
126
108
|
.action(async (opts) => {
|
|
127
109
|
await executeCommand(opts);
|
|
128
110
|
});
|
|
111
|
+
// ── export ────────────────────────────────────────────────────────────────────
|
|
112
|
+
program
|
|
113
|
+
.command("export")
|
|
114
|
+
.description("Export a proposal to a shareable JSON file")
|
|
115
|
+
.option("--proposal <id>", "Proposal ID or hash")
|
|
116
|
+
.option("--out <file>", "Output file path (prints to stdout if omitted)")
|
|
117
|
+
.action(async (opts) => {
|
|
118
|
+
await exportCommand(opts);
|
|
119
|
+
});
|
|
120
|
+
// ── import ────────────────────────────────────────────────────────────────────
|
|
121
|
+
program
|
|
122
|
+
.command("import")
|
|
123
|
+
.description("Import a proposal shared by another governance participant")
|
|
124
|
+
.argument("<file>", "Path to the exported proposal JSON")
|
|
125
|
+
.option("--force", "Overwrite an existing proposal without prompting")
|
|
126
|
+
.action(async (file, opts) => {
|
|
127
|
+
await importCommand({ file, ...opts });
|
|
128
|
+
});
|
|
129
129
|
// Show banner on bare invocation before help prints.
|
|
130
130
|
if (process.argv.length <= 2)
|
|
131
131
|
printBanner();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/blkl.d.ts
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import type { RegistryEntry, RegistryPayload } from "@ckb-firewall/sdk";
|
|
2
|
+
export interface GovernanceHeader {
|
|
3
|
+
signerCount: number;
|
|
4
|
+
threshold: number;
|
|
5
|
+
pubkeys: Uint8Array[];
|
|
6
|
+
validatorCount: number;
|
|
7
|
+
validatorMerkleRoot: Uint8Array;
|
|
8
|
+
}
|
|
2
9
|
export declare function strip0x(hex: string): string;
|
|
3
10
|
export declare function hexToBytes(hex: string): Uint8Array;
|
|
4
11
|
export declare function bytesToHex(bytes: Uint8Array): string;
|
|
5
|
-
export declare function
|
|
12
|
+
export declare function encodeGovernanceHeader(h: GovernanceHeader): Uint8Array;
|
|
13
|
+
export declare function parseGovernanceHeader(raw: Uint8Array): GovernanceHeader | null;
|
|
14
|
+
export declare function extractGovernanceHeaderRaw(hex: string): Uint8Array | null;
|
|
15
|
+
export declare function encodeRegistryPayload(payload: RegistryPayload, governanceHeaderRaw?: Uint8Array): Uint8Array;
|
|
6
16
|
export declare function insertSorted(entries: RegistryEntry[], newEntry: RegistryEntry): RegistryEntry[];
|
|
7
17
|
export declare function removeEntry(entries: RegistryEntry[], identifier: string): RegistryEntry[];
|
|
8
18
|
//# sourceMappingURL=blkl.d.ts.map
|
package/dist/lib/blkl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blkl.d.ts","sourceRoot":"","sources":["../../src/lib/blkl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAExE,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"blkl.d.ts","sourceRoot":"","sources":["../../src/lib/blkl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAExE,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,UAAU,CAAC;CACjC;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAUlD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIpD;AAED,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,gBAAgB,GAAG,UAAU,CAetE;AAID,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,GAAG,IAAI,CAe9E;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAUzE;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,eAAe,EAAE,mBAAmB,CAAC,EAAE,UAAU,GAAG,UAAU,CA8C5G;AAWD,wBAAgB,YAAY,CAC1B,OAAO,EAAE,aAAa,EAAE,EACxB,QAAQ,EAAE,aAAa,GACtB,aAAa,EAAE,CAOjB;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,aAAa,EAAE,EACxB,UAAU,EAAE,MAAM,GACjB,aAAa,EAAE,CAKjB"}
|
package/dist/lib/blkl.js
CHANGED
|
@@ -3,6 +3,9 @@ export function strip0x(hex) {
|
|
|
3
3
|
}
|
|
4
4
|
export function hexToBytes(hex) {
|
|
5
5
|
const clean = strip0x(hex);
|
|
6
|
+
if (clean.length % 2 !== 0) {
|
|
7
|
+
throw new Error(`hexToBytes: odd-length hex string (${clean.length} chars): "${hex.slice(0, 20)}"`);
|
|
8
|
+
}
|
|
6
9
|
const out = new Uint8Array(clean.length / 2);
|
|
7
10
|
for (let i = 0; i < clean.length; i += 2) {
|
|
8
11
|
out[i / 2] = Number.parseInt(clean.slice(i, i + 2), 16);
|
|
@@ -14,7 +17,57 @@ export function bytesToHex(bytes) {
|
|
|
14
17
|
.map((b) => b.toString(16).padStart(2, "0"))
|
|
15
18
|
.join("")}`;
|
|
16
19
|
}
|
|
17
|
-
export function
|
|
20
|
+
export function encodeGovernanceHeader(h) {
|
|
21
|
+
const size = 1 + 1 + 1 + 33 * h.pubkeys.length + 2 + 32;
|
|
22
|
+
const buf = new Uint8Array(size);
|
|
23
|
+
let off = 0;
|
|
24
|
+
buf[off++] = 0x01; // governance header version
|
|
25
|
+
buf[off++] = h.signerCount;
|
|
26
|
+
buf[off++] = h.threshold;
|
|
27
|
+
for (const pk of h.pubkeys) {
|
|
28
|
+
buf.set(pk, off);
|
|
29
|
+
off += 33;
|
|
30
|
+
}
|
|
31
|
+
buf[off++] = h.validatorCount & 0xff;
|
|
32
|
+
buf[off++] = (h.validatorCount >> 8) & 0xff;
|
|
33
|
+
buf.set(h.validatorMerkleRoot, off);
|
|
34
|
+
return buf;
|
|
35
|
+
}
|
|
36
|
+
// Parses a raw governance header byte slice into a GovernanceHeader.
|
|
37
|
+
// Format: gh_version(1) | signer_count(1) | threshold(1) | [pubkey(33)]×N | validator_count(2 LE) | merkle_root(32)
|
|
38
|
+
export function parseGovernanceHeader(raw) {
|
|
39
|
+
if (raw.length < 3)
|
|
40
|
+
return null;
|
|
41
|
+
if (raw[0] !== 0x01)
|
|
42
|
+
return null;
|
|
43
|
+
const signerCount = raw[1];
|
|
44
|
+
const threshold = raw[2];
|
|
45
|
+
const pubkeysEnd = 3 + signerCount * 33;
|
|
46
|
+
if (raw.length < pubkeysEnd + 2 + 32)
|
|
47
|
+
return null;
|
|
48
|
+
const pubkeys = [];
|
|
49
|
+
for (let i = 0; i < signerCount; i++) {
|
|
50
|
+
pubkeys.push(raw.slice(3 + i * 33, 3 + (i + 1) * 33));
|
|
51
|
+
}
|
|
52
|
+
const validatorCount = raw[pubkeysEnd] | (raw[pubkeysEnd + 1] << 8);
|
|
53
|
+
const validatorMerkleRoot = raw.slice(pubkeysEnd + 2, pubkeysEnd + 2 + 32);
|
|
54
|
+
return { signerCount, threshold, pubkeys, validatorCount, validatorMerkleRoot };
|
|
55
|
+
}
|
|
56
|
+
export function extractGovernanceHeaderRaw(hex) {
|
|
57
|
+
try {
|
|
58
|
+
const data = hexToBytes(hex);
|
|
59
|
+
if (data.length < 7 || data[4] !== 0x02)
|
|
60
|
+
return null;
|
|
61
|
+
const govHeaderLen = data[5] | (data[6] << 8);
|
|
62
|
+
if (data.length < 7 + govHeaderLen)
|
|
63
|
+
return null;
|
|
64
|
+
return data.slice(7, 7 + govHeaderLen);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export function encodeRegistryPayload(payload, governanceHeaderRaw) {
|
|
18
71
|
const encodedEntries = payload.entries.map((e) => {
|
|
19
72
|
const id = hexToBytes(e.identifier);
|
|
20
73
|
const buf = new Uint8Array(1 + id.length + 8);
|
|
@@ -27,14 +80,41 @@ export function encodeRegistryPayload(payload) {
|
|
|
27
80
|
}
|
|
28
81
|
return buf;
|
|
29
82
|
});
|
|
30
|
-
const
|
|
83
|
+
const entriesSize = encodedEntries.reduce((acc, e) => acc + e.length, 0);
|
|
84
|
+
if (governanceHeaderRaw) {
|
|
85
|
+
// BLKL v2: BLKL(4) + version(1) + gov_header_len(2) + gov_header(N) + entry_count(4) + entries
|
|
86
|
+
const govLen = governanceHeaderRaw.length;
|
|
87
|
+
const totalSize = 4 + 1 + 2 + govLen + 4 + entriesSize;
|
|
88
|
+
const out = new Uint8Array(totalSize);
|
|
89
|
+
let off = 0;
|
|
90
|
+
out[off++] = 0x42;
|
|
91
|
+
out[off++] = 0x4c;
|
|
92
|
+
out[off++] = 0x4b;
|
|
93
|
+
out[off++] = 0x4c; // BLKL
|
|
94
|
+
out[off++] = 0x02; // version 2
|
|
95
|
+
out[off++] = govLen & 0xff;
|
|
96
|
+
out[off++] = (govLen >> 8) & 0xff;
|
|
97
|
+
out.set(governanceHeaderRaw, off);
|
|
98
|
+
off += govLen;
|
|
99
|
+
const count = payload.entries.length;
|
|
100
|
+
out[off++] = count & 0xff;
|
|
101
|
+
out[off++] = (count >> 8) & 0xff;
|
|
102
|
+
out[off++] = (count >> 16) & 0xff;
|
|
103
|
+
out[off++] = (count >> 24) & 0xff;
|
|
104
|
+
for (const e of encodedEntries) {
|
|
105
|
+
out.set(e, off);
|
|
106
|
+
off += e.length;
|
|
107
|
+
}
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
// BLKL v1: BLKL(4) + version(1) + entry_count(4) + entries
|
|
111
|
+
const totalSize = 9 + entriesSize;
|
|
31
112
|
const out = new Uint8Array(totalSize);
|
|
32
113
|
let off = 0;
|
|
33
|
-
// Magic "BLKL"
|
|
34
114
|
out[off++] = 0x42;
|
|
35
115
|
out[off++] = 0x4c;
|
|
36
116
|
out[off++] = 0x4b;
|
|
37
|
-
out[off++] = 0x4c;
|
|
117
|
+
out[off++] = 0x4c; // BLKL
|
|
38
118
|
out[off++] = payload.version;
|
|
39
119
|
const count = payload.entries.length;
|
|
40
120
|
out[off++] = count & 0xff;
|
|
@@ -47,9 +127,19 @@ export function encodeRegistryPayload(payload) {
|
|
|
47
127
|
}
|
|
48
128
|
return out;
|
|
49
129
|
}
|
|
130
|
+
function compareIdentifierBytes(a, b) {
|
|
131
|
+
const len = Math.min(a.length, b.length);
|
|
132
|
+
for (let i = 0; i < len; i++) {
|
|
133
|
+
const diff = a[i] - b[i];
|
|
134
|
+
if (diff !== 0)
|
|
135
|
+
return diff;
|
|
136
|
+
}
|
|
137
|
+
return a.length - b.length;
|
|
138
|
+
}
|
|
50
139
|
export function insertSorted(entries, newEntry) {
|
|
51
140
|
const result = [...entries];
|
|
52
|
-
|
|
141
|
+
const newBytes = hexToBytes(newEntry.identifier);
|
|
142
|
+
let insertAt = result.findIndex((e) => compareIdentifierBytes(hexToBytes(e.identifier), newBytes) >= 0);
|
|
53
143
|
if (insertAt === -1)
|
|
54
144
|
insertAt = result.length;
|
|
55
145
|
result.splice(insertAt, 0, newEntry);
|