Refactor/cryptonote utils (#17)

* Change parse to be a static property

* First passthrough

* Change mutability of const -> let where needed

* Fix redundant type checks / global variables

* Reorg codebase + fix majority imports

* Add more types

* Add moment dep

* Add types to test

* More type err fixes

* Loop refactoring + more types

* Convert more errors to objects, fix more type errs, use functional constructs over loops

* Remove unused functions

* Add typescript dep

* Change string errors to obj

* Fix more tsc errors

* skirt around tsc errors for unimplemented bulletproofs

* Fix biginteger error

* Add ts-jest

* Fix rest of tsc errors, fix tests
pull/40/head
HenryNguyen5 6 years ago committed by GitHub
parent 12f131ee9d
commit 9100c6beea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

3
.gitignore vendored

@ -3,4 +3,5 @@ node_modules/
coverage
.vscode
yarn-error.log
tests/fixtures
tests/fixtures
dist

@ -1,3 +1,13 @@
import {
skGen,
ge_scalarmult_base,
identity,
ge_scalarmult,
hashToPoint,
MLSAG_Gen,
MLSAG_ver,
} from "cryptonote_utils";
// Copyright (c) 2014-2018, MyMonero.com
//
// All rights reserved.
@ -26,21 +36,19 @@
// 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.
const monero_utils = require("../").monero_utils;
it("MG_sigs", () => {
function skvGen(len) {
let skVec = [];
function skvGen(len: number) {
const skVec: string[] = [];
for (let i = 0; i < len; i++) {
skVec.push(monero_utils.skGen());
skVec.push(skGen());
}
return skVec;
}
//initializes a key matrix;
//first parameter is rows,
//second is columns
function keyMInit(rows, cols) {
let rv = [];
function keyMInit(cols: number) {
let rv: string[][] = [];
for (let i = 0; i < cols; i++) {
rv.push([]);
}
@ -53,7 +61,7 @@ it("MG_sigs", () => {
let N = 3; // cols
let R = 2; // rows
let xm = keyMInit(R, N); // = [[None]*N] #just used to generate test public keys
let xm = keyMInit(N); // = [[None]*N] #just used to generate test public keys
let sk = skvGen(R);
// [
@ -63,15 +71,15 @@ it("MG_sigs", () => {
// [pubkeyn, commitmentn]]
// // Gen creates a signature which proves that for some column in the keymatrix "pk"
// the signer knows a secret key for each row in that column
let P = keyMInit(R, N); // = keyM[[None]*N] #stores the public keys;
let P = keyMInit(N); // = keyM[[None]*N] #stores the public keys;
let ind = 2;
let i = 0;
for (j = 0; j < R; j++) {
for (i = 0; i < N; i++) {
xm[i][j] = monero_utils.skGen();
P[i][j] = monero_utils.ge_scalarmult_base(xm[i][j]); // generate fake [pubkey, commit]
xm[i][j] = skGen();
P[i][j] = ge_scalarmult_base(xm[i][j]); // generate fake [pubkey, commit]
}
}
@ -80,34 +88,27 @@ it("MG_sigs", () => {
sk[j] = xm[ind][j];
}
let message = monero_utils.identity();
let kimg = monero_utils.ge_scalarmult(
monero_utils.hashToPoint(P[ind][0]),
sk[0],
);
let rv = monero_utils.MLSAG_Gen(message, P, sk, kimg, ind);
let c = monero_utils.MLSAG_ver(message, P, rv, kimg);
let message = identity();
let kimg = ge_scalarmult(hashToPoint(P[ind][0]), sk[0]);
let rv = MLSAG_Gen(message, P, sk, kimg, ind);
let c = MLSAG_ver(message, P, rv, kimg);
expect(c).toEqual(true);
xtmp = skvGen(R);
xm = keyMInit(R, N); // = [[None]*N] #just used to generate test public keys
xm = keyMInit(N); // = [[None]*N] #just used to generate test public keys
sk = skvGen(R);
for (j = 0; j < R; j++) {
for (i = 0; i < N; i++) {
xm[i][j] = monero_utils.skGen();
P[i][j] = monero_utils.ge_scalarmult_base(xm[i][j]); // generate fake [pubkey, commit]
xm[i][j] = skGen();
P[i][j] = ge_scalarmult_base(xm[i][j]); // generate fake [pubkey, commit]
}
}
sk[1] = skGen(); //assume we don't know one of the private keys..
kimg = monero_utils.ge_scalarmult(
monero_utils.hashToPoint(P[ind][0]),
sk[0],
);
rv = monero_utils.MLSAG_Gen(message, P, sk, kimg, ind);
c = monero_utils.MLSAG_ver(message, P, rv, kimg);
kimg = ge_scalarmult(hashToPoint(P[ind][0]), sk[0]);
rv = MLSAG_Gen(message, P, sk, kimg, ind);
c = MLSAG_ver(message, P, rv, kimg);
expect(c).toEqual(false);
});

@ -1,3 +1,6 @@
import { generate_parameters } from "./test_parameters";
import { genBorromean, verifyBorromean } from "cryptonote_utils";
// Copyright (c) 2014-2018, MyMonero.com
//
// All rights reserved.
@ -26,13 +29,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.
const monero_utils = require("../../").monero_utils;
const { generate_parameters } = require("./test_parameters");
const { indi, P1v, P2v, xv, N } = generate_parameters();
it("borromean_3", () => {
// #true one
const bb = monero_utils.genBorromean(xv, [P1v, P2v], indi, 2, N); /*?.*/
const valid = monero_utils.verifyBorromean(bb, P1v, P2v); /*?.*/
const bb = genBorromean(xv, [P1v, P2v], indi, 2, N); /*?.*/
const valid = verifyBorromean(bb, P1v, P2v); /*?.*/
expect(valid).toBe(true);
});

@ -26,14 +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.
const monero_utils = require("../../").monero_utils;
const { generate_parameters } = require("./test_parameters");
import { generate_parameters } from "./test_parameters";
import { genBorromean, verifyBorromean } from "cryptonote_utils";
const { indi, P1v, P2v, xv, N } = generate_parameters();
it("borromean_2", () => {
//#false one
indi[3] = `${(+indi[3] + 1) % 2}`;
const bb = monero_utils.genBorromean(xv, [P1v, P2v], indi, 2, N); /*?.*/
const valid = monero_utils.verifyBorromean(bb, P1v, P2v); /*?.*/
const bb = genBorromean(xv, [P1v, P2v], indi, 2, N); /*?.*/
const valid = verifyBorromean(bb, P1v, P2v); /*?.*/
expect(valid).toBe(false);
});

@ -26,8 +26,8 @@
// 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.
const monero_utils = require("../../").monero_utils;
const { generate_parameters } = require("./test_parameters");
import { generate_parameters } from "./test_parameters";
import { genBorromean, verifyBorromean } from "cryptonote_utils";
const { indi, P1v, P2v, xv, N } = generate_parameters();
it("borromean_3", () => {
@ -35,7 +35,7 @@ it("borromean_3", () => {
indi[3] = `${(+indi[3] + 1) % 2}`;
indi[3] = `${(+indi[3] + 1) % 2}`;
const bb = monero_utils.genBorromean(xv, [P1v, P2v], indi, 2, N); /*?.*/
const valid = monero_utils.verifyBorromean(bb, P1v, P2v); /*?.*/
const bb = genBorromean(xv, [P1v, P2v], indi, 2, N); /*?.*/
const valid = verifyBorromean(bb, P1v, P2v); /*?.*/
expect(valid).toBe(true);
});

@ -1,3 +1,5 @@
import { genBorromean, verifyBorromean } from "cryptonote_utils";
// Copyright (c) 2014-2018, MyMonero.com
//
// All rights reserved.
@ -26,13 +28,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.
const monero_utils = require("../../").monero_utils;
const { generate_parameters } = require("./test_parameters");
import { generate_parameters } from "./test_parameters";
const { indi, P1v, P2v, xv, N } = generate_parameters();
it("borromean_4", () => {
// #false one
const bb = monero_utils.genBorromean(xv, [P2v, P1v], indi, 2, N); /*?.*/
const valid = monero_utils.verifyBorromean(bb, P1v, P2v); /*?.*/
const bb = genBorromean(xv, [P2v, P1v], indi, 2, N); /*?.*/
const valid = verifyBorromean(bb, P1v, P2v); /*?.*/
expect(valid).toBe(false);
});

@ -26,36 +26,35 @@
// 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.
const monero_utils = require("../../").monero_utils;
const { randomBytes } = require("crypto");
import { randomBytes } from "crypto";
import {
skGen,
ge_scalarmult_base,
ge_add,
ge_sub,
H2,
} from "cryptonote_utils";
import { padLeft } from "cryptonote_utils/formatters";
function randomBit() {
// get random 8 bits in hex
const rand8bits = randomBytes(1).toString("hex");
// take 4 bits "nibble" and convert to binary
// then take last index
return monero_utils.padLeft(
parseInt(rand8bits[0], 16).toString(2),
4,
0,
)[3];
return padLeft(parseInt(rand8bits[0], 16).toString(2), 4, "0")[3];
}
//Tests for Borromean signatures
//#boro true one, false one, C != sum Ci, and one out of the range..
const N = 64;
let xv = [], // vector of secret keys, 1 per ring (nrings)
P1v = [], //key64, arr of commitments Ci
P2v = [], //key64
indi = []; // vector of secret indexes, 1 per ring (nrings), can be a string
let indi_2 = [];
let indi_3 = [];
let indi_4 = [];
let xv: string[] = [], // vector of secret keys, 1 per ring (nrings)
P1v: string[] = [], //key64, arr of commitments Ci
P2v: string[] = [], //key64
indi: string[] = []; // vector of secret indexes, 1 per ring (nrings), can be a string
let generated = false;
function generate_parameters() {
export function generate_parameters() {
if (generated) {
const indiCopy = [...indi];
@ -64,20 +63,18 @@ function generate_parameters() {
for (let j = 0; j < N; j++) {
indi[j] = randomBit(); /*?.*/
xv[j] = monero_utils.skGen(); /*?.*/
xv[j] = skGen(); /*?.*/
if (+indi[j] === 0) {
P1v[j] = monero_utils.ge_scalarmult_base(xv[j]); /*?.*/
P1v[j] = ge_scalarmult_base(xv[j]); /*?.*/
} else {
P1v[j] = monero_utils.ge_scalarmult_base(xv[j]); // calculate aG = xv[j].G /*?.*/
P1v[j] = monero_utils.ge_add(P1v[j], monero_utils.H2[j]); // calculate aG + H2 /*?.*/
P1v[j] = ge_scalarmult_base(xv[j]); // calculate aG = xv[j].G /*?.*/
P1v[j] = ge_add(P1v[j], H2[j]); // calculate aG + H2 /*?.*/
}
P2v[j] = monero_utils.ge_sub(P1v[j], monero_utils.H2[j]); /*?.*/
P2v[j] = ge_sub(P1v[j], H2[j]); /*?.*/
}
generated = true;
return { xv, P1v, P2v, indi, N };
}
}
module.exports = { generate_parameters };

@ -26,122 +26,105 @@
// 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 mymonero = require("../");
const assert = require("assert");
import {
cn_fast_hash,
NetType,
valid_hex,
generate_key_derivation,
decode_address,
hash_to_scalar,
derivation_to_scalar,
derive_public_key,
derive_subaddress_public_key,
} from "cryptonote_utils";
var public_key =
const public_key =
"904e49462268d771cc1649084c35aa1296bfb214880fe2e7f373620a3e2ba597";
var private_key =
const private_key =
"52aa4c69b93b780885c9d7f51e6fd5795904962c61a2e07437e130784846f70d";
var nettype = mymonero.nettype_utils.network_type.MAINNET;
const nettype = NetType.MAINNET;
describe("cryptonote_utils tests", function() {
it("is valid hex", function() {
var valid = mymonero.monero_utils.valid_hex(private_key);
assert.strictEqual(valid, true);
const valid = valid_hex(private_key);
expect(valid).toEqual(true);
});
it("fast hash / keccak-256", function() {
var hash = mymonero.monero_utils.cn_fast_hash(
private_key,
private_key.length,
);
assert.equal(
hash,
const hash = cn_fast_hash(private_key);
expect(hash).toEqual(
"64997ff54f0d82ee87d51e971a0329d4315481eaeb4ad2403c65d5843480c414",
);
});
it("generate key derivation", function() {
var derivation = mymonero.monero_utils.generate_key_derivation(
public_key,
private_key,
);
assert.equal(
derivation,
const derivation = generate_key_derivation(public_key, private_key);
expect(derivation).toEqual(
"591c749f1868c58f37ec3d2a9d2f08e7f98417ac4f8131e3a57c1fd71273ad00",
);
});
it("decode mainnet primary address", function() {
var decoded = mymonero.monero_utils.decode_address(
const decoded = decode_address(
"49qwWM9y7j1fvaBK684Y5sMbN8MZ3XwDLcSaqcKwjh5W9kn9qFigPBNBwzdq6TCAm2gKxQWrdZuEZQBMjQodi9cNRHuCbTr",
nettype,
);
var expected = {
const expected = {
spend:
"d8f1e81ecbe25ce8b596d426fb02fe7b1d4bb8d14c06b3d3e371a60eeea99534",
view:
"576f0e61e250d941746ed147f602b5eb1ea250ca385b028a935e166e18f74bd7",
};
assert.deepEqual(decoded, expected);
expect(decoded).toEqual(expected);
});
it("decode mainnet integrated address", function() {
var decoded = mymonero.monero_utils.decode_address(
const decoded = decode_address(
"4KYcX9yTizXfvaBK684Y5sMbN8MZ3XwDLcSaqcKwjh5W9kn9qFigPBNBwzdq6TCAm2gKxQWrdZuEZQBMjQodi9cNd3mZpgrjXBKMx9ee7c",
nettype,
);
var expected = {
const expected = {
spend:
"d8f1e81ecbe25ce8b596d426fb02fe7b1d4bb8d14c06b3d3e371a60eeea99534",
view:
"576f0e61e250d941746ed147f602b5eb1ea250ca385b028a935e166e18f74bd7",
intPaymentId: "83eab71fbee84eb9",
};
assert.deepEqual(decoded, expected);
expect(decoded).toEqual(expected);
});
it("hash_to_scalar", function() {
var scalar = mymonero.monero_utils.hash_to_scalar(private_key);
assert.equal(
scalar,
const scalar = hash_to_scalar(private_key);
expect(scalar).toEqual(
"77c5899835aa6f96b13827f43b094abf315481eaeb4ad2403c65d5843480c404",
);
});
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,
const derivation = generate_key_derivation(public_key, private_key);
const scalar = derivation_to_scalar(derivation, 1);
expect(scalar).toEqual(
"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,
const derivation = generate_key_derivation(public_key, private_key);
const output_key = derive_public_key(derivation, 1, public_key);
expect(output_key).toEqual(
"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(
const derivation = generate_key_derivation(public_key, private_key);
const subaddress_public_key = derive_subaddress_public_key(
public_key,
derivation,
1,
);
assert.equal(
subaddress_public_key,
expect(subaddress_public_key).toEqual(
"dfc9e4a0039e913204c1c0f78e954a7ec7ce291d8ffe88265632f0da9d8de1be",
);
});

@ -1,3 +1,6 @@
import { BigInt } from "biginteger";
import { skGen, d2s, encode_rct_ecdh, decode_rct_ecdh } from "cryptonote_utils";
// Copyright (c) 2014-2018, MyMonero.com
//
// All rights reserved.
@ -26,29 +29,26 @@
// 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.
const JSBigInt = require("../cryptonote_utils/biginteger").BigInteger;
const monero_utils = require("../").monero_utils;
it("ecdh_roundtrip", () => {
const test_amounts = [
new JSBigInt(1),
new JSBigInt(1),
new JSBigInt(2),
new JSBigInt(3),
new JSBigInt(4),
new JSBigInt(5),
new JSBigInt(10000),
new BigInt(1),
new BigInt(1),
new BigInt(2),
new BigInt(3),
new BigInt(4),
new BigInt(5),
new BigInt(10000),
new JSBigInt("10000000000000000000"),
new JSBigInt("10203040506070809000"),
new BigInt("10000000000000000000"),
new BigInt("10203040506070809000"),
new JSBigInt("123456789123456789"),
new BigInt("123456789123456789"),
];
for (const amount of test_amounts) {
const k = monero_utils.skGen();
const scalar = monero_utils.skGen(); /*?*/
const amt = monero_utils.d2s(amount.toString());
const k = skGen();
const scalar = skGen(); /*?*/
const amt = d2s(amount.toString());
const t0 = {
mask: scalar,
amount: amt,
@ -57,9 +57,9 @@ it("ecdh_roundtrip", () => {
// both are strings so we can shallow copy
let t1 = { ...t0 };
t1 = monero_utils.encode_rct_ecdh(t1, k);
t1 = encode_rct_ecdh(t1, k);
t1 = monero_utils.decode_rct_ecdh(t1, k);
t1 = decode_rct_ecdh(t1, k);
expect(t1.mask).toEqual(t0.mask);
expect(t1.amount).toEqual(t0.amount);
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,3 +1,14 @@
import { BigInt } from "biginteger";
import {
hash_to_scalar,
Z,
generate_key_image_2,
genRct,
verRct,
decodeRct,
} from "cryptonote_utils";
import { ctskpkGen, populateFromBlockchain } from "./test_utils";
// Copyright (c) 2014-2018, MyMonero.com
//
// All rights reserved.
@ -25,12 +36,6 @@
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// 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.
const {
ctskpkGen,
populateFromBlockchain,
JSBigInt,
monero_utils,
} = require("./test_utils");
it("range_proofs", () => {
//Ring CT Stuff
@ -55,29 +60,29 @@ it("range_proofs", () => {
// key vector
let amount_keys = [];
amounts.push(new JSBigInt(500));
amount_keys.push(monero_utils.hash_to_scalar(monero_utils.Z));
amounts.push(new BigInt(500));
amount_keys.push(hash_to_scalar(Z));
amounts.push(new JSBigInt(4500));
amount_keys.push(monero_utils.hash_to_scalar(monero_utils.Z));
amounts.push(new BigInt(4500));
amount_keys.push(hash_to_scalar(Z));
amounts.push(new JSBigInt(500));
amount_keys.push(monero_utils.hash_to_scalar(monero_utils.Z));
amounts.push(new BigInt(500));
amount_keys.push(hash_to_scalar(Z));
amounts.push(new JSBigInt(500));
amount_keys.push(monero_utils.hash_to_scalar(monero_utils.Z));
amounts.push(new BigInt(500));
amount_keys.push(hash_to_scalar(Z));
//compute rct data with mixin 500
const { index, mixRing } = populateFromBlockchain(inPk, 3);
// generate kimg
const kimg = [monero_utils.generate_key_image_2(inPk[0].dest, inSk[0].x)];
const kimg = [generate_key_image_2(inPk[0].dest, inSk[0].x)];
let s = monero_utils.genRct(
monero_utils.Z,
let s = genRct(
Z,
inSk,
kimg,
[[]],
[],
amounts,
mixRing,
amount_keys,
@ -85,32 +90,22 @@ it("range_proofs", () => {
"0",
);
expect(monero_utils.verRct(s, true, mixRing, kimg[0])).toEqual(true);
expect(monero_utils.verRct(s, false, mixRing, kimg[0])).toEqual(true);
expect(verRct(s, true, mixRing, kimg[0])).toEqual(true);
expect(verRct(s, false, mixRing, kimg[0])).toEqual(true);
//decode received amount
monero_utils.decodeRct(s, amount_keys[1], 1);
decodeRct(s, amount_keys[1], 1);
// Ring CT with failing MG sig part should not verify!
// Since sum of inputs != outputs
amounts[1] = new JSBigInt(12501);
amounts[1] = new BigInt(12501);
s = monero_utils.genRct(
monero_utils.Z,
inSk,
kimg,
[[]],
amounts,
mixRing,
amount_keys,
[index],
"0",
);
s = genRct(Z, inSk, kimg, [], amounts, mixRing, amount_keys, [index], "0");
expect(monero_utils.verRct(s, true, mixRing, kimg[0])).toEqual(true);
expect(monero_utils.verRct(s, false, mixRing, kimg[0])).toEqual(false);
expect(verRct(s, true, mixRing, kimg[0])).toEqual(true);
expect(verRct(s, false, mixRing, kimg[0])).toEqual(false);
//decode received amount
monero_utils.decodeRct(s, amount_keys[1], 1);
decodeRct(s, amount_keys[1], 1);
});

@ -1,3 +1,15 @@
import { BigInt } from "biginteger";
import {
hash_to_scalar,
Z,
generate_key_image_2,
genRct,
verRct,
decodeRct,
} from "cryptonote_utils";
import { ctskpkGen, populateFromBlockchain } from "./test_utils";
import { SecretCommitment, MixCommitment } from "types";
// Copyright (c) 2014-2018, MyMonero.com
//
// All rights reserved.
@ -25,19 +37,13 @@
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// 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.
const {
ctskpkGen,
populateFromBlockchain,
JSBigInt,
monero_utils,
} = require("./test_utils");
it("range_proofs", () => {
//Ring CT Stuff
//ct range proofs
// ctkey vectors
let inSk = [],
inPk = [];
let inSk: SecretCommitment[] = [],
inPk: MixCommitment[] = [];
// ctkeys
// we test only a single input here since the current impl of
@ -55,29 +61,29 @@ it("range_proofs", () => {
// key vector
let amount_keys = [];
amounts.push(new JSBigInt(1000));
amount_keys.push(monero_utils.hash_to_scalar(monero_utils.Z));
amounts.push(new BigInt(1000));
amount_keys.push(hash_to_scalar(Z));
amounts.push(new JSBigInt(4000));
amount_keys.push(monero_utils.hash_to_scalar(monero_utils.Z));
amounts.push(new BigInt(4000));
amount_keys.push(hash_to_scalar(Z));
amounts.push(new JSBigInt(1000));
amount_keys.push(monero_utils.hash_to_scalar(monero_utils.Z));
amounts.push(new BigInt(1000));
amount_keys.push(hash_to_scalar(Z));
//compute rct data with mixin 500
const { index, mixRing } = populateFromBlockchain(inPk, 2);
// generate kimg
const kimg = [monero_utils.generate_key_image_2(inPk[0].dest, inSk[0].x)];
const kimg = [generate_key_image_2(inPk[0].dest, inSk[0].x)];
// add fee of 1 NOTE: fee is passed in with its endian not swapped, hence no usage of d2s
const fee = "1";
let s = monero_utils.genRct(
monero_utils.Z,
let s = genRct(
Z,
inSk,
kimg,
[[]],
[],
amounts,
mixRing,
amount_keys,
@ -85,32 +91,22 @@ it("range_proofs", () => {
fee,
);
expect(monero_utils.verRct(s, true, mixRing, kimg[0])).toEqual(true);
expect(monero_utils.verRct(s, false, mixRing, kimg[0])).toEqual(true);
expect(verRct(s, true, mixRing, kimg[0])).toEqual(true);
expect(verRct(s, false, mixRing, kimg[0])).toEqual(true);
//decode received amount
monero_utils.decodeRct(s, amount_keys[1], 1);
decodeRct(s, amount_keys[1], 1);
// Ring CT with failing MG sig part should not verify!
// Since sum of inputs != outputs
amounts[1] = new JSBigInt(4501);
amounts[1] = new BigInt(4501);
s = monero_utils.genRct(
monero_utils.Z,
inSk,
kimg,
[[]],
amounts,
mixRing,
amount_keys,
[index],
fee,
);
s = genRct(Z, inSk, kimg, [], amounts, mixRing, amount_keys, [index], fee);
expect(monero_utils.verRct(s, true, mixRing, kimg[0])).toEqual(true);
expect(monero_utils.verRct(s, false, mixRing, kimg[0])).toEqual(false);
expect(verRct(s, true, mixRing, kimg[0])).toEqual(true);
expect(verRct(s, false, mixRing, kimg[0])).toEqual(false);
//decode received amount
monero_utils.decodeRct(s, amount_keys[1], 1);
decodeRct(s, amount_keys[1], 1);
});

@ -26,12 +26,17 @@
// 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.
const {
ctskpkGen,
populateFromBlockchainSimple,
JSBigInt,
monero_utils,
} = require("./test_utils");
import { ctskpkGen, populateFromBlockchainSimple } from "./test_utils";
import {
hash_to_scalar,
Z,
random_scalar,
generate_key_image_2,
genRct,
verRctSimple,
decodeRctSimple,
} from "cryptonote_utils";
import { BigInt } from "index";
it("should test ringct simple transactions", () => {
//Ring CT Stuff
@ -50,7 +55,7 @@ it("should test ringct simple transactions", () => {
let [sctmp, pctmp] = ctskpkGen(3000);
inSk.push(sctmp);
inPk.push(pctmp);
inamounts.push(3000);
inamounts.push(new BigInt(3000));
}
//add fake input 3000
@ -60,16 +65,16 @@ it("should test ringct simple transactions", () => {
let [sctmp, pctmp] = ctskpkGen(3000);
inSk.push(sctmp);
inPk.push(pctmp);
inamounts.push(3000);
inamounts.push(new BigInt(3000));
}
outamounts.push(5000);
amount_keys.push(monero_utils.hash_to_scalar(monero_utils.Z));
outamounts.push(new BigInt(5000));
amount_keys.push(hash_to_scalar(Z));
outamounts.push(999);
amount_keys.push(monero_utils.hash_to_scalar(monero_utils.Z));
outamounts.push(new BigInt(999));
amount_keys.push(hash_to_scalar(Z));
const message = monero_utils.random_scalar();
const message = random_scalar();
const txnFee = "1";
// generate mixin and indices
@ -84,11 +89,11 @@ it("should test ringct simple transactions", () => {
// generate kimg
const kimg = [
monero_utils.generate_key_image_2(inPk[0].dest, inSk[0].x),
monero_utils.generate_key_image_2(inPk[1].dest, inSk[1].x),
generate_key_image_2(inPk[0].dest, inSk[0].x),
generate_key_image_2(inPk[1].dest, inSk[1].x),
];
const s = monero_utils.genRct(
const s = genRct(
message,
inSk,
kimg,
@ -100,8 +105,8 @@ it("should test ringct simple transactions", () => {
txnFee,
);
expect(monero_utils.verRctSimple(s, true, mixRings, kimg)).toEqual(true);
expect(monero_utils.verRctSimple(s, false, mixRings, kimg)).toEqual(true);
expect(verRctSimple(s, true, mixRings, kimg)).toEqual(true);
expect(verRctSimple(s, false, mixRings, kimg)).toEqual(true);
monero_utils.decodeRctSimple(s, amount_keys[1], 1);
decodeRctSimple(s, amount_keys[1], 1);
});

@ -25,60 +25,67 @@
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// 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.
const monero_utils = require("../../").monero_utils;
const JSBigInt = require("../../cryptonote_utils/biginteger").BigInteger;
const { randomBytes } = require("crypto");
import { randomBytes } from "crypto";
import {
random_keypair,
d2s,
ge_scalarmult,
ge_add,
H,
} from "cryptonote_utils";
import { SecretCommitment, MixCommitment } from "types";
//generates a <secret , public> / Pedersen commitment to the amount
function ctskpkGen(amount) {
let sk = {},
pk = {};
const key_pair1 = monero_utils.random_keypair();
const key_pair2 = monero_utils.random_keypair();
export function ctskpkGen(amount: number): [SecretCommitment, MixCommitment] {
let sk = { x: "", a: "" },
pk = { dest: "", mask: "" };
const key_pair1 = random_keypair();
const key_pair2 = random_keypair();
sk.x = key_pair1.sec;
pk.dest = key_pair1.pub;
sk.a = key_pair2.sec;
pk.mask = key_pair2.pub;
const am = monero_utils.d2s(amount.toString());
const bH = monero_utils.ge_scalarmult(monero_utils.H, am);
const am = d2s(amount.toString());
const bH = ge_scalarmult(H, am);
pk.mask = monero_utils.ge_add(pk.mask, bH);
pk.mask = ge_add(pk.mask, bH);
return [sk, pk];
}
function randomNum(upperLimit) {
export function randomNum(upperLimit: number) {
return parseInt(randomBytes(1).toString("hex"), 16) % upperLimit;
}
//These functions get keys from blockchain
//replace these when connecting blockchain
//getKeyFromBlockchain grabs a key from the blockchain at "reference_index" to mix with
function getKeyFromBlockchain(reference_index) {
let a = {};
a.dest = monero_utils.random_keypair().pub;
a.mask = monero_utils.random_keypair().pub;
// These functions get keys from blockchain
// replace these when connecting blockchain
// getKeyFromBlockchain grabs a key from the blockchain at "reference_index" (unused param) to mix with
export function getKeyFromBlockchain() {
let a = { dest: "", mask: "" };
a.dest = random_keypair().pub;
a.mask = random_keypair().pub;
return a;
}
// populateFromBlockchain creates a keymatrix with "mixin" + 1 columns and one of the columns is inPk
// the return values are the key matrix, and the index where inPk was put (random).
function populateFromBlockchain(inPk, mixin) {
export function populateFromBlockchain(inPk: MixCommitment[], mixin: number) {
const rows = inPk.length;
const inPkCpy = [...inPk];
// ctkeyMatrix
const mixRing = [];
const mixRing: MixCommitment[][] = [];
const index = randomNum(mixin);
for (let i = 0; i < rows; i++) {
mixRing[i] = [];
for (let j = 0; j <= mixin; j++) {
if (j !== index) {
mixRing[i][j] = getKeyFromBlockchain(index); /*?*/
mixRing[i][j] = getKeyFromBlockchain(); /*?*/
} else {
mixRing[i][j] = inPkCpy.pop();
mixRing[i][j] = inPkCpy.pop() as MixCommitment;
}
}
}
@ -86,13 +93,16 @@ function populateFromBlockchain(inPk, mixin) {
return { mixRing, index };
}
function populateFromBlockchainSimple(inPk, mixin) {
export function populateFromBlockchainSimple(
inPk: MixCommitment,
mixin: number,
) {
const index = randomNum(mixin);
const mixRing = [];
for (let i = 0; i <= mixin; i++) {
if (i !== index) {
mixRing[i] = getKeyFromBlockchain(index);
mixRing[i] = getKeyFromBlockchain();
} else {
mixRing[i] = inPk;
}
@ -100,12 +110,3 @@ function populateFromBlockchainSimple(inPk, mixin) {
return { mixRing, index };
}
module.exports = {
ctskpkGen,
populateFromBlockchain,
populateFromBlockchainSimple,
getKeyFromBlockchain,
monero_utils,
JSBigInt,
};

File diff suppressed because it is too large Load Diff

@ -1,6 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const cryptonote_base58_1 = require("./cryptonote_base58");
const { decode, encode } = cryptonote_base58_1.cnBase58;
exports.decode = decode;
exports.encode = encode;

@ -1,3 +0,0 @@
"use strict";
const CNCrypto = require("./cryptonote_crypto_EMSCRIPTEN");
module.exports = CNCrypto;

@ -1,9 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const nacl_fast_cn_1 = require("./nacl-fast-cn");
const { ge_add, ge_double_scalarmult_base_vartime, ge_double_scalarmult_postcomp_vartime, ge_scalarmult, ge_scalarmult_base, } = nacl_fast_cn_1.ll;
exports.ge_add = ge_add;
exports.ge_double_scalarmult_base_vartime = ge_double_scalarmult_base_vartime;
exports.ge_double_scalarmult_postcomp_vartime = ge_double_scalarmult_postcomp_vartime;
exports.ge_scalarmult = ge_scalarmult;
exports.ge_scalarmult_base = ge_scalarmult_base;

@ -1,571 +0,0 @@
(function(nacl) {
'use strict';
// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
// Public domain.
//
// Implementation derived from TweetNaCl version 20140427.
// See for details: http://tweetnacl.cr.yp.to/
// modified 2017 for some CN functions by luigi1111
var gf = function(init) {
var i, r = new Float64Array(16);
if (init) for (i = 0; i < init.length; i++) r[i] = init[i];
return r;
};
// Pluggable, initialized in high-level API below.
var randombytes = function(/* x, n */) { throw new Error('no PRNG'); };
var _0 = new Uint8Array(16);
var _9 = new Uint8Array(32); _9[0] = 9;
var gf0 = gf(),
gf1 = gf([1]),
_121665 = gf([0xdb41, 1]),
D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]),
D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]),
X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]),
Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]),
I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]);
function vn(x, xi, y, yi, n) {
var i,d = 0;
for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i];
return (1 & ((d - 1) >>> 8)) - 1;
}
function crypto_verify_16(x, xi, y, yi) {
return vn(x,xi,y,yi,16);
}
function crypto_verify_32(x, xi, y, yi) {
return vn(x,xi,y,yi,32);
}
function set25519(r, a) {
var i;
for (i = 0; i < 16; i++) r[i] = a[i]|0;
}
function car25519(o) {
var i, v, c = 1;
for (i = 0; i < 16; i++) {
v = o[i] + c + 65535;
c = Math.floor(v / 65536);
o[i] = v - c * 65536;
}
o[0] += c-1 + 37 * (c-1);
}
function sel25519(p, q, b) {
var t, c = ~(b-1);
for (var i = 0; i < 16; i++) {
t = c & (p[i] ^ q[i]);
p[i] ^= t;
q[i] ^= t;
}
}
function pack25519(o, n) {
var i, j, b;
var m = gf(), t = gf();
for (i = 0; i < 16; i++) t[i] = n[i];
car25519(t);
car25519(t);
car25519(t);
for (j = 0; j < 2; j++) {
m[0] = t[0] - 0xffed;
for (i = 1; i < 15; i++) {
m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1);
m[i-1] &= 0xffff;
}
m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1);
b = (m[15]>>16) & 1;
m[14] &= 0xffff;
sel25519(t, m, 1-b);
}
for (i = 0; i < 16; i++) {
o[2*i] = t[i] & 0xff;
o[2*i+1] = t[i]>>8;
}
}
function neq25519(a, b) {
var c = new Uint8Array(32), d = new Uint8Array(32);
pack25519(c, a);
pack25519(d, b);
return crypto_verify_32(c, 0, d, 0);
}
function par25519(a) {
var d = new Uint8Array(32);
pack25519(d, a);
return d[0] & 1;
}
function unpack25519(o, n) {
var i;
for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8);
o[15] &= 0x7fff;
}
function A(o, a, b) {
for (var i = 0; i < 16; i++) o[i] = a[i] + b[i];
}
function Z(o, a, b) {
for (var i = 0; i < 16; i++) o[i] = a[i] - b[i];
}
function M(o, a, b) {
var v, c,
t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0,
t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0,
t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0,
t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0,
b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5],
b6 = b[6], b7 = b[7], b8 = b[8], b9 = b[9], b10 = b[10],
b11 = b[11], b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15];
v = a[0];
t0 += v * b0; t1 += v * b1; t2 += v * b2; t3 += v * b3;
t4 += v * b4; t5 += v * b5; t6 += v * b6; t7 += v * b7;
t8 += v * b8; t9 += v * b9; t10 += v * b10; t11 += v * b11;
t12 += v * b12; t13 += v * b13; t14 += v * b14; t15 += v * b15;
v = a[1];
t1 += v * b0; t2 += v * b1; t3 += v * b2; t4 += v * b3;
t5 += v * b4; t6 += v * b5; t7 += v * b6; t8 += v * b7;
t9 += v * b8; t10 += v * b9; t11 += v * b10; t12 += v * b11;
t13 += v * b12; t14 += v * b13; t15 += v * b14; t16 += v * b15;
v = a[2];
t2 += v * b0; t3 += v * b1; t4 += v * b2; t5 += v * b3;
t6 += v * b4; t7 += v * b5; t8 += v * b6; t9 += v * b7;
t10 += v * b8; t11 += v * b9; t12 += v * b10; t13 += v * b11;
t14 += v * b12; t15 += v * b13; t16 += v * b14; t17 += v * b15;
v = a[3];
t3 += v * b0; t4 += v * b1; t5 += v * b2; t6 += v * b3;
t7 += v * b4; t8 += v * b5; t9 += v * b6; t10 += v * b7;
t11 += v * b8; t12 += v * b9; t13 += v * b10; t14 += v * b11;
t15 += v * b12; t16 += v * b13; t17 += v * b14; t18 += v * b15;
v = a[4];
t4 += v * b0; t5 += v * b1; t6 += v * b2; t7 += v * b3;
t8 += v * b4; t9 += v * b5; t10 += v * b6; t11 += v * b7;
t12 += v * b8; t13 += v * b9; t14 += v * b10; t15 += v * b11;
t16 += v * b12; t17 += v * b13; t18 += v * b14; t19 += v * b15;
v = a[5];
t5 += v * b0; t6 += v * b1; t7 += v * b2; t8 += v * b3;
t9 += v * b4; t10 += v * b5; t11 += v * b6; t12 += v * b7;
t13 += v * b8; t14 += v * b9; t15 += v * b10; t16 += v * b11;
t17 += v * b12; t18 += v * b13; t19 += v * b14; t20 += v * b15;
v = a[6];
t6 += v * b0; t7 += v * b1; t8 += v * b2; t9 += v * b3;
t10 += v * b4; t11 += v * b5; t12 += v * b6; t13 += v * b7;
t14 += v * b8; t15 += v * b9; t16 += v * b10; t17 += v * b11;
t18 += v * b12; t19 += v * b13; t20 += v * b14; t21 += v * b15;
v = a[7];
t7 += v * b0; t8 += v * b1; t9 += v * b2; t10 += v * b3;
t11 += v * b4; t12 += v * b5; t13 += v * b6; t14 += v * b7;
t15 += v * b8; t16 += v * b9; t17 += v * b10; t18 += v * b11;
t19 += v * b12; t20 += v * b13; t21 += v * b14; t22 += v * b15;
v = a[8];
t8 += v * b0; t9 += v * b1; t10 += v * b2; t11 += v * b3;
t12 += v * b4; t13 += v * b5; t14 += v * b6; t15 += v * b7;
t16 += v * b8; t17 += v * b9; t18 += v * b10; t19 += v * b11;
t20 += v * b12; t21 += v * b13; t22 += v * b14; t23 += v * b15;
v = a[9];
t9 += v * b0; t10 += v * b1; t11 += v * b2; t12 += v * b3;
t13 += v * b4; t14 += v * b5; t15 += v * b6; t16 += v * b7;
t17 += v * b8; t18 += v * b9; t19 += v * b10; t20 += v * b11;
t21 += v * b12; t22 += v * b13; t23 += v * b14; t24 += v * b15;
v = a[10];
t10 += v * b0; t11 += v * b1; t12 += v * b2; t13 += v * b3;
t14 += v * b4; t15 += v * b5; t16 += v * b6; t17 += v * b7;
t18 += v * b8; t19 += v * b9; t20 += v * b10; t21 += v * b11;
t22 += v * b12; t23 += v * b13; t24 += v * b14; t25 += v * b15;
v = a[11];
t11 += v * b0; t12 += v * b1; t13 += v * b2; t14 += v * b3;
t15 += v * b4; t16 += v * b5; t17 += v * b6; t18 += v * b7;
t19 += v * b8; t20 += v * b9; t21 += v * b10; t22 += v * b11;
t23 += v * b12; t24 += v * b13; t25 += v * b14; t26 += v * b15;
v = a[12];
t12 += v * b0; t13 += v * b1; t14 += v * b2; t15 += v * b3;
t16 += v * b4; t17 += v * b5; t18 += v * b6; t19 += v * b7;
t20 += v * b8; t21 += v * b9; t22 += v * b10; t23 += v * b11;
t24 += v * b12; t25 += v * b13; t26 += v * b14; t27 += v * b15;
v = a[13];
t13 += v * b0; t14 += v * b1; t15 += v * b2; t16 += v * b3;
t17 += v * b4; t18 += v * b5; t19 += v * b6; t20 += v * b7;
t21 += v * b8; t22 += v * b9; t23 += v * b10; t24 += v * b11;
t25 += v * b12; t26 += v * b13; t27 += v * b14; t28 += v * b15;
v = a[14];
t14 += v * b0; t15 += v * b1; t16 += v * b2; t17 += v * b3;
t18 += v * b4; t19 += v * b5; t20 += v * b6; t21 += v * b7;
t22 += v * b8; t23 += v * b9; t24 += v * b10; t25 += v * b11;
t26 += v * b12; t27 += v * b13; t28 += v * b14; t29 += v * b15;
v = a[15];
t15 += v * b0; t16 += v * b1; t17 += v * b2; t18 += v * b3;
t19 += v * b4; t20 += v * b5; t21 += v * b6; t22 += v * b7;
t23 += v * b8; t24 += v * b9; t25 += v * b10; t26 += v * b11;
t27 += v * b12; t28 += v * b13; t29 += v * b14; t30 += v * b15;
t0 += 38 * t16; t1 += 38 * t17; t2 += 38 * t18; t3 += 38 * t19;
t4 += 38 * t20; t5 += 38 * t21; t6 += 38 * t22; t7 += 38 * t23;
t8 += 38 * t24; t9 += 38 * t25; t10 += 38 * t26; t11 += 38 * t27;
t12 += 38 * t28; t13 += 38 * t29; t14 += 38 * t30; // t15 left as is
// first car
c = 1;
v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536;
v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536;
v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536;
v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536;
v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536;
v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536;
v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536;
v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536;
v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536;
v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536;
v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
t0 += c-1 + 37 * (c-1);
// second car
c = 1;
v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536;
v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536;
v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536;
v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536;
v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536;
v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536;
v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536;
v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536;
v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536;
v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536;
v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
t0 += c-1 + 37 * (c-1);
o[ 0] = t0;
o[ 1] = t1;
o[ 2] = t2;
o[ 3] = t3;
o[ 4] = t4;
o[ 5] = t5;
o[ 6] = t6;
o[ 7] = t7;
o[ 8] = t8;
o[ 9] = t9;
o[10] = t10;
o[11] = t11;
o[12] = t12;
o[13] = t13;
o[14] = t14;
o[15] = t15;
}
function S(o, a) {
M(o, a, a);
}
function inv25519(o, i) {
var c = gf();
var a;
for (a = 0; a < 16; a++) c[a] = i[a];
for (a = 253; a >= 0; a--) {
S(c, c);
if(a !== 2 && a !== 4) M(c, c, i);
}
for (a = 0; a < 16; a++) o[a] = c[a];
}
function pow2523(o, i) {
var c = gf();
var a;
for (a = 0; a < 16; a++) c[a] = i[a];
for (a = 250; a >= 0; a--) {
S(c, c);
if(a !== 1) M(c, c, i);
}
for (a = 0; a < 16; a++) o[a] = c[a];
}
function add(p, q) {
var a = gf(), b = gf(), c = gf(),
d = gf(), e = gf(), f = gf(),
g = gf(), h = gf(), t = gf();
Z(a, p[1], p[0]);
Z(t, q[1], q[0]);
M(a, a, t);
A(b, p[0], p[1]);
A(t, q[0], q[1]);
M(b, b, t);
M(c, p[3], q[3]);
M(c, c, D2);
M(d, p[2], q[2]);
A(d, d, d);
Z(e, b, a);
Z(f, d, c);
A(g, d, c);
A(h, b, a);
M(p[0], e, f);
M(p[1], h, g);
M(p[2], g, f);
M(p[3], e, h);
}
function cswap(p, q, b) {
var i;
for (i = 0; i < 4; i++) {
sel25519(p[i], q[i], b);
}
}
function pack(r, p) {
var tx = gf(), ty = gf(), zi = gf();
inv25519(zi, p[2]);
M(tx, p[0], zi);
M(ty, p[1], zi);
pack25519(r, ty);
r[31] ^= par25519(tx) << 7;
}
function scalarmult(p, q, s) {
var b, i;
set25519(p[0], gf0);
set25519(p[1], gf1);
set25519(p[2], gf1);
set25519(p[3], gf0);
for (i = 255; i >= 0; --i) {
b = (s[(i/8)|0] >> (i&7)) & 1;
cswap(p, q, b);
add(q, p);
add(p, p);
cswap(p, q, b);
}
}
function scalarbase(p, s) {
var q = [gf(), gf(), gf(), gf()];
set25519(q[0], X);
set25519(q[1], Y);
set25519(q[2], gf1);
M(q[3], X, Y);
scalarmult(p, q, s);
}
//new functions for CN - scalar operations are handled externally
// this only handles curve operations, except for Hp()
//why do we negate points when unpacking them???
function ge_neg(pub) {
pub[31] ^= 0x80;
}
//res = s*G
function ge_scalarmult_base(s) {
var p = [gf(), gf(), gf(), gf()];
scalarbase(p, s);
var pk = new Uint8Array(32);
pack(pk, p);
return pk;
}
//res = s*P
function ge_scalarmult(P, s) {
var p = [gf(), gf(), gf(), gf()],
upk = [gf(), gf(), gf(), gf()],
res = new Uint8Array(32);
ge_neg(P);
if (unpackneg(upk, P) !== 0) throw "non-0 error on point decode";
scalarmult(p, upk, s);
pack(res, p);
return res;
}
//res = c*P + r*G
function ge_double_scalarmult_base_vartime(c, P, r) {
var uP = [gf(), gf(), gf(), gf()],
cP = [gf(), gf(), gf(), gf()],
rG = [gf(), gf(), gf(), gf()],
res = new Uint8Array(32);
ge_neg(P);
if (unpackneg(uP, P) !== 0) throw "non-0 error on point decode";
scalarmult(cP, uP, c);
scalarbase(rG, r);
add(rG, cP);
pack(res, rG);
return res;
}
//name changed to reflect not using precomp; res = r*Pb + c*I
function ge_double_scalarmult_postcomp_vartime(r, Pb, c, I) {
var uPb = [gf(), gf(), gf(), gf()],
uI = [gf(), gf(), gf(), gf()],
cI = [gf(), gf(), gf(), gf()],
rPb = [gf(), gf(), gf(), gf()],
res = new Uint8Array(32);
ge_neg(Pb);
if (unpackneg(uPb, Pb) !== 0) throw "non-0 error on point decode";
scalarmult(rPb, uPb, r);
ge_neg(I);
if (unpackneg(uI, I) !== 0) throw "non-0 error on point decode";
scalarmult(cI, uI, c);
add(rPb, cI);
pack(res, rPb);
return res;
}
//res = P + Q
function ge_add(P, Q) {
var uP = [gf(), gf(), gf(), gf()],
uQ = [gf(), gf(), gf(), gf()],
res = new Uint8Array(32);
ge_neg(P);
ge_neg(Q);
if (unpackneg(uP, P) !== 0) throw "non-0 error on point decode";
if (unpackneg(uQ, Q) !== 0) throw "non-0 error on point decode";
add(uP, uQ);
pack(res, uP);
return res;
}
var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]);
function modL(r, x) {
var carry, i, j, k;
for (i = 63; i >= 32; --i) {
carry = 0;
for (j = i - 32, k = i - 12; j < k; ++j) {
x[j] += carry - 16 * x[i] * L[j - (i - 32)];
carry = (x[j] + 128) >> 8;
x[j] -= carry * 256;
}
x[j] += carry;
x[i] = 0;
}
carry = 0;
for (j = 0; j < 32; j++) {
x[j] += carry - (x[31] >> 4) * L[j];
carry = x[j] >> 8;
x[j] &= 255;
}
for (j = 0; j < 32; j++) x[j] -= carry * L[j];
for (i = 0; i < 32; i++) {
x[i+1] += x[i] >> 8;
r[i] = x[i] & 255;
}
}
function reduce(r) {
var x = new Float64Array(64), i;
for (i = 0; i < 64; i++) x[i] = r[i];
for (i = 0; i < 64; i++) r[i] = 0;
modL(r, x);
}
function unpackneg(r, p) {
var t = gf(), chk = gf(), num = gf(),
den = gf(), den2 = gf(), den4 = gf(),
den6 = gf();
set25519(r[2], gf1);
unpack25519(r[1], p);
S(num, r[1]);
M(den, num, D);
Z(num, num, r[2]);
A(den, r[2], den);
S(den2, den);
S(den4, den2);
M(den6, den4, den2);
M(t, den6, num);
M(t, t, den);
pow2523(t, t);
M(t, t, num);
M(t, t, den);
M(t, t, den);
M(r[0], t, den);
S(chk, r[0]);
M(chk, chk, den);
if (neq25519(chk, num)) M(r[0], r[0], I);
S(chk, r[0]);
M(chk, chk, den);
if (neq25519(chk, num)) return -1;
if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]);
M(r[3], r[0], r[1]);
return 0;
}
nacl.ll = {
ge_scalarmult_base: ge_scalarmult_base,
ge_scalarmult: ge_scalarmult,
ge_double_scalarmult_base_vartime: ge_double_scalarmult_base_vartime,
ge_add: ge_add,
ge_double_scalarmult_postcomp_vartime: ge_double_scalarmult_postcomp_vartime
};
/* High-level API */
function cleanup(arr) {
for (var i = 0; i < arr.length; i++) arr[i] = 0;
}
nacl.randomBytes = function(n) {
var b = new Uint8Array(n);
randombytes(b, n);
return b;
};
nacl.setPRNG = function(fn) {
randombytes = fn;
};
(function() {
// Initialize PRNG if environment provides CSPRNG.
// If not, methods calling randombytes will throw.
var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null;
if (crypto && crypto.getRandomValues) {
// Browsers.
var QUOTA = 65536;
nacl.setPRNG(function(x, n) {
var i, v = new Uint8Array(n);
for (i = 0; i < n; i += QUOTA) {
crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
}
for (i = 0; i < n; i++) x[i] = v[i];
cleanup(v);
});
} else if (typeof require !== 'undefined') {
// Node.js.
crypto = require('crypto');
if (crypto && crypto.randomBytes) {
nacl.setPRNG(function(x, n) {
var i, v = crypto.randomBytes(n);
for (i = 0; i < n; i++) x[i] = v[i];
cleanup(v);
});
}
}
})();
})(typeof module !== 'undefined' && module.exports ? module.exports : (self.nacl = self.nacl || {}));

@ -1,46 +0,0 @@
// 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
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// 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";
//
// 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_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.request_funds_uri_utils = require("./monero_utils/request_funds_uri_utils");
mymonero_core_js.key_image_utils = require("./monero_utils/key_image_utils");
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");
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;

@ -8,6 +8,7 @@
"url": "git+https://github.com/mymonero/mymonero-core-js.git"
},
"scripts": {
"build": "tsc",
"format": "find . -name '*.js*' | xargs prettier --write --config ./.prettierrc --config-precedence file-override",
"test": "jest",
"test:coverage": "jest --coverage"
@ -32,21 +33,32 @@
},
"homepage": "https://github.com/mymonero/mymonero-core-js#readme",
"dependencies": {
"keccakjs": "^0.2.1"
"keccakjs": "^0.2.1",
"moment": "^2.22.2"
},
"devDependencies": {
"jest": "^23.1.0",
"ts-jest": "^23.0.1",
"ts-node": "^7.0.0",
"tsconfig-paths": "^3.4.2"
"tsconfig-paths": "^3.4.2",
"typescript": "^2.9.2"
},
"jest": {
"testEnvironment": "node",
"moduleFileExtensions": [
"js",
"jsx",
"json",
"ts",
"tsx"
],
"transform": {
"\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"modulePaths": ["<rootDir>/src" ],
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.ts$",
"coveragePathIgnorePatterns": [
"node_modules",
"cryptonote_utils/biginteger.js",
"cryptonote_utils/nacl-fast-cn.js",
"cryptonote_utils/sha3.js",
"cryptonote_utils/cryptonote_crypto_EMSCRIPTEN.js"
"/node_modules/",
"__test__"
]
}
}

@ -291,7 +291,7 @@ declare namespace BigInteger {
* @returns {BigInteger}
* @memberof BigInteger
*/
parse(s: string, base?: number): BigInteger;
static parse(s: string, base?: number): BigInteger;
/**
* @description Add two <BigIntegers>.

@ -0,0 +1,4 @@
import BigInteger = require("./biginteger");
export const BigInt = BigInteger.BigInteger;
export type BigInt = BigInteger.BigInteger;

File diff suppressed because it is too large Load Diff

@ -0,0 +1,141 @@
import { config } from "monero_utils/monero_config";
import { BigInt } from "biginteger";
import { ParsedTarget } from "monero_utils/sending_funds/internal_libs/types";
export function formatMoneyFull(units: BigInt | string) {
let strUnits = units.toString();
const symbol = strUnits[0] === "-" ? "-" : "";
if (symbol === "-") {
strUnits = strUnits.slice(1);
}
let decimal;
if (strUnits.length >= config.coinUnitPlaces) {
decimal = strUnits.substr(
strUnits.length - config.coinUnitPlaces,
config.coinUnitPlaces,
);
} else {
decimal = padLeft(strUnits, config.coinUnitPlaces, "0");
}
return (
symbol +
(strUnits.substr(0, strUnits.length - config.coinUnitPlaces) || "0") +
"." +
decimal
);
}
export function formatMoneyFullSymbol(units: BigInt | string) {
return formatMoneyFull(units) + " " + config.coinSymbol;
}
export function formatMoney(units: BigInt | string) {
const f = trimRight(formatMoneyFull(units), "0");
if (f[f.length - 1] === ".") {
return f.slice(0, f.length - 1);
}
return f;
}
export function formatMoneySymbol(units: BigInt | string) {
return formatMoney(units) + " " + config.coinSymbol;
}
/**
*
* @param {string} str
*/
export function parseMoney(str: string): BigInt {
if (!str) return BigInt.ZERO;
const negative = str[0] === "-";
if (negative) {
str = str.slice(1);
}
const decimalIndex = str.indexOf(".");
if (decimalIndex == -1) {
if (negative) {
return config.coinUnits.multiply(str).negate();
}
return config.coinUnits.multiply(str);
}
if (decimalIndex + config.coinUnitPlaces + 1 < str.length) {
str = str.substr(0, decimalIndex + config.coinUnitPlaces + 1);
}
if (negative) {
return new BigInt(str.substr(0, decimalIndex))
.exp10(config.coinUnitPlaces)
.add(
new BigInt(str.substr(decimalIndex + 1)).exp10(
decimalIndex + config.coinUnitPlaces - str.length + 1,
),
)
.negate();
}
return new BigInt(str.substr(0, decimalIndex))
.exp10(config.coinUnitPlaces)
.add(
new BigInt(str.substr(decimalIndex + 1)).exp10(
decimalIndex + config.coinUnitPlaces - str.length + 1,
),
);
}
export function printDsts(dsts: ParsedTarget[]) {
for (let i = 0; i < dsts.length; i++) {
console.log(dsts[i].address + ": " + formatMoneyFull(dsts[i].amount));
}
}
export function decompose_tx_destinations(dsts: ParsedTarget[], rct: boolean) {
const out = [];
if (rct) {
for (let i = 0; i < dsts.length; i++) {
out.push({
address: dsts[i].address,
amount: dsts[i].amount,
});
}
} else {
for (let i = 0; i < dsts.length; i++) {
const digits = decompose_amount_into_digits(dsts[i].amount);
for (let j = 0; j < digits.length; j++) {
if (digits[j].compare(0) > 0) {
out.push({
address: dsts[i].address,
amount: digits[j],
});
}
}
}
}
return out.sort((a, b) => a.amount.subtract(b.amount).toJSValue());
}
function trimRight(str: string, char: string) {
while (str[str.length - 1] == char) str = str.slice(0, -1);
return str;
}
export function padLeft(str: string, len: number, char: string) {
while (str.length < len) {
str = char + str;
}
return str;
}
function decompose_amount_into_digits(amount: BigInt) {
let amtStr = amount.toString();
const ret = [];
while (amtStr.length > 0) {
//check so we don't create 0s
if (amtStr[0] !== "0") {
let digit = amtStr[0];
while (digit.length < amtStr.length) {
digit += "0";
}
ret.push(new BigInt(digit));
}
amtStr = amtStr.slice(1);
}
return ret;
}

@ -0,0 +1,2 @@
export * from "./cryptonote_utils";
export * from "./nettype";

@ -27,7 +27,7 @@
// 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").BigInt;
var cnBase58 = (function() {
var b58 = {};
@ -47,7 +47,7 @@ var cnBase58 = (function() {
var UINT64_MAX = new JSBigInt(2).pow(64);
function hextobin(hex) {
if (hex.length % 2 !== 0) throw "Hex string has invalid length!";
if (hex.length % 2 !== 0) throw Error("Hex string has invalid length!");
var res = new Uint8Array(hex.length / 2);
for (var i = 0; i < hex.length / 2; ++i) {
res[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
@ -81,7 +81,7 @@ var cnBase58 = (function() {
function uint8_be_to_64(data) {
if (data.length < 1 || data.length > 8) {
throw "Invalid input length";
throw Error("Invalid input length");
}
var res = JSBigInt.ZERO;
var twopow8 = new JSBigInt(2).pow(8);
@ -105,7 +105,7 @@ var cnBase58 = (function() {
res = res.multiply(twopow8).add(data[i++]);
break;
default:
throw "Impossible condition";
throw Error("Impossible condition");
}
return res;
}
@ -113,7 +113,7 @@ var cnBase58 = (function() {
function uint64_to_8be(num, size) {
var res = new Uint8Array(size);
if (size < 1 || size > 8) {
throw "Invalid input length";
throw Error("Invalid input length");
}
var twopow8 = new JSBigInt(2).pow(8);
for (var i = size - 1; i >= 0; i--) {
@ -125,7 +125,7 @@ var cnBase58 = (function() {
b58.encode_block = function(data, buf, index) {
if (data.length < 1 || data.length > full_encoded_block_size) {
throw "Invalid block length: " + data.length;
throw Error("Invalid block length: " + data.length);
}
var num = uint8_be_to_64(data);
var i = encoded_block_sizes[data.length] - 1;
@ -183,24 +183,24 @@ var cnBase58 = (function() {
b58.decode_block = function(data, buf, index) {
if (data.length < 1 || data.length > full_encoded_block_size) {
throw "Invalid block length: " + data.length;
throw Error("Invalid block length: " + data.length);
}
var res_size = encoded_block_sizes.indexOf(data.length);
if (res_size <= 0) {
throw "Invalid block size";
throw Error("Invalid block size");
}
var res_num = new JSBigInt(0);
var order = new JSBigInt(1);
for (var i = data.length - 1; i >= 0; i--) {
var digit = alphabet.indexOf(data[i]);
if (digit < 0) {
throw "Invalid symbol";
throw Error("Invalid symbol");
}
var product = order.multiply(digit).add(res_num);
// if product > UINT64_MAX
if (product.compare(UINT64_MAX) === 1) {
throw "Overflow";
throw Error("Overflow");
}
res_num = product;
order = order.multiply(alphabet_size);
@ -209,7 +209,7 @@ var cnBase58 = (function() {
res_size < full_block_size &&
new JSBigInt(2).pow(8 * res_size).compare(res_num) <= 0
) {
throw "Overflow 2";
throw Error("Overflow 2");
}
buf.set(uint64_to_8be(res_num, res_size), index);
return buf;
@ -226,7 +226,7 @@ var cnBase58 = (function() {
last_block_size,
);
if (last_block_decoded_size < 0) {
throw "Invalid encoded length";
throw Error("Invalid encoded length");
}
var data_size =
full_block_count * full_block_size + last_block_decoded_size;

@ -1,7 +1,6 @@
declare namespace CNCrypto {
type Memory = string & { _tag_: "memory" };
function _malloc(bytes: number): Memory;
function _free(mem: Memory): mem is never;
function _malloc(bytes: number): number;
function _free(mem: number): mem is never;
var HEAPU8: Uint8Array;

File diff suppressed because it is too large Load Diff

@ -45,44 +45,34 @@ const __STAGENET_CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX = 25;
const __STAGENET_CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX = 36;
export function cryptonoteBase58PrefixForStandardAddressOn(nettype: NetType) {
if (!nettype) {
console.warn("Unexpected nil nettype");
}
if (nettype == NetType.MAINNET) {
if (nettype === NetType.MAINNET) {
return __MAINNET_CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX;
} else if (nettype == NetType.TESTNET) {
} else if (nettype === NetType.TESTNET) {
return __TESTNET_CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX;
} else if (nettype == NetType.STAGENET) {
} else if (nettype === NetType.STAGENET) {
return __STAGENET_CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX;
}
throw "Illegal nettype";
throw Error("Illegal nettype");
}
export function cryptonoteBase58PrefixForIntegratedAddressOn(nettype: NetType) {
if (!nettype) {
console.warn("Unexpected nil nettype");
}
if (nettype == NetType.MAINNET) {
if (nettype === NetType.MAINNET) {
return __MAINNET_CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX;
} else if (nettype == NetType.TESTNET) {
} else if (nettype === NetType.TESTNET) {
return __TESTNET_CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX;
} else if (nettype == NetType.STAGENET) {
} else if (nettype === NetType.STAGENET) {
return __STAGENET_CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX;
}
throw "Illegal nettype";
throw Error("Illegal nettype");
}
export function cryptonoteBase58PrefixForSubAddressOn(nettype: NetType) {
if (!nettype) {
console.warn("Unexpected nil nettype");
}
if (nettype == NetType.MAINNET) {
if (nettype === NetType.MAINNET) {
return __MAINNET_CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX;
} else if (nettype == NetType.TESTNET) {
} else if (nettype === NetType.TESTNET) {
return __TESTNET_CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX;
} else if (nettype == NetType.STAGENET) {
} else if (nettype === NetType.STAGENET) {
return __STAGENET_CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX;
}
throw "Illegal nettype";
throw Error("Illegal nettype");
}

@ -2,6 +2,8 @@ declare module "keccakjs" {
type Message = Buffer | string;
class Hasher {
constructor(bitlength: number);
/**
* Update hash
*
@ -12,7 +14,7 @@ declare module "keccakjs" {
/**
* Return hash in integer array.
*/
digest(): number[];
digest(encoding?: "hex" | "binary"): string;
}
export = Hasher;

@ -0,0 +1,2 @@
export * from "./net_service_utils";
export * from "./response_parser_utils";

@ -26,7 +26,7 @@
// 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.
import { JSBigInt } from "types";
import { BigInt } from "biginteger";
import {
genKeyImage,
KeyImageCache,
@ -88,16 +88,16 @@ export function parseAddressInfo(
);
if (!isKeyImageEqual(spent_output, key_image)) {
total_sent = new JSBigInt(total_sent)
total_sent = new BigInt(total_sent)
.subtract(spent_output.amount)
.toString();
}
}
return {
total_received: new JSBigInt(total_received),
locked_balance: new JSBigInt(locked_balance),
total_sent: new JSBigInt(total_sent),
total_received: new BigInt(total_received),
locked_balance: new BigInt(locked_balance),
total_sent: new BigInt(total_sent),
spent_outputs,
account_scanned_tx_height,
@ -123,7 +123,7 @@ export function parseAddressTransactions(
scanned_block_height: account_scanned_block_height,
scanned_height: account_scanned_height,
start_height: account_scan_start_height,
total_received,
/*total_received*/
transaction_height,
transactions,
} = normalizeAddressTransactions(data);
@ -145,7 +145,7 @@ export function parseAddressTransactions(
);
if (!isKeyImageEqual(transaction.spent_outputs[j], keyImage)) {
transaction.total_sent = new JSBigInt(
transaction.total_sent = new BigInt(
transaction.total_sent,
).subtract(transaction.spent_outputs[j].amount);
@ -267,6 +267,6 @@ export function parseUnspentOuts(
return {
unspentOuts,
unusedOuts: [...unspentOuts],
per_kb_fee: new JSBigInt(per_kb_fee),
per_kb_fee: new BigInt(per_kb_fee),
};
}

@ -1,4 +1,5 @@
import { JSBigInt, Omit } from "types";
import { Omit } from "types";
import { BigInt } from "biginteger";
export interface SpentOutput {
amount: string;
@ -35,8 +36,8 @@ export interface AddressTransactions {
export interface NormalizedTransaction
extends Required<Omit<AddressTransactionsTx, "total_sent" | "timestamp">> {
total_sent: JSBigInt;
amount: JSBigInt;
total_sent: BigInt;
amount: BigInt;
approx_float_amount: number;
timestamp: Date;
}

@ -1,4 +1,3 @@
import monero_utils from "monero_utils/monero_cryptonote_utils_instance";
import {
AddressTransactions,
AddressTransactionsTx,
@ -7,7 +6,9 @@ import {
AddressInfo,
UnspentOutput,
} from "./types";
import { JSBigInt, Omit } from "types";
import { Omit } from "types";
import { BigInt } from "biginteger";
import { formatMoney } from "cryptonote_utils/formatters";
export function isKeyImageEqual({ key_image }: SpentOutput, keyImage: string) {
return key_image === keyImage;
@ -56,7 +57,7 @@ export function normalizeTransaction(
tx: AddressTransactionsTx,
): NormalizedTransaction {
const defaultObj: Omit<NormalizedTransaction, "timestamp"> = {
amount: new JSBigInt(0),
amount: new BigInt(0),
approx_float_amount: 0,
hash: "",
height: 0,
@ -66,7 +67,7 @@ export function normalizeTransaction(
mixin: 0,
spent_outputs: [] as SpentOutput[],
total_received: "0",
total_sent: new JSBigInt(0),
total_sent: new BigInt(0),
unlock_time: 0,
payment_id: "",
};
@ -75,7 +76,7 @@ export function normalizeTransaction(
...defaultObj,
...tx,
total_sent: tx.total_sent
? new JSBigInt(tx.total_sent)
? new BigInt(tx.total_sent)
: defaultObj.total_sent,
timestamp: new Date(tx.timestamp),
};
@ -92,18 +93,18 @@ export function zeroTransactionAmount({
total_received,
total_sent,
}: NormalizedTransaction) {
return new JSBigInt(total_received).add(total_sent).compare(0) <= 0;
return new BigInt(total_received).add(total_sent).compare(0) <= 0;
}
export function calculateTransactionAmount({
total_received,
total_sent,
}: NormalizedTransaction) {
return new JSBigInt(total_received).subtract(total_sent);
return new BigInt(total_received).subtract(total_sent);
}
export function estimateTransactionAmount({ amount }: NormalizedTransaction) {
return parseFloat(monero_utils.formatMoney(amount));
return parseFloat(formatMoney(amount));
}
/**

@ -25,11 +25,8 @@
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// 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_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;
export * from "./biginteger";
export * from "./cryptonote_utils";
export * from "./hostAPI";
export * from "./monero_utils";

@ -0,0 +1,6 @@
export * from "./sending_funds";
export * from "./key_image_utils";
export * from "./monero_config";
export * from "./monero_paymentID_utils";
export * from "./monero_txParsing_utils";
export * from "./request_funds_uri_utils";

@ -1,3 +1,5 @@
import { generate_key_image } from "cryptonote_utils";
// Copyright (c) 2014-2018, MyMonero.com
//
// All rights reserved.
@ -26,8 +28,6 @@
// 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.
const monero_utils = require("./monero_cryptonote_utils_instance");
// Managed caches - Can be used by apps which can't send a mutable_keyImagesByCacheKey
export type KeyImageCache = { [cacheIndex: string]: string };
@ -62,7 +62,7 @@ export function genKeyImage(
return cachedKeyImage;
}
const { key_image } = monero_utils.generate_key_image(
const { key_image } = generate_key_image(
txPubKey,
privViewKey,
pubSpendKey,
@ -110,7 +110,7 @@ export function clearKeyImageCache(address: string) {
const cache = keyImagesByWalletId[cacheId];
if (cache) {
throw "Key image cache still exists after deletion";
throw Error("Key image cache still exists after deletion");
}
}
@ -122,7 +122,7 @@ function parseAddress(address: string) {
// 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 (!address) {
throw "Address does not exist";
throw Error("Address does not exist");
}
return address.toString();

@ -1,4 +1,4 @@
import { JSBigInt } from "types";
import { BigInt } from "biginteger";
// Copyright (c) 2014-2018, MyMonero.com
//
@ -30,6 +30,7 @@ import { JSBigInt } from "types";
export interface XMRConfig {
readonly coinUnitPlaces: 12;
readonly coinUnits: BigInt;
readonly txMinConfirms: 10;
readonly coinSymbol: "XMR";
readonly openAliasPrefix: "xmr";
@ -38,14 +39,18 @@ export interface XMRConfig {
readonly addressPrefix: 18;
readonly integratedAddressPrefix: 19;
readonly subaddressPrefix: 42;
readonly dustThreshold: JSBigInt;
readonly dustThreshold: BigInt;
readonly maxBlockNumber: 500000000;
readonly avgBlockTime: 60;
}
const coinUnitPlaces = 12;
export const config: XMRConfig = {
// Number of atomic units in one unit of currency. e.g. 12 => 10^12 = 1000000000000
coinUnitPlaces: 12,
coinUnitPlaces,
coinUnits: new BigInt(10).pow(coinUnitPlaces),
// Minimum number of confirmations for a transaction to show as confirmed
txMinConfirms: 10,
@ -69,7 +74,7 @@ export const config: XMRConfig = {
// 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 BigInt("2000000000"),
// Maximum block number, used for tx unlock time
maxBlockNumber: 500000000,

@ -1,3 +1,5 @@
import { rand_8 } from "cryptonote_utils";
// Copyright (c) 2014-2018, MyMonero.com
//
// All rights reserved.
@ -26,13 +28,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.
import monero_utils from "./monero_cryptonote_utils_instance";
export function makePaymentID() {
return monero_utils.rand_8();
return rand_8();
}
export function isValidOrNoPaymentID(pid?: string) {
export function isValidOrNoPaymentID(pid?: string | null) {
if (!pid) {
return true;
}

@ -1,4 +1,5 @@
import { NormalizedTransaction } from "hostAPI/response_parser_utils/types";
import moment from "moment";
// Copyright (c) 2014-2018, MyMonero.com
//
@ -29,7 +30,6 @@ import { NormalizedTransaction } from "hostAPI/response_parser_utils/types";
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import { config } from "./monero_config";
import monero_utils from "./monero_cryptonote_utils_instance";
export function IsTransactionConfirmed(
tx: NormalizedTransaction,
@ -39,15 +39,58 @@ export function IsTransactionConfirmed(
}
export function IsTransactionUnlocked(
tx: NormalizedTransaction,
{ unlock_time }: NormalizedTransaction,
blockchainHeight: number,
) {
return monero_utils.is_tx_unlocked(tx.unlock_time, blockchainHeight);
if (!config.maxBlockNumber) {
throw Error("Max block number is not set in config!");
}
if (unlock_time < config.maxBlockNumber) {
// unlock time is block height
return blockchainHeight >= unlock_time;
} else {
// unlock time is timestamp
const current_time = Math.round(new Date().getTime() / 1000);
return current_time >= unlock_time;
}
}
export function TransactionLockedReason(
tx: NormalizedTransaction,
{ unlock_time }: NormalizedTransaction,
blockchainHeight: number,
) {
return monero_utils.tx_locked_reason(tx.unlock_time, blockchainHeight);
if (unlock_time < config.maxBlockNumber) {
// unlock time is block height
const numBlocks = unlock_time - blockchainHeight;
if (numBlocks <= 0) {
return "Transaction is unlocked";
}
const unlock_prediction = moment().add(
numBlocks * config.avgBlockTime,
"seconds",
);
return (
"Will be unlocked in " +
numBlocks +
" blocks, ~" +
unlock_prediction.fromNow(true) +
", " +
unlock_prediction.calendar() +
""
);
} else {
// unlock time is timestamp
const current_time = Math.round(new Date().getTime() / 1000);
const time_difference = unlock_time - current_time;
if (time_difference <= 0) {
return "Transaction is unlocked";
}
const unlock_moment = moment(unlock_time * 1000);
return (
"Will be unlocked " +
unlock_moment.fromNow() +
", " +
unlock_moment.calendar()
);
}
}

@ -27,10 +27,10 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import { config } from "./monero_config";
import monero_utils from "./monero_cryptonote_utils_instance";
import { NetType } from "cryptonote_utils/nettype";
import { possibleOAAddress } from "./sending_funds/internal_libs/open_alias_lite";
import { Omit } from "types";
import { decode_address } from "cryptonote_utils";
export enum URITypes {
addressAsFirstPathComponent = 1,
@ -53,7 +53,7 @@ type FundRequestPayload = {
export function encodeFundRequest(args: FundRequestPayload) {
const address = args.address;
if (!address) {
throw "missing address";
throw Error("missing address");
}
let mutable_uri = config.coinUriPrefix;
@ -64,7 +64,7 @@ export function encodeFundRequest(args: FundRequestPayload) {
} else if (uriType === URITypes.addressAsFirstPathComponent) {
// nothing to do
} else {
throw "Illegal args.uriType";
throw Error("Illegal args.uriType");
}
mutable_uri += address;
@ -116,7 +116,7 @@ export function decodeFundRequest(
if (!str.startsWith(config.coinUriPrefix)) {
if (str.includes("?")) {
// fairly sure this is correct.. (just an extra failsafe/filter)
throw "Unrecognized URI format";
throw Error("Unrecognized URI format");
}
if (possibleOAAddress(str)) {
@ -126,9 +126,9 @@ export function decodeFundRequest(
}
try {
monero_utils.decode_address(str, nettype);
decode_address(str, nettype);
} catch (e) {
throw "No Monero request info";
throw Error("No Monero request info");
}
// then it looks like a monero address
@ -141,7 +141,7 @@ export function decodeFundRequest(
const protocol = url.protocol;
if (protocol !== config.coinUriPrefix) {
throw "Request URI has non-Monero protocol";
throw Error("Request URI has non-Monero protocol");
}
// it seems that if the URL has // in it, pathname will be empty, but host will contain the address instead

@ -1,4 +1,4 @@
import { JSBigInt } from "types";
import { BigInt } from "biginteger";
/**
* @description Gets a starting total amount.
@ -11,19 +11,19 @@ import { JSBigInt } from "types";
*
* @export
* @param {boolean} isSweeping
* @param {JSBigInt} feelessTotal
* @param {JSBigInt} networkFee
* @param {BigInt} feelessTotal
* @param {BigInt} networkFee
* @returns
*/
export function getBaseTotalAmount(
isSweeping: boolean,
feelessTotal: JSBigInt,
networkFee: JSBigInt,
feelessTotal: BigInt,
networkFee: BigInt,
) {
// const hostingService_chargeAmount = hostedMoneroAPIClient.HostingServiceChargeFor_transactionWithNetworkFee(attemptAt_network_minimumFee)
if (isSweeping) {
return new JSBigInt("18450000000000000000"); //~uint64 max
return new BigInt("18450000000000000000"); //~uint64 max
} else {
return feelessTotal.add(
networkFee,

@ -1,7 +1,7 @@
import { ViewSendKeys, Output, AmountOutput } from "./types";
import { Log } from "./logger";
import { ERR } from "./errors";
import { JSBigInt } from "types";
import { BigInt } from "biginteger";
export class WrappedNodeApi {
private api: any;
@ -18,7 +18,7 @@ export class WrappedNodeApi {
) {
type ResolveVal = {
unusedOuts: Output[];
dynamicFeePerKB: JSBigInt;
dynamicFeePerKB: BigInt;
};
return new Promise<ResolveVal>((resolve, reject) => {
@ -28,7 +28,7 @@ export class WrappedNodeApi {
err: Error,
_: Output[], // unspent outs, the original copy of unusedOuts
unusedOuts: Output[],
dynamicFeePerKB: JSBigInt,
dynamicFeePerKB: BigInt,
) => {
if (err) {
return reject(err);

@ -2,13 +2,13 @@ import { WrappedNodeApi } from "../async_node_api";
import { NetType } from "cryptonote_utils/nettype";
import {
ViewSendKeys,
JSBigInt,
ParsedTarget,
Pid,
Output,
AmountOutput,
} from "../types";
import { Status } from "../../status_update_constants";
import { BigInt } from "biginteger";
export type GetFundTargetsAndFeeParams = {
senderAddress: string;
@ -22,9 +22,9 @@ export type GetFundTargetsAndFeeParams = {
unusedOuts: Output[];
simplePriority: number;
feelessTotal: JSBigInt;
feePerKB: JSBigInt; // obtained from server, so passed in
networkFee: JSBigInt;
feelessTotal: BigInt;
feePerKB: BigInt; // obtained from server, so passed in
networkFee: BigInt;
isSweeping: boolean;
isRingCT: boolean;
@ -52,9 +52,9 @@ export type CreateTxAndAttemptToSendParams = {
usingOuts: Output[];
simplePriority: number;
feelessTotal: JSBigInt;
feePerKB: JSBigInt; // obtained from server, so passed in
networkFee: JSBigInt;
feelessTotal: BigInt;
feePerKB: BigInt; // obtained from server, so passed in
networkFee: BigInt;
isSweeping: boolean;
isRingCT: boolean;

@ -1,6 +1,6 @@
import { JSBigInt } from "types";
import { config } from "monero_utils/monero_config";
import monero_utils from "monero_utils/monero_cryptonote_utils_instance";
import { BigInt } from "biginteger";
import { formatMoney } from "cryptonote_utils/formatters";
export namespace ERR {
export namespace RING {
@ -29,10 +29,10 @@ export namespace ERR {
}
export namespace BAL {
export function insuff(amtAvail: JSBigInt, requiredAmt: JSBigInt) {
export function insuff(amtAvail: BigInt, requiredAmt: BigInt) {
const { coinSymbol } = config;
const amtAvailStr = monero_utils.formatMoney(amtAvail);
const requiredAmtStr = monero_utils.formatMoney(requiredAmt);
const amtAvailStr = formatMoney(amtAvail);
const requiredAmtStr = formatMoney(requiredAmt);
const errStr = `Your spendable balance is too low. Have ${amtAvailStr} ${coinSymbol} spendable, need ${requiredAmtStr} ${coinSymbol}.`;
return Error(errStr);
}

@ -1,23 +1,23 @@
import { JSBigInt } from "types";
import { BigInt } from "biginteger";
export const DEFAULT_FEE_PRIORITY = 1;
export function calculateFee(
feePerKB: JSBigInt,
feePerKB: BigInt,
numOfBytes: number,
feeMultiplier: number,
) {
const numberOf_kB = new JSBigInt((numOfBytes + 1023.0) / 1024.0); // i.e. ceil
const numberOf_kB = new BigInt((numOfBytes + 1023.0) / 1024.0); // i.e. ceil
return calculateFeeKb(feePerKB, numberOf_kB, feeMultiplier);
}
export function calculateFeeKb(
feePerKB: JSBigInt,
numOfBytes: JSBigInt | number,
feePerKB: BigInt,
numOfBytes: BigInt | number,
feeMultiplier: number,
) {
const numberOf_kB = new JSBigInt(numOfBytes);
const numberOf_kB = new BigInt(numOfBytes);
const fee = feePerKB.multiply(feeMultiplier).multiply(numberOf_kB);
return fee;
@ -29,7 +29,9 @@ export function multiplyFeePriority(prio: number) {
const priority = prio || DEFAULT_FEE_PRIORITY;
if (priority <= 0 || priority > fee_multiplier.length) {
throw "fee_multiplier_for_priority: simple_priority out of bounds";
throw Error(
"fee_multiplier_for_priority: simple_priority out of bounds",
);
}
const priority_idx = priority - 1;
return fee_multiplier[priority_idx];

@ -1,6 +1,6 @@
import { NetType } from "cryptonote_utils/nettype";
import monero_utils from "monero_utils/monero_cryptonote_utils_instance";
import { Log } from "./logger";
import { decode_address } from "cryptonote_utils";
export function getTargetPubViewKey(
encPid: boolean,
@ -8,7 +8,7 @@ export function getTargetPubViewKey(
nettype: NetType,
): string | undefined {
if (encPid) {
const key = monero_utils.decode_address(targetAddress, nettype).view;
const key = decode_address(targetAddress, nettype).view;
Log.Target.viewKey(key);
return key;

@ -1,28 +1,35 @@
import monero_utils from "monero_utils/monero_cryptonote_utils_instance";
import { ParsedTarget, Output } from "./types";
import { JSBigInt } from "types";
import { BigInt } from "biginteger";
import {
formatMoneySymbol,
formatMoneyFullSymbol,
formatMoney,
formatMoneyFull,
printDsts,
} from "cryptonote_utils/formatters";
import { SignedTransaction } from "cryptonote_utils";
export namespace Log {
export namespace Amount {
export function beforeFee(feelessTotal: JSBigInt, isSweeping: boolean) {
export function beforeFee(feelessTotal: BigInt, isSweeping: boolean) {
const feeless_total = isSweeping
? "all"
: monero_utils.formatMoney(feelessTotal);
: formatMoney(feelessTotal);
console.log(`💬 Total to send, before fee: ${feeless_total}`);
}
export function change(changeAmount: JSBigInt) {
export function change(changeAmount: BigInt) {
console.log("changeAmount", changeAmount);
}
export function changeAmountDivRem(amt: [JSBigInt, JSBigInt]) {
export function changeAmountDivRem(amt: [BigInt, BigInt]) {
console.log("💬 changeAmountDivRem", amt);
}
export function toSelf(changeAmount: JSBigInt, selfAddress: string) {
export function toSelf(changeAmount: BigInt, selfAddress: string) {
console.log(
"Sending change of " +
monero_utils.formatMoneySymbol(changeAmount) +
formatMoneySymbol(changeAmount) +
" to " +
selfAddress,
);
@ -30,41 +37,41 @@ export namespace Log {
}
export namespace Fee {
export function dynPerKB(dynFeePerKB: JSBigInt) {
export function dynPerKB(dynFeePerKB: BigInt) {
console.log(
"Received dynamic per kb fee",
monero_utils.formatMoneySymbol(dynFeePerKB),
formatMoneySymbol(dynFeePerKB),
);
}
export function basedOnInputs(
newNeededFee: JSBigInt,
newNeededFee: BigInt,
usingOuts: Output[],
) {
console.log(
"New fee: " +
monero_utils.formatMoneySymbol(newNeededFee) +
formatMoneySymbol(newNeededFee) +
" for " +
usingOuts.length +
" inputs",
);
}
export function belowDustThreshold(changeDivDustRemainder: JSBigInt) {
export function belowDustThreshold(changeDivDustRemainder: BigInt) {
console.log(
"💬 Miners will add change of " +
monero_utils.formatMoneyFullSymbol(changeDivDustRemainder) +
formatMoneyFullSymbol(changeDivDustRemainder) +
" to transaction fee (below dust threshold)",
);
}
export function estLowerThanReal(
estMinNetworkFee: JSBigInt,
feeActuallyNeededByNetwork: JSBigInt,
estMinNetworkFee: BigInt,
feeActuallyNeededByNetwork: BigInt,
) {
console.log(
"💬 Need to reconstruct the tx with enough of a network fee. Previous fee: " +
monero_utils.formatMoneyFull(estMinNetworkFee) +
formatMoneyFull(estMinNetworkFee) +
" New fee: " +
monero_utils.formatMoneyFull(feeActuallyNeededByNetwork),
formatMoneyFull(feeActuallyNeededByNetwork),
);
console.log("Reconstructing tx....");
}
@ -72,45 +79,40 @@ export namespace Log {
export function txKB(
txBlobBytes: number,
numOfKB: number,
estMinNetworkFee: JSBigInt,
estMinNetworkFee: BigInt,
) {
console.log(
txBlobBytes +
" bytes <= " +
numOfKB +
" KB (current fee: " +
monero_utils.formatMoneyFull(estMinNetworkFee) +
formatMoneyFull(estMinNetworkFee) +
")",
);
}
export function successfulTx(finalNetworkFee: JSBigInt) {
export function successfulTx(finalNetworkFee: BigInt) {
console.log(
"💬 Successful tx generation, submitting tx. Going with final_networkFee of ",
monero_utils.formatMoney(finalNetworkFee),
formatMoney(finalNetworkFee),
);
}
}
export namespace Balance {
export function requiredBase(
totalAmount: JSBigInt,
isSweeping: boolean,
) {
export function requiredBase(totalAmount: BigInt, isSweeping: boolean) {
if (isSweeping) {
console.log("Balance required: all");
} else {
console.log(
"Balance required: " +
monero_utils.formatMoneySymbol(totalAmount),
"Balance required: " + formatMoneySymbol(totalAmount),
);
}
}
export function requiredPostRct(totalAmount: JSBigInt) {
export function requiredPostRct(totalAmount: BigInt) {
console.log(
"~ Balance required: " +
monero_utils.formatMoneySymbol(totalAmount),
"~ Balance required: " + formatMoneySymbol(totalAmount),
);
}
}
@ -126,7 +128,7 @@ export namespace Log {
export function display(out: Output) {
console.log(
"Using output: " +
monero_utils.formatMoney(out.amount) +
formatMoney(out.amount) +
" - " +
JSON.stringify(out),
);
@ -140,12 +142,12 @@ export namespace Log {
export function fullDisplay(fundTargets: ParsedTarget[]) {
console.log("Destinations: ");
monero_utils.printDsts(fundTargets);
printDsts(fundTargets);
}
export function displayDecomposed(splitDestinations: ParsedTarget[]) {
console.log("Decomposed destinations:");
monero_utils.printDsts(splitDestinations);
printDsts(splitDestinations);
}
export function viewKey(viewKey: string) {
@ -154,7 +156,7 @@ export namespace Log {
}
export namespace Transaction {
export function signed(signedTx) {
export function signed(signedTx: SignedTransaction) {
console.log("signed tx: ", JSON.stringify(signedTx));
}
export function serializedAndHash(
@ -167,10 +169,10 @@ export namespace Log {
}
export namespace SelectOutsAndAmtForMix {
export function target(targetAmount: JSBigInt) {
export function target(targetAmount: BigInt) {
console.log(
"Selecting outputs to use. target: " +
monero_utils.formatMoney(targetAmount),
formatMoney(targetAmount),
);
}
@ -192,11 +194,11 @@ export namespace Log {
}
}
export function usingOut(outAmount: JSBigInt, out: Output) {
export function usingOut(outAmount: BigInt, out: Output) {
console.log(
`Using output: ${monero_utils.formatMoney(
outAmount,
)} - ${JSON.stringify(out)}`,
`Using output: ${formatMoney(outAmount)} - ${JSON.stringify(
out,
)}`,
);
}
}

@ -2,17 +2,17 @@ import { Output } from "./types";
import { popRandElement } from "./arr_utils";
import { Log } from "./logger";
import { config } from "monero_utils/monero_config";
import { JSBigInt } from "types";
import { BigInt } from "biginteger";
export function selectOutputsAndAmountForMixin(
targetAmount: JSBigInt,
targetAmount: BigInt,
unusedOuts: Output[],
isRingCT: boolean,
sweeping: boolean,
) {
Log.SelectOutsAndAmtForMix.target(targetAmount);
let usingOutsAmount = new JSBigInt(0);
let usingOutsAmount = new BigInt(0);
const usingOuts: Output[] = [];
const remainingUnusedOuts = unusedOuts.slice(); // take copy so as to prevent issue if we must re-enter tx building fn if fee too low after building
while (
@ -24,7 +24,7 @@ export function selectOutputsAndAmountForMixin(
// out.rct is set by the server
continue; // skip rct outputs if not creating rct tx
}
const outAmount = new JSBigInt(out.amount);
const outAmount = new BigInt(out.amount);
if (outAmount.compare(config.dustThreshold) < 0) {
// amount is dusty..
if (!sweeping) {

@ -1,9 +1,9 @@
import { ParsedTarget, RawTarget } from "./types";
import { NetType } from "cryptonote_utils/nettype";
import { ERR } from "./errors";
import monero_utils from "monero_utils/monero_cryptonote_utils_instance";
import { possibleOAAddress } from "./open_alias_lite";
import { JSBigInt } from "types";
import { decode_address } from "cryptonote_utils";
import { parseMoney } from "cryptonote_utils/formatters";
/**
* @description Map through the provided targets and normalize each address/amount pair
@ -35,13 +35,13 @@ export function parseTargets(
const amountStr = amount.toString();
try {
monero_utils.decode_address(address, nettype);
decode_address(address, nettype);
} catch (e) {
throw ERR.PARSE_TRGT.decodeAddress(address, e);
}
try {
const parsedAmount: JSBigInt = monero_utils.parseMoney(amountStr);
const parsedAmount = parseMoney(amountStr);
return { address, amount: parsedAmount };
} catch (e) {
throw ERR.PARSE_TRGT.amount(amountStr, e);

@ -1,7 +1,7 @@
import monero_utils from "monero_utils/monero_cryptonote_utils_instance";
import monero_paymentID_utils from "monero_utils/monero_paymentID_utils";
import { isValidOrNoPaymentID } from "monero_utils/monero_paymentID_utils";
import { NetType } from "cryptonote_utils/nettype";
import { ERR } from "./errors";
import { decode_address, is_subaddress } from "cryptonote_utils";
/**
*
@ -35,13 +35,13 @@ export function checkAddressAndPidValidity(
let retPid = pid;
let encryptPid = false;
const decodedAddress = monero_utils.decode_address(address, nettype);
const decodedAddress = decode_address(address, nettype);
// assert that the target address is not of type integrated nor subaddress
// if a payment id is included
if (retPid) {
if (decodedAddress.intPaymentId) {
throw ERR.PID.NO_INTEG_ADDR;
} else if (monero_utils.is_subaddress(address, nettype)) {
} else if (is_subaddress(address, nettype)) {
throw ERR.PID.NO_SUB_ADDR;
}
}
@ -52,7 +52,7 @@ export function checkAddressAndPidValidity(
if (decodedAddress.intPaymentId) {
retPid = decodedAddress.intPaymentId;
encryptPid = true;
} else if (!monero_paymentID_utils.IsValidPaymentIDOrNoPaymentID(retPid)) {
} else if (!isValidOrNoPaymentID(retPid)) {
throw ERR.PID.INVAL;
}

@ -1,4 +1,3 @@
import monero_utils from "monero_utils/monero_cryptonote_utils_instance";
import { config } from "monero_utils/monero_config";
import { getTargetPubViewKey } from "../key_utils";
import {
@ -12,7 +11,18 @@ import { Log } from "../logger";
import { popRandElement } from "../arr_utils";
import { calculateFee, multiplyFeePriority } from "../fee_utils";
import { ParsedTarget } from "../types";
import { JSBigInt } from "types";
import { BigInt } from "biginteger";
import {
estimateRctSize,
random_scalar,
create_address,
create_transaction,
serialize_tx,
cn_fast_hash,
serialize_rct_tx_with_hash,
SignedTransaction,
} from "cryptonote_utils";
import { decompose_tx_destinations } from "cryptonote_utils/formatters";
// #region totalAmtAndEstFee
@ -65,7 +75,7 @@ function estRctFeeAndAmt(params: EstRctFeeAndAmtParams) {
let feeBasedOnOuts = calculateFee(
feePerKB,
monero_utils.estimateRctSize(usingOuts.length, mixin, 2),
estimateRctSize(usingOuts.length, mixin, 2),
multiplyFeePriority(simplePriority),
);
@ -82,7 +92,7 @@ function estRctFeeAndAmt(params: EstRctFeeAndAmtParams) {
return { totalAmount, newFee };
}
function estRctSwpingAmt(usingOutsAmount: JSBigInt, fee: JSBigInt) {
function estRctSwpingAmt(usingOutsAmount: BigInt, fee: BigInt) {
/*
// When/if sending to multiple destinations supported, uncomment and port this:
if (dsts.length !== 1) {
@ -107,7 +117,7 @@ function estRctSwpingAmt(usingOutsAmount: JSBigInt, fee: JSBigInt) {
return [totalAmount, fee];
}
function estRctNonSwpAmt(params: EstRctFeeAndAmtParams, fee: JSBigInt) {
function estRctNonSwpAmt(params: EstRctFeeAndAmtParams, fee: BigInt) {
const {
mixin,
remainingUnusedOuts,
@ -141,7 +151,7 @@ function estRctNonSwpAmt(params: EstRctFeeAndAmtParams, fee: JSBigInt) {
// and recalculate invalidated values
newFee = calculateFee(
feePerKB,
monero_utils.estimateRctSize(usingOuts.length, mixin, 2),
estimateRctSize(usingOuts.length, mixin, 2),
multiplyFeePriority(simplePriority),
);
currTotalAmount = feelessTotal.add(newFee);
@ -267,16 +277,14 @@ export function validateAndConstructFundTargets(
if (isRingCT) {
// then create random destination to keep 2 outputs always in case of 0 change
// so we dont create 1 output (outlier)
const fakeAddress = monero_utils.create_address(
monero_utils.random_scalar(),
nettype,
).public_addr;
const fakeAddress = create_address(random_scalar(), nettype)
.public_addr;
Log.Output.uniformity(fakeAddress);
fundTargets.push({
address: fakeAddress,
amount: JSBigInt.ZERO,
amount: BigInt.ZERO,
});
}
}
@ -327,13 +335,13 @@ function makeSignedTx(params: ConstructTxParams) {
nettype,
);
const splitDestinations: ParsedTarget[] = monero_utils.decompose_tx_destinations(
const splitDestinations: ParsedTarget[] = decompose_tx_destinations(
fundTargets,
isRingCT,
);
Log.Target.displayDecomposed(splitDestinations);
const signedTx = monero_utils.create_transaction(
const signedTx = create_transaction(
senderPublicKeys,
senderPrivateKeys,
splitDestinations,
@ -357,7 +365,7 @@ function makeSignedTx(params: ConstructTxParams) {
}
}
function getSerializedTxAndHash(signedTx) {
function getSerializedTxAndHash(signedTx: SignedTransaction) {
type ReturnVal = {
serializedSignedTx: string;
txHash: string;
@ -365,8 +373,8 @@ function getSerializedTxAndHash(signedTx) {
// pre rct
if (signedTx.version === 1) {
const serializedSignedTx = monero_utils.serialize_tx(signedTx);
const txHash = monero_utils.cn_fast_hash(serializedSignedTx);
const serializedSignedTx = serialize_tx(signedTx);
const txHash = cn_fast_hash(serializedSignedTx);
const ret: ReturnVal = {
serializedSignedTx,
@ -379,7 +387,7 @@ function getSerializedTxAndHash(signedTx) {
}
// rct
else {
const { raw, hash } = monero_utils.serialize_rct_tx_with_hash(signedTx);
const { raw, hash } = serialize_rct_tx_with_hash(signedTx);
const ret: ReturnVal = {
serializedSignedTx: raw,
@ -392,7 +400,7 @@ function getSerializedTxAndHash(signedTx) {
}
}
function getTxSize(serializedSignedTx: string, estMinNetworkFee: JSBigInt) {
function getTxSize(serializedSignedTx: string, estMinNetworkFee: BigInt) {
// work out per-kb fee for transaction and verify that it's enough
const txBlobBytes = serializedSignedTx.length / 2;
let numOfKB = Math.floor(txBlobBytes / 1024);

@ -6,7 +6,7 @@ import {
Output,
AmountOutput,
} from "../types";
import { JSBigInt } from "types";
import { BigInt } from "biginteger";
export type ConstructTxParams = {
senderPublicKeys: ViewSendKeys;
@ -22,7 +22,7 @@ export type ConstructTxParams = {
mixin: number;
usingOuts: Output[];
networkFee: JSBigInt;
networkFee: BigInt;
isRingCT: boolean;
@ -30,17 +30,17 @@ export type ConstructTxParams = {
};
export type TotalAmtAndEstFeeParams = {
usingOutsAmount: JSBigInt;
baseTotalAmount: JSBigInt;
usingOutsAmount: BigInt;
baseTotalAmount: BigInt;
mixin: number;
remainingUnusedOuts: Output[];
usingOuts: Output[];
simplePriority: number;
feelessTotal: JSBigInt;
feePerKB: JSBigInt; // obtained from server, so passed in
networkFee: JSBigInt;
feelessTotal: BigInt;
feePerKB: BigInt; // obtained from server, so passed in
networkFee: BigInt;
isSweeping: boolean;
isRingCT: boolean;
@ -48,14 +48,14 @@ export type TotalAmtAndEstFeeParams = {
export type EstRctFeeAndAmtParams = {
mixin: number;
usingOutsAmount: JSBigInt;
usingOutsAmount: BigInt;
remainingUnusedOuts: Output[];
usingOuts: Output[];
simplePriority: number;
feelessTotal: JSBigInt;
feePerKB: JSBigInt; // obtained from server, so passed in
networkFee: JSBigInt;
feelessTotal: BigInt;
feePerKB: BigInt; // obtained from server, so passed in
networkFee: BigInt;
isSweeping: boolean;
};
@ -64,9 +64,9 @@ export type ConstructFundTargetsParams = {
senderAddress: string;
targetAddress: string;
feelessTotal: JSBigInt;
totalAmount: JSBigInt;
usingOutsAmount: JSBigInt;
feelessTotal: BigInt;
totalAmount: BigInt;
usingOutsAmount: BigInt;
isSweeping: boolean;
isRingCT: boolean;

@ -1,4 +1,4 @@
import { JSBigInt } from "types";
import { BigInt } from "biginteger";
export type ViewSendKeys = {
view: string;
@ -11,7 +11,7 @@ export type RawTarget = {
export type ParsedTarget = {
address: string;
amount: JSBigInt;
amount: BigInt;
};
export type Pid = string | null;

@ -27,7 +27,6 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
import monero_utils from "monero_utils/monero_cryptonote_utils_instance";
import { NetType } from "cryptonote_utils/nettype";
import { RawTarget, Pid, ViewSendKeys } from "./internal_libs/types";
import {
@ -46,11 +45,13 @@ import {
getRestOfTxData,
createTxAndAttemptToSend,
} from "./internal_libs/construct_tx_and_send";
import { JSBigInt } from "types";
import { BigInt } from "biginteger";
import { estimateRctSize } from "cryptonote_utils";
import { formatMoneyFull } from "cryptonote_utils/formatters";
export function estimatedTransactionNetworkFee(
nonZeroMixin: number,
feePerKB: JSBigInt,
feePerKB: BigInt,
simplePriority: number,
) {
const numOfInputs = 2; // this might change -- might select inputs
@ -58,7 +59,7 @@ export function estimatedTransactionNetworkFee(
1 /*dest*/ + 1 /*change*/ + 0; /*no mymonero fee presently*/
// TODO: update est tx size for bulletproofs
// TODO: normalize est tx size fn naming
const estimatedTxSize = monero_utils.estimateRctSize(
const estimatedTxSize = estimateRctSize(
numOfInputs,
nonZeroMixin,
numOfOutputs,
@ -77,7 +78,7 @@ export type SendFundsRet = {
sentAmount: number;
pid: Pid;
txHash: string;
txFee: JSBigInt;
txFee: BigInt;
};
export async function SendFunds(
@ -118,7 +119,7 @@ export async function SendFunds(
}
const { address, amount } = singleTarget;
const feelessTotal = new JSBigInt(amount);
const feelessTotal = new BigInt(amount);
Log.Amount.beforeFee(feelessTotal, isSweeping);
@ -228,7 +229,7 @@ export async function SendFunds(
if (success) {
const sentAmount = isSweeping
? parseFloat(monero_utils.formatMoneyFull(feelessTotal))
? parseFloat(formatMoneyFull(feelessTotal))
: targetAmount;
return {

@ -0,0 +1,11 @@
export type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
export interface SecretCommitment {
x: string;
a: string;
}
export interface MixCommitment {
dest: string;
mask: string;
}

@ -3,7 +3,8 @@
"target": "es2017",
"sourceMap": false,
"module": "commonjs",
"baseUrl": "./",
"baseUrl": "src",
"outDir": "dist",
"lib": ["es2017", "dom"],
"allowSyntheticDefaultImports": true,
@ -20,5 +21,5 @@
"pretty": true,
"resolveJsonModule": true
},
"include": ["./src/", "./__test__/", "examples", "./"]
"include": ["./src/", "./__test__/", "examples"]
}

@ -1,6 +0,0 @@
import BigInt = require("cryptonote_utils/biginteger");
export const JSBigInt = BigInt.BigInteger;
export type JSBigInt = BigInt.BigInteger;
export type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;

@ -77,6 +77,13 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1:
dependencies:
color-convert "^1.9.0"
anymatch@^1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
dependencies:
micromatch "^2.1.5"
normalize-path "^2.0.0"
anymatch@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
@ -129,6 +136,18 @@ array-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
array-filter@~0.0.0:
version "0.0.1"
resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec"
array-map@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
array-reduce@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
array-unique@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
@ -157,6 +176,10 @@ astral-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
async-each@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
async-limiter@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
@ -246,6 +269,13 @@ babel-jest@^23.0.1:
babel-plugin-istanbul "^4.1.6"
babel-preset-jest "^23.0.1"
babel-jest@^23.4.0:
version "23.4.0"
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.4.0.tgz#22c34c392e2176f6a4c367992a7fcff69d2e8557"
dependencies:
babel-plugin-istanbul "^4.1.6"
babel-preset-jest "^23.2.0"
babel-messages@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
@ -265,10 +295,21 @@ babel-plugin-jest-hoist@^23.0.1:
version "23.0.1"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.0.1.tgz#eaa11c964563aea9c21becef2bdf7853f7f3c148"
babel-plugin-jest-hoist@^23.2.0:
version "23.2.0"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz#e61fae05a1ca8801aadee57a6d66b8cefaf44167"
babel-plugin-syntax-object-rest-spread@^6.13.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5"
babel-preset-jest@^23.0.0, babel-preset-jest@^23.2.0:
version "23.2.0"
resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz#8ec7a03a138f001a1a8fb1e8113652bf1a55da46"
dependencies:
babel-plugin-jest-hoist "^23.2.0"
babel-plugin-syntax-object-rest-spread "^6.13.0"
babel-preset-jest@^23.0.1:
version "23.0.1"
resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.0.1.tgz#631cc545c6cf021943013bcaf22f45d87fe62198"
@ -288,7 +329,7 @@ babel-register@^6.26.0:
mkdirp "^0.5.1"
source-map-support "^0.4.15"
babel-runtime@^6.22.0, babel-runtime@^6.26.0:
babel-runtime@^6.22.0, babel-runtime@^6.26.0, babel-runtime@^6.9.2:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
dependencies:
@ -305,7 +346,7 @@ babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0:
babylon "^6.18.0"
lodash "^4.17.4"
babel-traverse@^6.18.0, babel-traverse@^6.26.0:
babel-traverse@^6.0.0, babel-traverse@^6.18.0, babel-traverse@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee"
dependencies:
@ -319,7 +360,7 @@ babel-traverse@^6.18.0, babel-traverse@^6.26.0:
invariant "^2.2.2"
lodash "^4.17.4"
babel-types@^6.18.0, babel-types@^6.26.0:
babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
dependencies:
@ -354,6 +395,10 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
binary-extensions@^1.0.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205"
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@ -388,7 +433,7 @@ browser-process-hrtime@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e"
browser-resolve@^1.11.2:
browser-resolve@^1.11.2, browser-resolve@^1.11.3:
version "1.11.3"
resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6"
dependencies:
@ -475,6 +520,21 @@ chalk@^2.0.0, chalk@^2.0.1:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chokidar@^1.6.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
dependencies:
anymatch "^1.3.0"
async-each "^1.0.0"
glob-parent "^2.0.0"
inherits "^2.0.1"
is-binary-path "^1.0.0"
is-glob "^2.0.0"
path-is-absolute "^1.0.0"
readdirp "^2.0.0"
optionalDependencies:
fsevents "^1.0.0"
chownr@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181"
@ -571,6 +631,22 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
cpx@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/cpx/-/cpx-1.5.0.tgz#185be018511d87270dedccc293171e37655ab88f"
dependencies:
babel-runtime "^6.9.2"
chokidar "^1.6.0"
duplexer "^0.1.1"
glob "^7.0.5"
glob2base "^0.0.12"
minimatch "^3.0.2"
mkdirp "^0.5.1"
resolve "^1.1.7"
safe-buffer "^5.0.1"
shell-quote "^1.6.1"
subarg "^1.0.0"
cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
@ -619,6 +695,12 @@ decamelize@^1.0.0, decamelize@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
decamelize@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7"
dependencies:
xregexp "4.0.0"
decode-uri-component@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
@ -699,6 +781,10 @@ domexception@^1.0.0:
dependencies:
webidl-conversions "^4.0.2"
duplexer@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
ecc-jsbn@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
@ -817,6 +903,17 @@ expect@^23.1.0:
jest-message-util "^23.1.0"
jest-regex-util "^23.0.0"
expect@^23.4.0:
version "23.4.0"
resolved "https://registry.yarnpkg.com/expect/-/expect-23.4.0.tgz#6da4ecc99c1471253e7288338983ad1ebadb60c3"
dependencies:
ansi-styles "^3.2.0"
jest-diff "^23.2.0"
jest-get-type "^22.1.0"
jest-matcher-utils "^23.2.0"
jest-message-util "^23.4.0"
jest-regex-util "^23.3.0"
extend-shallow@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
@ -909,6 +1006,10 @@ fill-range@^4.0.0:
repeat-string "^1.6.1"
to-regex-range "^2.1.0"
find-index@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4"
find-up@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
@ -922,6 +1023,12 @@ find-up@^2.1.0:
dependencies:
locate-path "^2.0.0"
find-up@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
dependencies:
locate-path "^3.0.0"
for-in@^1.0.1, for-in@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@ -954,6 +1061,14 @@ fragment-cache@^0.2.1:
dependencies:
map-cache "^0.2.2"
fs-extra@6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b"
dependencies:
graceful-fs "^4.1.2"
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-minipass@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d"
@ -964,7 +1079,7 @@ fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
fsevents@^1.2.3:
fsevents@^1.0.0, fsevents@^1.2.3:
version "1.2.4"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426"
dependencies:
@ -1019,6 +1134,12 @@ glob-parent@^2.0.0:
dependencies:
is-glob "^2.0.0"
glob2base@^0.0.12:
version "0.0.12"
resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56"
dependencies:
find-index "^0.1.1"
glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
@ -1034,7 +1155,7 @@ globals@^9.18.0:
version "9.18.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
graceful-fs@^4.1.11, graceful-fs@^4.1.2:
graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
@ -1173,7 +1294,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@~2.0.3:
inherits@2, inherits@^2.0.1, inherits@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
@ -1207,6 +1328,12 @@ is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
is-binary-path@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
dependencies:
binary-extensions "^1.0.0"
is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
@ -1503,6 +1630,24 @@ jest-cli@^23.1.0:
which "^1.2.12"
yargs "^11.0.0"
jest-config@^23.0.0:
version "23.4.1"
resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.4.1.tgz#3172fa21f0507d7f8a088ed1dbe4157057f201e9"
dependencies:
babel-core "^6.0.0"
babel-jest "^23.4.0"
chalk "^2.0.1"
glob "^7.1.1"
jest-environment-jsdom "^23.4.0"
jest-environment-node "^23.4.0"
jest-get-type "^22.1.0"
jest-jasmine2 "^23.4.1"
jest-regex-util "^23.3.0"
jest-resolve "^23.4.1"
jest-util "^23.4.0"
jest-validate "^23.4.0"
pretty-format "^23.2.0"
jest-config@^23.1.0:
version "23.1.0"
resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.1.0.tgz#708ca0f431d356ee424fb4895d3308006bdd8241"
@ -1530,6 +1675,15 @@ jest-diff@^23.0.1:
jest-get-type "^22.1.0"
pretty-format "^23.0.1"
jest-diff@^23.2.0:
version "23.2.0"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.2.0.tgz#9f2cf4b51e12c791550200abc16b47130af1062a"
dependencies:
chalk "^2.0.1"
diff "^3.2.0"
jest-get-type "^22.1.0"
pretty-format "^23.2.0"
jest-docblock@^23.0.1:
version "23.0.1"
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.0.1.tgz#deddd18333be5dc2415260a04ef3fce9276b5725"
@ -1543,6 +1697,13 @@ jest-each@^23.1.0:
chalk "^2.0.1"
pretty-format "^23.0.1"
jest-each@^23.4.0:
version "23.4.0"
resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.4.0.tgz#2fa9edd89daa1a4edc9ff9bf6062a36b71345143"
dependencies:
chalk "^2.0.1"
pretty-format "^23.2.0"
jest-environment-jsdom@^23.1.0:
version "23.1.0"
resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.1.0.tgz#85929914e23bed3577dac9755f4106d0697c479c"
@ -1551,6 +1712,14 @@ jest-environment-jsdom@^23.1.0:
jest-util "^23.1.0"
jsdom "^11.5.1"
jest-environment-jsdom@^23.4.0:
version "23.4.0"
resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz#056a7952b3fea513ac62a140a2c368c79d9e6023"
dependencies:
jest-mock "^23.2.0"
jest-util "^23.4.0"
jsdom "^11.5.1"
jest-environment-node@^23.1.0:
version "23.1.0"
resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.1.0.tgz#452c0bf949cfcbbacda1e1762eeed70bc784c7d5"
@ -1558,6 +1727,13 @@ jest-environment-node@^23.1.0:
jest-mock "^23.1.0"
jest-util "^23.1.0"
jest-environment-node@^23.4.0:
version "23.4.0"
resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.4.0.tgz#57e80ed0841dea303167cce8cd79521debafde10"
dependencies:
jest-mock "^23.2.0"
jest-util "^23.4.0"
jest-get-type@^22.1.0:
version "22.4.3"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4"
@ -1590,6 +1766,22 @@ jest-jasmine2@^23.1.0:
jest-util "^23.1.0"
pretty-format "^23.0.1"
jest-jasmine2@^23.4.1:
version "23.4.1"
resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.4.1.tgz#fa192262430d418e827636e4a98423e5e7ff0fce"
dependencies:
chalk "^2.0.1"
co "^4.6.0"
expect "^23.4.0"
is-generator-fn "^1.0.0"
jest-diff "^23.2.0"
jest-each "^23.4.0"
jest-matcher-utils "^23.2.0"
jest-message-util "^23.4.0"
jest-snapshot "^23.4.1"
jest-util "^23.4.0"
pretty-format "^23.2.0"
jest-leak-detector@^23.0.1:
version "23.0.1"
resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.0.1.tgz#9dba07505ac3495c39d3ec09ac1e564599e861a0"
@ -1604,6 +1796,14 @@ jest-matcher-utils@^23.0.1:
jest-get-type "^22.1.0"
pretty-format "^23.0.1"
jest-matcher-utils@^23.2.0:
version "23.2.0"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.2.0.tgz#4d4981f23213e939e3cedf23dc34c747b5ae1913"
dependencies:
chalk "^2.0.1"
jest-get-type "^22.1.0"
pretty-format "^23.2.0"
jest-message-util@^23.1.0:
version "23.1.0"
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.1.0.tgz#9a809ba487ecac5ce511d4e698ee3b5ee2461ea9"
@ -1614,14 +1814,32 @@ jest-message-util@^23.1.0:
slash "^1.0.0"
stack-utils "^1.0.1"
jest-message-util@^23.4.0:
version "23.4.0"
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f"
dependencies:
"@babel/code-frame" "^7.0.0-beta.35"
chalk "^2.0.1"
micromatch "^2.3.11"
slash "^1.0.0"
stack-utils "^1.0.1"
jest-mock@^23.1.0:
version "23.1.0"
resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-23.1.0.tgz#a381c31b121ab1f60c462a2dadb7b86dcccac487"
jest-mock@^23.2.0:
version "23.2.0"
resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-23.2.0.tgz#ad1c60f29e8719d47c26e1138098b6d18b261134"
jest-regex-util@^23.0.0:
version "23.0.0"
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.0.0.tgz#dd5c1fde0c46f4371314cf10f7a751a23f4e8f76"
jest-regex-util@^23.3.0:
version "23.3.0"
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5"
jest-resolve-dependencies@^23.0.1:
version "23.0.1"
resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.0.1.tgz#d01a10ddad9152c4cecdf5eac2b88571c4b6a64d"
@ -1637,6 +1855,14 @@ jest-resolve@^23.1.0:
chalk "^2.0.1"
realpath-native "^1.0.0"
jest-resolve@^23.4.1:
version "23.4.1"
resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.4.1.tgz#7f3c17104732a2c0c940a01256025ed745814982"
dependencies:
browser-resolve "^1.11.3"
chalk "^2.0.1"
realpath-native "^1.0.0"
jest-runner@^23.1.0:
version "23.1.0"
resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.1.0.tgz#fa20a933fff731a5432b3561e7f6426594fa29b5"
@ -1696,6 +1922,22 @@ jest-snapshot@^23.0.1:
natural-compare "^1.4.0"
pretty-format "^23.0.1"
jest-snapshot@^23.4.1:
version "23.4.1"
resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.4.1.tgz#090de9acae927f6a3af3005bda40d912b83e9c96"
dependencies:
babel-traverse "^6.0.0"
babel-types "^6.0.0"
chalk "^2.0.1"
jest-diff "^23.2.0"
jest-matcher-utils "^23.2.0"
jest-message-util "^23.4.0"
jest-resolve "^23.4.1"
mkdirp "^0.5.1"
natural-compare "^1.4.0"
pretty-format "^23.2.0"
semver "^5.5.0"
jest-util@^23.1.0:
version "23.1.0"
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.1.0.tgz#c0251baf34644c6dd2fea78a962f4263ac55772d"
@ -1709,6 +1951,19 @@ jest-util@^23.1.0:
slash "^1.0.0"
source-map "^0.6.0"
jest-util@^23.4.0:
version "23.4.0"
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.4.0.tgz#4d063cb927baf0a23831ff61bec2cbbf49793561"
dependencies:
callsites "^2.0.0"
chalk "^2.0.1"
graceful-fs "^4.1.11"
is-ci "^1.0.10"
jest-message-util "^23.4.0"
mkdirp "^0.5.1"
slash "^1.0.0"
source-map "^0.6.0"
jest-validate@^23.0.1:
version "23.0.1"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.0.1.tgz#cd9f01a89d26bb885f12a8667715e9c865a5754f"
@ -1718,6 +1973,15 @@ jest-validate@^23.0.1:
leven "^2.1.0"
pretty-format "^23.0.1"
jest-validate@^23.4.0:
version "23.4.0"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.4.0.tgz#d96eede01ef03ac909c009e9c8e455197d48c201"
dependencies:
chalk "^2.0.1"
jest-get-type "^22.1.0"
leven "^2.1.0"
pretty-format "^23.2.0"
jest-watcher@^23.1.0:
version "23.1.0"
resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-23.1.0.tgz#a8d5842e38d9fb4afff823df6abb42a58ae6cdbd"
@ -1809,6 +2073,16 @@ json5@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
optionalDependencies:
graceful-fs "^4.1.6"
jsonify@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@ -1887,6 +2161,13 @@ locate-path@^2.0.0:
p-locate "^2.0.0"
path-exists "^3.0.0"
locate-path@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
dependencies:
p-locate "^3.0.0"
path-exists "^3.0.0"
lodash.sortby@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
@ -1952,7 +2233,7 @@ merge@^1.1.3:
version "1.2.0"
resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da"
micromatch@^2.3.11:
micromatch@^2.1.5, micromatch@^2.3.11:
version "2.3.11"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
dependencies:
@ -2002,7 +2283,7 @@ mimic-fn@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
minimatch@^3.0.3, minimatch@^3.0.4:
minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
@ -2012,7 +2293,7 @@ minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
minimist@^1.1.1, minimist@^1.2.0:
minimist@^1.1.0, minimist@^1.1.1, minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
@ -2046,6 +2327,10 @@ mkdirp@^0.5.0, mkdirp@^0.5.1:
dependencies:
minimist "0.0.8"
moment@^2.22.2:
version "2.22.2"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@ -2127,7 +2412,7 @@ normalize-package-data@^2.3.2:
semver "2 || 3 || 4 || 5"
validate-npm-package-license "^3.0.1"
normalize-path@^2.0.1, normalize-path@^2.1.1:
normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
dependencies:
@ -2270,16 +2555,32 @@ p-limit@^1.1.0:
dependencies:
p-try "^1.0.0"
p-limit@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec"
dependencies:
p-try "^2.0.0"
p-locate@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
dependencies:
p-limit "^1.1.0"
p-locate@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
dependencies:
p-limit "^2.0.0"
p-try@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
p-try@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1"
parse-glob@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
@ -2357,6 +2658,12 @@ pkg-dir@^2.0.0:
dependencies:
find-up "^2.1.0"
pkg-dir@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3"
dependencies:
find-up "^3.0.0"
pn@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
@ -2380,6 +2687,13 @@ pretty-format@^23.0.1:
ansi-regex "^3.0.0"
ansi-styles "^3.2.0"
pretty-format@^23.2.0:
version "23.2.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.2.0.tgz#3b0aaa63c018a53583373c1cb3a5d96cc5e83017"
dependencies:
ansi-regex "^3.0.0"
ansi-styles "^3.2.0"
private@^0.1.8:
version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
@ -2440,7 +2754,7 @@ read-pkg@^1.0.0:
normalize-package-data "^2.3.2"
path-type "^1.0.0"
readable-stream@^2.0.1, readable-stream@^2.0.6:
readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6:
version "2.3.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
dependencies:
@ -2452,6 +2766,15 @@ readable-stream@^2.0.1, readable-stream@^2.0.6:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readdirp@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
dependencies:
graceful-fs "^4.1.2"
minimatch "^3.0.2"
readable-stream "^2.0.2"
set-immediate-shim "^1.0.1"
realpath-native@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.0.tgz#7885721a83b43bd5327609f0ddecb2482305fdf0"
@ -2558,6 +2881,12 @@ resolve@1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
resolve@^1.1.7:
version "1.8.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26"
dependencies:
path-parse "^1.0.5"
ret@~0.1.10:
version "0.1.15"
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
@ -2611,7 +2940,7 @@ sax@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1:
"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
@ -2619,6 +2948,10 @@ set-blocking@^2.0.0, set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
set-immediate-shim@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
set-value@^0.4.3:
version "0.4.3"
resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1"
@ -2653,6 +2986,15 @@ shebang-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
shell-quote@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767"
dependencies:
array-filter "~0.0.0"
array-map "~0.0.0"
array-reduce "~0.0.0"
jsonify "~0.0.0"
shellwords@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
@ -2853,6 +3195,12 @@ strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
subarg@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2"
dependencies:
minimist "^1.1.0"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
@ -2952,6 +3300,19 @@ trim-right@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
ts-jest@^23.0.1:
version "23.0.1"
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-23.0.1.tgz#c90e747b2787d3394319cde77c2748a87aaf2f48"
dependencies:
babel-plugin-istanbul "^4.1.6"
babel-preset-jest "^23.0.0"
cpx "^1.5.0"
fs-extra "6.0.1"
jest-config "^23.0.0"
lodash "^4.17.10"
pkg-dir "^3.0.0"
yargs "^12.0.1"
ts-node@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.0.tgz#a94a13c75e5e1aa6b82814b84c68deb339ba7bff"
@ -2990,6 +3351,10 @@ type-check@~0.3.2:
dependencies:
prelude-ls "~1.1.2"
typescript@^2.9.2:
version "2.9.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
uglify-js@^2.6:
version "2.8.29"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
@ -3012,6 +3377,10 @@ union-value@^1.0.0:
is-extendable "^0.1.1"
set-value "^0.4.3"
universalify@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
unset-value@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559"
@ -3162,10 +3531,18 @@ xml-name-validator@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
xregexp@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020"
y18n@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
"y18n@^3.2.1 || ^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
@ -3174,6 +3551,12 @@ yallist@^3.0.0, yallist@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9"
yargs-parser@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8"
dependencies:
camelcase "^4.1.0"
yargs-parser@^9.0.2:
version "9.0.2"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077"
@ -3197,6 +3580,23 @@ yargs@^11.0.0:
y18n "^3.2.1"
yargs-parser "^9.0.2"
yargs@^12.0.1:
version "12.0.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.1.tgz#6432e56123bb4e7c3562115401e98374060261c2"
dependencies:
cliui "^4.0.0"
decamelize "^2.0.0"
find-up "^3.0.0"
get-caller-file "^1.0.1"
os-locale "^2.0.0"
require-directory "^2.1.1"
require-main-filename "^1.0.1"
set-blocking "^2.0.0"
string-width "^2.0.0"
which-module "^2.0.0"
y18n "^3.2.1 || ^4.0.0"
yargs-parser "^10.1.0"
yargs@~3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"

Loading…
Cancel
Save