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: replace Buffer with Uint8Array #713

Merged
merged 3 commits into from
Jun 13, 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
2 changes: 1 addition & 1 deletion packages/base/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ function computeScriptHash(script: Script): string {
return ckbHash(blockchain.Script.pack(script));
}

function hashCode(buffer: Buffer): number {
function hashCode(buffer: Uint8Array): number {
return xxHash32(buffer, 0);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/base/src/values.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
}

hashCode(): number {
return xxHash32(Buffer.from(this.buffer), 0);
return xxHash32(this.buffer, 0);

Check warning on line 19 in packages/base/src/values.ts

View check run for this annotation

Codecov / codecov/patch

packages/base/src/values.ts#L19

Added line #L19 was not covered by tests
}

hash(): Hash {
Expand Down
3 changes: 2 additions & 1 deletion packages/base/tests/utils.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const test = require("ava");
const { bytes } = require("@ckb-lumos/codec");

const {
CKBHasher,
Expand Down Expand Up @@ -63,7 +64,7 @@ test("computeScriptHash", (t) => {
});

test("hashCode, should return same hash if same input", (t) => {
const buffer = Buffer.from("1234ab", "hex");
const buffer = bytes.bytify("0x1234ab");
t.is(hashCode(buffer), hashCode(buffer));
});

Expand Down
5 changes: 2 additions & 3 deletions packages/codec/examples/custom-codec-utf8string.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { molecule, bytes } from "../src";
import { Buffer } from "buffer"; // https://github.com/feross/buffer

const UTF8String = molecule.byteVecOf<string>({
pack: (str) => Buffer.from(str, "utf8"),
unpack: (buf) => Buffer.from(bytes.bytify(buf)).toString("utf8"),
pack: (str) => new TextEncoder().encode(str),
unpack: (buf) => new TextDecoder().decode(bytes.bytify(buf)),
});

const packed = UTF8String.pack("hello world, 你好世界");
Expand Down
4 changes: 2 additions & 2 deletions packages/codec/examples/rpc-character.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ const SwordMaterial = byteOf<Material>({
});

const UTF8String = byteVecOf<string>({
pack: (str) => Uint8Array.from(Buffer.from(str, "utf8")),
unpack: (buf) => Buffer.from(bytes.bytify(buf)).toString("utf8"),
pack: (str) => new TextEncoder().encode(str),
unpack: (buf) => new TextDecoder().decode(bytes.bytify(buf)),
});

/***** molecule binding *****/
Expand Down
12 changes: 7 additions & 5 deletions packages/common-scripts/examples/pw_lock/lock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ import {
TransactionSkeletonType,
createTransactionFromSkeleton,
} from "@ckb-lumos/helpers";
import { bytes } from "@ckb-lumos/codec";
import { keccak256 } from "@ckb-lumos/crypto"
import { getConfig, Config, initializeConfig } from "@ckb-lumos/config-manager";
import { Set } from "immutable";
import keccak, { Keccak } from "keccak";

const { ScriptValue } = values;
const { bytify, hexify } = bytes;

// https://github.com/lay2dev/pw-lock/commit/b447c2bb3f855e933e36212b45af4dec92adf705 pw-lock is a lock script which uses secp256k1_keccak256 algorithm.

Expand Down Expand Up @@ -238,21 +240,21 @@ async function setupInputCell(

// It's a secp256k1_keccak256 sighash all lock script, so we need a keccak256 hash method.
class Keccak256Hasher {
private hasher: Keccak;
private hasher: ReturnType<typeof keccak256.create>;

constructor() {
this.hasher = keccak("keccak256");
this.hasher = keccak256.create();
}

update(data: string | ArrayBuffer | Reader): this {
const reader = new Reader(data);
const array: Buffer = Buffer.from(reader.serializeJson().slice(2), "hex");
const array = bytify(reader.serializeJson());
this.hasher.update(array);
return this;
}

digestReader(): Reader {
const hex = "0x" + this.hasher.digest("hex").toString();
const hex = hexify(this.hasher.digest())
return new Reader(hex);
}

Expand Down
3 changes: 1 addition & 2 deletions packages/common-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@ckb-lumos/base": "0.23.0",
"@ckb-lumos/bi": "0.23.0",
"@ckb-lumos/codec": "0.23.0",
"@ckb-lumos/crypto": "0.23.0",
"@ckb-lumos/config-manager": "0.23.0",
"@ckb-lumos/helpers": "0.23.0",
"@ckb-lumos/rpc": "0.23.0",
Expand Down Expand Up @@ -58,9 +59,7 @@
"@ckb-lumos/crypto": "0.23.0",
"@ckb-lumos/debugger": "0.23.0",
"@ckb-lumos/hd": "0.23.0",
"@types/keccak": "^3.0.1",
"@unisat/wallet-sdk": "^1.1.2",
"keccak": "^3.0.1",
"tweetnacl": "^1.0.3"
},
"publishConfig": {
Expand Down
6 changes: 3 additions & 3 deletions packages/common-scripts/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ function generateLockScriptInfos({ config = undefined }: Options = {}): void {
};

const configHashCode: number = utils.hashCode(
Buffer.from(JSON.stringify(config))
new TextEncoder().encode(JSON.stringify(config))
);

if (lockScriptInfos.infos.length === 0) {
Expand Down Expand Up @@ -931,8 +931,8 @@ function getTransactionSize(txSkeleton: TransactionSkeletonType): number {

function getTransactionSizeByTx(tx: Transaction): number {
const serializedTx = blockchain.Transaction.pack(tx);
// 4 is serialized offset bytesize
const size = serializedTx.byteLength + 4;
const offset = 4; // 4 is serialized offset bytesize
const size = serializedTx.byteLength + offset;
return size;
}

Expand Down
6 changes: 3 additions & 3 deletions packages/common-scripts/tests/p2pkh.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import test from "ava";
import { Script, utils } from "@ckb-lumos/base";
import { default as createKeccak } from "keccak";
import { keccak256 } from "@ckb-lumos/crypto";
import { createP2PKHMessageGroup } from "../src/p2pkh";
import { txObject, txSkeletonFromJson } from "./helper";
import p2pkhJson from "./p2pkh.json";
Expand Down Expand Up @@ -35,13 +35,13 @@ test("pw lock [g1]", (t) => {
SIGNATURE_PLACEHOLDER
);

const keccak = createKeccak("keccak256");
const keccak = keccak256.create();
const signLock = p2pkhJson["PW_LOCK_[G1]"].SIGN_LOCK as Script;

const messageGroup = createP2PKHMessageGroup(tx, [signLock], {
hasher: {
update: (message) => {
keccak.update(Buffer.from(new Uint8Array(message)));
keccak.update(new Uint8Array(message));
},
digest: () => keccak.digest(),
},
Expand Down
4 changes: 2 additions & 2 deletions packages/common-scripts/tests/sudt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -667,9 +667,9 @@ test("transfer secp => secp, change to acp and has previous output, split change

test("pack and unpack sudt amount", (t) => {
const unpacked = BI.from(0x1234);
const packed = Buffer.alloc(16);
const packed = new Uint8Array(16);
// little endian of 0x1234
packed.write("3412", "hex");
packed.set([0x34, 0x12]);

t.true(bytes.equal(packAmount(unpacked), packed));
t.true(unpackAmount(packed).eq(unpacked));
Expand Down
3 changes: 2 additions & 1 deletion packages/debugger/src/executor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DataLoader, ExecuteResult, Executor } from "./types";
import { TransactionSkeletonType } from "@ckb-lumos/helpers";
import { randomBytes } from "@ckb-lumos/crypto";
import { bytes } from "@ckb-lumos/codec";
import { spawnSync } from "child_process";
import { Hash } from "@ckb-lumos/base";
import * as fs from "fs";
Expand Down Expand Up @@ -52,7 +53,7 @@ export class CKBDebugger implements Executor {
private saveTmpTxFile(txSkeleton: TransactionSkeletonType): string {
const debuggerData = parseDebuggerData(txSkeleton, this.loader);
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
const randomHex = Buffer.from(randomBytes(18)).toString("hex");
const randomHex = bytes.hexify(randomBytes(18)).slice(2);
const tempFileName = `lumos-debugger-data-${randomHex}`;
const tmpTxPath = path.join(os.tmpdir(), `${tempFileName}.json`);
fs.writeFileSync(tmpTxPath, JSON.stringify(debuggerData));
Expand Down
2 changes: 1 addition & 1 deletion packages/hd/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
"dependencies": {
"@ckb-lumos/base": "0.23.0",
"@ckb-lumos/bi": "0.23.0",
"@ckb-lumos/codec": "0.23.0",
"@ckb-lumos/crypto": "0.23.0",
"bn.js": "^5.1.3",
"elliptic": "^6.5.4",
"scrypt-js": "^3.0.1",
"uuid": "^8.3.0"
},
"repository": {
Expand Down
40 changes: 22 additions & 18 deletions packages/hd/src/extended_key.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
/* eslint-disable @typescript-eslint/no-magic-numbers */
import Keychain from "./keychain";
import key, { privateToPublic } from "./key";
import { bytes } from "@ckb-lumos/codec";
import { utils, HexString } from "@ckb-lumos/base";
import { privateToPublic, publicKeyToBlake160 } from "./key";
import { assertPublicKey, assertChainCode, assertPrivateKey } from "./helper";

const { bytify, hexify } = bytes;

export enum AddressType {
Receiving = 0,
Change = 1,
Expand Down Expand Up @@ -55,19 +59,19 @@ export class AccountExtendedPublicKey extends ExtendedPublicKey {

publicKeyInfo(type: AddressType, index: number): PublicKeyInfo {
const publicKey: string = this.getPublicKey(type, index);
const blake160: string = key.publicKeyToBlake160(publicKey);
const blake160: string = publicKeyToBlake160(publicKey);
return {
publicKey,
blake160,
path: AccountExtendedPublicKey.pathFor(type, index),
};
}

public static pathForReceiving(index: number) {
public static pathForReceiving(index: number): string {
return AccountExtendedPublicKey.pathFor(AddressType.Receiving, index);
}

public static pathForChange(index: number) {
public static pathForChange(index: number): string {
return AccountExtendedPublicKey.pathFor(AddressType.Change, index);
}

Expand All @@ -77,14 +81,14 @@ export class AccountExtendedPublicKey extends ExtendedPublicKey {

private getPublicKey(type = AddressType.Receiving, index: number): HexString {
const keychain = Keychain.fromPublicKey(
Buffer.from(this.publicKey.slice(2), "hex"),
Buffer.from(this.chainCode.slice(2), "hex"),
bytify(this.publicKey),
bytify(this.chainCode),
AccountExtendedPublicKey.ckbAccountPath
)
.deriveChild(type, false)
.deriveChild(index, false);

return "0x" + keychain.publicKey.toString("hex");
return hexify(keychain.publicKey);
}
}

Expand Down Expand Up @@ -117,24 +121,24 @@ export class ExtendedPrivateKey {

toAccountExtendedPublicKey(): AccountExtendedPublicKey {
const masterKeychain = new Keychain(
Buffer.from(this.privateKey.slice(2), "hex"),
Buffer.from(this.chainCode.slice(2), "hex")
bytify(this.privateKey),
bytify(this.chainCode)
);
const accountKeychain = masterKeychain.derivePath(
AccountExtendedPublicKey.ckbAccountPath
);

return new AccountExtendedPublicKey(
"0x" + accountKeychain.publicKey.toString("hex"),
"0x" + accountKeychain.chainCode.toString("hex")
hexify(accountKeychain.publicKey),
hexify(accountKeychain.chainCode)
);
}

static fromSeed(seed: Buffer): ExtendedPrivateKey {
static fromSeed(seed: Uint8Array): ExtendedPrivateKey {
const keychain = Keychain.fromSeed(seed);
return new ExtendedPrivateKey(
"0x" + keychain.privateKey.toString("hex"),
"0x" + keychain.chainCode.toString("hex")
hexify(keychain.privateKey),
hexify(keychain.chainCode)
);
}

Expand All @@ -145,8 +149,8 @@ export class ExtendedPrivateKey {

privateKeyInfoByPath(path: string): PrivateKeyInfo {
const keychain = new Keychain(
Buffer.from(this.privateKey.slice(2), "hex"),
Buffer.from(this.chainCode.slice(2), "hex")
bytify(this.privateKey),
bytify(this.chainCode)
).derivePath(path);

return this.privateKeyInfoFromKeychain(keychain, path);
Expand All @@ -157,8 +161,8 @@ export class ExtendedPrivateKey {
path: string
): PrivateKeyInfo {
return {
privateKey: "0x" + keychain.privateKey.toString("hex"),
publicKey: "0x" + keychain.publicKey.toString("hex"),
privateKey: hexify(keychain.privateKey),
publicKey: hexify(keychain.publicKey),
path: path,
};
}
Expand Down
33 changes: 18 additions & 15 deletions packages/hd/src/key.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
/* eslint-disable @typescript-eslint/no-magic-numbers */
import { bytes } from "@ckb-lumos/codec";
import { HexString, utils } from "@ckb-lumos/base";
import { ec as EC, SignatureInput } from "elliptic";
import { assertPrivateKey, assertPublicKey } from "./helper";

const { bytify } = bytes;
const ec = new EC("secp256k1");

export function signRecoverable(
Expand Down Expand Up @@ -31,40 +34,40 @@
utils.assertHexString("message", message);
utils.assertHexString("signature", signature);

const msgBuffer = Buffer.from(message.slice(2), "hex");
const sigBuffer = Buffer.from(signature.slice(2), "hex");
const msg = bytify(message);
const sig = bytify(signature);

const sign: SignatureInput = {
r: sigBuffer.slice(0, 32),
s: sigBuffer.slice(32, 64),
recoveryParam: sigBuffer[64],
r: sig.slice(0, 32),
s: sig.slice(32, 64),
recoveryParam: sig[64],
};

const point = ec.recoverPubKey(msgBuffer, sign, sign.recoveryParam!);
const point = ec.recoverPubKey(msg, sign, sign.recoveryParam!);

Check warning on line 46 in packages/hd/src/key.ts

View workflow job for this annotation

GitHub Actions / lint-staged

Forbidden non-null assertion
const publicKey = "0x" + point.encode("hex", true).toLowerCase();
return publicKey;
}

export function privateToPublic(privateKey: Buffer): Buffer;
export function privateToPublic(privateKey: HexString): HexString;
export function privateToPublic(privateKey: Uint8Array): Uint8Array;

export function privateToPublic(
privateKey: Buffer | HexString
): Buffer | HexString {
let pkBuffer = privateKey;
privateKey: Uint8Array | HexString
): Uint8Array | HexString {
let pk = privateKey;
if (typeof privateKey === "string") {
assertPrivateKey(privateKey);
pkBuffer = Buffer.from(privateKey.slice(2), "hex");
pk = bytify(privateKey);
}
if (pkBuffer.length !== 32) {
if (pk.length !== 32) {
throw new Error("Private key must be 32 bytes!");
}

const publickey = ec.keyFromPrivate(pkBuffer).getPublic(true, "hex");
const publickey = "0x" + ec.keyFromPrivate(pk).getPublic(true, "hex");
if (typeof privateKey === "string") {
return "0x" + publickey;
return publickey;
}
return Buffer.from(publickey, "hex");
return bytify(publickey);
}

export function publicKeyToBlake160(publicKey: HexString): HexString {
Expand Down
Loading
Loading