Add prettier support

pull/25/head
HenryNguyen5 6 years ago
parent 87aaa28655
commit 6f3142aa1c

@ -1,40 +1,31 @@
{
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"node": true
},
"globals": {
"LocalFileSystem": false,
"cordova": false,
"device": false
},
"extends": "eslint:recommended",
"rules": {
"indent": [
"off",
"tab"
],
"linebreak-style": [
"error",
"unix"
],
"no-unused-vars": [
"off",
{
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": false
}
],
"no-console": [
"warn",
{ "allow": [ "warn", "error" ] }
],
"no-extra-semi": [ "warn" ],
"no-redeclare": [ "warn" ],
// "no-unreachable": [ "warn" ],
"no-inner-declarations": [ "warn" ]
}
}
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"node": true
},
"globals": {
"LocalFileSystem": false,
"cordova": false,
"device": false
},
"extends": "eslint:recommended",
"rules": {
"indent": ["off", "tab"],
"linebreak-style": ["error", "unix"],
"no-unused-vars": [
"off",
{
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": false
}
],
"no-console": ["warn", { "allow": ["warn", "error"] }],
"no-extra-semi": ["warn"],
"no-redeclare": ["warn"],
// "no-unreachable": [ "warn" ],
"no-inner-declarations": ["warn"]
}
}

@ -0,0 +1,10 @@
cryptonote_utils/biginteger.js
cryptonote_utils/sha3.js
cryptonote_utils/nacl-fast-cn.js
cryptonote_utils/mnemonic.js
cryptonote_utils/cryptonote_crypto_EMSCRIPTEN.js
cryptonote_utils/crc32.js
package.json
yarn.lock

@ -0,0 +1,8 @@
{
"printWidth": 80,
"singleQuote": false,
"useTabs": true,
"semi": true,
"tabWidth": 4,
"trailingComma": "all"
}

