Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BREAKING CHANGE: drop all fs related support #684

Merged
merged 9 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/afraid-planes-greet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@ckb-lumos/config-manager": minor
"@ckb-lumos/hd": minor
---

**BREAKING CHANGE**: remove filesystem support
5 changes: 5 additions & 0 deletions .changeset/khaki-brooms-swim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ckb-lumos/hd-cache": minor
---

**BREAKING CHANGE**: replace the loadFromKeystore with loadFromKeystoreJson
3 changes: 3 additions & 0 deletions .eslintrc.next.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ module.exports = {
{
ignoreEnums: true,
ignoreArrayIndexes: true,
ignoreClassFieldInitialValues: true,
ignoreDefaultValues: true,
ignore: [
-1, // index -1 is not found
0, // first element of an array
1, // common for i + 1 in a loop
2, // many .slice(2) since the '0x' prefix should be removed while calling 3rd-party library
16, // toString(16)
1000, // second to millisecond
],
},
],
Expand Down
62 changes: 21 additions & 41 deletions packages/base/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { BI, BIish } from "@ckb-lumos/bi";
import * as blockchain from "./blockchain";
import { Script, Input } from "./api";
import { Hash, HexNumber, HexString } from "./primitive";
import { Uint128LE, Uint64LE } from "@ckb-lumos/codec/lib/number";

type CKBHasherOptions = {
outLength?: number;
Expand Down Expand Up @@ -39,12 +40,27 @@ class CKBHasher {
}
}

/**
* create a 32-bytes Blake2b hash with the CKB personalization
* @param data
*/
function ckbHash(data: BytesLike): Hash {
const hasher = new CKBHasher();
hasher.update(bytes.bytify(data));
return hasher.digestHex();
}

/**
* create a 20-bytes Blake2b hash with the CKB personalization
* @param data
*/
function ckbHash160(data: BytesLike): Hash {
// 2 for prefix 0x
// 40 for 20-bytes hex string
const hash160HexLength = 42;
return ckbHash(data).slice(0, hash160HexLength);
}

/**
* compute lock/type hash
*
Expand All @@ -68,12 +84,7 @@ function toBigUInt64LE(num: BIish): HexString {
}

function toBigUInt64LECompatible(num: BIish): HexString {
num = BI.from(num);
const buf = Buffer.alloc(8);
buf.writeUInt32LE(num.and("0xffffffff").toNumber(), 0);
num = num.shr(32);
buf.writeUInt32LE(num.and("0xffffffff").toNumber(), 4);
return `0x${buf.toString("hex")}`;
return bytes.hexify(Uint64LE.pack(num));
}

/**
Expand All @@ -90,8 +101,7 @@ function readBigUInt64LE(hex: HexString): bigint {
* @deprecated please follow the {@link https://lumos-website.vercel.app/migrations/migrate-to-v0.19 migration-guide}
*/
function readBigUInt64LECompatible(hex: HexString): BI {
const buf = Buffer.from(hex.slice(2), "hex");
return BI.from(buf.readUInt32LE()).add(BI.from(buf.readUInt32LE(4)).shl(32));
return Uint64LE.unpack(hex);
}

// const U128_MIN = BigInt(0);
Expand All @@ -106,29 +116,8 @@ function toBigUInt128LE(u128: BIish): string {
return toBigUInt128LECompatible(u128);
}

const U128_MIN_COMPATIBLE = BI.from(0);
const U128_MAX_COMPATIBLE = BI.from("340282366920938463463374607431768211455");
function toBigUInt128LECompatible(num: BIish): HexNumber {
num = BI.from(num);
if (num.lt(U128_MIN_COMPATIBLE)) {
throw new Error(`u128 ${num} too small`);
}

if (num.gt(U128_MAX_COMPATIBLE)) {
throw new Error(`u128 ${num} too large`);
}

const buf = Buffer.alloc(16);
buf.writeUInt32LE(num.and(0xffffffff).toNumber(), 0);
num = num.shr(32);
buf.writeUInt32LE(num.and(0xffffffff).toNumber(), 4);

num = num.shr(32);
buf.writeUInt32LE(num.and(0xffffffff).toNumber(), 8);

num = num.shr(32);
buf.writeUInt32LE(num.and(0xffffffff).toNumber(), 12);
return `0x${buf.toString("hex")}`;
return bytes.hexify(Uint128LE.pack(num));
}

