add bech32 address option in single wallet page
This commit is contained in:
parent
72aefc03e0
commit
f53baa3de8
4 changed files with 159 additions and 1 deletions
|
@ -10,6 +10,7 @@ module.exports = function (grunt) {
|
||||||
output: "./bitaddress.org.html",
|
output: "./bitaddress.org.html",
|
||||||
tokens: [
|
tokens: [
|
||||||
{ token: "//biginteger.js", file: "./src/biginteger.js" },
|
{ token: "//biginteger.js", file: "./src/biginteger.js" },
|
||||||
|
{ token: "//bech32.js", file: "./src/bech32.js"},
|
||||||
{ token: "//bitcoinjs-lib.js", file: "./src/bitcoinjs-lib.js" },
|
{ token: "//bitcoinjs-lib.js", file: "./src/bitcoinjs-lib.js" },
|
||||||
{ token: "//bitcoinjs-lib.address.js", file: "./src/bitcoinjs-lib.address.js" },
|
{ token: "//bitcoinjs-lib.address.js", file: "./src/bitcoinjs-lib.address.js" },
|
||||||
{ token: "//bitcoinjs-lib.base58.js", file: "./src/bitcoinjs-lib.base58.js" },
|
{ token: "//bitcoinjs-lib.base58.js", file: "./src/bitcoinjs-lib.base58.js" },
|
||||||
|
|
149
src/bech32.js
Normal file
149
src/bech32.js
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
//https://raw.githubusercontent.com/bitcoinjs/bech32/e1536ebcc8e6471ae69813ac72e2f14f7656c483/index.js
|
||||||
|
'use strict'
|
||||||
|
var ALPHABET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'
|
||||||
|
|
||||||
|
// pre-compute lookup table
|
||||||
|
var ALPHABET_MAP = {}
|
||||||
|
for (var z = 0; z < ALPHABET.length; z++) {
|
||||||
|
var x = ALPHABET.charAt(z)
|
||||||
|
|
||||||
|
if (ALPHABET_MAP[x] !== undefined) throw new TypeError(x + ' is ambiguous')
|
||||||
|
ALPHABET_MAP[x] = z
|
||||||
|
}
|
||||||
|
|
||||||
|
function polymodStep (pre) {
|
||||||
|
var b = pre >> 25
|
||||||
|
return ((pre & 0x1FFFFFF) << 5) ^
|
||||||
|
(-((b >> 0) & 1) & 0x3b6a57b2) ^
|
||||||
|
(-((b >> 1) & 1) & 0x26508e6d) ^
|
||||||
|
(-((b >> 2) & 1) & 0x1ea119fa) ^
|
||||||
|
(-((b >> 3) & 1) & 0x3d4233dd) ^
|
||||||
|
(-((b >> 4) & 1) & 0x2a1462b3)
|
||||||
|
}
|
||||||
|
|
||||||
|
function prefixChk (prefix) {
|
||||||
|
var chk = 1
|
||||||
|
for (var i = 0; i < prefix.length; ++i) {
|
||||||
|
var c = prefix.charCodeAt(i)
|
||||||
|
if (c < 33 || c > 126) throw new Error('Invalid prefix (' + prefix + ')')
|
||||||
|
|
||||||
|
chk = polymodStep(chk) ^ (c >> 5)
|
||||||
|
}
|
||||||
|
chk = polymodStep(chk)
|
||||||
|
|
||||||
|
for (i = 0; i < prefix.length; ++i) {
|
||||||
|
var v = prefix.charCodeAt(i)
|
||||||
|
chk = polymodStep(chk) ^ (v & 0x1f)
|
||||||
|
}
|
||||||
|
return chk
|
||||||
|
}
|
||||||
|
|
||||||
|
function encode (prefix, words, LIMIT) {
|
||||||
|
LIMIT = LIMIT || 90
|
||||||
|
if ((prefix.length + 7 + words.length) > LIMIT) throw new TypeError('Exceeds length limit')
|
||||||
|
|
||||||
|
prefix = prefix.toLowerCase()
|
||||||
|
|
||||||
|
// determine chk mod
|
||||||
|
var chk = prefixChk(prefix)
|
||||||
|
var result = prefix + '1'
|
||||||
|
for (var i = 0; i < words.length; ++i) {
|
||||||
|
var x = words[i]
|
||||||
|
if ((x >> 5) !== 0) throw new Error('Non 5-bit word')
|
||||||
|
|
||||||
|
chk = polymodStep(chk) ^ x
|
||||||
|
result += ALPHABET.charAt(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 6; ++i) {
|
||||||
|
chk = polymodStep(chk)
|
||||||
|
}
|
||||||
|
chk ^= 1
|
||||||
|
|
||||||
|
for (i = 0; i < 6; ++i) {
|
||||||
|
var v = (chk >> ((5 - i) * 5)) & 0x1f
|
||||||
|
result += ALPHABET.charAt(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
function decode (str, LIMIT) {
|
||||||
|
LIMIT = LIMIT || 90
|
||||||
|
if (str.length < 8) throw new TypeError(str + ' too short')
|
||||||
|
if (str.length > LIMIT) throw new TypeError('Exceeds length limit')
|
||||||
|
|
||||||
|
// don't allow mixed case
|
||||||
|
var lowered = str.toLowerCase()
|
||||||
|
var uppered = str.toUpperCase()
|
||||||
|
if (str !== lowered && str !== uppered) throw new Error('Mixed-case string ' + str)
|
||||||
|
str = lowered
|
||||||
|
|
||||||
|
var split = str.lastIndexOf('1')
|
||||||
|
if (split === -1) throw new Error('No separator character for ' + str)
|
||||||
|
if (split === 0) throw new Error('Missing prefix for ' + str)
|
||||||
|
|
||||||
|
var prefix = str.slice(0, split)
|
||||||
|
var wordChars = str.slice(split + 1)
|
||||||
|
if (wordChars.length < 6) throw new Error('Data too short')
|
||||||
|
|
||||||
|
var chk = prefixChk(prefix)
|
||||||
|
var words = []
|
||||||
|
for (var i = 0; i < wordChars.length; ++i) {
|
||||||
|
var c = wordChars.charAt(i)
|
||||||
|
var v = ALPHABET_MAP[c]
|
||||||
|
if (v === undefined) throw new Error('Unknown character ' + c)
|
||||||
|
chk = polymodStep(chk) ^ v
|
||||||
|
|
||||||
|
// not in the checksum?
|
||||||
|
if (i + 6 >= wordChars.length) continue
|
||||||
|
words.push(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chk !== 1) throw new Error('Invalid checksum for ' + str)
|
||||||
|
return { prefix: prefix, words: words }
|
||||||
|
}
|
||||||
|
|
||||||
|
function convert (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
|
||||||
|
}
|
||||||
|
|
||||||
|
function toWords (bytes) {
|
||||||
|
return convert(bytes, 8, 5, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
function fromWords (words) {
|
||||||
|
return convert(words, 5, 8, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modified the module exports to window variables
|
||||||
|
window.bech32 = {
|
||||||
|
decode: decode,
|
||||||
|
encode: encode,
|
||||||
|
toWords: toWords,
|
||||||
|
fromWords: fromWords
|
||||||
|
}
|
|
@ -104,6 +104,9 @@
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
//crypto-scrypt.js
|
//crypto-scrypt.js
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
//bech32.js
|
||||||
</script>
|
</script>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
//main.css
|
//main.css
|
||||||
|
@ -155,6 +158,7 @@
|
||||||
<div id="singlearea" class="walletarea">
|
<div id="singlearea" class="walletarea">
|
||||||
<div class="commands">
|
<div class="commands">
|
||||||
<div id="singlecommands" class="row">
|
<div id="singlecommands" class="row">
|
||||||
|
<span><label id="singlelabelbech32" for="bech32">Bech32 Address?</label> <input type="checkbox" id="bech32" /></span>
|
||||||
<span><input type="button" id="newaddress" value="Generate New Address" onclick="ninja.wallets.singlewallet.generateNewAddressAndKey();" /></span>
|
<span><input type="button" id="newaddress" value="Generate New Address" onclick="ninja.wallets.singlewallet.generateNewAddressAndKey();" /></span>
|
||||||
<span class="print"><input type="button" name="print" value="Print" id="singleprint" onclick="window.print();" /></span>
|
<span class="print"><input type="button" name="print" value="Print" id="singleprint" onclick="window.print();" /></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,12 +17,16 @@
|
||||||
|
|
||||||
// generate bitcoin address and private key and update information in the HTML
|
// generate bitcoin address and private key and update information in the HTML
|
||||||
generateNewAddressAndKey: function () {
|
generateNewAddressAndKey: function () {
|
||||||
|
opt_bech32 = document.getElementById("bech32").checked
|
||||||
try {
|
try {
|
||||||
var key = new Bitcoin.ECKey(false);
|
var key = new Bitcoin.ECKey(false);
|
||||||
key.setCompressed(true);
|
key.setCompressed(true);
|
||||||
|
bech32_words = bech32.toWords(Bitcoin.Util.sha256ripe160(key.getPub()))
|
||||||
|
bech32_words.unshift(0x00);
|
||||||
|
var bech32Address = bech32.encode('bc', bech32_words);
|
||||||
var bitcoinAddress = key.getBitcoinAddress();
|
var bitcoinAddress = key.getBitcoinAddress();
|
||||||
var privateKeyWif = key.getBitcoinWalletImportFormat();
|
var privateKeyWif = key.getBitcoinWalletImportFormat();
|
||||||
document.getElementById("btcaddress").innerHTML = bitcoinAddress;
|
document.getElementById("btcaddress").innerHTML = opt_bech32 ? bech32Address : bitcoinAddress;
|
||||||
document.getElementById("btcprivwif").innerHTML = privateKeyWif;
|
document.getElementById("btcprivwif").innerHTML = privateKeyWif;
|
||||||
var keyValuePair = {
|
var keyValuePair = {
|
||||||
"qrcode_public": bitcoinAddress,
|
"qrcode_public": bitcoinAddress,
|
||||||
|
|
Loading…
Add table
Reference in a new issue