@ducatus/ducatus-wallet-service-rev
Version:
A service for Mutisig HD Bitcoin Wallets
161 lines • 7.09 kB
JavaScript
;
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var ducatus_crypto_wallet_core_rev_1 = require("@ducatus/ducatus-crypto-wallet-core-rev");
var btc_1 = require("../btc");
var Common = require('../../common');
var Constants = Common.Constants;
var Defaults = Common.Defaults;
var lodash_1 = __importDefault(require("lodash"));
var clienterror_1 = require("../../errors/clienterror");
var $ = require('preconditions').singleton();
var Errors = require('../../errors/errordefinitions');
var DucChain = (function (_super) {
__extends(DucChain, _super);
function DucChain() {
return _super.call(this, ducatus_crypto_wallet_core_rev_1.DucatuscoreLib) || this;
}
DucChain.prototype.validateAddress = function (wallet, inaddr, opts) {
var A = ducatus_crypto_wallet_core_rev_1.DucatuscoreLib.Address;
var addr = {};
try {
addr = new A(inaddr);
}
catch (ex) {
throw Errors.INVALID_ADDRESS;
}
if (addr.network.toString() != wallet.network) {
throw Errors.INCORRECT_ADDRESS_NETWORK;
}
return;
};
DucChain.prototype.getChangeAddress = function (server, wallet, opts) {
var _this = this;
return new Promise(function (resolve, reject) {
var getChangeAddress = function (wallet, cb) {
if (wallet.singleAddress) {
server.storage.fetchAddresses(server.walletId, function (err, addresses) {
if (err)
return cb(err);
if (lodash_1.default.isEmpty(addresses))
return cb(new clienterror_1.ClientError('The wallet has no addresses'));
return cb(null, lodash_1.default.head(addresses));
});
}
else {
if (opts.changeAddress) {
try {
_this.validateAddress(wallet, opts.changeAddress, opts);
}
catch (addrErr) {
return cb(addrErr);
}
server.storage.fetchAddressByWalletId(wallet.id, opts.changeAddress, function (err, address) {
if (err || !address)
return cb(Errors.INVALID_CHANGE_ADDRESS);
return cb(null, address);
});
}
else {
return cb(null, wallet.createAddress(true), true);
}
}
};
getChangeAddress(wallet, function (err, address, isNew) {
if (err)
return reject(err);
return resolve(address);
});
});
};
DucChain.prototype.buildTx = function (txp) {
var t = new ducatus_crypto_wallet_core_rev_1.DucatuscoreLib.Transaction();
t.setVersion(1);
switch (txp.addressType) {
case Constants.SCRIPT_TYPES.P2WSH:
case Constants.SCRIPT_TYPES.P2SH:
lodash_1.default.each(txp.inputs, function (i) {
$.checkState(i.publicKeys, 'Inputs should include public keys');
t.from(i, i.publicKeys, txp.requiredSignatures);
});
break;
case Constants.SCRIPT_TYPES.P2WPKH:
case Constants.SCRIPT_TYPES.P2PKH:
t.from(txp.inputs);
break;
}
lodash_1.default.each(txp.outputs, function (o) {
$.checkState(o.script || o.toAddress, 'Output should have either toAddress or script specified');
if (o.script) {
t.addOutput(new ducatus_crypto_wallet_core_rev_1.DucatuscoreLib.Transaction.Output({
script: o.script,
satoshis: o.amount
}));
}
else {
t.to(o.toAddress, o.amount);
}
});
t.fee(txp.fee);
if (txp.changeAddress) {
t.change(txp.changeAddress.address);
}
if (t.outputs.length > 1) {
var outputOrder_1 = lodash_1.default.reject(txp.outputOrder, function (order) {
return order >= t.outputs.length;
});
$.checkState(t.outputs.length == outputOrder_1.length);
t.sortOutputs(function (outputs) {
return lodash_1.default.map(outputOrder_1, function (i) {
return outputs[i];
});
});
}
var totalInputs = lodash_1.default.sumBy(t.inputs, 'output.satoshis');
var totalOutputs = lodash_1.default.sumBy(t.outputs, 'satoshis');
$.checkState(totalInputs > 0 && totalOutputs > 0 && totalInputs >= totalOutputs, 'not-enought-inputs');
$.checkState(totalInputs - totalOutputs <= Defaults.MAX_TX_FEE[txp.coin], 'fee-too-high');
return t;
};
DucChain.prototype.addSignaturesToBitcoreTx = function (tx, inputs, inputPaths, signatures, xpub) {
if (signatures.length != inputs.length)
throw new Error('Number of signatures does not match number of inputs');
var i = 0;
var x = new ducatus_crypto_wallet_core_rev_1.DucatuscoreLib.HDPublicKey(xpub);
lodash_1.default.each(signatures, function (signatureHex) {
try {
var signature = ducatus_crypto_wallet_core_rev_1.DucatuscoreLib.crypto.Signature.fromString(signatureHex);
var pub = x.deriveChild(inputPaths[i]).publicKey;
var s = {
inputIndex: i,
signature: signature,
sigtype: ducatus_crypto_wallet_core_rev_1.DucatuscoreLib.crypto.Signature.SIGHASH_ALL | ducatus_crypto_wallet_core_rev_1.DucatuscoreLib.crypto.Signature.SIGHASH_FORKID,
publicKey: pub
};
tx.inputs[i].addSignature(tx, s);
i++;
}
catch (e) { }
});
if (i != tx.inputs.length)
throw new Error('Wrong signatures');
};
return DucChain;
}(btc_1.BtcChain));
exports.DucChain = DucChain;
//# sourceMappingURL=index.js.map