UNPKG

@owstack/wallet-service

Version:

A service for multisignature HD wallets

111 lines (93 loc) 3.23 kB
const owsCommon = require('@owstack/ows-common'); const keyLib = require('@owstack/key-lib'); const Constants = owsCommon.Constants; const HDPublicKey = keyLib.HDPublicKey; const lodash = owsCommon.deps.lodash; const $ = require('preconditions').singleton(); const FIELDS = [ 'version', 'createdOn', 'address', 'walletId', 'isChange', 'path', 'publicKeys', 'networkName', 'type', 'hasActivity' ]; class Address { constructor(context) { // Context defines the coin network and is set by the implementing service in // order to instance this base service; e.g., btc-service. context.inject(this); } } Address.create = function (context, opts) { // Context defines the coin network and is set by the implementing service in // order to instance this base service; e.g., btc-service. const x = new Address(context); lodash.each(FIELDS, function (k) { x[k] = opts[k]; }); x.version = '1.0.0'; x.createdOn = Math.floor(Date.now() / 1000); x.networkName = x.ctx.Address(opts.address).toObject().network; x.type = x.type || Constants.SCRIPT_TYPES.P2SH; x.hasActivity = undefined; return x; }; Address.fromObj = function (context, obj) { // Context defines the coin network and is set by the implementing service in // order to instance this base service; e.g., btc-service. const x = new Address(context); lodash.each(FIELDS, function (k) { x[k] = obj[k]; }); x.type = x.type || Constants.SCRIPT_TYPES.P2SH; return x; }; Address.prototype.toObject = function () { const self = this; const x = {}; lodash.each(FIELDS, function (k) { x[k] = self[k]; }); return x; }; Address.prototype._deriveAddress = function (scriptType, publicKeyRing, path, m, networkName) { const self = this; $.checkArgument(lodash.includes(lodash.values(Constants.SCRIPT_TYPES), scriptType)); const publicKeys = lodash.map(publicKeyRing, function (item) { const xpub = new HDPublicKey(item.xPubKey); return xpub.deriveChild(path).publicKey; }); let address; const network = self.ctx.Networks.get(networkName); switch (scriptType) { case Constants.SCRIPT_TYPES.P2SH: address = self.ctx.Address.createMultisig(publicKeys, m, network.alias); break; case Constants.SCRIPT_TYPES.P2PKH: $.checkState(lodash.isArray(publicKeys) && publicKeys.length == 1); address = self.ctx.Address.fromPublicKey(publicKeys[0], network.alias); break; } return { address: address.toString(), path: path, publicKeys: lodash.invokeMap(publicKeys, 'toString'), networkName: networkName }; }; Address.prototype.derive = function (walletId, scriptType, publicKeyRing, path, m, networkName, isChange) { const self = this; const raw = self._deriveAddress(scriptType, publicKeyRing, path, m, networkName); const address = Address.create(self.getContext(), lodash.extend(raw, { walletId: walletId, type: scriptType, isChange: isChange, })); return address.toObject(); }; module.exports = Address;