smartledger-sdk
Version:
A comprehensive blockchain and cryptographic operations SDK for JavaScript
162 lines (143 loc) • 4.48 kB
JavaScript
import bsv from "bsv";
import Mnemonic from "bsv/mnemonic/index.js";
import { v4 as uuidv4 } from "uuid";
class BSVKeys {
constructor() {
this.bsv = bsv;
this.paths = {
identity: "m/44'/236'/0'/0/0",
financial: "m/44'/0'/0'/0/0",
contractual: "m/44'/236'/1'/0/0",
property: "m/44'/236'/2'/0/0",
document: "m/44'/236'/3'/0/0",
privacy: "m/44'/236'/4'/0/0",
};
this.uuid = uuidv4();
this.mnemonic = null;
this.privateKey = null;
this.publicKey = null;
this.hdPrivateKey = null;
this.path = null;
}
static generateMnemonic() {
// Generate 24-word mnemonic using 256 bits of entropy
const entropy = Buffer.from(
Array(32)
.fill(0)
.map(() => Math.floor(Math.random() * 256))
);
const mnemonic = new Mnemonic(entropy);
// Verify we have 24 words
const words = mnemonic.toString().split(" ");
if (words.length !== 24) {
// If not 24 words, try again
return BSVKeys.generateMnemonic();
}
return mnemonic;
}
static fromMnemonic(mnemonic, purpose = "financial") {
if (typeof mnemonic === "string") {
mnemonic = new Mnemonic(mnemonic);
}
const instance = new BSVKeys();
const path = instance.paths[purpose] || instance.paths.financial;
const hdPrivateKey = mnemonic.toHDPrivateKey();
const derivedKey = hdPrivateKey.deriveChild(path);
instance.privateKey = derivedKey.privateKey;
instance.publicKey = instance.privateKey.publicKey;
instance.hdPrivateKey = hdPrivateKey; // Store HD private key for derivation
instance.path = path;
return instance;
}
static generateKeyPair() {
const instance = new BSVKeys();
instance.mnemonic = BSVKeys.generateMnemonic();
instance.privateKey = instance.mnemonic
.toHDPrivateKey()
.deriveChild(instance.paths.identity).privateKey;
instance.publicKey = instance.privateKey.publicKey;
return instance;
}
static fromWIF(wif) {
const privateKey = new bsv.PrivateKey.fromWIF(wif);
const instance = new BSVKeys();
instance.privateKey = privateKey;
instance.publicKey = privateKey.publicKey;
return instance;
}
static fromPrivateKey(privateKey) {
const instance = new BSVKeys();
instance.privateKey = privateKey;
instance.publicKey = privateKey.publicKey;
return instance;
}
toWIF() {
if (!this.privateKey) {
throw new Error("Private key is required for WIF format");
}
return this.privateKey.toWIF();
}
toPublicKeyString() {
return this.publicKey.toString();
}
toAddress() {
return this.publicKey.toAddress().toString();
}
deriveChild(path) {
if (!this.hdPrivateKey) {
throw new Error(
"HD Private key is required for derivation. Use fromMnemonic to create a derivable key."
);
}
const derivedKey = this.hdPrivateKey.deriveChild(path);
const instance = new BSVKeys();
instance.privateKey = derivedKey.privateKey;
instance.publicKey = instance.privateKey.publicKey;
instance.hdPrivateKey = derivedKey;
instance.path = path;
return instance;
}
deriveForPurpose(purpose) {
if (!this.hdPrivateKey) {
throw new Error(
"HD Private Key not available. Keys must be created from mnemonic to derive for different purposes."
);
}
const path = this.paths[purpose] || this.paths.financial;
const derivedKey = this.hdPrivateKey.deriveChild(path);
const instance = new BSVKeys();
instance.privateKey = derivedKey.privateKey;
instance.publicKey = instance.privateKey.publicKey;
instance.hdPrivateKey = this.hdPrivateKey;
instance.path = path;
return instance;
}
static generateAllKeys(mnemonic) {
const instance = new BSVKeys();
const keys = {
mnemonic: mnemonic.toString(),
keys: [],
uuid: instance.uuid,
};
for (const [type, path] of Object.entries(instance.paths)) {
const derivedKey = this.fromMnemonic(mnemonic.toString(), type);
keys.keys.push({
type,
path,
wif: derivedKey.toWIF(),
publicKey: derivedKey.publicKey.toString(),
address: derivedKey.toAddress(),
});
}
return keys;
}
}
// Example usage
async function getAllKeys() {
const mnemonic = BSVKeys.generateMnemonic();
const keys = BSVKeys.generateAllKeys(mnemonic);
console.log(keys);
}
getAllKeys();
export default BSVKeys;
export { BSVKeys };