mirror of
https://github.com/ok2/coinbin.git
synced 2026-05-09 18:15:23 +02:00
Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 734e6b2eeb | |||
| 90a309d4b4 | |||
| abd2191c50 | |||
| bb8abb4ded | |||
| 40d514e0f0 | |||
| c3b1a47199 | |||
| ed7d5d6411 | |||
| 10e083bd89 | |||
| 56fa7b5139 | |||
| e85276dd89 | |||
| c843685662 | |||
| 64af126bc5 | |||
| 217897285e | |||
| b1603821da | |||
| c2ef949dd0 | |||
| ecb18acb0f | |||
| 4a4f302fe6 | |||
| 4afee020b0 | |||
| 2e0422656d | |||
| 6c480a1102 | |||
| d5fe5ea828 | |||
| 52b206c7d6 | |||
| 1f9d9e97c2 | |||
| d12b9d9072 | |||
| 6c22adaa5a | |||
| 605a6df343 | |||
| 60efbb5174 | |||
| 1b111b335d | |||
| 24028a001d | |||
| f4c2b3d425 | |||
| 20547ff133 | |||
| 858774b640 | |||
| 21ecedaa48 | |||
| 3c1e957519 | |||
| 44e6f5c639 | |||
| d176899774 | |||
| 970cd756ec | |||
| b6dfa6b822 | |||
| 85c9267379 | |||
| 0c3530590f | |||
| 74a0fad4d2 | |||
| 67f9c1f926 | |||
| 67bd6e927c | |||
| 284c6361e7 | |||
| 347ccf4947 | |||
| 8ac9f4207d | |||
| 3ba79f0e3d | |||
| cad1f6e98b | |||
| e818fc738d | |||
| 0a94fb64ef | |||
| e3fff74690 | |||
| 0154514309 | |||
| 1e8773c195 | |||
| 1ea47f6ff5 | |||
| b943cbd6de | |||
| 53c48af90c | |||
| 6970a07d60 | |||
| 695947b02d | |||
| 0a8bb6f33a | |||
| 27c9bff17e | |||
| c276998687 | |||
| 4f16149a26 | |||
| 7bfacd51b1 | |||
| 1da38e46f7 | |||
| 133a5d2858 | |||
| a9cfa44c44 | |||
| cedc6dddaf | |||
| d53c236ec3 | |||
| c8577e03be | |||
| 9a669885b3 | |||
| 8652fe789d | |||
| 6b39b86447 | |||
| 902370679f | |||
| ab395a82f2 | |||
| fe141b0b8a | |||
| e33b2dc58e | |||
| a62a822b71 | |||
| 91ee89282f | |||
| 42391aba8e | |||
| 8e0742d64c | |||
| a1c3c60244 | |||
| 004de1f318 | |||
| 6f8cd22d5f | |||
| cacc30cc95 | |||
| d2f1d3a5d5 | |||
| 1c3e81bfd2 | |||
| cf71efcf59 | |||
| da2d20f477 |
@@ -1,7 +1,7 @@
|
||||
coinbin
|
||||
=======
|
||||
|
||||
A Open Source Browser Based Bitcoin Wallet. Version 1.2 beta by OutCast3k
|
||||
A Open Source Browser Based Bitcoin Wallet. Version 1.4 beta by OutCast3k
|
||||
|
||||
Live version available at http://coinb.in/ or http://4zpinp6gdkjfplhk.onion
|
||||
|
||||
@@ -26,5 +26,10 @@ Coinb.in supports a number of key features such as:
|
||||
- An offical .onion address for tor users.
|
||||
- Offline qrcode creator and scanning tool
|
||||
- HD (bip32) support
|
||||
- Supports altcoins such as litecoin
|
||||
- Replace by fee (RBF) Support
|
||||
- Segwit Support
|
||||
- Bech32 address support
|
||||
- Fee calculator - https://coinb.in/#fees
|
||||
|
||||
Donate to 1CWHWkTWaq1K5hevimJia3cyinQsrgXUvg to see more development!
|
||||
Donate to 3K1oFZMks41C7qDYBsr72SYjapLqDuSYuN to see more development!
|
||||
|
||||
Vendored
+5
File diff suppressed because one or more lines are too long
@@ -24,3 +24,97 @@ body {
|
||||
background-color: #f5f5f5;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
overflow: hidden;
|
||||
-ms-text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#fees .txi_regular {
|
||||
background: #d3d3d3;
|
||||
}
|
||||
|
||||
#fees .txi_segwit {
|
||||
background: #bae1ff;
|
||||
}
|
||||
|
||||
#fees .txi_multisig {
|
||||
background: #baffc9;
|
||||
}
|
||||
|
||||
#fees .txi_hodl {
|
||||
background: #ffdfba;
|
||||
}
|
||||
|
||||
#fees .txi_unknown {
|
||||
background: #ffb3ba;
|
||||
}
|
||||
|
||||
#fees .txo_p2pkh {
|
||||
background: #E679C8;
|
||||
}
|
||||
|
||||
#fees .txo_p2sh {
|
||||
background: #FAFE92;
|
||||
}
|
||||
|
||||
#fees .txinputs {
|
||||
}
|
||||
|
||||
#fees .txoutputs {
|
||||
}
|
||||
|
||||
.hideOverflow {
|
||||
overflow:hidden;
|
||||
white-space:nowrap;
|
||||
text-overflow:ellipsis;
|
||||
}
|
||||
|
||||
#fees .slider {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
outline: none;
|
||||
opacity: 0.7;
|
||||
-webkit-transition: .2s;
|
||||
transition: opacity .2s;
|
||||
border: 2px dotted #c3c3c3;
|
||||
}
|
||||
|
||||
#fees .sliderbtn {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
#fees .slider:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#fees .slider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 0;
|
||||
background: url('https://coinb.in/images/btc32x.png');
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#fees .slider::-moz-range-thumb {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 0;
|
||||
background: url('https://coinb.in/images/btc32x.png');
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#fees .total {
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
+637
-28
@@ -5,17 +5,23 @@
|
||||
<title>Bitcoin Wallet by Coinb.in</title>
|
||||
|
||||
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
|
||||
<meta name="keywords" content="bitcoin, wallet, multisig, multisignature, address, browser, javascript, js, broadcast, transaction, verify, decode" />
|
||||
<meta name="description" content="A Bitcoin Wallet written in Javascript. Supports Multisig, Custom Transactions, nLockTime and more!" />
|
||||
<meta name="keywords" content="bitcoin, wallet, multisig, multisignature, address, browser, segwit, javascript, js, broadcast, transaction, verify, decode" />
|
||||
<meta name="description" content="A Bitcoin Wallet written in Javascript. Supports Multisig, SegWit, Custom Transactions, nLockTime and more!" />
|
||||
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" media="screen">
|
||||
<link rel="stylesheet" href="css/bootstrap-datetimepicker.min.css">
|
||||
<link rel="stylesheet" href="css/style.css" media="screen">
|
||||
|
||||
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
|
||||
<script type="text/javascript" src="js/moment.min.js"></script>
|
||||
<script type="text/javascript" src="js/transition.js"></script>
|
||||
<script type="text/javascript" src="js/collapse.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="js/bootstrap-datetimepicker.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/crypto-min.js"></script>
|
||||
<script type="text/javascript" src="js/crypto-sha256.js"></script>
|
||||
@@ -52,8 +58,10 @@
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-plus"></span> New<b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#newAddress" data-toggle="tab">New Address</a></li>
|
||||
<li><a href="#newAddress" data-toggle="tab">Address</a></li>
|
||||
<li><a href="#newSegWit" data-toggle="tab">SegWit Address</a></li>
|
||||
<li><a href="#newMultiSig" data-toggle="tab">MultiSig Address</a></li>
|
||||
<li><a href="#newTimeLocked" data-toggle="tab">Time Locked Address</a></li>
|
||||
<li><a href="#newHDaddress" data-toggle="tab">HD Address</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#newTransaction" data-toggle="tab">Transaction</a></li>
|
||||
@@ -66,6 +74,7 @@
|
||||
<li><a href="#about" data-toggle="tab"><span class="glyphicon glyphicon-info-sign"></span> About</a></li>
|
||||
|
||||
<li class="hidden"><a href="#settings" data-toggle="tab"><span class="glyphicon glyphicon-cog"></span> Settings</a></li>
|
||||
<li class="hidden"><a href="#fees" data-toggle="tab"><span class="glyphicon glyphicon-tag"></span> Fees</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -94,7 +103,7 @@
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h3><span class="glyphicon glyphicon-ok"></span> Open Source</h3>
|
||||
<p>Coinbin is an open source web based wallet written in javascript and released under the <a href="LICENSE">MIT license</a> which means its free to use and edit.</p>
|
||||
<p>Coinbin is an open source web based wallet written in javascript and released under the <a href="LICENSE">MIT license</a> which means it's free to use and edit.</p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
@@ -111,12 +120,12 @@
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h3><span class="glyphicon glyphicon-piggy-bank"></span> Wallet</h3>
|
||||
<p>Quick access to an <a href="#wallet">online wallet</a> where only you have access to your own private keys!</p>
|
||||
<p>Quick access to an <a href="#wallet">online wallet</a> where only you have access to your own private keys & can <a href="#fees">calculate your own fee</a>!</p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<h3><span class="glyphicon glyphicon-globe"></span> Addresses</h3>
|
||||
<p>We support <a href="#newAddress">regular addresses</a> but also <a href="#newMultiSig">multisig</a> and stealth, and access to your own private keys!</p>
|
||||
<p>We support <a href="#newAddress">regular addresses</a>, <a href="#newMultiSig">multisig</a>, <a href="#newSegWit">segwit / bech32</a> and stealth all with access to your own private keys!</p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
@@ -143,6 +152,22 @@
|
||||
<input id="openPass" type="password" class="form-control" placeholder="Password" required>
|
||||
<input id="openPassConfirm" type="password" class="form-control" placeholder="Password confirm" required>
|
||||
<br>
|
||||
|
||||
<div>
|
||||
<a href="javascript:;" class="optionsCollapse"><div class="well well-sm"><span class="glyphicon glyphicon-collapse-down" id="glyphcollapse"></span> Advanced Options</div></a>
|
||||
<div class="hidden optionsAdvanced">
|
||||
<label>Segregated Witness Address</label>
|
||||
<p class="checkbox">
|
||||
<label><input type="checkbox" id="walletSegwit" class="checkbox-inline" checked> Use a segwit address instead of a regular address. <span class="text-muted"><i>(recommended)</i></span></label></label>
|
||||
</p>
|
||||
|
||||
<label>Enable Replace by Fee (RBF)</label>
|
||||
<p class="checkbox">
|
||||
<label><input type="checkbox" id="walletRBF" class="checkbox-inline" checked> Enable RBF on all transactions, allowing you to manually raise the transaction fee later if required. <span class="text-muted"><i>(recommended)</i></span></label></label>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="openLoginStatus" class="alert alert-danger hidden"></div>
|
||||
<button id="openBtn" class="btn btn-primary" type="submit">Submit</button>
|
||||
</form>
|
||||
@@ -158,6 +183,14 @@
|
||||
<div>
|
||||
<span id="walletLoader" class="hidden"><img src="images/loader.gif"></span>
|
||||
<span id="walletAddress"></span>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" id="walletToBtn">SegWit <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="javascript:;" id="walletToSegWit">SegWit</a></li>
|
||||
<li><a href="javascript:;" id="walletToLegacy">Legacy</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div style="text-align:center; width:350px;">
|
||||
@@ -165,6 +198,7 @@
|
||||
<li role="presentation" class="active"><a href="javascript:;" id="walletBalance">0.00 BTC</a></li>
|
||||
<li role="presentation"><a href="javascript:;" id="walletShowSpend">Spend</a></li>
|
||||
<li role="presentation"><a id="walletHistory" href="javascript:;" target="_blank">History</a></li>
|
||||
<li role="presentation"><a href="https://localbitcoins.com/?ch=173j" target="_blank">Buy</a></li>
|
||||
<li role="presentation"><a href="javascript:;" id="walletShowKeys">Keys</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -173,6 +207,12 @@
|
||||
<div id="walletKeys" class="hidden">
|
||||
<label>Public Key</label>
|
||||
<input class="form-control pubkey" type="text" readonly>
|
||||
|
||||
<div class="walletSegWitRS hidden">
|
||||
<label>Redeem Script <i>(SegWit)</i></label>
|
||||
<input class="form-control" type="text" readonly>
|
||||
</div>
|
||||
|
||||
<label>Private key</label>
|
||||
<div class="input-group">
|
||||
<input class="form-control privkey" type="password" readonly>
|
||||
@@ -181,6 +221,7 @@
|
||||
<button class="showKey btn btn-default" type="button">Show</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<label>Private Key (AES256 encrypted key)</label>
|
||||
<input class="form-control privkeyaes" type="text" readonly>
|
||||
</div>
|
||||
@@ -214,12 +255,12 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<label><abbr title="the amount to pay in network miner fees - 0.0001 or more recommended">Transaction Fee</abbr></label>
|
||||
<input type="text" class="form-control" value="0.00001" id="txFee">
|
||||
<label><abbr title="the amount to pay in network miner fee">Transaction Fee</abbr> <a href="javascript:;" id="feesestwallet"><span class="glyphicon glyphicon-question-sign"></span></a></label>
|
||||
<input type="text" class="form-control" value="0.0004" id="txFee">
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
<label><abbr title="the amount to donate to the sites developer">Donation</abbr></label>
|
||||
<input type="text" class="form-control" value="0.00" id="developerDonation">
|
||||
<label><abbr title="the amount to donate to coinb.in">Donation</abbr></label>
|
||||
<input type="text" class="form-control" value="0.003" id="developerDonation">
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
@@ -298,11 +339,68 @@
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane tab-content" id="newSegWit">
|
||||
<h2>New SegWit Address <small> Smaller & Faster Transactions</small></h2>
|
||||
|
||||
<p>Any keys used you will need to manually store safely as they will be needed later to redeem the bitcoins.</p>
|
||||
|
||||
<label>SegWit Address (Share)</label>
|
||||
|
||||
<div class="input-group">
|
||||
<input id="newSegWitAddress" type="text" class="form-control address" value="" readonly>
|
||||
<span class="input-group-btn">
|
||||
<button class="qrcodeBtn btn btn-default" type="button" data-toggle="modal" data-target="#modalQrcode"><span class="glyphicon glyphicon-qrcode"></span></button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<label>RedeemScript</label>
|
||||
<input id="newSegWitRedeemScript" type="text" class="form-control" readonly>
|
||||
|
||||
<label>Public key</label>
|
||||
<input id="newSegWitPubKey" type="text" class="form-control" readonly>
|
||||
|
||||
<label>Private key (WIF key)</label>
|
||||
<div class="input-group">
|
||||
<input id="newSegWitPrivKey" type="password" class="form-control" value="" readonly>
|
||||
<span class="input-group-btn">
|
||||
<button class="showKey btn btn-default" type="button">Show</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<h3>Address Options</h3>
|
||||
<p>You can use the advanced options below to generate different kind of keys and addresses.</p>
|
||||
|
||||
<div class="checkbox">
|
||||
<label><input type="checkbox" id="newSegWitBech32addr" class="checkbox-inline" checked> Enable <a href="https://en.bitcoin.it/wiki/Bech32" target="_blank">Bech32</a>?</label>
|
||||
</div>
|
||||
|
||||
<div class="checkbox">
|
||||
<label><input type="checkbox" id="newSegWitBrainwallet" class="checkbox-inline"> Custom Seed or Brain Wallet</label>
|
||||
<input type="text" class="form-control hidden" id="brainwalletSegWit">
|
||||
</div>
|
||||
|
||||
<input type="button" class="btn btn-primary" value="Generate" id="newSegWitKeysBtn">
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane tab-content" id="newMultiSig">
|
||||
<h2>New Multisig Address <small>Secure multisig address</small></h2>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-8">
|
||||
<p>Public keys can be <a href="#newAddress">generated in your browser</a> or from your bitcoin client</a>.</p>
|
||||
<p>Enter the public keys of all the participants, to create a <a href="https://en.bitcoin.it/wiki/Address#Multi-signature_addresses" target="_blank">multi signature address</a>. Maximum of 15 allowed. Compressed and uncompressed public keys are accepted.</p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<p class="alert alert-info"><span class="glyphicon glyphicon-info-sign"></span> <a href="javascript:;" data-toggle="modal" data-target="#modalMediator"><abbr>Need a Mediator?</abbr></a></p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-1">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="multisigPubKeys" class="row">
|
||||
<div class="form-horizontal">
|
||||
@@ -358,13 +456,90 @@
|
||||
<p>This script should be <i>saved and should be shared with all the participants before a payment is made</i>, so they may validate the authenticity of the address, it will also be used later to release the bitcoins.</p>
|
||||
<textarea class="form-control script" style="height:160px" readonly></textarea>
|
||||
<label>Shareable URL</label>
|
||||
<input type="text" class="scriptUrl form-control" disabled>
|
||||
<input type="text" class="scriptUrl form-control" readonly>
|
||||
</div>
|
||||
|
||||
<input type="button" class="btn btn-primary" value="Submit" id="newMultiSigAddress">
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane tab-content" id="newTimeLocked">
|
||||
<h2>New Time Locked Address <small>Coins can be released only after a certain date</small></h2>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-11">
|
||||
<p>Use <i><a href="https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki" target="_blank">OP_CHECKLOCKTIMEVERIFY</a></i> (OP_HODL) to create a time locked address where the funds are unspendable until a set date and time has passed.</p>
|
||||
<p>Public keys can be <a href="#newAddress">generated in your browser</a> or from your bitcoin client</a>.</p>
|
||||
<p>Enter the public key that will be able to unlock the funds after the a certain date.
|
||||
</div>
|
||||
|
||||
<div class="col-md-1">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-horizontal">
|
||||
<div class="col-xs-12">
|
||||
<input id="timeLockedPubKey" type="text" class="form-control pubkey">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p id="timeLockedRbTypeBox">
|
||||
Enter the
|
||||
<input type="radio" id="timeLockedRbTypeDate" name="timeLockedRbType" value="date" checked="checked">
|
||||
<label for="timeLockedRbTypeDate">date and time</label>
|
||||
or
|
||||
<input type="radio" id="timeLockedRbTypeBlockHeight" name="timeLockedRbType" value="blockheight">
|
||||
<label for="timeLockedRbTypeBlockHeight">blockheight</label>
|
||||
|
||||
required to release the coins:
|
||||
</p>
|
||||
<div class="row">
|
||||
<div class='col-md-6'>
|
||||
<div class="form-group">
|
||||
<div class='input-group date' id='timeLockedDateTimePicker'>
|
||||
<input type='text' class="form-control" placeholder="MM/DD/YYYY hh:mm" />
|
||||
<span class="input-group-addon">
|
||||
<span class="glyphicon glyphicon-calendar"></span>
|
||||
</span>
|
||||
</div>
|
||||
<div class='input-group hidden' id='timeLockedBlockHeight'>
|
||||
<input type='text' id='timeLockedBlockHeightVal' class="form-control" placeholder="Blockheight" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div id="timeLockedErrorMsg" class="alert alert-danger" style="display:none;"></div>
|
||||
|
||||
<div class="alert alert-success hidden" id="timeLockedData">
|
||||
<label>Address</label>
|
||||
<p>Payment should be made to this address:</p>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control address" value="" readonly>
|
||||
<span class="input-group-btn">
|
||||
<button class="qrcodeBtn btn btn-default" type="button" data-toggle="modal" data-target="#modalQrcode"><span class="glyphicon glyphicon-qrcode"></span></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<label>Redeem Script</label>
|
||||
<p>This script should be <i>saved and should be shared with all the participants before a payment is made</i>, so they may validate the authenticity of the address, it will also be used later to release the bitcoins.</p>
|
||||
<textarea class="form-control script" style="height:160px" readonly></textarea>
|
||||
<label>Shareable URL</label>
|
||||
<input type="text" class="scriptUrl form-control" readonly>
|
||||
</div>
|
||||
|
||||
<input type="button" class="btn btn-primary" value="Submit" id="newTimeLockedAddress">
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane tab-content" id="newHDaddress">
|
||||
<h2>New HD Address <small>making bip32 even easier</small></h2>
|
||||
<p>Use the form below to generate a <i>master</i> hierarchical deterministic address.</p>
|
||||
@@ -400,7 +575,7 @@
|
||||
<h2>Transaction <small>Create a new transaction</small></h2>
|
||||
<p>Use this page to create a raw transaction</p>
|
||||
|
||||
<b>Address, WIF key or Multisig Redeem Script</b>:
|
||||
<b>Address, WIF key or Redeem Script</b>:
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-info qrcodeScanner" type="button" data-toggle="modal" data-target="#modalQrcodeScanner" forward-result="#redeemFrom"><span class="glyphicon glyphicon-camera"></span></button>
|
||||
@@ -418,9 +593,9 @@
|
||||
<div class="hidden alert alert-info" id="redeemFromAddress"></div>
|
||||
|
||||
<div>
|
||||
<a href="javascript:;" id="optionsCollapse"><div class="well well-sm"><span class="glyphicon glyphicon-collapse-down" id="glyphcollapse"></span> Advanced Options</div></a>
|
||||
<a href="javascript:;" class="optionsCollapse"><div class="well well-sm"><span class="glyphicon glyphicon-collapse-down" id="glyphcollapse"></span> Advanced Options</div></a>
|
||||
|
||||
<div class="hidden" id="optionsAdvanced">
|
||||
<div class="hidden optionsAdvanced">
|
||||
|
||||
<label>Clear Inputs</label>
|
||||
<p class="checkbox">
|
||||
@@ -429,7 +604,7 @@
|
||||
|
||||
<hr>
|
||||
|
||||
<label>Null Data</label> <span class="text-muted text-normal">(40 byte limit)</span>
|
||||
<label>Null Data</label> <span class="text-muted text-normal">(80 byte limit, <i>40 bytes recommended</i>)</span>
|
||||
<p class="checkbox">
|
||||
<label><input type="checkbox" id="opReturn" class="checkbox-inline"> Allow data to be sent within the transaction and stored in the blockchain by using <a href="https://bitcoin.org/en/developer-guide#null-data" target="_"blank">OP_RETURN</a>.</label>
|
||||
<div class="text-muted">When using this option you may enter a hex string or address into the address field on the output tab.</div>
|
||||
@@ -442,6 +617,19 @@
|
||||
<input type="text" class="form-control" value="0" id="nLockTime">
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<label>Replace By Fee (RBF)</label>
|
||||
<p class="checkbox">
|
||||
<label><input type="checkbox" id="txRBF" class="checkbox-inline"> Make this a <a href="https://en.bitcoin.it/wiki/Transaction_replacement" target="_blank">RBF transaction</a>.</label>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<label>Network</label>
|
||||
<p>The <a href="#settings">settings</a> page can be used to select alternative networks of which you can retrieve your unspent outputs and broadcast a signed transaction into.</p>
|
||||
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -453,7 +641,11 @@
|
||||
<br>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade in active" id="txoutputs">
|
||||
|
||||
<span class="pull-right"><a href="javascript:;" id="donateTxBtn" class="btn btn-link"><span class="glyphicon glyphicon-heart"></span> Donate!</a></span>
|
||||
|
||||
<p>Enter the address and amount you wish to make a payment to.</p>
|
||||
<div class="row">
|
||||
<div class="col-xs-8">
|
||||
@@ -529,13 +721,15 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-3">
|
||||
<label><abbr title="What is not spent will be used as a transaction fee">Transaction Fee</abbr></label>
|
||||
<label><abbr title="What is not spent will be used as a transaction fee, so remember to add a "change address"">Transaction Fee</abbr> <a href="javascript:;" id="feesestnewtx"><span class="glyphicon glyphicon-question-sign"></span></a></label>
|
||||
<input type="text" id="transactionFee" class="form-control" value="0.0000" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div id="transactionCreateStatus" class="alert alert-danger hidden"></div>
|
||||
|
||||
<div id="transactionCreate" class="alert alert-success hidden">
|
||||
<label>Transaction</label>
|
||||
<button class="qrcodeBtn btn btn-default" type="button" data-toggle="modal" data-target="#modalQrcode" style="float:right;"><span class="glyphicon glyphicon-qrcode"></span></button>
|
||||
@@ -552,6 +746,211 @@
|
||||
<br>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="tab-pane tab-content" id="fees">
|
||||
<h2>Bitcoin Fee Calculator</h2>
|
||||
<p>This page will give you a guide on the lowest fee to use to get your transaction included within the next few blocks. It works by predicting the size of a transaction and comparing it to another transaction in a recent block to determine an appropriate fee.</p>
|
||||
|
||||
<div align="center" class="alert alert-info">
|
||||
<h2><span class="glyphicon glyphicon-question-sign"></span> Recommended Fee: <span class="recommendedFee">0.00000000</span> BTC <small> <br> for a transaction of <span class="feeTxSize">0</span> bytes</small></h2>
|
||||
<span class="text-muted"><i><span class="feeSatByte">?</span> Sat/Byte</i></span>
|
||||
</div>
|
||||
|
||||
<div id="txsliders" class="row">
|
||||
<div class="col-md-6 txinputs">
|
||||
|
||||
<div align="center"><b><span class="txtotal total">0</span><br>Inputs</b></div>
|
||||
<div id="txinputstype" align="center" class="small text-muted">
|
||||
<br>
|
||||
<span><span class="txsize">0</span> Bytes</span>
|
||||
</div>
|
||||
|
||||
<h4 class="regular"><abbr title="Spending from a compressed legacy address. p2pkh">Regular</abbr> <small>Compressed</small>
|
||||
<span class="badge inputno" title="Number of Regular Inputs">1</span>
|
||||
<small><span class="bytes">148</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="1" class="slider txinput txi_regular" rel="regular">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<h4 class="segwit"><abbr title="Spending from a segwit address. p2sh">SegWit</abbr>
|
||||
<span class="badge inputno" title="Number of SegWit Inputs">0</span>
|
||||
<small><span class="bytes">0</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="0" class="slider txinput txi_segwit" rel="segwit">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<h4 class="multisig"><abbr title="Spending from a multisig address. p2sh">MultiSig</abbr>
|
||||
<span class="badge inputno" title="Number of MultiSig Inputs">0</span>
|
||||
<small><span class="bytes">0</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="0" class="slider txinput txi_multisig" rel="multisig">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<h4 class="hodl"><abbr title="Spending from a time locked address. p2sh">Hodl</abbr> <small>Time Locked</small>
|
||||
<span class="badge inputno" title="Number of Hodl Inputs">0</span>
|
||||
<small><span class="bytes">0</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="0" class="slider txinput txi_hodl" rel="hodl">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<h4 class="unknown"><abbr title="Spending from an unrecognized input. p2sh">Unknown</abbr>
|
||||
<span class="badge inputno" title="Number of Unknown Inputs">0</span>
|
||||
<small><span class="bytes">0</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="0" class="slider txinput txi_unknown" rel="unknown">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 txoutputs">
|
||||
|
||||
<div align="center"><b><span class="txtotal total">0</span><br>Outputs</b></div>
|
||||
<div id="txoutputtype" align="center" class="small text-muted">
|
||||
<br>
|
||||
<span><span class="txsize">0</span> Bytes</span>
|
||||
</div>
|
||||
|
||||
<h4 class="p2pkh"><abbr title="A pay 2 public key hash. Starts with 1. Used with legacy addresses">Regular</abbr> <small>p2pkh (1...)</small>
|
||||
<span class="badge outputno" title="Number of p2pkh Outputs">2</span>
|
||||
<small><span class="bytes">68</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="2" class="slider txoutput txo_p2pkh" rel="p2pkh">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<h4 class="p2sh"><abbr title="A pay 2 script hash address. Starts with a 3. For example a segwit or multisig address">Regular</abbr> <small>p2sh (3...)</small>
|
||||
<span class="badge outputno" title="Number of p2sh Outputs">0</span>
|
||||
<small><span class="bytes">0</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="0" class="slider txoutput txo_p2sh" rel="p2sh">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="text-muted">Chargable Transaction Size: <span class="feeTxSize">0</span> bytes</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12 recommended">
|
||||
|
||||
<h3>Blockchain Data <span class="pull-right"><button type="button" id="feeStatsReload" class="btn btn-default btn-sm"><span class="glyphicon glyphicon-refresh"></span></button></span></h3>
|
||||
|
||||
<p>This is based on us comparing your transaction against a very recent transaction found in a very recent block</p>
|
||||
<p><b>Block Height</b>: <span class="blockHeight">?</span></p>
|
||||
<p class="hideOverflow"><b>Block #</b>: <span class="blockHash">?</span></p>
|
||||
<p><b>Block Time</b>: <span class="blockTime">?</span> <span class="blockDateTime text-muted"></span></p>
|
||||
<p class="hideOverflow"><b>Transaction ID</b>: <span class="txId">?</span></p>
|
||||
<p><b>Transaction Size</b>: <span class="txSize">0</span> bytes</p>
|
||||
<p><b>Transaction Fee</b>: <span class="txFee">0.00000000</span></p>
|
||||
<p><b>Satoshi per Byte</b>: <span class="feeSatByte">0</span></p>
|
||||
|
||||
<p>Based on your data and this recently mined transaction we recommend a fee of <b><span class="recommendedFee">0.00000000</span> BTC</b> to get it into the next few blocks</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-12">
|
||||
<a href="javascript:;" id="advancedFeesCollapse">
|
||||
<div class="well well-sm"><span class="glyphicon glyphicon-collapse-down"></span> Advanced Options & Raw Transaction</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row hidden" id="advancedFees">
|
||||
<div class="col-md-12">
|
||||
<p>Enter your unsigned or signed hex encoded transaction below:</p>
|
||||
<textarea class="form-control txhex" style="height:160px"></textarea><br>
|
||||
<button type="button" class="btn btn-primary" id="feesAnalyseBtn">Analyse Transaction</button>
|
||||
|
||||
<hr>
|
||||
|
||||
<h4>Estimate Input Size <small>in bytes</small></h4>
|
||||
|
||||
<div class="form-inline">
|
||||
<div class="form-group">
|
||||
<label for="est_txi_regular">Regular</label>
|
||||
<input type="number" class="form-control" id="est_txi_regular" value="107">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="est_txi_segwit">SegWit</label>
|
||||
<input type="number" class="form-control" id="est_txi_segwit" value="27">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="est_txi_multisig">MultiSig</label>
|
||||
<input type="number" class="form-control" id="est_txi_multisig" value="351">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="est_txi_hodl">Hodl</label>
|
||||
<input type="number" class="form-control" id="est_txi_hodl" value="78">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="est_txi_unknown">Unknown</label>
|
||||
<input type="number" class="form-control" id="est_txi_unknown" value="512">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>Estimate Output Size <small> in bytes</small></h4>
|
||||
<div class="form-inline">
|
||||
<div class="form-group">
|
||||
<label for="est_txo_p2pkh">Regular P2PKH</label>
|
||||
<input type="number" class="form-control" id="est_txo_p2pkh" value="25">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="est_txo_p2sh">Regular P2SH</label>
|
||||
<input type="number" class="form-control" id="est_txo_p2sh" value="23">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane tab-content" id="verify">
|
||||
<h2>Verify <small>transactions and other scripts</small></h2>
|
||||
<div class="row">
|
||||
@@ -563,8 +962,11 @@
|
||||
<br>
|
||||
|
||||
<div class="hidden verifyData" id="verifyRsData">
|
||||
|
||||
<h4>Redeem Script</h4>
|
||||
<p><span style="float:right"><a href="javascript:;" target="_blank" class="verifyLink" title="Link to this page"><span class="glyphicon glyphicon-link"></span></a></span>The above redeem script has been decoded</p>
|
||||
|
||||
<div class="hidden" id="verifyRsDataMultisig">
|
||||
<label>Multi Signature Address</label>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
@@ -576,6 +978,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>Required Signatures</label>
|
||||
<p class="signaturesRequired">?</p>
|
||||
<label>Signatures Required from</label>
|
||||
@@ -583,6 +986,58 @@
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div class="hidden verifyData" id="verifyRsDataSegWit">
|
||||
<label>Segwit Address</label>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control address segWitAddress" value="" readonly>
|
||||
<span class="input-group-btn">
|
||||
<button class="qrcodeBtn btn btn-default" type="button" data-toggle="modal" data-target="#modalQrcode"><span class="glyphicon glyphicon-qrcode"></span></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div class="hidden verifyData" id="verifyRsDataHodl">
|
||||
<label>Hodl Address</label>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control address" value="" readonly>
|
||||
<span class="input-group-btn">
|
||||
<button class="qrcodeBtn btn btn-default" type="button" data-toggle="modal" data-target="#modalQrcode"><span class="glyphicon glyphicon-qrcode"></span></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>Required Signature</label>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control address pubkey" value="" readonly>
|
||||
<span class="input-group-btn">
|
||||
<button class="qrcodeBtn btn btn-default" type="button" data-toggle="modal" data-target="#modalQrcode"><span class="glyphicon glyphicon-qrcode"></span></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>Unlock Time</label>
|
||||
<div class="row">
|
||||
<div class='col-md-4'>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control date" value="" readonly>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hidden verifyData" id="verifyTransactionData">
|
||||
@@ -591,6 +1046,8 @@
|
||||
<div><b>Version</b>: <span class="transactionVersion"></span></div>
|
||||
<div><b>Transaction Size</b>: <span class="transactionSize"></span></div>
|
||||
<div><b>Lock time</b>: <span class="transactionLockTime"></span></div>
|
||||
<div class="transactionSegWit"><b>SegWit</b>: True</div>
|
||||
<div class="transactionRBF"><b>RBF</b>: This is a <a href="https://en.bitcoin.it/wiki/Transaction_replacement">replace by fee</a> transaction!</div>
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -617,6 +1074,7 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="hidden verifyData" id="verifyPrivKey">
|
||||
<h4>WIF key</h4>
|
||||
<p>The above wif key has been decoded</p>
|
||||
@@ -630,7 +1088,33 @@
|
||||
<div class="hidden verifyData" id="verifyPubKey">
|
||||
<h4>Public key</h4>
|
||||
<p><span style="float:right"><a href="" target="_blank" class="verifyLink" title="Link to this page"><span class="glyphicon glyphicon-link"></span></a></span>The above public key has been encoded to its address</p>
|
||||
<p><b>Address</b>: <input type="text" class="form-control address" readonly></p>
|
||||
<p><b>Legacy Address</b>: <input type="text" class="form-control address" readonly></p>
|
||||
|
||||
<div class="hidden verifyDataSw">
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<p><b>P2SH Segwit Address</b>: <input type="text" class="form-control addressSegWit" readonly></p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<p><b>P2SH Segwit Redeem Script</b>: <input type="text" class="form-control addressSegWitRedeemScript" readonly></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<p><b>Bech32 Address</b>: <input type="text" class="form-control addressBech32" readonly></p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<p><b>Bech32 Redeem Script</b>: <input type="text" class="form-control addressBech32RedeemScript" readonly></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hidden verifyData" id="verifyHDaddress">
|
||||
@@ -726,11 +1210,13 @@
|
||||
|
||||
<input type="button" value="Submit" class="btn btn-primary" id="verifyBtn">
|
||||
<br>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane tab-content" id="sign">
|
||||
<h2>Sign Transaction <small>once a transaction has been verified</small></h2>
|
||||
<p>Once you have <a href="#verify">verified</a> a transaction you can sign and then <a href="#broadcast">broadcast</a> it into the network.</p>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<label for="signPrivateKey">Private key</label>
|
||||
@@ -752,6 +1238,33 @@
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<a href="javascript:;" id="signAdvancedCollapse">
|
||||
<div class="well well-sm"><span class="glyphicon glyphicon-collapse-down"></span> Advanced Options</div>
|
||||
</a>
|
||||
|
||||
<div id="signAdvanced" class="hidden">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<label for="sighashType">Sig Hash Type</label>
|
||||
|
||||
<select id="sighashType" class="form-control">
|
||||
<option value="1" rel="SIGHASH_ALL: Signs all the inputs and outputs, protecting everything against modification.">ALL (default)</option>
|
||||
<option value="2" rel="SIGHASH_NONE: Signs all of the inputs but none of the outputs, allowing anyone to change where the satoshis are going unless other signatures using other signature hash flags protect the outputs.">NONE</option>
|
||||
<option value="3" rel="SIGHASH_SINGLE: The only output signed is the one corresponding to this input, ensuring nobody can change your part of the transaction but allowing other signers to change their part of the transaction.">SINGLE</option>
|
||||
<option value="129" rel="SIGHASH_ALL|SIGHASH_ANYONECANPAY: Signs all of the outputs but only this one input, it allows anyone to add or remove other inputs, so anyone can contribute additional satoshis but they cannot change how many satoshis are sent nor where they go.">ALL|ANYONECANPAY</option>
|
||||
<option value="130" rel="SIGHASH_NONE|SIGHASH_ANYONECANPAY: Signs only this one input and allows anyone to add or remove other inputs or outputs, so anyone who gets a copy of this input can spend it however they'd like.">NONE|ANYONECANPAY</option>
|
||||
<option value="131" rel="SIGHASH_SINGLE|SIGHASH_ANYONECANPAY: Signs this one input and its corresponding output. Allows anyone to add or remove other inputs.">SINGLE|ANYONECANPAY</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="alert alert-info" id="sighashTypeInfo">
|
||||
SIGHASH_ALL: The default, signs all the inputs and outputs, protecting everything except the signature scripts against modification.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-danger hidden" id="signedDataError">
|
||||
<span class="glyphicon glyphicon-exclamation-sign"></span> There is a problem with one or more of your inputs, please check and try again
|
||||
</div>
|
||||
@@ -772,6 +1285,7 @@
|
||||
|
||||
<div class="tab-pane tab-content" id="broadcast">
|
||||
<h2>Broadcast Transaction <small>into the bitcoin network</small></h2>
|
||||
<a href="#settings" style="float:right;"><span class="glyphicon glyphicon-cog"></span></a>
|
||||
<p>Enter your hex encoded bitcoin transaction</p>
|
||||
<textarea class="form-control" style="height:125px" id="rawTransaction"></textarea>
|
||||
<br>
|
||||
@@ -789,19 +1303,22 @@
|
||||
|
||||
<div class="tab-pane tab-content" id="about">
|
||||
<h2>About <small>open source bitcoin wallet</small></h2>
|
||||
<p>Version 1.2</p>
|
||||
<p>Compatible with bitcoin-qt</p>
|
||||
<p>Version 1.4</p>
|
||||
<p>Compatible with bitcoin core</p>
|
||||
<p>Github <a href="https://github.com/OutCast3k/coinbin/">https://github.com/OutCast3k/coinbin/</a></p>
|
||||
<p>TOR <a href="http://4zpinp6gdkjfplhk.onion">4zpinp6gdkjfplhk.onion</a></p>
|
||||
<h3>What is bitcoin?</h3>
|
||||
<h3>What is Bitcoin?</h3>
|
||||
<p>Bitcoin is a type of digital currency in which encryption techniques are used to regulate the generation of units of currency and verify the transfer of funds, operating independently of a central bank. See <a href="http://www.weusecoins.com/" target="_blank">weusecoins.com</a> for more information.</p>
|
||||
<p>If you are looking to buy some Bitcoin try <a href="https://localbitcoins.com/?ch=173j" target="_blank">LocalBitcoins.com</a>.</p>
|
||||
<h3>Information</h3>
|
||||
<p>Coinb.in is a free and open source project released under the MIT license, originally by <a href="https://bitcointalk.org/index.php?action=profile;u=34834" target="_blank">OutCast3k</a> in 2013. Discussion of the project can be found at <a href="https://bitcointalk.org/index.php?topic=390046" target="_blank">bitcointalk.org</a> during its early testing stages when its primary focus was to develop a proof of concept multisig solution in javascript.</p>
|
||||
<p>Coinb.in is run and funded by the generosity of others in terms of <a href="https://github.com/OutCast3k/coinbin/graphs/contributors" target="_blank">development</a> and hosting.</p>
|
||||
<h3>Privacy</h3>
|
||||
<p>Coinb.in beleives strongly in privacy, not only do we support the use of TOR, the site does not collect and store IP or transaction data via our servers nor do we store your bitcoins private key. We do use google analytics to track hits and route traffic via cloudflare using an SSL certificate.</p>
|
||||
<p>Coinb.in believes strongly in privacy, not only do we support the use of TOR, the site does not collect and store IP or transaction data via our servers nor do we store your bitcoins private key. We do route traffic via cloudflare using an SSL certificate.</p>
|
||||
<h3>Support</h3>
|
||||
<p>We recommend that you first check our <a href="https://status.coinb.in/" target="_blank">service status</a> page and then <a href="https://blog.coinb.in/" target="_blank">blog</a> page which has multiple <a href="https://blog.coinb.in/guides" target="_blank">guides</a>. However if the problem persists you can contact us by emailing support{at}coinb.in.</p>
|
||||
<h3>Donate</h3>
|
||||
<p>Please donate to <a href="bitcoin:1CWHWkTWaq1K5hevimJia3cyinQsrgXUvg">1CWHWkTWaq1K5hevimJia3cyinQsrgXUvg</a> if you found this project useful or want to see more features!</p>
|
||||
<p>Please donate to <a href="bitcoin:3K1oFZMks41C7qDYBsr72SYjapLqDuSYuN">3K1oFZMks41C7qDYBsr72SYjapLqDuSYuN</a> if you found this project useful or want to see more features!</p>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane tab-content" id="settings">
|
||||
@@ -814,7 +1331,10 @@
|
||||
<p class="text-muted">Select which network you'd like to use for key pair generation.</p>
|
||||
<select class="form-control" id="coinjs_coin">
|
||||
<option value="bitcoin_mainnet" rel="0x00;0x80;0x05;0x488b21e;0x488ade4;coinb.in;coinb.in">Bitcoin (mainnet)</option>
|
||||
<option value="bitcoin_testnet" rel="0x6f;0xef;0xc4;0x043587cf;0x04358394;blockr.io_bitcointestnet;false">Bitcoin (testnet)</option>
|
||||
<option value="dogecoin_mainnet" rel="0x1e;0x9e;0x16;0x0827421e;0x089944e4;chain.so_dogecoin;chain.so_dogecoin">Dogecoin (mainnet)</option>
|
||||
<option value="carboncoin_mainnet" rel="0x2f;0xaf;0x05;0x488b21e;0x488ade4;cryptoid.info_carboncoin;cryptoid.info_carboncoin">Carboncoin (mainnet)</option>
|
||||
<option value="shadowcash_mainnet" rel="0x3f;0xbf;0x7d;0xee80286a;0xee8031e8;false;false">ShadowCash (mainnet)</option>
|
||||
<option value="bitcoin_testnet" rel="0x6f;0xef;0xc4;0x043587cf;0x04358394;false;false">Bitcoin (testnet)</option>
|
||||
|
||||
<option value="custom" rel="0x00;0x80;0x05;0x488b21e;0x488ade4;false;false">Custom</option>
|
||||
</select>
|
||||
@@ -857,7 +1377,7 @@
|
||||
|
||||
<br>
|
||||
|
||||
<div class="alert alert-info"> <span class="glyphicon glyphicon-info-sign"></span> You will not be able to automatically broadcast or retreive your unspent inputs from coinb.in when using this setting and will need to use your desktop client instead, however everything else will continue to function normally.</div>
|
||||
<div class="alert alert-info"> <span class="glyphicon glyphicon-info-sign"></span> You will not be able to automatically broadcast or retreive your unspent outputs from coinb.in when using this setting and will need to use your desktop client instead, however everything else such as creating key pairs, addresses, transaction generation and signing will continue to function normally.</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
@@ -868,8 +1388,10 @@
|
||||
<p class="text-muted">Select the network you wish to broadcast the transaction via</p>
|
||||
<select class="form-control" id="coinjs_broadcast">
|
||||
<option value="coinb.in">coinb.in (Bitcoin mainnet)</option>
|
||||
<option value="blockr.io_bitcoinmainnet"> Blockr.io (Bitcoin mainnet)</option>
|
||||
<option value="blockr.io_bitcointestnet"> Blockr.io (Bitcoin testnet)</option>
|
||||
<option value="chain.so_bitcoinmainnet"> Chain.so (Bitcoin mainnet)</option>
|
||||
<option value="blockcypher_bitcoinmainnet"> Blockcypher.com (Bitcoin mainnet)</option>
|
||||
<option value="chain.so_dogecoin"> Chain.so (Dogecoin)</option>
|
||||
<option value="cryptoid.info_carboncoin"> Cryptoid.info (Carboncoin)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -882,6 +1404,9 @@
|
||||
<p class="text-muted">Select the network you wish to retreive your unspent inputs from</p>
|
||||
<select class="form-control" id="coinjs_utxo">
|
||||
<option value="coinb.in">coinb.in (Bitcoin mainnet)</option>
|
||||
<option value="chain.so_litecoin"> Chain.so (Litecoin)</option>
|
||||
<option value="chain.so_dogecoin"> Chain.so (Dogecoin)</option>
|
||||
<option value="cryptoid.info_carboncoin"> Cryptoid.info (Carboncoin)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -896,7 +1421,7 @@
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<p class="text-muted">This page uses javascript to generate your addresses and sign your transactions within your browser, this means we <i>never</i> receive your private keys, this can be indepently verified by reviewing the source code on <a href="https://github.com/OutCast3k/coinbin/" target="_blank">github</a>. You can even <a href="https://github.com/OutCast3k/coinbin/archive/master.zip">download</a> this page and host it yourself or run it offline!</p>
|
||||
<p class="text-muted">This page uses javascript to generate your addresses and sign your transactions within your browser, this means we <i>never</i> receive your private keys, this can be independently verified by reviewing the source code on <a href="https://github.com/OutCast3k/coinbin/" target="_blank">github</a>. You can even <a href="https://github.com/OutCast3k/coinbin/archive/master.zip">download</a> this page and host it yourself or run it offline!</p>
|
||||
<br>
|
||||
|
||||
</div>
|
||||
@@ -905,7 +1430,7 @@
|
||||
|
||||
<div id="footer">
|
||||
<div class="container text-right">
|
||||
<p class="text-muted">Version 1.2</p>
|
||||
<p class="text-muted">Version 1.4</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -924,6 +1449,12 @@
|
||||
|
||||
<br>
|
||||
<div id="walletSendConfirmStatus" class="alert alert-danger hidden"></div>
|
||||
|
||||
<div id="walletSendFailTransaction" class="alert alert-info hidden">
|
||||
<b>Raw Transaction:</b>
|
||||
<p>Below is a copy of the transaction we tried to submit</p>
|
||||
<textarea class="form-control" readonly></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
@@ -980,6 +1511,84 @@
|
||||
</div>
|
||||
<!-- qrcode scanner modal -->
|
||||
|
||||
<!-- mediator modal -->
|
||||
<div class="modal fade" id="modalMediator" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">Transaction Mediation</h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<p>You can add a public key when creating a <i>2-of-3 multi signature address</i> and for a low fee your mediator will help with the recovery of the funds should any disputes arise.</p>
|
||||
|
||||
<p>Should a dispute arise please contact the below address for further information</p>
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<label>Mediator:</label>
|
||||
|
||||
<!--
|
||||
You need to contact us before adding your pubkey
|
||||
and submitting a pull request on github.
|
||||
|
||||
format is: pubkey;email;fee
|
||||
-->
|
||||
|
||||
<select id="mediatorList" class="form-control">
|
||||
<option value="02b6231cc602740c29436eafbb6448880f4058cc3d2745c709deee313104678277;support@coinb.in;1">Coinb.in</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-5">
|
||||
<label>Address:</label> <span class="text-muted">(for disputes)</span>
|
||||
<input id="mediatorEmail" type="text" class="form-control address" value="" readonly>
|
||||
</div>
|
||||
|
||||
<div class="col-md-2">
|
||||
<label>Fee (%):</label>
|
||||
<input id="mediatorFee" type="text" class="form-control address" value="" readonly>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<label>Public Key:</label>
|
||||
<input id="mediatorPubkey" type="text" class="form-control address" value="" readonly>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary" type="button" id="mediatorAddKey">Add Public Key</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" id="mediatorClose">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- mediator modal -->
|
||||
|
||||
|
||||
<!-- warning (fee) modal -->
|
||||
<div class="modal fade" id="modalWarningFee" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title"><b>Warning High Fee!</b></h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
Please be aware that you have created a transaction with what seems to be a very high fee of <span id="modalWarningFeeAmount"></span> BTC!
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" data-dismiss="modal" id="warningFeeClose">OK, I've got it!</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- warning (fee) modal -->
|
||||
|
||||
<div class="hidden" id="entropybucket"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Vendored
+9
File diff suppressed because one or more lines are too long
+570
-46
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Coinjs 0.01 beta by OutCast3k{at}gmail.com
|
||||
A bitcoin frameworkcoinjs.
|
||||
A bitcoin framework.
|
||||
|
||||
http://github.com/OutCast3k/coinjs or http://coinb.in/coinjs
|
||||
*/
|
||||
@@ -14,11 +14,12 @@
|
||||
coinjs.priv = 0x80;
|
||||
coinjs.multisig = 0x05;
|
||||
coinjs.hdkey = {'prv':0x0488ade4, 'pub':0x0488b21e};
|
||||
coinjs.bech32 = {'charset':'qpzry9x8gf2tvdw0s3jn54khce6mua7l', 'version':0, 'hrp':'bc'};
|
||||
|
||||
coinjs.compressed = false;
|
||||
|
||||
/* other vars */
|
||||
coinjs.developer = '1CWHWkTWaq1K5hevimJia3cyinQsrgXUvg'; // bitcoin
|
||||
coinjs.developer = '3K1oFZMks41C7qDYBsr72SYjapLqDuSYuN'; //bitcoin
|
||||
|
||||
/* bit(coinb.in) api vars */
|
||||
coinjs.host = ('https:'==document.location.protocol?'https://':'http://')+'coinb.in/api/';
|
||||
@@ -98,9 +99,9 @@
|
||||
}
|
||||
|
||||
/* provide a public key and return address */
|
||||
coinjs.pubkey2address = function(h){
|
||||
coinjs.pubkey2address = function(h, byte){
|
||||
var r = ripemd160(Crypto.SHA256(Crypto.util.hexToBytes(h), {asBytes: true}));
|
||||
r.unshift(coinjs.pub);
|
||||
r.unshift(byte || coinjs.pub);
|
||||
var hash = Crypto.SHA256(Crypto.SHA256(r, {asBytes: true}), {asBytes: true});
|
||||
var checksum = hash.slice(0, 4);
|
||||
return coinjs.base58encode(r.concat(checksum));
|
||||
@@ -132,9 +133,76 @@
|
||||
var checksum = r.slice(0,4);
|
||||
var redeemScript = Crypto.util.bytesToHex(s.buffer);
|
||||
var address = coinjs.base58encode(x.concat(checksum));
|
||||
|
||||
if(s.buffer.length > 520){ // too large
|
||||
address = 'invalid';
|
||||
redeemScript = 'invalid';
|
||||
}
|
||||
|
||||
return {'address':address, 'redeemScript':redeemScript, 'size': s.buffer.length};
|
||||
}
|
||||
|
||||
/* new time locked address, provide the pubkey and time necessary to unlock the funds.
|
||||
when time is greater than 500000000, it should be a unix timestamp (seconds since epoch),
|
||||
otherwise it should be the block height required before this transaction can be released.
|
||||
|
||||
may throw a string on failure!
|
||||
*/
|
||||
coinjs.simpleHodlAddress = function(pubkey, checklocktimeverify) {
|
||||
|
||||
if(checklocktimeverify < 0) {
|
||||
throw "Parameter for OP_CHECKLOCKTIMEVERIFY is negative.";
|
||||
}
|
||||
|
||||
var s = coinjs.script();
|
||||
s.writeBytes(coinjs.numToByteArray(checklocktimeverify));
|
||||
s.writeOp(177);//OP_CHECKLOCKTIMEVERIFY
|
||||
s.writeOp(117);//OP_DROP
|
||||
s.writeBytes(Crypto.util.hexToBytes(pubkey));
|
||||
s.writeOp(172);//OP_CHECKSIG
|
||||
|
||||
var x = ripemd160(Crypto.SHA256(s.buffer, {asBytes: true}), {asBytes: true});
|
||||
x.unshift(coinjs.multisig);
|
||||
var r = x;
|
||||
r = Crypto.SHA256(Crypto.SHA256(r, {asBytes: true}), {asBytes: true});
|
||||
var checksum = r.slice(0,4);
|
||||
var redeemScript = Crypto.util.bytesToHex(s.buffer);
|
||||
var address = coinjs.base58encode(x.concat(checksum));
|
||||
|
||||
return {'address':address, 'redeemScript':redeemScript};
|
||||
}
|
||||
|
||||
/* create a new segwit address */
|
||||
coinjs.segwitAddress = function(pubkey){
|
||||
var keyhash = [0x00,0x14].concat(ripemd160(Crypto.SHA256(Crypto.util.hexToBytes(pubkey), {asBytes: true}), {asBytes: true}));
|
||||
var x = ripemd160(Crypto.SHA256(keyhash, {asBytes: true}), {asBytes: true});
|
||||
x.unshift(coinjs.multisig);
|
||||
var r = x;
|
||||
r = Crypto.SHA256(Crypto.SHA256(r, {asBytes: true}), {asBytes: true});
|
||||
var checksum = r.slice(0,4);
|
||||
var address = coinjs.base58encode(x.concat(checksum));
|
||||
|
||||
return {'address':address, 'type':'segwit', 'redeemscript':Crypto.util.bytesToHex(keyhash)};
|
||||
}
|
||||
|
||||
/* create a new segwit bech32 encoded address */
|
||||
coinjs.bech32Address = function(pubkey){
|
||||
var program = ripemd160(Crypto.SHA256(Crypto.util.hexToBytes(pubkey), {asBytes: true}), {asBytes: true});
|
||||
var address = coinjs.bech32_encode(coinjs.bech32.hrp, [coinjs.bech32.version].concat(coinjs.bech32_convert(program, 8, 5, true)));
|
||||
return {'address':address, 'type':'bech32', 'redeemscript':Crypto.util.bytesToHex(program)};
|
||||
}
|
||||
|
||||
/* extract the redeemscript from a bech32 address */
|
||||
coinjs.bech32redeemscript = function(address){
|
||||
var r = false;
|
||||
var decode = coinjs.bech32_decode(address);
|
||||
if(decode){
|
||||
decode.data.shift();
|
||||
return Crypto.util.bytesToHex(coinjs.bech32_convert(decode.data, 5, 8, true));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* provide a privkey and return an WIF */
|
||||
coinjs.privkey2wif = function(h){
|
||||
var r = Crypto.util.hexToBytes(h);
|
||||
@@ -237,9 +305,14 @@
|
||||
return false;
|
||||
}
|
||||
} catch(e) {
|
||||
bech32rs = coinjs.bech32redeemscript(addr);
|
||||
if(bech32rs){
|
||||
return {'type':'bech32', 'redeemscript':bech32rs};
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* retreive the balance from a given address */
|
||||
coinjs.addressBalance = function(address, callback){
|
||||
@@ -248,6 +321,7 @@
|
||||
|
||||
/* decompress an compressed public key */
|
||||
coinjs.pubkeydecompress = function(pubkey) {
|
||||
if((typeof(pubkey) == 'string') && pubkey.match(/^[a-f0-9]+$/i)){
|
||||
var curve = EllipticCurve.getSECCurveByName("secp256k1");
|
||||
try {
|
||||
var pt = curve.curve.decodePointHex(pubkey);
|
||||
@@ -263,6 +337,128 @@
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
coinjs.bech32_polymod = function(values) {
|
||||
var chk = 1;
|
||||
var BECH32_GENERATOR = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
|
||||
for (var p = 0; p < values.length; ++p) {
|
||||
var top = chk >> 25;
|
||||
chk = (chk & 0x1ffffff) << 5 ^ values[p];
|
||||
for (var i = 0; i < 5; ++i) {
|
||||
if ((top >> i) & 1) {
|
||||
chk ^= BECH32_GENERATOR[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return chk;
|
||||
}
|
||||
|
||||
coinjs.bech32_hrpExpand = function(hrp) {
|
||||
var ret = [];
|
||||
var p;
|
||||
for (p = 0; p < hrp.length; ++p) {
|
||||
ret.push(hrp.charCodeAt(p) >> 5);
|
||||
}
|
||||
ret.push(0);
|
||||
for (p = 0; p < hrp.length; ++p) {
|
||||
ret.push(hrp.charCodeAt(p) & 31);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
coinjs. bech32_verifyChecksum = function(hrp, data) {
|
||||
return coinjs.bech32_polymod(coinjs.bech32_hrpExpand(hrp).concat(data)) === 1;
|
||||
}
|
||||
|
||||
coinjs.bech32_createChecksum = function(hrp, data) {
|
||||
var values = coinjs.bech32_hrpExpand(hrp).concat(data).concat([0, 0, 0, 0, 0, 0]);
|
||||
var mod = coinjs.bech32_polymod(values) ^ 1;
|
||||
var ret = [];
|
||||
for (var p = 0; p < 6; ++p) {
|
||||
ret.push((mod >> 5 * (5 - p)) & 31);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
coinjs.bech32_encode = function(hrp, data) {
|
||||
var combined = data.concat(coinjs.bech32_createChecksum(hrp, data));
|
||||
var ret = hrp + '1';
|
||||
for (var p = 0; p < combined.length; ++p) {
|
||||
ret += coinjs.bech32.charset.charAt(combined[p]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
coinjs.bech32_decode = function(bechString) {
|
||||
var p;
|
||||
var has_lower = false;
|
||||
var has_upper = false;
|
||||
for (p = 0; p < bechString.length; ++p) {
|
||||
if (bechString.charCodeAt(p) < 33 || bechString.charCodeAt(p) > 126) {
|
||||
return null;
|
||||
}
|
||||
if (bechString.charCodeAt(p) >= 97 && bechString.charCodeAt(p) <= 122) {
|
||||
has_lower = true;
|
||||
}
|
||||
if (bechString.charCodeAt(p) >= 65 && bechString.charCodeAt(p) <= 90) {
|
||||
has_upper = true;
|
||||
}
|
||||
}
|
||||
if (has_lower && has_upper) {
|
||||
return null;
|
||||
}
|
||||
bechString = bechString.toLowerCase();
|
||||
var pos = bechString.lastIndexOf('1');
|
||||
if (pos < 1 || pos + 7 > bechString.length || bechString.length > 90) {
|
||||
return null;
|
||||
}
|
||||
var hrp = bechString.substring(0, pos);
|
||||
var data = [];
|
||||
for (p = pos + 1; p < bechString.length; ++p) {
|
||||
var d = coinjs.bech32.charset.indexOf(bechString.charAt(p));
|
||||
if (d === -1) {
|
||||
return null;
|
||||
}
|
||||
data.push(d);
|
||||
}
|
||||
if (!coinjs.bech32_verifyChecksum(hrp, data)) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
hrp: hrp,
|
||||
data: data.slice(0, data.length - 6)
|
||||
};
|
||||
}
|
||||
|
||||
coinjs.bech32_convert = function(data, inBits, outBits, pad) {
|
||||
var value = 0;
|
||||
var bits = 0;
|
||||
var maxV = (1 << outBits) - 1;
|
||||
|
||||
var result = [];
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
value = (value << inBits) | data[i];
|
||||
bits += inBits;
|
||||
|
||||
while (bits >= outBits) {
|
||||
bits -= outBits;
|
||||
result.push((value >> bits) & maxV);
|
||||
}
|
||||
}
|
||||
|
||||
if (pad) {
|
||||
if (bits > 0) {
|
||||
result.push((value << (outBits - bits)) & maxV);
|
||||
}
|
||||
} else {
|
||||
if (bits >= inBits) throw new Error('Excess padding');
|
||||
if ((value << (outBits - bits)) & maxV) throw new Error('Non-zero padding');
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
coinjs.testdeterministicK = function() {
|
||||
// https://github.com/bitpay/bitcore/blob/9a5193d8e94b0bd5b8e7f00038e7c0b935405a03/test/crypto/ecdsa.js
|
||||
@@ -587,7 +783,7 @@
|
||||
} else if (coinjs.isArray(data)) {
|
||||
r.buffer = data;
|
||||
} else if (data instanceof coinjs.script) {
|
||||
r.buffer = r.buffer;
|
||||
r.buffer = data.buffer;
|
||||
} else {
|
||||
r.buffer = data;
|
||||
}
|
||||
@@ -649,6 +845,21 @@
|
||||
r.pubkeys = pubkeys;
|
||||
var multi = coinjs.pubkeys2MultisigAddress(pubkeys, r.signaturesRequired);
|
||||
r.address = multi['address'];
|
||||
r.type = 'multisig__'; // using __ for now to differentiat from the other object .type == "multisig"
|
||||
} else if((s.chunks.length==2) && (s.buffer[0] == 0 && s.buffer[1] == 20)){ // SEGWIT
|
||||
r = {};
|
||||
r.type = "segwit__";
|
||||
var rs = Crypto.util.bytesToHex(s.buffer);
|
||||
r.address = coinjs.pubkey2address(rs, coinjs.multisig);
|
||||
r.redeemscript = rs;
|
||||
|
||||
} else if(s.chunks.length == 5 && s.chunks[1] == 177 && s.chunks[2] == 117 && s.chunks[4] == 172){
|
||||
// ^ <unlocktime> OP_CHECKLOCKTIMEVERIFY OP_DROP <pubkey> OP_CHECKSIG ^
|
||||
r = {}
|
||||
r.pubkey = Crypto.util.bytesToHex(s.chunks[3]);
|
||||
r.checklocktimeverify = coinjs.bytesToNum(s.chunks[0].slice());
|
||||
r.address = coinjs.simpleHodlAddress(r.pubkey, r.checklocktimeverify).address;
|
||||
r.type = "hodl__";
|
||||
}
|
||||
} catch(e) {
|
||||
// console.log(e);
|
||||
@@ -661,7 +872,10 @@
|
||||
r.spendToScript = function(address){
|
||||
var addr = coinjs.addressDecode(address);
|
||||
var s = coinjs.script();
|
||||
if(addr.version==5){ // multisig address
|
||||
if(addr.type == "bech32"){
|
||||
s.writeOp(0);
|
||||
s.writeBytes(Crypto.util.hexToBytes(addr.redeemscript));
|
||||
} else if(addr.version==coinjs.multisig){ // multisig address
|
||||
s.writeOp(169); //OP_HASH160
|
||||
s.writeBytes(addr.bytes);
|
||||
s.writeOp(135); //OP_EQUAL
|
||||
@@ -731,15 +945,16 @@
|
||||
r.lock_time = 0;
|
||||
r.ins = [];
|
||||
r.outs = [];
|
||||
r.witness = false;
|
||||
r.timestamp = null;
|
||||
r.block = null;
|
||||
|
||||
/* add an input to a transaction */
|
||||
r.addinput = function(txid, index, script){
|
||||
r.addinput = function(txid, index, script, sequence){
|
||||
var o = {};
|
||||
o.outpoint = {'hash':txid, 'index':index};
|
||||
o.script = coinjs.script(script||[]);
|
||||
o.sequence = (r.lock_time==0) ? 4294967295 : 0;
|
||||
o.sequence = sequence || ((r.lock_time==0) ? 4294967295 : 0);
|
||||
return this.ins.push(o);
|
||||
}
|
||||
|
||||
@@ -796,7 +1011,7 @@
|
||||
/* add data to a transaction */
|
||||
r.adddata = function(data){
|
||||
var r = false;
|
||||
if(((data.match(/^[a-f0-9]+$/gi)) && data.length<80) && (data.length%2)==0) {
|
||||
if(((data.match(/^[a-f0-9]+$/gi)) && data.length<160) && (data.length%2)==0) {
|
||||
var s = coinjs.script();
|
||||
s.writeOp(106); // OP_RETURN
|
||||
s.writeBytes(Crypto.util.hexToBytes(data));
|
||||
@@ -814,7 +1029,7 @@
|
||||
}
|
||||
|
||||
/* add unspent to transaction */
|
||||
r.addUnspent = function(address, callback){
|
||||
r.addUnspent = function(address, callback, script, segwit, sequence){
|
||||
var self = this;
|
||||
this.listUnspent(address, function(data){
|
||||
var s = coinjs.script();
|
||||
@@ -838,10 +1053,21 @@
|
||||
var u = xmlDoc.getElementsByTagName("unspent_"+i)[0]
|
||||
var txhash = (u.getElementsByTagName("tx_hash")[0].childNodes[0].nodeValue).match(/.{1,2}/g).reverse().join("")+'';
|
||||
var n = u.getElementsByTagName("tx_output_n")[0].childNodes[0].nodeValue;
|
||||
var script = u.getElementsByTagName("script")[0].childNodes[0].nodeValue;
|
||||
var scr = script || u.getElementsByTagName("script")[0].childNodes[0].nodeValue;
|
||||
|
||||
self.addinput(txhash, n, script);
|
||||
if(segwit){
|
||||
/* this is a small hack to include the value with the redeemscript to make the signing procedure smoother.
|
||||
It is not standard and removed during the signing procedure. */
|
||||
|
||||
s = coinjs.script();
|
||||
s.writeBytes(Crypto.util.hexToBytes(script));
|
||||
s.writeOp(0);
|
||||
s.writeBytes(coinjs.numToBytes(u.getElementsByTagName("value")[0].childNodes[0].nodeValue*1, 8));
|
||||
scr = Crypto.util.bytesToHex(s.buffer);
|
||||
}
|
||||
|
||||
var seq = sequence || false;
|
||||
self.addinput(txhash, n, scr, seq);
|
||||
value += u.getElementsByTagName("value")[0].childNodes[0].nodeValue*1;
|
||||
total++;
|
||||
}
|
||||
@@ -870,9 +1096,12 @@
|
||||
}
|
||||
|
||||
/* generate the transaction hash to sign from a transaction input */
|
||||
r.transactionHash = function(index) {
|
||||
r.transactionHash = function(index, sigHashType) {
|
||||
|
||||
var clone = coinjs.clone(this);
|
||||
if((clone.ins) && clone.ins[index]){
|
||||
var shType = sigHashType || 1;
|
||||
|
||||
/* black out all other ins, except this one */
|
||||
for (var i = 0; i < clone.ins.length; i++) {
|
||||
if(index!=i){
|
||||
clone.ins[i].script = coinjs.script();
|
||||
@@ -882,8 +1111,62 @@
|
||||
var extract = this.extractScriptKey(index);
|
||||
clone.ins[index].script = coinjs.script(extract['script']);
|
||||
|
||||
if((clone.ins) && clone.ins[index]){
|
||||
|
||||
/* SIGHASH : For more info on sig hashs see https://en.bitcoin.it/wiki/OP_CHECKSIG
|
||||
and https://bitcoin.org/en/developer-guide#signature-hash-type */
|
||||
|
||||
if(shType == 1){
|
||||
//SIGHASH_ALL 0x01
|
||||
|
||||
} else if(shType == 2){
|
||||
//SIGHASH_NONE 0x02
|
||||
clone.outs = [];
|
||||
for (var i = 0; i < clone.ins.length; i++) {
|
||||
if(index!=i){
|
||||
clone.ins[i].sequence = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} else if(shType == 3){
|
||||
|
||||
//SIGHASH_SINGLE 0x03
|
||||
clone.outs.length = index + 1;
|
||||
|
||||
for(var i = 0; i < index; i++){
|
||||
clone.outs[i].value = -1;
|
||||
clone.outs[i].script.buffer = [];
|
||||
}
|
||||
|
||||
for (var i = 0; i < clone.ins.length; i++) {
|
||||
if(index!=i){
|
||||
clone.ins[i].sequence = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (shType >= 128){
|
||||
//SIGHASH_ANYONECANPAY 0x80
|
||||
clone.ins = [clone.ins[index]];
|
||||
|
||||
if(shType==129){
|
||||
// SIGHASH_ALL + SIGHASH_ANYONECANPAY
|
||||
|
||||
} else if(shType==130){
|
||||
// SIGHASH_NONE + SIGHASH_ANYONECANPAY
|
||||
clone.outs = [];
|
||||
|
||||
} else if(shType==131){
|
||||
// SIGHASH_SINGLE + SIGHASH_ANYONECANPAY
|
||||
clone.outs.length = index + 1;
|
||||
for(var i = 0; i < index; i++){
|
||||
clone.outs[i].value = -1;
|
||||
clone.outs[i].script.buffer = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var buffer = Crypto.util.hexToBytes(clone.serialize());
|
||||
buffer = buffer.concat(coinjs.numToBytes(parseInt(1),4));
|
||||
buffer = buffer.concat(coinjs.numToBytes(parseInt(shType), 4));
|
||||
var hash = Crypto.SHA256(buffer, {asBytes: true});
|
||||
var r = Crypto.util.bytesToHex(Crypto.SHA256(hash, {asBytes: true}));
|
||||
return r;
|
||||
@@ -892,15 +1175,127 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* generate a segwit transaction hash to sign from a transaction input */
|
||||
r.transactionHashSegWitV0 = function(index, sigHashType){
|
||||
/*
|
||||
Notice: coinb.in by default, deals with segwit transactions in a non-standard way.
|
||||
Segwit transactions require that input values are included in the transaction hash.
|
||||
To save wasting resources and potentially slowing down this service, we include the amount with the
|
||||
redeem script to generate the transaction hash and remove it after its signed.
|
||||
*/
|
||||
|
||||
// start redeem script check
|
||||
var extract = this.extractScriptKey(index);
|
||||
if(extract['type'] != 'segwit'){
|
||||
return {'result':0, 'fail':'redeemscript', 'response':'redeemscript missing or not valid for segwit'};
|
||||
}
|
||||
|
||||
if(extract['value'] == -1){
|
||||
return {'result':0, 'fail':'value', 'response':'unable to generate a valid segwit hash without a value'};
|
||||
}
|
||||
|
||||
var scriptcode = Crypto.util.hexToBytes(extract['script']);
|
||||
|
||||
// end of redeem script check
|
||||
|
||||
/* P2WPKH */
|
||||
if(scriptcode.length == 20){
|
||||
scriptcode = [0x00,0x14].concat(scriptcode);
|
||||
}
|
||||
|
||||
if(scriptcode.length == 22){
|
||||
scriptcode = scriptcode.slice(1);
|
||||
scriptcode.unshift(25, 118, 169);
|
||||
scriptcode.push(136, 172);
|
||||
}
|
||||
|
||||
var value = coinjs.numToBytes(extract['value'], 8);
|
||||
|
||||
// start
|
||||
|
||||
var zero = coinjs.numToBytes(0, 32);
|
||||
var version = coinjs.numToBytes(parseInt(this.version), 4);
|
||||
|
||||
var bufferTmp = [];
|
||||
if(!(sigHashType >= 80)){ // not sighash anyonecanpay
|
||||
for(var i = 0; i < this.ins.length; i++){
|
||||
bufferTmp = bufferTmp.concat(Crypto.util.hexToBytes(this.ins[i].outpoint.hash).reverse());
|
||||
bufferTmp = bufferTmp.concat(coinjs.numToBytes(this.ins[i].outpoint.index, 4));
|
||||
}
|
||||
}
|
||||
var hashPrevouts = bufferTmp.length >= 1 ? Crypto.SHA256(Crypto.SHA256(bufferTmp, {asBytes: true}), {asBytes: true}) : zero;
|
||||
|
||||
var bufferTmp = [];
|
||||
if(!(sigHashType >= 80) && sigHashType != 2 && sigHashType != 3){ // not sighash anyonecanpay & single & none
|
||||
for(var i = 0; i < this.ins.length; i++){
|
||||
bufferTmp = bufferTmp.concat(coinjs.numToBytes(this.ins[i].sequence, 4));
|
||||
}
|
||||
}
|
||||
var hashSequence = bufferTmp.length >= 1 ? Crypto.SHA256(Crypto.SHA256(bufferTmp, {asBytes: true}), {asBytes: true}) : zero;
|
||||
|
||||
var outpoint = Crypto.util.hexToBytes(this.ins[index].outpoint.hash).reverse();
|
||||
outpoint = outpoint.concat(coinjs.numToBytes(this.ins[index].outpoint.index, 4));
|
||||
|
||||
var nsequence = coinjs.numToBytes(this.ins[index].sequence, 4);
|
||||
var hashOutputs = zero;
|
||||
var bufferTmp = [];
|
||||
if(sigHashType != 2 && sigHashType != 3){ // not sighash single & none
|
||||
for(var i = 0; i < this.outs.length; i++ ){
|
||||
bufferTmp = bufferTmp.concat(coinjs.numToBytes(this.outs[i].value, 8));
|
||||
bufferTmp = bufferTmp.concat(coinjs.numToVarInt(this.outs[i].script.buffer.length));
|
||||
bufferTmp = bufferTmp.concat(this.outs[i].script.buffer);
|
||||
}
|
||||
hashOutputs = Crypto.SHA256(Crypto.SHA256(bufferTmp, {asBytes: true}), {asBytes: true});
|
||||
|
||||
} else if ((sigHashType == 2) && index < this.outs.length){ // is sighash single
|
||||
bufferTmp = bufferTmp.concat(coinjs.numToBytes(this.outs[index].value, 8));
|
||||
bufferTmp = bufferTmp.concat(coinjs.numToVarInt(this.outs[i].script.buffer.length));
|
||||
bufferTmp = bufferTmp.concat(this.outs[index].script.buffer);
|
||||
hashOutputs = Crypto.SHA256(Crypto.SHA256(bufferTmp, {asBytes: true}), {asBytes: true});
|
||||
}
|
||||
|
||||
var locktime = coinjs.numToBytes(this.lock_time, 4);
|
||||
var sighash = coinjs.numToBytes(sigHashType, 4);
|
||||
|
||||
var buffer = [];
|
||||
buffer = buffer.concat(version);
|
||||
buffer = buffer.concat(hashPrevouts);
|
||||
buffer = buffer.concat(hashSequence);
|
||||
buffer = buffer.concat(outpoint);
|
||||
buffer = buffer.concat(scriptcode);
|
||||
buffer = buffer.concat(value);
|
||||
buffer = buffer.concat(nsequence);
|
||||
buffer = buffer.concat(hashOutputs);
|
||||
buffer = buffer.concat(locktime);
|
||||
buffer = buffer.concat(sighash);
|
||||
|
||||
var hash = Crypto.SHA256(buffer, {asBytes: true});
|
||||
return {'result':1,'hash':Crypto.util.bytesToHex(Crypto.SHA256(hash, {asBytes: true})), 'response':'hash generated'};
|
||||
}
|
||||
|
||||
/* extract the scriptSig, used in the transactionHash() function */
|
||||
r.extractScriptKey = function(index) {
|
||||
if(this.ins[index]){
|
||||
if((this.ins[index].script.chunks.length==5) && this.ins[index].script.chunks[4]==172 && coinjs.isArray(this.ins[index].script.chunks[2])){ //OP_CHECKSIG
|
||||
// regular scriptPubkey (not signed)
|
||||
return {'type':'scriptpubkey', 'signed':'false', 'signatures':0, 'script': Crypto.util.bytesToHex(this.ins[index].script.buffer)};
|
||||
} else if((this.ins[index].script.chunks.length==2) && this.ins[index].script.chunks[0][0]==48 && this.ins[index].script.chunks[1].length == 5 && this.ins[index].script.chunks[1][1]==177){//OP_CHECKLOCKTIMEVERIFY
|
||||
// hodl script (signed)
|
||||
return {'type':'hodl', 'signed':'true', 'signatures':1, 'script': Crypto.util.bytesToHex(this.ins[index].script.buffer)};
|
||||
} else if((this.ins[index].script.chunks.length==2) && this.ins[index].script.chunks[0][0]==48){
|
||||
// regular scriptPubkey (probably signed)
|
||||
return {'type':'scriptpubkey', 'signed':'true', 'signatures':1, 'script': Crypto.util.bytesToHex(this.ins[index].script.buffer)};
|
||||
} else if(this.ins[index].script.chunks.length == 5 && this.ins[index].script.chunks[1] == 177){//OP_CHECKLOCKTIMEVERIFY
|
||||
// hodl script (not signed)
|
||||
return {'type':'hodl', 'signed':'false', 'signatures': 0, 'script': Crypto.util.bytesToHex(this.ins[index].script.buffer)};
|
||||
} else if((this.ins[index].script.chunks.length <= 3 && this.ins[index].script.chunks.length > 0) && ((this.ins[index].script.chunks[0].length == 22 && this.ins[index].script.chunks[0][0] == 0) || (this.ins[index].script.chunks[0].length == 20 && this.ins[index].script.chunks[1] == 0))){
|
||||
var signed = ((this.witness[index]) && this.witness[index].length==2) ? 'true' : 'false';
|
||||
var sigs = (signed == 'true') ? 1 : 0;
|
||||
var value = -1; // no value found
|
||||
if((this.ins[index].script.chunks[2]) && this.ins[index].script.chunks[2].length==8){
|
||||
value = coinjs.bytesToNum(this.ins[index].script.chunks[2]); // value found encoded in transaction (THIS IS NON STANDARD)
|
||||
}
|
||||
return {'type':'segwit', 'signed':signed, 'signatures': sigs, 'script': Crypto.util.bytesToHex(this.ins[index].script.chunks[0]), 'value': value};
|
||||
} else if (this.ins[index].script.chunks[0]==0 && this.ins[index].script.chunks[this.ins[index].script.chunks.length-1][this.ins[index].script.chunks[this.ins[index].script.chunks.length-1].length-1]==174) { // OP_CHECKMULTISIG
|
||||
// multisig script, with signature(s) included
|
||||
return {'type':'multisig', 'signed':'true', 'signatures':this.ins[index].script.chunks.length-2, 'script': Crypto.util.bytesToHex(this.ins[index].script.chunks[this.ins[index].script.chunks.length-1])};
|
||||
@@ -920,7 +1315,7 @@
|
||||
}
|
||||
|
||||
/* generate a signature from a transaction hash */
|
||||
r.transactionSig = function(index, wif){
|
||||
r.transactionSig = function(index, wif, sigHashType, txhash){
|
||||
|
||||
function serializeSig(r, s) {
|
||||
var rBa = r.toByteArraySigned();
|
||||
@@ -941,7 +1336,8 @@
|
||||
return sequence;
|
||||
}
|
||||
|
||||
var hash = Crypto.util.hexToBytes(this.transactionHash(index));
|
||||
var shType = sigHashType || 1;
|
||||
var hash = txhash || Crypto.util.hexToBytes(this.transactionHash(index, shType));
|
||||
|
||||
if(hash){
|
||||
var curve = EllipticCurve.getSECCurveByName("secp256k1");
|
||||
@@ -966,7 +1362,7 @@
|
||||
};
|
||||
|
||||
var sig = serializeSig(r, s);
|
||||
sig.push(parseInt(1, 10));
|
||||
sig.push(parseInt(shType, 10));
|
||||
|
||||
return Crypto.util.bytesToHex(sig);
|
||||
} else {
|
||||
@@ -995,12 +1391,10 @@
|
||||
// hash is a byteArray of the message digest. so h1 == hash in our case
|
||||
|
||||
// Step: b
|
||||
var v = new Uint8Array(32);
|
||||
v = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
|
||||
var v = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
|
||||
|
||||
// Step: c
|
||||
var k = new Uint8Array(32);
|
||||
k = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
var k = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
// Step: d
|
||||
k = Crypto.HMAC(Crypto.SHA256, v.concat([0]).concat(x).concat(hash), k, { asBytes: true });
|
||||
@@ -1039,9 +1433,10 @@
|
||||
};
|
||||
|
||||
/* sign a "standard" input */
|
||||
r.signinput = function(index, wif){
|
||||
r.signinput = function(index, wif, sigHashType){
|
||||
var key = coinjs.wif2pubkey(wif);
|
||||
var signature = this.transactionSig(index, wif);
|
||||
var shType = sigHashType || 1;
|
||||
var signature = this.transactionSig(index, wif, shType);
|
||||
var s = coinjs.script();
|
||||
s.writeBytes(Crypto.util.hexToBytes(signature));
|
||||
s.writeBytes(Crypto.util.hexToBytes(key['pubkey']));
|
||||
@@ -1049,8 +1444,20 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
/* signs a time locked / hodl input */
|
||||
r.signhodl = function(index, wif, sigHashType){
|
||||
var shType = sigHashType || 1;
|
||||
var signature = this.transactionSig(index, wif, shType);
|
||||
var redeemScript = this.ins[index].script.buffer
|
||||
var s = coinjs.script();
|
||||
s.writeBytes(Crypto.util.hexToBytes(signature));
|
||||
s.writeBytes(redeemScript);
|
||||
this.ins[index].script = s;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* sign a multisig input */
|
||||
r.signmultisig = function(index, wif){
|
||||
r.signmultisig = function(index, wif, sigHashType){
|
||||
|
||||
function scriptListPubkey(redeemScript){
|
||||
var r = {};
|
||||
@@ -1062,46 +1469,107 @@
|
||||
|
||||
function scriptListSigs(scriptSig){
|
||||
var r = {};
|
||||
var c = 0;
|
||||
if (scriptSig.chunks[0]==0 && scriptSig.chunks[scriptSig.chunks.length-1][scriptSig.chunks[scriptSig.chunks.length-1].length-1]==174){
|
||||
for(var i=1;i<scriptSig.chunks.length-1;i++){
|
||||
r[i] = scriptSig.chunks[i];
|
||||
if (scriptSig.chunks[i] != 0){
|
||||
c++;
|
||||
r[c] = scriptSig.chunks[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
var redeemScript = (this.ins[index].script.chunks[this.ins[index].script.chunks.length-1]==174) ? this.ins[index].script.buffer : this.ins[index].script.chunks[this.ins[index].script.chunks.length-1];
|
||||
var sighash = Crypto.util.hexToBytes(this.transactionHash(index));
|
||||
var signature = Crypto.util.hexToBytes(this.transactionSig(index, wif));
|
||||
|
||||
var pubkeyList = scriptListPubkey(coinjs.script(redeemScript));
|
||||
var sigsList = scriptListSigs(this.ins[index].script);
|
||||
|
||||
var shType = sigHashType || 1;
|
||||
var sighash = Crypto.util.hexToBytes(this.transactionHash(index, shType));
|
||||
var signature = Crypto.util.hexToBytes(this.transactionSig(index, wif, shType));
|
||||
|
||||
sigsList[coinjs.countObject(sigsList)+1] = signature;
|
||||
|
||||
var s = coinjs.script();
|
||||
|
||||
s.writeOp(0);
|
||||
|
||||
if(this.ins[index].script.chunks[this.ins[index].script.chunks.length-1]==174){
|
||||
s.writeBytes(signature);
|
||||
|
||||
} else if (this.ins[index].script.chunks[0]==0 && this.ins[index].script.chunks[this.ins[index].script.chunks.length-1][this.ins[index].script.chunks[this.ins[index].script.chunks.length-1].length-1]==174){
|
||||
var pubkeyList = scriptListPubkey(coinjs.script(redeemScript));
|
||||
var sigsList = scriptListSigs(this.ins[index].script);
|
||||
sigsList[coinjs.countObject(sigsList)+1] = signature;
|
||||
|
||||
for(x in pubkeyList){
|
||||
for(y in sigsList){
|
||||
this.ins[index].script.buffer = redeemScript;
|
||||
sighash = Crypto.util.hexToBytes(this.transactionHash(index, sigsList[y].slice(-1)[0]*1));
|
||||
if(coinjs.verifySignature(sighash, sigsList[y], pubkeyList[x])){
|
||||
s.writeBytes(sigsList[y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
s.writeBytes(redeemScript);
|
||||
this.ins[index].script = s;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* sign segwit input */
|
||||
r.signsegwit = function(index, wif, sigHashType){
|
||||
var shType = sigHashType || 1;
|
||||
|
||||
var wif2 = coinjs.wif2pubkey(wif);
|
||||
var segwit = coinjs.segwitAddress(wif2['pubkey']);
|
||||
var bech32 = coinjs.bech32Address(wif2['pubkey']);
|
||||
|
||||
if((segwit['redeemscript'] == Crypto.util.bytesToHex(this.ins[index].script.chunks[0])) || (bech32['redeemscript'] == Crypto.util.bytesToHex(this.ins[index].script.chunks[0]))){
|
||||
var txhash = this.transactionHashSegWitV0(index, shType);
|
||||
|
||||
if(txhash.result == 1){
|
||||
|
||||
var segwitHash = Crypto.util.hexToBytes(txhash.hash);
|
||||
var signature = this.transactionSig(index, wif, shType, segwitHash);
|
||||
|
||||
// remove any non standard data we store, i.e. input value
|
||||
var script = coinjs.script();
|
||||
script.writeBytes(this.ins[index].script.chunks[0]);
|
||||
this.ins[index].script = script;
|
||||
|
||||
if(!coinjs.isArray(this.witness)){
|
||||
this.witness = [];
|
||||
}
|
||||
|
||||
this.witness.push([signature, wif2['pubkey']]);
|
||||
|
||||
/* attempt to reorder witness data as best as we can.
|
||||
data can't be easily validated at this stage as
|
||||
we dont have access to the inputs value and
|
||||
making a web call will be too slow. */
|
||||
|
||||
var witness_order = [];
|
||||
var witness_used = [];
|
||||
for(var i = 0; i < this.ins.length; i++){
|
||||
for(var y = 0; y < this.witness.length; y++){
|
||||
if(!witness_used.includes(y)){
|
||||
var sw = coinjs.segwitAddress(this.witness[y][1]);
|
||||
var b32 = coinjs.bech32Address(this.witness[y][1]);
|
||||
if((sw['redeemscript'] == Crypto.util.bytesToHex(this.ins[i].script.chunks[0])) || (b32['redeemscript'] == Crypto.util.bytesToHex(this.ins[i].script.chunks[0]))){
|
||||
witness_order.push(this.witness[y]);
|
||||
witness_used.push(y);
|
||||
if(b32['redeemscript'] == Crypto.util.bytesToHex(this.ins[i].script.chunks[0])){
|
||||
this.ins[index].script = coinjs.script();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.witness = witness_order;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* sign inputs */
|
||||
r.sign = function(wif){
|
||||
r.sign = function(wif, sigHashType){
|
||||
var shType = sigHashType || 1;
|
||||
for (var i = 0; i < this.ins.length; i++) {
|
||||
var d = this.extractScriptKey(i);
|
||||
|
||||
@@ -1110,9 +1578,17 @@
|
||||
var pubkeyHash = script.pubkeyHash(w2a['address']);
|
||||
|
||||
if(((d['type'] == 'scriptpubkey' && d['script']==Crypto.util.bytesToHex(pubkeyHash.buffer)) || d['type'] == 'empty') && d['signed'] == "false"){
|
||||
this.signinput(i, wif);
|
||||
this.signinput(i, wif, shType);
|
||||
|
||||
} else if (d['type'] == 'hodl' && d['signed'] == "false") {
|
||||
this.signhodl(i, wif, shType);
|
||||
|
||||
} else if (d['type'] == 'multisig') {
|
||||
this.signmultisig(i, wif);
|
||||
this.signmultisig(i, wif, shType);
|
||||
|
||||
} else if (d['type'] == 'segwit') {
|
||||
this.signsegwit(i, wif, shType);
|
||||
|
||||
} else {
|
||||
// could not sign
|
||||
}
|
||||
@@ -1124,8 +1600,12 @@
|
||||
r.serialize = function(){
|
||||
var buffer = [];
|
||||
buffer = buffer.concat(coinjs.numToBytes(parseInt(this.version),4));
|
||||
buffer = buffer.concat(coinjs.numToVarInt(this.ins.length));
|
||||
|
||||
if(coinjs.isArray(this.witness)){
|
||||
buffer = buffer.concat([0x00, 0x01]);
|
||||
}
|
||||
|
||||
buffer = buffer.concat(coinjs.numToVarInt(this.ins.length));
|
||||
for (var i = 0; i < this.ins.length; i++) {
|
||||
var txin = this.ins[i];
|
||||
buffer = buffer.concat(Crypto.util.hexToBytes(txin.outpoint.hash).reverse());
|
||||
@@ -1145,6 +1625,16 @@
|
||||
buffer = buffer.concat(scriptBytes);
|
||||
}
|
||||
|
||||
if((coinjs.isArray(this.witness)) && this.witness.length>=1){
|
||||
for(var i = 0; i < this.witness.length; i++){
|
||||
buffer = buffer.concat(coinjs.numToVarInt(this.witness[i].length));
|
||||
for(var x = 0; x < this.witness[i].length; x++){
|
||||
buffer = buffer.concat(coinjs.numToVarInt(Crypto.util.hexToBytes(this.witness[i][x]).length));
|
||||
buffer = buffer.concat(Crypto.util.hexToBytes(this.witness[i][x]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buffer = buffer.concat(coinjs.numToBytes(parseInt(this.lock_time),4));
|
||||
return Crypto.util.bytesToHex(buffer);
|
||||
}
|
||||
@@ -1156,6 +1646,8 @@
|
||||
}
|
||||
|
||||
var pos = 0;
|
||||
var witness = false;
|
||||
|
||||
var readAsInt = function(bytes) {
|
||||
if (bytes == 0) return 0;
|
||||
pos++;
|
||||
@@ -1181,8 +1673,15 @@
|
||||
}
|
||||
|
||||
var obj = new coinjs.transaction();
|
||||
|
||||
obj.version = readAsInt(4);
|
||||
|
||||
if(buffer[pos] == 0x00 && buffer[pos+1] == 0x01){
|
||||
// segwit transaction
|
||||
witness = true;
|
||||
obj.witness = [];
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
var ins = readVarInt();
|
||||
for (var i = 0; i < ins; i++) {
|
||||
obj.ins.push({
|
||||
@@ -1203,6 +1702,21 @@
|
||||
});
|
||||
}
|
||||
|
||||
if(witness == true){
|
||||
for (i = 0; i < ins; ++i) {
|
||||
var count = readVarInt();
|
||||
var vector = [];
|
||||
for(var y = 0; y < count; y++){
|
||||
var slice = readVarInt();
|
||||
pos += slice;
|
||||
if(!coinjs.isArray(obj.witness[i])){
|
||||
obj.witness[i] = [];
|
||||
}
|
||||
obj.witness[i].push(Crypto.util.bytesToHex(buffer.slice(pos - slice, pos)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
obj.lock_time = readAsInt(4);
|
||||
return obj;
|
||||
}
|
||||
@@ -1373,7 +1887,7 @@
|
||||
/* clone an object */
|
||||
coinjs.clone = function(obj) {
|
||||
if(obj == null || typeof(obj) != 'object') return obj;
|
||||
var temp = obj.constructor();
|
||||
var temp = new obj.constructor();
|
||||
|
||||
for(var key in obj) {
|
||||
if(obj.hasOwnProperty(key)) {
|
||||
@@ -1384,14 +1898,24 @@
|
||||
}
|
||||
|
||||
coinjs.numToBytes = function(num,bytes) {
|
||||
if (typeof bytes === undefined) bytes = 8;
|
||||
if (typeof bytes === "undefined") bytes = 8;
|
||||
if (bytes == 0) {
|
||||
return [];
|
||||
} else if (num == -1){
|
||||
return Crypto.util.hexToBytes("ffffffffffffffff");
|
||||
} else {
|
||||
return [num % 256].concat(coinjs.numToBytes(Math.floor(num / 256),bytes-1));
|
||||
}
|
||||
}
|
||||
|
||||
coinjs.numToByteArray = function(num) {
|
||||
if (num <= 256) {
|
||||
return [num];
|
||||
} else {
|
||||
return [num % 256].concat(coinjs.numToByteArray(Math.floor(num / 256)));
|
||||
}
|
||||
}
|
||||
|
||||
coinjs.numToVarInt = function(num) {
|
||||
if (num < 253) {
|
||||
return [num];
|
||||
@@ -1400,7 +1924,7 @@
|
||||
} else if (num < 4294967296) {
|
||||
return [254].concat(coinjs.numToBytes(num,4));
|
||||
} else {
|
||||
return [253].concat(coinjs.numToBytes(num,8));
|
||||
return [255].concat(coinjs.numToBytes(num,8));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+991
-104
File diff suppressed because it is too large
Load Diff
+211
@@ -0,0 +1,211 @@
|
||||
/* ========================================================================
|
||||
* Bootstrap: collapse.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#collapse
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// COLLAPSE PUBLIC CLASS DEFINITION
|
||||
// ================================
|
||||
|
||||
var Collapse = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, Collapse.DEFAULTS, options)
|
||||
this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
|
||||
'[data-toggle="collapse"][data-target="#' + element.id + '"]')
|
||||
this.transitioning = null
|
||||
|
||||
if (this.options.parent) {
|
||||
this.$parent = this.getParent()
|
||||
} else {
|
||||
this.addAriaAndCollapsedClass(this.$element, this.$trigger)
|
||||
}
|
||||
|
||||
if (this.options.toggle) this.toggle()
|
||||
}
|
||||
|
||||
Collapse.VERSION = '3.3.4'
|
||||
|
||||
Collapse.TRANSITION_DURATION = 350
|
||||
|
||||
Collapse.DEFAULTS = {
|
||||
toggle: true
|
||||
}
|
||||
|
||||
Collapse.prototype.dimension = function () {
|
||||
var hasWidth = this.$element.hasClass('width')
|
||||
return hasWidth ? 'width' : 'height'
|
||||
}
|
||||
|
||||
Collapse.prototype.show = function () {
|
||||
if (this.transitioning || this.$element.hasClass('in')) return
|
||||
|
||||
var activesData
|
||||
var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
|
||||
|
||||
if (actives && actives.length) {
|
||||
activesData = actives.data('bs.collapse')
|
||||
if (activesData && activesData.transitioning) return
|
||||
}
|
||||
|
||||
var startEvent = $.Event('show.bs.collapse')
|
||||
this.$element.trigger(startEvent)
|
||||
if (startEvent.isDefaultPrevented()) return
|
||||
|
||||
if (actives && actives.length) {
|
||||
Plugin.call(actives, 'hide')
|
||||
activesData || actives.data('bs.collapse', null)
|
||||
}
|
||||
|
||||
var dimension = this.dimension()
|
||||
|
||||
this.$element
|
||||
.removeClass('collapse')
|
||||
.addClass('collapsing')[dimension](0)
|
||||
.attr('aria-expanded', true)
|
||||
|
||||
this.$trigger
|
||||
.removeClass('collapsed')
|
||||
.attr('aria-expanded', true)
|
||||
|
||||
this.transitioning = 1
|
||||
|
||||
var complete = function () {
|
||||
this.$element
|
||||
.removeClass('collapsing')
|
||||
.addClass('collapse in')[dimension]('')
|
||||
this.transitioning = 0
|
||||
this.$element
|
||||
.trigger('shown.bs.collapse')
|
||||
}
|
||||
|
||||
if (!$.support.transition) return complete.call(this)
|
||||
|
||||
var scrollSize = $.camelCase(['scroll', dimension].join('-'))
|
||||
|
||||
this.$element
|
||||
.one('bsTransitionEnd', $.proxy(complete, this))
|
||||
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
|
||||
}
|
||||
|
||||
Collapse.prototype.hide = function () {
|
||||
if (this.transitioning || !this.$element.hasClass('in')) return
|
||||
|
||||
var startEvent = $.Event('hide.bs.collapse')
|
||||
this.$element.trigger(startEvent)
|
||||
if (startEvent.isDefaultPrevented()) return
|
||||
|
||||
var dimension = this.dimension()
|
||||
|
||||
this.$element[dimension](this.$element[dimension]())[0].offsetHeight
|
||||
|
||||
this.$element
|
||||
.addClass('collapsing')
|
||||
.removeClass('collapse in')
|
||||
.attr('aria-expanded', false)
|
||||
|
||||
this.$trigger
|
||||
.addClass('collapsed')
|
||||
.attr('aria-expanded', false)
|
||||
|
||||
this.transitioning = 1
|
||||
|
||||
var complete = function () {
|
||||
this.transitioning = 0
|
||||
this.$element
|
||||
.removeClass('collapsing')
|
||||
.addClass('collapse')
|
||||
.trigger('hidden.bs.collapse')
|
||||
}
|
||||
|
||||
if (!$.support.transition) return complete.call(this)
|
||||
|
||||
this.$element
|
||||
[dimension](0)
|
||||
.one('bsTransitionEnd', $.proxy(complete, this))
|
||||
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)
|
||||
}
|
||||
|
||||
Collapse.prototype.toggle = function () {
|
||||
this[this.$element.hasClass('in') ? 'hide' : 'show']()
|
||||
}
|
||||
|
||||
Collapse.prototype.getParent = function () {
|
||||
return $(this.options.parent)
|
||||
.find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
|
||||
.each($.proxy(function (i, element) {
|
||||
var $element = $(element)
|
||||
this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
|
||||
}, this))
|
||||
.end()
|
||||
}
|
||||
|
||||
Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
|
||||
var isOpen = $element.hasClass('in')
|
||||
|
||||
$element.attr('aria-expanded', isOpen)
|
||||
$trigger
|
||||
.toggleClass('collapsed', !isOpen)
|
||||
.attr('aria-expanded', isOpen)
|
||||
}
|
||||
|
||||
function getTargetFromTrigger($trigger) {
|
||||
var href
|
||||
var target = $trigger.attr('data-target')
|
||||
|| (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
|
||||
|
||||
return $(target)
|
||||
}
|
||||
|
||||
|
||||
// COLLAPSE PLUGIN DEFINITION
|
||||
// ==========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.collapse')
|
||||
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||||
|
||||
if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
|
||||
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.collapse
|
||||
|
||||
$.fn.collapse = Plugin
|
||||
$.fn.collapse.Constructor = Collapse
|
||||
|
||||
|
||||
// COLLAPSE NO CONFLICT
|
||||
// ====================
|
||||
|
||||
$.fn.collapse.noConflict = function () {
|
||||
$.fn.collapse = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// COLLAPSE DATA-API
|
||||
// =================
|
||||
|
||||
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
|
||||
var $this = $(this)
|
||||
|
||||
if (!$this.attr('data-target')) e.preventDefault()
|
||||
|
||||
var $target = getTargetFromTrigger($this)
|
||||
var data = $target.data('bs.collapse')
|
||||
var option = data ? 'toggle' : $this.data()
|
||||
|
||||
Plugin.call($target, option)
|
||||
})
|
||||
|
||||
}(jQuery);
|
||||
Vendored
+7
File diff suppressed because one or more lines are too long
@@ -0,0 +1,59 @@
|
||||
/* ========================================================================
|
||||
* Bootstrap: transition.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#transitions
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
|
||||
// ============================================================
|
||||
|
||||
function transitionEnd() {
|
||||
var el = document.createElement('bootstrap')
|
||||
|
||||
var transEndEventNames = {
|
||||
WebkitTransition : 'webkitTransitionEnd',
|
||||
MozTransition : 'transitionend',
|
||||
OTransition : 'oTransitionEnd otransitionend',
|
||||
transition : 'transitionend'
|
||||
}
|
||||
|
||||
for (var name in transEndEventNames) {
|
||||
if (el.style[name] !== undefined) {
|
||||
return { end: transEndEventNames[name] }
|
||||
}
|
||||
}
|
||||
|
||||
return false // explicit for ie8 ( ._.)
|
||||
}
|
||||
|
||||
// http://blog.alexmaccaw.com/css-transitions
|
||||
$.fn.emulateTransitionEnd = function (duration) {
|
||||
var called = false
|
||||
var $el = this
|
||||
$(this).one('bsTransitionEnd', function () { called = true })
|
||||
var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
|
||||
setTimeout(callback, duration)
|
||||
return this
|
||||
}
|
||||
|
||||
$(function () {
|
||||
$.support.transition = transitionEnd()
|
||||
|
||||
if (!$.support.transition) return
|
||||
|
||||
$.event.special.bsTransitionEnd = {
|
||||
bindType: $.support.transition.end,
|
||||
delegateType: $.support.transition.end,
|
||||
handle: function (e) {
|
||||
if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}(jQuery);
|
||||
@@ -1,22 +1,28 @@
|
||||
---- Version 1.2 2015.07.23 ----
|
||||
e6810907c901e6bd34a28735a68850936f0823b8 ./js/ellipticcurve.js
|
||||
9ba5ede3d7f9d4c8fd623395f196adfdcf7e970f ./js/crypto-min.js
|
||||
---- Version 1.4 2018.05.27 ---
|
||||
77e4519962e2f6a9fc93342137dbb31c33b76b04 ./js/aes.js
|
||||
0ce26da5ef686d4ece91acd6cb6506559e11ab07 ./js/qcode-decoder.min.js
|
||||
be17ca7c834204bff711f582e41f76c06d472bac ./js/jsbn.js
|
||||
0700fc9ad2e39adeca0b50614bb3d327fb49f609 ./js/crypto-sha256.js
|
||||
3a09a8fc0cfe828b57fc798d668234d0490ee1a6 ./js/bootstrap-datetimepicker.min.js
|
||||
253711c6d825de55a8360552573be950da180614 ./js/bootstrap.min.js
|
||||
dda26795fcd22541612067d44cf72ecae62f092b ./js/coinbin.js
|
||||
eec3c5f1c5f69a34205613f6bf62ff9cc5a8d07a ./js/coin.js
|
||||
988565bc2cb402d63ed5c5fd7ff47c4278efc2c5 ./js/collapse.js
|
||||
9ba5ede3d7f9d4c8fd623395f196adfdcf7e970f ./js/crypto-min.js
|
||||
f7c09f2f5a721371e7d478050119f7e2d58e3ef9 ./js/crypto-sha256-hmac.js
|
||||
0700fc9ad2e39adeca0b50614bb3d327fb49f609 ./js/crypto-sha256.js
|
||||
e6810907c901e6bd34a28735a68850936f0823b8 ./js/ellipticcurve.js
|
||||
ae49e56999d82802727455f0ba83b63acd90a22b ./js/jquery-1.9.1.min.js
|
||||
be17ca7c834204bff711f582e41f76c06d472bac ./js/jsbn.js
|
||||
ce4fa351a2e62accf7fad77110fa4ddb09a324bf ./js/moment.min.js
|
||||
0ce26da5ef686d4ece91acd6cb6506559e11ab07 ./js/qcode-decoder.min.js
|
||||
ad038e1f39646b68ae666324ed4c2882a8c42474 ./js/qrcode.js
|
||||
64eb4ea5c882f8bce3e1885bf00728455f1c2f4c ./js/ripemd160.js
|
||||
114089ef2a3feb6d4db4f9cabcb186d7750d5884 ./js/sha512.js
|
||||
3ff26f7ca616b01742a25f9aa304bdb653ce4a4d ./js/coin.js
|
||||
3d054bbad57fca0c091c8099a25e3cc802cf35c1 ./js/coinbin.js
|
||||
ae49e56999d82802727455f0ba83b63acd90a22b ./js/jquery-1.9.1.min.js
|
||||
5f570018ed044eafd464f7e0ab1783b966224055 ./LICENCE
|
||||
506c40035e0d22560478629434d0fea27643b77a ./js/transition.js
|
||||
5f570018ed044eafd464f7e0ab1783b966224055 ./LICENSE
|
||||
255c58c17e63eb54adb3cd02b5c06224c67fc364 ./css/bootstrap-datetimepicker.min.css
|
||||
ed29315e0ffb3f14382431f2724235bf67f44eb3 ./css/bootstrap.min.css
|
||||
fc6b4268fbd57ad95d2b41a1d4d6866f222fbdb2 ./css/bootstrap-theme.min.css
|
||||
8297b8f4d686ec6c65981077514975e06ce41812 ./css/style.css
|
||||
eb54f374256b75a17f274847b4ca9985fd046f9f ./css/style.css
|
||||
2e3217a3f3b7c2fb30562ab9a4ef9a407ae81897 ./images/btc32x.png
|
||||
8ac24915d59cef71c542e7cb7d7e153f560cba1f ./images/coinbin.gif
|
||||
f2af060f1cadbc9065c8c465c648dc01be67cc12 ./images/loader.gif
|
||||
86b6f62b7853e67d3e635f6512a5a5efc58ea3c3 ./fonts/glyphicons-halflings-regular.eot
|
||||
@@ -24,5 +30,5 @@ ca35b697d99cae4d1b60f2d60fcd37771987eb07 ./fonts/glyphicons-halflings-regular.w
|
||||
de51a8494180a6db074af2dee2383f0a363c5b08 ./fonts/glyphicons-halflings-regular.svg
|
||||
278e49a86e634da6f2a02f3b47dd9d2a8f26210f ./fonts/glyphicons-halflings-regular.woff
|
||||
44bc1850f570972267b169ae18f1cb06b611ffa2 ./fonts/glyphicons-halflings-regular.ttf
|
||||
fe8d57914bb036ab94e86ec35b2671eeb6d20d0d ./README.md
|
||||
528c2fd42260033391105215401bf122e3304f7b ./index.html
|
||||
c024021c71cba503979a859d23cbf7a88b570d82 ./README.md
|
||||
208b64a1ef61aaceec82f06515e4f7cf046793f6 ./index.html
|
||||
|
||||
Reference in New Issue
Block a user