forked from bitpay/copay-recovery
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.62c9b5864f3a7c9f455b.bundle.js
1 lines (1 loc) · 20.7 KB
/
main.62c9b5864f3a7c9f455b.bundle.js
1
webpackJsonp([1],{0:function(e,t){},1:function(e,t){},2:function(e,t){},4:function(e,t,n){e.exports=n("cDNt")},"6kpM":function(e,t,n){"use strict";var s=n("/oeL"),a=n("koeK"),i=(n.n(a),n("nVvX")),o=(n.n(i),n("x8nq")),r=(n.n(o),n("OGkG")),c=(n.n(r),n("xrDH")),l=(n.n(c),n("XKz0"));n.d(t,"a",function(){return u});var d=this&&this.__decorate||function(e,t,n,s){var a,i=arguments.length,o=i<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,n):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,n,s);else for(var r=e.length-1;r>=0;r--)(a=e[r])&&(o=(i<3?a(o):i>3?a(t,n,o):a(t,n))||o);return i>3&&o&&Object.defineProperty(t,n,o),o},p=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},u=function(){function e(e){this.http=e,this.apiURI={"btc/livenet":"https://insight.bitpay.com/api/","btc/testnet":"https://test-insight.bitpay.com/api/","bch/livenet":"https://bch-insight.bitpay.com/api/"},this.PATHS={BIP45:["m/45'/2147483647/0","m/45'/2147483647/1"],BIP44:{testnet:["m/44'/1'/0'/0","m/44'/1'/0'/1"],livenet:["m/44'/0'/0'/0","m/44'/0'/0'/1"],"bch/livenet":["m/44'/0'/0'/0","m/44'/0'/0'/1"]}}}return e.prototype.fromBackup=function(e,t,n,s,i){if(!e.backup)return null;try{JSON.parse(e.backup)}catch(e){throw console.log(e),new Error("JSON invalid. Please copy only the text within (and including) the { } brackets around it.")}var o;try{o=a.decrypt(e.password,e.backup)}catch(e){throw console.log(e),new Error("Incorrect backup password")}if(o=JSON.parse(o),!o.n)throw new Error("Backup format not recognized. If you are using a Copay Beta backup and version is older than 0.10, please see: https://github.com/bitpay/copay/issues/4730#issuecomment-244522614");if(o.m!=t||o.n!=n)throw new Error("The wallet configuration (m-n) does not match with values provided.");if(o.network!=i)throw new Error("Incorrect network.");if(!o.xPrivKeyEncrypted&&!o.xPrivKey)throw new Error("The backup does not have a private key");var r=o.xPrivKey;if(o.xPrivKeyEncrypted)try{r=a.decrypt(e.xPrivPass,o.xPrivKeyEncrypted)}catch(e){throw console.log(e),new Error("Can not decrypt private key")}return{walletId:o.walletId,copayerId:o.copayerId,publicKeyRing:o.publicKeyRing,xPriv:r,derivationStrategy:o.derivationStrategy||"BIP45",addressType:o.addressType||"P2SH",m:t,n:n,network:i,coin:s,from:"backup"}},e.prototype.checkAngularCryptoConfig=function(e){try{new r(e).toHDPrivateKey("","testnet").toString()}catch(e){return console.log(e),"Before starting, check the angular cli configuration described in the README/Installation section"}return null},e.prototype.fromMnemonic=function(e,t,n,s,a){if(!e.backup)return null;var i,o=e.backup,c=e.password;try{i=new r(o).toHDPrivateKey(c,a).toString()}catch(e){throw console.log(e),new Error("Mnemonic wallet seed is not valid.")}return{xPriv:i,derivationStrategy:"BIP44",addressType:1==n?"P2PKH":"P2SH",m:t,n:n,network:a,coin:s,from:"mnemonic"}},e.prototype.buildWallet=function(e){var t;if(e=c.compact(e),0==e.length)throw new Error("No data provided");if(1!=c.uniq(c.map(e,"from")).length)throw new Error("Mixed backup sources not supported");if(1!=c.uniq(c.map(e,"coin")).length)throw new Error("Mixed coins not supported");if(t=c.pick(e[0],["walletId","derivationStrategy","addressType","m","n","network","from","coin","publicKeyRing"]),t.copayers=c.map(e,function(e){if(e.walletId!=t.walletId)throw new Error("Backups do not belong to the same wallets.");return{copayerId:e.copayerId,xPriv:e.xPriv}}),"backup"==t.from&&c.uniq(c.compact(c.map(t.copayers,"copayerId"))).length!=t.copayers.length)throw new Error("Some of the backups belong to the same copayers");return console.log("Recovering wallet",t),t},e.prototype.getWallet=function(e,t,n,s,a){var r=this,l=this,d=c.map(e,function(e){return"{"==e.backup.charAt(0)?r.fromBackup(e,t,n,s,a):r.fromMnemonic(e,t,n,s,a)});if("btc"==s)l.bitcore=i;else{if("bch"!=s)throw new Error("Unknown coin "+s);l.bitcore=o}return this.buildWallet(d)},e.prototype.scanWallet=function(e,t,n,s){var a;this.getActiveAddresses(e,t,n,function(e,t){if(e)return s(e);a=c.flatten(c.map(t,"utxo"));var n={addresses:c.uniq(t),balance:c.sumBy(a,"amount")};return s(null,n)})},e.prototype.getPaths=function(e){return"BIP45"==e.derivationStrategy?this.PATHS[e.derivationStrategy]:"BIP44"==e.derivationStrategy?this.PATHS[e.derivationStrategy][e.network]:void 0},e.prototype.getHdDerivations=function(e){function t(e,t,n){var a=s.bitcore.HDPrivateKey(e);return n?a.deriveChild(t):a.deriveNonCompliantChild(t)}function n(e){return 1==e.length?e[0]:function(e,t){for(var n=[],s=0;s<e.length;s++)for(var a=0;a<t.length;a++)n.push(c.flatten([e[s],t[a]]));return n}(e[0],n(c.tail(e)))}var s=this,a=c.map(e.copayers,"xPriv"),i=[];return c.each(this.getPaths(e),function(e){var s=n(c.map(a,function(n,s){var a=t(n,e,!0),i=t(n,e,!1),o=[];return o.push({copayer:s+1,path:e,compliant:!0,key:a}),a.toString()!=i.toString()&&o.push({copayer:s+1,path:e,compliant:!1,key:i}),o}));i=i.concat(s)}),i},e.prototype.getActiveAddresses=function(e,t,n,s){function a(e){if(e>=d.length)return s(null,c.uniqBy(l,"address"));o=0,i(d[e],0,function(t,n){if(t)return s(t);a(e+1)})}function i(s,a,d){if(o>t)return d();var p=r.generateAddress(e,s,a);r.getAddressData(p,e.coin,e.network,function(e,t){if(e)return d(e);c.isEmpty(t)?o++:(console.log("#Active address:",t),l.push(t),o=0),n(o,c.uniqBy(l,"address")),i(s,a+1,d)})}var o,r=this,l=[],d=this.getHdDerivations(e);a(0)},e.prototype.generateAddress=function(e,t,n){var s=this,a=[],i=[];c.each([].concat(t),function(e){var t=s.bitcore.HDPrivateKey(e.key),o=t.deriveChild(n).privateKey;a.push(o),i.push(o.publicKey)}),e.publicKeyRing&&(i=[],e.publicKeyRing.forEach(function(e){var t=new s.bitcore.HDPublicKey(e.xPubKey).deriveChild(0).deriveChild(n);i.push(t.publicKey)}));var o;if("P2SH"==e.addressType)o=s.bitcore.Address.createMultisig(i,e.m,e.network);else{if("P2PKH"!=e.addressType)throw new Error("Address type not supported");o=s.bitcore.Address.fromPublicKey(i[0],e.network)}return{addressObject:o,pubKeys:i,privKeys:a,info:t,index:n}},e.prototype.getAddressData=function(e,t,n,s){var a=this;this.checkAddress(e.addressObject,t,n).then(function(i){i.subscribe(function(i){a.checkUtxos(e.addressObject,t,n).then(function(t){t.subscribe(function(t){var n={address:i.addrStr,balance:i.balance,unconfirmedBalance:i.unconfirmedBalance,utxo:t,privKeys:e.privKeys,pubKeys:e.pubKeys,info:e.info,index:e.index,isActive:i.unconfirmedTxApperances+i.txApperances>0};setTimeout(function(){return n.isActive?s(null,n):s()},5e3)})})})})},e.prototype.checkAddress=function(e,t,n){var s=this,a=this.apiURI[t+"/"+n]+"addr/"+e+"?noTxList=1";return new Promise(function(e){e(s.http.get(a))})},e.prototype.checkUtxos=function(e,t,n){var s=this,a=this.apiURI[t+"/"+n]+"addr/"+e+"/utxo?noCache=1";return new Promise(function(e){e(s.http.get(a))})},e.prototype.createRawTx=function(e,t,n,s){var a=this;if(!e||!a.bitcore.Address.isValid(e))throw new Error("Please enter a valid address.");var i=parseInt((1e8*t.balance-1e8*s).toFixed(0));if(i<=0)throw new Error("Funds are insufficient to complete the transaction");console.log("Generating a "+n.coin+" transaction");try{new a.bitcore.Address(e,n.network)}catch(e){throw console.log(e),new Error("Incorrect destination address network")}try{var o=[],r=new a.bitcore.Transaction;c.each(t.addresses,function(e){e.utxo.length>0&&c.each(e.utxo,function(t){"P2SH"==n.addressType?r.from(t,e.pubKeys,n.m):r.from(t),o=o.concat(e.privKeys.slice(0,n.m))})}),r.to(e,i),r.sign(c.uniq(o));var l=r.serialize();return console.log("Raw transaction: ",l),l}catch(e){throw console.log(e),new Error("Could not build tx: "+e)}},e.prototype.txBroadcast=function(e,t,n){var s=this,a=this.apiURI[t+"/"+n]+"tx/send";return console.log("Posting tx to..."+a),new Promise(function(t){t(s.http.post(a,{rawtx:e}))})},e}();u=d([n.i(s.c)(),p("design:paramtypes",["function"==typeof(h=void 0!==l.b&&l.b)&&h||Object])],u);var h},W675:function(e,t,n){t=e.exports=n("rP7Y")(!1),t.push([e.i,"",""]),e.exports=e.exports.toString()},"aR8+":function(e,t,n){"use strict";var s=n("fc+i"),a=n("/oeL"),i=n("bm2B"),o=n("XKz0"),r=n("wQAS");n.d(t,"a",function(){return l});var c=this&&this.__decorate||function(e,t,n,s){var a,i=arguments.length,o=i<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,n):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,n,s);else for(var r=e.length-1;r>=0;r--)(a=e[r])&&(o=(i<3?a(o):i>3?a(t,n,o):a(t,n))||o);return i>3&&o&&Object.defineProperty(t,n,o),o},l=function(){function e(){}return e}();l=c([n.i(a.b)({declarations:[r.a],imports:[s.a,i.a,o.a],providers:[],bootstrap:[r.a]})],l)},cDNt:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var s=n("/oeL"),a=n("Qa4U"),i=n("aR8+");n("p5Ee").a.production&&n.i(s.a)(),n.i(a.a)().bootstrapModule(i.a)},efyd:function(e,t){e.exports='<div class="header">\n <div class="header-content">\n <img class="bitpay-logo" src="assets/img/bitpay-logo-negative.svg" alt="Bitpay">\n <div class="header-center">\n <h3 class="header-title" >Recovery Tool</h3>\n <div class="repository-link">\n <a href="https://github.com/bitpay/copay-recovery" target="blank">\n <img src="assets/img/github.png" alt="Github">\n </a>\n </div>\n </div>\n <img class="copay-logo" src="assets/img/copay-logo-negative.svg" alt="Copay">\n </div>\n</div>\n<div [hidden]="!showLoadingSpinner" class="no-clickable-background">\n <div class="loading-message">\n <h5>Please wait</h5>\n <h5>This process could take several minutes</h5>\n <PRE *ngIf="(reportAddresses || reportAmount || reportInactive) && beforeScan">\n <div class="labels">\n Scanned addresses:\n Found funds:\n Inactive Addresses Streak:\n </div>\n <div class="values">\n {{reportAddresses}}\n {{reportAmount}}\n {{reportInactive}}\n </div>\n </PRE>\n </div>\n</div>\n<div class="container">\n\n <div [hidden]="!successMessage" class="alert alert-success">{{successMessage}}</div>\n <div [hidden]="!errorMessage" class="alert alert-danger">{{errorMessage}}</div>\n <div [hidden]="!statusMessage" class="alert alert-info">{{statusMessage}}</div>\n\n <form #processInputsForm="ngForm" (ngSubmit)="processInputs()" *ngIf="beforeScan">\n\n <div class="card">\n <div class="card-block">\n <h4 class="card-title">WALLET CONFIGURATION</h4>\n <div class="row">\n <div class="col-sm-12 col-xs-12 first-row">\n <div class="form-group signatures">\n <label for="signaturesNumber">Required number of signatures</label>\n <select class="form-control" id="signaturesNumber" name="signaturesNumber" [(ngModel)]="signaturesNumber">\n <option *ngFor="let option of availableOptions" [ngValue]="option">{{option}}</option>\n </select>\n </div>\n \n <div class="form-group copayers">\n <label for="copayersNumber">Total number of Copayers</label>\n <select class="form-control" id="copayersNumber" name="copayersNumber" [(ngModel)]="copayersNumber" (ngModelChange)="updateCopayersForm($event)">\n <option *ngFor="let option of availableOptions" [ngValue]="option">{{option}}</option>\n </select>\n </div>\n </div>\n\n <div class="form-group col-sm-6 col-xs-12">\n <label for="chain">Chain: Bitcoin</label>\n <span *ngIf="chain == \'btc/livenet\'">livenet</span>\n <span *ngIf="chain == \'btc/testnet\'">testnet</span>\n <span *ngIf="chain == \'bch/livenet\'">Cash livenet</span>\n <div class="chain-select">\n <select class="form-control" id="chain" name="chain" [(ngModel)]="chain">\n <option *ngFor="let chain of availableChains" [ngValue]="chain">{{chain}}</option>\n </select>\n <div class="chain-logo-container">\n <img src="assets/img/icon-btc.svg" class="chain-logo" *ngIf="chain == \'btc/livenet\'">\n <img src="assets/img/icon-testnet.svg" class="chain-logo" *ngIf="chain == \'btc/testnet\'">\n <img src="assets/img/icon-bch.svg" class="chain-logo" *ngIf="chain == \'bch/livenet\'">\n </div>\n </div>\n </div>\n\n <div class="form-group col-sm-6 col-xs-12">\n <label for="addressGap">Address Gap</label><small> (Usually does not need to be changed)</small>\n <input type="number" class="form-control" id="addressGap" name="addressGap" [(ngModel)]="addressGap" required>\n </div>\n </div>\n </div>\n </div>\n\n <div class="card" *ngFor="let copayer of copayers">\n <div class="card-block">\n <h6 class="card-title">Backup for copayer {{copayer}}:</h6>\n <div class="row">\n <div class="form-group col-sm-6">\n <label for="dataBackUp">Recovery phrase (mnemonic) or File/Text backup</label>\n <input type="text" class="form-control" id="dataBackUp" name="dataBackUp" [(ngModel)]="data.backUp[copayer]" autocomplete="off" required>\n </div>\n\n <div class="form-group col-sm-6">\n <label for="contentFile">Or upload a File/Text backup:</label>\n <input type="file" class="form-control-file" id="contentFile" name="contentFile" accept=".json, .txt" aria-describedby="contentFileHelp"\n (change)="fileChangeEvent($event, copayer)">\n <small id="fileHelp" class="form-text text-muted">Extensions accepted: .json and .txt</small>\n </div>\n </div>\n\n <div class="form-group">\n <label for="dataPass">Backup password:</label><small> (in case you have one)</small>\n <input type="password" class="form-control" id="dataPass" name="dataPass" [(ngModel)]="data.pass[copayer]">\n </div>\n\n <div class="form-group">\n <label for="dataPassX">Encrypted private key password</label><small> (spending password)</small>\n <input type="password" class="form-control" id="dataPassX" name="dataPassX" [(ngModel)]="data.passX[copayer]">\n </div>\n </div>\n </div>\n\n <div class="form-group">\n <label>\n <input type="checkbox" [(ngModel)]="termsAccepted" name="termsAccepted">\n I have read and accept <a href="https://copay.io/disclaimer" target="_blank">Terms and Conditions</a>\n </label>\n </div>\n\n <button type="submit" [disabled]="!processInputsForm.form.valid || showLoadingSpinner || !termsAccepted" class="btn btn-primary btn-lg btn-block">\n <span *ngIf="chain == \'btc/livenet\' || chain == \'btc/testnet\'">Scan BTC Wallet</span>\n <span *ngIf="chain == \'bch/livenet\'">Scan BCH Wallet</span>\n </button>\n </form>\n\n <form #sendFundsForm="ngForm" (ngSubmit)="sendFunds(destinationAddress, chain)" *ngIf="!beforeScan && !done">\n <div class="card">\n <div class="card-block">\n <h6 class="card-title">{{totalBalanceStr}}</h6>\n <div class="input-group" *ngIf="!insufficentsFunds">\n <div class="input-group-addon">Destination Address:</div>\n <input type="text" class="form-control" id="destinationAddress" name="destinationAddress" [(ngModel)]="destinationAddress" required>\n </div>\n </div>\n </div>\n <button type="submit" *ngIf="!insufficentsFunds" [disabled]="!sendFundsForm.form.valid || showLoadingSpinner" class="btn btn-primary btn-lg btn-block">Transfer</button>\n </form>\n <button type="button" (click)="ngOnInit()" *ngIf="!beforeScan" class="btn btn-outline-primary btn-lg btn-block">Go back</button>\n\n <div [hidden]="!showLoadingSpinner">\n <div class="s1">\n <div class="s b sb1"></div>\n <div class="s b sb2"></div>\n <div class="s b sb3"></div>\n <div class="s b sb4"></div>\n </div>\n <div class="s2">\n <div class="s b sb5"></div>\n <div class="s b sb6"></div>\n <div class="s b sb7"></div>\n <div class="s b sb8"></div>\n </div>\n <div class="bigcon">\n <div class="big b"></div>\n </div>\n </div>\n\n</div>\n'},n7du:function(e,t){function n(e){throw new Error("Cannot find module '"+e+"'.")}n.keys=function(){return[]},n.resolve=n,e.exports=n,n.id="n7du"},p5Ee:function(e,t,n){"use strict";n.d(t,"a",function(){return s});var s={production:!1}},wQAS:function(e,t,n){"use strict";var s=n("/oeL"),a=n("xrDH"),i=(n.n(a),n("6kpM"));n.d(t,"a",function(){return c});var o=this&&this.__decorate||function(e,t,n,s){var a,i=arguments.length,o=i<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,n):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,n,s);else for(var r=e.length-1;r>=0;r--)(a=e[r])&&(o=(i<3?a(o):i>3?a(t,n,o):a(t,n))||o);return i>3&&o&&Object.defineProperty(t,n,o),o},r=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},c=function(){function e(e){this.RecoveryService=e,this.copayers=[1],this.addressGap=20,this.data={backUp:[],pass:[],passX:[],gap:this.addressGap},this.availableOptions=[1,2,3,4,5,6],this.availableChains=["btc/livenet","btc/testnet","bch/livenet"],this.fee=.001,this.signaturesNumber=this.availableOptions[0],this.copayersNumber=this.availableOptions[0],this.chain=this.availableChains[0],this.statusMessage=null,this.successMessage=null,this.errorMessage=null,this.showLoadingSpinner=!1,this.done=!1,this.broadcasted=!1,this.insufficentsFunds=!1,this.termsAccepted=!1}return e.prototype.ngOnInit=function(){this.hideMessage(),this.beforeScan=!0,this.done=!1,this.broadcasted=!1,this.insufficentsFunds=!1,this.destinationAddress="",this.checkAngularCryptoConfig()},e.prototype.checkAngularCryptoConfig=function(){var e=this.RecoveryService.checkAngularCryptoConfig("imitate type scorpion whip oil cheese achieve rail organ donkey note screen");e&&this.showMessage(e,3)},e.prototype.updateCopayersForm=function(){this.copayers=a.map(a.range(1,this.copayersNumber+1),function(e){return e})},e.prototype.processInputs=function(){var e=this;this.hideMessage();var t=this;this.showLoadingSpinner=!0,this.beforeScan=!0;var n=a.map(a.range(1,this.copayersNumber+1),function(e){return{backup:t.data.backUp[e]||"",password:t.data.pass[e]||"",xPrivPass:t.data.passX[e]||""}});this.chain.match(/bch/)?(this.network="livenet",this.coin="bch"):(this.network=this.chain.replace("btc/",""),this.coin="btc");try{this.wallet=this.RecoveryService.getWallet(n,this.signaturesNumber,this.copayersNumber,this.coin,this.network)}catch(e){return this.showLoadingSpinner=!1,this.showMessage(e.message,3)}this.showMessage("Scanning funds...",1);var s=function(e,n){var s=a.sumBy(a.flatten(a.map(n,"utxo")),"amount"),i=s.toFixed(8)+" ";t.reportInactive=e,t.reportAmount=i+" "+t.wallet.coin,t.reportAddresses=n.length},i=+this.addressGap;i=i||20,this.RecoveryService.scanWallet(this.wallet,i,s,function(t,n){if(t)return e.showMessage(t,3);e.scanResults=n,console.log("## Total balance:",e.scanResults.balance.toFixed(8)+" BTC"),e.showMessage("Search completed",2),e.showLoadingSpinner=!1,e.beforeScan=!1,e.totalBalance=e.scanResults.balance.toFixed(8),e.totalBalanceStr="Available balance: "+e.scanResults.balance.toFixed(8)+" "+e.wallet.coin.toUpperCase(),e.scanResults.balance-e.fee<=0&&(e.totalBalanceStr+=". Insufficents funds.",e.insufficentsFunds=!0)})},e.prototype.fileChangeEvent=function(e,t){this.readThis(e.target,t)},e.prototype.readThis=function(e,t){var n=this,s=e.files[0],a=new FileReader;a.readAsText(s),a.onloadend=function(e){n.data.backUp[t]=a.result}},e.prototype.sendFunds=function(e,t){var n=this;if(confirm("A total of "+this.totalBalance+" will be send to: \n\nDestination address: "+e+"\nChain: "+t.substring(0,3).toUpperCase())){var s;this.showLoadingSpinner=!0;try{s=this.RecoveryService.createRawTx(e,this.scanResults,this.wallet,this.fee)}catch(e){return this.showMessage(e.message,3)}this.done=!0,this.RecoveryService.txBroadcast(s,this.coin,this.network).then(function(t){t.subscribe(function(t){n.showMessage((n.scanResults.balance-n.fee).toFixed(8)+" "+n.wallet.coin+" sent to address: "+e,2),console.log("Transaction complete. "+(n.scanResults.balance-n.fee)+" TX sent to address: "+e),n.broadcasted=!0})}).catch(function(e){n.showMessage("Could not broadcast transaction. Please, try later.",3)})}},e.prototype.hideMessage=function(){this.statusMessage=null,this.successMessage=null,this.errorMessage=null},e.prototype.showMessage=function(e,t){1==t?(this.statusMessage=e,this.successMessage=null,this.errorMessage=null):2==t?(this.successMessage=e,this.statusMessage=null,this.errorMessage=null,this.showLoadingSpinner=!1):3==t&&(this.errorMessage=e,this.statusMessage=null,this.successMessage=null,this.showLoadingSpinner=!1)},e}();c=o([n.i(s._5)({selector:"app-root",template:n("efyd"),styles:[n("W675")],providers:[i.a]}),r("design:paramtypes",["function"==typeof(l=void 0!==i.a&&i.a)&&l||Object])],c);var l}},[4]);