UNPKG

bsv-sdk

Version:

bsv sdk

432 lines (349 loc) 15.1 kB
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator"; function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } import _regeneratorRuntime from "@babel/runtime/regenerator"; import { bsv } from "scryptlib"; import { MetaSVProvider } from "showpay-providers"; import { getTransferNeedUtxosAndFee } from "./utils/Txutils"; import Sensible from "./modules/sensible"; var HdWallet = /*#__PURE__*/function () { function HdWallet(mnemonic, network, metasvAuth, feeb) { if (feeb === void 0) { feeb = 0.5; } this.hdPrivateKey = bsv.Mnemonic.fromString(mnemonic).toHDPrivateKey().deriveChild("m/44'/236'/0'"); this.xpriv = this.hdPrivateKey.xprivkey.toString(); this.xpub = this.hdPrivateKey.xpubkey; this.rootWallet = this.hdPrivateKey.deriveChild(0).deriveChild(0); this.rootWif = this.rootWallet.privateKey.toString(); this.rootAddress = this.rootWallet.privateKey.toAddress().toString(); this.provider = new MetaSVProvider(network, metasvAuth); this.feeb = feeb; this.addressWifMap = new Map(); this.network = network; this.metasvAuth = metasvAuth; } var _proto = HdWallet.prototype; _proto.ftMerge = /*#__PURE__*/function () { var _ftMerge = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(codehash, genesis, sensibleId) { var sensible; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: sensible = new Sensible(this.network, this.feeb, this.rootWif, this.metasvAuth); _context.next = 3; return this.transferAll(this.rootAddress, true); case 3: _context.next = 5; return sensible.ftMerge(codehash, genesis, sensibleId, this.rootWif); case 5: case "end": return _context.stop(); } } }, _callee, this); })); function ftMerge(_x, _x2, _x3) { return _ftMerge.apply(this, arguments); } return ftMerge; }(); _proto.getFtMergeTime = /*#__PURE__*/function () { var _getFtMergeTime = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(codehash, genesis, sensibleId) { var sensible, mergeTime; return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: sensible = new Sensible(this.network, this.feeb, this.rootWif, this.metasvAuth); _context2.next = 3; return sensible.ftMergeTime(codehash, genesis, sensibleId); case 3: mergeTime = _context2.sent; return _context2.abrupt("return", mergeTime); case 5: case "end": return _context2.stop(); } } }, _callee2, this); })); function getFtMergeTime(_x4, _x5, _x6) { return _getFtMergeTime.apply(this, arguments); } return getFtMergeTime; }(); _proto.ftMergeOne = /*#__PURE__*/function () { var _ftMergeOne = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(codehash, genesis, sensibleId) { var sensible, res; return _regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: sensible = new Sensible(this.network, this.feeb, this.rootWif, this.metasvAuth); _context3.next = 3; return this.transferAll(this.rootAddress, true); case 3: _context3.next = 5; return sensible.ftMergeOne(codehash, genesis, sensibleId, this.rootWif); case 5: res = _context3.sent; return _context3.abrupt("return", res); case 7: case "end": return _context3.stop(); } } }, _callee3, this); })); function ftMergeOne(_x7, _x8, _x9) { return _ftMergeOne.apply(this, arguments); } return ftMergeOne; }(); _proto.transferAll = /*#__PURE__*/function () { var _transferAll = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(receiverAddress, broadcast) { var balanceResp, xpubBalance, utxos, fee, minAmountCanTransfer, tx, privateKeys, _iterator, _step, utxo, txid, txHex, retUtxos, resTxid; return _regeneratorRuntime.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: _context4.next = 2; return this.provider.getXpubBalance(this.xpub); case 2: balanceResp = _context4.sent; xpubBalance = balanceResp.confirmed + balanceResp.unconfirmed; _context4.next = 6; return this.getUtxos(); case 6: utxos = _context4.sent; if (!(utxos.length == 1 && utxos[0].address == receiverAddress)) { _context4.next = 9; break; } return _context4.abrupt("return", null); case 9: fee = Math.ceil((utxos.length * 148 + 34 + 10) * this.feeb); minAmountCanTransfer = 135 + fee; if (!(xpubBalance < minAmountCanTransfer)) { _context4.next = 13; break; } throw new Error("Insufficient BSV Balance"); case 13: tx = new bsv.Transaction(); tx.from(utxos.map(function (utxo) { return { txId: utxo.txId, outputIndex: utxo.outputIndex, satoshis: utxo.satoshis, script: bsv.Script.buildPublicKeyHashOut(utxo.address).toHex() }; })); tx.addOutput(new bsv.Transaction.Output({ satoshis: xpubBalance - fee, script: bsv.Script.fromAddress(receiverAddress) })); privateKeys = []; for (_iterator = _createForOfIteratorHelperLoose(utxos); !(_step = _iterator()).done;) { utxo = _step.value; privateKeys.push(this.addressWifMap.get(utxo.address)); } tx.fee(fee); tx.sign(privateKeys); txid = tx.id; txHex = tx.serialize(true); retUtxos = [{ txId: txid, outputIndex: 0, satoshis: xpubBalance - fee, address: receiverAddress }]; if (!broadcast) { _context4.next = 29; break; } _context4.next = 26; return this.provider.broadcast(txHex); case 26: resTxid = _context4.sent; if (resTxid) { _context4.next = 29; break; } throw new Error("broadcast error"); case 29: return _context4.abrupt("return", { txid: txid, txHex: txHex, utxos: retUtxos }); case 30: case "end": return _context4.stop(); } } }, _callee4, this); })); function transferAll(_x10, _x11) { return _transferAll.apply(this, arguments); } return transferAll; }(); _proto.transfer = /*#__PURE__*/function () { var _transfer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(receivers, broadcast) { var balanceResp, xpubBalance, totalTransferAmount, _iterator2, _step2, receiver, utxos, minTransferFee, utxosAndFee, fee, tx, _iterator3, _step3, _receiver, utxoTotalAmount, privateKeys, _iterator4, _step4, utxo, txid, txHex, retUtxos, i, resTxid; return _regeneratorRuntime.wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: if (broadcast === void 0) { broadcast = true; } _context5.next = 3; return this.provider.getXpubBalance(this.xpub); case 3: balanceResp = _context5.sent; xpubBalance = balanceResp.confirmed + balanceResp.unconfirmed; totalTransferAmount = 0; for (_iterator2 = _createForOfIteratorHelperLoose(receivers); !(_step2 = _iterator2()).done;) { receiver = _step2.value; totalTransferAmount += receiver.amount; } _context5.next = 9; return this.getUtxos(); case 9: utxos = _context5.sent; minTransferFee = Math.ceil((utxos.length * 148 + 34 + 10) * this.feeb); if (!(xpubBalance < totalTransferAmount + minTransferFee)) { _context5.next = 13; break; } throw new Error("Insufficient BSV Balance"); case 13: utxosAndFee = getTransferNeedUtxosAndFee(receivers, utxos, this.feeb); utxos = utxosAndFee.utxos; fee = utxosAndFee.fee; tx = new bsv.Transaction(); tx.from(utxos.map(function (utxo) { return { txId: utxo.txId, outputIndex: utxo.outputIndex, satoshis: utxo.satoshis, script: bsv.Script.buildPublicKeyHashOut(utxo.address).toHex() }; })); for (_iterator3 = _createForOfIteratorHelperLoose(receivers); !(_step3 = _iterator3()).done;) { _receiver = _step3.value; tx.addOutput(new bsv.Transaction.Output({ satoshis: _receiver.amount, script: bsv.Script.fromAddress(_receiver.address) })); } utxoTotalAmount = 0; utxos.forEach(function (utxo) { utxoTotalAmount += utxo.satoshis; }); if (utxoTotalAmount - fee - totalTransferAmount >= 135) { tx.addOutput(new bsv.Transaction.Output({ satoshis: utxoTotalAmount - fee - totalTransferAmount, script: bsv.Script.fromAddress(this.rootAddress) })); } privateKeys = []; for (_iterator4 = _createForOfIteratorHelperLoose(utxos); !(_step4 = _iterator4()).done;) { utxo = _step4.value; privateKeys.push(this.addressWifMap.get(utxo.address)); } tx.fee(fee); tx.sign(privateKeys); txid = tx.id; txHex = tx.serialize(true); retUtxos = []; for (i = 0; i < tx.outputs.length; i++) { retUtxos.push({ txId: txid, outputIndex: i, satoshis: tx.outputs[i].satoshis, // @ts-ignore address: bsv.Address.fromScript(tx.outputs[i].script).toString() }); } if (!broadcast) { _context5.next = 36; break; } _context5.next = 33; return this.provider.broadcast(txHex); case 33: resTxid = _context5.sent; if (resTxid) { _context5.next = 36; break; } throw new Error("broadcast error"); case 36: return _context5.abrupt("return", { txid: txid, txHex: txHex, utxos: retUtxos }); case 37: case "end": return _context5.stop(); } } }, _callee5, this); })); function transfer(_x12, _x13) { return _transfer.apply(this, arguments); } return transfer; }(); _proto.getUtxos = /*#__PURE__*/function () { var _getUtxos = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6(limit) { var utxos, gUtxos, _iterator5, _step5, gUtxo, privateKey; return _regeneratorRuntime.wrap(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: if (limit === void 0) { limit = 300; } utxos = []; _context6.next = 4; return this.provider.getXpubUtxo(this.xpub, limit); case 4: gUtxos = _context6.sent; for (_iterator5 = _createForOfIteratorHelperLoose(gUtxos); !(_step5 = _iterator5()).done;) { gUtxo = _step5.value; if (!this.addressWifMap.has(gUtxo.address)) { privateKey = this.hdPrivateKey.deriveChild(gUtxo.addressType).deriveChild(gUtxo.addressIndex).privateKey; this.addressWifMap.set(gUtxo.address, privateKey); } utxos.push({ txId: gUtxo.txid, outputIndex: gUtxo.txIndex, satoshis: gUtxo.value, address: gUtxo.address, flag: gUtxo.flag }); } return _context6.abrupt("return", utxos); case 7: case "end": return _context6.stop(); } } }, _callee6, this); })); function getUtxos(_x14) { return _getUtxos.apply(this, arguments); } return getUtxos; }(); return HdWallet; }(); export { HdWallet as default };