xud
Version:
Exchange Union Daemon
141 lines • 5.98 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const bip39_1 = require("bip39");
const crypto_1 = require("crypto");
const fs_1 = require("fs");
const secp256k1_1 = __importDefault(require("secp256k1"));
const cryptoUtils_1 = require("../utils/cryptoUtils");
const seedutil_1 = require("../utils/seedutil");
/**
* A class representing an ECDSA public/private key pair that identifies an XU node on the network
* and can sign messages to prove their veracity.
*/
let NodeKey = /** @class */ (() => {
class NodeKey {
/**
* @param privKey The 32 byte private key
* @param pubKey The public key in hex string format.
*/
constructor(privKey, pubKey, path) {
this.privKey = privKey;
this.pubKey = pubKey;
this.path = path;
/**
* Signs a message with the private key.
* @param msg the data to sign
* @returns the signature
*/
this.sign = (msg) => {
return secp256k1_1.default.sign(msg, this.privKey).signature;
};
/**
* Saves the private key to a file, optionally encrypted by a password.
* @param path the path at which to save the file
* @param password an optional password parameter for encrypting the private key
*/
this.toFile = (password) => __awaiter(this, void 0, void 0, function* () {
let buf;
if (password) {
this.password = password;
buf = yield cryptoUtils_1.encrypt(this.privKey, password);
}
else {
buf = this.privKey;
}
yield fs_1.promises.writeFile(this.path, buf);
});
/**
* Derives a child mnemonic seed from the private key for the swap client.
* @param swapClient the swap client to create the seed for
* @returns a BIP39 mnemonic
*/
this.childSeed = (swapClient) => {
const privKeyHex = this.privKey.toString('hex');
const childSeedEntropy = crypto_1.createHash('sha256')
.update(`${privKeyHex}-${swapClient}`)
.digest();
return bip39_1.entropyToMnemonic(childSeedEntropy);
};
this.getMnemonic = () => __awaiter(this, void 0, void 0, function* () {
const decipheredSeed = this.privKey.slice(0, 19);
const decipheredSeedHex = decipheredSeed.toString('hex');
const seedMnemonic = yield seedutil_1.encipher(decipheredSeedHex);
return seedMnemonic;
});
}
}
/**
* Generates a random NodeKey.
*/
NodeKey.generate = (path) => __awaiter(void 0, void 0, void 0, function* () {
let privKey;
do {
privKey = yield cryptoUtils_1.randomBytes(32);
} while (!secp256k1_1.default.privateKeyVerify(privKey));
return NodeKey.fromBytes(privKey, path);
});
/**
* Converts a buffer of bytes to a NodeKey. Uses the first 32 bytes from the buffer to generate
* the private key. If the buffer has fewer than 32 bytes, the buffer is right-padded with zeros.
*/
NodeKey.fromBytes = (bytes, path) => {
let privKey;
if (bytes.byteLength === 32) {
privKey = bytes;
}
else if (bytes.byteLength < 32) {
privKey = Buffer.concat([bytes, Buffer.alloc(32 - bytes.byteLength)]);
}
else {
privKey = bytes.slice(0, 32);
}
const pubKeyBytes = secp256k1_1.default.publicKeyCreate(privKey);
const pubKey = pubKeyBytes.toString('hex');
return new NodeKey(privKey, pubKey, path !== null && path !== void 0 ? path : '');
};
/**
* Load a NodeKey from a file.
* @param path the path to the file
* @param password an optional password to decrypt the file
* @returns a NodeKey if a file containing a valid ECDSA private key exists at the given path
*/
NodeKey.fromFile = (path, password) => __awaiter(void 0, void 0, void 0, function* () {
let privKey;
const fileBuffer = yield fs_1.promises.readFile(path);
if (password) {
// decrypt file using the password
privKey = cryptoUtils_1.decrypt(fileBuffer, password);
}
else {
privKey = fileBuffer;
}
if (secp256k1_1.default.privateKeyVerify(privKey)) {
const nodeKey = NodeKey.fromBytes(privKey, path);
nodeKey.password = password;
return nodeKey;
}
else {
throw new Error(`${path} does not contain a valid ECDSA private key`);
}
});
NodeKey.getPath = (xudir, instanceId = 0) => {
return instanceId > 0
? `${xudir}/nodekey_${instanceId}.dat`
: `${xudir}/nodekey.dat`;
};
return NodeKey;
})();
exports.default = NodeKey;
//# sourceMappingURL=NodeKey.js.map