@ckb-firewall/cli 0.3.1 → 0.5.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 +11 -6
- package/dist/commands/anchor.d.ts +23 -0
- package/dist/commands/anchor.d.ts.map +1 -0
- package/dist/commands/anchor.js +412 -0
- package/dist/commands/anchor.js.map +1 -0
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +59 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/execute.d.ts +9 -1
- package/dist/commands/execute.d.ts.map +1 -1
- package/dist/commands/execute.js +394 -229
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/gui.d.ts +6 -0
- package/dist/commands/gui.d.ts.map +1 -0
- package/dist/commands/gui.js +112 -0
- package/dist/commands/gui.js.map +1 -0
- package/dist/commands/import.d.ts.map +1 -1
- package/dist/commands/import.js +15 -48
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/inspect.d.ts.map +1 -1
- package/dist/commands/inspect.js +32 -0
- package/dist/commands/inspect.js.map +1 -1
- package/dist/commands/proposals.d.ts.map +1 -1
- package/dist/commands/proposals.js +2 -4
- package/dist/commands/proposals.js.map +1 -1
- package/dist/commands/propose.d.ts +5 -0
- package/dist/commands/propose.d.ts.map +1 -1
- package/dist/commands/propose.js +91 -7
- package/dist/commands/propose.js.map +1 -1
- package/dist/commands/reclaim.d.ts +18 -0
- package/dist/commands/reclaim.d.ts.map +1 -0
- package/dist/commands/reclaim.js +214 -0
- package/dist/commands/reclaim.js.map +1 -0
- package/dist/commands/sign.d.ts.map +1 -1
- package/dist/commands/sign.js +40 -94
- package/dist/commands/sign.js.map +1 -1
- package/dist/commands/vote.d.ts +2 -0
- package/dist/commands/vote.d.ts.map +1 -1
- package/dist/commands/vote.js +31 -25
- package/dist/commands/vote.js.map +1 -1
- package/dist/index.js +101 -16
- package/dist/index.js.map +1 -1
- package/dist/lib/Transaction Firewall.html +201 -0
- package/dist/lib/blkl.d.ts +17 -2
- package/dist/lib/blkl.d.ts.map +1 -1
- package/dist/lib/blkl.js +133 -17
- package/dist/lib/blkl.js.map +1 -1
- package/dist/lib/capacity.d.ts +12 -0
- package/dist/lib/capacity.d.ts.map +1 -0
- package/dist/lib/capacity.js +18 -0
- package/dist/lib/capacity.js.map +1 -0
- package/dist/lib/config.d.ts +7 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +35 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/defaults.d.ts +19 -0
- package/dist/lib/defaults.d.ts.map +1 -1
- package/dist/lib/defaults.js +34 -7
- package/dist/lib/defaults.js.map +1 -1
- package/dist/lib/governance-v4.d.ts +39 -0
- package/dist/lib/governance-v4.d.ts.map +1 -0
- package/dist/lib/governance-v4.js +194 -0
- package/dist/lib/governance-v4.js.map +1 -0
- package/dist/lib/gui-bundle.html +4266 -0
- package/dist/lib/gui-server.d.ts +12 -0
- package/dist/lib/gui-server.d.ts.map +1 -0
- package/dist/lib/gui-server.js +1634 -0
- package/dist/lib/gui-server.js.map +1 -0
- package/dist/lib/hints.d.ts +1 -1
- package/dist/lib/hints.d.ts.map +1 -1
- package/dist/lib/hints.js +3 -9
- package/dist/lib/hints.js.map +1 -1
- package/dist/lib/portless.d.ts +41 -0
- package/dist/lib/portless.d.ts.map +1 -0
- package/dist/lib/portless.js +194 -0
- package/dist/lib/portless.js.map +1 -0
- package/dist/lib/proposals.d.ts +17 -9
- package/dist/lib/proposals.d.ts.map +1 -1
- package/dist/lib/proposals.js +4 -26
- package/dist/lib/proposals.js.map +1 -1
- package/dist/lib/rpc.d.ts +5 -0
- package/dist/lib/rpc.d.ts.map +1 -1
- package/dist/lib/rpc.js +21 -0
- package/dist/lib/rpc.js.map +1 -1
- package/dist/lib/treasury-status.d.ts +28 -0
- package/dist/lib/treasury-status.d.ts.map +1 -0
- package/dist/lib/treasury-status.js +70 -0
- package/dist/lib/treasury-status.js.map +1 -0
- package/dist/lib/treasury.d.ts +15 -0
- package/dist/lib/treasury.d.ts.map +1 -0
- package/dist/lib/treasury.js +62 -0
- package/dist/lib/treasury.js.map +1 -0
- package/dist/lib/tx-deps.d.ts +9 -0
- package/dist/lib/tx-deps.d.ts.map +1 -0
- package/dist/lib/tx-deps.js +15 -0
- package/dist/lib/tx-deps.js.map +1 -0
- package/dist/lib/witness.d.ts +13 -11
- package/dist/lib/witness.d.ts.map +1 -1
- package/dist/lib/witness.js +85 -48
- package/dist/lib/witness.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { LiveCell } from "./rpc.js";
|
|
2
|
+
import { type GovernanceHeader } from "./blkl.js";
|
|
3
|
+
export declare const TREASURY_DONATION_THRESHOLD_PERCENT = 70;
|
|
4
|
+
export interface TreasuryStatus {
|
|
5
|
+
lockHash: string;
|
|
6
|
+
lockScript?: {
|
|
7
|
+
code_hash: string;
|
|
8
|
+
hash_type: string;
|
|
9
|
+
args: string;
|
|
10
|
+
};
|
|
11
|
+
donationAddress?: string;
|
|
12
|
+
liveCellCount?: number;
|
|
13
|
+
balanceShannons?: string;
|
|
14
|
+
registryCapacityShannons: string;
|
|
15
|
+
registryOccupiedShannons: string;
|
|
16
|
+
poolCapacityShannons?: string;
|
|
17
|
+
poolUsedPercent?: number;
|
|
18
|
+
donateRecommended: boolean;
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function formatCkb(shannons: bigint): string;
|
|
22
|
+
export declare function knownTreasuryDonationAddress(rpcUrl: string, lockScript: {
|
|
23
|
+
code_hash: string;
|
|
24
|
+
hash_type: string;
|
|
25
|
+
args: string;
|
|
26
|
+
} | undefined): string | undefined;
|
|
27
|
+
export declare function loadTreasuryStatus(rpcUrl: string, registryCell: LiveCell, governanceHeader: GovernanceHeader | null): Promise<TreasuryStatus | null>;
|
|
28
|
+
//# sourceMappingURL=treasury-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treasury-status.d.ts","sourceRoot":"","sources":["../../src/lib/treasury-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAA0C,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAK1F,eAAO,MAAM,mCAAmC,KAAK,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wBAAwB,EAAE,MAAM,CAAC;IACjC,wBAAwB,EAAE,MAAM,CAAC;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,EACd,UAAU,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GAC7E,MAAM,GAAG,SAAS,CAUpB;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,QAAQ,EACtB,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,GACxC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA6ChC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { getLiveCellsByLock } from "./rpc.js";
|
|
2
|
+
import { bytesToHex, governanceTreasuryLockHash } from "./blkl.js";
|
|
3
|
+
import { occupiedCapacityShannons, parseCapacity } from "./capacity.js";
|
|
4
|
+
import { TESTNET_RPC_URL, TESTNET_TREASURY_DONATION_ADDRESS } from "./defaults.js";
|
|
5
|
+
const SHANNONS_PER_CKB = 100000000n;
|
|
6
|
+
export const TREASURY_DONATION_THRESHOLD_PERCENT = 70;
|
|
7
|
+
export function formatCkb(shannons) {
|
|
8
|
+
const whole = shannons / SHANNONS_PER_CKB;
|
|
9
|
+
const frac = shannons % SHANNONS_PER_CKB;
|
|
10
|
+
if (frac === 0n)
|
|
11
|
+
return `${whole} CKB`;
|
|
12
|
+
const fracText = frac.toString().padStart(8, "0").replace(/0+$/, "");
|
|
13
|
+
return `${whole}.${fracText} CKB`;
|
|
14
|
+
}
|
|
15
|
+
export function knownTreasuryDonationAddress(rpcUrl, lockScript) {
|
|
16
|
+
if (rpcUrl === TESTNET_RPC_URL &&
|
|
17
|
+
lockScript?.code_hash === "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8" &&
|
|
18
|
+
lockScript.hash_type === "type" &&
|
|
19
|
+
lockScript.args === "0x9888a8a74df4e0ce82e7a4604f8fd403fd4622ca") {
|
|
20
|
+
return TESTNET_TREASURY_DONATION_ADDRESS;
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
export async function loadTreasuryStatus(rpcUrl, registryCell, governanceHeader) {
|
|
25
|
+
const treasuryLockHash = governanceTreasuryLockHash(governanceHeader);
|
|
26
|
+
if (!treasuryLockHash)
|
|
27
|
+
return null;
|
|
28
|
+
const registryCapacity = parseCapacity(registryCell.capacity);
|
|
29
|
+
const registryOccupied = occupiedCapacityShannons({
|
|
30
|
+
lock: registryCell.lock,
|
|
31
|
+
type: registryCell.type,
|
|
32
|
+
data: registryCell.data,
|
|
33
|
+
});
|
|
34
|
+
const lockScript = governanceHeader?.treasuryLockScript;
|
|
35
|
+
const donationAddress = knownTreasuryDonationAddress(rpcUrl, lockScript);
|
|
36
|
+
const base = {
|
|
37
|
+
lockHash: bytesToHex(treasuryLockHash),
|
|
38
|
+
...(lockScript ? { lockScript } : {}),
|
|
39
|
+
...(donationAddress ? { donationAddress } : {}),
|
|
40
|
+
registryCapacityShannons: registryCapacity.toString(),
|
|
41
|
+
registryOccupiedShannons: registryOccupied.toString(),
|
|
42
|
+
donateRecommended: false,
|
|
43
|
+
};
|
|
44
|
+
if (!lockScript)
|
|
45
|
+
return base;
|
|
46
|
+
try {
|
|
47
|
+
const treasuryCells = await getLiveCellsByLock(rpcUrl, lockScript, 100);
|
|
48
|
+
const plainTreasuryCells = treasuryCells.filter((c) => !c.type && c.data === "0x");
|
|
49
|
+
const treasuryBalance = plainTreasuryCells.reduce((sum, c) => sum + parseCapacity(c.capacity), 0n);
|
|
50
|
+
const poolCapacity = registryCapacity + treasuryBalance;
|
|
51
|
+
const poolUsedPercent = poolCapacity > 0n
|
|
52
|
+
? Number((registryOccupied * 10000n) / poolCapacity) / 100
|
|
53
|
+
: 100;
|
|
54
|
+
return {
|
|
55
|
+
...base,
|
|
56
|
+
liveCellCount: plainTreasuryCells.length,
|
|
57
|
+
balanceShannons: treasuryBalance.toString(),
|
|
58
|
+
poolCapacityShannons: poolCapacity.toString(),
|
|
59
|
+
poolUsedPercent,
|
|
60
|
+
donateRecommended: poolUsedPercent >= TREASURY_DONATION_THRESHOLD_PERCENT,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
return {
|
|
65
|
+
...base,
|
|
66
|
+
error: err instanceof Error ? err.message : String(err),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=treasury-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treasury-status.js","sourceRoot":"","sources":["../../src/lib/treasury-status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface TreasuryConfig {
|
|
2
|
+
address: string;
|
|
3
|
+
fromAccount?: string;
|
|
4
|
+
privkeyPath?: string;
|
|
5
|
+
capacity: string;
|
|
6
|
+
feeRate: string;
|
|
7
|
+
outputIndex: number;
|
|
8
|
+
autoAnchor: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function loadTreasuryConfig(env?: NodeJS.ProcessEnv): TreasuryConfig | null;
|
|
11
|
+
export declare function assertTreasuryCanAutoFund(config: TreasuryConfig): void;
|
|
12
|
+
export declare function buildTreasuryTransferArgs(config: TreasuryConfig, rpcUrl: string, proposalDataHex: string): string[];
|
|
13
|
+
export declare function formatCommand(args: string[]): string;
|
|
14
|
+
export declare function submitTreasuryTransfer(config: TreasuryConfig, rpcUrl: string, proposalDataHex: string): string;
|
|
15
|
+
//# sourceMappingURL=treasury.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treasury.d.ts","sourceRoot":"","sources":["../../src/lib/treasury.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,cAAc,GAAG,IAAI,CAqB9F;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAMtE;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,CAanH;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAEpD;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,CAY9G"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
export function loadTreasuryConfig(env = process.env) {
|
|
3
|
+
const address = env.CKB_FIREWALL_TREASURY_ADDRESS?.trim();
|
|
4
|
+
if (!address)
|
|
5
|
+
return null;
|
|
6
|
+
const outputIndexRaw = env.CKB_FIREWALL_TREASURY_OUTPUT_INDEX?.trim() || "0";
|
|
7
|
+
if (!/^\d+$/.test(outputIndexRaw)) {
|
|
8
|
+
throw new Error("CKB_FIREWALL_TREASURY_OUTPUT_INDEX must be a non-negative integer.");
|
|
9
|
+
}
|
|
10
|
+
const config = {
|
|
11
|
+
address,
|
|
12
|
+
capacity: env.CKB_FIREWALL_TREASURY_CAPACITY?.trim() || "62",
|
|
13
|
+
feeRate: env.CKB_FIREWALL_TREASURY_FEE_RATE?.trim() || "1000",
|
|
14
|
+
outputIndex: Number.parseInt(outputIndexRaw, 10),
|
|
15
|
+
autoAnchor: /^(1|true|yes)$/i.test(env.CKB_FIREWALL_TREASURY_AUTO_ANCHOR?.trim() || ""),
|
|
16
|
+
};
|
|
17
|
+
const fromAccount = env.CKB_FIREWALL_TREASURY_FROM_ACCOUNT?.trim();
|
|
18
|
+
const privkeyPath = env.CKB_FIREWALL_TREASURY_PRIVKEY_PATH?.trim();
|
|
19
|
+
if (fromAccount)
|
|
20
|
+
config.fromAccount = fromAccount;
|
|
21
|
+
if (privkeyPath)
|
|
22
|
+
config.privkeyPath = privkeyPath;
|
|
23
|
+
return config;
|
|
24
|
+
}
|
|
25
|
+
export function assertTreasuryCanAutoFund(config) {
|
|
26
|
+
if (!config.privkeyPath) {
|
|
27
|
+
throw new Error("Treasury auto-funding requires CKB_FIREWALL_TREASURY_PRIVKEY_PATH so the backend can submit without a browser password prompt.");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function buildTreasuryTransferArgs(config, rpcUrl, proposalDataHex) {
|
|
31
|
+
const args = [
|
|
32
|
+
"--url", rpcUrl,
|
|
33
|
+
"wallet", "transfer",
|
|
34
|
+
"--to-address", config.address,
|
|
35
|
+
"--capacity", config.capacity,
|
|
36
|
+
"--to-data", proposalDataHex,
|
|
37
|
+
"--fee-rate", config.feeRate,
|
|
38
|
+
"--output-format", "json",
|
|
39
|
+
];
|
|
40
|
+
if (config.fromAccount)
|
|
41
|
+
args.push("--from-account", config.fromAccount);
|
|
42
|
+
if (config.privkeyPath)
|
|
43
|
+
args.push("--privkey-path", config.privkeyPath);
|
|
44
|
+
return args;
|
|
45
|
+
}
|
|
46
|
+
export function formatCommand(args) {
|
|
47
|
+
return ["ckb-cli", ...args].map((p) => (/\s/.test(p) ? JSON.stringify(p) : p)).join(" ");
|
|
48
|
+
}
|
|
49
|
+
export function submitTreasuryTransfer(config, rpcUrl, proposalDataHex) {
|
|
50
|
+
assertTreasuryCanAutoFund(config);
|
|
51
|
+
const output = execFileSync("ckb-cli", buildTreasuryTransferArgs(config, rpcUrl, proposalDataHex), {
|
|
52
|
+
encoding: "utf8",
|
|
53
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
54
|
+
timeout: 120_000,
|
|
55
|
+
});
|
|
56
|
+
const txHash = output.match(/0x[a-fA-F0-9]{64}/)?.[0];
|
|
57
|
+
if (!txHash) {
|
|
58
|
+
throw new Error(`ckb-cli did not return a transaction hash: ${output.trim()}`);
|
|
59
|
+
}
|
|
60
|
+
return txHash;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=treasury.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treasury.js","sourceRoot":"","sources":["../../src/lib/treasury.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface CellDepJson {
|
|
2
|
+
out_point: {
|
|
3
|
+
tx_hash: string;
|
|
4
|
+
index: string;
|
|
5
|
+
};
|
|
6
|
+
dep_type: "code" | "dep_group";
|
|
7
|
+
}
|
|
8
|
+
export declare function parseCellDepList(values: string[] | undefined, name: string): CellDepJson[];
|
|
9
|
+
//# sourceMappingURL=tx-deps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tx-deps.d.ts","sourceRoot":"","sources":["../../src/lib/tx-deps.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,QAAQ,EAAE,MAAM,GAAG,WAAW,CAAC;CAChC;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAa1F"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function parseCellDepList(values, name) {
|
|
2
|
+
return (values ?? []).map((value) => {
|
|
3
|
+
const raw = value.trim();
|
|
4
|
+
const match = /^(0x[0-9a-fA-F]{64})(?::|#)(\d+)(?::(code|dep_group))?$/.exec(raw);
|
|
5
|
+
if (!match) {
|
|
6
|
+
throw new Error(`${name} must be formatted as <tx-hash>:<index>[:code|dep_group]. Got "${value}".`);
|
|
7
|
+
}
|
|
8
|
+
const index = Number.parseInt(match[2], 10);
|
|
9
|
+
return {
|
|
10
|
+
out_point: { tx_hash: match[1], index: `0x${index.toString(16)}` },
|
|
11
|
+
dep_type: (match[3] ?? "code"),
|
|
12
|
+
};
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=tx-deps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tx-deps.js","sourceRoot":"","sources":["../../src/lib/tx-deps.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,gBAAgB,CAAC,MAA4B,EAAE,IAAY;IACzE,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAClC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,yDAAyD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClF,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,kEAAkE,KAAK,IAAI,CAAC,CAAC;QACtG,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC;QAC7C,OAAO;YACL,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,KAAK,EAAE,KAAK,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE;YACnE,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAyB;SACvD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/lib/witness.d.ts
CHANGED
|
@@ -5,21 +5,23 @@ export interface Gov1BindingParams {
|
|
|
5
5
|
oldRoot: Uint8Array;
|
|
6
6
|
newRoot: Uint8Array;
|
|
7
7
|
}
|
|
8
|
-
export declare function
|
|
9
|
-
|
|
8
|
+
export declare function buildGov1WitnessV4(params: Gov1BindingParams & {
|
|
9
|
+
proposalDataHash: Uint8Array;
|
|
10
|
+
reviewDelayMs: bigint;
|
|
10
11
|
}): Uint8Array;
|
|
11
|
-
export declare function
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
export declare function encodeRelativeTimestampSince(durationMs: bigint): string;
|
|
13
|
+
export interface ValidatorVoteWitnessEntry {
|
|
14
|
+
pubkey: Uint8Array;
|
|
15
|
+
vote: "yes" | "no" | "abstain";
|
|
16
|
+
timestamp: string;
|
|
17
|
+
signature: Uint8Array;
|
|
18
|
+
merkleLeafIndex: number;
|
|
19
|
+
merkleProof: Uint8Array[];
|
|
20
|
+
}
|
|
21
|
+
export declare function buildValidatorVoteWitness(votes: ValidatorVoteWitnessEntry[]): Uint8Array;
|
|
16
22
|
export declare function buildWitnessArgs(params: {
|
|
17
23
|
lock?: Uint8Array;
|
|
18
24
|
inputType?: Uint8Array;
|
|
19
25
|
outputType?: Uint8Array;
|
|
20
26
|
}): Uint8Array;
|
|
21
|
-
export declare function placeholderSigners(count?: 3 | 4 | 5): Array<{
|
|
22
|
-
index: number;
|
|
23
|
-
sig: Uint8Array;
|
|
24
|
-
}>;
|
|
25
27
|
//# sourceMappingURL=witness.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"witness.d.ts","sourceRoot":"","sources":["../../src/lib/witness.ts"],"names":[],"mappings":"AAIA,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAEvD;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,UAAU,CAAC;IAC3B,cAAc,EAAE,UAAU,CAAC;IAC3B,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,UAAU,CAAC;CACrB;AAKD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,iBAAiB,GAAG;IAAE,
|
|
1
|
+
{"version":3,"file":"witness.d.ts","sourceRoot":"","sources":["../../src/lib/witness.ts"],"names":[],"mappings":"AAIA,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAEvD;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,UAAU,CAAC;IAC3B,cAAc,EAAE,UAAU,CAAC;IAC3B,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,UAAU,CAAC;CACrB;AAKD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,iBAAiB,GAAG;IAAE,gBAAgB,EAAE,UAAU,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAClF,UAAU,CA2BZ;AAMD,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAOvE;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,UAAU,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B;AA2BD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,yBAAyB,EAAE,GAAG,UAAU,CAsCxF;AAYD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,GAAG,UAAU,CAqBb"}
|
package/dist/lib/witness.js
CHANGED
|
@@ -3,27 +3,28 @@ const CKB_PERSONALIZATION = new TextEncoder().encode("ckb-default-hash");
|
|
|
3
3
|
export function ckbBlake2b(data) {
|
|
4
4
|
return blake2b(data, { personalization: CKB_PERSONALIZATION, dkLen: 32 });
|
|
5
5
|
}
|
|
6
|
-
// GOV1
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
export function
|
|
6
|
+
// GOV1 v4 — 173 bytes. governance-lock locates the input whose cell data hashes to
|
|
7
|
+
// proposalDataHash and requires that input's `since` field to encode a relative
|
|
8
|
+
// median-time-past delay >= reviewDelayMs.
|
|
9
|
+
export function buildGov1WitnessV4(params) {
|
|
10
10
|
for (const [name, val] of [
|
|
11
11
|
["proposalIdHash", params.proposalIdHash],
|
|
12
12
|
["voteDigestHash", params.voteDigestHash],
|
|
13
13
|
["oldRoot", params.oldRoot],
|
|
14
14
|
["newRoot", params.newRoot],
|
|
15
|
+
["proposalDataHash", params.proposalDataHash],
|
|
15
16
|
]) {
|
|
16
17
|
if (val.length !== 32)
|
|
17
18
|
throw new Error(`${name} must be exactly 32 bytes, got ${val.length}`);
|
|
18
19
|
}
|
|
19
|
-
// 4 magic + 1 version + 32*
|
|
20
|
-
const buf = new Uint8Array(
|
|
20
|
+
// 4 magic + 1 version + 32*5 hashes + 8 reviewDelayMs = 173 bytes
|
|
21
|
+
const buf = new Uint8Array(173);
|
|
21
22
|
let off = 0;
|
|
22
23
|
buf[off++] = 0x47;
|
|
23
24
|
buf[off++] = 0x4f;
|
|
24
25
|
buf[off++] = 0x56;
|
|
25
26
|
buf[off++] = 0x31; // GOV1
|
|
26
|
-
buf[off++] =
|
|
27
|
+
buf[off++] = 0x04; // version 4
|
|
27
28
|
buf.set(params.proposalIdHash, off);
|
|
28
29
|
off += 32;
|
|
29
30
|
buf.set(params.voteDigestHash, off);
|
|
@@ -32,43 +33,40 @@ export function buildGov1WitnessV3(params) {
|
|
|
32
33
|
off += 32;
|
|
33
34
|
buf.set(params.newRoot, off);
|
|
34
35
|
off += 32;
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
buf.set(params.proposalDataHash, off);
|
|
37
|
+
off += 32;
|
|
38
|
+
// reviewDelayMs as LE u64
|
|
39
|
+
let ms = params.reviewDelayMs;
|
|
37
40
|
for (let i = 0; i < 8; i++) {
|
|
38
41
|
buf[off++] = Number(ms & 0xffn);
|
|
39
42
|
ms >>= 8n;
|
|
40
43
|
}
|
|
41
44
|
return buf;
|
|
42
45
|
}
|
|
43
|
-
// Encodes a
|
|
44
|
-
// Format:
|
|
45
|
-
|
|
46
|
+
// Encodes a duration in milliseconds as a CKB relative median-time-past `since` value.
|
|
47
|
+
// Format: bit63=1 (relative), bit62=1 (timestamp metric), bits55-0 = duration_in_SECONDS.
|
|
48
|
+
// CKB consensus enforces timestamp since values in seconds; the governance-lock contract
|
|
49
|
+
// multiplies the since seconds value by 1000 before comparing to review_delay_ms.
|
|
50
|
+
export function encodeRelativeTimestampSince(durationMs) {
|
|
46
51
|
const TIMESTAMP_FLAG = 0x4000000000000000n;
|
|
52
|
+
const RELATIVE_FLAG = 0x8000000000000000n;
|
|
47
53
|
const VALUE_MASK = 0x00ffffffffffffffn;
|
|
48
|
-
const
|
|
54
|
+
const durationSec = durationMs / 1000n; // CKB timestamp since field is in seconds
|
|
55
|
+
const since = RELATIVE_FLAG | TIMESTAMP_FLAG | (durationSec & VALUE_MASK);
|
|
49
56
|
return `0x${since.toString(16).padStart(16, "0")}`;
|
|
50
57
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const buf = new Uint8Array(1 + signers.length * 66);
|
|
64
|
-
buf[0] = signers.length;
|
|
65
|
-
let off = 1;
|
|
66
|
-
for (const s of signers) {
|
|
67
|
-
buf[off++] = s.index;
|
|
68
|
-
buf.set(s.sig, off);
|
|
69
|
-
off += 65;
|
|
70
|
-
}
|
|
71
|
-
return buf;
|
|
58
|
+
function voteCode(vote) {
|
|
59
|
+
if (vote === "yes")
|
|
60
|
+
return 1;
|
|
61
|
+
if (vote === "no")
|
|
62
|
+
return 2;
|
|
63
|
+
if (vote === "abstain")
|
|
64
|
+
return 3;
|
|
65
|
+
throw new Error(`unsupported vote: ${vote}`);
|
|
66
|
+
}
|
|
67
|
+
function writeU16LE(buf, offset, value) {
|
|
68
|
+
buf[offset] = value & 0xff;
|
|
69
|
+
buf[offset + 1] = (value >> 8) & 0xff;
|
|
72
70
|
}
|
|
73
71
|
function writeU32LE(buf, offset, value) {
|
|
74
72
|
buf[offset] = value & 0xff;
|
|
@@ -76,6 +74,59 @@ function writeU32LE(buf, offset, value) {
|
|
|
76
74
|
buf[offset + 2] = (value >> 16) & 0xff;
|
|
77
75
|
buf[offset + 3] = (value >> 24) & 0xff;
|
|
78
76
|
}
|
|
77
|
+
// Builds WitnessArgs.lock content for validator-authorized governance updates.
|
|
78
|
+
// Format:
|
|
79
|
+
// vote_count(1)
|
|
80
|
+
// repeated:
|
|
81
|
+
// pubkey(33) | vote(1) | timestamp_len(2 LE) | timestamp_utf8 |
|
|
82
|
+
// signature(65) | merkle_leaf_index(4 LE) | proof_count(1) | proof_hash(32)*
|
|
83
|
+
export function buildValidatorVoteWitness(votes) {
|
|
84
|
+
if (votes.length > 255)
|
|
85
|
+
throw new Error("vote_count must fit in 1 byte (max 255)");
|
|
86
|
+
const enc = new TextEncoder();
|
|
87
|
+
const parts = votes.map((v) => {
|
|
88
|
+
if (v.pubkey.length !== 33)
|
|
89
|
+
throw new Error(`validator pubkey must be 33 bytes, got ${v.pubkey.length}`);
|
|
90
|
+
if (v.signature.length !== 65)
|
|
91
|
+
throw new Error(`vote signature must be 65 bytes, got ${v.signature.length}`);
|
|
92
|
+
if (!Number.isInteger(v.merkleLeafIndex) || v.merkleLeafIndex < 0 || v.merkleLeafIndex > 0xffff_ffff) {
|
|
93
|
+
throw new Error(`merkle leaf index out of range: ${v.merkleLeafIndex}`);
|
|
94
|
+
}
|
|
95
|
+
if (v.merkleProof.length > 255)
|
|
96
|
+
throw new Error("merkle proof length must fit in 1 byte");
|
|
97
|
+
for (const proof of v.merkleProof) {
|
|
98
|
+
if (proof.length !== 32)
|
|
99
|
+
throw new Error(`merkle proof hash must be 32 bytes, got ${proof.length}`);
|
|
100
|
+
}
|
|
101
|
+
const timestamp = enc.encode(v.timestamp);
|
|
102
|
+
if (timestamp.length > 100)
|
|
103
|
+
throw new Error("timestamp is too long (max 100 bytes); governance-lock enforces this limit on-chain");
|
|
104
|
+
return { v, timestamp };
|
|
105
|
+
});
|
|
106
|
+
const size = 1 + parts.reduce((sum, p) => sum + 33 + 1 + 2 + p.timestamp.length + 65 + 4 + 1 + p.v.merkleProof.length * 32, 0);
|
|
107
|
+
const buf = new Uint8Array(size);
|
|
108
|
+
buf[0] = votes.length;
|
|
109
|
+
let off = 1;
|
|
110
|
+
for (const { v, timestamp } of parts) {
|
|
111
|
+
buf.set(v.pubkey, off);
|
|
112
|
+
off += 33;
|
|
113
|
+
buf[off++] = voteCode(v.vote);
|
|
114
|
+
writeU16LE(buf, off, timestamp.length);
|
|
115
|
+
off += 2;
|
|
116
|
+
buf.set(timestamp, off);
|
|
117
|
+
off += timestamp.length;
|
|
118
|
+
buf.set(v.signature, off);
|
|
119
|
+
off += 65;
|
|
120
|
+
writeU32LE(buf, off, v.merkleLeafIndex);
|
|
121
|
+
off += 4;
|
|
122
|
+
buf[off++] = v.merkleProof.length;
|
|
123
|
+
for (const proof of v.merkleProof) {
|
|
124
|
+
buf.set(proof, off);
|
|
125
|
+
off += 32;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return buf;
|
|
129
|
+
}
|
|
79
130
|
function bytesOpt(data) {
|
|
80
131
|
if (!data)
|
|
81
132
|
return new Uint8Array(0);
|
|
@@ -105,18 +156,4 @@ export function buildWitnessArgs(params) {
|
|
|
105
156
|
buf.set(outputTypeOpt, offOutputType);
|
|
106
157
|
return buf;
|
|
107
158
|
}
|
|
108
|
-
// FOR UNIT TESTING ONLY — generates structurally-valid but cryptographically fake signatures.
|
|
109
|
-
// governance-lock verifies secp256k1 signatures on-chain for GOV1 v3; these WILL be rejected by the chain.
|
|
110
|
-
// Never use in a real governance transaction. Only valid in test environments that mock the contract.
|
|
111
|
-
export function placeholderSigners(count = 3) {
|
|
112
|
-
return Array.from({ length: count }, (_, i) => ({
|
|
113
|
-
index: i,
|
|
114
|
-
sig: new Uint8Array(65).fill(0x11), // non-zero placeholder; recovery id corrected to 0x00 below
|
|
115
|
-
})).map((s) => {
|
|
116
|
-
// Recovery id must be 0-3. Set last byte to 0.
|
|
117
|
-
const sig = new Uint8Array(s.sig);
|
|
118
|
-
sig[64] = 0x00;
|
|
119
|
-
return { index: s.index, sig };
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
159
|
//# sourceMappingURL=witness.js.map
|
package/dist/lib/witness.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"witness.js","sourceRoot":"","sources":["../../src/lib/witness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,MAAM,mBAAmB,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAEzE,MAAM,UAAU,UAAU,CAAC,IAAgB;IACzC,OAAO,OAAO,CAAC,IAAI,EAAE,EAAE,eAAe,EAAE,mBAAmB,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;AAC5E,CAAC;AASD,
|
|
1
|
+
{"version":3,"file":"witness.js","sourceRoot":"","sources":["../../src/lib/witness.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckb-firewall/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "CLI for managing the CKB Transaction Firewall blacklist registry",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
17
|
"build": "tsc -p tsconfig.build.json",
|
|
18
|
-
"postbuild": "node -e \"require('fs').chmodSync('dist/index.js', 0o755)\"",
|
|
18
|
+
"postbuild": "node -e \"require('fs').chmodSync('dist/index.js', 0o755)\" && node scripts/build-gui.js",
|
|
19
19
|
"prepack": "npm run build",
|
|
20
20
|
"test": "npm run build && node --test test/*.test.mjs",
|
|
21
21
|
"typecheck": "tsc --noEmit",
|