UNPKG

@planetarium/account

Version:
371 lines (362 loc) 11.8 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw new Error('Dynamic require of "' + x + '" is not supported'); }); var __accessCheck = (obj, member, msg) => { if (!member.has(obj)) throw TypeError("Cannot " + msg); }; var __privateGet = (obj, member, getter) => { __accessCheck(obj, member, "read from private field"); return getter ? getter.call(obj) : member.get(obj); }; var __privateAdd = (obj, member, value) => { if (member.has(obj)) throw TypeError("Cannot add the same private member more than once"); member instanceof WeakSet ? member.add(obj) : member.set(obj, value); }; var __privateSet = (obj, member, value, setter) => { __accessCheck(obj, member, "write to private field"); setter ? setter.call(obj, value) : member.set(obj, value); return value; }; var __privateMethod = (obj, member, method) => { __accessCheck(obj, member, "access private method"); return method; }; // src/Account.ts function isAccount(account) { return typeof account === "object" && account != null && "getAddress" in account && account.getAddress instanceof Function && "getPublicKey" in account && account.getPublicKey instanceof Function && "sign" in account && account.sign instanceof Function; } __name(isAccount, "isAccount"); // src/Address.ts import { Buffer as Buffer3 } from "buffer"; import { keccak_256 } from "@noble/hashes/sha3"; // src/PublicKey.ts import { Buffer as Buffer2 } from "buffer"; import * as secp256k12 from "@noble/secp256k1"; // src/Message.ts import { sha256 } from "@noble/hashes/sha256"; async function hashMessage(message) { return sha256(message); } __name(hashMessage, "hashMessage"); // src/Signature.ts import * as secp256k1 from "@noble/secp256k1"; var Signature2 = class { #signature; constructor(signature) { if (signature.hasHighS()) throw new RangeError( "A signature with high S is unsupported; normalize it to get rid of high S" ); this.#signature = signature; } static fromBytes(bytes) { return new Signature2(secp256k1.Signature.fromDER(bytes)); } static fromHex(hex) { return new Signature2(secp256k1.Signature.fromDER(hex)); } toBytes() { return this.#signature.toDERRawBytes(); } toHex() { return this.#signature.toDERHex(); } toString() { return this.toHex(); } [Symbol.for("nodejs.util.inspect.custom")]() { return `Signature { ${this.toHex()} }`; } }; __name(Signature2, "Signature"); var Signature_default = Signature2; // src/PublicKey.ts var PublicKey = class { #point; constructor(point) { this.#point = point; } static fromBytes(bytes, form) { if (!(bytes instanceof Uint8Array)) { throw new Error(`Expected a Uint8Array, but got ${typeof bytes}`); } const header = bytes[0]; if (form === "compressed") { if (bytes.length !== 33) { throw new Error( `Invalid compressed public key: expected 33 bytes, but got ${bytes.length} bytes` ); } else if (header !== 2 && header !== 3) { throw new Error( `Invalid compressed public key: expected either 0x02 or 0x03 as the header, but got 0x${header.toString(16).padStart(2, "0")}` ); } } else if (form === "uncompressed") { if (bytes.length !== 65) { throw new Error( `Invalid uncompressed public key expected 65 bytes, but got ${bytes.length} bytes` ); } else if (header !== 4) { throw new Error( `Invalid compressed public key: expected 0x04 as the header, but got 0x${header.toString(16).padStart(2, "0")}` ); } } else { throw new Error( "Invalid public key form: choose 'compressed' or 'uncompressed'" ); } return new PublicKey(secp256k12.Point.fromHex(bytes)); } // TODO: more explicit length checking static fromHex(hex, form) { if (typeof hex !== "string") { throw new Error(`Expected a string, but got ${typeof hex}`); } else if (form === "compressed" && hex.length !== 66) { throw new Error( `Invalid compressed public key: expected 33 hexadigits, but got ${hex.length} hexadigits` ); } else if (form === "uncompressed" && hex.length !== 130) { throw new Error( `Invalid uncompressed public key expected 130 hexadigits, but got ${hex.length} hexadigits` ); } const bytes = new Uint8Array(Buffer2.from(hex, "hex")); return this.fromBytes(bytes, form); } async verify(message, signature) { if (!(message instanceof Uint8Array)) { throw new Error(`Expected Uint8Array, but got ${typeof message}`); } else if (!(signature instanceof Signature_default)) { throw new Error(`Expected Signature, but got ${typeof signature}`); } const msgHash = await hashMessage(message); return secp256k12.verify(signature.toBytes(), msgHash, this.#point); } toBytes(form) { if (form !== "compressed" && form !== "uncompressed") { throw new Error( "Invalid public key form: choose 'compressed' or 'uncompressed'" ); } return this.#point.toRawBytes(form === "compressed"); } toHex(form) { if (form !== "compressed" && form !== "uncompressed") { throw new Error( "Invalid public key form: choose 'compressed' or 'uncompressed'" ); } return this.#point.toHex(form === "compressed"); } equals(other) { return other instanceof PublicKey && this.#point.equals(other.#point); } }; __name(PublicKey, "PublicKey"); var PublicKey_default = PublicKey; // src/Address.ts if (typeof globalThis.TextEncoder === "undefined") { globalThis.TextEncoder = __require("node:util").TextEncoder; } function toHex(bytes) { let hex = ""; for (let i = 0; i < bytes.length; i++) { hex += bytes[i].toString(16).padStart(2, "0"); } return hex; } __name(toHex, "toHex"); function checksum(hex) { hex = hex.toLowerCase(); const hexAsciiIntoBytes = new TextEncoder().encode(hex); const hashedAddr = toHex(keccak_256(hexAsciiIntoBytes)); let checksum2 = ""; for (let nibbleIdx = 0; nibbleIdx < hex.length; nibbleIdx++) { const nibbleHex = hex.charAt(nibbleIdx); if (nibbleHex.match(/^[0-9]$/)) { checksum2 += nibbleHex; continue; } else { const nibble = parseInt(hashedAddr.charAt(nibbleIdx), 16); checksum2 += nibble > 7 ? nibbleHex.toUpperCase() : nibbleHex; } } return checksum2; } __name(checksum, "checksum"); var _bytes, _deriveFrom, deriveFrom_fn; var _Address = class { constructor(bytes) { __privateAdd(this, _bytes, void 0); __privateSet(this, _bytes, bytes); } static deriveFrom(publicKey) { if (isAccount(publicKey)) { return publicKey.getPublicKey().then(__privateMethod(this, _deriveFrom, deriveFrom_fn)); } else if (publicKey instanceof PublicKey) { return __privateMethod(this, _deriveFrom, deriveFrom_fn).call(this, publicKey); } throw new Error( `Expected either PublicKey or Account, got ${typeof publicKey}` ); } static fromHex(hex, ignoreChecksum = false) { if (typeof hex !== "string") { throw new Error(`Expected a string, but ${typeof hex} was given.`); } else if (!hex.match(/^(0x)?[0-9a-f]{40}$/i)) { throw new Error( `Expected a string of 40 hexadecimals, but ${JSON.stringify( hex )} was given.` ); } if (hex.match(/^0x/i)) { hex = hex.slice(2); } const addr = new _Address(new Uint8Array(Buffer3.from(hex, "hex"))); if (ignoreChecksum) { return addr; } const expectedChecksum = checksum(hex); if (expectedChecksum !== hex) { throw new Error( `Expected checksum is 0x${expectedChecksum}, but 0x${hex} was given.` ); } return addr; } static fromBytes(bytes) { if (!(bytes instanceof Uint8Array)) { throw new Error(`Expected a Uint8Array, but ${typeof bytes} was given.`); } if (bytes.length !== 20) { throw new Error( `Expected 20 bytes, but ${bytes.length} bytes were given.` ); } return new _Address(bytes); } toBytes() { return __privateGet(this, _bytes); } toHex(casing = "checksum") { const hex = toHex(__privateGet(this, _bytes)); return casing === "checksum" ? checksum(hex) : hex; } equals(other) { if (!(other instanceof _Address)) return false; for (let i = 0; i < 20; i++) { if (__privateGet(this, _bytes)[i] !== __privateGet(other, _bytes)[i]) return false; } return true; } isAddressOf(publicKey) { return _Address.deriveFrom(publicKey).equals(this); } toString() { return `0x${this.toHex()}`; } }; var Address = _Address; __name(Address, "Address"); _bytes = new WeakMap(); _deriveFrom = new WeakSet(); deriveFrom_fn = /* @__PURE__ */ __name(function(publicKey) { const pub = publicKey.toBytes("uncompressed").slice(1); const digest = keccak_256(pub); const addr = digest.slice(digest.length - 20); return new _Address(addr); }, "#deriveFrom"); __privateAdd(Address, _deriveFrom); var Address_default = Address; // src/RawPrivateKey.ts import { Buffer as Buffer4 } from "buffer"; import * as secp256k13 from "@noble/secp256k1"; var RawPrivateKey = class { #privatePart; #publicPart; constructor(privatePart) { this.#privatePart = privatePart; } static fromBytes(bytes) { if (!(bytes instanceof Uint8Array)) { throw new Error(`Expected Uint8Array, but got ${typeof bytes}`); } else if (bytes.length !== 32) { throw new Error( `Incorrect private key length; expected 32 bytes, but got ${bytes.length} bytes` ); } else if (!secp256k13.utils.isValidPrivateKey(bytes)) { throw new Error("Invalid private key"); } return new RawPrivateKey(new Uint8Array(bytes)); } static fromHex(hex) { if (typeof hex !== "string") { throw new Error(`Expected string, but got ${typeof hex}`); } else if (hex.length !== 64) { throw new Error( `Incorrect private key length; expected 64 hexadigits, but got ${hex.length} hexadigits` ); } const bytes = new Uint8Array(Buffer4.from(hex, "hex")); if (!secp256k13.utils.isValidPrivateKey(bytes)) { throw new Error("Invalid private key"); } return new RawPrivateKey(bytes); } static generate() { return this.fromBytes(secp256k13.utils.randomPrivateKey()); } getAddress() { return Promise.resolve(Address_default.deriveFrom(this.publicKey)); } /** * @deprecated Use {@link getPublicKey()} instead. */ get publicKey() { if (typeof this.#publicPart === "undefined") { this.#publicPart = PublicKey_default.fromBytes( secp256k13.getPublicKey(this.#privatePart), "uncompressed" ); } return this.#publicPart; } getPublicKey() { return Promise.resolve(this.publicKey); } async sign(message) { const sig = await secp256k13.sign( await hashMessage(message), this.#privatePart, { der: true } ); return Signature_default.fromBytes(sig); } exportPrivateKey() { return Promise.resolve(this); } toBytes() { return new Uint8Array(this.#privatePart); } }; __name(RawPrivateKey, "RawPrivateKey"); export { Address, PublicKey, RawPrivateKey, Signature2 as Signature }; /*! For license information please see index.js.LEGAL.txt */ //# sourceMappingURL=index.js.map