/**
Expand All @@ -145,17 +134,7 @@ function readBigUInt128LE(leHex: HexString): bigint {
* @deprecated please follow the {@link https://lumos-website.vercel.app/migrations/migrate-to-v0.19 migration-guide}
*/
function readBigUInt128LECompatible(leHex: HexString): BI {
if (leHex.length < 34 || !leHex.startsWith("0x")) {
throw new Error(`leHex format error`);
}

const buf = Buffer.from(leHex.slice(2, 34), "hex");

return BI.from(buf.readUInt32LE(0))
.shl(0)
.add(BI.from(buf.readUInt32LE(4)).shl(32))
.add(BI.from(buf.readUInt32LE(8)).shl(64))
.add(BI.from(buf.readUInt32LE(12)).shl(96));
return Uint128LE.unpack(leHex);
}

function assertHexString(debugPath: string, str: string): void {
Expand Down Expand Up @@ -278,6 +257,7 @@ function deepCamelizeTransaction(data: any): any {
export {
CKBHasher,
ckbHash,
ckbHash160,
deepCamel,
deepCamelizeTransaction,
toBigUInt64LE,
Expand Down
55 changes: 7 additions & 48 deletions packages/config-manager/src/manager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import deepFreeze from "deep-freeze-strict";
import { logger } from "@ckb-lumos/base";
import { Config } from "./types";
import { predefined } from "./predefined";

Expand All @@ -11,7 +10,10 @@ function assertHexString(debugPath: string, string: string) {

function assertHash(debugPath: string, hash: string) {
assertHexString(debugPath, hash);
if (hash.length != 66) {
// 2 for 0x
// 64 for 32 bytes in hex format
const hashHexLength = 66;
if (hash.length !== hashHexLength) {
throw new Error(`${debugPath} must be a hex string of 66 characters long!`);
}
}
Expand Down Expand Up @@ -77,50 +79,7 @@ export function getConfig(): Config {
return config;
}

/**
* Initialize current app with a config. The initializaton steps work as follows:
* 1. If `LUMOS_CONFIG_NAME` environment variable is set to a predefined config,
* the predefined config is loaded;
* 2. If `LUMOS_CONFIG_FILE` environment variable is set, it will be used as the
* name of a file containing the Config to use.
* 3. A file named `config.json` in current running directory will be used as the
* file containing the Config to use.
* @deprecated
* @returns void
*/
function initializeConfigLegacy() {
const env = process?.env;
const configName = env?.LUMOS_CONFIG_NAME;

if (
(configName === "LINA" || configName === "AGGRON4") &&
predefined[configName]
) {
config = predefined[configName];
return;
}

const configFile = env?.LUMOS_CONFIG_FILE;
const configFilename = configFile || "config.json";
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const data = require("fs").readFileSync(configFilename);
const loadedConfig = JSON.parse(data);
validateConfig(loadedConfig);
config = deepFreeze(loadedConfig);
} catch (e) {
throw new Error(`Error loading config from file ${configFilename}: ${e}`);
}
}

export function initializeConfig(inputConfig?: Config): void {
if (!inputConfig) {
logger.deprecated(
"initializeConfig with env will be deprecated, please migrate to initializeConfig(...)"
);
initializeConfigLegacy();
} else {
validateConfig(inputConfig);
config = deepFreeze(inputConfig);
}
export function initializeConfig(inputConfig: Config): void {
validateConfig(inputConfig);
config = deepFreeze(inputConfig);
}
18 changes: 0 additions & 18 deletions packages/config-manager/tests/manager.test.ts

This file was deleted.

1 change: 1 addition & 0 deletions packages/hd-cache/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@ckb-lumos/base": "0.22.2",
"@ckb-lumos/bi": "0.22.2",
"@ckb-lumos/ckb-indexer": "0.22.2",
"@ckb-lumos/codec": "0.22.2",
"@ckb-lumos/config-manager": "0.22.2",
"@ckb-lumos/hd": "0.22.2",
"@ckb-lumos/rpc": "0.22.2",
Expand Down
56 changes: 29 additions & 27 deletions packages/hd-cache/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import {
Cell,
CellCollector as CellCollectorInterface,
HashType,
helpers,
HexString,
Script,
Cell,
Indexer,
OutPoint,
Output,
QueryOptions,
Script,
Transaction,
Output,
CellCollector as CellCollectorInterface,
helpers,
utils,
Indexer,
TransactionWithStatus,
TransactionCollector as BaseTransactionCollector,
TransactionWithStatus,
utils,
} from "@ckb-lumos/base";
import { Map, Set } from "immutable";
import { Config, getConfig } from "@ckb-lumos/config-manager";
Expand All @@ -25,8 +25,11 @@ import {
Keystore,
mnemonic,
} from "@ckb-lumos/hd";
import { assertPublicKey, assertChainCode } from "@ckb-lumos/hd/lib/helper";
import { assertChainCode, assertPublicKey } from "@ckb-lumos/hd/lib/helper";
import { BI } from "@ckb-lumos/bi";
import { bytes } from "@ckb-lumos/codec";
import { Uint8 } from "@ckb-lumos/codec/lib/number";

const { isCellMatchQueryOptions } = helpers;
const { publicKeyToBlake160 } = key;
const { mnemonicToSeedSync } = mnemonic;
Expand Down Expand Up @@ -485,18 +488,15 @@ export function publicKeyToMultisigArgs(publicKey: HexString): HexString {
const M = 1;
const publicKeyHashes = [blake160];

const serialized =
"0x00" +
("00" + R.toString(16)).slice(-2) +
("00" + M.toString(16)).slice(-2) +
("00" + publicKeyHashes.length.toString(16)).slice(-2) +
publicKeyHashes.map((h) => h.slice(2)).join("");

const args = new utils.CKBHasher()
.update(serialized)
.digestHex()
.slice(0, 42);
return args;
const serialized = bytes.concat(
[0],
Uint8.pack(R),
Uint8.pack(M),
Uint8.pack(publicKeyHashes.length),
...publicKeyHashes
);

return utils.ckbHash160(serialized);
}

export function getDefaultInfos(
Expand Down Expand Up @@ -581,18 +581,20 @@ export class CacheManager {
}

/**
* Load from keystore, if needMasterPublicKey set to true or origin = "ckb-cli",
* will enable masterPublicKey
* Load from keystore file that is saved with the JSON format
*
* If `needMasterPublicKey` is true or origin = "ckb-cli",
* the master key will be required in the JSON file
*
* @param indexer
* @param path
* @param json Keystore formatted JSON
* @param password
* @param infos
* @param options
*/
static loadFromKeystore(
static loadFromKeystoreJson(
indexer: Indexer,
path: string,
json: string,
password: string,
infos: LockScriptMappingInfo[] = getDefaultInfos(),
options: {
Expand All @@ -604,7 +606,7 @@ export class CacheManager {
rpc?: RPC;
}
): CacheManager {
const keystore = Keystore.load(path);
const keystore = Keystore.fromJson(json);
const extendedPrivateKey = keystore.extendedPrivateKey(password);
const accountExtendedPublicKey =
extendedPrivateKey.toAccountExtendedPublicKey();
Expand Down
9 changes: 6 additions & 3 deletions packages/hd-cache/tests/cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import { BI } from "@ckb-lumos/bi";
import { stub } from "sinon";
import { Indexer } from "@ckb-lumos/ckb-indexer";
import * as fs from "node:fs";

const mockTxs: TransactionWithStatus[] = [
{
Expand Down Expand Up @@ -205,7 +206,7 @@ class MockTransactionCollector extends BaseIndexerModule.TransactionCollector {
}
}

stub(rpc, "getHeader").callsFake((blockHash) => {
stub(rpc, "getHeader").callsFake((blockHash) => {
return Promise.resolve({ ...headerData, ...{ hash: blockHash } });
});
const tipStub = stub(indexer, "tip");
Expand Down Expand Up @@ -310,9 +311,11 @@ test("getMasterPublicKeyInfo, needMasterPublicKey", async (t) => {
});

test("loadFromKeystore, ckb-cli", async (t) => {
const cacheManager = CacheManager.loadFromKeystore(
const cacheManager = CacheManager.loadFromKeystoreJson(
indexer,
__dirname + "/fixtures/ckb_cli_keystore.json",
fs
.readFileSync(__dirname + "/fixtures/ckb_cli_keystore.json")
.toString("utf8"),
"aaaaaa",
getDefaultInfos(),
{
Expand Down
Loading
Loading