2015-06-18 13:45:25 +00:00
|
|
|
/*
|
|
|
|
typedef struct {
|
|
|
|
uint32_t depth;
|
|
|
|
uint32_t fingerprint;
|
|
|
|
uint32_t child_num;
|
|
|
|
uint8_t chain_code[32];
|
|
|
|
uint8_t private_key[32];
|
|
|
|
uint8_t public_key[33];
|
|
|
|
} HDNode;
|
|
|
|
*/
|
|
|
|
|
|
|
|
var HEAPU8 = Module['HEAPU8'];
|
|
|
|
var _malloc = Module['_malloc'];
|
2016-05-12 17:29:24 +00:00
|
|
|
var _hdnode_public_ckd_address_optimized = Module['_hdnode_public_ckd_address_optimized'];
|
|
|
|
var _ecdsa_read_pubkey = Module['_ecdsa_read_pubkey'];
|
2015-06-18 13:45:25 +00:00
|
|
|
var Pointer_stringify = Module['Pointer_stringify'];
|
|
|
|
|
2016-05-12 17:29:24 +00:00
|
|
|
// HDNode structs global
|
|
|
|
var PUBPOINT_SIZE = 2 * 9 * 4; // (2 * bignum256 (= 9 * uint32_t))
|
|
|
|
var _pubpoint = _malloc(PUBPOINT_SIZE);
|
|
|
|
var PUBKEY_SIZE = 33;
|
|
|
|
var _pubkey = _malloc(PUBKEY_SIZE);
|
|
|
|
var CHAINCODE_SIZE = 32;
|
|
|
|
var _chaincode = _malloc(CHAINCODE_SIZE);
|
2015-06-18 13:45:25 +00:00
|
|
|
|
|
|
|
// address string global
|
2017-03-30 15:53:09 +00:00
|
|
|
var ADDRESS_SIZE = 60; // maximum size
|
2015-06-18 13:45:25 +00:00
|
|
|
var _address = _malloc(ADDRESS_SIZE);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* public library interface
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2015-11-06 13:52:25 +00:00
|
|
|
* @param {HDNode} node HDNode struct, see the definition above
|
2015-06-18 13:45:25 +00:00
|
|
|
*/
|
|
|
|
function serializeNode(node) {
|
2016-05-12 17:29:24 +00:00
|
|
|
var u8_pubkey = new Uint8Array(33);
|
|
|
|
u8_pubkey.set(node['public_key'], 0);
|
|
|
|
HEAPU8.set(u8_pubkey, _pubkey);
|
2015-06-18 13:45:25 +00:00
|
|
|
|
2016-05-12 17:29:24 +00:00
|
|
|
var u8_chaincode = new Uint8Array(32);
|
|
|
|
u8_chaincode.set(node['chain_code'], 0);
|
|
|
|
HEAPU8.set(u8_chaincode, _chaincode);
|
2015-06-18 13:45:25 +00:00
|
|
|
|
2016-05-12 17:29:24 +00:00
|
|
|
_ecdsa_read_pubkey(0, _pubkey, _pubpoint);
|
2015-06-18 13:45:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-11-06 13:52:25 +00:00
|
|
|
* @param {Number} index BIP32 index of the address
|
|
|
|
* @param {Number} version address version byte
|
2015-06-18 13:45:25 +00:00
|
|
|
* @return {String}
|
|
|
|
*/
|
2017-03-31 01:38:28 +00:00
|
|
|
function deriveAddress(index, version, segwit) {
|
|
|
|
_hdnode_public_ckd_address_optimized(_pubpoint, _chaincode, index, version, _address, ADDRESS_SIZE, segwit);
|
2015-06-18 13:45:25 +00:00
|
|
|
return Pointer_stringify(_address);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-11-06 13:52:25 +00:00
|
|
|
* @param {HDNode} node HDNode struct, see the definition above
|
|
|
|
* @param {Number} firstIndex index of the first address
|
|
|
|
* @param {Number} lastIndex index of the last address
|
|
|
|
* @param {Number} version address version byte
|
2015-06-18 13:45:25 +00:00
|
|
|
* @return {Array<String>}
|
|
|
|
*/
|
2017-03-31 01:38:28 +00:00
|
|
|
function deriveAddressRange(node, firstIndex, lastIndex, version, segwit) {
|
2015-06-18 13:45:25 +00:00
|
|
|
var addresses = [];
|
2016-05-12 17:29:24 +00:00
|
|
|
serializeNode(node);
|
2015-06-18 13:45:25 +00:00
|
|
|
var i;
|
2015-11-06 13:52:25 +00:00
|
|
|
for (i = firstIndex; i <= lastIndex; i++) {
|
2017-03-31 01:38:28 +00:00
|
|
|
addresses.push(deriveAddress(i, version, segwit));
|
2015-06-18 13:45:25 +00:00
|
|
|
}
|
|
|
|
return addresses;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof module !== 'undefined') {
|
|
|
|
module['exports'] = {
|
|
|
|
'serializeNode': serializeNode,
|
|
|
|
'deriveAddress': deriveAddress,
|
|
|
|
'deriveAddressRange': deriveAddressRange
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Web worker processing
|
|
|
|
*/
|
|
|
|
|
|
|
|
function processMessage(event) {
|
|
|
|
var data = event['data'];
|
|
|
|
var type = data['type'];
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case 'deriveAddressRange':
|
2015-11-06 13:52:25 +00:00
|
|
|
var addresses = deriveAddressRange(
|
2015-06-18 13:45:25 +00:00
|
|
|
data['node'],
|
2015-11-06 13:52:25 +00:00
|
|
|
data['firstIndex'],
|
|
|
|
data['lastIndex'],
|
2017-04-05 20:37:10 +00:00
|
|
|
data['version'],
|
|
|
|
!!data['segwit']
|
2015-06-18 13:45:25 +00:00
|
|
|
);
|
2017-05-04 00:34:41 +00:00
|
|
|
self.postMessage({
|
2015-11-06 13:52:25 +00:00
|
|
|
'addresses': addresses,
|
|
|
|
'firstIndex': data['firstIndex'],
|
|
|
|
'lastIndex': data['lastIndex']
|
|
|
|
});
|
2015-06-18 13:45:25 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
throw new Error('Unknown message type: ' + type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ENVIRONMENT_IS_WORKER) {
|
2017-05-04 00:34:41 +00:00
|
|
|
self.onmessage = processMessage;
|
2015-06-18 13:45:25 +00:00
|
|
|
}
|