UNPKG

bitcore-wallet-service

Version:
193 lines 8.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Wallet = void 0; const lodash_1 = __importDefault(require("lodash")); const config_1 = __importDefault(require("../../config")); const index_1 = require("../chain/index"); const common_1 = require("../common"); const logger_1 = __importDefault(require("../logger")); const address_1 = require("./address"); const addressmanager_1 = require("./addressmanager"); const copayer_1 = require("./copayer"); const $ = require('preconditions').singleton(); const Uuid = require('uuid'); const Constants = common_1.Common.Constants, Defaults = common_1.Common.Defaults, Utils = common_1.Common.Utils; const Bitcore = { btc: require('bitcore-lib'), bch: require('bitcore-lib-cash'), eth: require('bitcore-lib'), matic: require('bitcore-lib'), arb: require('bitcore-lib'), base: require('bitcore-lib'), op: require('bitcore-lib'), xrp: require('bitcore-lib'), doge: require('bitcore-lib-doge'), ltc: require('bitcore-lib-ltc'), sol: require('bitcore-lib'), }; class Wallet { static create(opts) { opts = opts || {}; const chain = opts.chain || opts.coin; let x = new Wallet(); $.shouldBeNumber(opts.m); $.shouldBeNumber(opts.n); $.checkArgument(Utils.checkValueInCollection(chain, Constants.CHAINS)); $.checkArgument(Utils.checkValueInCollection(opts.network, Constants.NETWORKS[chain])); x.version = '1.0.0'; x.createdOn = Math.floor(Date.now() / 1000); x.id = opts.id || Uuid.v4(); x.name = opts.name; x.m = opts.m; x.n = opts.n; x.singleAddress = !!opts.singleAddress; x.status = 'pending'; x.publicKeyRing = []; x.addressIndex = 0; x.copayers = []; x.pubKey = opts.pubKey; x.coin = opts.coin; x.chain = opts.chain || index_1.ChainService.getChain(x.coin); x.network = opts.network; x.derivationStrategy = opts.derivationStrategy || Constants.DERIVATION_STRATEGIES.BIP45; x.addressType = opts.addressType || Constants.SCRIPT_TYPES.P2SH; x.addressManager = addressmanager_1.AddressManager.create({ derivationStrategy: x.derivationStrategy }); x.usePurpose48 = opts.usePurpose48; x.scanStatus = null; x.beRegistered = false; x.beAuthPrivateKey2 = null; x.beAuthPublicKey2 = null; x.nativeCashAddr = lodash_1.default.isUndefined(opts.nativeCashAddr) ? (x.chain == 'bch' ? true : null) : opts.nativeCashAddr; x.hardwareSourcePublicKey = opts.hardwareSourcePublicKey; x.clientDerivedPublicKey = opts.clientDerivedPublicKey; return x; } static fromObj(obj) { let x = new Wallet(); $.shouldBeNumber(obj.m); $.shouldBeNumber(obj.n); x.version = obj.version; x.createdOn = obj.createdOn; x.id = obj.id; x.name = obj.name; x.m = obj.m; x.n = obj.n; x.singleAddress = !!obj.singleAddress; x.status = obj.status; x.publicKeyRing = obj.publicKeyRing; x.copayers = lodash_1.default.map(obj.copayers, copayer => { return copayer_1.Copayer.fromObj(copayer); }); x.pubKey = obj.pubKey; x.coin = obj.coin || Defaults.COIN; x.chain = obj.chain || index_1.ChainService.getChain(x.coin); x.network = obj.network; if (!x.network) { x.network = obj.isTestnet ? Utils.getNetworkName(x.chain, 'testnet') : 'livenet'; } x.derivationStrategy = obj.derivationStrategy || Constants.DERIVATION_STRATEGIES.BIP45; x.addressType = obj.addressType || Constants.SCRIPT_TYPES.P2SH; x.addressManager = addressmanager_1.AddressManager.fromObj(obj.addressManager); x.scanStatus = obj.scanStatus; x.beRegistered = obj.beRegistered; x.beAuthPrivateKey2 = obj.beAuthPrivateKey2; x.beAuthPublicKey2 = obj.beAuthPublicKey2; x.nativeCashAddr = obj.nativeCashAddr; x.usePurpose48 = obj.usePurpose48; x.hardwareSourcePublicKey = obj.hardwareSourcePublicKey; x.clientDerivedPublicKey = obj.clientDerivedPublicKey; return x; } toObject() { let x = lodash_1.default.cloneDeep(this); x.isShared = this.isShared(); return x; } static getMaxRequiredCopayers(totalCopayers) { return Wallet.COPAYER_PAIR_LIMITS[totalCopayers]; } static verifyCopayerLimits(m, n) { return n >= 1 && n <= 15 && m >= 1 && m <= n; } isShared() { return this.n > 1; } isUTXOChain() { return !!Constants.UTXO_CHAINS[this.chain.toUpperCase()]; } updateBEKeys() { $.checkState(this.isComplete(), 'Failed state: wallet incomplete at <updateBEKeys()>'); const chain = this.chain || index_1.ChainService.getChain(this.coin); const bitcore = Bitcore[chain]; const salt = config_1.default.BE_KEY_SALT || Defaults.BE_KEY_SALT; var seed = lodash_1.default.map(this.copayers, 'xPubKey') .sort() .join('') + Utils.getGenericName(this.network) + this.coin + salt; seed = bitcore.crypto.Hash.sha256(Buffer.from(seed)); const priv = bitcore.PrivateKey(seed, this.network); this.beAuthPrivateKey2 = priv.toString(); this.beAuthPublicKey2 = priv.toPublicKey().toString(); } _updatePublicKeyRing() { this.publicKeyRing = lodash_1.default.map(this.copayers, copayer => { return lodash_1.default.pick(copayer, ['xPubKey', 'requestPubKey']); }); } addCopayer(copayer) { $.checkState(copayer.coin == this.coin, 'Failed state: copayer.coin not equal to this.coin at <addCopayer()>'); this.copayers.push(copayer); if (this.copayers.length < this.n) return; this.status = 'complete'; this._updatePublicKeyRing(); } addCopayerRequestKey(copayerId, requestPubKey, signature, restrictions, name) { $.checkState(this.copayers.length == this.n, 'Failed state: this.copayers.length == this.n at addCopayerRequestKey()'); const c = this.getCopayer(copayerId); c.requestPubKeys.unshift({ key: requestPubKey.toString(), signature, selfSigned: true, restrictions: restrictions || {}, name: name || null }); } getCopayer(copayerId) { return this.copayers.find(c => c.id == copayerId); } isComplete() { return this.status == 'complete'; } isScanning() { return this.scanning; } isZceCompatible() { return this.coin === 'bch' && this.addressType === 'P2PKH'; } createAddress(isChange, step, escrowInputs) { $.checkState(this.isComplete(), 'Failed state: this.isComplete() at <createAddress()>'); const path = this.addressManager.getNewAddressPath(isChange, step); logger_1.default.debug('Deriving addr:' + path); const scriptType = escrowInputs ? 'P2SH' : this.addressType; return address_1.Address.derive(this.id, scriptType, this.publicKeyRing, path, this.m, this.coin, this.network, isChange, this.chain, !this.nativeCashAddr, escrowInputs, this.hardwareSourcePublicKey, this.clientDerivedPublicKey); } getSkippedAddress() { $.checkState(this.isComplete(), 'Failed state: this.isComplete() at <getSkipeedAddress()>'); const next = this.addressManager.getNextSkippedPath(); if (!next) return; const address = address_1.Address.derive(this.id, this.addressType, this.publicKeyRing, next.path, this.m, this.coin, this.network, next.isChange, this.chain); return address; } } exports.Wallet = Wallet; Wallet.COPAYER_PAIR_LIMITS = {}; //# sourceMappingURL=wallet.js.map