@ -1,21 +1,21 @@
// Copyright (c) 2014-2018, MyMonero.com
//
//
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@ -26,15 +26,14 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// v--- These should maybe be injected into context
const JSBigInt = require('./biginteger').BigInteger
const JSBigInt = require("./biginteger").BigInteger;
var cnBase58 = (function ()
{
var cnBase58 = (function() {
var b58 = {};
//
var alphabet_str = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
var alphabet_str =
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
var alphabet = [];
for (var i = 0; i < alphabet_str.length; i++) {
alphabet.push(alphabet_str.charCodeAt(i));
@ -88,25 +87,25 @@ var cnBase58 = (function ()
var twopow8 = new JSBigInt(2).pow(8);
var i = 0;
switch (9 - data.length) {
case 1:
res = res.add(data[i++]);
case 2:
res = res.multiply(twopow8).add(data[i++]);
case 3:
res = res.multiply(twopow8).add(data[i++]);
case 4:
res = res.multiply(twopow8).add(data[i++]);
case 5:
res = res.multiply(twopow8).add(data[i++]);
case 6:
res = res.multiply(twopow8).add(data[i++]);
case 7:
res = res.multiply(twopow8).add(data[i++]);
case 8:
res = res.multiply(twopow8).add(data[i++]);
break;
default:
throw "Impossible condition";
case 1:
res = res.add(data[i++]);
case 2:
res = res.multiply(twopow8).add(data[i++]);
case 3:
res = res.multiply(twopow8).add(data[i++]);
case 4:
res = res.multiply(twopow8).add(data[i++]);
case 5:
res = res.multiply(twopow8).add(data[i++]);
case 6:
res = res.multiply(twopow8).add(data[i++]);
case 7:
res = res.multiply(twopow8).add(data[i++]);
case 8:
res = res.multiply(twopow8).add(data[i++]);
break;
default:
throw "Impossible condition";
}
return res;
}
@ -124,7 +123,7 @@ var cnBase58 = (function ()
return res;
}
b58.encode_block = function (data, buf, index) {
b58.encode_block = function(data, buf, index) {
if (data.length < 1 || data.length > full_encoded_block_size) {
throw "Invalid block length: " + data.length;
}
@ -143,14 +142,16 @@ var cnBase58 = (function ()
return buf;
};
b58.encode = function (hex) {
b58.encode = function(hex) {
var data = hextobin(hex);
if (data.length === 0) {
return "";
}
var full_block_count = Math.floor(data.length / full_block_size);
var last_block_size = data.length % full_block_size;
var res_size = full_block_count * full_encoded_block_size + encoded_block_sizes[last_block_size];
var res_size =
full_block_count * full_encoded_block_size +
encoded_block_sizes[last_block_size];
var res = new Uint8Array(res_size);
var i;
@ -158,15 +159,29 @@ var cnBase58 = (function ()
res[i] = alphabet[0];
}
for (i = 0; i < full_block_count; i++) {
res = b58.encode_block(data.subarray(i * full_block_size, i * full_block_size + full_block_size), res, i * full_encoded_block_size);
res = b58.encode_block(
data.subarray(
i * full_block_size,
i * full_block_size + full_block_size,
),
res,
i * full_encoded_block_size,
);
}
if (last_block_size > 0) {
res = b58.encode_block(data.subarray(full_block_count * full_block_size, full_block_count * full_block_size + last_block_size), res, full_block_count * full_encoded_block_size)
res = b58.encode_block(
data.subarray(
full_block_count * full_block_size,
full_block_count * full_block_size + last_block_size,
),
res,
full_block_count * full_encoded_block_size,
);
}
return bintostr(res);
};
b58.decode_block = function (data, buf, index) {
b58.decode_block = function(data, buf, index) {
if (data.length < 1 || data.length > full_encoded_block_size) {
throw "Invalid block length: " + data.length;
}
@ -190,31 +205,52 @@ var cnBase58 = (function ()
res_num = product;
order = order.multiply(alphabet_size);
}
if (res_size < full_block_size && (new JSBigInt(2).pow(8 * res_size).compare(res_num) <= 0)) {
if (
res_size < full_block_size &&
new JSBigInt(2).pow(8 * res_size).compare(res_num) <= 0
) {
throw "Overflow 2";
}
buf.set(uint64_to_8be(res_num, res_size), index);
return buf;
};
b58.decode = function (enc) {
b58.decode = function(enc) {
enc = strtobin(enc);
if (enc.length === 0) {
return "";
}
var full_block_count = Math.floor(enc.length / full_encoded_block_size);
var last_block_size = enc.length % full_encoded_block_size;
var last_block_decoded_size = encoded_block_sizes.indexOf(last_block_size);
var last_block_decoded_size = encoded_block_sizes.indexOf(
last_block_size,
);
if (last_block_decoded_size < 0) {
throw "Invalid encoded length";
}
var data_size = full_block_count * full_block_size + last_block_decoded_size;
var data_size =
full_block_count * full_block_size + last_block_decoded_size;
var data = new Uint8Array(data_size);
for (var i = 0; i < full_block_count; i++) {
data = b58.decode_block(enc.subarray(i * full_encoded_block_size, i * full_encoded_block_size + full_encoded_block_size), data, i * full_block_size);
data = b58.decode_block(
enc.subarray(
i * full_encoded_block_size,
i * full_encoded_block_size + full_encoded_block_size,
),
data,
i * full_block_size,
);
}
if (last_block_size > 0) {
data = b58.decode_block(enc.subarray(full_block_count * full_encoded_block_size, full_block_count * full_encoded_block_size + last_block_size), data, full_block_count * full_block_size);
data = b58.decode_block(
enc.subarray(
full_block_count * full_encoded_block_size,
full_block_count * full_encoded_block_size +
last_block_size,
),
data,
full_block_count * full_block_size,
);
}
return bintohex(data);
};
@ -222,4 +258,4 @@ var cnBase58 = (function ()
return b58;
})();
exports.cnBase58 = cnBase58
exports.cnBase58 = cnBase58;

File diff suppressed because it is too large Load Diff

@ -1,21 +1,21 @@
// Copyright (c) 2014-2018, MyMonero.com
//
//
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@ -26,13 +26,12 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"use strict"
"use strict";
var network_type =
{
var network_type = {
MAINNET: 0,
TESTNET: 1,
STAGENET: 2
STAGENET: 2,
};
exports.network_type = network_type;
//
@ -48,49 +47,46 @@ var __STAGENET_CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 24;
var __STAGENET_CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX = 25;
var __STAGENET_CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX = 36;
//
function cryptonoteBase58PrefixForStandardAddressOn(nettype)
{
if (nettype == null || typeof nettype === 'undefined') {
console.warn("Unexpected nil nettype")
function cryptonoteBase58PrefixForStandardAddressOn(nettype) {
if (nettype == null || typeof nettype === "undefined") {
console.warn("Unexpected nil nettype");
}
if (nettype == network_type.MAINNET) {
return __MAINNET_CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX;
} else if (nettype == network_type.TESTNET) {
return __TESTNET_CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX
return __TESTNET_CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX;
} else if (nettype == network_type.STAGENET) {
return __STAGENET_CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX
return __STAGENET_CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX;
}
throw "Illegal nettype"
throw "Illegal nettype";
}
function cryptonoteBase58PrefixForIntegratedAddressOn(nettype)
{
if (nettype == null || typeof nettype === 'undefined') {
console.warn("Unexpected nil nettype")
function cryptonoteBase58PrefixForIntegratedAddressOn(nettype) {
if (nettype == null || typeof nettype === "undefined") {
console.warn("Unexpected nil nettype");
}
if (nettype == network_type.MAINNET) {
return __MAINNET_CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX;
} else if (nettype == network_type.TESTNET) {
return __TESTNET_CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX
return __TESTNET_CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX;
} else if (nettype == network_type.STAGENET) {
return __STAGENET_CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX
return __STAGENET_CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX;
}
throw "Illegal nettype"
throw "Illegal nettype";
}
function cryptonoteBase58PrefixForSubAddressOn(nettype)
{
if (nettype == null || typeof nettype === 'undefined') {
console.warn("Unexpected nil nettype")
function cryptonoteBase58PrefixForSubAddressOn(nettype) {
if (nettype == null || typeof nettype === "undefined") {
console.warn("Unexpected nil nettype");
}
if (nettype == network_type.MAINNET) {
return __MAINNET_CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX;
} else if (nettype == network_type.TESTNET) {
return __TESTNET_CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX
return __TESTNET_CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX;
} else if (nettype == network_type.STAGENET) {
return __STAGENET_CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX
return __STAGENET_CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX;
}
throw "Illegal nettype"
throw "Illegal nettype";
}
//
exports.cryptonoteBase58PrefixForStandardAddressOn = cryptonoteBase58PrefixForStandardAddressOn;
exports.cryptonoteBase58PrefixForIntegratedAddressOn = cryptonoteBase58PrefixForIntegratedAddressOn;
exports.cryptonoteBase58PrefixForSubAddressOn = cryptonoteBase58PrefixForSubAddressOn;
exports.cryptonoteBase58PrefixForSubAddressOn = cryptonoteBase58PrefixForSubAddressOn;

@ -26,117 +26,131 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
"use strict"
"use strict";
//
const response_parser_utils = require('./response_parser_utils')
const JSBigInt = require('../cryptonote_utils/biginteger').BigInteger // important: grab defined export
const response_parser_utils = require("./response_parser_utils");
const JSBigInt = require("../cryptonote_utils/biginteger").BigInteger; // important: grab defined export
//
function New_ParametersForWalletRequest(address, view_key__private)
{
function New_ParametersForWalletRequest(address, view_key__private) {
return {
address: address,
view_key: view_key__private
}
view_key: view_key__private,
};
}
exports.New_ParametersForWalletRequest = New_ParametersForWalletRequest
exports.New_ParametersForWalletRequest = New_ParametersForWalletRequest;
//
function AddUserAgentParamters(
parameters,
appUserAgent_product,
appUserAgent_version
appUserAgent_product,
appUserAgent_version,
) {
// setting these on params instead of as header field User-Agent so as to retain all info found in User-Agent, such as platform… and these are set so server has option to control delivery
parameters["app_name"] = appUserAgent_product
parameters["app_version"] = appUserAgent_version
parameters["app_name"] = appUserAgent_product;
parameters["app_version"] = appUserAgent_version;
}
exports.AddUserAgentParamters = AddUserAgentParamters
exports.AddUserAgentParamters = AddUserAgentParamters;
//
function HTTPRequest(
request_conformant_module, // such as 'request' or 'xhr' .. TODO: consider switching to 'fetch'
apiAddress_authority, // authority means [subdomain.]host.…[:…] with no trailing slash
endpointPath,
final_parameters,
fn
) { // fn: (err?, data?) -> new Request
if (typeof final_parameters == 'undefined' || final_parameters == null) {
throw "final_parameters must not be nil"
endpointPath,
final_parameters,
fn,
) {
// fn: (err?, data?) -> new Request
if (typeof final_parameters == "undefined" || final_parameters == null) {
throw "final_parameters must not be nil";
// return null
}
const completeURL = _new_APIAddress_baseURLString(apiAddress_authority) + endpointPath
console.log("📡 " + completeURL)
const completeURL =
_new_APIAddress_baseURLString(apiAddress_authority) + endpointPath;
console.log("📡 " + completeURL);
//
const request_options = _new_requestOptions_base("POST", completeURL, final_parameters)
const requestHandle = request_conformant_module(
request_options,
function(err_orProgressEvent, res, body)
{
_new_HTTPRequestHandlerFunctionCallingFn(fn)( // <- called manually instead of directly passed to request_conformant_module call to enable passing completeURL
completeURL,
err_orProgressEvent, res, body
)
}
)
const request_options = _new_requestOptions_base(
"POST",
completeURL,
final_parameters,
);
const requestHandle = request_conformant_module(request_options, function(
err_orProgressEvent,
res,
body,
) {
_new_HTTPRequestHandlerFunctionCallingFn(fn)(
// <- called manually instead of directly passed to request_conformant_module call to enable passing completeURL
completeURL,
err_orProgressEvent,
res,
body,
);
});
//
return requestHandle
return requestHandle;
}
exports.HTTPRequest = HTTPRequest
exports.HTTPRequest = HTTPRequest;
//
function _new_APIAddress_baseURLString(apiAddress_authority) // authority means [subdomain.]host.…[:…]
{
return "https" + "://" + apiAddress_authority + "/"
function _new_APIAddress_baseURLString(
apiAddress_authority, // authority means [subdomain.]host.…[:…]
) {
return "https" + "://" + apiAddress_authority + "/";
}
function _new_requestOptions_base(methodName, completeURL, json_parameters)
{
function _new_requestOptions_base(methodName, completeURL, json_parameters) {
return {
method: methodName,
url: completeURL,
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
Accept: "application/json",
},
json: json_parameters,
useXDR: true, // CORS
withCredentials: true // CORS
}
withCredentials: true, // CORS
};
}
function _new_HTTPRequestHandlerFunctionCallingFn(fn)
{
return function(completeURL, err_orProgressEvent, res, body)
{
function _new_HTTPRequestHandlerFunctionCallingFn(fn) {
return function(completeURL, err_orProgressEvent, res, body) {
// err appears to actually be a ProgressEvent
var err = null
const statusCode = typeof res !== 'undefined' ? res.statusCode : -1
if (statusCode == 0 || statusCode == -1) { // we'll treat 0 as a lack of internet connection.. unless there's a better way to make use of err_orProgressEvent which is apparently going to be typeof ProgressEvent here
err = new Error("Connection Failure")
var err = null;
const statusCode = typeof res !== "undefined" ? res.statusCode : -1;
if (statusCode == 0 || statusCode == -1) {
// we'll treat 0 as a lack of internet connection.. unless there's a better way to make use of err_orProgressEvent which is apparently going to be typeof ProgressEvent here
err = new Error("Connection Failure");
} else if (statusCode !== 200) {
const body_Error = body && typeof body == 'object' ? body.Error : undefined
const statusMessage = res && res.statusMessage ? res.statusMessage : undefined
if (typeof body_Error !== 'undefined' && body_Error) {
err = new Error(body_Error)
} else if (typeof statusMessage !== 'undefined' && statusMessage) {
err = new Error(statusMessage)
const body_Error =
body && typeof body == "object" ? body.Error : undefined;
const statusMessage =
res && res.statusMessage ? res.statusMessage : undefined;
if (typeof body_Error !== "undefined" && body_Error) {
err = new Error(body_Error);
} else if (typeof statusMessage !== "undefined" && statusMessage) {
err = new Error(statusMessage);
} else {
err = new Error("Unknown " + statusCode + " error")
err = new Error("Unknown " + statusCode + " error");
}
}
if (err) {
console.error("❌ " + err);
// console.error("Body:", body)
fn(err, null)
return
fn(err, null);
return;
}
var json;
if (typeof body === 'string') {
if (typeof body === "string") {
try {
json = JSON.parse(body);
} catch (e) {
console.error("❌ HostedMoneroAPIClient Error: Unable to parse json with exception:", e, "\nbody:", body);
fn(e, null)
console.error(
"❌ HostedMoneroAPIClient Error: Unable to parse json with exception:",
e,
"\nbody:",
body,
);
fn(e, null);
}
} else {
json = body
json = body;
}
console.log("✅ " + completeURL + " " + statusCode)
fn(null, json)
}
}
console.log("✅ " + completeURL + " " + statusCode);
fn(null, json);
};
}

@ -26,11 +26,11 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
"use strict"
"use strict";
//
const JSBigInt = require('../cryptonote_utils/biginteger').BigInteger
const monero_utils = require('../monero_utils/monero_cryptonote_utils_instance')
const monero_keyImage_cache_utils = require('../monero_utils/monero_keyImage_cache_utils')
const JSBigInt = require("../cryptonote_utils/biginteger").BigInteger;
const monero_utils = require("../monero_utils/monero_cryptonote_utils_instance");
const monero_keyImage_cache_utils = require("../monero_utils/monero_keyImage_cache_utils");
//
function Parsed_AddressInfo__sync(
keyImage_cache,
@ -38,18 +38,19 @@ function Parsed_AddressInfo__sync(
address,
view_key__private,
spend_key__public,
spend_key__private
) { // -> returnValuesByKey
spend_key__private,
) {
// -> returnValuesByKey
const total_received = new JSBigInt(data.total_received || 0);
const locked_balance = new JSBigInt(data.locked_funds || 0);
var total_sent = new JSBigInt(data.total_sent || 0) // will be modified in place
var total_sent = new JSBigInt(data.total_sent || 0); // will be modified in place
//
const account_scanned_tx_height = data.scanned_height || 0;
const account_scanned_block_height = data.scanned_block_height || 0;
const account_scan_start_height = data.start_height || 0;
const transaction_height = data.transaction_height || 0;
const blockchain_height = data.blockchain_height || 0;
const spent_outputs = data.spent_outputs || []
const spent_outputs = data.spent_outputs || [];
//
for (let spent_output of spent_outputs) {
var key_image = monero_keyImage_cache_utils.Lazy_KeyImage(
@ -59,20 +60,23 @@ function Parsed_AddressInfo__sync(
address,
view_key__private,
spend_key__public,
spend_key__private
)
spend_key__private,
);
if (spent_output.key_image !== key_image) {
// console.log('💬 Output used as mixin (' + spent_output.key_image + '/' + key_image + ')')
total_sent = new JSBigInt(total_sent).subtract(spent_output.amount)
total_sent = new JSBigInt(total_sent).subtract(spent_output.amount);
}
}
//
const ratesBySymbol = data.rates || {} // jic it's not there
const ratesBySymbol = data.rates || {}; // jic it's not there
//
const returnValuesByKey =
{
total_received_String: total_received ? total_received.toString() : null,
locked_balance_String: locked_balance ? locked_balance.toString() : null,
const returnValuesByKey = {
total_received_String: total_received
? total_received.toString()
: null,
locked_balance_String: locked_balance
? locked_balance.toString()
: null,
total_sent_String: total_sent ? total_sent.toString() : null,
// ^serialized JSBigInt
spent_outputs: spent_outputs,
@ -82,26 +86,29 @@ function Parsed_AddressInfo__sync(
transaction_height: transaction_height,
blockchain_height: blockchain_height,
//
ratesBySymbol: ratesBySymbol
}
return returnValuesByKey
ratesBySymbol: ratesBySymbol,
};
return returnValuesByKey;
}
function Parsed_AddressInfo__sync__keyImageManaged(
data,
address,
view_key__private,
spend_key__public,
spend_key__private
) { // -> returnValuesByKey
const keyImageCache = monero_keyImage_cache_utils.Lazy_KeyImageCacheForWalletWith(address)
spend_key__private,
) {
// -> returnValuesByKey
const keyImageCache = monero_keyImage_cache_utils.Lazy_KeyImageCacheForWalletWith(
address,
);
return Parsed_AddressInfo__sync(
keyImageCache,
data,
address,
view_key__private,
spend_key__public,
spend_key__private
)
spend_key__private,
);
}
function Parsed_AddressInfo(
keyImage_cache,
@ -110,7 +117,7 @@ function Parsed_AddressInfo(
view_key__private,
spend_key__public,
spend_key__private,
fn // (err?, returnValuesByKey) -> Void
fn, // (err?, returnValuesByKey) -> Void
) {
const returnValuesByKey = Parsed_AddressInfo__sync(
keyImage_cache,
@ -118,9 +125,9 @@ function Parsed_AddressInfo(
address,
view_key__private,
spend_key__public,
spend_key__private
)
fn(null, returnValuesByKey)
spend_key__private,
);
fn(null, returnValuesByKey);
}
function Parsed_AddressInfo__keyImageManaged(
data,
@ -128,8 +135,9 @@ function Parsed_AddressInfo__keyImageManaged(
view_key__private,
spend_key__public,
spend_key__private,
fn
) { // -> returnValuesByKey
fn,
) {
// -> returnValuesByKey
Parsed_AddressInfo(
monero_keyImage_cache_utils.Lazy_KeyImageCacheForWalletWith(address),
data,
@ -137,13 +145,13 @@ function Parsed_AddressInfo__keyImageManaged(
view_key__private,
spend_key__public,
spend_key__private,
fn
)
fn,
);
}
exports.Parsed_AddressInfo = Parsed_AddressInfo
exports.Parsed_AddressInfo__keyImageManaged = Parsed_AddressInfo__keyImageManaged // in case you can't send a mutable key image cache dictionary
exports.Parsed_AddressInfo__sync__keyImageManaged = Parsed_AddressInfo__sync__keyImageManaged // in case you can't send a mutable key image cache dictionary
exports.Parsed_AddressInfo__sync = Parsed_AddressInfo__sync
exports.Parsed_AddressInfo = Parsed_AddressInfo;
exports.Parsed_AddressInfo__keyImageManaged = Parsed_AddressInfo__keyImageManaged; // in case you can't send a mutable key image cache dictionary
exports.Parsed_AddressInfo__sync__keyImageManaged = Parsed_AddressInfo__sync__keyImageManaged; // in case you can't send a mutable key image cache dictionary
exports.Parsed_AddressInfo__sync = Parsed_AddressInfo__sync;
//
function Parsed_AddressTransactions(
keyImage_cache,
@ -152,7 +160,7 @@ function Parsed_AddressTransactions(
view_key__private,
spend_key__public,
spend_key__private,
fn // (err?, returnValuesByKey) -> Void
fn, // (err?, returnValuesByKey) -> Void
) {
const returnValuesByKey = Parsed_AddressTransactions__sync(
keyImage_cache,
@ -160,9 +168,9 @@ function Parsed_AddressTransactions(
address,
view_key__private,
spend_key__public,
spend_key__private
)
fn(null, returnValuesByKey)
spend_key__private,
);
fn(null, returnValuesByKey);
}
function Parsed_AddressTransactions__sync(
keyImage_cache,
@ -170,15 +178,15 @@ function Parsed_AddressTransactions__sync(
address,
view_key__private,
spend_key__public,
spend_key__private
spend_key__private,
) {
const account_scanned_height = data.scanned_height || 0
const account_scanned_block_height = data.scanned_block_height || 0
const account_scan_start_height = data.start_height || 0
const transaction_height = data.transaction_height || 0
const blockchain_height = data.blockchain_height || 0
const account_scanned_height = data.scanned_height || 0;
const account_scanned_block_height = data.scanned_block_height || 0;
const account_scan_start_height = data.start_height || 0;
const transaction_height = data.transaction_height || 0;
const blockchain_height = data.blockchain_height || 0;
//
const transactions = data.transactions || []
const transactions = data.transactions || [];
//
// TODO: rewrite this with more clarity if possible
for (let i = 0; i < transactions.length; ++i) {
@ -191,80 +199,99 @@ function Parsed_AddressTransactions__sync(
address,
view_key__private,
spend_key__public,
spend_key__private
)
spend_key__private,
);
if (transactions[i].spent_outputs[j].key_image !== key_image) {
// console.log('Output used as mixin, ignoring (' + transactions[i].spent_outputs[j].key_image + '/' + key_image + ')')
transactions[i].total_sent = new JSBigInt(transactions[i].total_sent).subtract(transactions[i].spent_outputs[j].amount).toString()
transactions[i].spent_outputs.splice(j, 1)
j--
transactions[i].total_sent = new JSBigInt(
transactions[i].total_sent,
)
.subtract(transactions[i].spent_outputs[j].amount)
.toString();
transactions[i].spent_outputs.splice(j, 1);
j--;
}
}
}
if (new JSBigInt(transactions[i].total_received || 0).add(transactions[i].total_sent || 0).compare(0) <= 0) {
transactions.splice(i, 1)
i--
continue
if (
new JSBigInt(transactions[i].total_received || 0)
.add(transactions[i].total_sent || 0)
.compare(0) <= 0
) {
transactions.splice(i, 1);
i--;
continue;
}
transactions[i].amount = new JSBigInt(transactions[i].total_received || 0).subtract(transactions[i].total_sent || 0).toString()
transactions[i].approx_float_amount = parseFloat(monero_utils.formatMoney(transactions[i].amount))
transactions[i].timestamp = transactions[i].timestamp
const record__payment_id = transactions[i].payment_id
if (typeof record__payment_id !== 'undefined' && record__payment_id) {
if (record__payment_id.length == 16) { // short (encrypted) pid
if (transactions[i].approx_float_amount < 0) { // outgoing
delete transactions[i]["payment_id"] // need to filter these out .. because the server can't filter out short (encrypted) pids on outgoing txs
transactions[i].amount = new JSBigInt(
transactions[i].total_received || 0,
)
.subtract(transactions[i].total_sent || 0)
.toString();
transactions[i].approx_float_amount = parseFloat(
monero_utils.formatMoney(transactions[i].amount),
);
transactions[i].timestamp = transactions[i].timestamp;
const record__payment_id = transactions[i].payment_id;
if (typeof record__payment_id !== "undefined" && record__payment_id) {
if (record__payment_id.length == 16) {
// short (encrypted) pid
if (transactions[i].approx_float_amount < 0) {
// outgoing
delete transactions[i]["payment_id"]; // need to filter these out .. because the server can't filter out short (encrypted) pids on outgoing txs
}
}
}
}
transactions.sort(function(a, b)
{
transactions.sort(function(a, b) {
if (a.mempool == true) {
if (b.mempool != true) {
return -1 // a first
return -1; // a first
}
// both mempool - fall back to .id compare
} else if (b.mempool == true) {
return 1 // b first
return 1; // b first
}
return b.id - a.id
})
return b.id - a.id;
});
// prepare transactions to be serialized
for (let transaction of transactions) {
transaction.amount = transaction.amount.toString() // JSBigInt -> String
if (typeof transaction.total_sent !== 'undefined' && transaction.total_sent !== null) {
transaction.total_sent = transaction.total_sent.toString()
transaction.amount = transaction.amount.toString(); // JSBigInt -> String
if (
typeof transaction.total_sent !== "undefined" &&
transaction.total_sent !== null
) {
transaction.total_sent = transaction.total_sent.toString();
}
}
// on the other side, we convert transactions timestamp to Date obj
const returnValuesByKey =
{
const returnValuesByKey = {
account_scanned_height: account_scanned_height,
account_scanned_block_height: account_scanned_block_height,
account_scan_start_height: account_scan_start_height,
transaction_height: transaction_height,
blockchain_height: blockchain_height,
serialized_transactions: transactions
}
return returnValuesByKey
serialized_transactions: transactions,
};
return returnValuesByKey;
}
function Parsed_AddressTransactions__sync__keyImageManaged(
data,
address,
view_key__private,
spend_key__public,
spend_key__private
spend_key__private,
) {
const keyImageCache = monero_keyImage_cache_utils.Lazy_KeyImageCacheForWalletWith(address)
const keyImageCache = monero_keyImage_cache_utils.Lazy_KeyImageCacheForWalletWith(
address,
);
return Parsed_AddressTransactions__sync(
keyImageCache,
data,
address,
view_key__private,
spend_key__public,
spend_key__private
)
spend_key__private,
);
}
function Parsed_AddressTransactions__keyImageManaged(
data,
@ -272,7 +299,7 @@ function Parsed_AddressTransactions__keyImageManaged(
view_key__private,
spend_key__public,
spend_key__private,
fn
fn,
) {
Parsed_AddressTransactions(
monero_keyImage_cache_utils.Lazy_KeyImageCacheForWalletWith(address),
@ -281,13 +308,13 @@ function Parsed_AddressTransactions__keyImageManaged(
view_key__private,
spend_key__public,
spend_key__private,
fn
)
fn,
);
}
exports.Parsed_AddressTransactions = Parsed_AddressTransactions
exports.Parsed_AddressTransactions__keyImageManaged = Parsed_AddressTransactions__keyImageManaged
exports.Parsed_AddressTransactions__sync = Parsed_AddressTransactions__sync
exports.Parsed_AddressTransactions__sync__keyImageManaged = Parsed_AddressTransactions__sync__keyImageManaged
exports.Parsed_AddressTransactions = Parsed_AddressTransactions;
exports.Parsed_AddressTransactions__keyImageManaged = Parsed_AddressTransactions__keyImageManaged;
exports.Parsed_AddressTransactions__sync = Parsed_AddressTransactions__sync;
exports.Parsed_AddressTransactions__sync__keyImageManaged = Parsed_AddressTransactions__sync__keyImageManaged;
//
function Parsed_UnspentOuts(
keyImage_cache,
@ -296,7 +323,7 @@ function Parsed_UnspentOuts(
view_key__private,
spend_key__public,
spend_key__private,
fn // (err?, returnValuesByKey)
fn, // (err?, returnValuesByKey)
) {
const returnValuesByKey = Parsed_UnspentOuts__sync(
keyImage_cache,
@ -304,9 +331,9 @@ function Parsed_UnspentOuts(
address,
view_key__private,
spend_key__public,
spend_key__private
)
fn(null, returnValuesByKey)
spend_key__private,
);
fn(null, returnValuesByKey);
}
function Parsed_UnspentOuts__sync(
keyImage_cache,
@ -314,33 +341,53 @@ function Parsed_UnspentOuts__sync(
address,
view_key__private,
spend_key__public,
spend_key__private
spend_key__private,
) {
const data_outputs = data.outputs
const finalized_unspentOutputs = data.outputs || [] // to finalize:
const data_outputs = data.outputs;
const finalized_unspentOutputs = data.outputs || []; // to finalize:
for (var i = 0; i < finalized_unspentOutputs.length; i++) {
const unspent_output = finalized_unspentOutputs[i]
if (unspent_output === null
|| typeof unspent_output === 'undefined'
|| !unspent_output // just preserving what was in the original code
const unspent_output = finalized_unspentOutputs[i];
if (
unspent_output === null ||
typeof unspent_output === "undefined" ||
!unspent_output // just preserving what was in the original code
) {
throw "unspent_output at index " + i + " was null"
throw "unspent_output at index " + i + " was null";
}
const spend_key_images = unspent_output.spend_key_images
if (spend_key_images === null || typeof spend_key_images === 'undefined') {
throw "spend_key_images of unspent_output at index " + i + " was null"
const spend_key_images = unspent_output.spend_key_images;
if (
spend_key_images === null ||
typeof spend_key_images === "undefined"
) {
throw "spend_key_images of unspent_output at index " +
i +
" was null";
}
for (var j = 0; j < spend_key_images.length; j++) {
const finalized_unspentOutput_atI_beforeSplice = finalized_unspentOutputs[i]
if (!finalized_unspentOutput_atI_beforeSplice || typeof finalized_unspentOutput_atI_beforeSplice === 'undefined') {
console.warn(`This unspent output at i ${i} was literally undefined! Skipping.`) // NOTE: Looks like the i-- code below should exit earlier if this is necessary
continue
const finalized_unspentOutput_atI_beforeSplice =
finalized_unspentOutputs[i];
if (
!finalized_unspentOutput_atI_beforeSplice ||
typeof finalized_unspentOutput_atI_beforeSplice === "undefined"
) {
console.warn(
`This unspent output at i ${i} was literally undefined! Skipping.`,
); // NOTE: Looks like the i-- code below should exit earlier if this is necessary
continue;
}
const beforeSplice__tx_pub_key = finalized_unspentOutput_atI_beforeSplice.tx_pub_key
const beforeSplice__index = finalized_unspentOutput_atI_beforeSplice.index
if (typeof beforeSplice__tx_pub_key === 'undefined' || !beforeSplice__tx_pub_key) {
console.warn("This unspent out was missing a tx_pub_key! Skipping.", finalized_unspentOutput_atI_beforeSplice)
continue
const beforeSplice__tx_pub_key =
finalized_unspentOutput_atI_beforeSplice.tx_pub_key;
const beforeSplice__index =
finalized_unspentOutput_atI_beforeSplice.index;
if (
typeof beforeSplice__tx_pub_key === "undefined" ||
!beforeSplice__tx_pub_key
) {
console.warn(
"This unspent out was missing a tx_pub_key! Skipping.",
finalized_unspentOutput_atI_beforeSplice,
);
continue;
}
var key_image = monero_keyImage_cache_utils.Lazy_KeyImage(
keyImage_cache,
@ -349,48 +396,61 @@ function Parsed_UnspentOuts__sync(
address,
view_key__private,
spend_key__public,
spend_key__private
)
if (key_image === finalized_unspentOutput_atI_beforeSplice.spend_key_images[j]) {
spend_key__private,
);
if (
key_image ===
finalized_unspentOutput_atI_beforeSplice.spend_key_images[j]
) {
// console.log("💬 Output was spent; key image: " + key_image + " amount: " + monero_utils.formatMoneyFull(finalized_unspentOutputs[i].amount));
// Remove output from list
finalized_unspentOutputs.splice(i, 1);
const finalized_unspentOutput_atI_afterSplice = finalized_unspentOutputs[i]
const finalized_unspentOutput_atI_afterSplice =
finalized_unspentOutputs[i];
if (finalized_unspentOutput_atI_afterSplice) {
j = finalized_unspentOutput_atI_afterSplice.spend_key_images.length;
j =
finalized_unspentOutput_atI_afterSplice.spend_key_images
.length;
}
i--;
} else {
console.log("💬 Output used as mixin (" + key_image + "/" + finalized_unspentOutputs[i].spend_key_images[j] + ")");
console.log(
"💬 Output used as mixin (" +
key_image +
"/" +
finalized_unspentOutputs[i].spend_key_images[j] +
")",
);
}
}
}
console.log("Unspent outs: " + JSON.stringify(finalized_unspentOutputs));
const unusedOuts = finalized_unspentOutputs.slice(0)
const returnValuesByKey =
{
const unusedOuts = finalized_unspentOutputs.slice(0);
const returnValuesByKey = {
unspentOutputs: finalized_unspentOutputs,
unusedOuts: unusedOuts,
per_kb_fee: data.per_kb_fee // String
}
return returnValuesByKey
per_kb_fee: data.per_kb_fee, // String
};
return returnValuesByKey;
}
function Parsed_UnspentOuts__sync__keyImageManaged(
data,
address,
view_key__private,
spend_key__public,
spend_key__private
spend_key__private,
) {
const keyImageCache = monero_keyImage_cache_utils.Lazy_KeyImageCacheForWalletWith(address)
const keyImageCache = monero_keyImage_cache_utils.Lazy_KeyImageCacheForWalletWith(
address,
);
return Parsed_UnspentOuts__sync(
keyImageCache,
data,
address,
view_key__private,
spend_key__public,
spend_key__private
)
spend_key__private,
);
}
function Parsed_UnspentOuts__keyImageManaged(
data,
@ -398,7 +458,7 @@ function Parsed_UnspentOuts__keyImageManaged(
view_key__private,
spend_key__public,
spend_key__private,
fn
fn,
) {
Parsed_UnspentOuts(
monero_keyImage_cache_utils.Lazy_KeyImageCacheForWalletWith(address),
@ -407,10 +467,10 @@ function Parsed_UnspentOuts__keyImageManaged(
view_key__private,
spend_key__public,
spend_key__private,
fn
)
fn,
);
}
exports.Parsed_UnspentOuts = Parsed_UnspentOuts
exports.Parsed_UnspentOuts__keyImageManaged = Parsed_UnspentOuts__keyImageManaged
exports.Parsed_UnspentOuts__sync = Parsed_UnspentOuts__sync
exports.Parsed_UnspentOuts__sync__keyImageManaged = Parsed_UnspentOuts__sync__keyImageManaged
exports.Parsed_UnspentOuts = Parsed_UnspentOuts;
exports.Parsed_UnspentOuts__keyImageManaged = Parsed_UnspentOuts__keyImageManaged;
exports.Parsed_UnspentOuts__sync = Parsed_UnspentOuts__sync;
exports.Parsed_UnspentOuts__sync__keyImageManaged = Parsed_UnspentOuts__sync__keyImageManaged;

@ -1,21 +1,21 @@
// Copyright (c) 2014-2018, MyMonero.com
//
//
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@ -26,23 +26,23 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
"use strict"
"use strict";
//
// NOTE: The main downside to using an index.js file like this is that it will pull in all the code - rather than the consumer requiring code module-by-module
// It's of course possible to construct your own stripped-down index.[custom name].js file for, e.g., special webpack bundling usages.
const mymonero_core_js = {}
mymonero_core_js.monero_utils = require('./monero_utils/monero_cryptonote_utils_instance')
mymonero_core_js.monero_wallet_utils = require('./monero_utils/monero_wallet_utils')
mymonero_core_js.monero_config = require('./monero_utils/monero_config')
mymonero_core_js.monero_txParsing_utils = require('./monero_utils/monero_txParsing_utils')
mymonero_core_js.monero_sendingFunds_utils = require('./monero_utils/monero_sendingFunds_utils')
mymonero_core_js.monero_requestURI_utils = require('./monero_utils/monero_requestURI_utils')
mymonero_core_js.monero_keyImage_cache_utils = require('./monero_utils/monero_keyImage_cache_utils')
mymonero_core_js.monero_wallet_locale = require('./monero_utils/monero_wallet_locale')
mymonero_core_js.monero_paymentID_utils = require('./monero_utils/monero_paymentID_utils')
mymonero_core_js.api_response_parser_utils = require('./hostAPI/response_parser_utils')
//
mymonero_core_js.nettype_utils = require('./cryptonote_utils/nettype_utils')
mymonero_core_js.JSBigInt = require('./cryptonote_utils/biginteger').BigInteger // so that it is available to a hypothetical consumer's language-bridging web context for constructing string arguments to the above modules
//
module.exports = mymonero_core_js
const mymonero_core_js = {};
mymonero_core_js.monero_utils = require("./monero_utils/monero_cryptonote_utils_instance");
mymonero_core_js.monero_wallet_utils = require("./monero_utils/monero_wallet_utils");
mymonero_core_js.monero_config = require("./monero_utils/monero_config");
mymonero_core_js.monero_txParsing_utils = require("./monero_utils/monero_txParsing_utils");
mymonero_core_js.monero_sendingFunds_utils = require("./monero_utils/monero_sendingFunds_utils");
mymonero_core_js.monero_requestURI_utils = require("./monero_utils/monero_requestURI_utils");
mymonero_core_js.monero_keyImage_cache_utils = require("./monero_utils/monero_keyImage_cache_utils");
mymonero_core_js.monero_wallet_locale = require("./monero_utils/monero_wallet_locale");
mymonero_core_js.monero_paymentID_utils = require("./monero_utils/monero_paymentID_utils");
mymonero_core_js.api_response_parser_utils = require("./hostAPI/response_parser_utils");
//
mymonero_core_js.nettype_utils = require("./cryptonote_utils/nettype_utils");
mymonero_core_js.JSBigInt = require("./cryptonote_utils/biginteger").BigInteger; // so that it is available to a hypothetical consumer's language-bridging web context for constructing string arguments to the above modules
//
module.exports = mymonero_core_js;

@ -1,21 +1,21 @@
// Copyright (c) 2014-2018, MyMonero.com
//
//
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@ -26,12 +26,11 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
"use strict"
"use strict";
//
const JSBigInt = require('../cryptonote_utils/biginteger').BigInteger
const JSBigInt = require("../cryptonote_utils/biginteger").BigInteger;
//
module.exports =
{
module.exports = {
// Number of atomic units in one unit of currency. e.g. 12 => 10^12 = 1000000000000
coinUnitPlaces: 12,
@ -39,16 +38,16 @@ module.exports =
txMinConfirms: 10,
// Currency symbol
coinSymbol: 'XMR',
coinSymbol: "XMR",
// OpenAlias prefix
openAliasPrefix: "xmr",
// Currency name
coinName: 'Monero',
coinName: "Monero",
// Payment URI Prefix
coinUriPrefix: 'monero:',
coinUriPrefix: "monero:",
// Prefix code for addresses
addressPrefix: 18, // 18 => addresses start with "4"
@ -57,11 +56,11 @@ module.exports =
// Dust threshold in atomic units
// 2*10^9 used for choosing outputs/change - we decompose all the way down if the receiver wants now regardless of threshold
dustThreshold: new JSBigInt('2000000000'),
dustThreshold: new JSBigInt("2000000000"),
// Maximum block number, used for tx unlock time
maxBlockNumber: 500000000,
// Average block time in seconds, used for unlock time estimation
avgBlockTime: 60
}
avgBlockTime: 60,
};

@ -1,21 +1,21 @@
// Copyright (c) 2014-2018, MyMonero.com
//
//
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@ -26,10 +26,10 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
"use strict"
"use strict";
//
const monero_config = require('./monero_config')
const cryptonote_utils = require('../cryptonote_utils/cryptonote_utils').cnUtil
const monero_cryptonote_utils_instance = cryptonote_utils(monero_config)
const monero_config = require("./monero_config");
const cryptonote_utils = require("../cryptonote_utils/cryptonote_utils").cnUtil;
const monero_cryptonote_utils_instance = cryptonote_utils(monero_config);
//
module.exports = monero_cryptonote_utils_instance
module.exports = monero_cryptonote_utils_instance;

@ -1,21 +1,21 @@
// Copyright (c) 2014-2018, MyMonero.com
//
//
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@ -26,70 +26,76 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
"use strict"
"use strict";
//
const monero_utils = require('./monero_cryptonote_utils_instance')
const monero_utils = require("./monero_cryptonote_utils_instance");
//
const Lazy_KeyImage = function(
mutable_keyImagesByCacheKey, // pass a mutable JS dictionary
tx_pub_key,
mutable_keyImagesByCacheKey, // pass a mutable JS dictionary
tx_pub_key,
out_index,
public_address,
view_key__private,
spend_key__public,
spend_key__private
spend_key__private,
) {
var cache_index = tx_pub_key + ':' + public_address + ':' + out_index
const cached__key_image = mutable_keyImagesByCacheKey[cache_index]
if (typeof cached__key_image !== 'undefined' && cached__key_image !== null) {
return cached__key_image
var cache_index = tx_pub_key + ":" + public_address + ":" + out_index;
const cached__key_image = mutable_keyImagesByCacheKey[cache_index];
if (
typeof cached__key_image !== "undefined" &&
cached__key_image !== null
) {
return cached__key_image;
}
var key_image = monero_utils.generate_key_image(
tx_pub_key,
view_key__private,
spend_key__public,
spend_key__private,
out_index
).key_image
out_index,
).key_image;
// cache:
mutable_keyImagesByCacheKey[cache_index] = key_image
mutable_keyImagesByCacheKey[cache_index] = key_image;
//
return key_image
}
exports.Lazy_KeyImage = Lazy_KeyImage
return key_image;
};
exports.Lazy_KeyImage = Lazy_KeyImage;
//
//
// Managed caches - Can be used by apps which can't send a mutable_keyImagesByCacheKey
const __global_managed_keyImageCaches_by_walletId = {}
function _managedKeyImageCacheWalletIdForWalletWith(public_address)
{ // NOTE: making the assumption that public_address is unique enough to identify a wallet for caching....
const __global_managed_keyImageCaches_by_walletId = {};
function _managedKeyImageCacheWalletIdForWalletWith(public_address) {
// NOTE: making the assumption that public_address is unique enough to identify a wallet for caching....
// FIXME: with subaddresses, is that still the case? would we need to split them up by subaddr anyway?
if (public_address == "" || !public_address || typeof public_address == 'undefined') {
throw "managedKeyImageCacheIdentifierForWalletWith: Illegal public_address"
if (
public_address == "" ||
!public_address ||
typeof public_address == "undefined"
) {
throw "managedKeyImageCacheIdentifierForWalletWith: Illegal public_address";
}
return (""+public_address)
return "" + public_address;
}
const Lazy_KeyImageCacheForWalletWith = function(public_address)
{
var cacheId = _managedKeyImageCacheWalletIdForWalletWith(public_address)
var cache = __global_managed_keyImageCaches_by_walletId[cacheId]
if (typeof cache === 'undefined' || !cache) {
cache = {}
__global_managed_keyImageCaches_by_walletId[cacheId] = cache
const Lazy_KeyImageCacheForWalletWith = function(public_address) {
var cacheId = _managedKeyImageCacheWalletIdForWalletWith(public_address);
var cache = __global_managed_keyImageCaches_by_walletId[cacheId];
if (typeof cache === "undefined" || !cache) {
cache = {};
__global_managed_keyImageCaches_by_walletId[cacheId] = cache;
}
return cache
}
return cache;
};
exports.Lazy_KeyImageCacheForWalletWith = Lazy_KeyImageCacheForWalletWith;
//
const DeleteManagedKeyImagesForWalletWith = function(public_address)
{ // IMPORTANT: Ensure you call this method when you want to clear your wallet from
// memory or delete it, or else you could leak key images and public addresses.
const cacheId = _managedKeyImageCacheWalletIdForWalletWith(public_address)
delete __global_managed_keyImageCaches_by_walletId[cacheId]
const DeleteManagedKeyImagesForWalletWith = function(public_address) {
// IMPORTANT: Ensure you call this method when you want to clear your wallet from
// memory or delete it, or else you could leak key images and public addresses.
const cacheId = _managedKeyImageCacheWalletIdForWalletWith(public_address);
delete __global_managed_keyImageCaches_by_walletId[cacheId];
//
const cache = __global_managed_keyImageCaches_by_walletId[cacheId]
if (typeof cache !== 'undefined') {
throw "Key image cache still exists after deletion"
const cache = __global_managed_keyImageCaches_by_walletId[cacheId];
if (typeof cache !== "undefined") {
throw "Key image cache still exists after deletion";
}
}
exports.DeleteManagedKeyImagesForWalletWith = DeleteManagedKeyImagesForWalletWith;
};
exports.DeleteManagedKeyImagesForWalletWith = DeleteManagedKeyImagesForWalletWith;

@ -1,21 +1,21 @@
// Copyright (c) 2014-2018, MyMonero.com
//
//
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@ -26,22 +26,24 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
"use strict"
"use strict";
//
const monero_utils = require('./monero_cryptonote_utils_instance')
const monero_utils = require("./monero_cryptonote_utils_instance");
//
// Note: long (64 char, plaintext) payment ids are deprecated.
//
function New_Short_TransactionID()
{
return monero_utils.rand_8()
function New_Short_TransactionID() {
return monero_utils.rand_8();
}
exports.New_Short_TransactionID = New_Short_TransactionID;
exports.New_TransactionID = New_Short_TransactionID;
//
function IsValidPaymentIDOrNoPaymentID(payment_id__orNil)
{
if (payment_id__orNil == null || payment_id__orNil == "" || typeof payment_id__orNil == "undefined") {
function IsValidPaymentIDOrNoPaymentID(payment_id__orNil) {
if (
payment_id__orNil == null ||
payment_id__orNil == "" ||
typeof payment_id__orNil == "undefined"
) {
return true; // no pid
}
let payment_id = payment_id__orNil;
@ -55,31 +57,30 @@ function IsValidPaymentIDOrNoPaymentID(payment_id__orNil)
}
exports.IsValidPaymentIDOrNoPaymentID = IsValidPaymentIDOrNoPaymentID;
//
function IsValidShortPaymentID(payment_id)
{
function IsValidShortPaymentID(payment_id) {
return IsValidPaymentIDOfLength(payment_id, 16);
}
exports.IsValidShortPaymentID = IsValidShortPaymentID;
//
function IsValidLongPaymentID(payment_id)
{
function IsValidLongPaymentID(payment_id) {
return IsValidPaymentIDOfLength(payment_id, 64);
}
exports.IsValidLongPaymentID = IsValidLongPaymentID;
//
function IsValidPaymentIDOfLength(payment_id, required_length)
{
function IsValidPaymentIDOfLength(payment_id, required_length) {
if (required_length != 16 && required_length != 64) {
throw "unexpected IsValidPaymentIDOfLength required_length";
}
let payment_id_length = payment_id.length;
if (payment_id_length !== required_length) { // new encrypted short
if (payment_id_length !== required_length) {
// new encrypted short
return false; // invalid length
}
let pattern = RegExp("^[0-9a-fA-F]{" + required_length + "}$");
if (pattern.test(payment_id) != true) { // not a valid required_length char pid
if (pattern.test(payment_id) != true) {
// not a valid required_length char pid
return false; // then not valid
}
}
return true;
}
exports.IsValidShortPaymentID = IsValidShortPaymentID;

@ -1,21 +1,21 @@
// Copyright (c) 2014-2018, MyMonero.com
//
//
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@ -26,126 +26,137 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
"use strict"
"use strict";
//
const monero_config = require('./monero_config')
const monero_utils = require('./monero_cryptonote_utils_instance')
const monero_config = require("./monero_config");
const monero_utils = require("./monero_cryptonote_utils_instance");
//
const URITypes =
{
const URITypes = {
addressAsFirstPathComponent: 1,
addressAsAuthority: 2
addressAsAuthority: 2,
};
exports.URITypes = URITypes;
//
function New_RequestFunds_URI(
args
) { // -> String?
const address = args.address
function New_RequestFunds_URI(args) {
// -> String?
const address = args.address;
if (!address) {
throw "missing address"
throw "missing address";
// return null
}
var mutable_uri = ""
mutable_uri += monero_config.coinUriPrefix
var mutable_uri = "";
mutable_uri += monero_config.coinUriPrefix;
{
const uriType = args.uriType;
if (uriType === URITypes.addressAsAuthority) {
mutable_uri += "//" // use for inserting a // so data detectors pick it up…
mutable_uri += "//"; // use for inserting a // so data detectors pick it up…
} else if (uriType === URITypes.addressAsFirstPathComponent) {
// nothing to do
} else {
throw "Illegal args.uriType"
throw "Illegal args.uriType";
}
}
mutable_uri += address
var isAppendingParam0 = true
function addParam(parameterName, value)
{
if (value == null || value == ""/*important*/ || typeof value === 'undefined') {
return
mutable_uri += address;
var isAppendingParam0 = true;
function addParam(parameterName, value) {
if (
value == null ||
value == "" /*important*/ ||
typeof value === "undefined"
) {
return;
}
var conjunctionStr = "&"
var conjunctionStr = "&";
if (isAppendingParam0 === true) {
isAppendingParam0 = false
conjunctionStr = "?"
isAppendingParam0 = false;
conjunctionStr = "?";
}
mutable_uri += conjunctionStr
mutable_uri += parameterName + '=' + encodeURIComponent(value)
mutable_uri += conjunctionStr;
mutable_uri += parameterName + "=" + encodeURIComponent(value);
}
{
addParam('tx_amount', args.amount)
if ((args.amountCcySymbol || "").toLowerCase() != monero_config.coinSymbol.toLowerCase()) {
addParam('tx_amount_ccy', args.amountCcySymbol)
addParam("tx_amount", args.amount);
if (
(args.amountCcySymbol || "").toLowerCase() !=
monero_config.coinSymbol.toLowerCase()
) {
addParam("tx_amount_ccy", args.amountCcySymbol);
}
addParam('tx_description', args.description)
addParam('tx_payment_id', args.payment_id)
addParam('tx_message', args.message)
addParam("tx_description", args.description);
addParam("tx_payment_id", args.payment_id);
addParam("tx_message", args.message);
}
return mutable_uri
return mutable_uri;
}
exports.New_RequestFunds_URI = New_RequestFunds_URI
exports.New_RequestFunds_URI = New_RequestFunds_URI;
//
function New_ParsedPayload_FromPossibleRequestURIString(string, nettype)
{ // throws; -> {}
function New_ParsedPayload_FromPossibleRequestURIString(string, nettype) {
// throws; -> {}
//
// detect no-scheme moneroAddr and possible OA addr - if has no monero: prefix
if (string.indexOf(monero_config.coinUriPrefix) !== 0) {
const stringHasQMark = string.indexOf("?") !== -1
if (stringHasQMark) { // fairly sure this is correct.. (just an extra failsafe/filter)
throw "Unrecognized URI format"
const stringHasQMark = string.indexOf("?") !== -1;
if (stringHasQMark) {
// fairly sure this is correct.. (just an extra failsafe/filter)
throw "Unrecognized URI format";
}
let couldBeOAAddress = string.indexOf(".") != -1 // contains period - would be nice to get this from DoesStringContainPeriodChar_excludingAsXMRAddress_qualifyingAsPossibleOAAddress so maybe mymonero_core_js should gain local_modules/OpenAlias
let couldBeOAAddress = string.indexOf(".") != -1; // contains period - would be nice to get this from DoesStringContainPeriodChar_excludingAsXMRAddress_qualifyingAsPossibleOAAddress so maybe mymonero_core_js should gain local_modules/OpenAlias
if (couldBeOAAddress) {
return {
address: string
}
address: string,
};
}
var address__decode_result;
var address__decode_result;
try {
address__decode_result = monero_utils.decode_address(string, nettype)
address__decode_result = monero_utils.decode_address(
string,
nettype,
);
} catch (e) {
throw "No Monero request info"
return
throw "No Monero request info";
return;
}
// then it looks like a monero address
return {
address: string
}
address: string,
};
}
const uriString = string
const url = new URL(uriString)
const protocol = url.protocol
const uriString = string;
const url = new URL(uriString);
const protocol = url.protocol;
if (protocol !== monero_config.coinUriPrefix) {
throw "Request URI has non-Monero protocol"
throw "Request URI has non-Monero protocol";
}
var target_address = url.pathname // var instead of const as have to finalize it
var target_address = url.pathname; // var instead of const as have to finalize it
// it seems that if the URL has // in it, pathname will be empty, but host will contain the address instead
if (target_address === "" || typeof target_address === 'undefined' || !target_address) {
target_address = url.host || url.hostname
if (
target_address === "" ||
typeof target_address === "undefined" ||
!target_address
) {
target_address = url.host || url.hostname;
}
if (target_address.indexOf("//") == 0) {
target_address = target_address.slice(0 + "//".length, target_address.length) // strip prefixing "//" in case URL had protocol:// instead of protocol:
target_address = target_address.slice(
0 + "//".length,
target_address.length,
); // strip prefixing "//" in case URL had protocol:// instead of protocol:
}
const searchParams = url.searchParams // needs to be parsed it seems
const searchParams = url.searchParams; // needs to be parsed it seems
//
const payload =
{
address: target_address
}
const keyPrefixToTrim = "tx_"
const lengthOf_keyPrefixToTrim = keyPrefixToTrim.length
searchParams.forEach(
function(value, key)
{
var storeAt_key = key
if (key.indexOf(keyPrefixToTrim) === 0) {
storeAt_key = key.slice(lengthOf_keyPrefixToTrim, key.length)
}
payload["" + storeAt_key] = value
const payload = {
address: target_address,
};
const keyPrefixToTrim = "tx_";
const lengthOf_keyPrefixToTrim = keyPrefixToTrim.length;
searchParams.forEach(function(value, key) {
var storeAt_key = key;
if (key.indexOf(keyPrefixToTrim) === 0) {
storeAt_key = key.slice(lengthOf_keyPrefixToTrim, key.length);
}
)
payload["" + storeAt_key] = value;
});
//
return payload
return payload;
}
exports.New_ParsedPayload_FromPossibleRequestURIString = New_ParsedPayload_FromPossibleRequestURIString
exports.New_ParsedPayload_FromPossibleRequestURIString = New_ParsedPayload_FromPossibleRequestURIString;

File diff suppressed because it is too large Load Diff

@ -1,21 +1,21 @@
// Copyright (c) 2014-2018, MyMonero.com
//
//
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@ -26,25 +26,25 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
"use strict"
"use strict";
//
const monero_config = require('./monero_config')
const monero_utils = require('./monero_cryptonote_utils_instance')
const monero_config = require("./monero_config");
const monero_utils = require("./monero_cryptonote_utils_instance");
//
function IsTransactionConfirmed(tx, blockchain_height)
{
return (blockchain_height - tx.height) > monero_config.txMinConfirms
function IsTransactionConfirmed(tx, blockchain_height) {
return blockchain_height - tx.height > monero_config.txMinConfirms;
}
exports.IsTransactionConfirmed = IsTransactionConfirmed
exports.IsTransactionConfirmed = IsTransactionConfirmed;
//
function IsTransactionUnlocked(tx, blockchain_height)
{
return monero_utils.is_tx_unlocked(tx.unlock_time || 0, blockchain_height)
function IsTransactionUnlocked(tx, blockchain_height) {
return monero_utils.is_tx_unlocked(tx.unlock_time || 0, blockchain_height);
}
exports.IsTransactionUnlocked = IsTransactionUnlocked
exports.IsTransactionUnlocked = IsTransactionUnlocked;
//
function TransactionLockedReason(tx, blockchain_height)
{
return monero_utils.tx_locked_reason(tx.unlock_time || 0, blockchain_height)
function TransactionLockedReason(tx, blockchain_height) {
return monero_utils.tx_locked_reason(
tx.unlock_time || 0,
blockchain_height,
);
}
exports.TransactionLockedReason = TransactionLockedReason
exports.TransactionLockedReason = TransactionLockedReason;

@ -26,22 +26,24 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
"use strict"
//
const monero_wallet_utils = require('./monero_wallet_utils')
//
function MnemonicWordsetNameWithLocale(currentLocale) // e.g. 'en'
{
const mnemonicWordsetNamesByAppLocaleNames = monero_wallet_utils.MnemonicWordsetNamesByAppLocaleNames
if (currentLocale.indexOf('en') === 0) {
return mnemonicWordsetNamesByAppLocaleNames.English
} else if (currentLocale.indexOf('es') === 0) {
return mnemonicWordsetNamesByAppLocaleNames.Spanish
} else if (currentLocale.indexOf('pt') === 0) {
return mnemonicWordsetNamesByAppLocaleNames.Portuguese
} else if (currentLocale.indexOf('ja') === 0) {
return mnemonicWordsetNamesByAppLocaleNames.Japanese
"use strict";
//
const monero_wallet_utils = require("./monero_wallet_utils");
//
function MnemonicWordsetNameWithLocale(
currentLocale, // e.g. 'en'
) {
const mnemonicWordsetNamesByAppLocaleNames =
monero_wallet_utils.MnemonicWordsetNamesByAppLocaleNames;
if (currentLocale.indexOf("en") === 0) {
return mnemonicWordsetNamesByAppLocaleNames.English;
} else if (currentLocale.indexOf("es") === 0) {
return mnemonicWordsetNamesByAppLocaleNames.Spanish;
} else if (currentLocale.indexOf("pt") === 0) {
return mnemonicWordsetNamesByAppLocaleNames.Portuguese;
} else if (currentLocale.indexOf("ja") === 0) {
return mnemonicWordsetNamesByAppLocaleNames.Japanese;
}
return monero_wallet_utils.DefaultWalletMnemonicWordsetName // which would be .English
return monero_wallet_utils.DefaultWalletMnemonicWordsetName; // which would be .English
}
exports.MnemonicWordsetNameWithLocale = MnemonicWordsetNameWithLocale
exports.MnemonicWordsetNameWithLocale = MnemonicWordsetNameWithLocale;

@ -1,21 +1,21 @@
// Copyright (c) 2014-2018, MyMonero.com
//
//
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@ -26,305 +26,352 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"use strict"
"use strict";
//
const mnemonic = require('../cryptonote_utils/mnemonic')
const monero_utils = require('./monero_cryptonote_utils_instance')
const monero_config = require('./monero_config')
const mnemonic = require("../cryptonote_utils/mnemonic");
const monero_utils = require("./monero_cryptonote_utils_instance");
const monero_config = require("./monero_config");
//
//
////////////////////////////////////////////////////////////////////////////////
// Mnemonic wordset utilities - Exposing available names
//
const wordsetNamesByWordsetName = {}
const allWordsetNames = Object.keys(mnemonic.mn_words)
//
const wordsetNamesByWordsetName = {};
const allWordsetNames = Object.keys(mnemonic.mn_words);
for (let wordsetName of allWordsetNames) {
wordsetNamesByWordsetName[wordsetName] = wordsetName
wordsetNamesByWordsetName[wordsetName] = wordsetName;
}
exports.WordsetNamesByWordsetName = wordsetNamesByWordsetName
exports.AllWordsetNames = allWordsetNames
exports.WordsetNamesByWordsetName = wordsetNamesByWordsetName;
exports.AllWordsetNames = allWordsetNames;
//
//
// Mnemonic wordset utilities - Comparison
// TODO: perhaps move this to mnemonic.js
function AreEqualMnemonics(
a,
b,
a__wordsetName,
b__wordsetName
) {
function AreEqualMnemonics(a, b, a__wordsetName, b__wordsetName) {
if (a__wordsetName !== b__wordsetName) {
return false
return false;
}
const wordsetName = a__wordsetName
const wordset = mnemonic.mn_words[wordsetName]
const prefix_len = wordset.prefix_len
const wordsetName = a__wordsetName;
const wordset = mnemonic.mn_words[wordsetName];
const prefix_len = wordset.prefix_len;
// since mnemonics can be entered with only the first N letters, we must check equality of mnemonics by prefix
let a__mnemonicString_words = a.split(" ")
let b__mnemonicString_words = b.split(" ")
let a__mnemonicString_words = a.split(" ");
let b__mnemonicString_words = b.split(" ");
if (a__mnemonicString_words.length != b__mnemonicString_words.length) {
return false
return false;
}
let numberOf_mnemonicString_words = a__mnemonicString_words.length
for (var i = 0 ; i < numberOf_mnemonicString_words ; i++) {
let a__word = a__mnemonicString_words[i]
let b__word = b__mnemonicString_words[i]
let numberOf_mnemonicString_words = a__mnemonicString_words.length;
for (var i = 0; i < numberOf_mnemonicString_words; i++) {
let a__word = a__mnemonicString_words[i];
let b__word = b__mnemonicString_words[i];
// ... We're assuming that a and b are already valid mneminics
const a_prefix = a__word.slice(0, prefix_len)
const b_prefix = b__word.slice(0, prefix_len)
const a_prefix = a__word.slice(0, prefix_len);
const b_prefix = b__word.slice(0, prefix_len);
if (a_prefix !== b_prefix) {
return false
return false;
}
}
return true
return true;
}
exports.AreEqualMnemonics = AreEqualMnemonics
exports.AreEqualMnemonics = AreEqualMnemonics;
//
////////////////////////////////////////////////////////////////////////////////
// Mnemonic wordset utilities - Wordset name detection by mnemonic contents
// TODO: perhaps move this to mnemonic.js
function WordsetNameAccordingToMnemonicString(mnemonicString) // throws
{
const mnemonicString_words = mnemonicString.split(' ')
function WordsetNameAccordingToMnemonicString(
mnemonicString, // throws
) {
const mnemonicString_words = mnemonicString.split(" ");
if (mnemonicString_words.length == 0) {
throw "Invalid mnemonic"
throw "Invalid mnemonic";
}
var wholeMnemonicSuspectedAsWordsetNamed = null // to derive
var wholeMnemonicSuspectedAsWordsetNamed = null; // to derive
for (let mnemonicString_word of mnemonicString_words) {
var thisWordIsInWordsetNamed = null // to derive
var thisWordIsInWordsetNamed = null; // to derive
for (let wordsetName of allWordsetNames) {
if (wordsetName === 'electrum') {
continue // skip because it conflicts with 'english'
if (wordsetName === "electrum") {
continue; // skip because it conflicts with 'english'
}
const wordset = mnemonic.mn_words[wordsetName]
const prefix_len = wordset.prefix_len
const wordset = mnemonic.mn_words[wordsetName];
const prefix_len = wordset.prefix_len;
if (mnemonicString_word.length < prefix_len) {
throw "Please enter more than " + (prefix_len-1) + " letters per word"
throw "Please enter more than " +
(prefix_len - 1) +
" letters per word";
}
const wordsetWords = wordset.words
const wordsetWords = wordset.words;
for (let wordsetWord of wordsetWords) {
if (wordsetWord.indexOf(mnemonicString_word) == 0) { // we can safely check prefix b/c we've checked mnemonicString_word is of at least min length
thisWordIsInWordsetNamed = wordsetName
break // done looking; exit interior then exterior loops
if (wordsetWord.indexOf(mnemonicString_word) == 0) {
// we can safely check prefix b/c we've checked mnemonicString_word is of at least min length
thisWordIsInWordsetNamed = wordsetName;
break; // done looking; exit interior then exterior loops
}
}
if (thisWordIsInWordsetNamed != null) { // just found
break // also exit
if (thisWordIsInWordsetNamed != null) {
// just found
break; // also exit
}
// haven't found it yet; keep looking
}
if (thisWordIsInWordsetNamed === null) { // didn't find this word in any of the mnemonic wordsets
throw "Unrecognized mnemonic language"
if (thisWordIsInWordsetNamed === null) {
// didn't find this word in any of the mnemonic wordsets
throw "Unrecognized mnemonic language";
}
if (wholeMnemonicSuspectedAsWordsetNamed === null) { // haven't found it yet
wholeMnemonicSuspectedAsWordsetNamed = thisWordIsInWordsetNamed
} else if (thisWordIsInWordsetNamed !== wholeMnemonicSuspectedAsWordsetNamed) {
throw "Ambiguous mnemonic language" // multiple wordset names detected
if (wholeMnemonicSuspectedAsWordsetNamed === null) {
// haven't found it yet
wholeMnemonicSuspectedAsWordsetNamed = thisWordIsInWordsetNamed;
} else if (
thisWordIsInWordsetNamed !== wholeMnemonicSuspectedAsWordsetNamed
) {
throw "Ambiguous mnemonic language"; // multiple wordset names detected
} else {
// nothing to do but keep verifying the rest of the words that it's the same suspsected wordset
}
}
if (wholeMnemonicSuspectedAsWordsetNamed === null) { // this might be redundant, but for logical rigor……
throw "Unrecognized mnemonic language"
if (wholeMnemonicSuspectedAsWordsetNamed === null) {
// this might be redundant, but for logical rigor……
throw "Unrecognized mnemonic language";
}
//
return wholeMnemonicSuspectedAsWordsetNamed
return wholeMnemonicSuspectedAsWordsetNamed;
}
exports.WordsetNameAccordingToMnemonicString = WordsetNameAccordingToMnemonicString
exports.WordsetNameAccordingToMnemonicString = WordsetNameAccordingToMnemonicString;
//
//
////////////////////////////////////////////////////////////////////////////////
// Mnemonic wordset utilities - By locale
//
const mnemonicWordsetNamesByAppLocaleNames =
{
//
const mnemonicWordsetNamesByAppLocaleNames = {
English: "english",
Japanese: "japanese",
Spanish: "spanish",
Portuguese: "portuguese"
Portuguese: "portuguese",
// NOTE: no support for 'electrum' wordset here
}
exports.MnemonicWordsetNamesByAppLocaleNames = mnemonicWordsetNamesByAppLocaleNames
};
exports.MnemonicWordsetNamesByAppLocaleNames = mnemonicWordsetNamesByAppLocaleNames;
//
exports.DefaultWalletMnemonicWordsetName = mnemonicWordsetNamesByAppLocaleNames.English
exports.DefaultWalletMnemonicWordsetName =
mnemonicWordsetNamesByAppLocaleNames.English;
//
//
////////////////////////////////////////////////////////////////////////////////
// Wallet creation:
//
function NewlyCreatedWallet(mnemonic_wordsetName, nettype)
{
const seed = monero_utils.random_scalar() // to generate a 32-byte (25-word) but reduced seed
const mnemonicString = mnemonic.mn_encode(seed, mnemonic_wordsetName)
const keys = monero_utils.create_address(seed, nettype)
//
function NewlyCreatedWallet(mnemonic_wordsetName, nettype) {
const seed = monero_utils.random_scalar(); // to generate a 32-byte (25-word) but reduced seed
const mnemonicString = mnemonic.mn_encode(seed, mnemonic_wordsetName);
const keys = monero_utils.create_address(seed, nettype);
//
return {
seed: seed,
mnemonicString: mnemonicString,
keys: keys
}
keys: keys,
};
}
exports.NewlyCreatedWallet = NewlyCreatedWallet
exports.NewlyCreatedWallet = NewlyCreatedWallet;
//
//
////////////////////////////////////////////////////////////////////////////////
// Wallet login:
//
function MnemonicStringFromSeed(account_seed, mnemonic_wordsetName)
{
const mnemonicString = mnemonic.mn_encode(account_seed, mnemonic_wordsetName)
//
function MnemonicStringFromSeed(account_seed, mnemonic_wordsetName) {
const mnemonicString = mnemonic.mn_encode(
account_seed,
mnemonic_wordsetName,
);
//
return mnemonicString
return mnemonicString;
}
exports.MnemonicStringFromSeed = MnemonicStringFromSeed
exports.MnemonicStringFromSeed = MnemonicStringFromSeed;
//
function SeedAndKeysFromMnemonic_sync(mnemonicString, mnemonic_wordsetName, nettype)
{ // -> {err_str?, seed?, keys?}
mnemonicString = mnemonicString.toLowerCase() || ""
function SeedAndKeysFromMnemonic_sync(
mnemonicString,
mnemonic_wordsetName,
nettype,
) {
// -> {err_str?, seed?, keys?}
mnemonicString = mnemonicString.toLowerCase() || "";
try {
var seed = null
var keys = null
var seed = null;
var keys = null;
switch (mnemonic_wordsetName) {
case 'english':
case "english":
try {
seed = mnemonic.mn_decode(mnemonicString)
seed = mnemonic.mn_decode(mnemonicString);
} catch (e) {
// Try decoding as an electrum seed, on failure throw the original exception
try {
seed = mnemonic.mn_decode(mnemonicString, "electrum")
seed = mnemonic.mn_decode(mnemonicString, "electrum");
} catch (ee) {
throw e
throw e;
}
}
break
break;
default:
seed = mnemonic.mn_decode(mnemonicString, mnemonic_wordsetName)
break
seed = mnemonic.mn_decode(mnemonicString, mnemonic_wordsetName);
break;
}
if (seed === null) {
return { err_str: "Unable to derive seed", seed: null, keys: null }
return { err_str: "Unable to derive seed", seed: null, keys: null };
}
keys = monero_utils.create_address(seed, nettype)
keys = monero_utils.create_address(seed, nettype);
if (keys === null) {
return { err_str: "Unable to derive keys from seed", seed: seed, keys: null }
return {
err_str: "Unable to derive keys from seed",
seed: seed,
keys: null,
};
}
return { err_str: null, seed: seed, keys: keys }
return { err_str: null, seed: seed, keys: keys };
} catch (e) {
console.error("Invalid mnemonic!")
return { err_str: typeof e === 'string' ? e : ""+e, seed: null, keys: null }
console.error("Invalid mnemonic!");
return {
err_str: typeof e === "string" ? e : "" + e,
seed: null,
keys: null,
};
}
}
exports.SeedAndKeysFromMnemonic_sync = SeedAndKeysFromMnemonic_sync
exports.SeedAndKeysFromMnemonic_sync = SeedAndKeysFromMnemonic_sync;
function SeedAndKeysFromMnemonic(mnemonicString, mnemonic_wordsetName, nettype, fn) // made available via callback not because it's async but for convenience
{ // fn: (err?, seed?, keys?)
const payload = SeedAndKeysFromMnemonic_sync(mnemonicString, mnemonic_wordsetName, nettype)
const err = payload.err_str ? new Error(payload.err_str) : null
const seed = payload.seed
const keys = payload.keys
fn(err, seed, keys)
function SeedAndKeysFromMnemonic(
mnemonicString,
mnemonic_wordsetName,
nettype,
fn, // made available via callback not because it's async but for convenience
) {
// fn: (err?, seed?, keys?)
const payload = SeedAndKeysFromMnemonic_sync(
mnemonicString,
mnemonic_wordsetName,
nettype,
);
const err = payload.err_str ? new Error(payload.err_str) : null;
const seed = payload.seed;
const keys = payload.keys;
fn(err, seed, keys);
}
exports.SeedAndKeysFromMnemonic = SeedAndKeysFromMnemonic
exports.SeedAndKeysFromMnemonic = SeedAndKeysFromMnemonic;
//
function VerifiedComponentsForLogIn_sync(
address,
address,
nettype,
view_key,
spend_key_orUndefinedForViewOnly,
seed_orUndefined,
wasAGeneratedWallet
view_key,
spend_key_orUndefinedForViewOnly,
seed_orUndefined,
wasAGeneratedWallet,
) {
var spend_key = typeof spend_key_orUndefinedForViewOnly !== 'undefined' && spend_key_orUndefinedForViewOnly != null && spend_key_orUndefinedForViewOnly != "" ? spend_key_orUndefinedForViewOnly : null
var spend_key =
typeof spend_key_orUndefinedForViewOnly !== "undefined" &&
spend_key_orUndefinedForViewOnly != null &&
spend_key_orUndefinedForViewOnly != ""
? spend_key_orUndefinedForViewOnly
: null;
var isInViewOnlyMode = spend_key == null;
if (!view_key || view_key.length !== 64 || (isInViewOnlyMode ? false : spend_key.length !== 64)) {
return { err_str: "invalid secret key length" }
if (
!view_key ||
view_key.length !== 64 ||
(isInViewOnlyMode ? false : spend_key.length !== 64)
) {
return { err_str: "invalid secret key length" };
}
if (!monero_utils.valid_hex(view_key) || (isInViewOnlyMode ? false : !monero_utils.valid_hex(spend_key))) {
return { err_str: "invalid hex formatting" }
if (
!monero_utils.valid_hex(view_key) ||
(isInViewOnlyMode ? false : !monero_utils.valid_hex(spend_key))
) {
return { err_str: "invalid hex formatting" };
}
var public_keys;
try {
public_keys = monero_utils.decode_address(address, nettype)
public_keys = monero_utils.decode_address(address, nettype);
} catch (e) {
return { err_str: "invalid address" }
return { err_str: "invalid address" };
}
var expected_view_pub;
try {
expected_view_pub = monero_utils.sec_key_to_pub(view_key)
expected_view_pub = monero_utils.sec_key_to_pub(view_key);
} catch (e) {
return { err_str: "invalid view key" }
return { err_str: "invalid view key" };
}
var expected_spend_pub
var expected_spend_pub;
if (spend_key.length === 64) {
try {
expected_spend_pub = monero_utils.sec_key_to_pub(spend_key)
expected_spend_pub = monero_utils.sec_key_to_pub(spend_key);
} catch (e) {
return { err_str: "invalid spend key" }
return { err_str: "invalid spend key" };
}
}
if (public_keys.view !== expected_view_pub) {
return { err_str: "invalid view key" }
return { err_str: "invalid view key" };
}
if (!isInViewOnlyMode && (public_keys.spend !== expected_spend_pub)) {
return { err_str: "invalid spend key" }
if (!isInViewOnlyMode && public_keys.spend !== expected_spend_pub) {
return { err_str: "invalid spend key" };
}
const private_keys =
{
const private_keys = {
view: view_key,
spend: spend_key
}
spend: spend_key,
};
var account_seed = null; // default
if (typeof seed_orUndefined !== 'undefined' && seed_orUndefined && seed_orUndefined.length != 0) {
if (
typeof seed_orUndefined !== "undefined" &&
seed_orUndefined &&
seed_orUndefined.length != 0
) {
var expected_account;
try {
expected_account = monero_utils.create_address(seed_orUndefined, nettype)
expected_account = monero_utils.create_address(
seed_orUndefined,
nettype,
);
} catch (e) {
return { err_str: "invalid seed" }
return { err_str: "invalid seed" };
}
if (expected_account.view.sec !== view_key ||
if (
expected_account.view.sec !== view_key ||
expected_account.spend.sec !== spend_key ||
expected_account.public_addr !== address) {
return { err_str: "invalid seed" }
expected_account.public_addr !== address
) {
return { err_str: "invalid seed" };
}
account_seed = seed_orUndefined
account_seed = seed_orUndefined;
}
const payload =
{
const payload = {
err_str: null, // err
address: address,
account_seed: account_seed !== "" ? account_seed : null,
public_keys: public_keys,
private_keys: private_keys,
isInViewOnlyMode: isInViewOnlyMode
}
return payload
isInViewOnlyMode: isInViewOnlyMode,
};
return payload;
}
exports.VerifiedComponentsForLogIn_sync = VerifiedComponentsForLogIn_sync
exports.VerifiedComponentsForLogIn_sync = VerifiedComponentsForLogIn_sync;
//
function VerifiedComponentsForLogIn(
address,
address,
nettype,
view_key,
spend_key_orUndefinedForViewOnly,
seed_orUndefined,
view_key,
spend_key_orUndefinedForViewOnly,
seed_orUndefined,
wasAGeneratedWallet,
fn
) { // fn: (err?, address, account_seed, public_keys, private_keys, isInViewOnlyMode) -> Void
fn,
) {
// fn: (err?, address, account_seed, public_keys, private_keys, isInViewOnlyMode) -> Void
const payload = VerifiedComponentsForLogIn_sync(
address,
address,
nettype,
view_key,
spend_key_orUndefinedForViewOnly,
seed_orUndefined,
wasAGeneratedWallet
)
view_key,
spend_key_orUndefinedForViewOnly,
seed_orUndefined,
wasAGeneratedWallet,
);
fn(
payload.err_str ? new Error(payload.err_str) : null,
payload.address,
payload.account_seed,
payload.public_keys,
payload.private_keys,
payload.isInViewOnlyMode
)
payload.isInViewOnlyMode,
);
}
exports.VerifiedComponentsForLogIn = VerifiedComponentsForLogIn
exports.VerifiedComponentsForLogIn = VerifiedComponentsForLogIn;

@ -7,6 +7,9 @@
"type": "git",
"url": "git+https://github.com/mymonero/mymonero-core-js.git"
},
"scripts": {
"format": "find . -name '*.js*' | xargs prettier --write --config ./.prettierrc --config-precedence file-override"
},
"keywords": [
"monero",
"mymonero",

@ -1,61 +1,120 @@
"use strict"
const mymonero = require('mymonero-core-js');
const assert = require('assert');
"use strict";
const mymonero = require("mymonero-core-js");
const assert = require("assert");
var public_key = "904e49462268d771cc1649084c35aa1296bfb214880fe2e7f373620a3e2ba597";
var private_key = "52aa4c69b93b780885c9d7f51e6fd5795904962c61a2e07437e130784846f70d";
var public_key =
"904e49462268d771cc1649084c35aa1296bfb214880fe2e7f373620a3e2ba597";
var private_key =
"52aa4c69b93b780885c9d7f51e6fd5795904962c61a2e07437e130784846f70d";
var nettype = mymonero.nettype_utils.network_type.MAINNNET;
describe('cryptonote_utils tests', function() {
it('is valid hex', function() {
describe("cryptonote_utils tests", function() {
it("is valid hex", function() {
var valid = mymonero.monero_utils.valid_hex(private_key);
assert.strictEqual(valid, true);
});
it('fast hash / keccak-256', function() {
var hash = mymonero.monero_utils.cn_fast_hash(private_key , private_key.length);
assert.equal(hash, "64997ff54f0d82ee87d51e971a0329d4315481eaeb4ad2403c65d5843480c414");
it("fast hash / keccak-256", function() {
var hash = mymonero.monero_utils.cn_fast_hash(
private_key,
private_key.length,
);
assert.equal(
hash,
"64997ff54f0d82ee87d51e971a0329d4315481eaeb4ad2403c65d5843480c414",
);
});
it('generate key derivation', function() {
var derivation = mymonero.monero_utils.generate_key_derivation(public_key, private_key);
assert.equal(derivation, "591c749f1868c58f37ec3d2a9d2f08e7f98417ac4f8131e3a57c1fd71273ad00");
it("generate key derivation", function() {
var derivation = mymonero.monero_utils.generate_key_derivation(
public_key,
private_key,
);
assert.equal(
derivation,
"591c749f1868c58f37ec3d2a9d2f08e7f98417ac4f8131e3a57c1fd71273ad00",
);
});
it('decode mainnet primary address', function() {
var decoded = mymonero.monero_utils.decode_address("49qwWM9y7j1fvaBK684Y5sMbN8MZ3XwDLcSaqcKwjh5W9kn9qFigPBNBwzdq6TCAm2gKxQWrdZuEZQBMjQodi9cNRHuCbTr", nettype);
var expected = { spend: "d8f1e81ecbe25ce8b596d426fb02fe7b1d4bb8d14c06b3d3e371a60eeea99534", view: "576f0e61e250d941746ed147f602b5eb1ea250ca385b028a935e166e18f74bd7" }
it("decode mainnet primary address", function() {
var decoded = mymonero.monero_utils.decode_address(
"49qwWM9y7j1fvaBK684Y5sMbN8MZ3XwDLcSaqcKwjh5W9kn9qFigPBNBwzdq6TCAm2gKxQWrdZuEZQBMjQodi9cNRHuCbTr",
nettype,
);
var expected = {
spend:
"d8f1e81ecbe25ce8b596d426fb02fe7b1d4bb8d14c06b3d3e371a60eeea99534",
view:
"576f0e61e250d941746ed147f602b5eb1ea250ca385b028a935e166e18f74bd7",
};
assert.deepEqual(decoded, expected);
});
it('decode mainnet integrated address', function() {
var decoded = mymonero.monero_utils.decode_address("4KYcX9yTizXfvaBK684Y5sMbN8MZ3XwDLcSaqcKwjh5W9kn9qFigPBNBwzdq6TCAm2gKxQWrdZuEZQBMjQodi9cNd3mZpgrjXBKMx9ee7c", nettype);
var expected = { spend: "d8f1e81ecbe25ce8b596d426fb02fe7b1d4bb8d14c06b3d3e371a60eeea99534", view: "576f0e61e250d941746ed147f602b5eb1ea250ca385b028a935e166e18f74bd7", intPaymentId: "83eab71fbee84eb9" }
it("decode mainnet integrated address", function() {
var decoded = mymonero.monero_utils.decode_address(
"4KYcX9yTizXfvaBK684Y5sMbN8MZ3XwDLcSaqcKwjh5W9kn9qFigPBNBwzdq6TCAm2gKxQWrdZuEZQBMjQodi9cNd3mZpgrjXBKMx9ee7c",
nettype,
);
var expected = {
spend:
"d8f1e81ecbe25ce8b596d426fb02fe7b1d4bb8d14c06b3d3e371a60eeea99534",
view:
"576f0e61e250d941746ed147f602b5eb1ea250ca385b028a935e166e18f74bd7",
intPaymentId: "83eab71fbee84eb9",
};
assert.deepEqual(decoded, expected);
});
it('hash_to_scalar', function() {
it("hash_to_scalar", function() {
var scalar = mymonero.monero_utils.hash_to_scalar(private_key);
assert.equal(scalar, "77c5899835aa6f96b13827f43b094abf315481eaeb4ad2403c65d5843480c404");
assert.equal(
scalar,
"77c5899835aa6f96b13827f43b094abf315481eaeb4ad2403c65d5843480c404",
);
});
it('derivation_to_scalar', function() {
var derivation = mymonero.monero_utils.generate_key_derivation(public_key, private_key);
it("derivation_to_scalar", function() {
var derivation = mymonero.monero_utils.generate_key_derivation(
public_key,
private_key,
);
var scalar = mymonero.monero_utils.derivation_to_scalar(derivation, 1);
assert.equal(scalar, "201ce3c258e09eeb6132ec266d24ee1ca957828f384ce052d5bc217c2c55160d");
});
it('derive public key', function() {
var derivation = mymonero.monero_utils.generate_key_derivation(public_key, private_key);
var output_key = mymonero.monero_utils.derive_public_key(derivation, 1, public_key);
assert.equal(output_key, "da26518ddb54cde24ccfc59f36df13bbe9bdfcb4ef1b223d9ab7bef0a50c8be3");
});
it('derive subaddress public key', function() {
var derivation = mymonero.monero_utils.generate_key_derivation(public_key, private_key);
var subaddress_public_key = mymonero.monero_utils.derive_subaddress_public_key(public_key, derivation, 1);
assert.equal(subaddress_public_key, "dfc9e4a0039e913204c1c0f78e954a7ec7ce291d8ffe88265632f0da9d8de1be")
assert.equal(
scalar,
"201ce3c258e09eeb6132ec266d24ee1ca957828f384ce052d5bc217c2c55160d",
);
});
it("derive public key", function() {
var derivation = mymonero.monero_utils.generate_key_derivation(
public_key,
private_key,
);
var output_key = mymonero.monero_utils.derive_public_key(
derivation,
1,
public_key,
);
assert.equal(
output_key,
"da26518ddb54cde24ccfc59f36df13bbe9bdfcb4ef1b223d9ab7bef0a50c8be3",
);
});
it("derive subaddress public key", function() {
var derivation = mymonero.monero_utils.generate_key_derivation(
public_key,
private_key,
);
var subaddress_public_key = mymonero.monero_utils.derive_subaddress_public_key(
public_key,
derivation,
1,
);
assert.equal(
subaddress_public_key,
"dfc9e4a0039e913204c1c0f78e954a7ec7ce291d8ffe88265632f0da9d8de1be",
);
});
});

@ -0,0 +1,17 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
async@^2.6.0:
version "2.6.1"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610"
dependencies:
lodash "^4.17.10"
lodash@^4.17.10:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
prettier@^1.13.5:
version "1.13.5"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.5.tgz#7ae2076998c8edce79d63834e9b7b09fead6bfd0"
Loading…
Cancel
Save