You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

100 lines
3.1 KiB

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const NETWORKS = require("./networks");
const types = require("./types");
const ecc = require('tiny-secp256k1');
const randomBytes = require('randombytes');
const typeforce = require('typeforce');
const wif = require('wif');
const isOptions = typeforce.maybe(typeforce.compile({
compressed: types.maybe(types.Boolean),
network: types.maybe(types.Network),
}));
class ECPair {
constructor(d, Q, options) {
if (options === undefined)
options = {};
this.compressed =
options.compressed === undefined ? true : options.compressed;
this.network = options.network || NETWORKS.bitcoin;
this.__D = undefined;
this.__Q = undefined;
if (d !== undefined)
this.__D = d;
if (Q !== undefined)
this.__Q = ecc.pointCompress(Q, this.compressed);
}
get privateKey() {
return this.__D;
}
get publicKey() {
if (!this.__Q)
this.__Q = ecc.pointFromScalar(this.__D, this.compressed);
return this.__Q;
}
toWIF() {
if (!this.__D)
throw new Error('Missing private key');
return wif.encode(this.network.wif, this.__D, this.compressed);
}
sign(hash) {
if (!this.__D)
throw new Error('Missing private key');
return ecc.sign(hash, this.__D);
}
verify(hash, signature) {
return ecc.verify(hash, this.publicKey, signature);
}
}
function fromPrivateKey(buffer, options) {
typeforce(types.Buffer256bit, buffer);
if (!ecc.isPrivate(buffer))
throw new TypeError('Private key not in range [1, n)');
typeforce(isOptions, options);
return new ECPair(buffer, undefined, options);
}
exports.fromPrivateKey = fromPrivateKey;
function fromPublicKey(buffer, options) {
typeforce(ecc.isPoint, buffer);
typeforce(isOptions, options);
return new ECPair(undefined, buffer, options);
}
exports.fromPublicKey = fromPublicKey;
function fromWIF(wifString, network) {
const decoded = wif.decode(wifString);
const version = decoded.version;
// list of networks?
if (types.Array(network)) {
network = network
.filter((x) => {
return version === x.wif;
})
.pop();
if (!network)
throw new Error('Unknown network version');
// otherwise, assume a network object (or default to bitcoin)
}
else {
network = network || NETWORKS.bitcoin;
if (version !== network.wif)
throw new Error('Invalid network version');
}
return fromPrivateKey(decoded.privateKey, {
compressed: decoded.compressed,
network: network,
});
}
exports.fromWIF = fromWIF;
function makeRandom(options) {
typeforce(isOptions, options);
if (options === undefined)
options = {};
const rng = options.rng || randomBytes;
let d;
do {
d = rng(32);
typeforce(types.Buffer256bit, d);
} while (!ecc.isPrivate(d));
return fromPrivateKey(d, options);
}
exports.makeRandom = makeRandom;